Repository navigation
feat(ssh): port the SSH connection work ledger and transport close ledger (#16741 T2) - #24210
Conversation
|
Comments Outside DiffThese findings could not be posted inline.
|
There was a problem hiding this comment.
ℹ️ No critical issues — one API-consistency note inline, a couple of defer-able observations below.
Reviewed changes
- Per-connection work ledger (
src/main/ssh/ssh-connection-work-ledger.ts): tracks operations and channels under anAsyncLocalStoragescope, admits nested work only under an already-admitted non-exempt parent afterfenceForReset(), and drains cancellably while retaining the first failure. - Channel/socket lifetime tracking (
src/main/ssh/ssh-connection-channel-lifetime.ts): binds each open→close to a ledger entry; an untrackable open result is marked unverifiable rather than settled. - Transport close ledger and observation (
src/main/ssh/ssh-transport-close-ledger.ts,ssh-transport-close-observation.ts): wait for every allocated client's realclose(failed-auth included) and refuse allocations added after the drain snapshot. - WebSocket lifecycle extraction and strict bind (
src/main/runtime/rpc/node-websocket-lifecycle.ts,websocket-transport-limits.ts,ws-transport.ts; from #24186, merged in): handlers andstop()extracted order-equivalently,stop()now also callscloseAllConnections(), andstrictPort/requirePinnedWsPortfails closed instead of falling back when a managed tunnel needs one port. - Tests for all of the above (33 cases), all passing locally.
ℹ️ Nitpicks
src/main/ssh/ssh-connection-work-ledger.ts:44-48—markTransportUnverifiable()is a silent no-op beforefenceForReset(), unlikebeginChannelOpen().markUnverifiable(), which persists its error on the entry even pre-fence. Fine if the reset flow always fences first; otherwise a connection-level failure can vanish before the fence.src/main/ssh/ssh-connection-work-ledger.ts:90-132—beginSession()is the only public method in the port with no test coverage, and it owns non-trivialclosed/closeFailed/activestate. Close-before-drain, close-with-error mid-flight, and run-after-close would pin it.
DeepSeek Flash (free via Pullfrog for OSS) | 𝕏
| isDrained(): boolean { | ||
| return this.pending.size === 0 && !this.failure | ||
| } |
There was a problem hiding this comment.
isDrained() counts the exempt control entry as pending, while drain() and assertDrained() deliberately exclude it. After a legitimate drain with a live control channel (ssh-connection-work-ledger.test.ts:216-233), fence.assertDrained() passes but isDrained() still reports false — anything that gates reset completion on isDrained() would never see it finish. Consider excluding this.exempt (or documenting isDrained() as the pre-fence variant) and adding a matching test.
Technical details
# isDrained() disagrees with the fence's drained definition
## Affected sites
- `src/main/ssh/ssh-connection-work-ledger.ts:35-37` — `isDrained()` returns `pending.size === 0 && !failure`
- `src/main/ssh/ssh-connection-work-ledger.ts:169-175` — `assertDrained()` filters `entry !== this.exempt`
- `src/main/ssh/ssh-connection-work-ledger.ts:184` — `drain()` filters the exempt entry too
## Required outcome
After a legitimate drain that leaves the exempt control channel open, `isDrained()` and the fence's `assertDrained()` return the same verdict.
## Suggested approach (optional)
Filter `this.exempt` out of the `isDrained()` count, or rename/document it as the pre-fence variant. Add a test mirroring the exempt-control case at `ssh-connection-work-ledger.test.ts:216-233`.5da66b8 to
4446ea6
Compare
54ce722 to
014daa4
Compare
4446ea6 to
3977d5b
Compare
…acking Dormant foundation for the T2 SSH core port of #16741 (design D9.3). No production module imports it yet; only tests do, so SSH behavior is unchanged. The next T2 slice wires SshConnection.exec/sftp/channel opens and forwarded sockets through it. Adds: - SshConnectionWorkLedger: tracks local operation and channel lifetimes per connection. fenceForReset closes admission (except work nested under an already-admitted operation and one exactly-identified control channel) and drain() waits for the rest, failing sticky on any failure or unverifiable opening observed after the fence. Channel closure is local lifetime evidence only, never proof that a remote process exited. - trackSshConnectionChannelLifetime / openTrackedSshSocket: bind an opened channel or socket to its ledger entry and settle it only on 'close' ('end', 'error' and the destroyed flag are not closure). Porting note (source: #16741 head a68b6f3, merge-base 277c289; T2 per the #24137 track manifest): - Taken verbatim: ssh-connection-work-ledger behavior and tests, ssh-forward-socket-admission.test.ts, openTrackedSshSocket. - Adapted: the ledger no longer calls assertProfileLifetimeAdmission on every admit. That module is an opt-in native-addon profile lock (addon dropped in T0) that overlaps the SQLite authority from #22612; callers inject their own admission check through the existing constructor argument instead (SshConnection will pass its disposed check). The broad `object` resource type became SshConnectionWorkChannel (on/once/ removeListener), and trackSshConnectionChannelLifetime uses a type guard instead of a cast, so a value without removeListener is now reported unverifiable rather than tracked. Added ssh-connection-channel-lifetime tests, since #16741 covered it only through SshConnection. - Dropped: none in these files. - Not in this slice: SshConnection wiring (ssh-connection.ts), forwarded channel lifetime (T4), upload session lifetime (T6), profile lifetime admission/lock/participation (needs a D9.4 decision against #22612). No wire change: nothing is sent to relays or clients.
Dormant foundation for the T2 SSH core port of #16741. No production module imports it yet, so SSH behavior is unchanged; the next T2 slice has SshConnection track every ssh2 client it allocates and gate its transport-closure subscribers on this ledger plus the work ledger. Adds: - SshTransportCloseLedger: remembers every allocated client (including ones whose authentication failed) until it emits 'close'. drain() waits for the snapshot and fails with ssh_client_close_allocations_changed if a client was allocated after the caller should have fenced allocation. Authentication settlement, 'end' and 'error' are not physical closure. - observeSshTransportClose: registers 'close' listeners on a set of transport resources before close is initiated; wait() is cancelable without dropping the evidence, dispose() removes the listeners. Porting note (source: #16741 head a68b6f3, merge-base 277c289; T2 per the #24137 track manifest): - Taken verbatim: both modules and ssh-transport-close-ledger.test.ts. - Adapted: the ledger test no longer casts EventEmitter to ssh2 Client, since track() already accepts an EventEmitter. Added ssh-transport-close-observation tests, since #16741 covered it only through SshConnection.dispose. - Dropped: none. No wire change. Loss of transport is still reported as unverifiable, never as remote process exit.
014daa4 to
a5540c4
Compare
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (9)
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 7 remain after this review. 📝 WalkthroughWalkthroughThe changes add a work ledger for SSH connection operations, sessions, and channel openings. Channel tracking links opened sockets to ledger entries and settles them on closure. The changes also add a ledger for tracking transport client closure and an abortable observer for transport resource close events. Tests cover admission, reset draining, channel errors, close events, aborts, and retries. Priority: ⬇️ Low Merge Risk: ⚪ Minimal · up to This change adds tracking modules that nothing uses yet, so SSH behavior is unchanged. No concrete merge-blocking problem was found. Security Architecture ReviewSecurity architecture risk: 🔵 Low · up to Current exposure appears limited because the new lifecycle code is not connected to production SSH operations. No introduced attack path was established, but reset and recovery guarantees cannot yet be assessed end to end. Retained concerns Security review detailsSecurity Blast Radius
Trust Boundaries and Controls
Resilience and Maintainability Implications
Hardening Proposals
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
* Revert "feat(orcad): source-side dormant export of a relay-hosted SSH target (#16741 T6-8) (#24519)" This reverts commit 783101b. * Revert "feat(ssh): update, roll back, recover and stop a managed orcad server (#16741 T6-5 follow-up) (#24463)" This reverts commit 38c2d1d. * Revert "feat(ssh): deploy and pair an empty managed orcad server over SSH (#16741 T6-5) (#24453)" This reverts commit 8b76683. * Revert "fix(ssh): orcad GC honors the activation journal; readiness requires proven daemon coverage (#16741 T6 follow-up) (#24451)" This reverts commit d3f8c50. * Revert "feat(ssh): remote orcad stop by request file and journaled decommission (#16741 T6-4) (#24449)" This reverts commit 43d9b43. * Revert "feat(orcad): supervisable server: stop requests, managed stop receipts and a lifetime that keeps its lock on failed teardown (#16741 T6-3) (#24433)" This reverts commit b093d3a. * Revert "feat(ssh): crash-safe orcad activation, rollback and recovery (#16741 T6-2) (#24423)" This reverts commit 1a9ac0e. * Revert "feat(runtime): SSH access links for paired servers in a downgrade-safe sidecar (#16741 T5-1+T5-2) (#24420)" This reverts commit 99db2bf. * Revert "feat(relay): capability-gated owner reset with a durable preparation journal (#16741 T3 R1) (#24418)" This reverts commit 34a582b. * Revert "feat(ssh): track connection-manager drains, test probes and provider continuations (#16741 T2 P3+P8a) (#24407)" This reverts commit d53063d. * Revert "feat(daemon): idle retirement, session census and recovery-only provider (#16741 T2 P4b) (#24409)" This reverts commit ff212db. * Revert "feat(ssh): add pty.resumeClient and split SSH PTY process listing (#16741 T2 P5+P6) (#24414)" This reverts commit 92cb717. * Revert "feat(relay): await owned watcher and agent children on shutdown (#16741 T2 P1) (#24400)" This reverts commit 6b36e4f. * Revert "feat(session): retry failed renderer session writes and verify local folder PTYs (#16741 T2 P9) (#24406)" This reverts commit d23ecef. * Revert "feat(ssh): remote orcad primitives on the pinned Node runtime (#16741 T6-1) (#24419)" This reverts commit dd87ae5. * Revert "fix(runtime): fence runtime-environment subscriptions and status probes by identity (#16741 T5-3) (#24421)" This reverts commit ece9e4d. * Revert "feat(orcad): migration manifest and dormant-state contracts (#16741 T6-7) (#24422)" This reverts commit 3fbdaba. * Revert "feat(ssh): wire SshConnection through the work and transport close ledgers (#16741 T2 P2) (#24401)" This reverts commit 4e8edc8. * Revert "feat(profiles): carry markdown frontmatter visibility in project transfers (#16741 T2 P7) (#24405)" This reverts commit 60c9326. * Revert "fix(runtime): project the PTY incarnation onto mobile session tabs (#24413)" This reverts commit 99e0303. * Revert "feat(daemon): tag daemon stream data with the PTY incarnation id (#16741 T2 P4a) (#24402)" This reverts commit 817af76. * Revert "feat(ssh): port the SSH connection work ledger and transport close ledger (#16741 T2) (#24210)" This reverts commit c991893. * Revert "feat(relay): fence and drain file and git response streams on shutdown (#24185)" This reverts commit dc08ffe. * Revert "refactor(runtime-rpc): extract the Node WebSocket lifecycle; opt-in pinned port (#24186)" This reverts commit a789233. * Revert "feat(relay): route relay handlers through work admission; producer publication drain (#24181)" This reverts commit 0b812bd. * Revert "feat(relay): land the #16741 T1 seam (work drain, publication drain, release gate) (#24156)" This reverts commit 3aa2d3a. --------- Co-authored-by: m4air <m4air@Mac.localdomain>

ELI5
This is the first slice of #16741's T2 track (SSH core). It adds a per-connection work ledger that tracks in-flight operations and channels, so a later reset can drain cleanly, plus a transport close ledger. Nothing uses them yet, so behavior doesn't change.
What Changed
ssh-connection-work-ledger.ts: tracks operations and channel lifetimes, and blocks new work once a reset starts.assertProfileLifetimeAdmission, because it depends on the native addon dropped in T0 and overlaps the SQLite authority (Persist profile state in SQLite with a durable background writer #22612).objectresource type with a named type, and the cast with a type guard.Why
Design D9: these are the T2 foundations that
SshConnectionwiring and T3 reset build on.Linked Issue
Part of the Node runtime plan (Phase 3). Stacked on #24185, with #24186 merged in.
Visual Proof
N/A. Nothing uses this code yet.
Testing
The ported ledger, channel-lifetime and forward-socket-admission tests pass.
Not wired yet:
SshConnectionintegration;I manually tested these changes locally
Automated tests added/updated, or explained why not below
Agent skill upstream boundary
docs/reference/agent-skill-sharing-upstream-boundary.mdand copies or mechanically translates no upstream skill-installer source, tests, fixtures, registry entries, path tables, comments, or documentation.