[v0.1/P1] Give structural session JSON an explicit contract owner #336
Labels
No labels
priority/P0
priority/P1
priority/P2
release/v0.1.0
status/blocked
status/planned
type/bug
type/design
type/test-gap
type/tracker
No milestone
No project
No assignees
1 participant
Due date
No due date set.
Dependencies
No dependencies set
Reference
natsukium/felis#336
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
felis_grid::transcode::{body_to_json,json_to_body}is described as the shared JSON engine for satellite consumers such as a WebSocket gateway and fcast, but its public shape is the direct serde representation of Rust domain enums.That creates an unowned second public encoding:
#193 fixes one incorrect
RowPayloadshape, but it does not decide who owns or versions the surrounding structural JSON contract.Decision required
Choose one of two explicit contracts before the first consumers record public data:
felis-json.v1, with dedicated DTOs, a version envelope, generated JSON Schema, golden conversations/fixtures, and an explicit compatibility policy.Do not treat “whatever serde currently emits for the Rust domain model” as a third option.
The CLI bridge's existing
v: 1envelope and published schemas should remain separate unless the decision explicitly makes it an instance of the same format.Acceptance criteria
RowDelta.docs/reference/ipc.mdanddocs/explanation/architecture/overview.mdagree on the resulting boundary.Evidence
crates/felis-grid/src/transcode.rscrates/felis-protocol/src/messages.rsdocs/explanation/architecture/overview.mddocs/explanation/architecture/ipc.mddocs/reference/ipc.mdRelated: #29, #193, #326.
Decision: Option 2, a named versioned format with dedicated DTOs and an explicit envelope, owned by
felis-grid; P1 (reviewed)Facts that decide it: both out-of-repo consumers exist and call
body_to_jsondirectly.felis-web-gatewayforwards Grid/Image/Conn/Session to a separately deployed browser view;felis-fcastpersists Grid/Image in.fcastfiles (its header versions its own envelope and recordsproto_minor, but the frame payloads are the raw domain-serde shape). Both pinfelis-gridby git rev. So the accidental dependency is real and already on disk, and Option 1 would make each satellite invent its own DTO for the same messages, the drift the shared engine exists to prevent.transcodetoday also accepts every family except Input, wider than any satellite needs, and the in-repo bridge uses it for Region rows.What lands:
felis_grid::json_v1(behind thejsonfeature): dedicated DTO types for Grid, Image, Conn, Session, plus Input for the replay direction, converted explicitly from and to the domain types, so a domain rename fails to compile the conversion instead of changing the JSON.{"felis_json": 1, "kind": "<family>", "msg": <DTO>}; the version is in-band.RowDeltawith structural rows (#193), round-trippedjson → wire → json.ipc.md, stricter than REQ-104b because a.fcastfile or a deployed browser has no effective-minor gate: withinfelis_json: 1the only permitted addition is a new optional object field readers may ignore (schemaadditionalProperties: true, nodeny_unknown_fields); a new kind, variant, enum value, rename, retype, or required semantic isfelis_json: 2, writers emit the version their consumer asked for (latest for a recording), readers keep both for a deprecation window. Old-reader/new-writer fixtures: an unknown optional field decodes; an unknown variant is rejected at the version check, not deep inside a mirror.felis-clibehind the CLI's ownv: 1contract, whose published schemas already cover them;felis-grid::transcodekeeps only the row recode the DTO conversion needs. The bridge envelope stays a separate contract.Satellite follow-ups (adopt the envelope, drop their kind-name mapping) are filed in their repos after this lands. Doc cascade:
ipc.md("One encoding on the socket, JSON at a bridge"),overview.md,workspace.md,CHANGELOG.md. Independent of the proto batch.