protocol: version connection modes through the minor ledger #319
No reviewers
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!319
Loading…
Reference in a new issue
No description provided.
Delete branch "connection-mode-minor"
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?
Option 1 from the issue: a connection mode is an additive minor, recorded in the ledger and gated on the effective minor.
What lands
ConnectionMode::since_minor()plus aDowngradeimpl that withholds rather than maps: a mode decides which familiesa connection speaks at all, so answering with another one would open a surface the caller did not ask for. Every
shipped mode is a base-schema one (since = 0).
ConnMsg::Hellofolds its mode's requirement intoMinorGated, so the send gate reads it like any other addition,and the ledger's schema walk now covers every
ConnectionModevalue: a mode added later cannot reach the wirewithout a ledger row.
check_mode_minorrefuses the dial withConnectError::MinorTooOldbefore theHellois written, sothe skew is reported instead of lost in an EOF (CLI exit
2,daemon_unreachable).Hellowhose mode this build cannot read is answeredRefused { UnknownMode }and then closed,rather than dropped as a corrupt body. Widening
Rolewas rejected: re-reading an existing enum value is a semanticchange the minor rule does not admit.
RefusalReason::UNKNOWN_MODE, with its ledger row inMINOR_LEDGER,felis.protoanddocs/reference/ipc.md. A peer below the minor is closed unanswered, asAtCapacityalready is.Tests
felis-protocol:a_hello_costs_the_minor_that_defined_its_mode,a_mode_is_withheld_rather_than_downgraded, plusthe existing ledger-coverage test, which now fails if a mode is added without a row.
felis-client-core:a_mode_above_the_effective_minor_is_refused— a synthetic mode one minor past this build isrefused at the negotiated minor, and the refusal is not transient.
felis-daemon:a_hello_naming_an_unknown_mode_is_refused_by_name— a hand-encoded future-modeHello(the shape anewer client writes) gets the typed refusal and then a clean close.
Gates run:
cargo nextest runfor felis-protocol, felis-client-core, felis-daemon, felis-cli (--all-features),felis-transport and the workspace guards;
cargo clippy --workspace --all-targets(clean);just proto,just proto-compat(wire-compatible with the base),just schema,just prose-check,just docs-links.Left undone
An end-to-end mixed-version test on the client side is not possible in-tree: every mode this build ships is since = 0,
so no
ConnectionModevalue exists that a realconnect()could refuse. The client half is pinned at the gatefunction with a synthetic minor; the daemon half uses a hand-encoded wire value, which is exactly what a newer client
would write.
Closes #312