CB-548: architect slots — fresh clean-room advisory peers #16

Open
opened 2026-08-13 16:28:39 +02:00 by ltms · 1 comment
Owner

Problem

Leads are intentionally long-running, human-facing sessions. Their context accumulates across issues, which is useful for continuity but poor for narrow planning and investigation. A lead needs two independent, strong-model partners that start from a clean context for each engagement, advise the lead or an involved worker, then disappear.

This is not the orchestrator tier described by the current CB-500 Development C design. The human-facing root does not move: requests still land on a lead, and the lead decides after consulting both architects.

Fixed semantics

  • Two stable, config-declared slots (for example architect-1, architect-2).
  • Slot identity persists; session context does not.
  • Every engagement spawns a brand-new peer session and discards it after its terminal report.
  • A lead sends the same self-contained context slice separately to both architects. They work independently and cannot see each other's result through this flow.
  • The lead reads both reports and decides. The daemon does not enforce quorum or adjudication.
  • Architect stop/go advice is an ordinary status-gated bridge message. It does not interrupt or preempt a busy target; a worker may see it only after its current turn.
  • Local gateway only. Federation and global names remain CB-308 work.

Session seam (depends on CB-547)

Each engagement uses the fixed CB-547 launch contract:

new SpawnRequest(profileName, requestedCwd, callerCwd,
        slotName, null /* always fresh; never resume architect context */)

The logical slot name is gateway-local. Architect lifecycle must branch on peer capabilities rather than adapter kind. CB-548 must not merge until CB-547 has landed on main.

Identity and authorization

Add a connection-resolved ARCHITECT role with least privilege:

Action Architect
bridge_send ordinary advisory message to an addressable lead or worker allow
bridge_reply as its own terminal allow
read status/roster needed for addressing allow
spawn peers deny
stop peers deny
drain another inbox deny
act/reply as another session deny

An architect's identity comes from its live slot-to-terminal binding and the existing connection PID-to-pane resolution, never from a request argument. Do not reuse PRIMARY or widen WORKER.

bridge_send remains ordinary status-gated delivery. Do not add priority, interruption, cancellation, or pane-teardown authority. A direct architect advisory must not silently replace the worker's existing delegator/reply routing or create a second mandatory turn obligation.

Slot lifecycle and contention

  • Config declares a stable slot name and a strong-model profile.
  • Engagement of an idle slot creates one fresh live terminal with sessionName=slotName and resumeSessionId=null.
  • The live binding makes that connection resolve as ARCHITECT and makes the slot addressable in the roster.
  • A slot remains singleton: it never has more than one live engagement.
  • A second engagement of a busy slot queues instead of being refused. Admission is FIFO per slot and promotes the oldest non-expired request when the live engagement releases/fails.
  • Queue waits are bounded. Expiry returns a clear named timeout outcome; cancellation removes a pending request without spawning.
  • The MCP primitive engages one named slot per request. A lead requests both slots independently in canonical configured-slot order and polls both; no call holds one slot while waiting for another, so two leads cannot deadlock by opposite lock order.
  • The accepted tradeoff is latency: one lead may wait for another lead's short architect engagement. Do not multiply slots or introduce concurrent sessions per slot to hide that wait; keeping two literal singleton architects is the requirement.
  • Completion or teardown clears the live binding while preserving the configured slot, then promotes one queued request.
  • Roster distinguishes configured-but-idle, queued/live, and unknown slot names; live addressing resolves the slot's current terminal.
  • Configured/scanned leaders remain unchanged and are never spawned by this feature.

Architect reply charter

Architect startup uses a role-specific charter, not the worker implementer charter:

  • Its terminal report goes to its delegating lead via exactly one bridge_reply.
  • Any stop/go advice to a worker is an independent advisory bridge_send and creates no reply obligation.
  • An architect never replies on behalf of the worker it advised.

Acceptance criteria

  • Two architect slots can be declared with distinct gateway-local names and valid profiles.
  • Duplicate slot names and invalid profile references fail clearly.
  • Engaging each slot produces a fresh session; no architect resume handle is reused.
  • The same slot cannot have two concurrent live sessions.
  • A second engagement of a busy slot queues FIFO and is admitted when the slot frees; it is not rejected merely for contention.
  • Queue waits are bounded and return a clear timeout; cancelling/expiring a waiter does not spawn it later.
  • Two leads requesting both slots cannot deadlock; each slot request is independently queued and no request holds a second slot resource.
  • A live architect connection resolves as ARCHITECT; its role cannot be self-declared.
  • An architect can send ordinary advisory messages to a live lead and worker.
  • An architect can reply only as its own terminal.
  • Architect spawn, stop, drain, and reply-as-other attempts are refused.
  • An architect message to a busy worker remains status-gated and does not interrupt the active turn or steal its reply route.
  • Completion/stop removes the live terminal binding but leaves the slot configured and addressable as idle.
  • The fleet roster reports architect slots separately from leads and workers, including idle/queued/live state and current session address when live.
  • A lead can fan out an identical brief to both slots and receive two independent reports; no daemon quorum is introduced.
  • The role-specific architect charter routes the terminal report to the delegating lead and gives worker advice no reply obligation.
  • Existing leaders:/leadScan: identity and worker delegation tests remain unchanged in behavior.
  • CLAUDE.md portable charter, its wiki template, config example, MCP contract, implementation docs, roadmap, and Features are updated and synchronized where their role/tool claims change.
  • Full mvn clean install passes and edited files have no IDE errors or warnings.

Explicitly deferred

  • Architect-to-architect communication or result sharing.
  • Daemon-enforced quorum, voting, or adjudication.
  • Turn interruption, priority messages, cooperative cancellation, or forced pane stop by an architect.
  • Architect session resume or fork.
  • Managing/spawning/resuming leads.
  • Cross-gateway architect slots, globally unique names, or federated addressing (CB-308).
  • Automatic ticket mutation; attaching advice to a ticket remains a lead/tool workflow unless separately specified.

Documentation correction

CB-500 Development C currently describes a different architecture in which the human drives a top-tier orchestrator that manages lead sessions. Update the roadmap/design status so that proposal is not mistaken for CB-548's chosen product behavior. Preserve the still-true premise that configured leaders pre-exist and are recognized rather than spawned.

## Problem Leads are intentionally long-running, human-facing sessions. Their context accumulates across issues, which is useful for continuity but poor for narrow planning and investigation. A lead needs two independent, strong-model partners that start from a clean context for each engagement, advise the lead or an involved worker, then disappear. This is **not** the orchestrator tier described by the current CB-500 Development C design. The human-facing root does not move: requests still land on a lead, and the lead decides after consulting both architects. ## Fixed semantics - Two stable, config-declared slots (for example `architect-1`, `architect-2`). - Slot identity persists; session context does not. - Every engagement spawns a brand-new peer session and discards it after its terminal report. - A lead sends the same self-contained context slice separately to both architects. They work independently and cannot see each other's result through this flow. - The lead reads both reports and decides. The daemon does not enforce quorum or adjudication. - Architect stop/go advice is an ordinary status-gated bridge message. It does not interrupt or preempt a busy target; a worker may see it only after its current turn. - Local gateway only. Federation and global names remain CB-308 work. ## Session seam (depends on CB-547) Each engagement uses the fixed CB-547 launch contract: ```java new SpawnRequest(profileName, requestedCwd, callerCwd, slotName, null /* always fresh; never resume architect context */) ``` The logical slot name is gateway-local. Architect lifecycle must branch on peer capabilities rather than adapter kind. CB-548 must not merge until CB-547 has landed on `main`. ## Identity and authorization Add a connection-resolved `ARCHITECT` role with least privilege: | Action | Architect | |---|---| | `bridge_send` ordinary advisory message to an addressable lead or worker | allow | | `bridge_reply` as its own terminal | allow | | read status/roster needed for addressing | allow | | spawn peers | deny | | stop peers | deny | | drain another inbox | deny | | act/reply as another session | deny | An architect's identity comes from its live slot-to-terminal binding and the existing connection PID-to-pane resolution, never from a request argument. Do not reuse `PRIMARY` or widen `WORKER`. `bridge_send` remains ordinary status-gated delivery. Do not add priority, interruption, cancellation, or pane-teardown authority. A direct architect advisory must not silently replace the worker's existing delegator/reply routing or create a second mandatory turn obligation. ## Slot lifecycle and contention - Config declares a stable slot name and a strong-model profile. - Engagement of an idle slot creates one fresh live terminal with `sessionName=slotName` and `resumeSessionId=null`. - The live binding makes that connection resolve as `ARCHITECT` and makes the slot addressable in the roster. - A slot remains singleton: it never has more than one live engagement. - A second engagement of a busy slot **queues instead of being refused**. Admission is FIFO per slot and promotes the oldest non-expired request when the live engagement releases/fails. - Queue waits are bounded. Expiry returns a clear named timeout outcome; cancellation removes a pending request without spawning. - The MCP primitive engages one named slot per request. A lead requests both slots independently in canonical configured-slot order and polls both; no call holds one slot while waiting for another, so two leads cannot deadlock by opposite lock order. - The accepted tradeoff is latency: one lead may wait for another lead's short architect engagement. Do not multiply slots or introduce concurrent sessions per slot to hide that wait; keeping two literal singleton architects is the requirement. - Completion or teardown clears the live binding while preserving the configured slot, then promotes one queued request. - Roster distinguishes configured-but-idle, queued/live, and unknown slot names; live addressing resolves the slot's current terminal. - Configured/scanned leaders remain unchanged and are never spawned by this feature. ## Architect reply charter Architect startup uses a role-specific charter, not the worker implementer charter: - Its terminal report goes to its delegating lead via exactly one `bridge_reply`. - Any stop/go advice to a worker is an independent advisory `bridge_send` and creates no reply obligation. - An architect never replies on behalf of the worker it advised. ## Acceptance criteria - [ ] Two architect slots can be declared with distinct gateway-local names and valid profiles. - [ ] Duplicate slot names and invalid profile references fail clearly. - [ ] Engaging each slot produces a fresh session; no architect resume handle is reused. - [ ] The same slot cannot have two concurrent live sessions. - [ ] A second engagement of a busy slot queues FIFO and is admitted when the slot frees; it is not rejected merely for contention. - [ ] Queue waits are bounded and return a clear timeout; cancelling/expiring a waiter does not spawn it later. - [ ] Two leads requesting both slots cannot deadlock; each slot request is independently queued and no request holds a second slot resource. - [ ] A live architect connection resolves as `ARCHITECT`; its role cannot be self-declared. - [ ] An architect can send ordinary advisory messages to a live lead and worker. - [ ] An architect can reply only as its own terminal. - [ ] Architect spawn, stop, drain, and reply-as-other attempts are refused. - [ ] An architect message to a busy worker remains status-gated and does not interrupt the active turn or steal its reply route. - [ ] Completion/stop removes the live terminal binding but leaves the slot configured and addressable as idle. - [ ] The fleet roster reports architect slots separately from leads and workers, including idle/queued/live state and current session address when live. - [ ] A lead can fan out an identical brief to both slots and receive two independent reports; no daemon quorum is introduced. - [ ] The role-specific architect charter routes the terminal report to the delegating lead and gives worker advice no reply obligation. - [ ] Existing `leaders:`/`leadScan:` identity and worker delegation tests remain unchanged in behavior. - [ ] `CLAUDE.md` portable charter, its wiki template, config example, MCP contract, implementation docs, roadmap, and Features are updated and synchronized where their role/tool claims change. - [ ] Full `mvn clean install` passes and edited files have no IDE errors or warnings. ## Explicitly deferred - Architect-to-architect communication or result sharing. - Daemon-enforced quorum, voting, or adjudication. - Turn interruption, priority messages, cooperative cancellation, or forced pane stop by an architect. - Architect session resume or fork. - Managing/spawning/resuming leads. - Cross-gateway architect slots, globally unique names, or federated addressing (CB-308). - Automatic ticket mutation; attaching advice to a ticket remains a lead/tool workflow unless separately specified. ## Documentation correction CB-500 Development C currently describes a different architecture in which the human drives a top-tier orchestrator that manages lead sessions. Update the roadmap/design status so that proposal is not mistaken for CB-548's chosen product behavior. Preserve the still-true premise that configured leaders pre-exist and are recognized rather than spawned.
ltms added the blocked label 2026-08-15 13:10:19 +02:00
ltms added this to the 2.0 — one operation centre, many hosts milestone 2026-08-16 18:27:55 +02:00
Author
Owner

Release cut decision: deferred to 2.0.

This is a new capability, not a single-host defect. The 1.1 admission rule is if it would still be broken with exactly one host, it belongs in 1.1 — nothing is broken today without architect slots; the lead simply does the planning itself, which is what the charter already tells it to do.

It is also genuinely blocked rather than merely unstarted. It depends on the CB-547 launch contract, and MemberRegistry.bind is never called, so the half of CB-548 that did land cannot work. Carrying a blocked ticket on the release milestone makes the milestone lie about what is left.

Moving it to 2.0 — one operation centre, many hosts. That is also the more natural home: two independent clean-room advisory peers is an orchestration-tier idea, and the tier above one lead per host is exactly what release 2 is about.

Nothing here is rejected. When it is picked up, the two things to settle first are the MemberRegistry.bind gap and whether the ARCHITECT role's authorization row is still correct after this release's changes to Authz.

**Release cut decision: deferred to 2.0.** This is a new capability, not a single-host defect. The 1.1 admission rule is *if it would still be broken with exactly one host, it belongs in 1.1* — nothing is broken today without architect slots; the lead simply does the planning itself, which is what the charter already tells it to do. It is also genuinely blocked rather than merely unstarted. It depends on the CB-547 launch contract, and `MemberRegistry.bind` is never called, so the half of CB-548 that did land cannot work. Carrying a blocked ticket on the release milestone makes the milestone lie about what is left. Moving it to **2.0 — one operation centre, many hosts**. That is also the more natural home: two independent clean-room advisory peers is an orchestration-tier idea, and the tier above one lead per host is exactly what release 2 is about. Nothing here is rejected. When it is picked up, the two things to settle first are the `MemberRegistry.bind` gap and whether the `ARCHITECT` role's authorization row is still correct after this release's changes to `Authz`.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: fleet/fleetd#16