Skip to content

feat(lesson-capture): correction→bake-in loop v1 — lesson-capture fragment + mechanik bake-in doctrine (tk-7druqk)#88

Open
zook-bot wants to merge 2 commits into
mainfrom
polecat/tk-7druqk
Open

feat(lesson-capture): correction→bake-in loop v1 — lesson-capture fragment + mechanik bake-in doctrine (tk-7druqk)#88
zook-bot wants to merge 2 commits into
mainfrom
polecat/tk-7druqk

Conversation

@zook-bot

@zook-bot zook-bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Summary

Correction→bake-in loop v1: lesson-capture fragment + mechanik bake-in doctrine

Why (self-contained context — do not assume any other context is injected)

Operator decision (2026-06-03, mechanik thread lo-d5by "ship correction-bake-in loop v1"):
the city should continuously reinforce what works and stop repeating what doesn't.
Analysis converged on building the correction→bake-in loop first: when the operator
gives corrective feedback ("this isn't right", "don't do X", "always do Y first"), that
correction must become a durable process change — not evaporate when the conversation ends.
This is foundation.md's first belief ("Agents improve… every lesson compounds into the pack
so attention is never spent twice") made operational. Deliberately NO statistics, NO
approval-rate tracking, NO new agents/formulas — one instance of a correction is enough
signal. (An adversarial review killed the statistics-based alternative; corrections carry
the signal, approvals don't.)

Today NOTHING instructs agents to capture operator corrections. Some agents (mechanik,
mayor) have auto-memory and do it ad hoc; pool agents (polecats, dogs) have no memory and
lose corrections entirely. This change closes that gap with a convention fragment + a
mechanik triage doctrine.

Optional deeper context (readable on this host, NOT required):
/home/zook/loomington/.gc/agents/mechanik-thread/gc-toolkit.mechanik-thread-adhoc-7d34f10c5d/fill-the-queue-design.md

Deliverable 1: template-fragments/lesson-capture.template.md (NEW)

A gc-toolkit core template-fragment, written for injection into ANY agent prompt via
agent_defaults.append_fragments. Study template-fragments/ siblings (e.g. the existing
fragments referenced by city.toml's append_fragments = ["command-glossary", "operational-awareness"]) and match their {{ define "<name>" }} structure exactly —
the define-name must be lesson-capture to match the append_fragments key convention.

Content the fragment must convey (write it in the pack's voice; concise — this lands in
every agent's prompt, so budget ~30-45 lines):

Trigger: the operator (human) gives EXPLICIT corrective feedback on how you worked —
"this is wrong", "don't do X", "you should have done Y", "stop doing Z", a redirect after
a mistake. NOT routine instructions, NOT preferences you already honored, NOT agent-to-agent
feedback. v1 is explicit corrections only.

Action A — agent-local (only if you have auto-memory): write a feedback-type memory
now, per your memory conventions (include the why and how-to-apply; quote the operator
where short). This makes the lesson durable for YOUR future sessions.

Action B — city-level (always, when the lesson should change SHARED process): if the
correction implies a change to shared machinery — an agent prompt, a formula step, a
convention doc, a review check — file a lesson bead in HQ:

gc bd create "LESSON: <one-line imperative form of the correction>" \
  -t task -l lesson -a gc-toolkit.mechanik \
  -d "<operator's correction as close to verbatim as practical>
Context: <what you were doing when corrected; bead/PR/session refs>
Suggested durable home: <prompt amendment | fragment | formula step | convention doc | review check — best guess>"

Bar and dedup: real corrections only — a lesson bead is a claim that the process
should change. Before filing, check gc bd list -l lesson --status open,in_progress
(open AND in_progress — claim flips status) and extend an existing bead's notes instead of
duplicating. Do not file statistics, scores, or "the operator approved this" — approvals
are not lessons.

What happens next (one line, so filers know the loop closes): the mechanik triages
lesson beads, picks the durable home, dispatches the change, and closes the bead with a
pointer to the shipped change.

Deliverable 2: mechanik prompt amendment (agents/mechanik/prompt.template.md)

Add a compact "Lesson bake-in" section to the mechanik prompt (place it near the existing
inputs/outputs doctrine; match surrounding voice and heading style). Content:

  • Lesson beads (-l lesson, HQ, assigned to you) are corrections other agents captured
    from the operator. Triage them on hook like routed work.
  • For each: decide the durable home — agent prompt, template-fragment, formula step,
    convention doc, review-leg check, or (if it's genuinely agent-local) the filer's memory
    with no pack change. Then dispatch the gc-toolkit edit through the normal bead→polecat
    path (Principle 6 — you scope, polecats edit), and close the lesson bead with a pointer
    to the shipped change (PR/commit/bead).
  • Lessons must not rot: an open lesson bead older than ~a week gets surfaced in your next
    operator conversation, not silently backlogged.
  • Anti-patterns: do not convert lessons into approval statistics; do not batch-hold
    corrections waiting for a pattern — ONE clear correction is sufficient signal; do not
    bake in a "lesson" that contradicts an operator decision without asking.

Deliverable 3: activation note (DOCUMENT ONLY — do NOT apply)

Activation = adding "lesson-capture" to agent_defaults.append_fragments in the
consuming city's city.toml. Do NOT touch any city.toml in this PR. Document the wiring
line wherever the pack documents fragment adoption (follow the existing pattern — e.g. how
other append_fragments fragments are documented; a short note in the fragment's header
comment or the pack docs is enough). Reason it's deferred: city.toml edits drift session
CoreFingerprints and drain detached manual sessions (known issue, fix not yet deployed);
the operator/mechanik applies the wiring at a safe moment after merge.

Acceptance criteria

  • template-fragments/lesson-capture.template.md exists, {{ define "lesson-capture" }},
    covers: trigger (explicit operator corrections only), Action A (memory, if agent has
    it), Action B (HQ lesson bead with the exact create command), dedup
    (--status open,in_progress), the bar (no approvals/statistics), loop-closure line.
  • Mechanik prompt gains the "Lesson bake-in" triage doctrine (durable-home menu,
    Principle-6 dispatch, close-with-pointer, no-rot rule, anti-patterns).
  • Activation line documented but NOT applied; no city.toml modified.
  • No gastown base pack files touched; gc-toolkit only.
  • Fragment length stays lean (~≤45 lines) — it injects into every agent prompt.

Provenance

Operator greenlight 2026-06-03 (thread lo-d5by). Design record: thread working note path
above. Foundation: docs/foundation.md ("Agents improve", "attention is the budget").

Implementation notes

Implemented: lesson-capture fragment (39 rendered lines; trigger/Action A/Action B/dedup/bar/loop-closure, activation line in header comment, NOT wired) + mechanik 'Lesson Bake-in' doctrine (durable-home menu, Principle-6 dispatch, close-with-pointer, no-rot, anti-patterns). Validated: fragment+prompt parse and render via text/template mimicking gascity loadSharedTemplates/renderPrompt. No city.toml touched, no gastown files touched.

Refinery handoff

  • Issue: tk-7druqk (task, P2)
  • Source branch: polecat/tk-7druqk
  • Target: main
  • Rebased on main via Gastown Refinery.

…k doctrine (tk-7druqk)

Adds template-fragments/lesson-capture.template.md: a lean (~39 rendered
lines) append_fragments fragment instructing any agent to capture explicit
operator corrections — agent-local feedback memory when the agent has
auto-memory, plus an HQ lesson bead (-l lesson, assigned to mechanik) when
the lesson should change shared process. Covers the dedup check
(--status open,in_progress) and the bar (corrections only; approvals are
not lessons).

Adds a 'Lesson Bake-in' section to the mechanik prompt: triage lesson
beads on hook, pick the durable home, dispatch edits via the bead→polecat
path (Principle 6), close with a pointer to the shipped change, surface
week-old lessons to the operator, and the anti-patterns (no approval
statistics, no batch-holding, no overriding operator decisions).

Activation (adding "lesson-capture" to agent_defaults.append_fragments
in the consuming city.toml) is documented in the fragment header comment
but deliberately NOT applied: city.toml edits drift session
CoreFingerprints and drain detached manual sessions.

Provenance: operator greenlight 2026-06-03, thread lo-d5by.

@zook-bot zook-bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocking finding:

  • template-fragments/lesson-capture.template.md:32 / :41: the fragment says to file and dedup lesson beads in HQ, but both commands run in the caller's current bead store. From a gc-toolkit rig worktree, gc bd list loads /home/zook/loomington/rigs/gc-toolkit/.beads/config.yaml, while gc bd list -C "$GC_CITY" loads HQ at /home/zook/loomington/.beads/config.yaml. Since this fragment is intended for any agent prompt, rig agents would create and dedup -l lesson beads in their rig DB, not HQ; city-scoped mechanik's hook would not reliably see or triage them. Please force the HQ store in both commands, for example with gc bd list -C "$GC_CITY" ... and gc bd create -C "$GC_CITY" ... or the equivalent documented HQ selector.

Checks performed:

  • Reviewed PR diff against origin/main.
  • git diff --check origin/main...HEAD passes.
  • Probed gc bd list --verbose vs gc bd list -C "$GC_CITY" --verbose to verify the store mismatch.

Note: I attempted to submit this as REQUEST_CHANGES, but GitHub rejected it because the authenticated account is treated as the PR author. This is a blocking review finding despite the GitHub review event being a comment.

…ds (tk-gst80h)

Codex review on PR#88 found that the fragment's gc bd create/list
commands run in the caller's current bead store: from a rig worktree
they load the rig's .beads config, not HQ, so rig agents would file
lesson beads where the city-scoped mechanik never sees them.

Add -C "$GC_CITY" to both the create and dedup-list commands (probe
confirmed it loads /home/zook/loomington/.beads/config.yaml even with
BEADS_DIR pinning the rig store), plus a two-line comment in the code
block explaining why. Rendered fragment is 40 lines, within the ~45
budget; all 13 fragments + mechanik prompt still parse and render.

@zook-bot zook-bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No blocking findings on the updated head.

Reviewed after the follow-up fix commit 9207893, which forces the lesson bead create and dedup commands through the HQ bead store with -C "$GC_CITY". The earlier HQ-store blocking finding is addressed.

Checks performed:

  • Reviewed the PR diff against origin/main.
  • git diff --check origin/main...HEAD
  • All doctor/*/run.sh checks with GC_PACK_DIR=$PWD
  • Targeted Go text/template parse/render probe for all top-level template fragments, the mechanik prompt, and the new lesson-capture fragment

@zook-bot
zook-bot marked this pull request as ready for review June 3, 2026 22:16
@zook-bot
zook-bot marked this pull request as draft June 5, 2026 20:20
@zook-bot

zook-bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor Author

Back to draft (operator, 2026-06-05): a feature that isn't wired in just sits and confuses. #88 is half-wired by construction — the mechanik "Lesson Bake-in" section goes live on merge (mechanik told to triage a lesson-bead queue), but the lesson-capture fragment that fills that queue stays dormant until "lesson-capture" is added to append_fragments in the city's city.toml. Merging alone = a mechanik watching for work that never arrives.

To make it useful = the city.toml activation, scoped to operator-facing agents (mayor/mechanik/deacon — the rest never receive corrections). That edit drifts session CoreFingerprints and can drain detached sessions; the fix (gascity f96fe8dc / PR#25) merged 06-03 and gc was rebuilt 06-05 17:46, so it's likely deployed — confirm behavior before the edit. Plan: land #88 + the append_fragments activation together at a safe window (wire-and-land), not #88 alone.

@zook-bot
zook-bot marked this pull request as ready for review June 12, 2026 06:56
zook-bot added a commit that referenced this pull request Jul 21, 2026
…one (tk-vpx62)

Second arm of tk-vpx62 (mayor scope extension, 2026-07-21). The first arm
handled a PR whose anchor is stranded; this one handles a PR whose anchor is
GONE.

Every close-on-land path — merge-skill.sh, this reconciler, the refinery patrol
— enumerates from the BEAD and reads its pr_number. Sound while the bead
outlives the PR, which close-on-land guarantees. But a PR whose bead is CLOSED
is not merely unhandled, it is unseen: no scan starts anywhere that reaches it,
so it never lands, never escalates, never times out. It does not read as broken,
it reads as absent. The pre-#163 close-on-publish model created that state by
design, and the 7 PRs it stranded (#171 #170 #166 #108 #88 #80 #77) sat
untouched for weeks — found only by a human cross-checking `gh pr list` against
the ledger by hand.

So reconcile from the other side too: enumerate open PRs, subtract every PR
number any LIVE bead references, report the remainder. Verified against the live
ledger: flags exactly those 7 and correctly excludes in-flight PR#195.

Detection and surfacing ONLY, per the mayor's scope note — it never merges,
closes, or reopens an anchorless PR. Disposition stays an operator call.

Convergence, since a patrol pass runs on every idle wake:
- Escalate once, bounded by an anchorless_flagged marker written to the closed
  bead BEFORE the mail (stamp-first, mirroring the merged path's close-first).
  A failed stamp means no bound, so it does not mail — a delayed escalation is
  recoverable, a mail storm is not.
- A PR with NO bead in any state is logged but never mailed: nothing durable
  exists to record that we already said it.
- A failed ledger read is empty, not "[]", and the scan fails CLOSED on it —
  treating "could not read" as "nothing is tracked" would flag every open PR at
  once.
- Anchor resolution picks the OLDEST bead carrying merge_result, so the operator
  is pointed at the bead that OPENED the PR rather than a review bead or a later
  "address findings" child (several closed beads routinely name one PR); the
  mail lists the whole set regardless.

Zero gating anchors is no longer an early exit — that was precisely the state
where this scan matters most (no live anchors WITH open PRs is the stranded
shape).

Tests: 24 new hermetic assertions (62 total, all pass); verified 13 of them FAIL
against the pre-arm script while all 38 pre-existing ones still pass. Sibling
suites green (merge-skill 36, one-anchor-per-pr 13, pre-open-resolve 16,
signoff-anchor-resolution 14, signoff-anchor-failclosed 14,
reconcile-graduated-convoys 14, reconcile-rig-checkouts 8, husk-guard 16).
bash -n + shellcheck clean at warning severity.
zook-bot added a commit that referenced this pull request Jul 22, 2026
…astownhall (tk-c07sq)

Addresses the pre-open signoff finding on tk-dmqdq (P2, line 31).

The provenance row credited `fa487632b` to `gastownhall/gascity` as a
2026-07-11 merge. Verified against the local gascity checkout:

  - `fa487632b` is NOT an ancestor of `upstream/main` (gastownhall);
    it IS an ancestor of `origin/main` (zookanalytics fork).
  - `clearStaleOpenAssigneeForPoolRoute` appears nowhere in
    `upstream/main` — the change is fork-local, not upstream at all.
  - `(#88)` in the subject is the fork PR, not a gastownhall PR.
  - 2026-07-11 is the AUTHOR date; committer date is 2026-07-22. The
    fork rebases `main`, so the SHA churns (the same subject appears on
    a dozen rebased commits) — no durable "merged on <date>" claim.
  - `engdocs/architecture/dispatch.md:180` was cited as "upstream's own
    prose", but upstream's copy of that file carries no such passage.

Rewrites the row to name the fork as producer, state plainly that the
change is absent from canonical gascity, and pin verification to
`zookanalytics/gascity` `origin/main` `7bba3de3b`. Line-number citations
re-verified at that commit and left as-is.

Also scopes the two body claims that inherited the same misattribution
(Lane 1 "Also clears", Lane 3 "no longer the only way to clear") so the
doc's field contract does not read as canonical-gascity behavior.
zook-bot added a commit that referenced this pull request Jul 23, 2026
…he durable record, not the coordination state (tk-4jz9s)

The belief said documentation is the system's memory and that "what's
written survives", but never said where "written" lands. An agent could
satisfy it completely by writing a long analysis into the transient state
that coordinates the work — durable-looking, but not part of the record
anyone inherits with the work. That ambiguity stalled four docs-only PRs
(#171, #170, #108, #88) for 4-7 weeks: the open question was not review,
it was whether those documents belonged in the durable record at all.

Stated as a principle, not a substrate: memory lives in the durable
record, not in the state that coordinates the work. Supersedes PR #212,
which encoded the same rule by naming the Gas City substrate (repo vs
bead-store, committed-file vs bead-comment) inside an engine-agnostic
Core Belief — the wrong altitude for a belief a beadless engine must also
be able to satisfy. Distinct from the earlier PR #203 (tk-zdkfe) attempt
in docs/file-structure.md, which governs the documentation surface, not
whether a work product joins the durable record at all.

Sharpened in place on the existing belief; one line, two sentences,
matching neighbouring belief density. docs/file-structure.md, other
beliefs, agent prompts, and template-fragments untouched; lesson-capture
(tk-63qgj) left out of scope.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant