Commit 70c43c6
fix(server): enforce D7 live-session guard + resume lease on REST resume paths (ks38) (#540)
* docs: add implementation plan for rest-resume-live-guard
🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)
Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
* docs(plan): apply load-bearing validation findings to the rest-resume-live-guard plan
Falsified assumptions fixed:
- The in-process tabs-sync restore caller no longer exists (deleted by
2ed6b94) - plan now names the three real REST callers only.
- Plain check-then-spawn is NOT parity with WS: the shipped client
always negotiates paneReconcileV1, so the WS create path holds the
D8 per-sessionRef lease in production. New Task 5 claims the same
registry lease at the REST choke point (conservative 409 arms, RAII
release, claim completed into a binding on success).
Also: definitive Debug-derive instruction for TerminalIdentityRegistry,
corrected pane_ops helper range (1007-1021), removed the ks38 respawn
misquote, renumbered verification/land tasks to 6/7.
Ledger: .the-usual-logs/rest-resume-live-guard/load-bearing-ledger.md
(16 verified, 2 falsified-and-fixed, 1 acceptable).
🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)
Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
* docs(plan): make Task 5's claim-completion test observe the bindings map directly
Fresh-eyes review found the rest_create_resume_completes_claim_into_binding
test vacuous: a late claim_session_ref probe is answered BoundElsewhere by
the row-join arm (registry.rs:1771-1773) from the Running row's
resume_session_id stamp alone, so the prescribed red state (Acquired) was
unachievable and the green test never proved complete_session_ref_claim ran.
The test now asserts bound_terminal_for_session_ref (registry.rs:2007, pub
test probe; only complete_session_ref_claim writes that map) is None before
the spawn and Some(tid) after, with the expected-red text and Task 5's
consumed-interfaces list updated to match.
🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)
Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
* feat(terminal): add shared D7 live-session-owner predicate to TerminalRegistry
Extracts the D7 liveness join (identity arm behind a new
SessionIdentityLookup trait + registry-row arm) into
TerminalRegistry::live_session_owner so the WS create guard and the
REST spawn pipeline can share one predicate instead of copies.
Part of ks38.
🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)
Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
* style(terminal): fix fmt and clippy doc lint in Task 1's live_session_owner code
cargo fmt --all --check and clippy's doc_lazy_continuation (-D warnings)
both failed on 8c800c9's additions: two over-wide assert_eq! lines in
the registry tests and a doc-comment paragraph that clippy read as a
lazy list continuation. Mechanical fixes only; no behavior change.
Part of ks38.
🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)
Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
* refactor(ws): route the D7 create guard through the shared live_session_owner predicate
TerminalIdentityRegistry now implements the freshell-terminal
SessionIdentityLookup seam, and the terminal.create D7 block delegates
its two-arm liveness join to TerminalRegistry::live_session_owner.
Behavior-preserving: live_session_ref_guard and the restore-unavailable
suites pin the wire contract. Part of ks38.
🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)
Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
* fix(freshagent): enforce the D7 live-session guard on the REST spawn pipeline (ks38)
POST /api/tabs (and every spawn_terminal_pane caller) now refuses a
sessionRef resume onto a (mode, sessionId) owned by a Running terminal
with 409 {code: RESTORE_UNAVAILABLE}, via the shared
TerminalRegistry::live_session_owner predicate -- both arms: registry
rows plus the identity registry injected from freshell-server through
the new SessionIdentityLookup seam. Same message text as the WS guard;
refusal happens before any side effect, so no rollback is needed.
🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)
Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
* test(freshagent): pin D7 REST guard coverage on respawn and split routes
Respawn/split with a sessionRef onto a live (mode, sessionId) are
refused 409 RESTORE_UNAVAILABLE through the shared spawn choke point;
respawn-resume succeeds once the owner exits; and respawn has NO
self-exemption -- the pane's own detached-but-running predecessor
counts as the live owner (two-writers doctrine). Part of ks38.
🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)
Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
* fix(freshagent): serialize REST sessionRef resumes with the D8 session-ref lease
The REST choke point now claims the registry's per-sessionRef lease
(claim_session_ref) after the D7 guard and completes it into a binding
on success, closing the REST-x-REST / REST-x-WS duplicate-writer race
the check-then-spawn guard alone leaves open. Conservative arms:
Held/BoundElsewhere/ExpiredNeedsKill all answer 409 RESTORE_UNAVAILABLE;
RAII release on every failure path. Part of ks38.
🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)
Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
---------
Co-authored-by: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>1 parent cab6c95 commit 70c43c6
7 files changed
Lines changed: 2057 additions & 27 deletions
File tree
- crates
- freshell-freshagent/src
- freshell-server/src
- freshell-terminal/src
- freshell-ws/src
- docs/plans
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
116 | 116 | | |
117 | 117 | | |
118 | 118 | | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
119 | 126 | | |
120 | 127 | | |
121 | 128 | | |
| |||
238 | 245 | | |
239 | 246 | | |
240 | 247 | | |
| 248 | + | |
241 | 249 | | |
242 | 250 | | |
243 | 251 | | |
| |||
388 | 396 | | |
389 | 397 | | |
390 | 398 | | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
391 | 413 | | |
392 | 414 | | |
393 | 415 | | |
| |||
1257 | 1279 | | |
1258 | 1280 | | |
1259 | 1281 | | |
| 1282 | + | |
| 1283 | + | |
| 1284 | + | |
| 1285 | + | |
| 1286 | + | |
| 1287 | + | |
| 1288 | + | |
| 1289 | + | |
| 1290 | + | |
| 1291 | + | |
| 1292 | + | |
1260 | 1293 | | |
1261 | 1294 | | |
1262 | 1295 | | |
| |||
0 commit comments