跳轉到

FE → BE wiring: resolved

Snapshot: 2026-05-23. All P0–P3 items from the original FE-agent report (see git log for the prior revision of this file) have shipped. contract.md is the single source of truth going forward; every row in §2 is now and the FE renders against the live BE without mocks.

The notes below are kept as a wiring summary so future agents can find the moving pieces without re-deriving them from commits.


Resolved items

Concern Resolution Commit / file
POST /investigations/{id}/messages not in /openapi.json spec.apply(app) cached the schema before the custom routes were registered. create_app now calls spec.openapi(app) a second time after every route is registered. src/workspace_app/api/app.py
DELETE /investigations/{id}/messages/current Already shipped on the BE; the FE now fires the DELETE alongside the local AbortController.abort so the agent loop tears down promptly. web/src/hooks/useAgent.tsx, web/src/api/real.ts
Files API (GET / PUT /investigations/{id}/files[...]) Shipped (Phase 5). src/workspace_app/api/app.py, tests/api/test_messages.py
Template seed on POST /investigation Shipped (Phase 2). Includes /brief.md, /drift.ipynb, /pareto.ipynb, /fishbone.canvas, /5-why.md, /report.v1.md, /data/reflow.zone3.sample.csv. src/workspace_app/rca/templates/default/
/report.md vs /report.v1.md Renamed the seed file so the FE's six initial design tabs all open. src/workspace_app/rca/templates/default/report.v1.md
Notebook cell execute (POST/DELETE .../cells/{idx}/execute) Shipped (Phase 9). FE's interruptCell now also fires the DELETE to actually stop the kernel. src/workspace_app/api/app.py, web/src/renderers/notebook/NotebookRenderer.tsx
POST .../kernel/restart Shipped (Phase 9). Exposed via api.restartKernel; UI affordance can be added once a kernel-status pill is wired. src/workspace_app/api/app.py, web/src/api/real.ts
POST /investigations/{id}/close Shipped (Phase 4). FE now has a Close dropdown in the top bar (Resolved / Abandoned) that calls the endpoint and navigates back to Home. src/workspace_app/api/app.py, web/src/pages/investigation/InvestigationShell.tsx
SPA bundle delivery The FE source lives in this repo's web/. web/dist/ is the build output; FastAPI's StaticFiles mount auto-picks it up. Build script: cd web && pnpm run build. vite.config.ts, src/workspace_app/api/app.py

Known polish items (not blocking)

All P0–P3 items shipped. Remaining v1 polish:

  • /-workspacefiles openapi leak — resolved by swapping __main__.py to MemoryFileStore (no specstar storage model = no auto-routes). SpecstarFileStore is still around if you want spec-backed persistence (and accept the route noise).
  • Restart kernel button — shipped. Status bar pill calls api.restartKernel for the currently-open notebook.
  • Upload file UI — shipped. Sidebar + opens a file picker, uploads via api.writeFile to /uploads/{filename} (8 MB cap, supports Blob/binary).
  • Settings panel — shipped. Replaces the prior alert with a modal (model picker / theme stub / about).
  • Sign-out — replaced with a "single-user · no auth in v1" popover note; full sign-in lands when multi-tenant ships.
  • Split view — shipped. Two independent panes; right pane has its own tab picker.
  • Terminal pane — shipped. POST /investigations/{id}/exec returns ExecResult; the bottom panel terminal has ↑/↓ history, ⌘L clear, exit-code indicators.

How to verify

# Backend
uv run python -m workspace_app   # 127.0.0.1:8000

# Frontend (only needed when iterating; production reads from web/dist)
cd web && pnpm run dev           # 5173 with proxy to :8000

Curl smoke:

curl -s -X POST http://127.0.0.1:8000/investigation \
  -H 'content-type: application/json' \
  -d '{"title":"smoke","owner":"default-user"}'
# -> { resource_id: "investigation:<uuid>", ... }

curl -s "http://127.0.0.1:8000/investigations/<urlencoded-id>/files"
# -> [ {path: "/brief.md", size: ...}, ..., {path: "/report.v1.md", ...} ]