Date: 2026-07-08 Status: Accepted
Context
A frontend/UX audit of the Rocky console (rocky.erid.tech) surfaced four operator-facing complaints:
- The left-nav taxonomy is confusing (13 items grouped
Instrument / Observe / Configurewith subsystem codesSS-04,SS-07,HATCH,AGENT, etc. rendered as mono chips next to each label). - Repo Sniffer occupies a top-level nav slot, though it is a single-purpose utility.
- The
/ralphpage rendersNO DATAon a workspace with zero submitted runs, with no visible call to action. - The
/agentspage is a projection-only surface that empty-states with "Go to workspace →", giving the operator no direct action.
Four parallel analysis streams (primary IA proposal, adversarial alternative, framing critic, factual grounder) converged on a subtler diagnosis than "the sidebar is cluttered":
- Streams disagreed on nav restructure (entity-shaped vs. agent-lifecycle-shaped vs. no-restructure), but agreed that subsystem codes leaking into the operator surface (
sidebar.tsx:60-168,278-285) is a category error, not a polish miss. - The framing critic (Stream 3) flagged an unresolved persona conflation: intent.md says "developer or small team," the spec's Polar tier ladder implies external paying customers, and the SS-code aesthetic reads as internal-devarno-ops. Every unresolved persona debate hides in nav ambiguity forever.
- The factual grounder (Stream 4) confirmed the console is on Next.js App Router with 13 top-level surfaces; the SS chips are hardcoded inline in
console/src/components/layout/sidebar.tsx:60-168with no config layer; andMILESTONES.md+docs/decisions/show the pipeline of new UI subsystems is essentially one (Phase 8 KILN as a consumer contract, ADR 0011).
Before any IA edit, the persona conflation must be resolved. Design work downstream of this ADR (nav labels, empty-state CTAs, chip visibility, workspace-vs-fleet framing) all depend on the answer.
Decision
Rocky's operator is a single persona: the workspace operator — a developer or small team running one or more project workspaces of their own.
The console is designed for this persona and only this persona. Every UI edit, empty-state, and nav decision optimizes for the operator's task loop:
submit a workspace-scoped RALPH run → observe outcome on a CAIRNET-backed dashboard → provision knowledge infrastructure — without leaving the workspace context.
(Verbatim from docs/north-star/intent.md:23.)
What this means concretely
- Subsystem codes (SS-04, SS-07, HATCH, AGENT, REQ, INTEL) are engineering topology and MUST NOT appear on operator-facing chrome. They stay in:
- URLs where useful for debuggability
- decision docs, CLAUDE.md files, and
AGENTS.xml - a keyboard-triggered dev overlay (
?debug=1or a shortcut) for internal work - never in nav labels, page headers, or breadcrumbs seen by a non-devarno operator
- The workspace is the primary object. Cross-workspace views are secondary. Any surface without a workspace context is either (a) an admin surface (bound to role, not nav), (b) a global settings surface, or (c) a bug.
- Fleet-scale ambition is capped. The apparent pipeline of "many more integrations" (KAHN Scope, Polar, KILN, LORE, CAIRNET, HATCH federation) is not new operator-facing nav slots. It is either:
- a producer contract (Rocky emits; other product owns the surface — e.g. KAHN Scope lives at kahn-hq)
- a consumer contract (Rocky reads; the surface stays workspace-scoped — e.g. KILN per ADR 0011)
- a driver / backend concern (no UI, e.g. HEARTH DevarnoCloud driver Phase 6b) Rocky's operator sidebar SHOULD NOT grow past its current cardinality; new subsystems must find a home inside an existing surface or land as a workspace-tab.
- The "operator" is neither the devarno-internal engineer nor the multi-tenant SaaS customer. Both those personas are served elsewhere: devarno-internal uses the raw repo + decision ledger; multi-tenant billing/entitlement lives in Polar's own surface + Rocky's admin routes (role-gated, not persona-first).
What this ADR explicitly rejects
- Rejected: agent-lifecycle IA (Register → Provision → Run → Observe → Reconcile). Reshaping Rocky around a generic agent-ops model violates
intent.md:65("Rocky is not for … arbitrary agent orchestration that isn't workspace-scoped") and drift-watch 1 (generic-agent-ledger). Rocky is not an agent control plane; it is a workspace console that happens to house agent producers. - Rejected: five-peer fleet-nav restructure (
Overview / Workspaces / Fleet / Activity / Settings) as a Phase-1 change. Over-designs for a fleet Rocky is explicitly forbidden from becoming. The workspace-scoped shape already IS the correct shape; the fix is to make it legible, not to re-carve the routes. - Rejected: seeding demo runs into
/ralph's empty state. Injecting synthetic runs pollutes the HATCH audit ledger (agent-audit.json) and creates a shadow-mode operators cannot distinguish from real state. The tenancy invariant (Airlock → HATCH → Polar → action) requires audit events be write-real. The empty-state fix is a call-to-action pointing at the existing (buried) submit surface atralph/prompts/[file]/page.tsx:147, not fake data. - Rejected: "Agents" as a standalone fleet registry.
/agentsis a projection of workspace-scopedagent.*events; without a workspace it has no coherent content. The empty-state fix is a workspace picker on entry, not a rethink into a global registry.
Consequences
Immediate (Phase 8-adjacent, no route changes):
- SS-code chips are removed from
console/src/components/layout/sidebar.tsxrender. TheViewDef.ssfield is retained on internal data (still useful for future?debug=1overlays) but no operator sees it. First implementation: separate PR. /ralphempty-state gets a "Start a run" CTA linking to prompt selection. First implementation: separate PR./snifferdemotes from top-level nav into a workspace-scoped tool. The/snifferroute remains (for palette and deep-link stability); nav entry moves under Workspace. First implementation: separate PR./agentsempty-state replaces its "Go to workspace →" link with a workspace picker. First implementation: separate PR.- Section labels
Instrument / Observe / Configure(which broke because RALPH is both instrument and observe) collapse into a workspace-first taxonomy. Specific labels deferred to the sidebar PR that lands the chip removal.
Long-term (post-Phase 8):
- Any proposal to add a new top-level nav entry requires a decision doc referencing this ADR and justifying why the surface cannot live inside an existing workspace tab. Presumption is against additions.
- Any proposal to render cross-workspace fleet views (a "fleet dashboard," a global agent registry, a cross-tenant activity feed) requires a decision doc referencing this ADR and drift-watch 1. Presumption is against; if accepted, the surface is admin-role-gated and clearly labeled as such.
- If a second persona ever becomes real (e.g. a support-operator role for devarno cloud), it gets its own console (or its own subdomain of
erid.tech), not a persona-toggle inside Rocky.
References
docs/north-star/intent.md§"Who Rocky is for", §"Not for", §Drift watch 1 (generic-agent-ledger)docs/specs/2026-05-02-rocky-system-redesign.md§Subsystem map, §Polar.sh integrationdocs/decisions/2026-05-08-erid-domain-adoption.md— Rocky lives atrocky.erid.tech; pantheon citizens live on siblings, not inside Rocky- ADR 0011 — Rocky as KILN consumer, not originator
console/src/components/layout/sidebar.tsx:60-168— current SS-code render site (target of the first follow-on PR)console/src/app/agents/page.tsx+src/components/agent/agent-directory.tsx:267— current Agents projection surfaceconsole/src/app/ralph/page.tsx:176— current NO DATA empty-stateconsole/src/app/sniffer/page.tsx— current top-level Sniffer route