fix(daemon): reject unsupported raw --save-script flags at request ingress (#1501)

* fix(daemon): reject unsupported raw --save-script flags at request ingress

`flags.saveScript` arms session-script publication the moment a successful
handler records the request's action, so any recordable command reaching a
handler with the raw flag set could arm publication and write a `.ad`
artifact — `record stop` immediately through record-only cleanup, `trace` and
the interaction commands later on close. The CLI/Node/MCP surfaces only emit
the flag for its released owners, so that arming path was reachable only by a
hand-built wire request or a free-form `batch` step.

Close it at the daemon request seam (`createRequestHandler`), the single entry
point both the socket and HTTP transports funnel through, and ahead of
admission, session lookup, device resolution, and handler dispatch. Ownership
is declared on the command descriptor (`saveScriptFlagOwner`) rather than
re-stated as a string set, so `open`, `close`, and `replay` keep the flag and
everything else is rejected with an ADR 0010 shaped `INVALID_ARGS` carrying a
hint, diagnosticId, and logPath.

With that path pinned closed, a record-only session can no longer carry
`recordSession`, so `record stop`'s immediate `writeSessionLog` could only ever
be a no-op; delete it.

Refs #1478.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RXQLYV7etZx3gcXsUsrQJ8

* test(daemon): assert ADR 0010 diagnostics on save-script rejection

The HTTP test helper projected only code/message/hint, so `diagnosticId`
and `logPath` could regress while the transport tests stayed green.
Preserve both in the helper and assert on each transport that
`diagnosticId` is present, `logPath` is present and exists, and the log
records `save_script_flag_rejected`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RXQLYV7etZx3gcXsUsrQJ8

---------

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Michał Pierzchała
2026-07-30 18:10:50 +02:00
committed by GitHub
parent 0ee2a86129
commit 3c09bb2566
8 changed files with 466 additions and 6 deletions
+1
View File
@@ -2,6 +2,7 @@
## Unreleased
- `--save-script` is now accepted only by the commands that declare it — `open`, `close`, and `replay`. A hand-built daemon request (or a `batch` step) that set `saveScript` on any other command, such as `record` or `trace`, used to arm script publication and could write a `.ad` artifact; it is now rejected with `INVALID_ARGS` before the request reaches admission, the device, or any handler. CLI, Node, and MCP usage of `--save-script` on its documented commands is unchanged.
- `diff screenshot` no longer runs the retired best-effort OCR and non-text analyzers. Their optional `ocr` and `nonTextDeltas` fields remain in the result type for source compatibility but are no longer emitted; use the baseline/current images and diff artifact with vision for qualitative interpretation.
- Breaking: removed the deprecated `--session-locked` and `--session-lock-conflicts` flags. Use `--session-lock reject|strip` instead; passing either old flag now fails with `Unknown flag: ... Use --session-lock reject|strip instead.`
- Breaking: removed the `replay export --format` flag. `replay export` always writes Maestro YAML.