Repository navigation
refactor(commands): declare project-config admission and recorder sanitization on the flag declaration #2445
Copy link
Copy link
Closed
Labels
Description
Wave 2 child of #2409. The "#1665-shaped follow-up" named in PR #2421; hops A11 and A18 in the #2410 hop trace.
Purpose
A flag that may be set from agent-device.json, or that the session recorder may copy into SessionAction.flags, is declared once, on its flag declaration. Today each property is a separate hand-maintained allowlist, fail-closed by omission, so adding a flag that needs either behaviour edits the allowlist file as well.
Baseline
On main at 41e2633f10:
PROJECT_CONFIG_FLAG_KEYS: module-privateSet<FlagKey>of 85 keys atsrc/cli-schema/cli-config.ts:37. One consumer at:219rejects any project-config key outside the set withINVALID_ARGS.SANITIZED_FLAG_KEYS: module-private tuple of 39 keys (33 literals plusSCREENSHOT_ACTION_FLAG_KEYSfrompackages/contracts/src/screenshot.ts:81) atsrc/daemon/session-action-recorder.ts:360. One consumer,sanitizeFlagsat:397, copies only these keys into the recorded action.- Flag declarations: 156 across
src/commands/cli-grammar/flag-definitions-{action,connection,target,workflow}.ts(39 / 38 / 44 / 35), typed byFlagDefinitionatsrc/commands/cli-grammar/flag-types.ts:19. refactor(commands): declare a command option once and derive its surfaces #2421 addedinputDescriptionthere and derived the command input field from it. - No test pins membership of either set. A flag omitted from either set is silently rejected or dropped.
- The refactor(commands): declare a command option once; derive cli-schema, MCP schema and daemon flags from the descriptor #2410 hop trace classifies both sets as "fail-closed by omission, so they must move onto the option declaration as explicit fields, never be inferred from a flag's existence".
- Replay of feat(ios): expose AX custom actions on merged accessibility elements #1665 (
snapshotCustomActions): the change edited both sets in addition to the declaration.
Required work
- Add two required fields to
FlagDefinition:projectConfig: boolean(may be set fromagent-device.json) andrecorded: boolean(copied intoSessionAction.flags). Required, not optional. Omission must be a type error, so the fail-closed property is held by the compiler instead of by a list. - Populate the 156 declarations from the current sets exactly (85 true / 71 false; 39 true / 117 false). Mechanical.
- Derive:
cli-config.ts:219andsanitizeFlagsread the sets derived from the declarations. Delete the two literal sets.SCREENSHOT_ACTION_FLAG_KEYSstays whilescreenshot-options.test.tsstill consumes it. - Planted divergence test, per the refactor(commands): declare a command option once and derive its surfaces #2421 pattern (
src/commands/command-input-option-field.test.ts): flippingrecordedorprojectConfigon one declaration changes the corresponding admission or sanitization outcome, observed through the production derivation.
Acceptance, measurable from git
- Re-doing feat(ios): expose AX custom actions on merged accessibility elements #1665's flag addition edits the declaration (with both fields) and no allowlist.
src/cli-schema/cli-config.tsandsrc/daemon/session-action-recorder.tsare untouched by the replay. - The derived sets equal the deleted sets: the PR records the one-off diff (empty) and the existing project-config and recorder tests stay green with no edits.
- A flag declaration without both fields does not compile.
Non-goals
- Inferring either property from a flag's existence, type or command. Rejected in the trace.
CONFIG_EXCLUDED_FLAG_KEYS(6 keys) andENV_EXCLUDED_FLAG_KEYS(2 keys) atsrc/cli-schema/option-schema.ts:21and:30. These are fail-open exclusions with a different safety property. Fold them in only if the same PR shows the same fail-closed guarantee for them; otherwise leave them.- Per-command
allowedFlags(36 sites): per-command admission, not collapsible (trace A3).
Dependencies
None. Builds on #2421 (ad79461c72).
Reactions are currently unavailable
Activity
refactor(commands): return the recorded keys as a set, matching proje…
refactor(commands): declare project-config admission and recorder san…
refactor(commands): return the recorded keys as a set, matching proje…
fix(commands): keep the CommandFlags guard on recorded flag declarations
refactor(commands): declare project-config admission and recorder san…