Repository navigation
Conversation
Plan items 6 and 7 from docs/design/shipping-orcad.html. Install reuses the relay's transaction verbatim — per-version lock, staged SFTP write, .install-complete sentinel, stale-lock recovery — under a parameterized namespace, so orcad-<v>/ sits beside relay-<v>/ permanently (§06). Parameterizing GC is the trap that creates: each model now collects only its own directories, enforced twice (prefix-scoped remote listing plus a local ownership re-check), and a client picks its model from how the host is registered, never from what it finds on disk. Activation is separate from installation, because a versioned directory selects nothing. A candidate is launched, publishes orca_server_ready, and only becomes active if its cross-process health payload passes: right build hash, listening, daemon live, PTY self-test green. A rejected candidate is stopped and the incumbent restarted, so a careful deploy cannot cause the outage it was being careful about. Update and rollback are shaped by the daemon. An update restarts orcad, the daemon outlives it, and the surviving daemon was forked from the outgoing bundle — so live terminals defer the update rather than proceed, and GC pins the active version, the rollback target and the live daemon's bundle. Orca's persisted state carries no schema version, so rollback restores a pre-activation snapshot rather than trusting backward-readability; the point past which it is unsafe is the first terminal created after activation, which the snapshot cannot describe and the surviving daemon still owns. Running the generated shell for real found two bugs the text assertions missed: tar members re-quoted inside a shell variable captured nothing, and kill -0 reports a zombie as alive.
Collaborator
|
Closing as superseded: versioned orcad deploy, activation and rollback landed in #16398 and now live under |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Plan items 6 and 7, stacked on #16375. The last work before the swap.
Reuse, per the design's §02 table — not a second pipeline
uploadRelayDirectory, SFTP write + lock helperscomputeRemoteRelayDirhardcodedrelay-${version}andRELAY_VERSION_DIR_REGEXonly matched^relay-…$, so it was blind to orcad dirsORCA-RELAYsentinel; orcad publishesorca_server_readyThe GC trap — §06 falsifier 1, answered
Each model GCs only its own namespace, permanently. orcad removes
orcad-<v>/; the relay removesrelay-<v>/; neither ever removes the other's.That is not a migration compromise. The two models serve different users on the same machine (SSH target vs paired peer), so there is no moment at which one is entitled to clean up after the other — a pass that deleted the sibling's tree would reach across the execution boundary the design exists to keep intact.
On top of ownership, orcad pins three idle-looking but load-bearing directories: the active version, the rollback target, and whichever version the live terminal daemon was forked from.
Activation is health-gated on the daemon, not on "listening"
A host answers readiness from its own process, so listening stays true while the terminal daemon that owns every terminal is dead — a green host that cannot run a single command. The gate therefore refuses on
daemon_absent,daemon_degraded, and distinguishespty-spawncoverage (a real PTY created and torn down inside the daemon) fromhandshake(the daemon answered but its spawn probe was a no-op).Verified load-bearing: short-circuiting
evaluateOrcadActivationto always activate fails 10 of its 11 tests, including:(My first injection attempt was a no-op and everything passed. That proved nothing about the tests, so I injected properly rather than concluding they were weak.)
The update must not kill the daemon
Item 4 bought the property that work survives an orcad restart — I verified a daemon outlives an orcad stop while holding a live PTY. An update restarts orcad, so the stop path uses SIGTERM, then a second SIGTERM meaning "your deadline elapsed", and never a kill: a kill skips orcad's own release of the daemon. Activation treats running terminals as a reason to defer, not proceed.
Proof
1,857 tests pass across
src/main/ssh+src/main/orcad. Ratchet 0;build-orcadgreen and now stamping a version+hash (0.1.0+6f924cee5e71);smoke:orcad-terminalpasses; typecheck and lint clean.Trade-offs
Zero user-facing. Nothing ships or runs this yet — it is the deploy path the swap will use.