docs: ADR for interactive replay and resolution disclosure - #1177
Conversation
… retiring --update healing Records the decision to retire --update healing as a silent actor (repurposing its candidate machinery as ranked suggestions), disclose selector disambiguation in every interaction response, verify replay steps against record-time identity evidence, and add an interactive replay --from loop with a structured divergence report for all callers.
…ce for --from Adds hands-on evidence from driving replay on the RN playground (silent text-mode success, app-state divergence heal cannot fix, Maestro step-index shift from runFlow flattening, per-format hint/code inconsistency, recordings carrying zero observation steps), makes step provenance (source file + line, including through Maestro runFlow inlining) a requirement of the divergence report plus an optional replay --list-steps dry-run, and adds a one-line text-mode success summary as decision 4d.
|
Architecture review of P1 - "every interaction response" conflicts with the accepted direct iOS path. Decisions 2-3 (ADR lines 111-131) assume daemon-side P1 - the structured divergence report does not fit the current failure wire path. Lines 138-156 require actionable refs on a failed replay for all callers. Today replay enriches P1 - recorded identity is not a specified backward-compatible contract. Lines 125-131 name id/role/label/rect but do not define grammar, escaping, optionality, normalization, or comparison semantics. Exact rect equality would create false divergences from layout/device/window drift, while restricting verification to ambiguous resolutions still permits a unique-but-wrong rebind. Also line 192 says this is not a format change while line 225 calls it one. Specify the plain-text representation and parser/writer round trip, old-reader/new-script and new-reader/old-script behavior, field stability/tolerance, and whether every resolved replay target is verified. This is target-binding verification, not general outcome verification. P2 - Before acceptance, validation should require focused unit/provider/MCP contracts for direct-iOS behavior, typed disambiguation payload and tie cases, identity round trips/backward compatibility, mismatch-before-action behavior, divergence error/ref propagation, response caps, |
|
Re-review of
Please extend mandatory validation for these cases. The revised direct-iOS provenance, additive |
|
Final re-review of The second-pass findings are resolved with enforceable contracts: resolution alternatives are bounded pre-action diagnostics rather than reusable refs; duplicate target evidence is structurally scoped and fails closed as unverifiable; All five docs-only checks pass. No device evidence is required for this proposed design-only ADR. Ready for maintainer judgment. |
|
Follow-up on the latest ADR: changing One substantive issue remains in the Non-blocking cleanup: make the benchmark/audit evidence durable and quantitative instead of pointing at Otherwise the ADR is strong: the six-path classification, direct-iOS honesty, actionable-ref separation, bounded/redacted divergence contract, and conservative resume preflight are well specified. |
…unt, define matching algorithm Reworks the target-v1 contract per review: identity is recorded id, else role + normalized label, plus a leaf-anchored ancestry prefix (K=8, nearest ancestors kept, root-side truncation only); absolute rects are demoted to never-compared diagnostics with the ±8 tolerance removed rather than tuned; duplicates disambiguate by recorded sibling order among the matching set, then viewport-relative order within the recorded scroll region — never absolute pixels; ties are identity-unverifiable divergences with candidates listed. matchCount is redefined as the replay-time recorded-selector match count (0..N, always present), with selector-miss (0) and identity-mismatch (>=1, no identity candidate) as distinct classes in an explicit six-path verification classification. Also inlines the quantitative benchmark numbers (3.67->1.00 snapshots, 14.3 vs 23.3/26.7 commands, 38/38 in 539s) so the evidence is durable without the external harness directory.
|
Addressed the 2026-07-10 08:30Z review in 1. 2. 3. Exact matching/truncation algorithm. Now numbered and parameterized in decision 3: local identity = both carry Non-blocking (a): the key benchmark numbers are inlined in the ADR's evidence section as a table (snapshots/interaction 3.67 → 1.00; commands per task 14.3 vs 23.3/26.7; 38/38 Maestro flows in 539 s at zero model turns), so the evidence no longer depends on the external harness directory. The identical-rect sibling repro was already inline in audit item (b). Non-blocking (b): the PR description is aligned with what the ADR actually commits to: resume requires both Validation section updated to match: the six verification paths (including out-of-range ordinals and |
…ord and replay Fixes the P1 domain mismatch: sibling becomes a genuine same-parent child index (parent already captured as ancestry[0], no new field; identical by definition on both sides, non-isolating when the same index recurs under different parents); viewportOrder gets one region-scoped domain — the identity set partitioned by scroll region, ordinal within the recorded partition on both sides, unavailable (never compared cross-region) when the recorded region no longer exists; document order (pre-order index) is the canonical total order making every ordering deterministic, including equal rect centers. Residual ties stay identity-unverifiable with candidates listed. Record-time write, replay verification, and mandatory validation updated in lockstep; the six-path classification is unchanged.
|
Addressed the remaining P1 (positional signals used different candidate sets at record vs replay) in Different ordinal domains for
No deterministic final tie-break for equal rect centers → document order. A node's pre-order tree-traversal index is now the contract's canonical total order: equal rect centers, rect-less members, candidate enumeration, and candidate listing all resolve by document order, so every comparison in the chain identity → sibling → region-scoped viewportOrder → document order is total. A residual tie would require two nodes at identical positions in an identical tree — impossible under pre-order indexing — and the ADR states explicitly that even that residual case remains the identity-unverifiable divergence path with candidates listed, never a silent pick. Document order is an ordering tie-break, not a selection signal: exhausted/unavailable signals still end in identity-unverifiable, preserving the never-silent-pick invariant. Lockstep updates. Record-time write (steps renumbered, partition definition added), replay path 6 (both signals restated over the shared domains), the three-tier signal description, and the mandatory validation bullet (same-index-different-parents, record/replay domain parity, region-gone unavailability, out-of-range ordinals, document-order determinism) all describe the same candidate sets. The six-path classification is unchanged — only the internals of path 6 tightened. One consequence of the redefinition, now stated in the ADR: because both ordinals are computed from the winner over deterministic total orders, the record-time self-check succeeds by construction whenever the capture supplies the structural data, so One deliberate interpretation choice, flagged for visibility: the region-partitioned candidate base is the identity set (local identity + leaf-anchored ancestry prefix), not bare local identity — using bare local identity at replay would have introduced a fresh record/replay domain asymmetry of exactly the kind this fix removes. PR description updated to match the tightened signal definitions. |
… writer invariant, suggestion ranking contract
|
Addressed the four remaining items in 054682a (the previous worker session was interrupted mid-edit; this commit completes and extends its partial work): P1 — matchCount on the recorded-unverifiable path: optional, key omitted (never null) exactly and only on path 1, which fires before any resolution; required 0..N on paths 2–6. No diagnostic-only resolution was added — a recorded-unverifiable annotation means there is no trustworthy recorded identity to resolve against, so a count there would invite misreading. The presence rule is stated once in decision 3 and mirrored verbatim in decision 4's wire contract. P1 — migration dependency inversion: reordered into seven dependency-explicit slices. Divergence transport (report-only, P2 — writer overflow: writer-parser invariant added — the recorder must never emit a payload its own parser rejects; deterministic root-side ancestry reduction until the 4 KiB ceiling fits; fail-closed downgrade to P2 — ranking contract: decision 1 now defines a total order (identity-component strength > same scrollRegion > document order) with node-level dedup tagged by strongest match basis; digest level omits suggestion entries but carries One additional fix from a holistic pass: the interim state of the P1 edit had introduced a decision-3/decision-4 contradiction — the wire contract still said |
|
Summary
Adds ADR 0012 documenting a decision set that emerged from several maintainer discussions, grounded in this week's benchmark and audit findings on
.adreplay plus live hands-on replay sessions on the RN playground (iOS sim, both.adand Maestro paths). Key quantitative evidence is inlined in the ADR (snapshots/interaction 3.67→1.00 with--settle, 14.3 vs 23.3/26.7 commands per task, 38/38 Maestro flows replayed in 539 s with zero model turns):--updatehealing as a silent actor. With an agent in the loop, a heal proposal costs one cheap turn to adjudicate — repurpose the existing candidate machinery (collectReplaySelectorCandidates, chain re-resolution) as ranked suggestions in the divergence report;--updatenever rewrites the script.resolutionfield carries match count, winner, tiebreak reason, and at most 5 pre-action (non-actionable, non-pinned) alternatives on the runtime path; the direct-iOS fast path honestly reportsnot-observed; all six ADR 0011 dispatch paths get honestresolutionDisclosurecells..adtarget-binding evidence (target-v1): identity is the recordedid(else normalized role+label) plus a leaf-anchored ancestry prefix (K=8, root-side truncation only); duplicates disambiguate by a genuine same-parentsiblingchild index, thenviewportOrderscoped to the recorded scroll-region partition (one candidate domain at record and replay; unavailable regions never compared cross-region), with document order as the final deterministic tie-break — absolute geometry is demoted to never-compared diagnostics (no ±px tolerance). Replay classifies every annotated step through an exact six-path verification —matchCount(recorded-selector matches at replay, 0..N, always present) separates selector-miss (0) from identity-mismatch (≥1, no identity candidate); residual ties fail closed as identity-unverifiable with candidates listed, never a silent pick.REPLAY_DIVERGENCEerror preserved end-to-end (CLI/JSON/MCP, with error-path ref pinning), bounded and redacted per response level with overflow artifacts, step provenance (source file + line through MaestrorunFlowflattening), and areplay-only resume requiring both--from <step>and--plan-digest <sha>from the report, with conservative variable/control-flow preflight rejection. Successful text replay prints a one-line summary.--updateno-write — the settle-benchmark replay arm (clean replay + one induced divergence) measures the economics only after those contracts pass.Also adds the ADR to the
docs/adr/README.mdindex.This is a design-only ADR — no implementation changes are included. Every claim was verified against the current codebase (exact file/line citations throughout).
Test plan
git diffreviewed — docs-only change (new ADR file + README index row)pnpm lint/check:*only coversrc/test/config files), so nothing to run