Skip to content

docs: ADR-0012 Decision 6 (agent-supervised re-record repair)#1226

Merged
thymikee merged 4 commits into
mainfrom
docs/adr-0012-decision7-repair
Jul 12, 2026
Merged

docs: ADR-0012 Decision 6 (agent-supervised re-record repair)#1226
thymikee merged 4 commits into
mainfrom
docs/adr-0012-decision7-repair

Conversation

@thymikee

@thymikee thymikee commented Jul 12, 2026

Copy link
Copy Markdown
Member

Summary

  • Adds Decision 6: Agent-supervised re-record repair ("heal-by-doing") to ADR-0012 as an addendum decision after "5. Mandatory validation". When a replay diverges on selector drift, the agent performs the failed step's intent with ordinary interactive commands against the fresh blessed @refs the divergence report already hands it, and the CLI emits a healed .ad equal to the session's actual successful execution path — no .ad text editing, no silent similarity-heal.
  • Routing is mechanical (repairHint). The enum is computed daemon-side at divergence time from two inputs the daemon already holds — the recorded targetEvidence annotation and the divergence's own full pre-action capture (the whole tree, not the flat/20-capped screen.refs on the wire) — so only the enum value crosses the wire and the agent never computes it. Defined for all four divergence kinds: selector-missrecord-and-heal/state-repair by recorded-container presence; identity-mismatchcaution; identity-unverifiablemanual; action-failure → same container-presence test (dispatch-thrown selector-miss now surfaces here per PR fix: wrap replay selector-miss as REPLAY_DIVERGENCE (repair-loop regression) #1223); sparse/unavailable capture → manual (fail-safe).
  • Six NORMATIVE protocol rules (R1-R6). R1 arm-from-first-replay; R2 --from-continuation-only; R3 mechanical daemon-side repairHint gating; R4 selector-materialization with a loud fail (non-zero exit, never a swallowed/dropped line) on a bare @ref; R5 recorded-open requirement; R6 repair-run boundary watermark = session.actions.length at invocation, so the healed script serializes only the post-watermark slice and a reused session's earlier actions never pollute it (no fresh session required for the repair).
  • Opt-in via replay --save-script[=<out>]; default output is the <original-stem>.healed.ad sibling; the original is never overwritten without an explicit path. Digest/resume reuses decision 4's live --from/--plan-digest loop unchanged.
  • Makes explicit this is not a reversal of decision 1: decision 1 retired --update's silent auto-rewrite; decision 6 adds an explicit, agent-driven, opt-in re-record.
  • Design content is a faithful transcription of an externally reviewed draft (verdict: SOUND-WITH-FIXES, R1-R5 folded in as normative rules; a follow-up review's two P1 fixes folded in as the daemon-side repairHint framing + the R6 boundary watermark).

Test plan

  • Docs-only change; no code touched.
  • Confirmed repo's lint/format scripts (oxlint/oxfmt) do not cover docs/**, so no markdown lint gate applies.
  • Cross-checked every file:line citation in Decision 6 against current main source.
  • Fresh end-to-end read: decision headings run 1-6; repairHint mapping covers all four kinds + fail-safe; R1-R6 present and mutually consistent (R6 bounds prior-session pollution, R2 bounds within-run re-run duplication); R4 fails loud; no residual "future enhancement / agent-judgment routes" language contradicting R3.

thymikee added 3 commits July 12, 2026 12:39
Adds "heal-by-doing": when replay diverges on selector drift, the agent
performs the failed step's intent with ordinary interactive commands
against blessed refs, and the CLI emits the healed .ad from the session's
actual successful execution path (session.actions) instead of hand-edited
selector text. Folds in five normative protocol rules (R1-R5) from an
external design review (verdict: SOUND-WITH-FIXES) covering record-arming
timing, --from continuation semantics, mechanical repairHint routing, the
writer's bare-@ref fail-close, and the recorded-open requirement. Makes
explicit that this reintroduces an EXPLICIT, opt-in heal and is therefore
consistent with (not a reversal of) decision 1's retirement of --update's
SILENT auto-rewrite.
…ry router

- Rename 'Decision 7' -> 'Decision 6' (ADR has decisions 1-5; new one is the
  6th, placed after 5. Mandatory validation; existing decisions unchanged).
- Reframe the two-sub-flows router: the CLI-computed repairHint (mechanical,
  in-scope, ships with this decision per R3) is the PRIMARY router; the agent
  follows the hint and uses screen.refs only as an ambiguity override, not as
  the default router. Removes the agent-judgment-vs-R3 contradiction.
…-run boundary (R6)

Addresses two P1 review gaps:
- P1-A: state that repairHint is computed daemon-side at divergence time from
  the recorded targetEvidence + the daemon's own full pre-action capture (only
  the enum crosses the wire, so the flat/capped screen.refs never gate routing);
  define repairHint for all four divergence kinds (selector-miss, identity-
  mismatch, identity-unverifiable, action-failure) with the sparse-capture
  fail-safe to manual.
- P1-B: add R6 — --save-script records a boundary watermark (session.actions.
  length at invocation); the healed script serializes only the post-watermark
  slice, so a reused session's earlier actions don't pollute it.
Clarifications: R4 fails loudly (non-zero exit, never swallowed); exact default
output path = <original-stem>.healed.ad sibling; arming sets recordSession AND
the watermark before step 1.
@thymikee thymikee changed the title docs: ADR-0012 Decision 7 (agent-supervised re-record repair) docs: ADR-0012 Decision 6 (agent-supervised re-record repair) Jul 12, 2026
@thymikee

Copy link
Copy Markdown
Member Author

Re-review at 2a33e38: R6 resolves prior-session pollution, and R4 and default output behavior are now explicit. Remaining protocol blockers:

  1. Add repairHint to Decision 4 normative details.divergence wire field list, define its enum and bounding behavior, and state that it survives text, JSON, client, and MCP projection.
  2. Make R3 total when action-failure has no targetEvidence. PR fix: wrap replay selector-miss as REPLAY_DIVERGENCE (repair-loop regression) #1223 explicitly covers unannotated actions. Use fail-safe manual or scope heal-by-doing to annotated scripts.
  3. Correct the capture wording: target-binding divergence has a pre-action capture, but ordinary action-failure currently captures after the failed response. Either specify that distinction or require storing a pre-action tree.

Not ready yet. No fixer dispatched.

Addresses three protocol blockers:
- Blocker 1: add repairHint to Decision 4's details.divergence field list and
  spec it as a single bounded enum (record-and-heal|state-repair|caution|manual),
  present on every divergence, carried at every level, surviving all four
  projections (text/JSON/client/MCP).
- Blocker 2: make R3's mapping total — no recorded targetEvidence (reachable for
  unannotated action-failure per #1223, or any kind on a legacy script) => manual,
  generalizing the sparse-capture fail-safe.
- Blocker 3: correct capture-timing — target-binding kinds use their PRE-action
  tree; action-failure uses its POST-response tree (adequate for the container
  presence test); no new pre-action tree is stored for action-failure.
Validation extended for the projection-survival and no-evidence/post-response cases.
@thymikee thymikee merged commit e61edf7 into main Jul 12, 2026
5 checks passed
@thymikee thymikee deleted the docs/adr-0012-decision7-repair branch July 12, 2026 12:28
@github-actions

Copy link
Copy Markdown
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-07-12 12:28 UTC

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