Skip to content

record-and-heal: armed --save-script repair records the agent's read-only diagnostics into the healed script (can introduce new divergences) #1271

Closed

Description

@thymikee

Summary

During an armed --save-script record-and-heal repair segment, the agent's read-only diagnostic
commands
(snapshot -i, get attrs, find, is) are recorded into the healed script alongside the
corrective actions. This pollutes the healed artifact, and in one measured case a recorded diagnostic
introduced a new, self-inflicted divergence on fresh replay.

Found in the wave-3 E3 repair-economics experiment (single-field-rename drift on iOS test-app).

Evidence

Two independent sonnet trials both used the documented --save-script/--from heal-by-doing flow
correctly, and both still required a manual .ad edit afterward solely to remove recorded diagnostics:

  • sonnet-1: three extraneous get attrs … steps (from triage inspection) were captured into the healed
    script; harmless but not part of the flow — hand-removed.
  • sonnet-2: a get attrs @e13 run during triage was captured; on a fresh replay its recorded
    ancestry did not hold
    and it caused a second divergence (identity-mismatch: recorded ancestry
    scrollview/"Checkout form" vs observed other/"Legal name"). Hand-removed to finalize.

Net: across all 4 E3 trials, 0 produced a clean healed script hands-off — the flow foot-guns even the
agent that follows it. --no-record exists but neither agent discovered it for reads mid-repair.

Why it matters

The record-and-heal flow's value is a clean, replayable healed script produced without hand-editing. Today
it doesn't deliver that: an agent that inspects the screen to find the corrected target (the expected
behavior) pollutes its own output, and the pollution can be worse than cosmetic (a recorded read can carry
state-dependent identity that re-diverges).

Design options (maintainer call — not a silent patch)

  1. Cheap / hint-layer: the divergence repairHint text (and help workflow) should teach that
    inspections during an armed repair must use --no-record. Zero behavior change; just stops the agent
    foot-gunning itself. Aligns with "tune the hint, not the design."
  2. Real / ADR-0012 decision-6 amendment: decide whether read-only commands (snapshot/get/is/
    find) recorded inside a repair segment should default out of the healed script (they never mutate
    state, so they're arguably diagnostics by definition, not flow steps). This changes what the heal
    transaction commits and is a semantic decision about the record-and-heal contract — hence an ADR
    amendment, not a patch.

Option 2 is the more complete fix; option 1 is a safe interim. A related sub-finding worth its own look:
the sonnet-2 case is also a state-dependent-identity data point on iOS (a field's recorded ancestry
differed between mid-repair and fresh replay) — in mild tension with the E1 iOS FDR-0 result, whose flows
didn't contain a get-on-a-just-interacted-field step. Worth an autopsy (filled vs focused vs scroll state).

Activity

  1. thymikee commented on Jul 15, 2026

    @thymikee
    MemberAuthor

    Maintainer triage: this is a record-and-heal contract decision, so needs-triage is intentional and it should not be assigned as an AFK implementation yet.

    Recommended two-stage handling:

    1. Safe interim: update the divergence repairHint and help workflow to say that read-only diagnostics during an armed repair must use --no-record. Add a focused command-planning/SkillGym regression so agents discover this without hand-editing the healed script.
    2. Semantic fix: amend ADR 0012 before changing defaults. The amendment must define which read-only commands are excluded from a repair transaction, whether explicit recording remains possible, and how the rule projects across CLI/Node/MCP surfaces. Regression coverage should prove that diagnostic reads are omitted while corrective actions remain, and that the resulting healed script replays cleanly.

    The interim guidance is low risk and independently useful. Default exclusion is the more complete behavior, but it should not ship as an undocumented recording-contract change.

  2. thymikee commented on Jul 16, 2026

    @thymikee
    MemberAuthor

    Stage 1 shipped in #1287 (merged). This issue stays open to track stage 2.

    What landed:

    • The divergence repairHint now appends a diagnostics clause — "Read-only inspection while armed (snapshot -i, get attrs, find, is) is recorded too — use --no-record on those commands or they will land in the healed script." — gated strictly on resume.repairSessionHeld === true, so it renders only on divergences from a repair-armed (--save-script) replay and is silent otherwise.
    • Same guidance added to help workflow's heal-by-doing section (distinct from the pre-existing --no-record mentions, which are about fixing app state, not inspection reads).
    • Regressions: 12 unit tests (clause present iff armed, across record-and-heal/state-repair/caution/manual) + a SkillGym case. The SkillGym case was live-validated: with a facts-only contract it reproduced the bug (haiku emitted unrecorded get attrs reads); with the clause present it passed 3/3 across haiku and codex-mini. So the guidance demonstrably changes agent behavior — which was the point of the interim stage.

    No recording behavior or defaults were changed.


    Stage 2 — still open, still ADR-gated

    Per the triage, the ADR-0012 amendment must define: (1) which read-only commands are excluded from a repair transaction, (2) whether explicit recording remains possible (and how it's requested), (3) how the rule projects across CLI / Node / MCP surfaces — with regression coverage proving diagnostic reads are omitted while corrective actions remain, and that the healed script replays cleanly.

    One design wrinkle worth capturing before the amendment is drafted: "read-only" is not a clean discriminator on its own. A corrective action can itself be a read — in the wave-3 E3 drift the diverged step was a get, so the corrective step is a recorded get that must land in the heal. A blanket "exclude reads from a repair segment" would silently drop it and produce a heal missing the very step it repaired. The amendment therefore needs to separate "the read that replaces the diverged step" from "reads used to locate the target" — e.g. by position relative to the resume, or an explicit opt-in — rather than excluding by command class alone.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    in-progressWork is actively in progressneeds-triageNew or unreviewed issue

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions