ship: v0.2 P0 pre-execution #9

Merged
coreci-bot merged 8 commits from phase/00-pre-execution into milestone/v0.2-mvp 2026-09-27 10:58:36 +00:00

8 Commits

Author SHA1 Message Date
coreci 61c099e97f decision(P00): mvp/ux gate — PASS; grill decisions G-001..G-010 promoted
---ci---
phase: 0
milestone: v0.2
status: mvp_ux_check
message: >-
  MVP/UX CHECK (REQ-MVP-UX-001): PASS — PLAN.md carries all three
  sections authored at PLAN stage (User-Facing Surface, Happy Path,
  UX Acceptance Criteria); no auto-generation needed. Grill binding
  decisions promoted into PLAN.md: G-001 (probe contracts in P1,
  live probing in P2 — must_haves T-1.10/T-1.11 reworded), G-002
  (live-mode surface = core research loop only), G-003 (pauseRun/
  resumeRun as the single P3 ApiClient extension), G-004 (liveness =
  per-run export gate + opt-in keyed tier), G-005 (openapi.json
  snapshot discipline), G-006 (P2 split lever), G-007 (cost counters),
  G-008 (DDG degraded-mode contract), G-010 (Deep Report contingency
  lever). G-009 stays an open escalation for the P5 owner gate.
decisions:
  - id: G-009
    decision: Owner ratifies the live-mode surface (core loop only) at the P5 gate — presented, not silently assumed
    rationale: The approved prototype has surfaces the MVP backend will not serve live; the owner must record acceptance at the gate
    confidence: 0.85
    alternatives: [silent scope reduction]
---/ci---
2026-09-27 10:57:28 +00:00
coreci 6f232476d6 docs(grill): adversarial review — 17 challenges, 10 binding decisions (G-001..G-010), 1 escalation
---ci---
phase: 0
milestone: v0.2
status: grill
message: >-
  Mechanical nine-axis grill, verdict Proceed (0.72). Two internal
  contradictions + one measurability hole bound as decisions:
  G-001 REQ-07/12 phase mapping resolved ROADMAP-favor (contracts in
  P1, live probing in P2); G-002 live-mode surface = core research
  loop only in v0.2 (Library/Settings-persistence/Suggestions/
  Refine/graph stay mock-bound to v0.3+); G-003 pause/resume added
  to ApiClient as the single planned P3 extension; G-004 REQ-23
  liveness = per-run export gate + opt-in keyed tier, not a zero-key
  CI assertion; G-005 openapi.json snapshot + regen discipline as a
  P3 must-have; G-006 P2 may split into two patches if it slips;
  G-007 advisory cost counters via GET /api/config; G-008 DDG =
  degraded-mode contract; G-009 escalation: owner ratifies the
  live-mode surface at the P5 gate; G-010 contingency lever: Deep
  Report deferrable to v0.3 if P2/P4 slip (owner sign-off to pull).
decisions:
  - id: G-001
    decision: P1 ships typed probe/warning contracts proven with fakes; live endpoint probing executes in P2 (ROADMAP mapping wins)
    rationale: PLAN must_haves T-1.10/T-1.11 claim live probing while PLAN frontmatter and ROADMAP map REQ-07/12 to P2
    confidence: 0.9
    alternatives: [live probing in P1]
  - id: G-002
    decision: v0.2 live-mode surface = core research loop only; Library, Settings persistence, Suggestions, Refine, graph/inbox, profile stay mock-bound until v0.3+
    rationale: client.ts documents seven v0.2 endpoint mappings REQ-25 never promised — the P3 swap hidden-scope grenade
    confidence: 0.85
    alternatives: [full-prototype live mode in v0.2]
  - id: G-003
    decision: Add pauseRun/resumeRun to ApiClient in P3 as the single planned interface extension
    rationale: v0.1 pause/resume is client-side scripted; REQ-15 demands server-side pause across restarts
    confidence: 0.85
    alternatives: [no interface extension]
  - id: G-004
    decision: REQ-23 liveness = runtime per-run export gate + opt-in keyed live-URL test tier
    rationale: the 99% bar is unprovable in the zero-key fixture suite it was scheduled into
    confidence: 0.8
    alternatives: [zero-key CI assertion of 99%]
  - id: G-005
    decision: Committed openapi.json snapshot, regen only from snapshot, schema-drift gate, stable operation-ids — P3 must-have
    rationale: regenerating from a live server invites nondeterministic schema drift
    confidence: 0.85
    alternatives: [live-server regen]
  - id: G-006
    decision: P2 (13 REQs) may ship as two patches (P2a engine/SSE, P2b trust/probe); P3 swap endpoint plan drafted at P2 start
    rationale: heaviest phase; schedule risk needs a sanctioned split lever
    confidence: 0.7
    alternatives: [single P2 patch regardless]
escalations:
  - 'G-009 (axis 2): owner ratification of the live-mode surface (core loop only) required at the P5 gate — must not be discovered by the owner at the gate'
---/ci---
2026-09-27 10:57:04 +00:00
coreci 05662e0eb9 docs(P00): checkpoint — grill stage
---ci---
phase: 0
milestone: v0.2
status: grill
---/ci---
2026-09-27 10:52:16 +00:00
coreci 718b0c30cd docs(P00): create phase plans — P1 vertical-slice plan + ROADMAP v0.2 refresh
---ci---
phase: 0
milestone: v0.2
status: plan
message: >-
  PLAN stage complete: PLAN.md rewritten as the P1 (Methodology
  Framework + Adapter Layer) vertical-slice plan — 4 waves, 14 tasks,
  must_haves, REQ-01..06/08..11/31 mapping, User-Facing Surface +
  Happy Path + UX Acceptance Criteria authored for the MVP/UX gate.
  ROADMAP.md v0.2 section unblocked: P0 in progress, phase mapping
  clarified (REQ-07/12 live probing ships in P2), task waves anchored
  to PLAN.md. Plans for P2..P4 refresh at each phase boundary
  (v0.1 practice).
---/ci---
2026-09-27 10:52:14 +00:00
coreci 5765b605ec docs(P00): research findings + persona assessment for v0.2
---ci---
phase: 0
milestone: v0.2
status: research
message: >-
  RESEARCH stage complete. RESEARCH-v02.md records 8 topic areas
  (uv/FastAPI foundation, Ollama endpoints, Tavily/DDG search, SSE +
  durability, state machine patterns, quote anchoring + liveness,
  OpenAPI client gen, monorepo ergonomics) with 14 conclusions
  consumed by PLAN and 4 refinements to D-007..D-020 (hatchling
  packages key, openapi.json snapshot discipline, single-worker
  uvicorn, structured-output smoke-test detection). PERSONAS.md
  rewritten for v0.2: backend-engineer + data-engineer activated,
  frontend-engineer retained (P3 client swap + P4 E2E), phase-specific
  security-engineer added for P2 trust loop (deactivates after P2).
---/ci---
2026-09-27 10:51:44 +00:00
coreci c5e9cb1b3f docs(P00): clarify — PROJECT.md + REQUIREMENTS.md updated with D-007..D-020 resolutions
---ci---
phase: 0
milestone: v0.2
status: clarify
message: >-
  Clarify-stage file updates: PROJECT.md gains the v0.2 Key Decisions
  section (14 decisions D-007..D-020); REQUIREMENTS.md gains the
  clarified-constraints block binding the decisions to REQ-01..34.
---/ci---
2026-09-27 10:43:18 +00:00
coreci e79102b901 decision(P00): clarification — v0.2 MVP ambiguities resolved (D-007..D-020)
---ci---
phase: 0
milestone: v0.2
status: clarify
decisions:
  - id: D-007
    decision: Backend layout = backend/ package at repo root, src-layout researchx with config/, methodologies/, adapters/, engine/, evidence/, trust/, api/ per ARCHITECTURE §Components
    rationale: Matches ARCHITECTURE.md component map 1:1; src-layout avoids import shadowing; uv manages the venv + Python 3.12
    confidence: 0.95
    alternatives: [flat single-package, api-first layout]
  - id: D-008
    decision: Provision uv + uv-managed Python 3.12 (official installer, user-local ~/.local/bin); system Python is 3.11.2
    rationale: REQ-33 mandates uv-managed Python 3.12; uv fetches a managed CPython so the system interpreter is irrelevant
    confidence: 0.9
    alternatives: [system 3.11 venv + pip (deviation from spec)]
  - id: D-009
    decision: Backend serves on 127.0.0.1:8000; frontend dev on :3000 calls backend via NEXT_PUBLIC_API_BASE_URL=http://127.0.0.1:8000; FastAPI CORS allows localhost:3000
    rationale: FastAPI/uvicorn defaults for a local-first single-user tool; frontend env var keeps the ApiClient boundary intact
    confidence: 0.85
    alternatives: [single-origin reverse proxy, fixed port 3001]
  - id: D-010
    decision: Run IDs = 8-char nanoid-style lowercase alnum slug (e.g. r-3f9k2q7z), generated by the API layer; storage layout = <storage_dir>/runs/<run_id>/
    rationale: Human-referenceable in URLs and folders; nanoid avoids UUID's file-name collisions with 8 chars at 62-alphabet entropy (~10^14)
    confidence: 0.8
    alternatives: [uuid4 hex, monotonic counter]
  - id: D-011
    decision: Ollama endpoints resolve from secrets scopes: base URLs via OLLAMA_BASE_URL (default https://ollama.com/v1) and fallback http://localhost:11434/v1; API key via OLLAMA_API_KEY from .ciagent/.env.secrets only
    rationale: config.json secrets.model scope already declares OLLAMA_API_KEY + OLLAMA_BASE_URL; env-file secrets-loader is the only resolution path per ship/verify credential rules
    confidence: 0.9
    alternatives: [config.json fields, interactive setup]
  - id: D-012
    decision: DuckDuckGo keyless fallback = HTML-lite endpoint (html.duckduckgo.com/html) scraped conservatively (top results, title+url+snippet); Tavily remains the default search adapter via TAVILY_API_KEY
    rationale: Keyless fallback must need zero credentials; the html endpoint requires none and is the standard keyless DDG surface; Tavily default per REQ-09
    confidence: 0.75
    alternatives: [duckduckgo_search python lib, searx instance]
  - id: D-013
    decision: OpenAPI client generation = openapi-typescript (types) + openapi-fetch (typed fetch client) into frontend/src/lib/api/generated/, bound behind the existing ApiClient interface in P3
    rationale: Zero-runtime overhead, TS-strict, produces a typed fetch function that wraps cleanly behind ApiClient; avoids heavyweight SDK codegen
    confidence: 0.8
    alternatives: [orval, @openapitools/openapi-generator-cli]
  - id: D-014
    decision: SSE transport = GET /api/runs/{id}/events via sse-starlette EventSourceResponse; typed event bus is asyncio.Queue-fed with pydantic event models (run_started, query_fired, source_visited, passage_extracted, state_changed, run_done, run_error)
    rationale: sse-starlette is the maintained FastAPI SSE standard; pydantic events give the typed bus REQ-16 demands; matches the MockApiClient replay contract already in the frontend
    confidence: 0.85
    alternatives: [websockets, polling]
  - id: D-015
    decision: Quote-anchoring fuzzy match = normalized token-subset + difflib SequenceMatcher ratio >= 0.85 as the primary check; exact substring match short-circuits; mismatch flagged in the ledger, never silently dropped
    rationale: difflib is stdlib (zero deps), 0.85 threshold balances recall/precision on quoted prose; flagged mismatches preserve trust-loop transparency
    confidence: 0.75
    alternatives: [rapidfuzz, embedding similarity]
  - id: D-016
    decision: URL liveness pass = HTTP HEAD/GET (follow redirects, 10s timeout) classifying 200-299=live, 3xx-stale-after-redirect-limit/stale-content=stale, 4xx/5xx/timeout/dead-url=dead; runs post-run per REQ-19; recheck at export
    rationale: Simple, deterministic classification REQ-19 names live/stale/dead; single GET with redirect following captures the common moved-page case
    confidence: 0.8
    alternatives: [HEAD-only, wayback fallback]
  - id: D-017
    decision: Engine durability = JSON state file per run (runs/<id>/state.json) rewritten atomically (tmp+rename) after every state transition + EventBus subscribers receive replay on resume; asyncio tasks checkpointed via state machine position, not mid-task
    rationale: REQ-15 demands pause/cancel/resume across restarts; atomic rewrite prevents torn files; transitions are natural checkpoint boundaries
    confidence: 0.85
    alternatives: [sqlite, append-only journal]
  - id: D-018
    decision: Run termination semantics for THIS pipeline run: phases ship P1..P4 + final P5; the milestone → main merge HALTS at the owner approval gate (merge_to_main escalation hook) exactly as v0.1 did — the run presents v0.2.5 and stops
    rationale: Owner-approved run directive (this session): 'P0–P5, halt at owner gate'; config.json escalation_hooks includes merge_to_main; v0.1 precedent (v0.1.8 halted, owner recorded approval in a follow-up)
    confidence: 1.0
    alternatives: [autonomous merge at full autonomy]
  - id: D-019
    decision: Deploy policy for this run = none; no LXC staging without an explicit owner directive (deploy escalation hook)
    rationale: Owner-approved run directive (this session): 'No deploys without owner directive'
    confidence: 1.0
    alternatives: [stage v0.2.x-uat at P5 gate]
  - id: D-020
    decision: Frontend stays on the v0.1 ApiClient boundary in P1/P2 (MockApiClient), P3 adds a generated OpenAPI client + ApiClient binding switch (env-flag RESEARCHX_API_MODE=mock|live with mock default), no component rewrites (REQ-26/REQ-54)
    rationale: Keeps REQ-54 zero-throwaway promise explicit; live binding only activated when the backend runs, mock remains default for dev/tests
    confidence: 0.9
    alternatives: [hard swap in P3, dual clients per component]
---/ci---

CLARIFY stage, milestone v0.2: 14 ambiguities resolved at full
autonomy (defaults accepted). Key resolutions: backend/ src-layout
package, uv + managed Python 3.12, run IDs as short slugs, DDG
html-lite keyless fallback, openapi-typescript client gen, sse-starlette
event transport, difflib quote anchoring at 0.85, JSON durable state
with atomic rewrites, owner-gate halt at P5, no deploys without
directive. PROJECT.md + REQUIREMENTS.md updated with the clarified
constraints.
2026-09-27 10:43:05 +00:00
coreci 9a005f5c64 docs(init): validate specification — milestone v0.2-mvp
---ci---
phase: 0
milestone: v0.2
status: specify
message: >-
  Branch gate ran: milestone/v0.2-mvp created from main (v0.1 complete
  and owner-approved, checkpoint cleared), phase/00-pre-execution
  checked out. Specification validated: PROJECT.md two-milestone
  objective, REQUIREMENTS.md REQ-01..34 (MVP) defined and traceable,
  milestone v0.2-mvp established in config.json (feature, tag line
  v0.2.x). Checkpoint written at stage specify.
requirements:
  covered: []
  partial: []
---/ci---
2026-09-27 10:42:35 +00:00