Freeze wire scalar shapes: attachment ids, resource report, env pair, pacing flag #328
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#328
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?
Background
Pre-freeze review (parent #326) found wire scalar shapes that force every future peer — including non-Rust ones reading
felis.proto— to carry conversions the schema could state directly. None of these is covered by #326's six findings. Fixing any of them after the baseline costs a major bump; documenting the intent now costs a paragraph.Cases
Attachment.idisuint64on the wire but a decimal string in CLI/bridge JSON, while session ids are 32-hex strings in the same objects. One object carries two integer spellings. Either unify the JSON spelling or freeze the "u64-as-string" rule (with the existingx-bound-exceeds-f64-precisionannotation story) as the permanent convention for integer ids.ResourceReportuses threeoptionalfields where absent ≠0(max_subject_used,per_subject_limit,global_limit), and the human/--format jsonrenderings branch on each. A reader under pressure (the report's stated purpose) must notice a missing key. Either split per-scope messages or collapse to0 = unlimited, and freeze the human↔JSON correspondence table incli.md.SpawnArgs.env(UTF-8stringpairs, user-typed) vsenv_base(bytespairs, captured): two origins, two spellings, both implemented by every peer. If both survive, freeze "only the relay sendsenv_base, and only over a local socket" as wire-enforced rather than convention (decode already checks the caps; the sender rule is prose only).ConnHello.pull_paced: boolbesideConnectionMode: the capability-bitmap rejection left exactly one bool standing. A second optimization reopens the bitmap debate. Freeze the rule now: the next optimization earns a mode, not a bool (ipc.mddesign record), or fold pacing into the mode enum while renumbering is still free.Acceptance criteria
docs/reference/ipc.md/docs/reference/cli.mdbefore the baseline in #115 lands.convert/narrowing tests and the arm-table sync test where applicable.skills/felis/SKILL.mdexamples still match the frozen shapes.Parent: #326 (final interface simplification audit).
Related: #313 (protocol 1.0 baseline).
Decision: do; only case 2 changes the schema, cases 1, 3, 4 are recorded decisions (reviewed)
Attachment.idu64 vs JSON string: freeze the rule, no schema change. "Integer ids beyond f64 precision are JSON strings" becomes the permanent convention incli.md(thex-bound-exceeds-f64-precisionannotation already exists).ResourceReport: schema change.0is legitimate formax_subject_used, so collapsing to0 = unlimitedis out. Applying #327's policy with every scope-dependent field inside its scope arm:max_subject_usedis plain under subject scope because the daemon always computes it there and never under daemon scope: the oldoptionalencoded the scope, not availability. A daemon row with a per-subject limit becomes unrepresentable. CLI rendering is preserved by flattening:--format jsonkeeps today's keys, an unlimited limit stays an omitted key, and only human output printsunlimited; thecli.mdtable is rewritten in terms of the arms. Own PR rebased on merged #330 (same message renumbered), ownbase:line.env/env_base: keep both; the sender rule stays a send-side invariant, the "wire-enforced" ask is declined. The rule is the oneipc.mdand REQ-912a already state: the dialing process fillsenv_baseonly when its carrier is the local socket; an SSH dial leaves it absent and the relay's environment travels inFRLY. A daemon-side check is impossible: an over-cap relay legally omitsFRLYand splices a bareFLISstream, so the daemon cannot tell SSH from local, and the protobuf decoder has no carrier context. Recorded in the IPC explanation.pull_paced: bool: keep; record "the next optimization earns a mode, not a bool" in the IPC explanation. Folding it into the enum reopens the settled bitmap debate for no gain.