lesson-harvest
Process chat sessions into durable lessons — walk unprocessed transcripts (Claude first; other lanes as enumerators land), extract every defect/workaround/correction/insight, route each to its EXISTIN
SKILL.md.claude/skills/lesson-harvest/SKILL.md
GitHublesson-harvest
The operator's law (memory feedback-codify-every-session-lesson): every discussion carries
lessons, and a discussion not processed into a durable owner was wasted. scripts/ lesson-harvest.py owns everything deterministic (queue, cursor, backlog); this skill owns
only judgment — reading a session and deciding what it taught, where that lesson binds, and
whether it is already codified.
Iron rules:
- Route ONLY to existing termini. Never invent a new ledger, doc, or registry for a lesson
(
PREC-2026-07-30-plan-decisions-dont-bind: a lesson binds only when it names a registry path, predicate script, lever id, or precedent id). - PII firewall: owner refs and one-line summaries only. No verbatim personal content, no
third-party names, no secrets, no
/Users/...paths in anything tracked. Person-scoped material (people reviews, relationship content) is NOT a lesson-harvest output — it belongs to the_people-privatereview lane (ARCA-sealed), and in a background session its writes are classifier-gated; citeexistingand move on. - Bounded reads only:
vendor-insights.py cat-sessionexcerpts, never whole-file loads. - Tier the fan-out: session reading is scan-class work — use cheap-tier subagents for the first pass; reserve the session model for judgment on candidate lessons.
Steps
- Queue.
python3 scripts/lesson-harvest.py --queue [--vendor <vendor>] [--limit N]→ TSV: vendor, session id, project label, day, bytes. Newest first. Note the excluded vendors and thecoverage:lines it prints — carry both into your report verbatim (backlog unknown ≠ zero; every non-Claude lane is listed from a rolling-window index, so a session older than that window is not in the queue). - Read. For each session, with the vendor from its queue row:
python3 scripts/vendor-insights.py cat-session --vendor <vendor> --session <sid>(raise--max-charsonly when the excerpt truncates mid-incident). Look for: a correction from the operator; a workaround that was narrated but not codified; a wrong confident claim and what refuted it; a gate/tool/method fought twice; a decision that binds future sessions. Skip pleasantries and routine execution — a lesson is something the NEXT session would otherwise get wrong. - Dedupe against the owners first. Before writing anything, check whether the lesson
already lives somewhere:
grepcensor/precedents.jsonl,his-hand-levers.json, the memory index (.agent-runtime/claude/projects/<project>/memory/MEMORY.md), and CLAUDE.md. Already owned → record{"owner_kind":"existing","owner_ref":"<the id/path>"}and write nothing new. - Route each genuinely new lesson by the cascade:
- Repeatable correction with a binding site → precedent: append one JSON line to
censor/precedents.jsonlmatching the live schema (id: PREC-YYYY-MM-DD-<slug>,ts,type,subject,outcome,reversible,actionnaming WHERE it binds,authorised_by(the file's uniform spelling — all 36 records),review). Any script it cites must exist (check-runner-coverage.pyE). - Irreducible human atom → lever in
his-hand-levers.json(idL-…, label with the concrete ~minutes action, owner, cost, unlocks, source_task, issue). - Behavioral/project knowledge for future sessions → memory file (frontmatter
name/description/metadata.type) + one pointer line inMEMORY.md(evocator.py-verifiable). - Buildable work → board task through the conduct broker (
limen conduct …/ TABVLARIVS) — never by editingtasks.yaml.
- Repeatable correction with a binding site → precedent: append one JSON line to
- Mark.
python3 scripts/lesson-harvest.py --mark <sid> --vendor <vendor> --lessons '[{"owner_kind":"precedent","owner_ref":"PREC-…"}, …]'— or--none-foundwhen a session genuinely taught nothing (processed is a state, not a success claim). Marking is idempotent; re-marking is a no-op. - Report. End with
python3 scripts/lesson-harvest.py --checkoutput: per-vendor remaining/processed, coverage windows, exclusions, TOTAL. The backlog number is the deliverable — never summarize a tranche as if it drained the corpus.
Tranche discipline
Default tranche: 10 sessions, newest first (recency = highest un-codified density; the
oldest sessions' lessons mostly got codified since). The daily lesson-harvest-backlog
sensor keeps the remaining count on the beat, so stopping mid-backlog is safe — the state
is in the cursor, not in anyone's memory.