ship: v0.3 phase 0 — pre-execution (specify, clarify, research, plan, grill, mvp/ux) #16
Reference in New Issue
Block a user
Delete Branch "phase/00-pre-execution"
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?
Squash-merge of phase/00-pre-execution into milestone/v0.3-hosted. v0.3 hosted milestone pre-execution: SPECIFY (REQ-69..85, supersession), CLARIFY (D-101..D-115), RESEARCH (RESEARCH-v03, C3-01..C3-20, P-1..P-14), PLAN (P1..P4 vertical slices), GRILL (Proceed 0.68, G-101..G-110, G-111 escalation), MVP/UX PASS. Ships as v0.3.0.
---ci--- phase: 0 milestone: v0.3 status: clarify decisions: - id: D-101 decision: "Sessions: server-side store (in-process dict + durable sessions.json), httpOnly SameSite=Lax cookies, opaque tokens, 14-day sliding expiry, immediate revocation" rationale: "Single uvicorn worker makes in-process sound; server-side is the only posture satisfying REQ-70 deactivation" confidence: 0.90 - id: D-102 decision: "argon2id via argon2-cffi, verify via asyncio.to_thread" rationale: "REQ-69 names argon2id; standard maintained implementation" confidence: 0.95 - id: D-103 decision: "401 guard on all /api/* except login/register; CSRF = SameSite=Lax + custom header on non-GET; /healthz outside /api" rationale: "Same-origin proxy + JSON fetch + custom header kills cross-site CSRF without token round-trips" confidence: 0.82 - id: D-104 decision: "Register open only while user store empty (first user = admin); then admin-created accounts with admin-set passwords" rationale: "Only mechanism without CLI/mail; race-safe under single asyncio worker" confidence: 0.85 - id: D-105 decision: "user_id = 8-char slug, email login, no email verification" rationale: "House ID style; filesystem-safe partition key" confidence: 0.75 - id: D-106 decision: "User-prefixed storage runs/<user_id>/<run_id>/ (supersedes D-010); owner_id in RunState; no migration" rationale: "Defense in depth; per-user library = single directory scan" confidence: 0.88 - id: D-107 decision: "Data root = RESEARCHX_DATA_DIR (dev backend/var/researchx; container /var/lib/researchx)" rationale: "cwd-dependent storage breaks under container workdirs" confidence: 0.85 - id: D-108 decision: "KEK = RESEARCHX_KEK (env-file 'keys' scope), AES-256-GCM with user_id as AAD; disabled honestly when unconfigured" rationale: "REQ-73 mandate; graceful degradation keeps zero-key dev green" confidence: 0.83 - id: D-109 decision: "Key store scope = model key only in v0.3" rationale: "REQ-73/74 name model keys; minimal encrypted surface" confidence: 0.80 - id: D-110 decision: "Model adapter constructed per run via factory resolving user→server→keyless; probe per resolved tier" rationale: "Shared adapter mutates _active_base globally (verified bug); per-user keys impossible on shared instance" confidence: 0.90 - id: D-111 decision: "GET /api/config stays read-only status; new GET/PUT /api/config/settings for per-user settings; storage path display-only hosted" rationale: "Two read models already split in the ApiClient" confidence: 0.87 - id: D-112 decision: "Code default stays mock; hosted image built with NEXT_PUBLIC_RESEARCHX_API_MODE=live; no live delegation to mock after P3" rationale: "Build-time inlining of NEXT_PUBLIC vars; zero-key discipline preserved" confidence: 0.85 - id: D-113 decision: "REQ-82 in scope as backend work: persist report.json + evidence.json at DONE; endpoints enriched; live exports use real data" rationale: "Evidence is in-memory only today; hover quotes impossible without persisted artifacts" confidence: 0.90 - id: D-114 decision: "Open questions = plan sub-questions answered-iff DONE; no synthetic suggestions; empty state for new users" rationale: "Real, persisted, user-scoped, honest, zero extra model cost" confidence: 0.65 - id: D-115 decision: "Read-models read disk artifacts, not RunRegistry; in-flight runs marked cancelled on restart; rehydration out of v0.3 scope" rationale: "RunRegistry is in-process; disk-backed read-models mandatory for hosted restarts" confidence: 0.80 requirements: covered: [] partial: [] ---/ci--- REQUIREMENTS.md REQ-69..85 refined with the decision outcomes; PROJECT.md carries the D-101..D-115 decision log.---ci--- project: researchx phase: 0 milestone: v0.3 status: grill decisions: - id: G-101 decision: "Startup sweep handles PLANNING runs: C3-11's 'verified' CANCELLED-legality claim is false (states.py PLANNING to {AWAITING_APPROVAL,FAILED}); add PLANNING to CANCELLED in _LEGAL_TRANSITIONS or document a bypass; pinned by sweep test in T-1.8" rationale: "A crash mid-PLANNING leaves a persisted state the sweep cannot legally cancel — restart-path corruption at the first hosted redeploy" confidence: 0.90 - id: G-102 decision: "Stale out-of-scope rows fixed (REQUIREMENTS 'Auth/multi-tenancy' + PROJECT 'multi-tenant/auth') to match the recorded supersession" rationale: "Same-file contradictions with the owner-recorded v0.3 supersession" confidence: 0.95 - id: G-103 decision: "REQ-75 split bound (delegation-end P3, hosted-default P4); traceability row fixed; PLAN's pitfall-phase mapping authoritative over C3-19" rationale: "G-001-class triple-mapping contradiction across three documents" confidence: 0.85 - id: G-104 decision: "Exposure hardening: password min length 12 at register + admin-create; per-IP login rate limit at HAProxy front; audit asserts throttle + uniform 401s" rationale: "Public URL + argon2 ~50-100ms CPU per verify = DoS amplifier; no policy existed anywhere" confidence: 0.80 - id: G-105 decision: "KEK-loss posture stated: loss = per-user keys unrecoverable, honest degradation, re-entry under re-provisioned KEK; owner backs up off-repo; rotation out of v0.3 (recorded)" rationale: "KEK becomes load-bearing at P2; loss posture was stated nowhere" confidence: 0.85 - id: G-106 decision: "deploy.sh: free-disk assert + dangling-image prune + documented 4-container host budget" rationale: "P4 doubles image families on a single LXC host; current script has neither" confidence: 0.75 - id: G-107 decision: "Staged deploy defined: candidate pair on the host, health green, four smoke assertions host-locally; public cutover is a discrete owner-directive act with -prev armed" rationale: "P4's DoD used an undefined term; the host runs one container today" confidence: 0.75 - id: G-108 decision: "P3 pressure valve (G-006 precedent): may ship as P3a backend + P3b frontend patches without scope change" rationale: "P3 is the heaviest phase (7 REQs + standalone client + all swaps) with no pre-agreed valve" confidence: 0.70 - id: G-109 decision: "Task-inbox honesty: live-mode status derived (answered-iff DONE); checkbox display-honest in live mode; persisted check state is v0.4+; pinned by test" rationale: "REQ-78 promises 'checkable' but the derived GET-only read-model silently reverts user checks" confidence: 0.75 - id: G-110 decision: "Cost posture stated: server-tier runs bill the owner's key; bound = admin-managed accounts; per-user counters surface usage; no hard cap in v0.3" rationale: "Server-key-as-fallback (owner-picked) with the cost ceiling stated nowhere" confidence: 0.70 escalations: - "[G-111] P4's DoD (staged smoke on the LXC host) requires a host deployment D-019 forbids without a directive — owner must pre-authorize staged deploys for P4 DoD (no public cutover) or accept host proofs deferred to the gate" requirements: covered: [] partial: [] ---/ci--- Verdict: Proceed (0.68). 11/12 sampled research claims verified exact; the one false claim (sweep legality) bound as G-101 with a test pin. G-102/G-103 applied to REQUIREMENTS/PROJECT/PLAN in this commit; G-101/104..110 encoded as PLAN must-haves; G-111 visible via ciagent audit.