Skip to content

ADR-014: Typed Agent-Role Contract for Orchestration Surfaces

Status: Proposed Date: 2026-04-20 Authors: Tom Martin WU: WU-2751 Initiative: INIT-060

ADR-010 established initiative orchestration as an evidence-based control plane. It separated planning, handoff, execution, reconciliation, finish, and status, and it defined a richer orchestration-state model than earlier prompt-centric flows. ADR-013 then moved conductor-mode expansion to the pack layer, making pack-owned contracts the correct place for software-delivery semantics.

INIT-060 and INIT-061 now need more than WU and transport identity. They need to know which kind of agent owns which part of the work, what that agent is expected to do, what it is actually doing, and how that identity should travel across delegation, liveness, relaunch, and local coordination surfaces.

Today, actor identity is fragmented across incompatible surfaces:

  • OrchestrationLaunchReceipt captures WU, lane, wave, claimed mode, branch or worktree, and handoff artifact path, but not canonical role, capability, or ownership data.
  • DelegationEvent records intent, status, pickup state, and brief attestation, but not the requested responsibility model for the target worker.
  • Session records normalize agent_type, client_type, capabilities, agent_version, and host_id, but those are transport/runtime facts rather than a delivery-role contract.
  • mem:signal core can persist type, sender, target_agent, and origin, yet the CLI and launch hook still route most coordination through prose messages.
  • Human-facing agent names such as lumenflow-pm, test-engineer, lumenflow-enforcer, initiative-architect, and the legacy lumenflow-doc-sync mix lifecycle, specialty, and policy concerns. They are useful aliases, but weak canonical orchestration keys.

Without a typed role contract, local orchestrators, vendor adapters, and future cloud launchers must infer responsibility from prompts, display names, or free text. That is exactly the kind of under-specification ADR-010 rejected.

The software-delivery / agent-runtime pack will define a typed agent-role contract for orchestration surfaces. The kernel may transport role metadata, but it does not own the vocabulary. Canonical coordination identity is a pack-scoped descriptor with four parts:

  1. lifecycle role
  2. specialty profile
  3. capability set
  4. ownership scope

Human-friendly agent names remain supported as aliases, but aliases are not the source of truth.

The software-delivery pack owns the role taxonomy because the semantics are delivery-specific: orchestration, implementation, review, finish, and recovery all describe software-delivery work, not kernel-intrinsic behavior.

The kernel and shared SDKs may carry opaque role metadata fields, but they must not define or hardcode the software-delivery vocabulary. That preserves the ADR-013 direction: packs own their own contracts, and the kernel stays domain-agnostic.

The first contract version uses these canonical axes:

type AgentLifecycleRole = 'orchestrator' | 'implementer' | 'reviewer' | 'finisher' | 'recovery';

type AgentSpecialtyProfile = 'general' | 'delivery' | 'docs' | 'test' | 'triage' | 'compliance';

type AgentResponsibilityKind =
  | 'coordinate'
  | 'plan'
  | 'implement'
  | 'verify'
  | 'finish'
  | 'recover'
  | 'document';

interface AgentRoleDescriptor {
  lifecycle_role: AgentLifecycleRole;
  specialty_profile: AgentSpecialtyProfile;
  role_alias?: string;
  capabilities: string[];
}

interface OwnershipScope {
  initiative_id?: string;
  wu_ids?: string[];
  lane?: string;
  responsibility_kinds: AgentResponsibilityKind[];
}

Normative rules:

  • lifecycle_role answers “what phase of delivery does this agent own?”
  • specialty_profile answers “what specialized lens does it bring?”
  • capabilities answer “what can it do?” and are not a substitute for role.
  • ownership_scope answers “what initiative, WU, lane, and responsibility band is this actor coordinating?”
  • A derived role_id may be rendered as <lifecycle_role>/<specialty_profile>, but the split fields are authoritative.

The initial vocabulary is intentionally small. New values are additive pack changes, not ad hoc prompt conventions.

3. Names and Aliases Remain Compatible, but They Are Not Canonical

Section titled “3. Names and Aliases Remain Compatible, but They Are Not Canonical”

Existing vendor-facing agent names stay valid as compatibility labels and UI handles. The role contract maps them onto canonical descriptors instead of treating them as authoritative identity.

Initial alias guidance:

Existing aliasCanonical role descriptor
general-purposeimplementer/general
lumenflow-pmorchestrator/delivery
initiative-architectorchestrator/delivery
test-engineerimplementer/test
code-reviewerreviewer/general
bug-triagereviewer/triage
lumenflow-enforcerfinisher/compliance
lumenflow-doc-syncreviewer/docs (legacy)

This keeps human-readable names and vendor-specific agent inventories stable while giving orchestration surfaces one canonical identity model.

As of ADR-016 / INIT-063, lumenflow-doc-sync is no longer part of the recommended default framework roster. Documentation sync is handled by the CLI and normal docs WUs; keep the alias only for historical compatibility when reading older artifacts.

4. Durable Artifacts Carry Requested Role and Actual Role Separately

Section titled “4. Durable Artifacts Carry Requested Role and Actual Role Separately”

The contract distinguishes between the role an orchestrator requested and the role a live worker actually assumed. That distinction is load-bearing for relaunch, mismatch diagnostics, and auditability.

Required durable additions:

SurfaceRequired role dataWhy it matters
Delegation registry / wu:delegate lineagerequested_role, requested_ownership_scopeLaunch intent must be explicit before any worker starts.
Launch receipts / orchestration launch.json and status.jsonrequested_role, actual_role?, role_mismatch?, requested_ownership_scope, actual_ownership_scope?The control plane needs role-aware status and relaunch decisions.
Session records / agent:sessionactual_role, actual_ownership_scope, existing transport metadataLiveness and cloud enrollment need actor identity beyond agent_type.
Recovery and relaunch recordsrequested_role, last_actual_role, relaunch_reasonINIT-061 relaunch must know which role it is reconstituting.

requested_role and actual_role may differ. That is a state to surface, not to flatten away. A reviewer session picking up implementer work, or a recovery actor reusing a stale implementer alias, should show as a role mismatch that the orchestrator can inspect.

5. Memory Is a Coordination Overlay, Not the Source of Truth

Section titled “5. Memory Is a Coordination Overlay, Not the Source of Truth”

Shared memory remains supporting evidence only. ADR-010 explicitly treats signals, checkpoints, and shared memory as inputs to reconciliation rather than terminal execution truth, and ADR-009 keeps memory local by default. That means mem:* can accelerate coordination but cannot become the authoritative role ledger.

Memory still needs the same typed vocabulary for local coordination:

  • mem:signal should support structured role-aware fields such as sender_role, target_role, delegation_id, initiative_id, and artifact_path instead of relying on prose alone.
  • mem:context and mem:inbox should render open handoffs, active workers, and unresolved role mismatches grouped by role.
  • The legacy message field remains human-readable, but it is no longer the whole contract.

If memory and durable orchestration artifacts disagree, durable artifacts win.

6. Implementation Order Is Delegation -> Session -> Memory

Section titled “6. Implementation Order Is Delegation -> Session -> Memory”

Follow-on WUs must wire the contract in this order:

  1. Delegation and launch surfaces first. Orchestration intent originates here, so the contract must be stamped onto wu:delegate, delegation records, and launch receipts before downstream surfaces can consume it.
  2. Session surfaces second. Once a worker is live, agent:session, auto-session records, and liveness or relaunch hooks must report the actual role that is running, plus its ownership scope and capability set.
  3. Memory surfaces third. mem:signal, mem:context, and related local coordination views should reuse the same descriptors as a fast path for local operators, not invent a parallel state model.

This order aligns with INIT-060 and INIT-061. INIT-060 needs the pack-owned contract on orchestration surfaces; INIT-061 then benefits from consistent role identity for liveness guidance and relaunch from stored handoff artifacts.

7. Transport Metadata Stays, but It No Longer Pretends To Be Role Data

Section titled “7. Transport Metadata Stays, but It No Longer Pretends To Be Role Data”

Fields such as agent_type, client_type, agent_version, host_id, and raw capabilities remain valuable. They describe transport, host, and runtime facts. They do not answer “what role is this worker fulfilling in the delivery workflow?”

The new contract therefore layers on top of transport metadata instead of replacing it:

  • transport metadata explains how the worker is running,
  • role metadata explains why it is participating,
  • ownership scope explains what it is responsible for.

That separation prevents future surfaces from overloading client names or host identifiers into orchestration decisions.

  • Humans, local agents, vendor adapters, and future cloud launchers get one role vocabulary for routing, monitoring, relaunch, and audit.
  • Existing agent names stay usable as aliases, so migration does not require an immediate rename of every inventory or prompt surface.
  • mem:* coordination can become structured and machine-usable without being promoted to authoritative orchestration truth.
  • INIT-061 relaunch and liveness work can describe which role is being recovered, not just which WU or handoff artifact is involved.
  • Several schemas and projections need additive changes before the contract is visible end to end.
  • The initial role vocabulary may feel coarse for some teams or future packs.
  • For a transition period, docs and inventories may show alias names while durable artifacts expose canonical role descriptors.
  • Keep the first vocabulary deliberately small and additive.
  • Preserve role_alias for backward compatibility and human-friendly displays.
  • Treat requested_role vs actual_role mismatches as visible diagnostics before any future enforcement turns them into blocking errors.
  • Keep the vocabulary pack-local so other packs can define their own role descriptors without waiting on kernel changes.

A. Keep Existing Agent Names as the Canonical Role Model

Section titled “A. Keep Existing Agent Names as the Canonical Role Model”

Rejected. Current names mix lifecycle, specialty, and policy concerns, and they vary by vendor surface. They are useful labels, not stable orchestration keys.

B. Use Capabilities Only, Without Typed Roles

Section titled “B. Use Capabilities Only, Without Typed Roles”

Rejected. Capability lists answer “what could this worker do?” but not “what is it expected to own right now?” Orchestration, relaunch, and review routing need both.

C. Make Shared Memory the Authoritative Coordination Ledger

Section titled “C. Make Shared Memory the Authoritative Coordination Ledger”

Rejected. Shared memory is local by default and is already defined as supporting evidence rather than terminal control-plane truth.

D. Define the Role Taxonomy in the Kernel or Shared SDK

Section titled “D. Define the Role Taxonomy in the Kernel or Shared SDK”

Rejected. The vocabulary is software-delivery specific. Hardcoding it into the kernel or shared SDK would reverse the pack-boundary work ADR-013 locked in.

E. Let Local and Cloud Orchestration Evolve Separate Role Models

Section titled “E. Let Local and Cloud Orchestration Evolve Separate Role Models”

Rejected. ADR-010 requires one evidence-based control plane across local and cloud launchers. Only the launcher backend should vary.

  • ADR-009 - Shared memory JSONL distribution model
  • ADR-010 - Evidence-based orchestration control plane
  • ADR-013 - Pack-owned conductor surfaces
  • INIT-060 - Conductor-mode pack surfaces
  • INIT-061 - Delivery tooling hardening for liveness and relaunch

Notes:

  • Follow-on implementation WUs should reference this ADR when extending delegation, session, memory, relaunch, or orchestration-status schemas with role metadata.
  • The canonical source of truth for this ADR is docs/09-architecture-decisions/ADR-014-typed-agent-role-contract.md in the LumenFlow repository; this page mirrors that file for public readers.