2026-05-09 — petrova.host v1 — fleet dashboard
rank: decision outranks: [finding, runbook]
Section titled “rank: decision outranks: [finding, runbook]”2026-05-09 — petrova.host v1 — fleet dashboard
Section titled “2026-05-09 — petrova.host v1 — fleet dashboard”Date: 2026-05-09 Status: closed Supersedes: none Superseded-by: none — current
Context
Section titled “Context”v0 shipped a JSON-RPC API at petrova.host/rpc. v1 adds a read-only
operations console at /console that consumes the same API via server-side
fetches, turning petrova.host from a headless endpoint into a visible fleet
dashboard. Implementation tracked in
docs/superpowers/plans/2026-05-09-petrova-host-v1-dashboard-plan.md.
Decisions
Section titled “Decisions”D1 — Private (Vercel Password Protection)
Section titled “D1 — Private (Vercel Password Protection)”The dashboard is not for public consumption. Fleet internals (registry,
governance state, decisions, prompts) are behind Vercel Password Protection
on the petrova-host project. Enabling password protection is a manual
Vercel project setting — it cannot be wired in vercel.json. Note in the
PR description.
D2 — Per-request /rpc calls (no ISR / no cache)
Section titled “D2 — Per-request /rpc calls (no ISR / no cache)”Every SSR page calls /rpc on each request with no caching layer. Latency
is the source-of-truth signal for an ops console; stale data is worse than
a slow page.
D3 — Same Vercel project, different function
Section titled “D3 — Same Vercel project, different function”Dashboard Astro SSR pages run as Vercel functions alongside api/rpc.ts in
the existing petrova-host project. One deploy, one domain, one bearer
secret. vercel.json updated: buildCommand builds dashboard/, and
outputDirectory points at dashboard/.vercel/output so Vercel picks up
the Astro adapter output while the api/rpc.ts function block is preserved.
D4 — Astro SSR with @astrojs/vercel
Section titled “D4 — Astro SSR with @astrojs/vercel”Chosen because site/ (petrova.blog) already uses Astro, making design
tokens, CSS conventions, and the build adapter familiar. The @astrojs/vercel
adapter emits SSR pages as Vercel functions. Dashboard is a custom layout
(not Starlight) — it is an ops console, not documentation.
D5 — Read-only
Section titled “D5 — Read-only”No mutating RPC calls in v1. All write surfaces (phase transitions, decision creation) are deferred to v2.
D6 — Bearer stays server-side
Section titled “D6 — Bearer stays server-side”PETROVA_HOST_BEARER is read only inside Astro server-side frontmatter code
via dashboard/src/lib/rpc.ts. It is never passed to client-side scripts or
embedded in rendered HTML.
Architecture
Section titled “Architecture”Browser ──▶ /console/* (Vercel Password gate) │ ▼ Astro SSR page (function) │ callRpc(method, params) │ POST /rpc Authorization: Bearer ENV ▼ api/rpc.ts (v0, intact) │ ▼ PetrovaSource / EvaSource / KahnSource / GraceSourceSurfaces shipped (MVP)
Section titled “Surfaces shipped (MVP)”| Route | Description |
|---|---|
/console | Fleet overview — registry × state cards, alphabetical sort |
/console/repo/[slug] | Single-repo deep view — state, transitions, decisions, prompts |
/console/decisions | Decision search (q + repo params, server-side form submit) |
/console/decisions/[id] | Decision detail — body rendered as prose |
/console/prompts | Prompt library list |
/console/prompts/[id] | Prompt detail — body rendered as prose |
/console/governance | Fleet-wide audit — rows × phases heatmap |
Mount point
Section titled “Mount point”Dashboard at /console/*. Landing public/index.html stays at / — the
public face is preserved and the dashboard path is unambiguous (Q1 answer
from the implementation briefing).
Files added / modified
Section titled “Files added / modified”dashboard/src/layouts/Shell.astro— shared dark-monospace shelldashboard/src/pages/console/index.astro— fleet overviewdashboard/src/pages/console/repo/[slug].astro— repo deep viewdashboard/src/pages/console/decisions/index.astro— decision searchdashboard/src/pages/console/decisions/[id].astro— decision detaildashboard/src/pages/console/prompts/index.astro— prompt listdashboard/src/pages/console/prompts/[id].astro— prompt detaildashboard/src/pages/console/governance.astro— audit heatmapvercel.json—buildCommand+outputDirectoryfor dual-output build
Pre-existing (not modified):
dashboard/src/lib/rpc.ts— server-side RPC helperdashboard/src/styles/console.css— design tokensdashboard/astro.config.mjs— Astro SSR config withbase: "/console"dashboard/package.json—@astrojs/vercel+astrodeps
Acceptance criteria (from plan)
Section titled “Acceptance criteria (from plan)”| Task | Criterion | Result |
|---|---|---|
| 1 | astro build succeeds locally | Passed — 0 errors, 0 warnings |
| 2 | Shared layout renders with dark monospace tokens | Passed — Shell.astro + console.css |
| 3 | callRpc reads bearer server-side only | Passed — env-only read in lib/rpc.ts |
| 4 | Fleet overview renders repo cards | Passed — parallel Promise.all fan-out |
| 5 | /repo/[slug] shows transitions, decisions, prompts | Passed — parallel fetch |
| 6 | Decisions search + detail | Passed |
| 7 | Prompts list + detail | Passed |
| 8 | Governance audit heatmap | Passed |
| 9 | vercel.json updated, api/rpc.ts intact | Passed |
| 10 | Vercel Password Protection | Manual step — note in PR |
| 11 | Landing at / unchanged | public/index.html untouched |
| 12 | This decision doc | This doc |
Known gaps (v2)
Section titled “Known gaps (v2)”- Write surfaces (phase transitions, decision creation).
- Real-time updates (no SSE).
- Per-user auth (single shared Vercel password in v1).
- Client-side filtering / debounced search (decisions page uses a form submit).
- Vercel Password Protection cannot be enabled from code — requires manual project setting.
Alternatives considered
Section titled “Alternatives considered”- Next.js for dashboard — rejected: Astro matches the existing
site/stack; no need for a second framework footprint. - Dashboard on a separate Vercel project — rejected (D3): adds a second domain, second bearer rotation point, and split deploys. Only fall back if the dual-output build proves unworkable.
- ISR / edge caching — rejected (D2): staleness is unacceptable for ops data.
Consequences
Section titled “Consequences”/consoleis live once deployed and password-protected. The landing page at/remains public.- SSR pages add a latency hop (Astro function →
/rpcfunction). Acceptable for v1; v1.1 can short-circuit by importing handlers directly if p95 > 2s. vercel.jsonchange meansvercel --prodnow runscd dashboard && npm install && npm run buildbefore deploying the function bundle.
Sign-off
Section titled “Sign-off”- Subagent: claude:petrova-host-v1
- Human: alex@devarno.com 2026-05-09