fix(fill): redact the read-back of a sensitive fill

Merged
TH
2d ago
+402-19

Summary

A sensitive fill (--text-stdin, --record-as) redacted only the exact literal, so altered read-back forms still came back. Fixes #3392.

  • Success: an unconfirmed fill's requested, before and after become the redaction placeholder. Read-back is redacted before literal scrubbing, and the verification, target and read-back keys are structural, so a short literal such as a cannot rewrite them.
  • Settle (contract change): with --settle, a sensitive fill's diff line text and tail labels are replaced whole by the placeholder, in the response and in the recorded result. Structured refs, counts and summaries stay, and the CLI formatter leads an added line whose text lost its ref prefix with the pinned @eN~s<gen> ref. Text around the value inside that field (prefix…suffix) is no longer shown. This is not scoped to the filled element: removed lines carry no ref, so scoping would need matching.
  • Error: Android fill-failure details.expected, actual and the observed input text are replaced, including for an empty sensitive value (typed by failureReason).
  • iOS runner: TEXT_ENTRY_MISMATCH message is text entry read-back did not match the requested text, with the same code and hint. The runner cannot know a fill is sensitive, so no typed detail values were added.
  • Other backends return no read-back text. Out of scope: #3261.
  • 14 files; CLI help, commands.md and a patch changeset updated.

Validation

  • Tested SHA: cf2b1a21ae. pnpm check:affected --run --head cf2b1a21ae: all runnable checks passed, exactCommit=true.
  • Regressions failed on 5f96199 before each fix: short literal, discriminator collision, settle text, empty value. They pass now.
  • test/integration/provider-scenarios/active-session-script-publication.test.ts updated to the settle contract; it passes under --project provider-integration.
  • Swift runner tests pass on iPhone Air (1B89356B) with an exact-message assertion.
  • CLI formatter regression (fill CLI output) failed before the formatter fix. MCP pins refs from the structured ref, so only the CLI text path changed.
  • The read-back helpers live in parameterized-recorded-fill.ts, which both callers already load, so the daemon eager closure does not grow (eager-closure-budgets passes).
  • Unverified: remote CI at the new head.

🤖 Generated with Claude Code