From 7ac527ae40b4624b4996fae211b2ac2833d693ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9=20=D0=A1=D0=B5?= =?UTF-8?q?=D0=BB=D0=B5=D0=B7=D0=BD=D0=B5=D0=B2?= Date: Sun, 10 May 2026 11:59:31 +0300 Subject: [PATCH] Add NullOS Mission Control local agent recovery demo --- HACKATHON_SUBMISSION.md | 197 ++- MISSION_CONTROL_PLAN.md | 390 ++++++ README.md | 91 ++ docs/demo/.gitignore | 3 + docs/demo/mission-control-local-demo.md | 86 ++ docs/demo/mission-control-pr-package.md | 180 +++ docs/demo/mission-control-replay-artifact.md | 75 ++ .../nullhub-mission-control-live.png | Bin 0 -> 108481 bytes .../nullhub-mission-control-recovered.png | Bin 0 -> 108998 bytes scripts/mission_control_demo.sh | 148 +++ scripts/record_mission_control_demo.sh | 69 ++ src/api/meta.zig | 48 + src/api/mission_control.zig | 704 +++++++++++ src/api/mission_control/code_red.v1.json | 505 ++++++++ src/api/mission_control_replay.zig | 501 ++++++++ src/root.zig | 4 + src/server.zig | 10 +- tests/test_mission_control_smoke.sh | 72 ++ ui/src/lib/api/client.ts | 141 +++ ui/src/lib/components/Sidebar.svelte | 1 + ui/src/routes/mission-control/+page.svelte | 1095 +++++++++++++++++ ui/src/routes/observability/+page.svelte | 8 +- 22 files changed, 4272 insertions(+), 56 deletions(-) create mode 100644 MISSION_CONTROL_PLAN.md create mode 100644 docs/demo/.gitignore create mode 100644 docs/demo/mission-control-local-demo.md create mode 100644 docs/demo/mission-control-pr-package.md create mode 100644 docs/demo/mission-control-replay-artifact.md create mode 100644 docs/screenshots/nullhub-mission-control-live.png create mode 100644 docs/screenshots/nullhub-mission-control-recovered.png create mode 100755 scripts/mission_control_demo.sh create mode 100755 scripts/record_mission_control_demo.sh create mode 100644 src/api/mission_control.zig create mode 100644 src/api/mission_control/code_red.v1.json create mode 100644 src/api/mission_control_replay.zig create mode 100755 tests/test_mission_control_smoke.sh create mode 100644 ui/src/routes/mission-control/+page.svelte diff --git a/HACKATHON_SUBMISSION.md b/HACKATHON_SUBMISSION.md index 7c64695..2c35804 100644 --- a/HACKATHON_SUBMISSION.md +++ b/HACKATHON_SUBMISSION.md @@ -1,98 +1,189 @@ -# Agent Flight Recorder +# NullOS Mission Control ## Problem Discovered -NullWatch already provides the observability layer for the nullclaw ecosystem: -run summaries, spans, evals, OTLP ingest, cost, token usage, and failure context. -It also exports a NullHub-compatible manifest. NullHub already provides the -operator UI and orchestration pages, but it did not register NullWatch or expose -its tracing/eval data in the UI. +The nullclaw ecosystem already has the building blocks of a lightweight local +agent platform: NullHub for control, NullBoiler for orchestration, +NullTickets for tracker-backed work, and NullWatch for traces and evals. +What was missing was a memorable local demo that shows these ideas as one +operator experience. -## Chosen Solution +Without that vertical slice, a new contributor or hackathon judge has to infer +the platform story from separate repositories, APIs, and docs. -Add a local-first Observability cockpit to NullHub: +## Chosen Solution -- register `nullwatch` as a known component -- proxy `/api/observability/*` to a managed NullWatch instance -- add a Flight Recorder page for runs, spans, evals, cost, tokens, and errors -- document the local demo flow through NullHub's managed install path +Add a local-first Mission Control page to NullHub: + +- a deterministic backend mission API under `/api/mission-control` +- a versioned embedded replay fixture for scenario data +- a `/mission-control` control-room UI +- one cinematic workflow showing agent roles, checkpointing, test failure, + human intervention, recovered replay, review, and telemetry +- schema-versioned API responses and structured errors for invalid actions +- NullWatch-style trace references that map replay events to run ids, span ids, + operations, and eval keys +- a replay artifact export for sharing the current snapshot, source fixture, + and ecosystem mapping as JSON +- a local smoke test for the full mission lifecycle +- a judge-mode demo driver and macOS local video recorder +- screenshots and a written demo plan for PR review + +The demo is intentionally deterministic. It does not call hosted services, +require model keys, or depend on a running multi-repo stack. ## Why This Idea Was Chosen -This is stronger than a single CLI preflight because it connects multiple parts -of the ecosystem into a visible agent platform story: execution, orchestration, -task tracking, observability, and operations. It is still hackathon-sized because -it uses existing NullWatch APIs and NullHub UI patterns instead of changing core -agent runtime behavior. +This was chosen over a smaller CLI-only contribution because it creates a +stronger hackathon story: judges can see autonomy, orchestration, +observability, failure recovery, and human-in-the-loop control in under three +minutes. + +It belongs in NullHub because NullHub is already the control plane for the +ecosystem. The page can honestly present simulated NullTickets-style tasks, +NullBoiler-style checkpoints, and NullWatch-style telemetry while leaving a +clear future path to real cross-service wiring. ## What Was Implemented -- NullWatch component registration in the NullHub registry. -- Observability reverse proxy with optional bearer token forwarding. -- Sidebar entry and `/observability` UI page. -- API client methods for NullWatch summary, runs, spans, evals, and health. -- README documentation for the proxy and local demo setup. +- Added `src/api/mission_control.zig` with structured mission state, reset, + launch, recover, deterministic phase progression, telemetry, graph nodes, + graph edges, agent roles, failure details, and recovery details. +- Added `src/api/mission_control/code_red.v1.json` as the versioned replay + fixture for phase timing, graph, events, telemetry, and failure/recovery + metadata. +- Added `src/api/mission_control_replay.zig` to parse and validate replay + fixtures before serving mission state. +- Added validated trace references in mission events so the demo can deep-link + from Mission Control to `/observability?run_id=...` without requiring + NullWatch to be running for the local replay. +- Added explicit response metadata: `schema_version`, `mode`, `scenario_id`, + `scenario_version`, and `generated_at_ms`. +- Added `GET /api/mission-control/replay` to export the current snapshot, + source fixture, and NullTickets/NullBoiler/NullClaw/NullWatch mapping + metadata as a portable JSON artifact. +- Added transition guards so early recovery and duplicate launch return + actionable `409 Conflict` responses. +- Registered the Mission Control API in the NullHub server route table and API + metadata. +- Added typed frontend client methods for mission state and actions. +- Added a sidebar entry and `/mission-control` Svelte page with adaptive + polling, retry handling, trace chips, observability deep links, and responsive + mission panels. +- Added in-screen three-minute story beats and a failed-vs-recovered comparison + panel so the demo narrative remains visible during judging and PR review. +- Added a PR-ready plan file, README documentation, and screenshots. +- Added backend tests for mission path routing, idle state, failure state, + recovery state, action handlers, invalid transitions, and route semantics. +- Added replay fixture tests for duplicate ids, graph references, telemetry + references, trace references, ordering, required fields, and required phases. +- Added `tests/test_mission_control_smoke.sh` for live API validation. +- Added `scripts/mission_control_demo.sh` for a timed judge-mode mission run. +- Added `scripts/record_mission_control_demo.sh` and + `docs/demo/mission-control-local-demo.md` so the local demo can be recorded + as a review video artifact. +- Added `docs/demo/mission-control-replay-artifact.md` to document the export + schema and ecosystem mapping. +- Added `docs/demo/mission-control-pr-package.md` with the copy-ready PR title, + PR description, reviewer path, validation matrix, and three-minute hackathon + story. ## Files Changed -- `src/installer/registry.zig` -- `src/api/observability.zig` -- `src/api/proxy.zig` -- `src/api/components.zig` +- `MISSION_CONTROL_PLAN.md` +- `src/api/mission_control.zig` +- `src/api/mission_control_replay.zig` +- `src/api/mission_control/code_red.v1.json` - `src/api/meta.zig` - `src/root.zig` - `src/server.zig` - `ui/src/lib/api/client.ts` - `ui/src/lib/components/Sidebar.svelte` - `ui/src/routes/observability/+page.svelte` +- `ui/src/routes/mission-control/+page.svelte` +- `tests/test_mission_control_smoke.sh` +- `scripts/mission_control_demo.sh` +- `scripts/record_mission_control_demo.sh` +- `docs/demo/.gitignore` +- `docs/demo/mission-control-local-demo.md` +- `docs/demo/mission-control-replay-artifact.md` +- `docs/demo/mission-control-pr-package.md` +- `docs/screenshots/nullhub-mission-control-live.png` +- `docs/screenshots/nullhub-mission-control-recovered.png` - `README.md` - `HACKATHON_SUBMISSION.md` ## How To Test Or Demo -Start NullHub: +Run the backend tests: ```bash -zig build run -- serve --no-open +zig build test -Dembed-ui=false --summary all ``` -Install NullWatch from NullHub: +Build the UI: -1. Open the web UI. -2. Go to `Install Component`. -3. Select `NullWatch`. -4. Keep or set the API port to `7710`. -5. Finish the wizard. The installer starts the NullWatch instance and NullHub - discovers it automatically. +```bash +npm --prefix ui run build +``` -Optional sample data can be ingested through the NullHub proxy: +Start NullHub locally: ```bash -curl -X POST http://127.0.0.1:19800/api/observability/v1/spans \ - -H 'Content-Type: application/json' \ - -d '{"run_id":"demo-run-1","trace_id":"trace-demo-1","span_id":"span-1","source":"nullclaw","operation":"tool.call","status":"error","started_at_ms":1710000000000,"ended_at_ms":1710000001500,"tool_name":"shell","error_message":"tool call failed: command timed out","attributes_json":"{\"exit_code\":124}"}' +zig build run -- serve --host 127.0.0.1 --port 19802 --no-open +``` -curl -X POST http://127.0.0.1:19800/api/observability/v1/evals \ - -H 'Content-Type: application/json' \ - -d '{"run_id":"demo-run-1","eval_key":"tool_success","scorer":"deterministic","score":0.0,"verdict":"fail","dataset":"demo","notes":"The tool call timed out."}' +Run the live smoke test: + +```bash +NULLHUB_URL=http://127.0.0.1:19802 ./tests/test_mission_control_smoke.sh ``` -Open `/observability` in NullHub and inspect the NullWatch runs. +Run the automated local demo: + +```bash +MISSION_CONTROL_OPEN_BROWSER=1 ./scripts/mission_control_demo.sh +``` + +Export the current replay artifact: + +```bash +curl -fsS http://127.0.0.1:19802/api/mission-control/replay \ + -o mission-control-replay.json +``` + +Record a local macOS video artifact: + +```bash +./scripts/record_mission_control_demo.sh +``` + +The generated `.mov` is ignored by git and can be uploaded directly to the PR +discussion or hackathon submission. + +Open `/mission-control`, then: -## Screenshots +1. Click `Launch Mission`. +2. Watch the workflow progress through research, patching, checkpointing, and + test execution. +3. When the test fails, click `Fork From Checkpoint`. +4. Use the trace chips or failed/recovered run links to jump into Flight + Recorder deep links. +5. Watch the recovered run pass and complete review. -Flight Recorder overview: +Live mission state: -![NullHub Observability overview](docs/screenshots/nullhub-observability-overview.png) +![NullHub Mission Control live workflow](docs/screenshots/nullhub-mission-control-live.png) -Failure detail with tool-call error context: +Recovered mission: -![NullHub Observability failure detail](docs/screenshots/nullhub-observability-failure.png) +![NullHub Mission Control recovered workflow](docs/screenshots/nullhub-mission-control-recovered.png) ## Limitations And Future Improvements -- `NULLWATCH_URL` remains useful for pointing NullHub at an external NullWatch - instance, but the default demo path uses a managed NullWatch install. -- The first UI version renders a compact timeline, not a full waterfall chart. -- Run correlation with NullBoiler orchestration pages can be added as a follow-up - when both systems share stable run ids. +- The MVP uses deterministic demo state instead of real cross-service execution. +- The mission replay maps to NullTickets, NullBoiler, and NullWatch concepts, + but does not yet write into those services. +- A future version could add durable replay storage, side-by-side replay + comparison, exportable replay bundles, real NullWatch span hydration, and a + judge-mode one-click replay. diff --git a/MISSION_CONTROL_PLAN.md b/MISSION_CONTROL_PLAN.md new file mode 100644 index 0000000..de872b1 --- /dev/null +++ b/MISSION_CONTROL_PLAN.md @@ -0,0 +1,390 @@ +# NullOS Mission Control Plan + +## Product Goal + +Build the most memorable local-first AI-agent platform demo on top of the +nullclaw ecosystem: a three-minute control-room experience showing autonomous +work, live orchestration, failure, human intervention, replay/fork recovery, +and observability. + +This is a hackathon product slice, not a generic platform rewrite. + +## Demo Narrative + +1. Launch a mission from NullHub. +2. A task appears in the agent backlog. +3. Role-based agents move through research, code, test, and review. +4. Live telemetry updates: spans, evals, errors, tokens, cost. +5. A test step fails and the UI highlights the failing tool call. +6. The human forks from a checkpoint and injects a fix instruction. +7. The recovered run passes and the final screen compares failed vs recovered + execution. + +## MVP Scope + +- One NullHub page: `/mission-control`. +- One deterministic local mission scenario. +- A local mission API in NullHub that can: + - reset the mission + - launch the mission + - advance deterministic phases + - expose current mission state + - recover/fork the failed run +- Visual panels: + - mission status and current phase + - agent role board + - workflow graph + - event timeline + - telemetry strip + - failure/recovery panel +- No external services, secrets, or real model calls required for the MVP. + +## Production-Grade Hackathon Bar + +Mission Control is production-ready for the hackathon when it is a durable, +reviewable demo mode rather than a throwaway mock: + +- The API has a stable schema version, scenario identity, explicit demo-mode + metadata, and predictable action semantics. +- Invalid actions return actionable errors instead of mutating state silently. +- The UI is typed, resilient to API errors, responsive, and honest about the + deterministic local replay boundary. +- Tests cover the mission state machine, action routing, invalid transitions, + and API response shape. +- Documentation explains how to run, demo, validate, and extend the feature. +- The implementation leaves a clear path to real NullTickets, NullBoiler, and + NullWatch integration without pretending those services are already being + mutated by the demo. + +## One-Week Delivery Plan + +Day 1 - Harden the local Mission Control product slice. + +- Status: DONE +- Stable API schema and scenario metadata. +- Structured invalid-transition errors. +- Typed frontend contract. +- Adaptive polling, retry state, screenshots, and smoke test. + +Day 2 - Make replay data maintainable. + +- Status: DONE +- Moved scenario content into `src/api/mission_control/code_red.v1.json`. +- Added `src/api/mission_control_replay.zig` as the typed replay contract. +- Added fixture validation tests for schema version, duplicate ids, graph + references, telemetry references, ordering, required fields, and required + phases. + +Day 3 - Add observability affordances. + +- Status: DONE +- Link mission run ids and events to NullWatch-style trace/eval concepts. +- Add Flight Recorder deep links via `/observability?run_id=...`. +- Keep the UI useful without NullWatch running. + +Day 4 - Strengthen demo automation. + +- Status: DONE +- Add a judge-mode reset/launch/recover script or one-click replay action. +- Add a local presentation runbook and required local run-through before demo. +- Add a macOS video recording script for PR/hackathon review artifacts. +- Capture updated screenshots after the full flow. + +Day 5 - Add export/replay artifact. + +- Status: DONE +- Export current mission replay JSON for sharing and debugging. +- Document how the artifact maps to tasks, workflows, spans, evals, and + recovery. + +Day 6 - Polish the three-minute story. + +- Status: IN PROGRESS +- DONE: Added in-screen three-minute story beats so the demo has visible + presenter timing and narrative anchors. +- DONE: Added an explicit failed run vs recovered run comparison panel with + verdict, checkpoint, intervention, and trace links. +- Remaining: Test from a clean clone with only documented prerequisites. + +Day 7 - Stabilize for submission. + +- Status: DONE +- DONE: Run full validation. +- DONE: Freeze screenshots and demo script. +- DONE: Run the local demo end-to-end on the presentation machine. +- DONE: Record or refresh the Mission Control screenshot artifacts. +- DONE: Prepare PR title, PR description, reviewer path, validation matrix, and + hackathon narration in `docs/demo/mission-control-pr-package.md`. +- DONE: Record or refresh the optional `.mov` video artifact for upload outside + git. + +## Stretch Scope + +- Drive real NullTickets/NullBoiler/NullWatch APIs when configured. +- Side-by-side replay comparison. +- Animated graph edges and span waterfall. +- Judge mode: one button to reset and replay the full cinematic demo. +- Export mission replay bundle as JSON. + +## Iterations + +### Iteration 0 - Plan And Branch + +Status: DONE + +- Create a dedicated branch. +- Capture the plan in this file. +- Keep existing Flight Recorder PR work intact. + +### Iteration 1 - Mission State API + +Status: DONE + +- Add a small NullHub backend API under `/api/mission-control`. +- Use deterministic in-memory or file-backed demo state. +- Support: + - `GET /api/mission-control/state` + - `POST /api/mission-control/reset` + - `POST /api/mission-control/launch` + - `POST /api/mission-control/recover` +- Include enough structured state for UI: + - phases + - agents + - graph nodes/edges + - events + - telemetry + - failed run and recovered run summaries + +Definition of done: + +- Unit tests cover initial state, launch, phase advancement, reset, and recover. +- API routes are registered in NullHub without affecting existing routes. + +### Iteration 2 - Mission Control UI + +Status: DONE + +- Add `/mission-control`. +- Poll state every second while mission is active. +- Render: + - launch/recover/reset controls + - graph visualization + - role board + - mission timeline + - telemetry cards + - failure/recovery comparison + +Definition of done: + +- The page works without external services. +- A judge can understand the narrative by watching the screen. + +### Iteration 3 - Demo Flow Polish + +Status: DONE + +- Make the mission auto-progress after launch. +- Add clear failure moment. +- Add recovery moment after clicking recover. +- Ensure visual states are cinematic but still readable. + +Definition of done: + +- The whole demo can be completed in under three minutes. + +### Iteration 4 - Ecosystem Integration Hooks + +Status: DONE + +- Shape mission events so they can map to Observability runs later. +- Show NullWatch-style run ids. +- Preserve future path to real NullTickets/NullBoiler/NullWatch integration. + +Definition of done: + +- The MVP is honest about what is simulated and what maps to real ecosystem + components. + +### Iteration 5 - Validation And Demo Assets + +Status: DONE + +- Run Zig tests. +- Run Svelte build. +- Capture screenshots. +- Update README or hackathon submission notes. + +Definition of done: + +- Local validation commands pass or blockers are documented. +- Demo script is written and screenshots are committed. + +### Iteration 6 - Production Hardening + +Status: DONE + +- Add explicit API schema/demo metadata. +- Reject invalid transitions with structured errors. +- Type Mission Control frontend state instead of using `any`. +- Make polling adaptive and UI states clearer. +- Add tests for invalid actions and response shape. + +Definition of done: + +- Mission Control behaves predictably under repeated clicks, refreshes, + invalid actions, and API failures. +- Validation commands still pass after the hardening pass. + +### Iteration 7 - Week-Scale Platform Path + +Status: DONE + +- Replaced hardcoded scenario data with a versioned replay fixture. +- Added validated NullWatch-style trace refs to mission timeline events. +- Added Flight Recorder deep links that work as local affordances and can point + at real NullWatch runs when configured. +- Added a local smoke-test script for the full demo sequence. +- Kept optional mission replay JSON export as the Day 5 follow-up instead of + mixing artifact export into the observability slice. + +Definition of done: + +- The hackathon demo remains local-first while becoming progressively closer to + real cross-service orchestration. + +### Iteration 8 - Demo Automation And Recording + +Status: DONE + +- Added `scripts/mission_control_demo.sh` as a portable judge-mode driver. +- Added `scripts/record_mission_control_demo.sh` for local macOS video capture + via `screencapture`. +- Added `docs/demo/mission-control-local-demo.md` with the local run-through, + video recording steps, presenter script, and pre-demo quality gate. +- Kept generated `.mov` files ignored so large local review artifacts do not + pollute the source diff. + +Definition of done: + +- A reviewer can run the mission without manual timing. +- A presenter can record a local video artifact from the same deterministic + flow used by the smoke test. + +### Iteration 9 - Replay Artifact Export + +Status: DONE + +- Added `GET /api/mission-control/replay` as a read-only export endpoint. +- Export includes the current snapshot, source replay fixture, fixture path, + schema identity, and ecosystem mapping metadata. +- Added `Export Replay` in the Mission Control UI. +- Added smoke/demo validation for the replay artifact. +- Added `docs/demo/mission-control-replay-artifact.md`. + +Definition of done: + +- A reviewer can export a single JSON file that explains the current mission + state and how the local replay maps to NullTickets, NullBoiler, NullClaw, and + NullWatch concepts. + +### Iteration 10 - Three-Minute Story Polish + +Status: DONE + +- Added a compact story strip to `/mission-control` with six timed beats: + launch, checkpoint, failure, intervention, replay, and review. +- Added a `Failure Recovery` comparison panel that makes the failed run, + recovered run, checkpoint, human instruction, verdict transition, and + observability links visible without presenter narration. +- Kept the change frontend-only because the existing mission state API already + exposes the required evidence. + +Definition of done: + +- A judge can understand the failure/recovery arc by reading the screen during + the live replay. +- `npm --prefix ui run build` passes after the polish change. + +### Iteration 11 - PR Package And Submission Notes + +Status: DONE + +- Added `docs/demo/mission-control-pr-package.md` with a copy-ready PR title, + PR description, reviewer path, three-minute story, validation matrix, video + artifact instructions, scope boundaries, and future work. +- Linked the PR package from the README demo section and project tree. +- Updated Day 7 status so the remaining final-submission task is explicit: + upload the ignored local `.mov` artifact if the PR or hackathon submission + needs an attached video. + +Definition of done: + +- A reviewer can understand what to run, what changed, why it matters, and what + validation was performed from one file. +- The PR package is separate from the broader hackathon notes so it can be + pasted into GitHub without editing unrelated documentation. + +### Iteration 12 - Final Local Demo Recording + +Status: DONE + +- Ran the final local validation matrix. +- Started NullHub on `127.0.0.1:19802`. +- Ran the live smoke test, judge-mode demo driver, replay export check, and + macOS recording script. +- Refreshed the ignored local video artifact at + `docs/demo/nullhub-mission-control-demo.mov`. + +Definition of done: + +- The demo can be run and recorded locally from the documented commands. +- The video artifact is available for manual upload but remains excluded from + the source diff. + +## Three-Minute Script + +0:00 - Open `/mission-control`; click `Launch Mission`. + +0:30 - Research and coding phases light up. Timeline records task claim, model +planning, code patch, and checkpoint creation. + +1:00 - Test phase fails. The graph marks `test` red, telemetry increments errors, +and the failure panel shows `zig build test exited with status 1`. + +1:30 - Click `Fork From Checkpoint`. The UI shows the human instruction: +`apply missing validation guard`. + +2:00 - Recovered run replays from checkpoint and passes tests. + +2:30 - Review phase passes. Final comparison shows failed run vs recovered run, +cost, duration, and eval verdict. + +## Technical Shape + +```mermaid +flowchart LR + H["NullHub /mission-control"] --> A["/api/mission-control/state"] + H --> C["/api/mission-control/actions"] + C --> S["Mission demo state"] + S --> T["NullTickets-like tasks/events"] + S --> B["NullBoiler-like workflow/checkpoints"] + S --> W["NullWatch-like spans/evals"] +``` + +## Risks + +- Real cross-service orchestration can consume the week. Control this by making + the MVP deterministic first and adding integration hooks later. +- Visual polish can expand without limit. Keep one page and one scenario. +- If backend state becomes complicated, switch to a static replay bundle with + action-controlled phase transitions. + +## Fallback + +If Mission Control slips, ship a focused Time-Travel Debugger: + +- failed run +- checkpoint +- forked recovered run +- state/span diff +- screenshots and demo script diff --git a/README.md b/README.md index f01ef27..db1c387 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ NullTickets, NullWatch). - **Managed instance admin API** -- instance-scoped status, config, models, cron, channels, and skills routes for managed NullClaw installs - **Orchestration UI** -- workflow editor, poll-based run monitoring, checkpoint forking, encoded workflow/run/store links, and key-value store browser (proxied to NullTickets through NullHub) - **Observability cockpit** -- local NullWatch run summaries, span timelines, eval results, token usage, cost, and error context through a NullHub proxy +- **Mission Control demo** -- local-first agent mission replay with orchestration, role-based agents, failure, checkpoint recovery, and live telemetry in one screen ## Quick Start @@ -151,6 +152,83 @@ Local NullWatch setup: -d '{"run_id":"demo-run-1","eval_key":"tool_success","scorer":"deterministic","score":0.0,"verdict":"fail","dataset":"demo","notes":"The tool call timed out."}' ``` +**Mission Control API** -- requests to `/api/mission-control/*` drive a +deterministic local demo scenario for the `/mission-control` page. The demo +does not require hosted infrastructure or model secrets; it shows how +NullTickets-style tasks, NullBoiler-style workflow checkpoints, and +NullWatch-style traces can fit into one operator view. Responses include a +schema version, scenario id, deterministic replay mode, controls, graph, +timeline, telemetry, NullWatch-style run/span/eval trace references, and +structured conflict errors for invalid actions. The scenario lives in a +versioned embedded replay fixture at +`src/api/mission_control/code_red.v1.json`; `zig build test` validates fixture +schema, references, ordering, required phases, graph links, and telemetry phase +coverage. Mission timeline trace links deep-link to `/observability?run_id=...` +so a real NullWatch instance can attach detailed spans and evals without making +the local demo depend on external infrastructure. `GET /api/mission-control/replay` +exports the current snapshot, source fixture, and ecosystem mapping metadata as +a portable JSON artifact for debugging and review. + +### Mission Control Demo + +Start NullHub locally and open `/mission-control`: + +```bash +zig build run -- serve --host 127.0.0.1 --port 19802 --no-open +``` + +The page provides `Reset`, `Launch Mission`, and `Fork From Checkpoint` +controls. Launching the mission advances a deterministic agent workflow through +research, patching, checkpointing, test failure, human intervention, recovered +test pass, and review completion. Timeline events include trace chips that map +the cinematic replay back to local NullWatch-style run ids, span ids, operations, +and eval keys. The page also includes timed story beats and a failed-vs-recovered +comparison panel so the three-minute demo can be followed directly from the +screen. + +Run the judge-mode demo driver against a started server: + +```bash +MISSION_CONTROL_OPEN_BROWSER=1 ./scripts/mission_control_demo.sh +``` + +Record a local macOS video artifact for PR or hackathon review: + +```bash +./scripts/record_mission_control_demo.sh +``` + +The generated video defaults to `docs/demo/nullhub-mission-control-demo.mov` and +is ignored by git so it can be uploaded directly to the PR discussion or +hackathon submission. See `docs/demo/mission-control-local-demo.md` for the +full presenter runbook and `docs/demo/mission-control-pr-package.md` for the +copy-ready PR title, description, validation matrix, and reviewer path. + +Export the current replay artifact: + +```bash +curl -fsS http://127.0.0.1:19802/api/mission-control/replay \ + -o mission-control-replay.json +``` + +The same export is available from the `Export Replay` button in Mission Control. +See `docs/demo/mission-control-replay-artifact.md` for the artifact shape and +ecosystem mapping. + +Run the live API smoke test against a started server: + +```bash +NULLHUB_URL=http://127.0.0.1:19802 ./tests/test_mission_control_smoke.sh +``` + +Live mission state: + +![NullHub Mission Control live workflow](docs/screenshots/nullhub-mission-control-live.png) + +Recovered mission: + +![NullHub Mission Control recovered workflow](docs/screenshots/nullhub-mission-control-recovered.png) + ### Observability Screenshots Flight Recorder overview: @@ -182,6 +260,8 @@ End-to-end: ```bash ./tests/test_e2e.sh +NULLHUB_URL=http://127.0.0.1:19802 ./tests/test_mission_control_smoke.sh +MISSION_CONTROL_OPEN_BROWSER=1 ./scripts/mission_control_demo.sh ``` `zig build test-integration` runs structured backend HTTP integration tests @@ -206,6 +286,9 @@ src/ api/ # REST endpoints (components, instances, wizard, ...) orchestration.zig # Reverse proxy to NullBoiler orchestration API observability.zig # Reverse proxy to NullWatch tracing/eval API + mission_control.zig # Local deterministic agent mission demo API + mission_control_replay.zig # Typed replay fixture parser and validator + mission_control/ # Embedded Mission Control replay fixtures core/ # Manifest parser, state, platform, paths installer/ # Download, build, UI module fetching supervisor/ # Process spawn, health checks, manager @@ -213,10 +296,18 @@ ui/src/ routes/ # SvelteKit pages orchestration/ # Orchestration pages (dashboard, workflows, runs, store) observability/ # NullWatch flight recorder page + mission-control/ # Local agent mission control room demo lib/components/ # Reusable Svelte components orchestration/ # GraphViewer, StateInspector, RunEventLog, InterruptPanel, # CheckpointTimeline, WorkflowJsonEditor, NodeCard, SendProgressBar lib/api/ # Typed API client tests/ test_e2e.sh # End-to-end test script +scripts/ + mission_control_demo.sh # Judge-mode local demo driver + record_mission_control_demo.sh # macOS local video recorder for the demo +docs/demo/ + mission-control-local-demo.md # Presenter runbook and recording instructions + mission-control-replay-artifact.md # Replay JSON artifact schema and mapping + mission-control-pr-package.md # Copy-ready PR body and reviewer checklist ``` diff --git a/docs/demo/.gitignore b/docs/demo/.gitignore new file mode 100644 index 0000000..4b9b9f0 --- /dev/null +++ b/docs/demo/.gitignore @@ -0,0 +1,3 @@ +*.mov +*.mp4 +*.webm diff --git a/docs/demo/mission-control-local-demo.md b/docs/demo/mission-control-local-demo.md new file mode 100644 index 0000000..fd8e80f --- /dev/null +++ b/docs/demo/mission-control-local-demo.md @@ -0,0 +1,86 @@ +# Mission Control Local Demo + +This is the local runbook for a live hackathon presentation and video capture. +It assumes NullHub is running locally and does not require hosted services, +model keys, or external infrastructure. + +## Start NullHub + +```bash +zig build run -- serve --host 127.0.0.1 --port 19802 --no-open +``` + +Open: + +```text +http://127.0.0.1:19802/mission-control +``` + +## Run The Judge-Mode Demo + +In a second terminal: + +```bash +MISSION_CONTROL_OPEN_BROWSER=1 ./scripts/mission_control_demo.sh +``` + +The script resets the mission, launches the local replay, waits for the +validation failure, forks from the checkpoint, waits for recovered completion, +verifies that the failed and recovered timeline events carry trace refs, and +checks that `/api/mission-control/replay` exports a completed artifact. + +## Export A Replay Artifact + +The current Mission Control state can be exported as JSON: + +```bash +curl -fsS http://127.0.0.1:19802/api/mission-control/replay \ + -o mission-control-replay.json +``` + +The same export is available from the `Export Replay` button in the UI. The +artifact contains the current snapshot, the source fixture, and the ecosystem +mapping used to explain the local replay. + +## Record A Local Video + +On macOS: + +```bash +./scripts/record_mission_control_demo.sh +``` + +The script opens `/mission-control`, records the screen with +`screencapture`, and drives the mission automatically. The default output is: + +```text +docs/demo/nullhub-mission-control-demo.mov +``` + +The video file is intentionally ignored by git because it is a local review +artifact. Upload it directly to the hackathon submission or PR discussion. + +If macOS asks for Screen Recording permission, allow it in System Settings and +rerun the command. + +## Presenter Script + +1. Show that the demo is local-first: one NullHub server, no external services. +2. Launch the mission and call out the role board, workflow graph, and telemetry. +3. Pause at the failure: the test tool fails, errors increment, and recovery is + blocked until the failure phase. +4. Click or let the script trigger checkpoint recovery. +5. Show the recovered run, passing eval verdict, and trace links into Flight + Recorder via `/observability?run_id=...`. +6. Export the replay artifact to show the scenario can be reviewed after the + live demo. + +## Pre-Demo Quality Gate + +```bash +zig build test -Dembed-ui=false --summary all +npm --prefix ui run build +zig build test --summary all +NULLHUB_URL=http://127.0.0.1:19802 ./tests/test_mission_control_smoke.sh +MISSION_CONTROL_OPEN_BROWSER=1 ./scripts/mission_control_demo.sh +``` diff --git a/docs/demo/mission-control-pr-package.md b/docs/demo/mission-control-pr-package.md new file mode 100644 index 0000000..e4caba6 --- /dev/null +++ b/docs/demo/mission-control-pr-package.md @@ -0,0 +1,180 @@ +# Mission Control PR Package + +This file is the copy-ready review package for the NullOS Mission Control +hackathon contribution. + +## Suggested PR Title + +Add NullOS Mission Control local agent recovery demo + +## Suggested PR Description + +Adds a local-first Mission Control demo to NullHub: a three-minute control-room +experience for lightweight agent infrastructure. + +The demo shows a deterministic agent mission from launch to failure, human +checkpoint recovery, recovered validation, review, trace links, telemetry, and +replay export. It is designed to run locally without hosted services, model +keys, or external infrastructure. + +What changed: + +- Added `/api/mission-control/*` for mission state, reset, launch, recovery, + and replay export. +- Added a versioned replay fixture at + `src/api/mission_control/code_red.v1.json`. +- Added replay fixture parsing and validation in + `src/api/mission_control_replay.zig`. +- Added `/mission-control` UI with mission controls, role board, workflow + graph, telemetry, timeline, trace links, story beats, and failed-vs-recovered + comparison. +- Added deep links from mission events to `/observability?run_id=...`. +- Added local smoke test, judge-mode demo driver, macOS video recorder, + screenshots, README docs, and hackathon submission notes. + +Why: + +NullHub already acts as the control plane for the nullclaw ecosystem, and the +surrounding repositories already sketch out runtime, orchestration, task state, +and observability. What was missing was a memorable local vertical slice that +lets reviewers see those concepts working as one operator experience. + +This PR keeps the demo deterministic and honest: it does not pretend to mutate +real NullTickets, NullBoiler, NullClaw, or NullWatch services. Instead it +provides a stable local replay with explicit ecosystem mapping and a future path +for real service hydration. + +Validation performed: + +```bash +zig build test -Dembed-ui=false --summary all +npm --prefix ui run build +zig build test --summary all +NULLHUB_URL=http://127.0.0.1:19802 ./tests/test_mission_control_smoke.sh +MISSION_CONTROL_OPEN_BROWSER=0 ./scripts/mission_control_demo.sh +git diff --check +``` + +Demo: + +```bash +zig build run -- serve --host 127.0.0.1 --port 19802 --no-open +MISSION_CONTROL_OPEN_BROWSER=1 ./scripts/mission_control_demo.sh +``` + +Open: + +```text +http://127.0.0.1:19802/mission-control +``` + +Screenshots: + +- `docs/screenshots/nullhub-mission-control-live.png` +- `docs/screenshots/nullhub-mission-control-recovered.png` + +## Reviewer Path + +1. Start NullHub: + + ```bash + zig build run -- serve --host 127.0.0.1 --port 19802 --no-open + ``` + +2. Open the UI: + + ```text + http://127.0.0.1:19802/mission-control + ``` + +3. Run the automated demo in another terminal: + + ```bash + MISSION_CONTROL_OPEN_BROWSER=1 ./scripts/mission_control_demo.sh + ``` + +4. Watch the page move through: + + - launch + - research + - patching + - checkpoint + - test failure + - human fork from checkpoint + - recovered validation + - review complete + +5. Open a trace link or export the replay artifact: + + ```bash + curl -fsS http://127.0.0.1:19802/api/mission-control/replay \ + -o mission-control-replay.json + ``` + +## Three-Minute Hackathon Story + +0:00 - Launch the mission from NullHub. + +0:30 - Agents light up on the role board and workflow graph. + +1:00 - Tests fail. The graph marks the tool step red, telemetry increments +errors, and the timeline points at the failed NullWatch-style eval. + +1:30 - The operator forks from the checkpoint with the instruction +`apply missing validation guard`. + +2:00 - The recovered run replays validation and passes. + +2:30 - The final screen compares failed and recovered runs, with trace links and +exportable replay evidence. + +## Latest Local Validation + +Last run: 2026-05-10 + +| Command | Result | +| --- | --- | +| `npm --prefix ui run build` | pass | +| `zig build test -Dembed-ui=false --summary all` | pass | +| `zig build test --summary all` | pass | +| `NULLHUB_URL=http://127.0.0.1:19802 ./tests/test_mission_control_smoke.sh` | pass | +| `MISSION_CONTROL_OPEN_BROWSER=0 ./scripts/mission_control_demo.sh` | pass | +| `git diff --check` | pass | +| `./scripts/record_mission_control_demo.sh` | pass | + +## Video Artifact + +On macOS: + +```bash +./scripts/record_mission_control_demo.sh +``` + +The generated video defaults to: + +```text +docs/demo/nullhub-mission-control-demo.mov +``` + +The video is ignored by git and can be uploaded to PR discussion or the +hackathon submission. + +Latest local recording: 2026-05-10, `36M`. + +## Scope Boundaries + +This PR intentionally does not: + +- run real model calls; +- require hosted infrastructure; +- require NullTickets, NullBoiler, NullClaw, or NullWatch to be running; +- mutate real task or workflow state; +- replace the existing observability page. + +## Future Work + +- Hydrate replay trace panels from a running NullWatch instance when available. +- Connect real NullBoiler workflow run ids and checkpoint metadata. +- Compare failed and recovered replay artifacts side by side. +- Add durable mission replay storage. +- Add a one-click judge replay button in the UI. diff --git a/docs/demo/mission-control-replay-artifact.md b/docs/demo/mission-control-replay-artifact.md new file mode 100644 index 0000000..4cf6e78 --- /dev/null +++ b/docs/demo/mission-control-replay-artifact.md @@ -0,0 +1,75 @@ +# Mission Control Replay Artifact + +Mission Control exposes the current deterministic replay as JSON: + +```text +GET /api/mission-control/replay +``` + +The artifact is intended for local debugging, PR review, and hackathon +submission evidence. It does not mutate runtime state and does not require +NullTickets, NullBoiler, NullClaw, or NullWatch to be running. + +## Shape + +The exported JSON contains: + +- `artifact_schema_version` - version of the export wrapper. +- `artifact_kind` - `nullhub.mission_control.replay`. +- `generated_at_ms` - export timestamp. +- `replay_fixture_path` - repository path of the embedded scenario fixture. +- `scenario_id`, `scenario_version`, `mode` - replay identity. +- `snapshot` - the current rendered Mission Control state. +- `replay_fixture` - the source fixture used to derive the replay. +- `ecosystem_mapping` - how the fixture maps to nullclaw ecosystem concepts. + +## Ecosystem Mapping + +`ecosystem_mapping.nulltickets` points to tracker-style evidence: + +- `events[source=nulltickets]` +- `graph.nodes[kind=tracker]` + +`ecosystem_mapping.nullboiler` points to orchestration evidence: + +- phase timing and workflow graph edges +- `checkpoint_id` +- failed and recovered run ids +- human fork instruction + +`ecosystem_mapping.nullclaw` points to agent evidence: + +- role-based agents +- agent graph nodes +- NullClaw-style event source entries + +`ecosystem_mapping.nullwatch` points to observability evidence: + +- failed and recovered run ids +- `events[].trace` +- telemetry counters +- failure and recovery run panels + +## Local Export + +Start NullHub: + +```bash +zig build run -- serve --host 127.0.0.1 --port 19802 --no-open +``` + +Export the current replay: + +```bash +curl -fsS http://127.0.0.1:19802/api/mission-control/replay \ + -o mission-control-replay.json +``` + +Or use the UI button: + +```text +/mission-control -> Export Replay +``` + +The exported JSON can be attached to PR discussion or used as a compact record +of the local demo state at the moment it was captured. diff --git a/docs/screenshots/nullhub-mission-control-live.png b/docs/screenshots/nullhub-mission-control-live.png new file mode 100644 index 0000000000000000000000000000000000000000..160ee833c0d28cd10e7cce3655581c4b2e8dfe77 GIT binary patch literal 108481 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 literal 0 HcmV?d00001 diff --git a/docs/screenshots/nullhub-mission-control-recovered.png b/docs/screenshots/nullhub-mission-control-recovered.png new file mode 100644 index 0000000000000000000000000000000000000000..059d5b0a086c605fdf25dcb1e52dd4c825cf0c9f GIT binary patch literal 108998 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

`G_toT0M75X(cVqf{i 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
  • fRfby`9; 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
  • Q6N>s@^Y|c9e+~%h_<-b#*L$njvfckrUA`UfSUz)!nOd_Q+~9OnIwUT)F4pbm^wFz4=zAqFV%h@Iz+lz2e1w-TECUwoC)K z%0gdwy5V6}coB9wvo^u1|{qPhC(mwKu_zjo%vq3frP)zo;ww|f5i_v(>>#k;Wc zYgfp4Tx4n7^q~G)p7zvtE4PKpuAObLu}$@i&e^@W%R2qPaQtCIUUc)LTmN(vaC7sr zL(@;q%9!NHByixtvMSg)O$Wl&vY7-x-h~3{Z&-yIOzgH;9~K4!#;>JOxrv2}LQrS< zFaXOtq4}#Xsk8vsLil*-w&va~+<6gJdmd;J5EIw>xKqp5NdkDfq41=lfVUf4qJ1o{ zr?#2J=1k;-I6;BI;-k2fywlm%w|8sSc})hNyp?D=C-2oOo%b(zeR+(%(@NN&N4@=j zz2@b@W5#E%ty>nS?HdHN>Ojje_8TW_CO|U@hY4t4WdK9%H)t31|NkL%OMU?vY@p@@ ZGeb?NJFC&UtuY{XdAj setTimeout(resolve, ms)); +} + +function assert(condition, message) { + if (!condition) throw new Error(message); +} + +async function api(path, method = 'GET') { + let res; + try { + res = await fetch(`${base}${path}`, { method }); + } catch (error) { + throw new Error(`Cannot reach NullHub at ${base}: ${error.message}`); + } + + const text = await res.text(); + const body = text ? JSON.parse(text) : null; + return { status: res.status, body }; +} + +function openMissionPage() { + const command = + process.platform === 'darwin' + ? 'open' + : process.platform === 'win32' + ? 'cmd' + : 'xdg-open'; + const args = process.platform === 'win32' ? ['/c', 'start', '', missionUrl] : [missionUrl]; + const child = spawn(command, args, { detached: true, stdio: 'ignore' }); + child.unref(); +} + +function formatState(state) { + return [ + `phase=${state.phase}`, + `status=${state.status}`, + `progress=${state.progress}%`, + `run=${state.active_run_id || '-'}`, + `spans=${state.telemetry?.spans ?? 0}`, + `evals=${state.telemetry?.evals ?? 0}`, + `verdict=${state.telemetry?.verdict || '-'}`, + ].join(' '); +} + +function printStep(label, state) { + console.log(`${label.padEnd(12)} ${formatState(state)}`); +} + +async function expectOk(path, method) { + const response = await api(path, method); + assert(response.status === 200, `${method} ${path} returned HTTP ${response.status}`); + return response.body; +} + +async function waitFor(label, predicate) { + const started = Date.now(); + let lastPhase = ''; + let lastState = null; + + while (Date.now() - started < timeoutMs) { + const response = await api('/api/mission-control/state'); + assert(response.status === 200, `state returned HTTP ${response.status}`); + lastState = response.body; + + if (lastState.phase !== lastPhase) { + printStep(label, lastState); + lastPhase = lastState.phase; + } + + if (predicate(lastState)) return lastState; + await sleep(pollMs); + } + + throw new Error(`Timed out waiting for ${label}. Last state: ${lastState ? formatState(lastState) : 'none'}`); +} + +console.log('NullOS Mission Control judge demo'); +console.log(`Base URL: ${base}`); +console.log(`Open UI: ${missionUrl}`); + +let state = await expectOk('/api/mission-control/reset', 'POST'); +assert(state.schema_version === 1, 'unexpected mission schema version'); +assert(state.mode === 'deterministic_local_replay', 'unexpected mission mode'); +printStep('reset', state); + +if (openBrowser) { + openMissionPage(); + console.log('browser opened mission-control page'); +} + +await sleep(prerollMs); + +state = await expectOk('/api/mission-control/launch', 'POST'); +printStep('launch', state); + +state = await waitFor('primary', (candidate) => candidate.status === 'intervention_required' && candidate.controls?.can_recover === true); +const failedEvent = state.events?.find((event) => event.title === 'Validation failed'); +assert(failedEvent?.trace?.run_id === 'run-demo-failed-test', 'missing failed run trace reference'); +assert(failedEvent?.trace?.eval_key === 'tool_success', 'missing failed eval trace reference'); +console.log('failure human intervention point reached'); + +await sleep(failureHoldMs); + +state = await expectOk('/api/mission-control/recover', 'POST'); +assert(state.recovered_run_id === 'run-demo-recovered-fork', 'missing recovered run id'); +printStep('recover', state); + +state = await waitFor('recovery', (candidate) => candidate.status === 'completed' && candidate.telemetry?.verdict === 'pass'); +const recoveredEvent = state.events?.find((event) => event.title === 'Recovered tests passed'); +assert(recoveredEvent?.trace?.run_id === 'run-demo-recovered-fork', 'missing recovered run trace reference'); + +await sleep(completionHoldMs); + +const artifactResponse = await api('/api/mission-control/replay'); +assert(artifactResponse.status === 200, `replay export returned HTTP ${artifactResponse.status}`); +assert(artifactResponse.body?.artifact_kind === 'nullhub.mission_control.replay', 'unexpected replay artifact kind'); +assert(artifactResponse.body?.snapshot?.status === 'completed', 'replay export did not capture completed snapshot'); + +console.log('completed recovered mission passed'); +console.log(`failed run: ${state.failed_run_id}`); +console.log(`recovered: ${state.recovered_run_id}`); +console.log(`trace link: ${base}/observability?run_id=${encodeURIComponent(state.recovered_run_id)}`); +console.log(`export: ${base}/api/mission-control/replay`); +NODE diff --git a/scripts/record_mission_control_demo.sh b/scripts/record_mission_control_demo.sh new file mode 100755 index 0000000..22b81ed --- /dev/null +++ b/scripts/record_mission_control_demo.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +set -euo pipefail + +BASE_URL="${NULLHUB_URL:-http://127.0.0.1:19802}" +OUTPUT="${MISSION_CONTROL_VIDEO_OUT:-docs/demo/nullhub-mission-control-demo.mov}" +RECORD_SECONDS="${MISSION_CONTROL_RECORD_SECONDS:-36}" +DEMO_SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "$DEMO_SCRIPT_DIR/.." && pwd)" +OUTPUT_ABS="$REPO_ROOT/$OUTPUT" + +if [[ "$(uname -s)" != "Darwin" ]]; then + echo "Mission Control video recording currently uses macOS screencapture." >&2 + echo "Run scripts/mission_control_demo.sh for the portable live demo driver." >&2 + exit 2 +fi + +if ! command -v screencapture >/dev/null 2>&1; then + echo "screencapture is required for local video recording on macOS." >&2 + exit 2 +fi + +mkdir -p "$(dirname "$OUTPUT_ABS")" +rm -f "$OUTPUT_ABS" + +node - "$BASE_URL" <<'NODE' +const base = process.argv[2].replace(/\/$/, ''); +try { + const res = await fetch(`${base}/api/mission-control/state`); + if (!res.ok) throw new Error(`HTTP ${res.status}`); +} catch (error) { + console.error(`Cannot reach NullHub at ${base}: ${error.message}`); + process.exit(1); +} +NODE + +echo "Recording Mission Control demo to $OUTPUT_ABS" +echo "Open UI: $BASE_URL/mission-control" +echo "If macOS asks for Screen Recording permission, allow it and rerun this script." + +open "$BASE_URL/mission-control" >/dev/null 2>&1 || true +sleep 1 + +screencapture -v -V "$RECORD_SECONDS" -k "$OUTPUT_ABS" & +RECORDER_PID=$! + +cleanup() { + if kill -0 "$RECORDER_PID" >/dev/null 2>&1; then + kill "$RECORDER_PID" >/dev/null 2>&1 || true + fi +} +trap cleanup INT TERM + +MISSION_CONTROL_OPEN_BROWSER=0 \ +MISSION_CONTROL_PREROLL_MS=2000 \ +MISSION_CONTROL_FAILURE_HOLD_MS=3200 \ +MISSION_CONTROL_COMPLETION_HOLD_MS=4000 \ +MISSION_CONTROL_TIMEOUT_MS=50000 \ +"$DEMO_SCRIPT_DIR/mission_control_demo.sh" + +wait "$RECORDER_PID" +trap - INT TERM + +if [[ ! -s "$OUTPUT_ABS" ]]; then + echo "Recording did not produce a video file. Check macOS Screen Recording permission and rerun." >&2 + exit 1 +fi + +ls -lh "$OUTPUT_ABS" +echo "Video ready: $OUTPUT_ABS" diff --git a/src/api/meta.zig b/src/api/meta.zig index 0313e21..a554199 100644 --- a/src/api/meta.zig +++ b/src/api/meta.zig @@ -1343,6 +1343,54 @@ const routes = [_]RouteSpec{ .body = "Forwarded as-is to NullWatch.", .response = "Forwarded upstream JSON response.", }, + .{ + .id = "mission-control.state", + .method = "GET", + .path_template = "/api/mission-control/state", + .category = "mission-control", + .summary = "Read the local deterministic NullOS Mission Control replay state.", + .auth_mode = "optional_bearer", + .response = "Schema-versioned mission state, controls, graph, timeline, telemetry, recovery metadata, and NullWatch-style trace references.", + }, + .{ + .id = "mission-control.replay", + .method = "GET", + .path_template = "/api/mission-control/replay", + .category = "mission-control", + .summary = "Export the current Mission Control replay artifact for local review and debugging.", + .auth_mode = "optional_bearer", + .response = "Replay artifact with current snapshot, source fixture, and NullTickets/NullBoiler/NullClaw/NullWatch mapping metadata.", + }, + .{ + .id = "mission-control.reset", + .method = "POST", + .path_template = "/api/mission-control/reset", + .category = "mission-control", + .summary = "Reset the local Mission Control replay to idle.", + .auth_mode = "optional_bearer", + .body = "No request body required.", + .response = "Reset mission state.", + }, + .{ + .id = "mission-control.launch", + .method = "POST", + .path_template = "/api/mission-control/launch", + .category = "mission-control", + .summary = "Launch the local Mission Control replay if it is idle.", + .auth_mode = "optional_bearer", + .body = "No request body required.", + .response = "Mission state after launch, or 409 when already started.", + }, + .{ + .id = "mission-control.recover", + .method = "POST", + .path_template = "/api/mission-control/recover", + .category = "mission-control", + .summary = "Fork the local Mission Control replay after the failure phase.", + .auth_mode = "optional_bearer", + .body = "No request body required.", + .response = "Mission state after checkpoint recovery, or 409 before recovery is allowed.", + }, }; pub fn allRoutes() []const RouteSpec { diff --git a/src/api/mission_control.zig b/src/api/mission_control.zig new file mode 100644 index 0000000..bf45c41 --- /dev/null +++ b/src/api/mission_control.zig @@ -0,0 +1,704 @@ +const std = @import("std"); +const std_compat = @import("compat"); +const helpers = @import("helpers.zig"); +const replay = @import("mission_control_replay.zig"); + +const ApiResponse = helpers.ApiResponse; + +const prefix = "/api/mission-control"; + +const RuntimeState = struct { + launched: bool = false, + started_at_ms: i64 = 0, + recovered: bool = false, + recovery_started_at_ms: i64 = 0, +}; + +const MissionControls = struct { + can_launch: bool, + can_recover: bool, + can_reset: bool, +}; + +const Agent = struct { + id: []const u8, + role: []const u8, + status: []const u8, + current_step: []const u8, +}; + +const GraphNode = struct { + id: []const u8, + label: []const u8, + kind: []const u8, + status: []const u8, +}; + +const GraphEdge = struct { + from: []const u8, + to: []const u8, + status: []const u8, +}; + +const MissionGraph = struct { + nodes: []const GraphNode, + edges: []const GraphEdge, +}; + +const MissionEvent = struct { + at_ms: i64, + source: []const u8, + level: []const u8, + title: []const u8, + detail: []const u8, + status: []const u8, + trace: ?replay.EventTraceDef, +}; + +const MissionTelemetry = struct { + runs: usize, + spans: usize, + evals: usize, + errors: usize, + total_tokens: usize, + total_cost_usd: f64, + verdict: []const u8, +}; + +const FailurePanel = struct { + run_id: []const u8, + checkpoint_id: []const u8, + failed_step: []const u8, + error_message: []const u8, + suggested_intervention: []const u8, +}; + +const RecoveryPanel = struct { + run_id: []const u8, + forked_from: []const u8, + human_instruction: []const u8, + status: []const u8, +}; + +const MissionSnapshot = struct { + schema_version: u8, + mode: []const u8, + scenario_id: []const u8, + scenario_version: []const u8, + generated_at_ms: i64, + mission_id: []const u8, + title: []const u8, + status: []const u8, + phase: []const u8, + headline: []const u8, + elapsed_ms: i64, + progress: u8, + active_run_id: ?[]const u8, + failed_run_id: ?[]const u8, + recovered_run_id: ?[]const u8, + controls: MissionControls, + agents: []const Agent, + graph: MissionGraph, + events: []const MissionEvent, + telemetry: MissionTelemetry, + failure: ?FailurePanel, + recovery: ?RecoveryPanel, +}; + +const ComponentMapping = struct { + component: []const u8, + role: []const u8, + evidence: []const []const u8, +}; + +const WorkflowMapping = struct { + component: []const u8, + role: []const u8, + checkpoint_id: []const u8, + failed_run_id: []const u8, + recovered_run_id: []const u8, + human_instruction: []const u8, + evidence: []const []const u8, +}; + +const ObservabilityMapping = struct { + component: []const u8, + role: []const u8, + failed_run_id: []const u8, + recovered_run_id: []const u8, + trace_ref_source: []const u8, + evidence: []const []const u8, +}; + +const ReplayArtifactMapping = struct { + nulltickets: ComponentMapping, + nullboiler: WorkflowMapping, + nullclaw: ComponentMapping, + nullwatch: ObservabilityMapping, +}; + +const ReplayArtifact = struct { + artifact_schema_version: u8, + artifact_kind: []const u8, + generated_at_ms: i64, + replay_fixture_path: []const u8, + scenario_id: []const u8, + scenario_version: []const u8, + mode: []const u8, + snapshot: MissionSnapshot, + replay_fixture: replay.ReplayFixture, + ecosystem_mapping: ReplayArtifactMapping, +}; + +var mission_mutex: std_compat.sync.Mutex = .{}; +var mission_runtime = RuntimeState{}; + +pub fn isPath(target: []const u8) bool { + const path = stripQuery(target); + return std.mem.eql(u8, path, prefix) or std.mem.startsWith(u8, path, prefix ++ "/"); +} + +pub fn handle(allocator: std.mem.Allocator, method: []const u8, target: []const u8) ApiResponse { + const path = stripQuery(target); + if (!isPath(path)) return helpers.notFound(); + + const is_state = std.mem.eql(u8, path, prefix ++ "/state"); + const is_replay = std.mem.eql(u8, path, prefix ++ "/replay"); + const is_reset = std.mem.eql(u8, path, prefix ++ "/reset"); + const is_launch = std.mem.eql(u8, path, prefix ++ "/launch"); + const is_recover = std.mem.eql(u8, path, prefix ++ "/recover"); + if (!is_state and !is_replay and !is_reset and !is_launch and !is_recover) return helpers.notFound(); + + if (is_state or is_replay) { + if (!std.mem.eql(u8, method, "GET")) return helpers.methodNotAllowed(); + } else if (!std.mem.eql(u8, method, "POST")) { + return helpers.methodNotAllowed(); + } + + mission_mutex.lock(); + defer mission_mutex.unlock(); + + const now_ms = std_compat.time.milliTimestamp(); + + if (is_state) { + const body = buildStateJson(allocator, mission_runtime, now_ms) catch return helpers.serverError(); + return helpers.jsonOk(body); + } + + if (is_replay) { + const body = buildReplayArtifactJson(allocator, mission_runtime, now_ms) catch return helpers.serverError(); + return helpers.jsonOk(body); + } + + if (is_reset) { + mission_runtime = .{}; + const body = buildStateJson(allocator, mission_runtime, now_ms) catch return helpers.serverError(); + return helpers.jsonOk(body); + } + + var parsed = replay.parseValidated(allocator) catch return helpers.serverError(); + defer parsed.deinit(); + const elapsed_ms = elapsedSince(mission_runtime.started_at_ms, now_ms); + const recovery_elapsed_ms = elapsedSince(mission_runtime.recovery_started_at_ms, now_ms); + const phase = currentPhase(parsed.value, mission_runtime, elapsed_ms, recovery_elapsed_ms); + + if (is_launch) { + if (!canLaunch(mission_runtime)) { + return missionAlreadyStarted(); + } + mission_runtime = .{ + .launched = true, + .started_at_ms = now_ms, + }; + const body = buildStateJson(allocator, mission_runtime, now_ms) catch return helpers.serverError(); + return helpers.jsonOk(body); + } + + if (is_recover) { + if (!canRecover(parsed.value, mission_runtime, phase)) { + return missionNotRecoverable(); + } + mission_runtime.recovered = true; + mission_runtime.recovery_started_at_ms = now_ms; + const body = buildStateJson(allocator, mission_runtime, now_ms) catch return helpers.serverError(); + return helpers.jsonOk(body); + } + + return helpers.notFound(); +} + +fn missionAlreadyStarted() ApiResponse { + return .{ + .status = "409 Conflict", + .content_type = "application/json", + .body = "{\"error\":{\"code\":\"mission_already_started\",\"message\":\"Mission is already started. Reset before launching again.\"}}", + }; +} + +fn missionNotRecoverable() ApiResponse { + return .{ + .status = "409 Conflict", + .content_type = "application/json", + .body = "{\"error\":{\"code\":\"mission_not_recoverable\",\"message\":\"Mission can only be recovered after the validation failure phase.\"}}", + }; +} + +fn stripQuery(target: []const u8) []const u8 { + if (std.mem.indexOfScalar(u8, target, '?')) |idx| return target[0..idx]; + return target; +} + +fn buildStateJson(allocator: std.mem.Allocator, runtime: RuntimeState, now_ms: i64) ![]u8 { + var parsed = try replay.parseValidated(allocator); + defer parsed.deinit(); + const fixture = parsed.value; + + const elapsed_ms = elapsedSince(runtime.started_at_ms, now_ms); + const recovery_elapsed_ms = elapsedSince(runtime.recovery_started_at_ms, now_ms); + const phase = currentPhase(fixture, runtime, elapsed_ms, recovery_elapsed_ms); + const agents = try buildAgents(allocator, fixture, phase); + defer allocator.free(agents); + const nodes = try buildNodes(allocator, fixture, phase); + defer allocator.free(nodes); + const edges = try buildEdges(allocator, fixture, phase); + defer allocator.free(edges); + const events = try buildEvents(allocator, fixture, phase); + defer allocator.free(events); + const snapshot = buildSnapshot( + fixture, + runtime, + now_ms, + elapsed_ms, + phase, + agents, + nodes, + edges, + events, + ); + return std.json.Stringify.valueAlloc(allocator, snapshot, .{ .whitespace = .indent_2 }); +} + +fn buildReplayArtifactJson(allocator: std.mem.Allocator, runtime: RuntimeState, now_ms: i64) ![]u8 { + var parsed = try replay.parseValidated(allocator); + defer parsed.deinit(); + const fixture = parsed.value; + + const elapsed_ms = elapsedSince(runtime.started_at_ms, now_ms); + const recovery_elapsed_ms = elapsedSince(runtime.recovery_started_at_ms, now_ms); + const phase = currentPhase(fixture, runtime, elapsed_ms, recovery_elapsed_ms); + const agents = try buildAgents(allocator, fixture, phase); + defer allocator.free(agents); + const nodes = try buildNodes(allocator, fixture, phase); + defer allocator.free(nodes); + const edges = try buildEdges(allocator, fixture, phase); + defer allocator.free(edges); + const events = try buildEvents(allocator, fixture, phase); + defer allocator.free(events); + const snapshot = buildSnapshot( + fixture, + runtime, + now_ms, + elapsed_ms, + phase, + agents, + nodes, + edges, + events, + ); + const artifact = ReplayArtifact{ + .artifact_schema_version = 1, + .artifact_kind = "nullhub.mission_control.replay", + .generated_at_ms = now_ms, + .replay_fixture_path = "src/api/mission_control/code_red.v1.json", + .scenario_id = fixture.scenario_id, + .scenario_version = fixture.scenario_version, + .mode = fixture.mode, + .snapshot = snapshot, + .replay_fixture = fixture, + .ecosystem_mapping = replayArtifactMapping(fixture), + }; + return std.json.Stringify.valueAlloc(allocator, artifact, .{ .whitespace = .indent_2 }); +} + +fn replayArtifactMapping(fixture: replay.ReplayFixture) ReplayArtifactMapping { + return .{ + .nulltickets = .{ + .component = "nulltickets", + .role = "Tracker-style task source and terminal workflow status.", + .evidence = &.{ "events[source=nulltickets]", "graph.nodes[kind=tracker]" }, + }, + .nullboiler = .{ + .component = "nullboiler", + .role = "Workflow orchestration, checkpointing, dispatch, and fork recovery.", + .checkpoint_id = fixture.checkpoint_id, + .failed_run_id = fixture.run_ids.failed, + .recovered_run_id = fixture.run_ids.recovered, + .human_instruction = fixture.human_instruction, + .evidence = &.{ "phases", "graph.edges", "events[source=nullboiler]", "failure.checkpoint_id", "recovery.forked_from" }, + }, + .nullclaw = .{ + .component = "nullclaw", + .role = "Lightweight role agents that perform research, coding, testing, and review steps.", + .evidence = &.{ "agents", "events[source=nullclaw]", "graph.nodes[kind=agent]" }, + }, + .nullwatch = .{ + .component = "nullwatch", + .role = "Run, span, eval, token, cost, and failure telemetry references.", + .failed_run_id = fixture.run_ids.failed, + .recovered_run_id = fixture.run_ids.recovered, + .trace_ref_source = "events[].trace", + .evidence = &.{ "events[].trace", "telemetry", "failure.run_id", "recovery.run_id" }, + }, + }; +} + +fn buildSnapshot( + fixture: replay.ReplayFixture, + runtime: RuntimeState, + now_ms: i64, + elapsed_ms: i64, + phase: []const u8, + agents: []const Agent, + nodes: []const GraphNode, + edges: []const GraphEdge, + events: []const MissionEvent, +) MissionSnapshot { + const failed_visible = isAtOrAfter(fixture, phase, fixture.failure.visible_from_phase); + const recovered_visible = runtime.recovered; + const phase_def = replay.phaseById(fixture, phase).?; + + return .{ + .schema_version = fixture.schema_version, + .mode = fixture.mode, + .scenario_id = fixture.scenario_id, + .scenario_version = fixture.scenario_version, + .generated_at_ms = now_ms, + .mission_id = fixture.scenario_id, + .title = fixture.title, + .status = phase_def.status, + .phase = phase, + .headline = phase_def.headline, + .elapsed_ms = if (runtime.launched) elapsed_ms else 0, + .progress = phase_def.progress, + .active_run_id = activeRunId(fixture, phase), + .failed_run_id = if (failed_visible) fixture.failure.run_id else null, + .recovered_run_id = if (recovered_visible) fixture.recovery.run_id else null, + .controls = .{ + .can_launch = canLaunch(runtime), + .can_recover = canRecover(fixture, runtime, phase), + .can_reset = true, + }, + .agents = agents, + .graph = .{ + .nodes = nodes, + .edges = edges, + }, + .events = events, + .telemetry = telemetryForPhase(fixture, phase), + .failure = if (failed_visible) FailurePanel{ + .run_id = fixture.failure.run_id, + .checkpoint_id = fixture.failure.checkpoint_id, + .failed_step = fixture.failure.failed_step, + .error_message = fixture.failure.error_message, + .suggested_intervention = fixture.failure.suggested_intervention, + } else null, + .recovery = if (recovered_visible) RecoveryPanel{ + .run_id = fixture.recovery.run_id, + .forked_from = fixture.recovery.forked_from, + .human_instruction = fixture.recovery.human_instruction, + .status = if (std.mem.eql(u8, phase, "completed")) "passed" else "replaying", + } else null, + }; +} + +fn elapsedSince(start_ms: i64, now_ms: i64) i64 { + if (start_ms <= 0 or now_ms <= start_ms) return 0; + return now_ms - start_ms; +} + +fn currentPhase(fixture: replay.ReplayFixture, runtime: RuntimeState, elapsed_ms: i64, recovery_elapsed_ms: i64) []const u8 { + if (!runtime.launched) return "idle"; + return phaseForTrack(fixture, if (runtime.recovered) "recovery" else "primary", if (runtime.recovered) recovery_elapsed_ms else elapsed_ms); +} + +fn phaseForTrack(fixture: replay.ReplayFixture, track: []const u8, elapsed_ms: i64) []const u8 { + var selected: ?replay.PhaseDef = null; + for (fixture.phases) |phase| { + if (!std.mem.eql(u8, phase.track, track)) continue; + if (phase.starts_at_ms > elapsed_ms) continue; + if (selected == null or phase.starts_at_ms >= selected.?.starts_at_ms) { + selected = phase; + } + } + return if (selected) |phase| phase.id else "idle"; +} + +fn canLaunch(runtime: RuntimeState) bool { + return !runtime.launched; +} + +fn canRecover(fixture: replay.ReplayFixture, runtime: RuntimeState, phase: []const u8) bool { + return runtime.launched and !runtime.recovered and std.mem.eql(u8, phase, fixture.failure.visible_from_phase); +} + +fn activeRunId(fixture: replay.ReplayFixture, phase: []const u8) ?[]const u8 { + if (std.mem.eql(u8, phase, "idle")) return null; + if (isAtOrAfter(fixture, phase, fixture.recovery.visible_from_phase)) return fixture.recovery.run_id; + return fixture.failure.run_id; +} + +fn statusAfter(fixture: replay.ReplayFixture, phase: []const u8, own_phase: []const u8) []const u8 { + const current_rank = phaseRank(fixture, phase); + const own_rank = phaseRank(fixture, own_phase); + if (current_rank > own_rank) return "done"; + if (current_rank == own_rank) return "active"; + return "pending"; +} + +fn buildAgents(allocator: std.mem.Allocator, fixture: replay.ReplayFixture, phase: []const u8) ![]Agent { + const agents = try allocator.alloc(Agent, fixture.agents.len); + for (fixture.agents, 0..) |agent, index| { + agents[index] = .{ + .id = agent.id, + .role = agent.role, + .status = agentStatus(fixture, agent, phase), + .current_step = agentStep(agent, phase), + }; + } + return agents; +} + +fn agentStatus(fixture: replay.ReplayFixture, agent: replay.AgentDef, phase: []const u8) []const u8 { + for (agent.active_phases) |active_phase| { + if (std.mem.eql(u8, phase, active_phase)) return "active"; + } + if (agent.failed_phase) |failed_phase| { + if (std.mem.eql(u8, phase, failed_phase)) return "failed"; + } + if (agent.blocked_phase) |blocked_phase| { + if (std.mem.eql(u8, phase, blocked_phase)) return "blocked"; + } + if (phaseRank(fixture, phase) > phaseRank(fixture, agent.done_after_phase)) return "done"; + return "standby"; +} + +fn agentStep(agent: replay.AgentDef, phase: []const u8) []const u8 { + for (agent.steps) |step| { + if (std.mem.eql(u8, step.phase, phase)) return step.step; + } + return "waiting"; +} + +fn buildNodes(allocator: std.mem.Allocator, fixture: replay.ReplayFixture, phase: []const u8) ![]GraphNode { + const nodes = try allocator.alloc(GraphNode, fixture.graph.nodes.len); + for (fixture.graph.nodes, 0..) |node, index| { + nodes[index] = .{ + .id = node.id, + .label = node.label, + .kind = node.kind, + .status = nodeStatus(fixture, node, phase), + }; + } + return nodes; +} + +fn nodeStatus(fixture: replay.ReplayFixture, node: replay.GraphNodeDef, phase: []const u8) []const u8 { + if (node.error_phase) |error_phase| { + if (std.mem.eql(u8, phase, error_phase)) return "error"; + } + return statusAfter(fixture, phase, node.phase); +} + +fn buildEdges(allocator: std.mem.Allocator, fixture: replay.ReplayFixture, phase: []const u8) ![]GraphEdge { + const edges = try allocator.alloc(GraphEdge, fixture.graph.edges.len); + for (fixture.graph.edges, 0..) |edge, index| { + edges[index] = .{ + .from = edge.from, + .to = edge.to, + .status = edgeStatus(fixture, edge, phase), + }; + } + return edges; +} + +fn edgeStatus(fixture: replay.ReplayFixture, edge: replay.GraphEdgeDef, phase: []const u8) []const u8 { + if (edge.error_phase) |error_phase| { + if (std.mem.eql(u8, phase, error_phase)) return "error"; + } + return statusAfter(fixture, phase, edge.phase); +} + +fn buildEvents(allocator: std.mem.Allocator, fixture: replay.ReplayFixture, phase: []const u8) ![]MissionEvent { + const events = try allocator.alloc(MissionEvent, fixture.events.len); + for (fixture.events, 0..) |event, index| { + events[index] = .{ + .at_ms = event.at_ms, + .source = event.source, + .level = event.level, + .title = event.title, + .detail = event.detail, + .status = statusAfter(fixture, phase, event.phase), + .trace = event.trace, + }; + } + return events; +} + +fn telemetryForPhase(fixture: replay.ReplayFixture, phase: []const u8) MissionTelemetry { + const current_rank = phaseRank(fixture, phase); + var selected = fixture.telemetry[0]; + var selected_rank = phaseRank(fixture, selected.phase); + for (fixture.telemetry) |entry| { + const entry_rank = phaseRank(fixture, entry.phase); + if (entry_rank <= current_rank and entry_rank >= selected_rank) { + selected = entry; + selected_rank = entry_rank; + } + } + return .{ + .runs = selected.runs, + .spans = selected.spans, + .evals = selected.evals, + .errors = selected.errors, + .total_tokens = selected.total_tokens, + .total_cost_usd = selected.total_cost_usd, + .verdict = selected.verdict, + }; +} + +fn phaseRank(fixture: replay.ReplayFixture, phase: []const u8) u8 { + return replay.phaseRank(fixture, phase) orelse 0; +} + +fn isAtOrAfter(fixture: replay.ReplayFixture, phase: []const u8, threshold: []const u8) bool { + return phaseRank(fixture, phase) >= phaseRank(fixture, threshold); +} + +test "isPath matches mission-control namespace" { + try std.testing.expect(isPath("/api/mission-control/state")); + try std.testing.expect(isPath("/api/mission-control/replay")); + try std.testing.expect(isPath("/api/mission-control/reset")); + try std.testing.expect(isPath("/api/mission-control/state?poll=1")); + try std.testing.expect(!isPath("/api/observability/v1/runs")); +} + +test "buildStateJson returns idle mission before launch" { + const json = try buildStateJson(std.testing.allocator, .{}, 1_000); + defer std.testing.allocator.free(json); + + try std.testing.expect(std.mem.indexOf(u8, json, "\"schema_version\": 1") != null); + try std.testing.expect(std.mem.indexOf(u8, json, "\"mode\": \"deterministic_local_replay\"") != null); + try std.testing.expect(std.mem.indexOf(u8, json, "\"scenario_id\": \"mission-code-red\"") != null); + try std.testing.expect(std.mem.indexOf(u8, json, "\"status\": \"idle\"") != null); + try std.testing.expect(std.mem.indexOf(u8, json, "\"phase\": \"idle\"") != null); + try std.testing.expect(std.mem.indexOf(u8, json, "\"can_launch\": true") != null); +} + +test "buildStateJson exposes failed mission and recover control" { + const json = try buildStateJson(std.testing.allocator, .{ + .launched = true, + .started_at_ms = 1_000, + }, 11_000); + defer std.testing.allocator.free(json); + + try std.testing.expect(std.mem.indexOf(u8, json, "\"status\": \"intervention_required\"") != null); + try std.testing.expect(std.mem.indexOf(u8, json, "\"phase\": \"failed\"") != null); + try std.testing.expect(std.mem.indexOf(u8, json, "\"can_recover\": true") != null); + try std.testing.expect(std.mem.indexOf(u8, json, "\"trace_id\": \"trace-demo-code-red-primary\"") != null); + try std.testing.expect(std.mem.indexOf(u8, json, "\"eval_key\": \"tool_success\"") != null); + try std.testing.expect(std.mem.indexOf(u8, json, "zig build test exited with status 1") != null); +} + +test "buildStateJson exposes recovered completed mission" { + const json = try buildStateJson(std.testing.allocator, .{ + .launched = true, + .started_at_ms = 1_000, + .recovered = true, + .recovery_started_at_ms = 11_000, + }, 19_000); + defer std.testing.allocator.free(json); + + try std.testing.expect(std.mem.indexOf(u8, json, "\"status\": \"completed\"") != null); + try std.testing.expect(std.mem.indexOf(u8, json, "\"phase\": \"completed\"") != null); + try std.testing.expect(std.mem.indexOf(u8, json, "\"recovered_run_id\": \"run-demo-recovered-fork\"") != null); + try std.testing.expect(std.mem.indexOf(u8, json, "\"verdict\": \"pass\"") != null); +} + +test "buildReplayArtifactJson exports fixture snapshot and ecosystem mapping" { + const json = try buildReplayArtifactJson(std.testing.allocator, .{ + .launched = true, + .started_at_ms = 1_000, + .recovered = true, + .recovery_started_at_ms = 11_000, + }, 19_000); + defer std.testing.allocator.free(json); + + try std.testing.expect(std.mem.indexOf(u8, json, "\"artifact_kind\": \"nullhub.mission_control.replay\"") != null); + try std.testing.expect(std.mem.indexOf(u8, json, "\"replay_fixture_path\": \"src/api/mission_control/code_red.v1.json\"") != null); + try std.testing.expect(std.mem.indexOf(u8, json, "\"snapshot\"") != null); + try std.testing.expect(std.mem.indexOf(u8, json, "\"replay_fixture\"") != null); + try std.testing.expect(std.mem.indexOf(u8, json, "\"ecosystem_mapping\"") != null); + try std.testing.expect(std.mem.indexOf(u8, json, "\"nullwatch\"") != null); + try std.testing.expect(std.mem.indexOf(u8, json, "\"trace_ref_source\": \"events[].trace\"") != null); +} + +test "handle supports reset launch and recovery after failure" { + const reset = handle(std.testing.allocator, "POST", "/api/mission-control/reset"); + defer std.testing.allocator.free(reset.body); + try std.testing.expectEqualStrings("200 OK", reset.status); + + const launched = handle(std.testing.allocator, "POST", "/api/mission-control/launch"); + defer std.testing.allocator.free(launched.body); + try std.testing.expectEqualStrings("200 OK", launched.status); + try std.testing.expect(std.mem.indexOf(u8, launched.body, "\"status\": \"running\"") != null); + + mission_mutex.lock(); + mission_runtime = .{ + .launched = true, + .started_at_ms = std_compat.time.milliTimestamp() - 10_000, + }; + mission_mutex.unlock(); + + const recovered = handle(std.testing.allocator, "POST", "/api/mission-control/recover"); + defer std.testing.allocator.free(recovered.body); + try std.testing.expectEqualStrings("200 OK", recovered.status); + try std.testing.expect(std.mem.indexOf(u8, recovered.body, "\"recovered_run_id\": \"run-demo-recovered-fork\"") != null); +} + +test "handle rejects invalid mission transitions" { + const reset = handle(std.testing.allocator, "POST", "/api/mission-control/reset"); + defer std.testing.allocator.free(reset.body); + try std.testing.expectEqualStrings("200 OK", reset.status); + + const early_recover = handle(std.testing.allocator, "POST", "/api/mission-control/recover"); + try std.testing.expectEqualStrings("409 Conflict", early_recover.status); + try std.testing.expect(std.mem.indexOf(u8, early_recover.body, "mission_not_recoverable") != null); + + const launched = handle(std.testing.allocator, "POST", "/api/mission-control/launch"); + defer std.testing.allocator.free(launched.body); + try std.testing.expectEqualStrings("200 OK", launched.status); + + const duplicate_launch = handle(std.testing.allocator, "POST", "/api/mission-control/launch"); + try std.testing.expectEqualStrings("409 Conflict", duplicate_launch.status); + try std.testing.expect(std.mem.indexOf(u8, duplicate_launch.body, "mission_already_started") != null); +} + +test "handle returns clear status codes for unknown paths and methods" { + const unknown_get = handle(std.testing.allocator, "GET", "/api/mission-control/nope"); + try std.testing.expectEqualStrings("404 Not Found", unknown_get.status); + + const wrong_method = handle(std.testing.allocator, "GET", "/api/mission-control/launch"); + try std.testing.expectEqualStrings("405 Method Not Allowed", wrong_method.status); + + const wrong_replay_method = handle(std.testing.allocator, "POST", "/api/mission-control/replay"); + try std.testing.expectEqualStrings("405 Method Not Allowed", wrong_replay_method.status); +} + +test "handle returns replay artifact" { + const replay_resp = handle(std.testing.allocator, "GET", "/api/mission-control/replay"); + defer std.testing.allocator.free(replay_resp.body); + + try std.testing.expectEqualStrings("200 OK", replay_resp.status); + try std.testing.expect(std.mem.indexOf(u8, replay_resp.body, "\"artifact_schema_version\": 1") != null); + try std.testing.expect(std.mem.indexOf(u8, replay_resp.body, "\"artifact_kind\": \"nullhub.mission_control.replay\"") != null); +} diff --git a/src/api/mission_control/code_red.v1.json b/src/api/mission_control/code_red.v1.json new file mode 100644 index 0000000..d32e510 --- /dev/null +++ b/src/api/mission_control/code_red.v1.json @@ -0,0 +1,505 @@ +{ + "schema_version": 1, + "mode": "deterministic_local_replay", + "scenario_id": "mission-code-red", + "scenario_version": "2026-05-06", + "title": "Ship a bug fix through autonomous agents", + "run_ids": { + "failed": "run-demo-failed-test", + "recovered": "run-demo-recovered-fork" + }, + "checkpoint_id": "cp-demo-before-test", + "human_instruction": "apply missing validation guard", + "phases": [ + { + "id": "idle", + "track": "idle", + "rank": 0, + "starts_at_ms": 0, + "status": "idle", + "progress": 0, + "headline": "Mission ready. Launch the local agent stack." + }, + { + "id": "launching", + "track": "primary", + "rank": 1, + "starts_at_ms": 0, + "status": "running", + "progress": 8, + "headline": "Backlog item claimed and orchestration run started." + }, + { + "id": "research", + "track": "primary", + "rank": 2, + "starts_at_ms": 1500, + "status": "running", + "progress": 20, + "headline": "Research agent is isolating the defect." + }, + { + "id": "coding", + "track": "primary", + "rank": 3, + "starts_at_ms": 3500, + "status": "running", + "progress": 36, + "headline": "Coder agent is applying a targeted patch." + }, + { + "id": "checkpoint", + "track": "primary", + "rank": 4, + "starts_at_ms": 5500, + "status": "running", + "progress": 48, + "headline": "Checkpoint captured before validation." + }, + { + "id": "testing", + "track": "primary", + "rank": 5, + "starts_at_ms": 7000, + "status": "running", + "progress": 60, + "headline": "Test runner is validating the patch." + }, + { + "id": "failed", + "track": "primary", + "rank": 6, + "starts_at_ms": 9000, + "status": "intervention_required", + "progress": 64, + "headline": "Validation failed. Human intervention is required." + }, + { + "id": "forking", + "track": "recovery", + "rank": 7, + "starts_at_ms": 0, + "status": "running", + "progress": 70, + "headline": "Forking from checkpoint with human guidance." + }, + { + "id": "patching", + "track": "recovery", + "rank": 8, + "starts_at_ms": 1500, + "status": "running", + "progress": 80, + "headline": "Recovered run is applying the injected fix." + }, + { + "id": "retesting", + "track": "recovery", + "rank": 9, + "starts_at_ms": 3500, + "status": "running", + "progress": 88, + "headline": "Recovered run is replaying tests." + }, + { + "id": "review", + "track": "recovery", + "rank": 10, + "starts_at_ms": 5500, + "status": "running", + "progress": 94, + "headline": "Reviewer agent is approving the recovered fix." + }, + { + "id": "completed", + "track": "recovery", + "rank": 11, + "starts_at_ms": 7000, + "status": "completed", + "progress": 100, + "headline": "Mission recovered and completed." + } + ], + "agents": [ + { + "id": "agent-researcher", + "role": "researcher", + "active_phases": ["research"], + "done_after_phase": "research", + "blocked_phase": null, + "failed_phase": null, + "steps": [ + { + "phase": "research", + "step": "reading ticket and isolating scope" + } + ] + }, + { + "id": "agent-coder", + "role": "coder", + "active_phases": ["coding", "patching"], + "done_after_phase": "coding", + "blocked_phase": "failed", + "failed_phase": null, + "steps": [ + { + "phase": "coding", + "step": "editing implementation" + }, + { + "phase": "patching", + "step": "applying injected guard" + } + ] + }, + { + "id": "agent-test-runner", + "role": "test", + "active_phases": ["testing", "retesting"], + "done_after_phase": "testing", + "blocked_phase": null, + "failed_phase": "failed", + "steps": [ + { + "phase": "testing", + "step": "running failing validation" + }, + { + "phase": "retesting", + "step": "replaying validation" + } + ] + }, + { + "id": "agent-reviewer", + "role": "reviewer", + "active_phases": ["review"], + "done_after_phase": "review", + "blocked_phase": null, + "failed_phase": null, + "steps": [ + { + "phase": "review", + "step": "checking recovered patch" + } + ] + } + ], + "graph": { + "nodes": [ + { + "id": "ticket", + "label": "Ticket", + "kind": "tracker", + "phase": "launching", + "error_phase": null + }, + { + "id": "research", + "label": "Research", + "kind": "agent", + "phase": "research", + "error_phase": null + }, + { + "id": "code", + "label": "Patch", + "kind": "agent", + "phase": "coding", + "error_phase": null + }, + { + "id": "checkpoint", + "label": "Checkpoint", + "kind": "checkpoint", + "phase": "checkpoint", + "error_phase": null + }, + { + "id": "test", + "label": "Test", + "kind": "tool", + "phase": "testing", + "error_phase": "failed" + }, + { + "id": "recover", + "label": "Fork", + "kind": "human", + "phase": "forking", + "error_phase": null + }, + { + "id": "review", + "label": "Review", + "kind": "agent", + "phase": "review", + "error_phase": null + } + ], + "edges": [ + { + "from": "ticket", + "to": "research", + "phase": "research", + "error_phase": null + }, + { + "from": "research", + "to": "code", + "phase": "coding", + "error_phase": null + }, + { + "from": "code", + "to": "checkpoint", + "phase": "checkpoint", + "error_phase": null + }, + { + "from": "checkpoint", + "to": "test", + "phase": "testing", + "error_phase": "failed" + }, + { + "from": "checkpoint", + "to": "recover", + "phase": "forking", + "error_phase": null + }, + { + "from": "recover", + "to": "review", + "phase": "review", + "error_phase": null + } + ] + }, + "events": [ + { + "at_ms": 0, + "phase": "launching", + "source": "nulltickets", + "level": "info", + "title": "Task queued", + "detail": "Mission task entered the durable backlog.", + "trace": { + "kind": "span", + "run_id": "run-demo-failed-test", + "trace_id": "trace-demo-code-red-primary", + "span_id": "span-ticket-queued", + "operation": "ticket.claim" + } + }, + { + "at_ms": 1500, + "phase": "research", + "source": "nullboiler", + "level": "info", + "title": "Workflow run started", + "detail": "Graph runtime selected researcher -> coder -> test -> review.", + "trace": { + "kind": "span", + "run_id": "run-demo-failed-test", + "trace_id": "trace-demo-code-red-primary", + "span_id": "span-workflow-started", + "operation": "workflow.dispatch" + } + }, + { + "at_ms": 3500, + "phase": "coding", + "source": "nullclaw", + "level": "info", + "title": "Patch drafted", + "detail": "Coder agent produced a minimal implementation patch.", + "trace": { + "kind": "span", + "run_id": "run-demo-failed-test", + "trace_id": "trace-demo-code-red-primary", + "span_id": "span-agent-coder", + "operation": "agent.coder.patch" + } + }, + { + "at_ms": 5500, + "phase": "checkpoint", + "source": "nullboiler", + "level": "info", + "title": "Checkpoint created", + "detail": "State saved as cp-demo-before-test.", + "trace": { + "kind": "span", + "run_id": "run-demo-failed-test", + "trace_id": "trace-demo-code-red-primary", + "span_id": "span-checkpoint-created", + "operation": "workflow.checkpoint" + } + }, + { + "at_ms": 7000, + "phase": "failed", + "source": "nullwatch", + "level": "error", + "title": "Validation failed", + "detail": "tool.call shell returned exit code 1.", + "trace": { + "kind": "eval", + "run_id": "run-demo-failed-test", + "trace_id": "trace-demo-code-red-primary", + "span_id": "span-test-failure", + "eval_key": "tool_success", + "operation": "tool.shell.zig_build_test" + } + }, + { + "at_ms": 9000, + "phase": "failed", + "source": "human", + "level": "warning", + "title": "Intervention requested", + "detail": "Fork from checkpoint and inject validation guard.", + "trace": { + "kind": "span", + "run_id": "run-demo-failed-test", + "trace_id": "trace-demo-code-red-primary", + "span_id": "span-human-intervention", + "operation": "human.checkpoint_fork" + } + }, + { + "at_ms": 10500, + "phase": "forking", + "source": "nullboiler", + "level": "info", + "title": "Recovered fork started", + "detail": "run-demo-recovered-fork replayed from cp-demo-before-test.", + "trace": { + "kind": "span", + "run_id": "run-demo-recovered-fork", + "trace_id": "trace-demo-code-red-recovered", + "span_id": "span-recovered-fork", + "operation": "workflow.fork" + } + }, + { + "at_ms": 13000, + "phase": "retesting", + "source": "nullwatch", + "level": "info", + "title": "Recovered tests passed", + "detail": "tool_success eval changed from fail to pass.", + "trace": { + "kind": "eval", + "run_id": "run-demo-recovered-fork", + "trace_id": "trace-demo-code-red-recovered", + "span_id": "span-recovered-tests", + "eval_key": "tool_success", + "operation": "tool.shell.zig_build_test" + } + }, + { + "at_ms": 15000, + "phase": "completed", + "source": "nulltickets", + "level": "success", + "title": "Mission done", + "detail": "Ticket moved to review-approved terminal stage.", + "trace": { + "kind": "span", + "run_id": "run-demo-recovered-fork", + "trace_id": "trace-demo-code-red-recovered", + "span_id": "span-ticket-completed", + "operation": "ticket.complete" + } + } + ], + "telemetry": [ + { + "phase": "idle", + "runs": 0, + "spans": 0, + "evals": 0, + "errors": 0, + "total_tokens": 0, + "total_cost_usd": 0.0, + "verdict": "not_started" + }, + { + "phase": "research", + "runs": 1, + "spans": 2, + "evals": 0, + "errors": 0, + "total_tokens": 740, + "total_cost_usd": 0.006, + "verdict": "running" + }, + { + "phase": "checkpoint", + "runs": 1, + "spans": 5, + "evals": 1, + "errors": 0, + "total_tokens": 1810, + "total_cost_usd": 0.017, + "verdict": "running" + }, + { + "phase": "testing", + "runs": 1, + "spans": 7, + "evals": 1, + "errors": 0, + "total_tokens": 2320, + "total_cost_usd": 0.021, + "verdict": "running" + }, + { + "phase": "failed", + "runs": 1, + "spans": 8, + "evals": 2, + "errors": 2, + "total_tokens": 2760, + "total_cost_usd": 0.022, + "verdict": "fail" + }, + { + "phase": "retesting", + "runs": 2, + "spans": 13, + "evals": 3, + "errors": 2, + "total_tokens": 3910, + "total_cost_usd": 0.033, + "verdict": "recovering" + }, + { + "phase": "completed", + "runs": 2, + "spans": 16, + "evals": 4, + "errors": 2, + "total_tokens": 4280, + "total_cost_usd": 0.036, + "verdict": "pass" + } + ], + "failure": { + "visible_from_phase": "failed", + "run_id": "run-demo-failed-test", + "checkpoint_id": "cp-demo-before-test", + "failed_step": "test", + "error_message": "zig build test exited with status 1", + "suggested_intervention": "Fork from checkpoint and inject the missing validation guard." + }, + "recovery": { + "visible_from_phase": "forking", + "run_id": "run-demo-recovered-fork", + "forked_from": "cp-demo-before-test", + "human_instruction": "apply missing validation guard" + } +} diff --git a/src/api/mission_control_replay.zig b/src/api/mission_control_replay.zig new file mode 100644 index 0000000..5f918f0 --- /dev/null +++ b/src/api/mission_control_replay.zig @@ -0,0 +1,501 @@ +const std = @import("std"); + +pub const expected_schema_version: u8 = 1; +pub const embedded_json = @embedFile("mission_control/code_red.v1.json"); + +pub const ReplayFixture = struct { + schema_version: u8, + mode: []const u8, + scenario_id: []const u8, + scenario_version: []const u8, + title: []const u8, + run_ids: RunIds, + checkpoint_id: []const u8, + human_instruction: []const u8, + phases: []const PhaseDef, + agents: []const AgentDef, + graph: GraphDef, + events: []const EventDef, + telemetry: []const TelemetryDef, + failure: FailureDef, + recovery: RecoveryDef, +}; + +pub const RunIds = struct { + failed: []const u8, + recovered: []const u8, +}; + +pub const PhaseDef = struct { + id: []const u8, + track: []const u8, + rank: u8, + starts_at_ms: i64, + status: []const u8, + progress: u8, + headline: []const u8, +}; + +pub const AgentDef = struct { + id: []const u8, + role: []const u8, + active_phases: []const []const u8, + done_after_phase: []const u8, + blocked_phase: ?[]const u8, + failed_phase: ?[]const u8, + steps: []const AgentStepDef, +}; + +pub const AgentStepDef = struct { + phase: []const u8, + step: []const u8, +}; + +pub const GraphDef = struct { + nodes: []const GraphNodeDef, + edges: []const GraphEdgeDef, +}; + +pub const GraphNodeDef = struct { + id: []const u8, + label: []const u8, + kind: []const u8, + phase: []const u8, + error_phase: ?[]const u8, +}; + +pub const GraphEdgeDef = struct { + from: []const u8, + to: []const u8, + phase: []const u8, + error_phase: ?[]const u8, +}; + +pub const EventDef = struct { + at_ms: i64, + phase: []const u8, + source: []const u8, + level: []const u8, + title: []const u8, + detail: []const u8, + trace: ?EventTraceDef = null, +}; + +pub const EventTraceDef = struct { + kind: []const u8, + run_id: ?[]const u8 = null, + trace_id: ?[]const u8 = null, + span_id: ?[]const u8 = null, + eval_key: ?[]const u8 = null, + operation: []const u8, +}; + +pub const TelemetryDef = struct { + phase: []const u8, + runs: usize, + spans: usize, + evals: usize, + errors: usize, + total_tokens: usize, + total_cost_usd: f64, + verdict: []const u8, +}; + +pub const FailureDef = struct { + visible_from_phase: []const u8, + run_id: []const u8, + checkpoint_id: []const u8, + failed_step: []const u8, + error_message: []const u8, + suggested_intervention: []const u8, +}; + +pub const RecoveryDef = struct { + visible_from_phase: []const u8, + run_id: []const u8, + forked_from: []const u8, + human_instruction: []const u8, +}; + +pub const ValidationError = error{ + UnsupportedReplaySchema, + InvalidReplayFixture, + DuplicateReplayId, + UnknownReplayReference, + UnsortedReplayFixture, +}; + +pub fn parse(allocator: std.mem.Allocator) !std.json.Parsed(ReplayFixture) { + return parseBytes(allocator, embedded_json); +} + +pub fn parseBytes(allocator: std.mem.Allocator, bytes: []const u8) !std.json.Parsed(ReplayFixture) { + return std.json.parseFromSlice(ReplayFixture, allocator, bytes, .{ + .allocate = .alloc_always, + .ignore_unknown_fields = false, + }); +} + +pub fn parseValidated(allocator: std.mem.Allocator) !std.json.Parsed(ReplayFixture) { + var parsed = try parse(allocator); + errdefer parsed.deinit(); + try validate(parsed.value); + return parsed; +} + +pub fn validate(fixture: ReplayFixture) ValidationError!void { + if (fixture.schema_version != expected_schema_version) return error.UnsupportedReplaySchema; + try requireNonEmpty(fixture.mode); + try requireNonEmpty(fixture.scenario_id); + try requireNonEmpty(fixture.scenario_version); + try requireNonEmpty(fixture.title); + try requireNonEmpty(fixture.run_ids.failed); + try requireNonEmpty(fixture.run_ids.recovered); + try requireNonEmpty(fixture.checkpoint_id); + try requireNonEmpty(fixture.human_instruction); + + try validatePhases(fixture); + try requirePhase(fixture, "idle"); + try requirePhase(fixture, "failed"); + try requirePhase(fixture, "completed"); + try validateAgents(fixture); + try validateGraph(fixture); + try validateEvents(fixture); + try validateTelemetry(fixture); + try validateFailure(fixture.failure, fixture); + try validateRecovery(fixture.recovery, fixture); +} + +pub fn phaseById(fixture: ReplayFixture, id: []const u8) ?PhaseDef { + for (fixture.phases) |phase| { + if (std.mem.eql(u8, phase.id, id)) return phase; + } + return null; +} + +pub fn phaseRank(fixture: ReplayFixture, id: []const u8) ?u8 { + return if (phaseById(fixture, id)) |phase| phase.rank else null; +} + +fn validatePhases(fixture: ReplayFixture) ValidationError!void { + if (fixture.phases.len == 0) return error.InvalidReplayFixture; + + for (fixture.phases, 0..) |phase, index| { + try requireNonEmpty(phase.id); + try requireNonEmpty(phase.track); + try requireNonEmpty(phase.status); + try requireNonEmpty(phase.headline); + if (!isKnownTrack(phase.track)) return error.InvalidReplayFixture; + if (phase.progress > 100) return error.InvalidReplayFixture; + if (phase.starts_at_ms < 0) return error.InvalidReplayFixture; + + for (fixture.phases[0..index]) |previous| { + if (std.mem.eql(u8, previous.id, phase.id)) return error.DuplicateReplayId; + if (previous.rank == phase.rank) return error.DuplicateReplayId; + } + } + + try validateTrackOrdering(fixture, "primary"); + try validateTrackOrdering(fixture, "recovery"); +} + +fn validateTrackOrdering(fixture: ReplayFixture, track: []const u8) ValidationError!void { + var seen = false; + var last_start: i64 = 0; + for (fixture.phases) |phase| { + if (!std.mem.eql(u8, phase.track, track)) continue; + if (seen and phase.starts_at_ms < last_start) return error.UnsortedReplayFixture; + seen = true; + last_start = phase.starts_at_ms; + } + if (!seen) return error.InvalidReplayFixture; +} + +fn validateAgents(fixture: ReplayFixture) ValidationError!void { + if (fixture.agents.len == 0) return error.InvalidReplayFixture; + + for (fixture.agents, 0..) |agent, index| { + try requireNonEmpty(agent.id); + try requireNonEmpty(agent.role); + try requirePhase(fixture, agent.done_after_phase); + if (agent.active_phases.len == 0) return error.InvalidReplayFixture; + for (agent.active_phases) |phase| try requirePhase(fixture, phase); + if (agent.blocked_phase) |phase| try requirePhase(fixture, phase); + if (agent.failed_phase) |phase| try requirePhase(fixture, phase); + for (agent.steps) |step| { + try requirePhase(fixture, step.phase); + try requireNonEmpty(step.step); + } + + for (fixture.agents[0..index]) |previous| { + if (std.mem.eql(u8, previous.id, agent.id)) return error.DuplicateReplayId; + } + } +} + +fn validateGraph(fixture: ReplayFixture) ValidationError!void { + if (fixture.graph.nodes.len == 0) return error.InvalidReplayFixture; + + for (fixture.graph.nodes, 0..) |node, index| { + try requireNonEmpty(node.id); + try requireNonEmpty(node.label); + try requireNonEmpty(node.kind); + try requirePhase(fixture, node.phase); + if (node.error_phase) |phase| try requirePhase(fixture, phase); + + for (fixture.graph.nodes[0..index]) |previous| { + if (std.mem.eql(u8, previous.id, node.id)) return error.DuplicateReplayId; + } + } + + for (fixture.graph.edges) |edge| { + try requireNode(fixture, edge.from); + try requireNode(fixture, edge.to); + try requirePhase(fixture, edge.phase); + if (edge.error_phase) |phase| try requirePhase(fixture, phase); + } +} + +fn validateEvents(fixture: ReplayFixture) ValidationError!void { + if (fixture.events.len == 0) return error.InvalidReplayFixture; + var last_at_ms: i64 = 0; + for (fixture.events, 0..) |event, index| { + if (event.at_ms < 0) return error.InvalidReplayFixture; + if (index > 0 and event.at_ms < last_at_ms) return error.UnsortedReplayFixture; + last_at_ms = event.at_ms; + try requirePhase(fixture, event.phase); + try requireNonEmpty(event.source); + try requireNonEmpty(event.level); + try requireNonEmpty(event.title); + try requireNonEmpty(event.detail); + if (event.trace) |trace| try validateEventTrace(trace, fixture); + } +} + +fn validateEventTrace(trace: EventTraceDef, fixture: ReplayFixture) ValidationError!void { + try requireNonEmpty(trace.kind); + try requireNonEmpty(trace.operation); + if (!std.mem.eql(u8, trace.kind, "span") and !std.mem.eql(u8, trace.kind, "eval")) { + return error.InvalidReplayFixture; + } + + if (trace.run_id) |run_id| { + try requireNonEmpty(run_id); + try requireRun(fixture, run_id); + } + if (trace.trace_id) |trace_id| try requireNonEmpty(trace_id); + if (trace.span_id) |span_id| try requireNonEmpty(span_id); + if (trace.eval_key) |eval_key| try requireNonEmpty(eval_key); + + if (std.mem.eql(u8, trace.kind, "span") and trace.span_id == null) return error.InvalidReplayFixture; + if (std.mem.eql(u8, trace.kind, "eval") and trace.eval_key == null) return error.InvalidReplayFixture; +} + +fn validateTelemetry(fixture: ReplayFixture) ValidationError!void { + if (fixture.telemetry.len == 0) return error.InvalidReplayFixture; + for (fixture.telemetry) |entry| { + try requirePhase(fixture, entry.phase); + try requireNonEmpty(entry.verdict); + if (entry.errors > entry.spans) return error.InvalidReplayFixture; + if (entry.evals > entry.spans) return error.InvalidReplayFixture; + if (entry.total_cost_usd < 0) return error.InvalidReplayFixture; + } +} + +fn validateFailure(failure: FailureDef, fixture: ReplayFixture) ValidationError!void { + try requirePhase(fixture, failure.visible_from_phase); + try requireNonEmpty(failure.run_id); + try requireNonEmpty(failure.checkpoint_id); + try requireNonEmpty(failure.failed_step); + try requireNode(fixture, failure.failed_step); + try requireNonEmpty(failure.error_message); + try requireNonEmpty(failure.suggested_intervention); +} + +fn validateRecovery(recovery: RecoveryDef, fixture: ReplayFixture) ValidationError!void { + try requirePhase(fixture, recovery.visible_from_phase); + try requireNonEmpty(recovery.run_id); + try requireNonEmpty(recovery.forked_from); + try requireNonEmpty(recovery.human_instruction); +} + +fn requirePhase(fixture: ReplayFixture, id: []const u8) ValidationError!void { + if (phaseById(fixture, id) == null) return error.UnknownReplayReference; +} + +fn requireNode(fixture: ReplayFixture, id: []const u8) ValidationError!void { + for (fixture.graph.nodes) |node| { + if (std.mem.eql(u8, node.id, id)) return; + } + return error.UnknownReplayReference; +} + +fn requireRun(fixture: ReplayFixture, id: []const u8) ValidationError!void { + if (std.mem.eql(u8, id, fixture.run_ids.failed)) return; + if (std.mem.eql(u8, id, fixture.run_ids.recovered)) return; + return error.UnknownReplayReference; +} + +fn requireNonEmpty(value: []const u8) ValidationError!void { + if (value.len == 0) return error.InvalidReplayFixture; +} + +fn isKnownTrack(track: []const u8) bool { + return std.mem.eql(u8, track, "idle") or + std.mem.eql(u8, track, "primary") or + std.mem.eql(u8, track, "recovery"); +} + +test "embedded mission replay fixture validates" { + var parsed = try parseValidated(std.testing.allocator); + defer parsed.deinit(); + + try std.testing.expectEqual(@as(u8, expected_schema_version), parsed.value.schema_version); + try std.testing.expectEqualStrings("mission-code-red", parsed.value.scenario_id); + try std.testing.expect(phaseById(parsed.value, "completed") != null); +} + +test "validate rejects duplicate phase ids" { + const phases = [_]PhaseDef{ + .{ .id = "idle", .track = "idle", .rank = 0, .starts_at_ms = 0, .status = "idle", .progress = 0, .headline = "idle" }, + .{ .id = "failed", .track = "primary", .rank = 1, .starts_at_ms = 0, .status = "intervention_required", .progress = 60, .headline = "failed" }, + .{ .id = "failed", .track = "recovery", .rank = 2, .starts_at_ms = 0, .status = "completed", .progress = 100, .headline = "done" }, + }; + const fixture = minimalFixture(phases[0..], test_nodes[0..], test_edges[0..], test_events[0..], test_telemetry[0..]); + try std.testing.expectError(error.DuplicateReplayId, validate(fixture)); +} + +test "validate rejects graph edges pointing at unknown nodes" { + const edges = [_]GraphEdgeDef{ + .{ .from = "ticket", .to = "missing", .phase = "failed", .error_phase = null }, + }; + const fixture = minimalFixture(test_phases[0..], test_nodes[0..], edges[0..], test_events[0..], test_telemetry[0..]); + try std.testing.expectError(error.UnknownReplayReference, validate(fixture)); +} + +test "validate rejects telemetry for unknown phases" { + const telemetry = [_]TelemetryDef{ + .{ .phase = "missing", .runs = 1, .spans = 1, .evals = 0, .errors = 0, .total_tokens = 1, .total_cost_usd = 0.001, .verdict = "running" }, + }; + const fixture = minimalFixture(test_phases[0..], test_nodes[0..], test_edges[0..], test_events[0..], telemetry[0..]); + try std.testing.expectError(error.UnknownReplayReference, validate(fixture)); +} + +test "validate rejects trace refs for unknown run ids" { + const events = [_]EventDef{ + .{ + .at_ms = 0, + .phase = "launching", + .source = "nullwatch", + .level = "info", + .title = "event", + .detail = "detail", + .trace = .{ + .kind = "span", + .run_id = "missing-run", + .trace_id = "trace", + .span_id = "span", + .operation = "agent.step", + }, + }, + }; + const fixture = minimalFixture(test_phases[0..], test_nodes[0..], test_edges[0..], events[0..], test_telemetry[0..]); + try std.testing.expectError(error.UnknownReplayReference, validate(fixture)); +} + +test "validate rejects eval trace refs without eval keys" { + const events = [_]EventDef{ + .{ + .at_ms = 0, + .phase = "launching", + .source = "nullwatch", + .level = "info", + .title = "event", + .detail = "detail", + .trace = .{ + .kind = "eval", + .run_id = "failed-run", + .trace_id = "trace", + .span_id = "span", + .operation = "eval.tool_success", + }, + }, + }; + const fixture = minimalFixture(test_phases[0..], test_nodes[0..], test_edges[0..], events[0..], test_telemetry[0..]); + try std.testing.expectError(error.InvalidReplayFixture, validate(fixture)); +} + +fn minimalFixture( + phases: []const PhaseDef, + nodes: []const GraphNodeDef, + edges: []const GraphEdgeDef, + events: []const EventDef, + telemetry: []const TelemetryDef, +) ReplayFixture { + return .{ + .schema_version = expected_schema_version, + .mode = "deterministic_local_replay", + .scenario_id = "test", + .scenario_version = "v1", + .title = "test", + .run_ids = .{ .failed = "failed-run", .recovered = "recovered-run" }, + .checkpoint_id = "checkpoint", + .human_instruction = "fix", + .phases = phases, + .agents = test_agents[0..], + .graph = .{ .nodes = nodes, .edges = edges }, + .events = events, + .telemetry = telemetry, + .failure = .{ + .visible_from_phase = "failed", + .run_id = "failed-run", + .checkpoint_id = "checkpoint", + .failed_step = "ticket", + .error_message = "failed", + .suggested_intervention = "recover", + }, + .recovery = .{ + .visible_from_phase = "completed", + .run_id = "recovered-run", + .forked_from = "checkpoint", + .human_instruction = "fix", + }, + }; +} + +const test_phases = [_]PhaseDef{ + .{ .id = "idle", .track = "idle", .rank = 0, .starts_at_ms = 0, .status = "idle", .progress = 0, .headline = "idle" }, + .{ .id = "launching", .track = "primary", .rank = 1, .starts_at_ms = 0, .status = "running", .progress = 10, .headline = "launch" }, + .{ .id = "failed", .track = "primary", .rank = 2, .starts_at_ms = 100, .status = "intervention_required", .progress = 60, .headline = "failed" }, + .{ .id = "completed", .track = "recovery", .rank = 3, .starts_at_ms = 0, .status = "completed", .progress = 100, .headline = "done" }, +}; + +const test_agent_steps = [_]AgentStepDef{ + .{ .phase = "failed", .step = "work" }, +}; + +const test_agents = [_]AgentDef{ + .{ + .id = "agent", + .role = "coder", + .active_phases = &.{"failed"}, + .done_after_phase = "failed", + .blocked_phase = null, + .failed_phase = null, + .steps = test_agent_steps[0..], + }, +}; + +const test_nodes = [_]GraphNodeDef{ + .{ .id = "ticket", .label = "Ticket", .kind = "tracker", .phase = "launching", .error_phase = null }, +}; + +const test_edges = [_]GraphEdgeDef{}; + +const test_events = [_]EventDef{ + .{ .at_ms = 0, .phase = "launching", .source = "test", .level = "info", .title = "event", .detail = "detail" }, +}; + +const test_telemetry = [_]TelemetryDef{ + .{ .phase = "idle", .runs = 0, .spans = 0, .evals = 0, .errors = 0, .total_tokens = 0, .total_cost_usd = 0, .verdict = "idle" }, +}; diff --git a/src/root.zig b/src/root.zig index aeb7966..33af021 100644 --- a/src/root.zig +++ b/src/root.zig @@ -17,6 +17,8 @@ pub const manager = @import("supervisor/manager.zig"); pub const managed_skills = @import("managed_skills.zig"); pub const meta_api = @import("api/meta.zig"); pub const mdns = @import("mdns.zig"); +pub const mission_control_api = @import("api/mission_control.zig"); +pub const mission_control_replay = @import("api/mission_control_replay.zig"); pub const observability_api = @import("api/observability.zig"); pub const orchestrator = @import("installer/orchestrator.zig"); pub const manifest = @import("core/manifest.zig"); @@ -65,6 +67,8 @@ test { _ = managed_skills; _ = meta_api; _ = mdns; + _ = mission_control_api; + _ = mission_control_replay; _ = observability_api; _ = orchestrator; _ = manifest; diff --git a/src/server.zig b/src/server.zig index 1d7bec5..d764196 100644 --- a/src/server.zig +++ b/src/server.zig @@ -27,6 +27,7 @@ const usage_api = @import("api/usage.zig"); const report_api = @import("api/report.zig"); const orchestration_api = @import("api/orchestration.zig"); const observability_api = @import("api/observability.zig"); +const mission_control_api = @import("api/mission_control.zig"); const launch_args_mod = @import("core/launch_args.zig"); const ui_modules = @import("installer/ui_modules.zig"); const orchestrator = @import("installer/orchestrator.zig"); @@ -790,10 +791,16 @@ pub const Server = struct { instances_api.isTicketsActionPath(target) or logs_api.isLogsPath(target) or orchestration_api.isProxyPath(target) or - observability_api.isProxyPath(target); + observability_api.isProxyPath(target) or + mission_control_api.isPath(target); } fn route(self: *Server, allocator: std.mem.Allocator, method: []const u8, target: []const u8, body: []const u8) Response { + if (mission_control_api.isPath(target)) { + const resp = mission_control_api.handle(allocator, method, target); + return .{ .status = resp.status, .content_type = resp.content_type, .body = resp.body }; + } + if (std.mem.eql(u8, method, "GET")) { if (std.mem.eql(u8, target, "/health")) { return .{ @@ -2191,6 +2198,7 @@ test "routeWithoutServerMutex keeps orchestration proxy requests off global lock try std.testing.expect(Server.routeWithoutServerMutex("/api/orchestration/runs")); try std.testing.expect(Server.routeWithoutServerMutex("/api/orchestration/store/search")); try std.testing.expect(Server.routeWithoutServerMutex("/api/observability/v1/runs")); + try std.testing.expect(Server.routeWithoutServerMutex("/api/mission-control/state")); try std.testing.expect(Server.routeWithoutServerMutex("/api/instances/nullclaw/demo/logs")); try std.testing.expect(Server.routeWithoutServerMutex("/api/instances/nulltickets/tracker-a/tickets")); try std.testing.expect(!Server.routeWithoutServerMutex("/api/components")); diff --git a/tests/test_mission_control_smoke.sh b/tests/test_mission_control_smoke.sh new file mode 100755 index 0000000..dac1475 --- /dev/null +++ b/tests/test_mission_control_smoke.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash +set -euo pipefail + +BASE_URL="${NULLHUB_URL:-http://127.0.0.1:19802}" + +node - "$BASE_URL" <<'NODE' +const base = process.argv[2]; + +async function api(path, method = 'GET') { + const res = await fetch(base + path, { method }); + const text = await res.text(); + const body = text ? JSON.parse(text) : null; + return { status: res.status, body }; +} + +function assert(condition, message) { + if (!condition) throw new Error(message); +} + +function sleep(ms) { + return new Promise((resolve) => setTimeout(resolve, ms)); +} + +let response = await api('/api/mission-control/reset', 'POST'); +assert(response.status === 200, `reset returned ${response.status}`); +assert(response.body.schema_version === 1, 'missing schema_version'); +assert(response.body.mode === 'deterministic_local_replay', 'unexpected mission mode'); +assert(response.body.status === 'idle', `expected idle, got ${response.body.status}`); + +response = await api('/api/mission-control/recover', 'POST'); +assert(response.status === 409, `early recover returned ${response.status}`); +assert(response.body.error?.code === 'mission_not_recoverable', 'missing recover conflict code'); + +response = await api('/api/mission-control/launch', 'POST'); +assert(response.status === 200, `launch returned ${response.status}`); +assert(response.body.status === 'running', `expected running, got ${response.body.status}`); + +response = await api('/api/mission-control/launch', 'POST'); +assert(response.status === 409, `duplicate launch returned ${response.status}`); +assert(response.body.error?.code === 'mission_already_started', 'missing launch conflict code'); + +await sleep(10_500); +response = await api('/api/mission-control/state'); +assert(response.status === 200, `state returned ${response.status}`); +assert(response.body.status === 'intervention_required', `expected intervention_required, got ${response.body.status}`); +assert(response.body.controls.can_recover === true, 'expected recover control'); +const failedEvent = response.body.events.find((event) => event.title === 'Validation failed'); +assert(failedEvent?.trace?.run_id === 'run-demo-failed-test', 'missing failed run trace ref'); +assert(failedEvent?.trace?.eval_key === 'tool_success', 'missing failed eval trace ref'); + +response = await api('/api/mission-control/recover', 'POST'); +assert(response.status === 200, `recover returned ${response.status}`); +assert(response.body.recovered_run_id === 'run-demo-recovered-fork', 'missing recovered run id'); + +await sleep(12_000); +response = await api('/api/mission-control/state'); +assert(response.status === 200, `final state returned ${response.status}`); +assert(response.body.status === 'completed', `expected completed, got ${response.body.status}`); +assert(response.body.telemetry.verdict === 'pass', `expected pass verdict, got ${response.body.telemetry.verdict}`); +const recoveredEvent = response.body.events.find((event) => event.title === 'Recovered tests passed'); +assert(recoveredEvent?.trace?.run_id === 'run-demo-recovered-fork', 'missing recovered run trace ref'); +const finalState = response.body; + +response = await api('/api/mission-control/replay'); +assert(response.status === 200, `replay export returned ${response.status}`); +assert(response.body.artifact_kind === 'nullhub.mission_control.replay', 'unexpected replay artifact kind'); +assert(response.body.snapshot?.status === 'completed', 'replay export missing completed snapshot'); +assert(response.body.replay_fixture?.scenario_id === 'mission-code-red', 'replay export missing source fixture'); +assert(response.body.ecosystem_mapping?.nullwatch?.trace_ref_source === 'events[].trace', 'replay export missing nullwatch mapping'); + +console.log(`mission-control smoke ok: ${finalState.status}, ${finalState.telemetry.spans} spans, ${finalState.telemetry.evals} evals`); +NODE diff --git a/ui/src/lib/api/client.ts b/ui/src/lib/api/client.ts index 6ed8d3d..c3fe7fc 100644 --- a/ui/src/lib/api/client.ts +++ b/ui/src/lib/api/client.ts @@ -20,6 +20,141 @@ export type LogSource = 'instance' | 'nullhub'; export type ReportOption = { value: string; label: string }; export type ReportTypeOption = ReportOption & { labels: string[] }; export type ReportRepoOption = ReportOption & { repo: string }; +export type MissionControlStatus = 'idle' | 'running' | 'intervention_required' | 'completed'; +export type MissionControlPhase = + | 'idle' + | 'launching' + | 'research' + | 'coding' + | 'checkpoint' + | 'testing' + | 'failed' + | 'forking' + | 'patching' + | 'retesting' + | 'review' + | 'completed'; +export type MissionControlControls = { + can_launch: boolean; + can_recover: boolean; + can_reset: boolean; +}; +export type MissionControlAgent = { + id: string; + role: string; + status: string; + current_step: string; +}; +export type MissionControlGraphNode = { + id: string; + label: string; + kind: string; + status: string; +}; +export type MissionControlGraphEdge = { + from: string; + to: string; + status: string; +}; +export type MissionControlTraceRef = { + kind: 'span' | 'eval'; + run_id: string | null; + trace_id: string | null; + span_id: string | null; + eval_key: string | null; + operation: string; +}; +export type MissionControlEvent = { + at_ms: number; + source: string; + level: string; + title: string; + detail: string; + status: string; + trace: MissionControlTraceRef | null; +}; +export type MissionControlTelemetry = { + runs: number; + spans: number; + evals: number; + errors: number; + total_tokens: number; + total_cost_usd: number; + verdict: string; +}; +export type MissionControlFailure = { + run_id: string; + checkpoint_id: string; + failed_step: string; + error_message: string; + suggested_intervention: string; +}; +export type MissionControlRecovery = { + run_id: string; + forked_from: string; + human_instruction: string; + status: string; +}; +export type MissionControlState = { + schema_version: number; + mode: string; + scenario_id: string; + scenario_version: string; + generated_at_ms: number; + mission_id: string; + title: string; + status: MissionControlStatus; + phase: MissionControlPhase; + headline: string; + elapsed_ms: number; + progress: number; + active_run_id: string | null; + failed_run_id: string | null; + recovered_run_id: string | null; + controls: MissionControlControls; + agents: MissionControlAgent[]; + graph: { + nodes: MissionControlGraphNode[]; + edges: MissionControlGraphEdge[]; + }; + events: MissionControlEvent[]; + telemetry: MissionControlTelemetry; + failure: MissionControlFailure | null; + recovery: MissionControlRecovery | null; +}; +export type MissionControlComponentMapping = { + component: string; + role: string; + evidence: string[]; +}; +export type MissionControlWorkflowMapping = MissionControlComponentMapping & { + checkpoint_id: string; + failed_run_id: string; + recovered_run_id: string; + human_instruction: string; +}; +export type MissionControlObservabilityMapping = MissionControlComponentMapping & { + failed_run_id: string; + recovered_run_id: string; + trace_ref_source: string; +}; +export type MissionControlReplayArtifact = { + artifact_schema_version: number; + artifact_kind: string; + generated_at_ms: number; + replay_fixture_path: string; + scenario_id: string; + scenario_version: string; + mode: string; + snapshot: MissionControlState; + replay_fixture: unknown; + ecosystem_mapping: { + nulltickets: MissionControlComponentMapping; + nullboiler: MissionControlWorkflowMapping; + nullclaw: MissionControlComponentMapping; + nullwatch: MissionControlObservabilityMapping; + }; +}; type InstanceStartOptions = { launch_mode?: string; verbose?: boolean; @@ -238,6 +373,12 @@ export const api = { }), ), + getMissionControlState: () => request('/mission-control/state'), + getMissionControlReplay: () => request('/mission-control/replay'), + launchMissionControl: () => request('/mission-control/launch', { method: 'POST' }), + resetMissionControl: () => request('/mission-control/reset', { method: 'POST' }), + recoverMissionControl: () => request('/mission-control/recover', { method: 'POST' }), + applyUpdate: (c: string, n: string) => request(`/instances/${c}/${n}/update`, { method: 'POST' }), diff --git a/ui/src/lib/components/Sidebar.svelte b/ui/src/lib/components/Sidebar.svelte index 0bf74a9..88c3b55 100644 --- a/ui/src/lib/components/Sidebar.svelte +++ b/ui/src/lib/components/Sidebar.svelte @@ -125,6 +125,7 @@