Problem
The Codev sidebar currently has two parallel trees that hide a real relationship between them:
- Architects — flat list of running architect sessions (MAIN, REVIEWER, etc.)
- Builders — area- or phase-grouped list of in-flight builders
Each builder has a spawnedByArchitect owner (the affinity model that routes gates, blocked-on questions, and afx send architect messages back to the spawner). That ownership is invisible in the UI: nothing on a builder row indicates which architect spawned it, and nothing in the Architects tree indicates what each architect is working on. As more workspaces run multiple specialised architects, "which builder is owned by which architect" becomes increasingly load-bearing for triage.
Proposal
Replace the two trees with one Agents section, rooted at architects when multi-architect, collapsing to today's area-or-phase grouping when single-architect. The architect-rooted variant is a 3-level hierarchy that preserves the existing area/phase grouping below the architect tier rather than displacing it. Architect creation becomes a conversation with the main architect rather than a direct CLI call.
Tree shape
When architectCount > 1:
Agents
├── MAIN
│ ├── TOWER (1 blocked · 1 active)
│ │ ├── #1054 fix afx spawn substring match blocked on plan-approval [3h]
│ │ └── #1048 cron evaluator ReferenceError
│ └── VSCODE (1 active)
│ └── #1073 codelens keyboard shortcut
├── VSCODE
│ └── (no builders)
└── REVIEWER
(no builders — passive, never spawns)
When architectCount === 1:
Agents
├── TOWER (1 blocked · 1 active)
│ ├── #1054 fix afx spawn substring match blocked on plan-approval [3h]
│ └── #1048 cron evaluator ReferenceError
└── VSCODE (1 active)
└── #1073 codelens keyboard shortcut
Implemented as a count check in the tree's root getChildren(): when architectCount === 1, skip the architect level entirely and root at area-groups. No user toggle, no config — the level that doesn't earn its keep doesn't render.
What survives
- Existing grouping toggle (group by area vs group by phase) lives at level 2, untouched. Off-axis prefix on builder rows continues to surface the complementary axis.
rollupGroupState / worstBuilderState (builder-row.ts:56-107) extend naturally to a second tier: architect-level rollup at level 1, area/phase-level rollup at level 2.
- Builder file-tree children (
BuilderFileTreeItem, BuilderFolderTreeItem) hang off level-3 builder rows exactly as today.
- Architect rows stay interactive even when childless. A passive architect like REVIEWER renders as a leaf (
collapsibleState: None) — right-click → message stays available without pretending to own work it never will.
description field on builder rows carries the architect name as a dim badge in the single-architect-collapsed view and in any flat sub-tree where the architect isn't already in the row's ancestry. Conditional render (only when architectCount > 1) so single-architect workspaces stay clean.
What goes away
- The standalone Architects tree contributes no view of its own. Its registered tree-view id is either removed or repurposed; its content moves to the Agents root level.
- The existing Builders tree is renamed to Agents and gains the architect-root level adaptively.
Workspace view delineation
The Codev sidebar's Workspace view has its own Architects subsection (workspace.ts:84-92), distinct from the standalone Architects tree this proposal removes. It survives unchanged, reframed by purpose:
- Workspace > Architects = workspace configuration. "Who is registered in this workspace, open their terminals." Configuration-shaped, read-only-style listing.
- Agents (new) = active ownership. "Who owns the in-flight work, with their builders nested." Work-shaped, the primary triage surface.
Both views read from the same architect roster (Tower's architects-updated event), so they stay in sync automatically.
Architect creation: conversational, not direct
The Codev: Add Architect action does not call afx workspace add-architect directly anymore. It becomes a request to the main architect, who decides whether to act on it.
The rationale: architect creation is a workspace-orchestration event — it changes the roster, the specialisation matrix, and the conversation routing. Main is the workspace orchestrator (owns backlog triage, release decisions, sibling-architect dispatch); architect creation belongs in main's lane for the same reason cross-cutting work and release decisions do. Letting any developer create an unbriefed architect via direct CLI call leads to architect proliferation, missing briefs, and roster drift in main's state.
New Codev: Add Architect UX:
- User invokes the action (Agents title-bar
+, Workspace > Architects +, Cmd+K A keybinding, or command palette).
- VS Code shows an input box for the architect name. Same validation as today (single source of truth in
@cluesmith/codev-core, shipped in v3.2.1).
- The extension sends a message to the main architect via
afx send architect:main "Please add a <name> architect." (or the equivalent envelope through Tower's command relay — see Implementation notes).
- Main receives the request, decides whether the specialisation makes sense (may push back, may ask for scope clarification), runs
afx workspace add-architect --name <name> from its own terminal, sends the brief as the new architect's first message, and updates its working memory.
- The Workspace view's Architects subsection and the Agents tree both update automatically once Tower broadcasts
architects-updated.
What stays available as fallbacks:
afx workspace add-architect --name <name> — CLI surface unchanged. Power users who want to bypass main intentionally still can.
- Main is required to be active. If no main architect is registered or its terminal session is closed, the Add Architect action refuses with a message pointing the user at
afx workspace start or the CLI fallback. This is deliberate — the action's contract is "ask main to add", so without main there's nothing to ask.
Optional polish (deferrable, may not ship in v1):
- Side-effect of the Add Architect action could auto-open main's terminal so the user can follow main's response (or push back / clarify scope) without hunting for it.
- A second input prompt could collect a scope/brief sentence to include in the message, sparing main a round-trip. Skip for v1 — let main ask if it needs the scope.
Why this shape
Discussed and validated through a design conversation that ruled out:
- Plain badge on builder rows — minimum-disruption fix, but doesn't surface ownership in the Architects view and forces a per-row visual element competing with the area badge and state suffix.
- Expand-architect-to-show-its-builders within both trees — logical duplication (same builder in two places), and the Architects tree's primary purpose (message/status) gets buried under secondary builder lists.
- Group-by-architect as a 3rd grouping option in the Builders tree — cheap and reversible, but doesn't address the underlying parallel-trees problem and leaves the Architects tree without ownership context.
- Full merge of Architects + Builders + Backlog — the backlog's cardinality (~30+) would dominate the smaller-volume sections; backlog stays in its own tree.
- Direct CLI architect creation from the sidebar
+ — fast but bypasses main's awareness; leads to unbriefed architects and roster drift.
The 3-level adaptive design pays its hierarchy cost only when there's value (multiple active spawners), preserves the existing area/phase organising axis, and keeps passive architects (the REVIEWER pattern) honest as leaf rows rather than always-empty parents. The conversational creation model keeps the roster intentional and main's working memory in sync with reality.
Implementation notes
- Strategy machinery: today's grouping strategies (
builders.ts:71-73) operate one level deep. The architect tier is a new outer wrapper that delegates to the existing strategy at level 2. The strategy interface should stay unchanged; the outer wrapper is a separate concern.
getChildren() branch: root-level call inspects architectCount. When > 1, returns architect nodes; when === 1, returns the current area/phase group nodes directly (today's behaviour).
- Architect node
collapsibleState: Collapsed when it has builders, None when it doesn't. A passive architect therefore looks like a peer leaf to a collapsed parent — interactive but unmistakably empty.
- Rollup at the architect tier sums across all area-groups beneath the architect. Same
BUILDER_STATE_GLYPH vocabulary, same worst-of severity, same tooltip shape (<b> blocked · <i> waiting · <a> active).
Codev: Add Architect command rewrite: today's handler shells out to afx workspace add-architect. New handler resolves the main architect's terminal session (via Tower), prepares the request message, and dispatches it via the existing afx send envelope (or directly through Tower's messaging API to avoid the CLI hop). If main is not registered or its session is closed, the handler shows a modal with the CLI fallback path.
- Tests:
builder-grouping.test.ts, builders-accordion.test.ts, builders-autoreveal.test.ts will need new cases for the multi-architect branch. The single-architect branch should be a regression-test that today's behaviour is preserved bit-for-bit. New tests for the Add Architect handler: main-present → message dispatched; main-absent → modal with CLI fallback; name validation parity with afx workspace add-architect.
Protocol fit
PIR. This is a moderate-scope structural UI change with multiple design decisions baked in (the count-check collapse, the leaf-passive-architect rule, the conversational creation model, the Workspace-view delineation). The plan gate validates the layout decisions before any code is written; the dev gate validates the running tree in the sidebar on both a single-architect and multi-architect workspace, plus the Add Architect → main dispatch flow end-to-end, before the PR is opened.
Open questions
- Should the Agents section ship with a default-expanded state for architects with >0 builders, or default-collapsed? (Default-collapsed is the lighter-touch starting position; default-expanded matches today's Builders-tree behaviour but adds vertical density in multi-architect workspaces.)
- Tree-view id migration: rename the existing
codev.builders id, or register a new codev.agents id and deprecate codev.builders? Affects external when-clause references and any saved view layout.
- Add Architect: should the extension auto-open main's terminal after dispatching the request, or stay silent and trust the toast notification? (Auto-open is helpful for follow-up; silent is less intrusive when main is mid-task.)
- Add Architect: should the input box also collect a scope/brief sentence, or keep it name-only and let main ask? (Name-only ships faster and lets main own the scope conversation; scope-included spares main a round-trip.)
Problem
The Codev sidebar currently has two parallel trees that hide a real relationship between them:
Each builder has a
spawnedByArchitectowner (the affinity model that routes gates, blocked-on questions, andafx send architectmessages back to the spawner). That ownership is invisible in the UI: nothing on a builder row indicates which architect spawned it, and nothing in the Architects tree indicates what each architect is working on. As more workspaces run multiple specialised architects, "which builder is owned by which architect" becomes increasingly load-bearing for triage.Proposal
Replace the two trees with one Agents section, rooted at architects when multi-architect, collapsing to today's area-or-phase grouping when single-architect. The architect-rooted variant is a 3-level hierarchy that preserves the existing area/phase grouping below the architect tier rather than displacing it. Architect creation becomes a conversation with the main architect rather than a direct CLI call.
Tree shape
When
architectCount > 1:When
architectCount === 1:Implemented as a count check in the tree's root
getChildren(): whenarchitectCount === 1, skip the architect level entirely and root at area-groups. No user toggle, no config — the level that doesn't earn its keep doesn't render.What survives
rollupGroupState/worstBuilderState(builder-row.ts:56-107) extend naturally to a second tier: architect-level rollup at level 1, area/phase-level rollup at level 2.BuilderFileTreeItem,BuilderFolderTreeItem) hang off level-3 builder rows exactly as today.collapsibleState: None) — right-click → message stays available without pretending to own work it never will.descriptionfield on builder rows carries the architect name as a dim badge in the single-architect-collapsed view and in any flat sub-tree where the architect isn't already in the row's ancestry. Conditional render (only whenarchitectCount > 1) so single-architect workspaces stay clean.What goes away
Workspace view delineation
The Codev sidebar's Workspace view has its own Architects subsection (
workspace.ts:84-92), distinct from the standalone Architects tree this proposal removes. It survives unchanged, reframed by purpose:Both views read from the same architect roster (Tower's
architects-updatedevent), so they stay in sync automatically.Architect creation: conversational, not direct
The
Codev: Add Architectaction does not callafx workspace add-architectdirectly anymore. It becomes a request to the main architect, who decides whether to act on it.The rationale: architect creation is a workspace-orchestration event — it changes the roster, the specialisation matrix, and the conversation routing. Main is the workspace orchestrator (owns backlog triage, release decisions, sibling-architect dispatch); architect creation belongs in main's lane for the same reason cross-cutting work and release decisions do. Letting any developer create an unbriefed architect via direct CLI call leads to architect proliferation, missing briefs, and roster drift in main's state.
New
Codev: Add ArchitectUX:+, Workspace > Architects+,Cmd+K Akeybinding, or command palette).@cluesmith/codev-core, shipped in v3.2.1).afx send architect:main "Please add a <name> architect."(or the equivalent envelope through Tower's command relay — see Implementation notes).afx workspace add-architect --name <name>from its own terminal, sends the brief as the new architect's first message, and updates its working memory.architects-updated.What stays available as fallbacks:
afx workspace add-architect --name <name>— CLI surface unchanged. Power users who want to bypass main intentionally still can.afx workspace startor the CLI fallback. This is deliberate — the action's contract is "ask main to add", so without main there's nothing to ask.Optional polish (deferrable, may not ship in v1):
Why this shape
Discussed and validated through a design conversation that ruled out:
+— fast but bypasses main's awareness; leads to unbriefed architects and roster drift.The 3-level adaptive design pays its hierarchy cost only when there's value (multiple active spawners), preserves the existing area/phase organising axis, and keeps passive architects (the REVIEWER pattern) honest as leaf rows rather than always-empty parents. The conversational creation model keeps the roster intentional and main's working memory in sync with reality.
Implementation notes
builders.ts:71-73) operate one level deep. The architect tier is a new outer wrapper that delegates to the existing strategy at level 2. The strategy interface should stay unchanged; the outer wrapper is a separate concern.getChildren()branch: root-level call inspectsarchitectCount. When > 1, returns architect nodes; when === 1, returns the current area/phase group nodes directly (today's behaviour).collapsibleState:Collapsedwhen it has builders,Nonewhen it doesn't. A passive architect therefore looks like a peer leaf to a collapsed parent — interactive but unmistakably empty.BUILDER_STATE_GLYPHvocabulary, same worst-of severity, same tooltip shape (<b> blocked · <i> waiting · <a> active).Codev: Add Architectcommand rewrite: today's handler shells out toafx workspace add-architect. New handler resolves the main architect's terminal session (via Tower), prepares the request message, and dispatches it via the existingafx sendenvelope (or directly through Tower's messaging API to avoid the CLI hop). If main is not registered or its session is closed, the handler shows a modal with the CLI fallback path.builder-grouping.test.ts,builders-accordion.test.ts,builders-autoreveal.test.tswill need new cases for the multi-architect branch. The single-architect branch should be a regression-test that today's behaviour is preserved bit-for-bit. New tests for the Add Architect handler: main-present → message dispatched; main-absent → modal with CLI fallback; name validation parity withafx workspace add-architect.Protocol fit
PIR. This is a moderate-scope structural UI change with multiple design decisions baked in (the count-check collapse, the leaf-passive-architect rule, the conversational creation model, the Workspace-view delineation). The plan gate validates the layout decisions before any code is written; the dev gate validates the running tree in the sidebar on both a single-architect and multi-architect workspace, plus the Add Architect → main dispatch flow end-to-end, before the PR is opened.
Open questions
codev.buildersid, or register a newcodev.agentsid and deprecatecodev.builders? Affects externalwhen-clause references and any saved view layout.