Date: 2026-04-22 Coordinator: atlas (wr-atlas) Executor: pantheon agent (wr-atlas:0.3) Scope: A — ship-what's-built, no new surfaces
Get the Pantheon dashboard back to a state where Kairos can open it in a browser and see Portfolio + drill into Project Detail without errors. Leverages already-shipped surfaces 1-3 + the merged-but-unverified Themis-PM Hub slice (PR #3).
Single, concrete acceptance bar:
Operator opens dashboard in browser. Portfolio renders card grid (or clean empty-state). Clicks a project. Project Detail loads without 404 banner. DevTools console shows zero errors.
d479eb4 (2026-04-20, PR #3) merged Hub slice: /api/fleet-tasks read proxy + /dispatch section (Themis-PM v1 data surface). Unverified — needs Hub restart to go live.com.k4120s.pm-hub on K20N0S.Single-agent, single-room dispatch:
atlas (wr-atlas:0.0)
│ dispatch spec file + tmux msg
▼
pantheon (wr-atlas:0.3)
│ reads spec, runs /skill-plan, executes
▼
launchd (com.k4120s.pm-hub) → Hub process
│
├── HTTP smoke (3 curls)
├── Browser smoke (playwright-mcp primary, screencapture fallback)
└── STATE.md + chronicle update
│
▼
.done file + tmux callback → atlas
File: /tmp/war-room/atlas/dispatch/pantheon-hub-relaunch.md
Contents:
- Task ID, scope, success criteria
- Exact verification commands (launchctl, curls)
- .done path: /tmp/war-room/atlas/dispatch/pantheon-hub-relaunch.done
- Callback: wr-atlas:0.0
- Mandatory /skill-plan invocation before execution
launchctl kickstart -k gui/$(id -u)/com.k4120s.pm-hublaunchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.k4120s.pm-hub.plistlaunchctl list | grep pm-hubGET /api/projects → HTTP 200, JSON arrayGET /api/project-entities/<first_id>/detail → HTTP 200 (NOT 404)GET /api/fleet-tasks → HTTP 200 (Themis-PM slice alive)All curls with -sS -w '\nHTTP %{http_code}\n'.
playwright-mcp (repo has .playwright-mcp/)screencapture -R into /tmp/war-room/atlas/reports/pantheon-hub-<timestamp>.pngpantheon/.planning/STATE.md: update last_activity, stopped_at, mark surface 3 restart verified + PR #3 slice livepantheon/docs/devlog/chronicle.md: append insight entry with verification results + commit references.done with YAML frontmatter + verification artifacts (curl codes, screenshot paths, console log, STATE.md diff summary)tmux send-keys -t wr-atlas:0.0 -l <one-line-summary> then sleep 0.3; tmux send-keys -t wr-atlas:0.0 C-m (per fleet tmux-send protocol)t=0 atlas writes dispatch spec, sends tmux msg to pantheon pane
t+2s pantheon reads spec, runs /skill-plan
t+30s pantheon confirms d479eb4 fix commit present in local git
pantheon notes pre-restart PID via launchctl list
t+60s pantheon runs launchctl kickstart
t+65s pantheon confirms new PID, state=0 (running)
t+70s pantheon runs API smoke battery
t+90s pantheon runs browser smoke
t+2m pantheon updates STATE.md + chronicle
t+3m pantheon writes .done, sends tmux callback
t+3m atlas reads .done, reports to operator
Artifact trail:
- /tmp/war-room/atlas/dispatch/pantheon-hub-relaunch.md (spec)
- /tmp/war-room/atlas/dispatch/pantheon-hub-relaunch.done (result)
- /tmp/war-room/atlas/reports/pantheon-hub-*.png (screenshots)
- pantheon/.planning/STATE.md (surface 3 verified)
- pantheon/docs/devlog/chronicle.md (insight entry)
No code commits in this scope.
| # | Failure | Detection | Response |
|---|---|---|---|
| 1 | launchctl kickstart sandbox-blocked |
stderr "Operation not permitted" | .done status=blocked. Escalate to operator for direct atlas-pane launchctl. NO silent override. |
| 2 | Plist not loaded | launchctl list empty |
Pantheon bootstraps plist, retries kickstart. If still fails → escalate. |
| 3 | Hub starts then crashes | post-restart exit code ≠ 0 | Pantheon tails logs + reports. Out-of-scope to fix — file to backlog. |
| 4 | Port in use / EADDRINUSE | curl refuses connection | Pantheon identifies squatter via lsof. Operator decides kill. |
| 5 | /api/project-entities/:id/detail still 404 |
curl 404 | Fix not live. Check running bundle vs d479eb4. Rebuild + restart. |
| 6 | /api/fleet-tasks 404 |
curl 404 | PR #3 route not loaded. Diagnose via d479eb4 diff + Hub entrypoint imports. |
| 7 | APIs return 200 but empty | jq length == 0 |
Not a bug to fix. Flag as finding. Pass if empty-state renders cleanly. |
| 8 | Browser console errors | playwright console log non-empty | Capture verbatim in .done. Fails success criteria. |
| 9 | Playwright-mcp unavailable | Tool not loaded | Fall back to manual screencapture + devtools screenshots. |
All failures → .done with status: blocked or status: degraded + artifacts. Atlas NEVER declares success with any of 1-6 or 8 unresolved.
Testing = verification pass. No unit tests.
Acceptance matrix:
| # | Check | Pass criteria | Artifact |
|---|---|---|---|
| 1 | Hub alive | launchctl list state=running, exit=0 |
.done |
| 2 | /api/projects |
HTTP 200, JSON array | .done |
| 3 | /api/project-entities/:id/detail |
HTTP 200, not 404 | .done |
| 4 | /api/fleet-tasks |
HTTP 200 | .done |
| 5 | Portfolio renders | Card grid OR clean empty-state visible | screenshot |
| 6 | Project Detail renders | Click → page loads, tabs visible, no 404 banner | screenshot |
| 7 | Console clean | 0 errors (warnings allowed) | console log |
Session success = all 7 pass.
Verification-before-completion: pantheon MUST provide evidence in .done before claiming success. No bare claims. Atlas reads artifacts before reporting to operator.
Regression scope: zero. No code merged, no behavior changed.