feat: report a switch as queued and attribute its landings #82
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
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
natsukium/felis!82
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/operation-ids-24"
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?
Fixes #24.
A switch reply used to say
accepted, which promised more than thedaemon had done: it counted the outboxes that took the reattach push,
not the windows that landed on the new session. The field is renamed
queued(and theerror.kindtokennot_acceptedtonot_queued)across
sessions switch,switch-all,retarget-all,window retarget/felis ssh, andfelis bridge, so the name states exactlywhat happened.
The reply also carries an
operation_idnow — an opaqueincarnation/sequencetoken naming the fan-out the reply queued,nullwhen nothing was pushed. The daemon keeps a ring of the last 256operations and records one verdict per pushed window under it:
landedwhen that window re-attaches (the client echoes the id back on
SessionAttach),supersededwhen a later switch moves it first. Awindow that re-dials onto another daemon never reports back, and an id
older than the ring, or from before a restart, resolves to nothing.
Wire: protocol minor 8 —
OperationId,OpsSwitched.operation_id, theOperationEchoonPushReattach/PushRetargetHost, andSessionAttach.operation. A peer below it omits the fields, so theswitch is still reported as queued with nothing to attribute. The
accepted→queuedrename is a tag-3 rename (invisible on the wire,a compile break for a generated client), acknowledged in
crates/felis-protocol/proto/BREAKING.mdas a deliberate pre-releasebreak.
Doc cascade:
docs/reference/ipc.md(the minor ledger row, theoperation-id wire shapes),
docs/reference/cli.mdanddocs/reference/control-surfaces.md(the renamed fields and the newresult field),
docs/explanation/architecture/ipc.md(why a queuedreply plus an attributed ledger, and the rejected alternatives), and
CHANGELOG.md.Verified: just check green (fmt, clippy, nextest, deny); reviewed by
plan/correctness/docs lenses and pi sol.
Deferred
--wait <timeout>onsessions switch/switch-all/retarget-all— the plan moves it post-v0.1; it needs the query armbelow, and the id it waits on is now frozen on the wire.
Ops::OperationStatus { id }/OperationReportquery armreporting pending/landed/superseded and
Unknown{Evicted,OtherIncarnation}— the plan moves it post-v0.1; the ledger already computes every
verdict it would return, so it is purely additive.
Welcome/felis daemon status— only useful once a client can query an operation id; itships with the query arm.
failedas an inferred timeout verdict — rejected for v0.1 in theplan and recorded as rejected in the explanation doc: it could only
ever be inference dressed as observation.
not_queuederror kind — no existingharness reaches it (a scope that resolves to a window whose outbox is
dead); the kind's token is pinned by the
cli_outputgolden test.in round 4 of the plan and recorded with a Revisit-if trigger; the
origin daemon holds no record the target daemon can reach.
regression would pass it. Test-hardening beyond the current acceptance
criteria: the finding does not show current retention behavior is
wrong, only that the test could pass under a hypothetical future
regression, so strengthening the assertion is an extra test, not a fix
to shipped behavior.
ConnWelcomeor daemonstatus, contrary to the round-2 amendment — this is the same item as
"reporting the daemon incarnation" above, and it ships with the query
arm, which the accepted plan defers post-v0.1. The round-2 amendment
freezes only the
OperationIdfield shape now; it does not mandatewiring the
Welcome/status surfaces before the query arm lands.