learn-lessons — Lesson Processing and Queue Activation
learn-lessons processes per-entry state/lessons/*.yaml files as change-requests against
doctrine, agent prompts, hooks, scripts, wiki guides, and improvement queues — one destination +
change-kind per lesson, tracking recurrence and archiving discards. Success metric: did doctrine
and queues evolve, not did the file shrink. Supersedes coordinator:lesson-triage (renamed;
no alias shim). Modes, the routing schema, the fabrication-verify-gate mechanics + recovery
playbook, the Phase 8 report shape, and the heavy-queue promotion-sprint procedure: wiki.
Every coordinator CLI named on this page is engine-homed and has a settings-home launcher —
resolve each by absolute path per snippets/resolve-coordinator-bin.md (Shape W on a PowerShell
host, Shape A/B on POSIX). Never a bareword, and never coordinator/bin/<cli>.py cwd-relative:
this skill runs with cwd set to the consuming repo, where that path does not exist.
Announce: "I'm using the coordinator:learn-lessons skill in <mode> mode." Mode default: cwd
~/.claude central → central; else local; PM can override.
Hard Rules (not engine-enforced)
- No-defer. A
wiki-append/wiki-newrecord with a named destination applies THIS run — never "the next pass." Legitimate deferrals: a structurally-required cross-mode block (e.g.strip-localbefore its central commit SHA lands), or a record needing PM authorization. - Wikis are the default destination.
doctrine-edit/memory-pointerare doctrine-plane-only — a worker NEVER emits either; downgrade towiki-*+doe_escalation: truebefore the record reaches the PM gate. - Extraction never runs through an LLM (
extract-lessons— a parse, not a judgment call; an LLM extraction pass produced a real fabrication incident). Routing judgment can, behind the verify gate. - Mechanical-contract lessons need an executable witness (a passing test, live tool behavior, official docs) — discard if none can be found or one contradicts the claim; narrative confidence alone never overrides a converging set of independent authorities.
- Domain-looking universals default to
retag-local, never a blind[universal]string replace (corrupts retag history). - A
wiki-append/wiki-newtarget must be reachable from a real traversal surface (index, skill step, dispatch preamble) — not merely exist. - Central mode needs a PM decision per record (apply / defer / reject, batching OK) — never
auto-applied. Local mode auto-applies
discard/wiki-append/retag-local/dedupe/age-sweep; PM-surfacesdoctrine-edit,memory-pointer,doe_escalation,agent-prompt-edit,hook-edit,script-edit,snippet-sync-update,project-structural.strip-localis NOT PM-surface. - Central strips only after its own promotion's commit SHA exists, same run — never deferred to the sibling's next age-sweep.
- Fail-close: an undated-universal leak, or a strip-list id with no routed sibling record,
blocks the run's
COMPLETEsentinel — surface to the PM, don't push through. - Universals-pending: if ≥ 20 unactioned
[universal]entries, surface to PM before proceeding. - Never fabricate a routing
id— every cited id must exist in its extraction, or the mechanical verify-gate hard-fails the apply. Never hand-correct a router's fabricated output; re-dispatch it instead (launders the fabrication into the audit trail otherwise).
Phase Flow (invocation pointers — mechanics: wiki)
Discovery roots: learn-lessons-roots (machine-registry-derived, never a
committed list). Baton lift source: batons joined to the plan under distillation by
deliverable_id; each baton's ## What I Learned section is a flat bullet list, one standalone
lesson per line, no sub-headings and no nesting — that shape is fixed so a line survives being
lifted out of the baton with nothing around it. Every line read this way is a candidate lesson,
never an auto-promote: the EM still decides to promote, amend, or drop it through the same
routing/gate mechanics as any other extracted lesson. Extraction: extract-lessons.py extract. Routing populates
candidate_restatements via coordinator_core.learn_lessons_assemble.generate_candidates(...)
(or learn-lessons-reconcile-candidates for bulk). Central mode also runs an undated-pass via
coordinator_core.ops.lessons_filter.filter_undated_universal(extraction_yaml) (registered op
lessons.filter_undated_universal) and drains state/lessons-outbox/ via
lessons-outbox-drain.py (read → assert cross-plane emptiness → group → dedupe → apply → mark
drained). Verify: extract-lessons.py verify <extraction> <records.yaml>. Strip-orphan check:
learn-lessons-age-sweep check-strip-orphans <records.yaml> <strip-list.yaml>. Local-mode
age-sweep bounds state/lessons/: learn-lessons-age-sweep cutoff then age-sweep-lessons.py --before <cutoff> [--apply]. Universal-routing queue fork:
coordinator-lesson-promote (central-wiki target) / auto-apply (project-local wiki) /
coordinator-queue-append --schema improvement-queue (project scope). Recheck-mode delta:
query-records --type lesson --since <date>, cadence marker at state/lesson-triage-recheck-due- <date>.md, volume nudge via central-run-due.
Emit the Phase 8 end-of-run report (exempt from the ≤200-word budget — the run's only audit
trail; do not convert to report-by-exception) before writing the COMPLETE sentinel; the sentinel
is written last, after every apply/commit lands.
Anti-Patterns
Auto-applying central promotions without the PM gate. Bespoke extra parameters (modes are the
parameter surface). git add -A for strips. True-deleting a discard instead of archiving first.
Conflating the improvement queue with state/lessons/ (capture queue vs. this periodic router).
Same-session capture-and-validate a lesson as universal. Default-routing to CLAUDE.md instead of a
wiki. Defer-chaining wiki promotions as "candidates for next pass" — every record is (a) applied,
(b) PM-surfaced, or (c) mode-escalated, no fourth bucket. Declaring "no additional work needed"
while project-specific (non-[universal]) entries remain un-routed. Full list + rationale: wiki.
Related
wiki (full reference) · ${CLAUDE_PLUGIN_ROOT}/snippets/em-operating-doctrine.md § How to Plan and Hand Off, "Improvement Queue"