MemClaw / docs
Skill Factory

Forge

The server-side resident that mines fleet behavior into skill candidates — how it runs, how operators trigger and observe it, and the knobs that tune it.

Forge is the half of Skill Factory that authors skills for you. Where direct authoring needs an agent to remember to write a skill, Forge watches what the fleet actually does — clusters of repeated, successful procedures across sessions and agents — and distills each cluster into a skill candidate automatically.

What Forge produces

Every candidate Forge writes lands with status='candidate' and source='forge'. Candidates are never visible to agents — they're an internal staging area. A candidate only becomes useful by clearing the six auto-gates and being promoted to staged (then active via the Inbox or auto_promote_clean).

Re-running Forge over the same cluster is safe: a new candidate may overwrite an existing candidate at the same slug (that's how Forge refines its own work), but Forge will not overwrite a slug that has already moved past candidate (staged, active, rejected, quarantined, stale, or deprecated) — it skips it and records candidates_skipped_existing.

How it runs (operator setup)

Forge runs per tenant on a cadence you drive, via a fan-out endpoint:

external scheduler ──POST /admin/lifecycle/fanout/forge-distill──▶ core-api

                          lists tenants with skills_factory.enabled=true

                  publishes memclaw.lifecycle.forge-distill-requested │ (per tenant)

                                              run_forge_cron_tick(tenant)

You point a scheduler (Google Cloud Scheduler, a Kubernetes CronJob, cron + curl, …) at the endpoint:

curl -fsS -X POST "$CORE_API_BASE_URL/admin/lifecycle/fanout/forge-distill"

The cadence is entirely the scheduler's. skills_factory.forge.cron_interval_hours (default 6) is informational only — set it to match your real schedule so operators reading the config aren't misled. A 1-hour dedup window means an extra fan-out inside that window is a no-op for a tenant that already ran.

Forge does nothing for a tenant until skills_factory.enabled = true. The fan-out lists only opted-in tenants, so enabling/disabling the flag is the on/off switch.

What operators see

Each tick writes one lifecycle_audit row per tenant, with per-run counts under stats:

  • candidates_written — new candidates persisted.
  • candidates_skipped_poisoned — cluster fingerprint is in the reject poison table (an operator rejected a prior version).
  • candidates_skipped_sentinel — the in-Forge scan flagged the draft.
  • candidates_skipped_existing — the slug already moved past candidate.
  • candidates_skipped_distill_error / candidates_skipped_io_error — distillation or persistence failures (operator-actionable).

Fresh candidates that pass the gates appear in the Skills Inbox. A failure in one tenant's tick never aborts another tenant's.

Tuning

Key (skills_factory.*)DefaultEffect
forge.cron_interval_hours6Informational; your scheduler sets the real cadence.
forge.min_cluster_size3Minimum executions in a cluster (the volume gate).
forge.min_distinct_agents3Minimum distinct agents in a cluster (the diversity gate).
forge.freshness_window_days14How recent a cluster's activity must be (the freshness gate).
sentinel.auto_promote_cleanfalseIf true, a candidate that passes all gates and scans clean skips the Inbox and goes straight to active. A trust decision — see below.

Auto-promote: shipping without a human

sentinel.auto_promote_clean=true removes the human review step for clean, fully-gated candidates. Only enable it once you trust that the gate thresholds and the Sentinel rule-set are tuned for your content — otherwise keep it false and approve from the Inbox.

Where to look in the source