fix(security/docs): SessionHandle Drop + free-swallow + recovery_qr docs + dev-c launcher (Stream A) #3
Reference in New Issue
Block a user
Delete Branch "feature/arch-followup-stream-a-security-polish"
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?
Summary
Stream A of the architecture-review-followup. Small security-flavored polish PR addressing four findings from the 2026-05-04 audit:
impl Drop for SessionHandleso.free()becomes a real cleanup safety net (Rust fix). Native test exercises construct → drop → registry empty; companion wasm-bindgen-test intests/session_drop.rsfor symmetry. Recorded audit of every.free()callsite underextension/src/.try { current.free() } catch { /* already freed */ }atextension/src/service-worker/session.tsso failures propagate. Vitest covers no-op / called-once-with-idempotency / propagating-throw.crates/relicario-core/src/recovery_qr.rsbrought up to the documentation density ofcrypto.rs/backup.rs/tar_safe.rs. Module `//!` header (3 sections), ASCII layout diagram pinned by static-assert, doc-comments on all four public items, `production_params()` fn replaced with a top-level `RECOVERY_PRODUCTION_PARAMS` const, named slice-range constants, audit-H1 length-prefix one-liner.Synthesis references
.free() callsite audit
`grep -rn "\.free\b" extension/src/` returns exactly one functional callsite:
```
extension/src/service-worker/session.ts:32: current.free();
```
Two additional matches (`session.ts:12, 14`) are documentation references inside the new doc-block. Phase 1's `impl Drop` makes this single `.free()` call cleanup the SESSIONS registry entry directly; calling `wasm.lock(handle.value)` first is now redundant belt-and-suspenders and the SW intentionally does not.
Lifecycle audit — both paths reach `clearCurrent()`:
Test plan
Pre-existing test failures (acknowledged)
`cd extension && bun run test` reports 17 failed / 335 passed (52 files). The 17 failures are pre-existing on the kickoff baseline `bd3d53f` (verified by checking out the baseline and running the same suite cleanly: same exact 17 reds). Stream A added 3 new passes (`session.test.ts`) and zero regressions.
Failing-test clusters (all unrelated to Stream A scope):
Per PM directive (Option A), these are documented here and left to a follow-up stream.
Phase commits
Phase 1 added impl Drop for SessionHandle on the Rust side so .free() now actually removes the SESSIONS registry entry. The JS-side try { current.free() } catch { /* already freed */ } swallow was hiding the fact that .free() wasn't doing the cleanup at all; post-Phase-1 it has to go so failures surface instead of being lost. .free() callsite audit: exactly one match under extension/src/ — the SW session.ts line this commit edits. Lifecycle audit: clearCurrent() is reached via (a) popup lock → router popup-only.ts and (b) session-timer expiry → service-worker/index.ts. Refs: docs/superpowers/specs/2026-05-04-security-polish-design.md (Phase 2) Refs: docs/superpowers/reviews/2026-05-04-architecture-review.md (P1.1, DEV-C P2 service-worker) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.