The v0.10 milestone: employers become principals of the marketplace
(REQ-F-019 activated as REQ-10-001..005 per D-085). Employer auth
with scrypt password hashing, hashed session tokens, and login/
register throttles (G-311/G-312/G-315); employer identity as claim/
verify over the v0.6 marketplace entities with advisory evidence
adjudication and admin approval (D-089/D-089/G-316/G-317); the
dashboard converted to real data with honest empty/pending/
processing states (no mock charts); self-serve postings through
the shared D-091 entitlement gate byte-identical with the admin
path (G-318/G-319); self-serve checkout over the v0.9 catalog
through the REAL webhook path with the own-session mock-complete
closing the G-301 class (G-302/G-303/G-304 carried forward); and
the admin network overview — accounts, claim queue, and audit in
one panel (D-094). Final review verdict SHIP: 2 P0s found and
fixed (the /me claim-state leak, the dead billing confirm button),
3 P1s dispositioned; audit PASS — reconstruction clean, discipline
green. Tags v0.9.0..v0.9.6 on the v0.9.x line; the tag lane builds
every release's full asset matrix per D-064.
---ci---
phase: 6
milestone: v0.10
status: complete
requirements:
covered: [REQ-10-001, REQ-10-002, REQ-10-003, REQ-10-004, REQ-10-005]
partial: []
---/ci---
The v0.9 milestone: payment processing and subscription management
(REQ-F-018 activated as REQ-9-001..005 per D-074). The billing module
(ai_service/billing/ — PaymentProvider protocol with deterministic
mock + Stripe-compatible REST over the shared pool, the 7th D-027
store with 7 tables, the HMAC-SHA256 webhook core per D-077), the
seeded catalog + /v1/billing routes, the pricing page's runtime
conversion, posting entitlement enforcement with honest 402 upgrade
CTAs, and the full subscription lifecycle with a queryable audit
trail. Operator-mediated checkout at pilot (D-076); grants exactly-
once per session (G-303); webhook state resolved from local rows only
(G-302); consumption as a single conditional UPDATE (G-304). Tags
v0.8.0..v0.8.6 on the v0.8.x line; the tag lane built every release's
full asset matrix + registry image (D-064).
---ci---
phase: 6
milestone: v0.9
status: complete
requirements:
covered: [REQ-9-001, REQ-9-002, REQ-9-003, REQ-9-004, REQ-9-005]
partial: []
---/ci---
The v0.8 milestone: installable on any Debian-based server via docker
(Gitea registry image, honest sandbox degrade), deb (amd64+arm64,
advisory postinst), and arch-aware binary — with release consistency
enforced by pre-commit hooks + Gitea Actions (3-runner fleet on CT 113,
machine-made releases with the full 8-asset matrix + registry image), the
CLI carrying the full suite (guide, channel-aware doctor), and the admin
runbook (deploy/README.md, evidence-backed recipes).
---ci---
phase: 6
milestone: v0.8
status: complete
requirements:
covered: [REQ-8-001, REQ-8-002, REQ-8-003, REQ-8-004, REQ-8-005]
partial: []
---/ci---
---ci---
phase: 7
milestone: v0.3
status: review
lessons:
- P0 CORS: allow_methods lacked PUT while the build surface writes files with PUT — every cross-origin Save failed preflight; pinned with tests/api/test_cors.py
- P0 ingest leak: queue-overflow flood path returned without the disconnect sentinel, parking the drainer forever (one leaked task-set per flooded trace); sentinel now always enqueued, real-server regression test added
- P1 perf: flood cap counted rows via len(get_trace(...)) — O(trace) per append, O(n²) per session; TraceStore.count() (COUNT(*)) added and wired
- P0 security: file routes followed exec-planted symlinks out of the workspace bind; _resolve_in_workspace refuses escapes (422), read/write now 404 on unknown sandboxes (was 500)
- P1 security: WS ingest accepted any browser Origin (CORS middleware does not cover WS); localhost dev origins + no-Origin (capture agent) allowed, others 1008
- P1 correctness: use-sandbox-session leaked a created sandbox on any mid-start failure (per-learner cap 1 → all retries 429 forever); failed starts now destroy what they created
- P2 testing: reconnect-flush test killed mid-burst (nondeterministic under load, reproduced on pre-change code); now waits for server-side observation of the pre-kill burst — the underlying one-line replay-margin/ACK gap is documented for v0.4
- maintainability: grading-store/templates/grading.ts docstrings claimed grading is variant-blind (stale pre-P4 text) — updated; ARCHITECTURE.md referenced nonexistent voice/openai_audio.py; dead if TYPE_CHECKING: pass blocks removed
---/ci---