Repository navigation
feat(planning): terminal commands to set and clear superseded-by-plan ledger rows #6124
Description
Problem
/planning:plan's "Plan changes after the Brief" (plugins/planning/skills/plan/SKILL.md:280-282) has the session edit interview-ledger rows by hand. It sets a row to superseded-by-plan with plan proposes: <new>; was: <old>, then on the user's reply rewrites it as answered with proposal:: <new>; was:: <old>; answer:: accepted: <new>, escaping each value the way surface/exporters.py does. surface/round.py has record-terminal and apply, but they write the page's responses.json, not the markdown register, and many plans run with no page at all. No script edits the register.
Every plan that displaces an answer pays for this. In one multi-workstream effort, four plans in a row (2026-10-03) each needed a throwaway Python script for it (reconfirm_rows.py in one session, ws_u_supersede.py in the next), each re-deriving the escape rules and copying the old resolution into was by hand. A wrong escape breaks the register's parse (the history in #4611 and #5534), and a hand copy can drop part of the old answer without anything noticing.
Proposed fix
Two terminal commands, beside check-open-questions.sh or as round.py subcommands that target the ledger file:
supersede --ledger <file> <Q> --proposes <text>: takes the row's current resolution aswasitself, escapes through the exporter's own function, refuses a row that is notanswered.resolve --ledger <file> <Q> reconfirm|restore [--note <text>]:reconfirmwrites the answeredproposal::/was::/answer::form;restoreputs back the original row byte for byte.
Both back up the ledger first and print the check-open-questions.sh verdict after. SKILL.md:280-282 then names the commands instead of describing the grammar.
Acceptance
supersedethenreconfirmon a fixture row produces the text the exporter writes for the same pair, and it round-trips throughimport-ledger.supersedethenrestoreleaves the ledger byte-identical to the original.check-open-questions.shcounts the row as superseded aftersupersedeand answered afterreconfirm.- A row containing a literal
;,\or|survives both paths.
Activity
kyle-sexton commentedon Oct 4, 2026
This was generated by AI during triage.
Decision defaulted: add
supersedeandresolveasround.py(andround.sh) subcommands that take a--ledger <file>target, not a separate script besidecheck-open-questions.sh— veto before mergeBasis: verified,
plugins/planning/surface/round.py:2120-2136already hosts the ledger-facingexport-ledgerandimport-ledgersubcommands, andplugins/planning/surface/exporters.py:140(esc_field) is the escape function the new commands must reuse, importable fromround.pydirectly; a standalone script would have to re-import or re-implement it. Alternative: a standalone script underplugins/planning/scripts/, which only moves the entry point.Routing: decision-defaulted,
work-class: scoped(C3, feature),priority: medium(every plan that displaces an answer pays for it; hand-written escaping has broken the register's parse before, #4611, #5534). Verified: the plan skill's "Plan changes after the Brief" section has the session hand-edit register rows (plugins/planning/skills/plan/SKILL.md:280-282), and no existing subcommand writes the markdown register:record-terminalandapplywrite the page's data files.check-open-questions.shalready countssuperseded-by-planassuperseded=<n>(plugins/planning/scripts/check-open-questions.sh:42-44).Agent Brief
Type: Feature
Summary: Ship terminal commands that set a ledger register row to
superseded-by-planand later clear it (reconfirm or restore), so plans stop hand-editing the register.Current behavior:
When a plan displaces an interview answer, the session edits the interview ledger's open-question register by hand: it sets the row to
superseded-by-planwithplan proposes: <new>; was: <old>, and on the user's reply rewrites it asansweredwithproposal:: <new>; was:: <old>; answer:: accepted: <new>, escaping each value as the exporter does. Sessions write throwaway scripts for this, and a wrong escape or a partial copy of the old answer goes unnoticed.Desired behavior:
supersede --ledger <file> <Q> --proposes <text>: reads the row's current resolution and records it aswasitself; escapes every value through the exporter's own escape function; refuses a row whose status is notanswered, with a clear error and no write.resolve --ledger <file> <Q> reconfirm|restore [--note <text>]:reconfirmwrites the answeredproposal::/was::/answer::form the exporter writes for the same pair;restorereturns the row to exactly its pre-supersedebytes. Refuses a row that is notsuperseded-by-plan.check-open-questions.shverdict line afterwards.Key interfaces:
round.py/round.shsubcommandssupersedeandresolve(defaulted placement, see the decision line above).import-ledger, which must read the written rows back.Acceptance criteria:
supersedethenreconfirmon a fixture row produces the same text the exporter writes for that pair, and the ledger round-trips throughimport-ledger.supersedethenrestoreleaves the ledger byte-identical to the original.check-open-questions.shcounts the row as superseded aftersupersedeand as answered afterreconfirm.;,\or|survives both paths.supersedeon a non-answered row, andresolveon a non-superseded row, exit non-zero without changing the file.Out of scope:
responses.jsonflow (record-terminal,apply).kyle-sexton commentedon Oct 4, 2026
This was generated by AI during work-loop.
Approve this for autonomous dispatch (with its defaulted decision), or keep it for a human?
Triage marked this decision-defaulted as a feature-shaped C3 (
work-class: scoped). The work-loop admission gate human-gates feature-shaped C3 work, so the lane removedagent-readyand appliedneeds-human. Flip it back through/work-items:attend-queueto dispatch.Lane: work-loop, instance melo-worker-1, cycle 2.
kyle-sexton commentedon Oct 11, 2026
Owner decision (2026-10-11): Add supersede and resolve subcommands to round.py, reusing the exporter's escape function.
Recorded by the coordinating agent session with the owner's approval. Removing
needs-human; implementation is queued and will link its branch here.kyle-sexton commentedon Oct 13, 2026
Owner batch-ratified this admission in an attended session on 2026-10-12: work-class: scoped. Rule: class C1-C3, no trust surface, the independent check confirmed the recorded decision, and no owner step remains.
kyle-sexton commentedon Oct 18, 2026
Agent Brief
Type: Feature
Summary: Add terminal commands that set an interview-ledger register row to superseded-by-plan and later clear it, so plans stop hand-editing the register.
Current behavior:
When a plan displaces an interview answer, the session edits the open-question register by hand: it writes
superseded-by-planwithplan proposes: <new>; was: <old>, then rewrites the row asansweredwithproposal:: <new>; was:: <old>; answer:: accepted: <new>, escaping each value as the exporter does. Sessions write throwaway scripts for this, and a wrong escape breaks the register's parse.Desired behavior:
supersede --ledger <file> <Q> --proposes <text>: it takes the row's current resolution aswas, escapes through the exporter's own field-escape function, and refuses a row that is notanswered.resolve --ledger <file> <Q> reconfirm|restore [--note <text>]:reconfirmwrites the answered proposal/was/answer form;restoreputs back the original row byte for byte.Key interfaces:
Acceptance criteria:
supersedethenreconfirmon a fixture row produces the text the exporter writes for the same pair and round-trips throughimport-ledger.supersedethenrestoreleaves the ledger byte-identical.supersedeand answered afterreconfirm.;, a backslash or|survives both paths.scripts/run-test-file.shpasses on the round test file.scripts/check-changelog-fragments.sh.Out of scope:
record-terminal.This was generated by AI during backlog shaping. Held, not admitted: this brief is drafted and checked, but the issue lane would stop on it today. It is admitted, by adding
agent-ready, once the lane can run the skill-quality check scripts (Automation Lanes' PR #7912). Held under the owner's 2026-10-18 lane-narrowing course correction.feat(planning): round.sh supersede and resolve for ledger rows (#6124)
melodic-automation-lanes commentedon Oct 18, 2026
The work-resolve-issue run that
agent-readystarted failed before it reported, or the token broker refused it because its workflow files differ from main's. work-unblock removed and addedagent-readyback to start a fresh run on main's workflow files. It does this once per version of those files, so if this run fails the same way, a person looks at it.