Phase 9 S1-S3: TTL-scoped sessions with tag leases
Build with clawstor cache / Cargo build (clawstor-cached) (pull_request) Failing after 24s

Adds an aggregator-side session store so wizard-style flows can pin
tags fleet-wide and have them auto-reap on cancel or timeout. Solves
the wizard-cancel problem discussed in the roadmap: activate a repo
on step 2, commit on final submit, or let the sweeper undo it if the
user walks away.

- new module `sessions` — persistent (JSON) session+lease store with
  create/get/list/attach_lease/renew/commit/remove + snapshot_expired
- background sweeper (15s tick) reaps expired non-committed sessions
  by fanning out DELETE /api/v2/tags/:name for each attached lease
- HTTP: POST /api/v2/sessions, GET/DELETE /api/v2/sessions/:id,
  POST .../pin, .../renew, .../commit
- namespace-scoped: namespaced tokens only see + touch their own
  sessions; admin sees all (matches F4 tag ACL model)
- max TTL 24h, renew is absolute-from-now (idempotent heartbeats)
- pin fans out BEFORE recording the lease so failures don't strand
  phantom leases; delete unpins across fleet BEFORE removing session
This commit is contained in:
Omar Sobh
2026-07-15 00:52:11 -07:00
parent baefd95427
commit 3f5df05b07
6 changed files with 570 additions and 0 deletions
+3
View File
@@ -55,6 +55,9 @@ axum = { version = "0.7", features = ["macros"] }
tower-http = { version = "0.5", features = ["cors", "fs"] }
tokio-stream = "0.1"
serde_json = "1"
# v1 — session IDs (Phase 9 S1). v4 random hex; no persistence
# concerns beyond "opaque URL-safe id".
uuid = { version = "1", features = ["v4"] }
# v0.2.0 — flock(2) wrapper for atomic+locked manifest writes
# (manifest.rs). Already a transitive dep; declaring it directly
# makes the call site obvious.