mirror of
https://github.com/callstack/agent-device.git
synced 2026-09-14 20:06:34 +08:00
480e3883b1
* fix(daemon): reject unarmed close --save-script before teardown Live evidence (2026-08-02) showed a plain `open` followed by `close --save-script` silently published a script: the close request armed authoring at record time and published moments later in the same request, folding the never-armed case into the ADR 0016 authoring lifecycle. The resulting .ad carries selector fallback chains but no recording-time target-v1 evidence, and nothing told the caller evidence capture never ran — degraded replay verification with no signal beats a loud refusal. `assertTerminalRecordingCloseAllowed` (src/daemon/handlers/session-close.ts) now rejects an unarmed `close --save-script` with INVALID_ARGS before any teardown or filesystem work runs, the same seam that already rejected ABORTED/PUBLISHED terminal recordings. The rejection does not tear the session down, so a plain `close` retry still completes cleanly; recovery names `open --save-script` since evidence can only be captured from action zero. Repair transactions (ADR 0012) are a disjoint lifecycle and are explicitly unaffected. This is distinct from #1533 (an already-armed-then-aborted session whose flag ingress re-enables recordSession and lets a *bare* close publish); that case remains open. * fix: review follow-ups for #1558 (help text, test strength, docs) - Give replay --save-script its own help text instead of the shared open/close "arm on open, publish on close" description: replay's flag arms an ADR 0012 repair transaction, a disjoint lifecycle. Adds CommandSchema.flagDescriptionOverrides so a command can swap a shared flag's usageDescription without duplicating the FlagDefinition entry (which would have shown --save-script twice in `help replay`). Pinned in src/cli/parser/__tests__/cli-help-command-usage.test.ts (open/close keep the shared text unchanged; replay gets the new one). - Strengthen the never-armed close --save-script regression test in session-close-shutdown.test.ts: the fixture now carries real cleanup-bearing state (an active iOS simulator recording, reusing makeIosSimulatorRecordingSession/recordingKillMock) with spies proving no teardown hook (recorder kill, runner stop) runs on the rejected request, then that a follow-up plain close does tear it down. The prior fixture had nothing for teardown to observably touch, so moving the guard after stopBestEffortSessionResources would have passed it silently. Also fixes a latent test-isolation leak this exposed: an earlier test set a persistent mockStopIosRunnerSession rejection (vi.clearAllMocks() clears call history, not implementations), which would have poisoned any later Apple-platform close test; scoped it to mockRejectedValueOnce. - Point the migration guide (website/docs/docs/migrating-gestures.md) at `open --save-script` → interact → `close` instead of the now-rejected `open` → interact → `close --save-script`, matching the new guard and the corrected help text. _Generated by [Claude Code](https://claude.ai/code)_
ADR index — read this when…
| ADR | Read when you touch… |
|---|---|
| 0001 Provider-First Integration Scenarios | integration testing strategy, provider transcripts, the scenario harness |
| 0002 Persistent Platform Helper Sessions | helper process lifecycle, keep-alive semantics |
| 0003 Daemon Command Registry | daemon routing, request-policy traits |
| 0004 iOS Snapshot Backend Strategy | snapshot capture plans, backend fallbacks, quality verdicts |
| 0005 iOS Runner Interaction Lifecycle | XCTest runner sessions, leases, adoption, idle-stop |
| 0006 Daemon RPC Protocol Version | remote daemon HTTP/JSON-RPC compatibility |
| 0007 Remote Device Leases | leases, tenancy, provider-owned devices |
| 0008 Command Descriptor Registry | adding/changing a command, any surface projection (CLI/MCP/client/batch), timeout policy |
| 0009 Apple Platform Consolidation | Apple platform family, apple/appleOs axes, the apple-leak guard |
| 0010 Error system conventions | error codes, hints, normalizeError, typed error signals |
| 0011 Interaction Guarantee Contract | interaction dispatch paths, fast paths, guards, the guarantee matrix, parity tables |
| 0012 Interactive Replay | replay healing/--update, diagnostic resolution disclosure, bounded .ad target-binding evidence, bounded divergence wire/error handling, plan-bound replay-only --from semantics, and agent-supervised re-record repair ("heal-by-doing") |
| 0013 Unified Gesture Plans | gesture API/routing, contact topology, multi-touch geometry, native pointer injection, two-finger pan |
| 0014 Session Ref-Frame Lifetime | ref authorization epochs, complete/partial issuance, pre-side-effect expiration, replay/batch compatibility, and cross-platform stale-mutation policy |
| 0015 Direct Maestro Compatibility Engine | Maestro YAML parsing/execution, compatibility observation policy, conformance, performance gates, gesture integration |
| 0016 Active-Session Script Publication | publishing an armed open-to-destination .ad script without closing its live session |
| 0017 Parameterized Recorded Inputs | safely authoring sensitive fill inputs as ${VAR} placeholders across recording, replay, and repair |
ADRs record why; the registries and gates they describe are the living source of truth — when prose and a registry disagree, the registry wins and the ADR needs a follow-up.
Shape conventions, so consulting an ADR stays cheap:
- Normative rules first, terse. Status, then a "Rules at a glance" summary a reader can stop after; full contracts and rationale below it.
- Rationale and refuted alternatives stay in the ADR — they are what stops re-litigating settled ideas — but below the fold.
- Process history is deleted once complete, not archived in-file. Migration plans, per-step landing tables, and point-in-time status change-logs go to git history; the Status section keeps one line saying so plus any accepted, still-relevant waiver or evidence gap.
- Once a rule is gate-enforced, the ADR keeps the why and points at the gate rather than restating the rule's details.