core/docs/handoff/wave-R2-backend-brief-2026-06-12.md
Shay 5182b495d5 docs(handoff): commit Wave 1 + Wave R2 brief packs incl. part 2 (R2-S/Runs/Packs/Vault/Settings)
Production-line record: the already-executed Wave 1 and R2-B/R2-T/R2-A
briefs, plus the new part-2 pack — R2-S (EvidenceSubject extension +
Proposals wrinkles, gating), then Runs, Packs, Vault (fail-closed),
Settings. Strictly sequential merges; operators stop after checks green.
2026-06-12 16:34:53 -07:00

3.9 KiB

Brief R2-B — Workbench Backend Read Substrate (/runs, /audit, /packs, /vault)

Date: 2026-06-12 Plan: docs/workbench/wave-R-mastery-revamp.md § Wave R2 (the route specs); this brief front-loads their BACKEND halves so R2 route briefs become frontend-only.

Agent: GPT5.5-Thinking (XHIGH) Scope: Python ONLY — workbench/ + its tests. Do not touch workbench-ui/ at all (R0d is concurrently changing it; zero-overlap is the parallel-safety guarantee). TS types land with each R2 route later. Parallel-safe with: R0d, R1. Merges independently of both.

Worktree

cd /Users/kaizenpro/Projects/core
git fetch origin
git worktree add ../core-wb-r2-backend origin/main -b feat/wb-r2-backend-reads
cd ../core-wb-r2-backend

Read first

  • workbench/api.py, workbench/readers.py, workbench/schemas.py, workbench/journal.py — the existing read-only patterns (envelope, pagination, error codes, size ceilings)
  • docs/workbench/api-contract-v1.md, docs/workbench/data-shapes-v1.md
  • docs/workbench/wave-R-mastery-revamp.md § Wave R2
  • CLAUDE.md "Security and Trust Boundaries" (path traversal, pack IDs)

Deliverables — read-only endpoints, { ok, generated_at, data/error } envelope

For each endpoint: deterministic ordering, ?limit=&offset= pagination on lists, 404 (not synthetic data) for unknown ids, no mutation anywhere, and the W-026 16 MiB read ceiling.

  1. GET /packs, GET /packs/{pack_id} — sources: language_packs/data/* manifests (and identity packs if cleanly readable). Surface manifest checksums VERBATIM (the UI's DigestBadge verify affordance depends on byte-honesty). Trust boundary (mandatory): validate pack_id against a safe pattern BEFORE any filesystem access; reject path traversal with a test proving it.

  2. GET /audit/events — merged read-only view over the deterministic audit sources that already exist on disk (reboot-event audit trail per ADR-0158, teaching review/ratification records, workbench operator telemetry). Stable total ordering (timestamp + tiebreak), each event tagged with source and mutation_boundary: bool. Do NOT invent an event store — this is a reader over existing artifacts.

  3. GET /runs, GET /runs/{session_id}investigate first: derive "run/session" only from artifacts that already exist (engine_state manifests/checkpoints, turn journal grouping). If no deterministic on-disk session boundary exists, ship what IS derivable and document the gap in the PR body — never synthesize.

  4. GET /vault/summary, GET /vault/entriesinvestigate first, optional: only if Shape B+ persisted engine_state provides a deterministic on-disk vault source (persistence is OPT-IN, often absent). If absent: return a typed evidence_unavailable error (the 501/unsupported pattern already used for /replay/), document the gap, and stop. Do NOT reach into live runtime memory; do NOT fake entries.

  5. Schemas in workbench/schemas.py for every new shape (dataclasses, same style as existing) — these become the source for the R1 schema-drift gate.

Tests (pytest, alongside the existing workbench API tests)

Per endpoint: list + get + 404 + pagination + deterministic ordering; path-traversal rejection for packs; a read-only proof (no writes outside nothing — assert no dirty tree after requests); envelope conformance.

Verification before push

uv run python -m pytest tests/ -k "workbench" -q     # adjust to the real test path
core test --suite smoke -q
git diff --stat origin/main                          # workbench/ + tests + docs ONLY — no workbench-ui/

PR title: feat(workbench): R2 backend read substrate — packs, audit, runs (+vault investigate)

PR body must state, per CLAUDE.md: the trust boundary enforced (pack_id validation, path confinement), and that no mutation path was added.