docs: align snapshot fallback and actions guidance - #1713
Conversation
The snapshot guide claimed a zero-node XCTest result fails without ever
switching to AX, but regular iOS capture has an explicit recursive-tree →
query-sweep → private-AX recovery plan (ADR 0004,
RunnerTests+SnapshotCapturePlan.swift). The public CLI also exposes
`--actions`, `--force-full`, and `--timeout`, while both website reference
pages published a three-flag snapshot usage line.
- Add a schema-derived gate: `commands.md` must publish the exact usage
`buildCommandUsage('snapshot', getCliCommandSchema('snapshot'))` produces,
so the canonical invocation cannot drift from the command schema again. The
flag list is never restated in the test. Proven red against the pre-fix
`commands.md`.
- Extract the fence walker both doc checks now share, and prove the new gate
fails on a planted usage drift.
- Publish the canonical snapshot usage in the command reference and describe
`--actions` as iOS-simulator-only and planning-only.
- Replace the "Backends (iOS)" list with an iOS capture behavior section
written from ADR 0004 and the live capture plan: regular visible strategy
with a bounded recovery ladder, raw diagnostic strategy preserving strict
capture failures, and recovered/sparse/degraded output staying observable
through quality warnings. Capture tiers are documented as internal, not as
user-selectable backends.
Custom-action discovery stays separate from invocation: the runner can read
names but cannot trigger them (RunnerAXSnapshotBridge.h), so neither page
implies otherwise.
Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_014VzyMim5q4jbp1xDMm3jVo
|
Size Report
Startup median (7 runs, lower is better):
Top changed chunks: no changes in the largest emitted chunks. |
|
Exact-head review at |
Both pages described the combination as a silent no-op ("returns a raw
tree without them"), which cannot happen: `customActionFlagsResponse` in
src/daemon/request-router.ts rejects `snapshotCustomActions` + `snapshotRaw`
with INVALID_ARGS at the shared request seam, before any session or device
work, so CLI, Node client, and MCP all get the same answer. Pinned by
src/daemon/__tests__/request-router-custom-action-flags.test.ts.
The underlying reason was right and is kept — custom actions are only
readable through the private-AX capture path, which the raw diagnostic
strategy does not take — but the user-visible outcome is a rejection, not a
degraded capture, so both pages now say to choose one flag or the other.
Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_014VzyMim5q4jbp1xDMm3jVo
|
You're right, and thanks for catching it — fixed in I'd searched for the guard and concluded no rejection existed. My grep was scoped to Both pages now say the pair is rejected as
Generated by Claude Code |
|
Exact-head re-review at |
Summary
Two website pages described
snapshotin ways that no longer match the shipped command, so an agent reading them would misdiagnose a recovered capture and never discover--actions.Snapshot guide claimed regular iOS capture never falls back:
Regular capture actually runs a bounded
recursiveTree → querySweep → privateAXrecovery ladder (regularVisiblePlaninRunnerTests+SnapshotCapturePlan.swift, per ADR 0004). The page now has an iOS capture behavior section written from the accepted decision and the live plan: the regular visible strategy recovers through the ladder when XCTest returns sparse output; the ladder is bounded by the capture budget; recovered/sparse results stay observable through quality warnings and--jsonsnapshotQualityrather than being presented as an empty UI;--rawselects the raw diagnostic strategy, which stays tree-first and preserves strict capture failures. Private-AX recovery and custom-action reads are documented as simulator-specific — physical devices bound the XCTest work with a probe instead. Capture tiers are described as internal, not as user-selectable backends (the oldxctest/ax"Backends (iOS)" list read like a choice; it isn't one).Command reference published a three-flag usage line while the CLI has grown three more flags:
--actionsis now documented on both pages as iOS-simulator-only and planning-only. It names the affordances an element merged away (UIAccessibilityCustomAction, React NativeaccessibilityActions) so a card whose reply/options controls are not separate elements still lists them — but there is no API to trigger one, so the docs route readers to the detail screen, an equivalent labeled element, or coordinates from the rect. The guide also records the per-element accessibility round trip, the partial-coverage disclosure, and that--actionsis mutually exclusive with--raw:customActionFlagsResponseinsrc/daemon/request-router.tsrejects the pair asINVALID_ARGSat the shared request seam, before any session or device work, so CLI, Node client, and MCP all give the same answer.To stop the usage line drifting a third time,
src/__tests__/command-doc-coverage.test.tsgains a schema-derived gate:commands.mdmust publish exactly whatbuildCommandUsage('snapshot', getCliCommandSchema('snapshot'))returns. The flag list is never restated in the test — the schema stays the single source of truth, so adding asnapshotflag fails the gate until the reference is updated. The fence walker the existing token checks already used is extracted so both checks parse code blocks one way.Closes #1689
Validation
Docs-only for behavior — no runtime, CLI, grammar, ADR, or runner code changed, so there is no device-facing path to verify on a simulator; the two prose pages are checked against ADR 0004, the live
regularVisiblePlan/rawDiagnosticPlan, the request-router flag guard, and the--actionsfield description rather than against a device.The new gate was proven red before the docs edit, failing as
command reference doc coverage > commands.md publishes the canonical snapshot CLI usageand naming the missing line verbatim; it passes after. A companion test plants a drifted usage line to prove the gate can still fail.check:affectedselected format, lint, typecheck, fallow, and the related-vitest run — all green — and the Rspress site builds clean.Two notes for the reviewer:
commands.mdas changed since13bc70f24, but the drift is confined to the HarmonyOS, install, and cloud sections; every in-scope excerpt still matched live code, so this was not treated as a stop.website/doc_build/is not gitignored, sopnpm --dir website buildleaves ~2,300 untracked generated files in the worktree.check:affectedfolds untracked files into its change set, so the build output failsformat:checkon a clean tree and makes the gate unrunnable until the directory is deleted by hand. I removed the output rather than adding an ignore rule, since.gitignoreis outside this change's scope — but the missing entry looks worth a follow-up.3 files changed; scope stayed within the two website pages and their gate.