Conduir Role Fabric shared architecture and interface specification
Date: 2026-08-21
Revision: V0.4-SHARED-FINAL-ACCOUNTING-CANDIDATE
Status: source architecture successor after collaborative and independent review
Authority/effect: NONE
Current implementation subject: commit e5b83ec1b4027f22e4e99315ab1cd4c957f98460,
tree 3fdd28fb468844becf924800cdb7283322a05319
Adoption: not adopted; exact review and an immutable successor are required
1. Purpose
This document is the shared contract between:
1. the existing role-queue, Temporal-observer, session-launcher and worker-MCP implementation; and
2. the proposed frontend and MCP interface package previously described as mcp-temporal.
It prevents those efforts from creating two work databases, two role lifecycles, two competing MCP
tool catalogs, or a browser that infers authority from a Temporal or message projection.
The product is named Conduir Role Fabric. Its operator interface is the Role Fabric Console.
Temporal is one orchestration adapter inside the fabric; it is not the product name and is never
work, role, result, message, or effect truth.
2. Evidence and truth boundary
| ID | Evidence | Establishes | Does not establish |
|---|---|---|---|
E-01 | Exact Git subject e5b83ec1b..., tree 3fdd28fb... | Current committed worker MCP, launcher, API and console baseline | Latest mutable worktree bytes or deployment |
E-02 | tools/team_role_mcp.py | Five fixed-context worker tools and stdio MCP transport | Standalone network service or operator control MCP |
E-03 | services/symposium/src/symposium/team_execution/api.py | Existing v2 admin and per-binding agent HTTP routes | Composite onboarding, process lifecycle or run-list API |
E-04 | services/symposium/src/symposium/team_execution/role_kernel.py | SQLite lab work/custody truth, roles, bindings, queues, CAS, leases and outcomes | PostgreSQL, multi-host fencing or production identity |
E-05 | services/symposium/src/symposium/team_execution/role_console.py | Read-only selected-run projection and Phase 0 HTML page | Mutation authority or process-liveness proof |
E-06 | Reported local command python3 -m unittest -v tests/tools/test_team_role_mcp.py tests/tools/test_team_role_session_launcher.py on 2026-08-21 | 13/13 passed: worker MCP 9/9 and session launcher 4/4 | Durable CI receipt, console regression closure or full six-agent run |
E-07 | Proposed mcp-temporal handoff summary | Intended 15-tool taxonomy, seams, OpenAPI/schema scaffold and known questions | Exact bytes: the reported files were not discoverable in local/remote Git or shared worktrees |
E-08 | Concurrent uncommitted console correction | Candidate fix for numbered claimant attribution | Reviewed or committed successor evidence |
E-09 | delivery/00-EXECUTION-CHARTER.md section 9 | Binding evidence discipline for source, build, deployment and effectiveness claims | Runtime enforcement or effect authority |
This specification is therefore a reconciliation candidate, not a claim that the proposed 38-file
package or the current Role Fabric is complete, deployed, or effective.
3. Non-negotiable principles
1. RoleExecutionKernel remains work, claim, lease, result and receipt truth.
2. Temporal supplies durable start, wait, retry, timer, cancellation and observation behavior only.
3. A communication ledger owns messages and per-recipient transport states; it never owns work.
4. The process supervisor owns client process/session state; a role binding does not prove liveness.
5. The operator/meta-agent control plane and worker-agent plane have separate MCP servers and tool
catalogs.
6. The browser consumes an HTTP projection/BFF. It does not call a local stdio MCP directly.
7. Phase 0 is local, loopback, single-host and effect=NONE; lack of multi-host support is explicit
noncoverage rather than a blocker.
8. No role, successful task, review or certification implicitly grants merge, push, deploy, release,
destructive mutation or external effect authority.
9. All mutation uses expected-version CAS, fences where applicable and replay-safe idempotency.
10. Unknown, unavailable and not-proven states remain visible. They are never rendered as empty,
idle, free, absent or successful.
11. A browser, worker binding and internal service key are three different principals. Loopback
placement alone authenticates none of them.
4. Vocabulary and identity model
There are no seats and no personas in this contract.
| Resource | Example | Meaning |
|---|---|---|
| Role contract | TEAM-ROLE-DESIGNER | Reusable eligibility and behavior contract |
| Role identifier | 1 | Positive integer within one role contract |
| Role instance | TEAM-ROLE-DESIGNER-1 | Role contract plus identifier; one eligibility/capacity unit within the semantic role queue |
| Incarnation | phase0-r1-designer-1-a7f... | Currently a caller-declared client identifier; provider readback may later prove a process lifetime |
| Binding | rb-<32 lowercase hex> | One time-bounded authorization of an incarnation to a role instance |
| Run | phase0-workflow-blueprint-v0-r1 | One workflow execution identity |
| Work item | <run>:<stage>:<lane>:g<n> | One reducer-created unit of work |
| Claim | Work item plus binding, incarnation, fence and lease | Current fenced custody |
| Outcome receipt | rr-<32 lowercase hex> | Immutable typed result for one exact work subject |
| Allocation operation | op-... | Durable supervisor request to provision, bind, drain or retire an incarnation |
Do not assert or derive persona_id == member_id == agent_id. Those terms are absent from this
contract. Replacement may change incarnation and binding while preserving the role instance.
5. Component architecture
+----------------------------+
| Role Fabric Console |
| browser, read + local ops |
+-------------+--------------+
|
| HTTP/BFF
v
+----------------------+ +-----------+---------------------------+
| Role Fabric Control | | Symposium Role Fabric gateway |
| MCP +-->| composite lifecycle operations |
| operator/meta-agent | | and read projections |
+----------------------+ +------+---------------+----------------+
| |
| +--> Process provider
| local tmux in P0
v
+----------+-----------+
| RoleExecutionKernel |
| work/custody truth |
+---+--------------+---+
| |
observed state | | outbox projection
v v
+-----+----+ +-----+----------------+
| Temporal | | Durable message |
| adapter | | ledger/channel |
+----------+ +-----------------------+
Per agent process:
Codex / Claude / other MCP client
|
| private fixed context, no selectors
v
+------+-------------+
| Role Workflow MCP |
| worker tools only |
+------+-------------+
|
v
v2 role-agent API5.1 Phase 0 classification
- The role kernel is a subsystem of Symposium.
tools/team_role_mcp.pyis a local stdio adapter, not a standalone network service.- The proposed
services/mcp-temporaltree is a contract scaffold, not a service while handlers,
entrypoint, runtime MCP surface, health and packaging tests are absent.
- Do not extract a separate microservice until the composite gateway interface is implemented and
stable. A later extraction should use services/mcp-role-fabric, not mcp-temporal.
6. Authority-plane separation
6.1 Role Fabric Control MCP
This server is launched only for an operator or explicitly authorized meta-agent. It is absent from
ordinary worker sessions. In Phase 0, stdio control inherits the launching supervisor process
boundary. HTTP control requires the separate local operator contract in section 10.4; binding to
loopback is not authorization and the service is never a public unauthenticated network service.
| Tool | Purpose | Phase 0 state |
|---|---|---|
fabric.status | Service, dependency and truth-source posture | Partial: static health and kernel diagnostics only |
fabric.run.list | Bounded run summaries and cursored filtering | Backend gap |
fabric.run.describe | Exact run, generation, queues, evidence denominator | Partial kernel run/work detail only |
fabric.plan.create | Validate and record an immutable fixed-leaf plan | Backend gap |
fabric.run.create | Create a planned run from an exact plan digest | Backend gap |
fabric.run.execute | Admit the kernel run and start/reconcile its observer | Direct kernel start exists; composite gap |
fabric.run.cancel | Cancel observation or request a separately defined kernel run action | Backend gap |
fabric.run.reprioritize | Expected-version priority change | Existing low-level supply |
fabric.role.list | Role instances, bindings and participation state | Partial: binding rows only |
fabric.role.allocate | Provision incarnation and issue binding as one durable operation | Composite/provider gap |
fabric.role.replace | Preserve one role instance while replacing its incarnation/binding | Phase 1; current primitive may change role/identifier and has no process/channel replacement |
fabric.role.drain | Deny new claims while resolving current custody | Composite/kernel-access gap |
fabric.role.retire | Revoke/stop/retire after exact custody and process checks | Composite/provider gap |
fabric.work.requeue | Requeue verified orphan after custody review | Partial: expected-version/actor primitive lacks review evidence |
fabric.operation.get | Inspect asynchronous lifecycle operation | Backend gap |
Control tools must never appear in worker tools/list.
Current start_run replay is not the target exact-plan contract. Its stored spec_sha256 binds role
topology but not every title, objective, priority or admitting-actor field; reusing a run ID with a
changed request can return the existing run. Target plan/run idempotency binds the full canonical
request digest.
6.2 Role Workflow MCP
The compatibility anchor remains the five current tools. Every process is fixed at startup to one
run, role instance, incarnation, binding and queue URL. No public input accepts any of those values
as a selector.
This run boundary is currently adapter/supervisor confinement, not kernel authorization. The
underlying binding authorizes its role instance across runs and the agent queue can return eligible
work across runs. team_role_mcp.py filters locally and rejects work outside its configured run. A
future security-grade run audience requires a binding-schema and kernel claim-check successor.
| Tool | Closed input | Meaning |
|---|---|---|
workflow.context | {} | Fixed context, instructions and queue posture |
workflow.next | {} | Highest-priority eligible item or honest idle/block state; no claim |
workflow.claim | work_id, expected_version, optional lease_seconds | One-winner CAS claim |
workflow.heartbeat | work_id, fence, expected_version, optional lease_seconds | Extend exact current custody |
workflow.submit | work_id, fence, expected_version, typed result, bounded body, idempotency_key | Commit outcome; reducer selects successor |
Do not add:
workflow.act: it hides distinct CAS/fence/result contracts;task.complete: workers submit outcomes; reducers and certification decide completion;workflow.leave: no voluntary release/handover contract exists yet; or- role, run, queue, credential, binding or incarnation selectors.
6.3 Communication tools
Communication remains a separately composable adapter. Prefer the existing message.* capability
family or a successor durable-channel MCP. Do not duplicate it inside the core Role Fabric tool
catalog.
Minimum later composition:
- receive bounded addressed messages by cursor;
- acknowledge
RECEIVEDseparately fromCOMPLETEDorREJECTED; - send bounded causal messages to recipients from the fixed run roster; and
- bind immutable evidence references rather than copying large artifacts into messages.
SENT, DELIVERED, RECEIVED, COMPLETED and REJECTED are transport/response states. None means
work claimed, review passed, authority granted or effect executed.
7. Agent participation lifecycle
Onboarding, allocation, access, presence, custody and process liveness are not synonyms. One durable
allocation projection carries independent axes instead of collapsing them into one state machine.
| Axis | States | Truth owner |
|---|---|---|
| Allocation operation | PLANNED, PROVISIONING, ACTIVE, DRAINING, RETIRED, FAILED, BLOCKED | Role Fabric supervisor store |
| Process | NOT_STARTED, LIVE, STOPPED, UNKNOWN | Process provider readback |
| Access | NOT_ISSUED, ACTIVE, REVOKED, REPLACED, EXPIRED | Binding registry plus observed time |
| Participation | NOT_JOINED, COMPATIBILITY_NOT_PROVEN, JOINED, READY, STALE | Join/presence receipts |
| Custody | NONE, CLAIMED, ORPHANED_UNVERIFIED, HANDED_OVER | Role kernel |
IN_PROGRESS is reserved for a future explicit kernel transition. The current kernel moves fromclaimed directly to a terminal outcome and must not project an invented in-progress state.
Access projection uses this precedence at a declared observed_at: persisted replaced, then
persisted revoked, then derived expired when expires_at <= observed_at, then active. A row may
remain persisted as active after expiry; projection must not represent that as usable access.
Current Phase 0 compatibility mode pre-generates a binding/context before client launch. It may
project access=ACTIVE, provider-derived process state andparticipation=COMPATIBILITY_NOT_PROVEN; it must not claim JOINED or READY. Current incarnation
values are declared identifiers until provider readback binds them to one concrete process.
Phase 1 may add OFFERED and ACCEPTED willingness receipts before binding. They grant no role,
work or effect authority and are deliberately absent from Phase 0.
7.1 Drain, retire and replacement
Drain may begin while custody is active. It atomically prevents new claims while preserving the
current owner's heartbeat and outcome rights for already claimed work. This requires a kernel-
enforced access property such as accepts_new_claims=false; a gateway-only flag is insufficient and
the current all-or-nothing active-binding authentication cannot implement it.
Retire refuses CLAIMED or ORPHANED_UNVERIFIED custody. A role instance is VACANT only when
access is inactive, custody is NONE or HANDED_OVER, and the provider proves the incarnation
stopped. No process evidence means DRAINING or UNKNOWN, never VACANT.
Temporal cancel_activity is not process-stop evidence. The Phase 0 local provider may stop a tmux
session and prove it no longer exists. Forced process loss with active custody preservesORPHANED_UNVERIFIED; it never silently requeues or marks work complete.
Current low-level binding replacement can change role and identifier. Targetfabric.role.replace instead preserves the role instance and changes only incarnation/binding.
Role-instance reassignment is a separate explicit operation. Phase 0 replacement returns conflict
while the durable channel roster is binding-specific; it becomes available only with an atomic
channel-root successor.
8. Work and run lifecycle
Work truth remains:
READY -> CLAIMED -> COMPLETED | FAILED
|
| lease loss
v
ORPHANED_UNVERIFIED
|
| explicit custody review + expected version
v
READYThe current reducer remains one fixed leaf:
design
-> build
-> validation
-> configured parallel reviews
-> optional remediation generation(s)
-> fresh validation and reviews
-> independent certificationIt is not an arbitrary workflow compiler and not the complete V12 B0-B15 programme DAG. The first
generic extension is a closed Workflow Blueprint validator; execution of arbitrary blueprints is a
later successor.
9. Temporal boundary
Phase 0 agents do not talk to Temporal directly.
Temporal may:
- start one admitted observer workflow;
- wait and retry bounded administrative reads;
- record bounded current-generation observations;
- enforce timers and report timeout/cancellation; and
- return a bounded completion observation.
Temporal may not:
- issue roles or bindings;
- mint agent credentials;
- select an agent's identity or queue;
- fabricate a role outcome;
- infer message receipt or work acceptance;
- mutate a completed kernel receipt; or
- grant any external effect.
Decision for Phase 0: POST /tal/v1/tokens is REFUSED/NOT_IMPLEMENTED. A shared replayable
internal key is not an acceptable agent credential. The supervisor privately generates one fixed
context per role MCP process. Remote/public access requires a later authenticated exchange and is
outside this revision.
9.1 Durable control operations
The Role Fabric supervisor store owns plan_id, operation_id, request digest, provider
reference, attempts, compensation and reconciliation evidence. In Phase 0 these are separate tables
in the same SQLite file as the kernel, but they do not share the current kernel connection or
transaction. The supervisor is their sole writer. Temporal, the browser and MCP adapters are
clients, not alternate operation stores.
Plans are immutable records, so plan creation is a control-plane write with zero execution or
external effect. The exact order is:
1. validate and record PlanV1 under a deterministic plan digest;
2. create a PLANNED run resource with a deterministic run ID and no kernel work;
3. attach/provision the plan's minimum role allocations and record provider readback;
4. execute the planned run as a durable saga: commit KERNEL_ADMISSION_REQUESTED, invoke exact-
digest idempotent kernel admission through the existing boundary, then reconcile readback;
5. advance through KERNEL_ADMITTED, OBSERVER_START_REQUESTED, OBSERVER_CONFIRMED, or
OBSERVER_UNAVAILABLE; and
6. reconcile lost responses by the same operation/idempotency digest without creating a second run,
process, binding or Temporal workflow.
OBSERVER_UNAVAILABLE does not undo or complete admitted kernel work. An operator may retry the
same deterministic observer start or request a separately recorded kernel action.
Cancellation is explicit and scoped. observer-only requests cancellation of the Temporal
observer and leaves kernel work unchanged. run-drain disables new claims and waits for custody
resolution; it does not silently fail, complete, abandon or requeue work. A later destructive run
termination requires its own authority/effect contract and is outside Phase 0.
10. HTTP interface for the console
The browser uses HTTP/BFF, not stdio MCP.
10.1 Existing read supply
| Method | Path | Use |
|---|---|---|
GET | /v2/team/health | Local capability and dependency posture |
GET | /workflow?run_id=... | Current read-only HTML console |
GET | /v2/team/console/{run_id} | Selected-run projection |
GET | /v2/team/admin/runs/{run_id} | Exact administrative run detail |
GET | /v2/team/admin/bindings | Binding registry projection |
GET | /v2/team/admin/diagnostics | Queue age, ready/claimed and outbox posture |
Phase 0B adds read-only GET /v2/team/console/runs andGET /v2/team/console/runs/{run_id} routes under the existing explicit lab-console gate. They return
the same immutable RunSummaryPageV1 and RunCompositeV1 contracts as the internal control reads,
require same-origin browser access, set Cache-Control: no-store, expose no mutation capability and
never require or disclose X-Internal-Key. The /control/* routes remain internal-key/operator-only.
10.2 Target composite control API
The composite gateway, not the browser, coordinates binding, context files, process provider and
Temporal start.
| Method | Target path | Meaning |
|---|---|---|
GET | /v2/team/control/status | Composite capability/dependency posture with freshness |
POST | /v2/team/control/plans | Validate and record immutable fixed-leaf plan/digest; zero execution effect |
GET | /v2/team/control/plans/{plan_id} | Exact immutable plan |
POST | /v2/team/control/runs | Create a PLANNED run from an exact plan; replay-safe |
GET | /v2/team/control/runs | Bounded/cursored run list |
GET | /v2/team/control/runs/{run_id} | Composite run projection |
POST | /v2/team/control/runs/{run_id}/execute | Admit exact kernel run and start/reconcile observer |
POST | /v2/team/control/runs/{run_id}/cancel | Explicit observer-only or run-drain request |
POST | /v2/team/control/runs/{run_id}/priority | Expected-version reprioritization |
GET | /v2/team/control/roles | Role-instance and binding/participation projection |
POST | /v2/team/control/runs/{run_id}/allocations | Allocate one role instance/incarnation |
GET | /v2/team/control/allocations/{allocation_id} | Allocation state and evidence |
POST | /v2/team/control/allocations/{allocation_id}/drain | Begin safe drain |
POST | /v2/team/control/allocations/{allocation_id}/retire | Retire after exact checks |
GET | /v2/team/control/operations/{operation_id} | Durable async operation status |
POST | /v2/team/control/orphans/{work_id}/requeue | Explicit reviewed recovery |
GET | /v2/team/control/runs/{run_id}/events | Run-scoped reducer/observer/message cursor set |
GET | /v2/team/control/runs/{run_id}/tasks/{work_id} | Sanitized bounded task, receipt and findings detail |
GET | /v2/team/control/runs/{run_id}/evidence/{evidence_ref} | Run-bound approved opaque/content-addressed evidence metadata |
Lifecycle mutations return 202 and a durable operation resource when process/provider work is
asynchronous. Lost responses replay to the same operation, incarnation and binding.
The run-event response carries independent reducer, Temporal and communication cursors plus a source
label per event; one global cursor must not imply atomic ordering across those truth sources. Task
and evidence responses omit credentials, internal context paths, internal keys, raw receipt bodies
not admitted for display, and unnecessary binding provenance.
Every task, cursor and evidence reference is authorized and validated against the path run_id;
cross-run references fail closed even when the opaque reference exists.
RunCompositeV1 freezes separate supervisor_state and kernel_admission_state fields plus a
truth-source marker in Phase 0B. It represents supervisor-only planned runs with no kernel row,
admitted runs with both records, and legacy kernel runs with supervisor_state=UNKNOWN; Phase 0C
must not require a breaking projection change.
10.3 Control MCP to HTTP mapping
Every control tool has one declared HTTP operation and schema pair. The event/task/evidence reads are
frontend/BFF operations and are intentionally not MCP tools in Phase 0.
Paths in the following table are relative to /v2/team.
| Control MCP tool | HTTP operation | Request/output contracts |
|---|---|---|
fabric.status | GET /control/status | EmptyV1 / FabricStatusV1 |
fabric.run.list | GET /control/runs | RunListQueryV1 / RunSummaryPageV1 |
fabric.run.describe | GET /control/runs/{run_id} | RunRefV1 / RunCompositeV1 |
fabric.plan.create | POST /control/plans | PlanDraftV1 / PlanV1 |
fabric.run.create | POST /control/runs | RunCreateV1 / RunCompositeV1 |
fabric.run.execute | POST /control/runs/{run_id}/execute | RunExecuteV1 / OperationV1 |
fabric.run.cancel | POST /control/runs/{run_id}/cancel | RunCancelV1 / OperationV1 |
fabric.run.reprioritize | POST /control/runs/{run_id}/priority | RunPriorityV1 / RunCompositeV1 |
fabric.role.list | GET /control/roles | RoleListQueryV1 / RoleInstancePageV1 |
fabric.role.allocate | POST /control/runs/{run_id}/allocations | AllocationCreateV1 / OperationV1 |
fabric.role.drain | POST /control/allocations/{allocation_id}/drain | DrainRequestV1 / OperationV1 |
fabric.role.retire | POST /control/allocations/{allocation_id}/retire | RetireRequestV1 / OperationV1 |
fabric.work.requeue | POST /control/orphans/{work_id}/requeue | OrphanRecoveryV1 / OperationV1 |
fabric.operation.get | GET /control/operations/{operation_id} | OperationRefV1 / OperationV1 |
The current global lease-expiry sweep remains an internal maintenance primitive and is not exported
as a control MCP tool. fabric.role.replace remains unavailable in Phase 0 for the channel reason in
section 7.1.
10.4 Phase 0 local operator boundary
The existing read-only console flag enables only read projection routes. It must never enable
control routes. Until the following BFF boundary exists, browser mutation controls remain absent:
- the launcher creates an expiring, narrowly scoped local supervisor session and records its actor;
- the browser receives only an
HttpOnly,Securewhere TLS applies,SameSite=Strictsession
cookie, never X-Internal-Key or a worker binding credential;
- every mutation requires exact same-origin
Origin/Host, a CSRF token bound to that session,
route capability, expiry and actor/audit attribution;
- CORS is closed for control routes and capability discovery fails closed; and
- worker credentials, anonymous read-console access and the shared internal service key are rejected
as browser operator credentials.
This is a local supervisor session, not a public identity system. Stdio control MCP may instead use
the launching process boundary and does not expose a browser token.
11. Role Fabric Console
11.1 Required pages/panels
1. Overview: health, configured environment, runs by state, blocked queues and stale processes.
2. Run view: objective, generation, state, effect ceiling, exact workflow topology and evidence
completeness.
3. Role instances: every required and additional numbered role instance, incarnation, binding,
join, presence and work state.
4. Industrial queues: one lane per semantic role queue, ready/claimed counts, priority, age and
all selected-run tasks.
5. Task drawer: work ID, subject, required role/instance, claim/fence/lease, outcome receipt,
findings and immutable evidence references.
6. Timeline: reducer events, Temporal observations and message events with their truth source
clearly labelled.
7. Operations: plan/create/execute/cancel, allocate/drain/retire, reprioritize and reviewed orphan
recovery. Replacement is visibly unavailable in Phase 0. All controls are local-supervisor only.
8. Evidence: source/tree/package identities, tests, review/certification denominator, manual
operations and explicit noncoverage.
11.2 Presence rendering
Do not collapse presence to one badge. At minimum show:
binding: ACTIVE | INACTIVE | UNKNOWN
process: LIVE | STALE | STOPPED | UNKNOWN
join: JOINED | COMPATIBILITY_NOT_PROVEN | NOT_JOINED | UNKNOWN
work: IDLE | READY_AVAILABLE | CLAIMED | ORPHANED_UNVERIFIEDThe exact numbered claimant controls WORKING. A generic role task claimed by DESIGNER-2 must not
mark DESIGNER-1 as working. Until the concurrent correction is committed and independently
reviewed, this remains a frontend/backend join blocker.
11.3 Frontend safety
- Render dynamic values with text-safe DOM operations.
- Bound every list, body and error projection; use pagination/cursors for history.
- Never expose credentials, internal context paths, internal keys or raw exception detail.
- Require explicit confirmation for mutations and display expected version/digest.
- Require the section 10.4 local operator session and CSRF/capability check for every mutation.
- Refetch after conflicts; never retry a mutation under a new guessed version.
- Distinguish dependency unavailable from empty data.
- Disable mutation controls when the control-plane capability is absent; do not simulate success.
12. Contract rules
Contracts are per resource and per protocol revision; a generic identifier or envelope must not
silently redefine current behavior.
The existing worker MCP stays on protocol 2024-11-05. Its five tools publish closedinputSchema; text content is the normative response and current structuredContent is a
currently unnegotiated extension outside that revision's normative result shape. They do not
currently publish outputSchema. Phase 0A must choose one of two explicit paths:
1. retain 2024-11-05, freeze/test the current text response contract and prove installed Codex and
Claude clients tolerate or ignore the extension; or
2. negotiate 2025-06-18, add five exact output schemas, validate outputs server-side and prove
installed Codex and Claude compatibility before changing the compatibility anchor.
Protocol references: MCP tools 2024-11-05
and MCP tools 2025-06-18.
New control MCP tools and HTTP routes have checked, closed request/output schemas. The mandatory
inventory is exactly: EmptyV1, FabricStatusV1, PlanDraftV1, PlanV1, RunCreateV1,RunExecuteV1, RunCancelV1, RunListQueryV1, RunSummaryPageV1, RunRefV1, RunCompositeV1,RunPriorityV1, RoleListQueryV1, RoleInstanceProjectionV1, RoleInstancePageV1,AllocationCreateV1, AllocationV1, DrainRequestV1, RetireRequestV1, OrphanRecoveryV1,OperationRefV1, OperationV1, RunEventCursorSetV1, TaskDetailV1, EvidenceRefV1,EvidenceMetadataV1, ControlResponseV1, ControlErrorV1 and CoverageManifestV1.
Current exact identifier rules remain resource-specific:
- kernel bounded identifiers use
[A-Za-z0-9][A-Za-z0-9._:/-]{0,254}(maximum 255); - worker MCP currently advertises
work_id.maxLength=256and relies on downstream rejection; - the session launcher run ID uses
^[A-Za-z0-9][A-Za-z0-9._-]{2,127}$; and - every successor schema must name its exact pattern/minimum/maximum instead of inheriting a common
regex.
Validation supply is boundary-specific:
| Boundary | Strict integers | Duplicate/non-finite JSON | Object closure and identifiers |
|---|---|---|---|
| Worker MCP stdio | Implemented for tool integer arguments, including boolean rejection and bounds | Gap: plain json.loads | Tool arguments closed except outcome body; work ID length/prefix checked before kernel |
| Session-launcher ready file | Closed typed checks | Implemented with duplicate-key and non-finite rejection | Exact 0600 secure read; exact run-ID regex above |
| Existing v2 HTTP API | Mixed: lease fields strict; other Pydantic integers may coerce | Gap before model decoding | Route models vary; existing response shapes are not new control envelopes |
| Role kernel | Stage/result-specific semantic bounds | Receives decoded objects and canonicalizes admitted bodies | Kernel identifier regex above; required stage fields and closed finding records, but top-level body extras generally accepted |
| Target control HTTP/MCP | Required for every integer | Required before ordinary model decoding | Every request/output closed under its named per-resource schema |
workflow.submit.body remains intentionally open in the MCP input schema and is currently validated
as a bounded canonical object with stage-specific required fields and closed finding records. Fully
closed stage-specific unions are a separately tested hardening gap.
Cross-resource target rules:
- SHA-256 is exactly 64 lowercase hexadecimal characters;
- canonical receipt IDs are
rr-plus 32 lowercase hexadecimal characters; - admitted inline outcome/message bodies are canonical UTF-8 JSON and at most 32 KiB;
- large evidence uses an approved opaque/content-addressed reference plus digest, never an internal
filesystem path;
- idempotency key reuse with a different canonical request digest is
409 CONFLICT; - unavailable dependencies return explicit retryable
503, not empty success; and - secrets are absent from structured output, logs, UI and evidence artifacts.
The following envelopes apply only to the new control HTTP/MCP interface. They do not change the
five worker tools or existing v2 admin routes.
Internal /control/ success responses use ControlResponseV1, with resource constrained by the
route's named output schema. Read-only /console/ BFF routes return that resource schema directly;
fixtures contain both forms and the frontend field map consumes only the direct console resource.
Control success envelope:
{
"schema_version": "conduir.role-fabric-response/v1",
"status": "...",
"request_id": "...",
"replayed": false,
"external_effect_authority": "NONE",
"control_effect": "ROLE_BINDING_ISSUED",
"resource": {}
}Control error envelope:
{
"schema_version": "conduir.role-fabric-error/v1",
"code": "VERSION_CONFLICT",
"message": "bounded safe description",
"retryable": false,
"current_version": 3,
"conflict_ref": "optional immutable reference",
"external_effect_authority": "NONE",
"control_effect": "NONE"
}control_effect is a closed operation-specific enum such as PLAN_RECORDED, RUN_ADMITTED,RUN_REPRIORITIZED, ROLE_BINDING_ISSUED, ROLE_ACCESS_DRAINING, ROLE_ACCESS_REVOKED orORPHAN_REQUEUED. It records internal control/work mutation without implying deployment or other
external effect authority.
13. Reconciliation of the proposed 15 tools
| Proposed tool | Shared disposition |
|---|---|
| onboard | Replace with supervisor plan/provision/join state; not one synchronous worker tool |
| allocate | fabric.role.allocate; supervisor-only, durable operation |
| renew | Do not publish until an exact binding/session renewal contract exists |
| deallocate | Split into fabric.role.drain and fabric.role.retire; one generic state-hiding tool is rejected |
| roster | fabric.role.list; read-only control plane |
| env.list | Target gap until an environment registry exists |
| env.describe | Phase 0 fixed-environment status only; no fleet claim |
| workflow.list | fabric.run.list; backend run-list projection required |
| join | Internal participation lifecycle step; never self-selects role/run |
| observe | Compose workflow.context, run snapshot and console APIs |
| act | Delete; use explicit claim/heartbeat/submit |
| leave | Delete until voluntary handover/release is designed |
| task.complete | Delete; reducer/certification owns completion |
| agent.emit | Move to optional communication adapter |
| agent.inbox | Move to optional communication adapter |
Metadata-only blocks with no handler.py remain correctly absent from tools/list, but they are not
implemented functionality and must not be counted as available MCP tools.
14. Packaging and extraction
Phase 0 keeps the kernel/API in Symposium and the worker MCP as a local adapter. The shared contract
may be implemented without first creating a new deployable service.
When extraction becomes justified, use:
services/mcp-role-fabric/
pyproject.toml
README.md
Dockerfile
Dockerfile.dockerignore
docker-compose.fragment.yml
healthcheck.sh
cert.manifest.yaml
mcp.profile.control.yaml
openapi.v1.yaml
contracts/
control-tools.v1.json
worker-tools.v1.json
empty.v1.schema.json
fabric-status.v1.schema.json
plan-draft.v1.schema.json
plan.v1.schema.json
run-create.v1.schema.json
run-execute.v1.schema.json
run-cancel.v1.schema.json
run-list-query.v1.schema.json
run-summary-page.v1.schema.json
run-ref.v1.schema.json
run-composite.v1.schema.json
run-priority.v1.schema.json
role-list-query.v1.schema.json
role-instance-projection.v1.schema.json
role-instance-page.v1.schema.json
allocation-create.v1.schema.json
allocation.v1.schema.json
drain-request.v1.schema.json
retire-request.v1.schema.json
orphan-recovery.v1.schema.json
operation-ref.v1.schema.json
operation.v1.schema.json
run-event-cursor-set.v1.schema.json
task-detail.v1.schema.json
evidence-ref.v1.schema.json
evidence-metadata.v1.schema.json
control-response.v1.schema.json
control-error.v1.schema.json
coverage-manifest.v1.schema.json
src/mcp_role_fabric/
control_app.py
worker_stdio.py
schemas.py
posture.py
clients/team_api.py
clients/channel.py
providers/base.py
providers/local_tmux.py
handlers/control.py
handlers/worker.py
tests/
test_contracts.py
test_tool_separation.py
test_lifecycle.py
test_packaging.py
test_phase0_e2e.pyQuality Fabric is a packaging reference, not a code-copy authority. A real extracted service needs
an entrypoint, MCP initialize/list/call behavior, health/live/ready, build identity, packaged
contracts, installed-wheel tests, non-root image, service-local configuration and explicit caller
inventory. Port 48086 remains unassigned until the service registry and compose topology adopt it.
15. Acceptance gates
15.1 Shared contract
RF-A01: one exact tool catalog exists per authority plane with zero overlapping mutation ownership.RF-A02: operator tools are absent from workertools/list.RF-A03: existing five worker tools retain closed selectors and behavior.RF-A04: frontend field mappings are checked against the same schemas as backend responses.RF-A05: exact source, schema, tool-catalog and frontend compatibility digests are recorded.
15.2 Identity and lifecycle
RF-A06: role instance, incarnation and binding are never substituted for one another.RF-A07: allocation lost-response replay creates exactly one process, incarnation and binding.RF-A08: binding alone never renders processLIVEor participationREADY.RF-A09: drain atomically denies new claims while preserving current-custody heartbeat/outcome rights.RF-A10: retire refusesCLAIMEDorORPHANED_UNVERIFIEDcustody.RF-A11: revoked/replaced/expired bindings and stale fences cannot mutate work.RF-A12: process unknown remains visible and does not free capacity.
15.3 Work and evidence
RF-A13: priority, one-winner claim, version conflict, fence and lease behavior remain green.RF-A14: missing/duplicate/corrupt receipt and claim lineage fail closed.RF-A15: deliberate review failure creates a digest-bound remediation successor.RF-A16: fresh validation/reviews and independent certification bind the final exact subject.RF-A17: completion does not grant external effect authority; internal control effects remain explicit.
15.4 Temporal and communication
RF-A18: Temporal replay creates no duplicate run, allocation, binding, work or result.RF-A19: Temporal history remains bounded and contains no credential or large chat body.RF-A20: observer-only cancellation leaves kernel run/work/custody unchanged.RF-A21: run-drain prevents new claims, preserves current-custody heartbeat/outcome and never
silently completes, fails or requeues work.
RF-A22: repeated cancellation with the same digest is replay-safe; a changed mode/digest conflicts.RF-A23: observer start loss orOBSERVER_UNAVAILABLEcannot project kernel completion; exact-
digest retry reconciles the same observer identity and operation.
RF-A24: send, delivery, receive, response and work acceptance are tested as distinct states.RF-A25: channel failure/corruption cannot mutate work truth.
15.5 Frontend
RF-A26: all role instances and queues appear for the selected run.RF-A27: numbered claimant attribution is exact.RF-A28: empty, unavailable, unknown and unauthorized render distinctly.RF-A29: dynamic output is DOM-safe and bounded.RF-A30: task, event-cursor and evidence references are exact-run-bound; cross-run access fails closed.RF-A31: mutation controls use exact versions/digests and expose conflicts.RF-A32: anonymous read-console and worker credentials cannot invoke control routes; origin, CSRF,
expiry, capability and actor attribution gates all pass.
RF-A33: no credential, internal path or raw secret marker reaches HTML, JSON or logs.
15.6 Service/productization
RF-A34: protocol-level initialize, tools/list and tools/call tests pass if extraction occurs.RF-A35: health/live/ready, version/build and contract discovery are implemented.RF-A36: service-local boot and useful-operation tests pass.RF-A37: Quality Fabric runs the contract/regression package, or an explicit local fallback is recorded.RF-A38: one digest-boundCoverageManifestV1contains exactly one result for everyRF-A01
through RF-A37, with no missing, duplicate or extra IDs; classifies each as applicable or
non-applicable for the exact phase/packet; gives a reason for every non-applicable gate; and binds
complete passing evidence/results for 100 percent of applicable gates. Its own coverage-report
receipt is the result of this check, not a premise in its denominator. Code/branch coverage is a separate
risk-based metric with an exact file/statement/branch denominator; no percentage substitutes for
a missing lifecycle, authority or security gate.
16. Shared work split
Backend/Role Fabric lane
Owns:
- immutable correction for exact numbered claimant attribution;
- run-list and composite snapshot API;
- plan/create/execute/cancel composite lifecycle and operation reconciliation;
- allocation operation registry and local provider readback;
- drain/retire semantics;
- worker MCP compatibility and control-plane MCP handlers; and
- kernel/Temporal/idempotency/evidence tests.
Must not independently redesign frontend states or duplicate message storage.
Frontend/interface lane
Owns:
- console information architecture and wireframes;
- checked frontend view models generated/mapped from shared schemas;
- overview, run, role-instance, queue, task, timeline, operation and evidence panels;
- safe mutation journeys against the composite control API;
- loading/empty/unavailable/conflict/unknown states; and
- browser contract and DOM-safety tests.
Must not call low-level binding/context/tmux steps directly or invent backend success states.
Communication adapter lane
Owns message send/receive/ack only if admitted separately. It must reuse or supersede the existing
message capability under an explicit migration and must not mutate kernel work state.
Integration join
The two primary lanes join only when:
1. the exact backend OpenAPI/schema/tool catalogs are immutable;
2. frontend mappings test every declared field and status;
3. one composed local run demonstrates plan, allocation, worker claim/outcome, review correction,
certification, drain and evidence projection;
4. independent review finds no cross-plane authority substitution; and
5. no artifact claims deployment or external effect.
17. Collaboration protocol
Both implementations use this document as the common intent and publish proposed changes as exact
deltas rather than silently editing incompatible local copies.
Every handoff includes:
- source commit/tree or content-addressed archive;
- changed paths and ownership lane;
- relevant schema/tool/API digests;
- tests and denominator;
- what the result proves and does not prove;
- unresolved conflicts and decisions; and
- next expected receiver/action.
The reported services/mcp-temporal package must first publish its exact bytes. Its next review is a
mapping review against sections 6, 10, 13 and 14, not a general approval of all 15 proposed tools.
The backend lane must publish the pending console correction as an immutable successor before the
frontend binds claimant-presence behavior. Neither mutable worktree is accepted as the shared base.
18. Phased delivery
Phase 0A: reconcile contracts
- Freeze this shared architecture successor.
- Publish the proposed interface package exact bytes.
- Freeze separate control/worker tool catalogs and common envelopes.
- Decide and test the worker MCP protocol path: retained
2024-11-05or negotiated
2025-06-18 output schemas.
- Freeze per-resource patterns, strict-decoding gaps and exact control MCP-to-HTTP mappings.
- Reconcile current backend API and frontend view model.
- No new runtime or effect.
Phase 0B: current local Role Fabric
- Commit/review numbered claimant correction.
- Add bounded run list and composite snapshot.
- Build frontend read-only views against current HTTP projection.
- Preserve current five worker tools.
- Demonstrate fixed six-role local run with
effect=NONE.
Phase 0C: local supervisor operations
- Add immutable plan recording, planned-run creation and exact execute/reconcile operations.
- Add durable allocation operations and provider readback.
- Add safe drain/retire.
- Add observer-only/run-drain cancellation, local operator BFF/session controls, control MCP and
frontend operation journeys.
Phase 1: dynamic single-host participation
- Join/presence receipts, restart/resume, mid-run allocation, channel roster successor and explicit
handover.
Phase 2: V12 composition
- Workflow Blueprint execution, generic dependency/join reducer, programme parent/children,
operator decision nodes and Quality Fabric evidence adapter.
Phase 3 and later
- PostgreSQL/multi-host fencing, authenticated principals/tenants, HA process provider and finally
separately granted external effects with canary/rollback/effectiveness receipts.
19. Decisions and open questions
Decided for this revision
1. Product name: Conduir Role Fabric.
2. Frontend name: Role Fabric Console.
3. Participation model: supervisor-bound external agent process.
4. No seats and no persona identity.
5. Worker and control MCP catalogs are separate.
6. Communication is a separate adapter.
7. No generic act, direct task.complete or leave tool.
8. No Phase 0 /tal/v1/tokens.
9. Browser uses HTTP/BFF.
10. Temporal is never work truth.
11. Phase 0 durable control-operation tables are supervisor-owned and co-located with the local
kernel database.
12. A planned run exists before allocations; kernel admission/observer start occurs only on explicit
execute.
13. Browser mutations require the local operator boundary in section 10.4.
14. Binding replacement is unavailable in Phase 0.
Open
1. Exact contract and owner for voluntary claim handover/release.
2. Whether the local process provider remains tmux or gains another provider under the same seam.
3. Environment registry model before env.list can exist.
4. Final remote/public authentication and delegated authorization model.
5. Retention/privacy policy for message and operational event history.
6. Port assignment and extraction trigger for a future mcp-role-fabric service.
7. Exact successor channel-root protocol for mid-run role replacement.
8. Retain MCP 2024-11-05 or migrate with negotiation to 2025-06-18 output schemas.
20. First shared implementation sequence
20.1 RF-BE-P0B-READ-01A — truthful read model and claimant attribution
Base: the accepted successor of this specification; implementation lineage based one5b83ec1b4027f22e4e99315ab1cd4c957f98460 plus an independently accepted claimant correction.
Backend scope:
- freeze the exact-numbered-claimant correction;
- add bounded/cursored run-list supply;
- add internal
GET /v2/team/control/runsand/runs/{run_id}reads; - add read-only
GET /v2/team/console/runsand/runs/{run_id}projections under the existing lab-
console gate, same-origin and no-store;
- publish closed
RunListQueryV1,RunSummaryPageV1,RunRefV1,RunCompositeV1,
RoleInstanceProjectionV1 and ControlErrorV1 schemas plus deterministic fixtures;
- freeze planned/admitted/legacy truth-source fields and opaque cursor contract;
- return process/join/allocation fields as
UNKNOWNorCOMPATIBILITY_NOT_PROVEN; and - preserve all five worker MCP tools unchanged.
Acceptance:
1. A generic role task claimed by DESIGNER-2 marks only DESIGNER-2 working.
2. Additional numbered instances render dynamically.
3. Expired access is derived at a declared observed_at with the section 7 precedence.
4. Stable cursor ordering, bounded limits, invalid-cursor rejection and
unavailable-versus-empty tests pass.
5. Static /v2/team/console/runs route registration precedes the legacy dynamic
/v2/team/console/{run_id} route; tests prove both list and exact-run dispatch.
6. Internal control fixtures wrap route-specific resources in ControlResponseV1; console fixtures
expose the identical direct resource, and the field map proves their equality.
7. The console reads need no browser-held internal key, expose no mutation and set no-store.
8. No credential, internal path, raw exception or fabricated process/presence fact reaches fixtures
or responses.
9. Existing kernel, role-bound, worker-MCP and console regressions remain green.
Immutable handoff: exact commit/tree, schema and fixture digests, commands/test denominator,
current/target field map, proof/noncoverage and expected frontend receiver.
20.2 RF-FE-P0B-READ-01B — read-only Role Fabric Console
This packet starts only after 01A's immutable handoff is accepted. It:
- consumes exactly the handed-off schemas and fixtures;
- renders overview, selected run, role-instance and queue panels;
- binds working state to the exact numbered claimant;
- uses only the read-only console routes, never the internal control key/routes; and
- implements loading, empty, unavailable and unknown states without mutation controls.
Frontend acceptance checks schema/fixture digest equality, dynamic numbered instances, exact
claimant attribution, same-origin/no-store reads, unavailable-versus-empty behavior, bounded DOM-safe
rendering and zero credential/internal-path exposure.
The 01A CoverageManifestV1 marks RF-A03, RF-A06, RF-A08, RF-A11 through RF-A14,RF-A27 and RF-A33 applicable. The 01B manifest marks RF-A04, RF-A05, RF-A26 throughRF-A29 and RF-A33 applicable. RF-A30 is deferred until the task/event/evidence reads and panels
are implemented. All other RF-A01 through RF-A37 gates are future-phase/non-applicable with
explicit reasons; they are not represented as passed. RF-A38 then validates the manifest and
produces its separate coverage-report receipt.
Out of scope for both packets: plan/create/execute mutations, provider launch,
allocation/drain/retire, control MCP, channel replacement, operator-session/public authentication,
deployment and external effect.
21. Current stop condition
This V0.4 shared candidate is ready for rebound exact review when committed. Backend packet 01A may
begin after this spec and the claimant correction are independently accepted; frontend packet 01B
waits for the immutable 01A handoff. Full control-MCP convergence begins only after:
- the other interface application's exact artifacts are supplied;
- the pending backend console correction is frozen;
- both are mapped to this document without unresolved authority-plane conflicts; and
- an independent reviewer accepts the exact successor subject.
Until then, the existing five-tool Role Workflow MCP and read-only console remain the only committed
MCP/frontend supply described here. No tool, service, port, environment, deployment or effect is
created by this document.