Request schema accepts source and attachment strings the runtime rejects, so schema-valid requests can still fail as malformed #178

Closed
opened 2026-09-07 15:45:15 +09:00 by natsukium · 2 comments
Owner

SessionsCaptureParams.source is typed as a bare Option<String> in the published schema, but crates/felis-cli/src/cli_bridge.rs:1291-1295 (and :1977-1981) requires it to parse via crate::cli_sessions::parse_region_source, which accepts only a fixed small set of values and otherwise returns BridgeError::malformed. Similarly SessionsSwitchParams.attachment is a bare Option<String> though the runtime table at cli_bridge.rs:754 and its consumer only accept specific attachment tokens.

A client can therefore construct a request that validates cleanly against the published bundle and still receives malformed_request from the live bridge: the published schema promises more than the runtime honors.

Correction: add the source enum's known values (or an equivalent pattern/enum for attachment) to the schema, or explicitly document in the schema description that the request schema is structural-only and does not encode these semantic value constraints.

Reason deferred from #29: acceptance criterion 2 names only invalid ids, unknown fields, and out-of-range integers as required fixture coverage. Semantic enum-value validation for these string params is additional hardening beyond that criterion, and it would fall out naturally from the already-deferred per-op typed-params refactor.

Split from #29.

`SessionsCaptureParams.source` is typed as a bare `Option<String>` in the published schema, but `crates/felis-cli/src/cli_bridge.rs:1291-1295` (and `:1977-1981`) requires it to parse via `crate::cli_sessions::parse_region_source`, which accepts only a fixed small set of values and otherwise returns `BridgeError::malformed`. Similarly `SessionsSwitchParams.attachment` is a bare `Option<String>` though the runtime table at `cli_bridge.rs:754` and its consumer only accept specific attachment tokens. A client can therefore construct a request that validates cleanly against the published bundle and still receives `malformed_request` from the live bridge: the published schema promises more than the runtime honors. Correction: add the `source` enum's known values (or an equivalent pattern/enum for `attachment`) to the schema, or explicitly document in the schema description that the request schema is structural-only and does not encode these semantic value constraints. Reason deferred from #29: acceptance criterion 2 names only invalid ids, unknown fields, and out-of-range integers as required fixture coverage. Semantic enum-value validation for these string params is additional hardening beyond that criterion, and it would fall out naturally from the already-deferred per-op typed-params refactor. Split from #29.
Author
Owner

Triage note: #184 moves parse_region_source (and the --format parsers) onto PossibleValuesParser / ValueEnum. If SessionsCaptureParams.source is then typed with that same enum and the schema is derived from it, the source half of this issue falls out of #184 for free; only attachment would remain. Sequence this after #184 and re-check scope then.

Triage note: #184 moves `parse_region_source` (and the `--format` parsers) onto `PossibleValuesParser` / `ValueEnum`. If `SessionsCaptureParams.source` is then typed with that same enum and the schema is derived from it, the `source` half of this issue falls out of #184 for free; only `attachment` would remain. Sequence this after #184 and re-check scope then.
Author
Owner

Triage plan (2026-09-07)

Decision (user, 2026-09-07): fix in v0.1. The published request schema is the v0.1 contract for bridge clients; a schema that accepts what the runtime refuses is a contract defect, not hardening. status/blocked is lifted; the typed-params refactor deferred in #29 stays deferred.

Approach

Minimal tightening of the generated bridge schema in crates/felis-cli/src/cli_schema.rs:

  • SessionsCaptureParams.source: an enum of exactly the values parse_region_source accepts (after #187 lands this is the ValueEnum's variant list; derive the schema from that type rather than a hand-written list so the two cannot drift).
  • SessionsSwitchParams.attachment: the same pattern the CLI's attachment id uses (parse_attachment_id in cli_sessions.rs), applied via the schema annotation the other id fields already carry.
  • Regenerate crates/felis-cli/schemas/felis-bridge-v1.schema.json with just schema.

Not in scope: rewriting the bridge's Params accessors, or adding semantic constraints the runtime does not enforce.

Tests

  • The existing schema-invalid fixture set gains two request lines: sessions.capture with source: "bogus" and sessions.switch with a malformed attachment; tests/schema_fixtures.rs asserts the schema rejects them and cli_bridge.rs asserts the live bridge answers malformed_request.
  • The parity guard (published property sets vs allowed_params) is unchanged; add one assertion that the source enum in the published schema equals the runtime's accepted set.

Cascade

docs/reference/cli.md "JSON Schema" section if it describes the request schema as structural-only (it should now say the finite string params are enumerated); CHANGELOG.md Unreleased (schema tightened, pre-publish).

Dependencies

After #187 (to derive the enum from the ValueEnum). If #187 is not merged when this starts, hand-list the four values and leave a comment naming the ValueEnum as the source to switch to.

## Triage plan (2026-09-07) **Decision (user, 2026-09-07): fix in v0.1.** The published request schema is the v0.1 contract for bridge clients; a schema that accepts what the runtime refuses is a contract defect, not hardening. `status/blocked` is lifted; the typed-params refactor deferred in #29 stays deferred. ## Approach Minimal tightening of the generated bridge schema in `crates/felis-cli/src/cli_schema.rs`: - `SessionsCaptureParams.source`: an enum of exactly the values `parse_region_source` accepts (after #187 lands this is the `ValueEnum`'s variant list; derive the schema from that type rather than a hand-written list so the two cannot drift). - `SessionsSwitchParams.attachment`: the same pattern the CLI's attachment id uses (`parse_attachment_id` in `cli_sessions.rs`), applied via the schema annotation the other id fields already carry. - Regenerate `crates/felis-cli/schemas/felis-bridge-v1.schema.json` with `just schema`. Not in scope: rewriting the bridge's `Params` accessors, or adding semantic constraints the runtime does not enforce. ## Tests - The existing schema-invalid fixture set gains two request lines: `sessions.capture` with `source: "bogus"` and `sessions.switch` with a malformed `attachment`; `tests/schema_fixtures.rs` asserts the schema rejects them and `cli_bridge.rs` asserts the live bridge answers `malformed_request`. - The parity guard (published property sets vs `allowed_params`) is unchanged; add one assertion that the `source` enum in the published schema equals the runtime's accepted set. ## Cascade `docs/reference/cli.md` "JSON Schema" section if it describes the request schema as structural-only (it should now say the finite string params are enumerated); `CHANGELOG.md` Unreleased (schema tightened, pre-publish). ## Dependencies After #187 (to derive the enum from the ValueEnum). If #187 is not merged when this starts, hand-list the four values and leave a comment naming the ValueEnum as the source to switch to.
Sign in to join this conversation.
No description provided.