"CUO supervisor Phase 4 — 5 special-case workflow handlers: time-critical SLA bypass, per-instance iteration, multi-output fan-out, sequential-approval gating, persona-pair partnership"
§1 — Description (BCP-14 normative)
The CUO supervisor MUST ship 5 workflow Handler subclasses at modules/cuo/cuo/core/handlers/ dispatched from workflow pattern: frontmatter, with 8 memory audit kinds, and updated workflow YAML in the 9 affected catalog workflows.
- MUST validate
workflow_patternagainst closed enum per DEC-2381 (cardinality 6, defaultlinear).
- MUST dispatch in
dispatch.py::pick_handler(workflow)per DEC-2387:
- Read
workflow.frontmatter.pattern(defaultlinear) - Return matching Handler subclass instance
- Linear pattern → existing
execute_chain()(unchanged path) - All others → new Handler subclass
- MUST implement
TimeCriticalHandlerper DEC-2382:
- Bypass any queueing/batching/work-stealing
- Read
workflow.frontmatter.sla_minutes - Start timer, walk chain
- If
total_duration_ms > sla_minutes * 60 * 1000: emitcuo.time_critical_sla_breachmemory row withextra.breach_severity = (actual - sla) / sla - Affected workflows:
chief-privacy-officer/breach-response-cycle(sla_minutes: 240 = 4h),chief-communications-officer/per-crisis-response(sla_minutes: 120 = 2h),chief-trust-officer/per-trust-incident-update(sla_minutes: 240)
- MUST implement
PerInstanceHandlerper DEC-2383:
- Read
workflow.frontmatter.instance_descriptor(list of dicts) - For each instance: invoke
execute_chain()withinputs.merged(instance) - Collect ChainResults in list; build fan-in summary
ChainResultwithoutcome="COMPLETED_BATCH",per_instance: list[ChainResult] - Emit one
cuo.per_instance_iterationrow per instance + onecuo.per_instance_summaryrow for the batch - Affected workflow:
chief-sales-officer/quarterly-account-plan(10–20 top-tier accounts per quarter)
- MUST implement
MultiOutputHandlerper DEC-2384:
- Run chain end-to-end ONCE
- Read
workflow.frontmatter.output_recipients(list of{recipient_id, format, delivery_method}) - For each recipient: render final step's output through
recipient.format, deliver viarecipient.delivery_method - Emit one
cuo.multi_output_fanoutmemory row per recipient - Affected workflow:
chief-legal-officer/quarterly-regulatory-cycle(1 source artefact → N regulator filings)
- MUST implement
SequentialApprovalHandlerper DEC-2385:
- Read
workflow.frontmatter.gates(list of{approver_persona, approver_workflow}) - Execute the gating workflow first (the approver's chain)
- If approver chain
outcome != COMPLETED: halt parent chain withoutcome=BLOCKED, emitcuo.sequential_approval_halted - If approver chain emits explicit approval audit kind: proceed with gated chain, emit
cuo.sequential_approval_resumed - Affected pair:
chief-ethics-officer/per-model-card-ethics-sign-offgateschief-ai-officer/per-model-card-release
- MUST implement
PersonaPairHandlerper DEC-2386:
- Read
workflow.frontmatter.peer_persona+workflow.frontmatter.shared_artefact - Run primary chain up to declared handoff step
- Pause, dispatch to peer persona's matching workflow (looked up by shared_artefact content_hash)
- Receive peer's contribution; resume primary chain
- Emit one
cuo.persona_pair_handoffrow per peer-direction transition - Affected pairs:
chief-revenue-officer/churn-collaboration↔chief-customer-officer/churn-collaboration(shared: churn cohort analysis)chief-marketing-officer/content-strategy↔chief-communications-officer/distribution-strategy(shared: campaign plan)chief-risk-officer/postmortem-risk-lens↔chief-technology-officer/postmortem-engineering-lens(shared: incident report)chief-customer-officer/customer-360-cx-lens↔chief-data-officer/customer-360-data-lens(shared: customer profile)
- MUST preserve audit-chain integrity: all 8 new memory audit kinds (DEC-2388) routed through
cyberos.core.writer.Writer(no direct file writes).
- MUST wire handler dispatch into
cli.py executesubcommand: when workflow haspattern != linear, log# dispatched to <HandlerClass>before invoking.
- MUST version-bump
modules/cuo/pyproject.tomlfrom3.0.0a3to3.0.0a4.
- MUST NOT mutate
skill_chain[]at runtime (forbidden by CUO AGENTS.md §A.12).
- MUST NOT bypass HITL halts in sequential_approval (the approval gate IS a HITL pause).
- MUST NOT drop the
cuo.handler_dispatchedmemory row for any non-linear pattern execution.
§2 — Why this design
Why dispatch by frontmatter pattern: field (DEC-2387)? Workflow author declares the pattern in YAML; the supervisor reads it and picks the Handler. Keeps the linear/default path unchanged (zero performance regression for 185/194 workflows) and makes the special cases self-documenting.
Why one Handler subclass per pattern (DEC-2381)? Each pattern has distinct invariants — time-critical wants SLA tracking, per-instance wants fan-in summary, multi-output wants fan-out delivery, sequential-approval wants HITL gates, persona-pair wants peer handoff. Lumping them into a generic handler with a giant switch statement loses these invariants in code review.
Why peer lookup by shared_artefact.content_hash (DEC-2386)? Persona-pair handoffs are about shared artefact ownership, not about routing strings. Looking up by content hash ensures both personas see the same artefact even if their workflows name it differently.
Why version 3.0.0a4 not 3.1.0? Phase 4 is alpha-grade like Phase 1–3 — handler implementations are basic; production hardening (retries, timeouts, observability) comes in 3.2.0.
§3 — API contract
Workflow frontmatter additions (per affected workflow):
# Time-critical workflow
pattern: time_critical
sla_minutes: 240
# Per-instance workflow
pattern: per_instance
instance_descriptor:
source: workflow.inputs.account_list
fields: [account_id, account_name, account_tier]
# Multi-output workflow
pattern: multi_output
output_recipients:
- { recipient_id: "vn-mst", format: "filing-xml-mst", delivery_method: "email" }
- { recipient_id: "vn-mof", format: "filing-pdf-mof", delivery_method: "portal" }
# Sequential-approval workflow (the gated one)
pattern: sequential_approval
gates:
- { approver_persona: "chief-ethics-officer", approver_workflow: "per-model-card-ethics-sign-off" }
# Persona-pair workflow
pattern: persona_pair
peer_persona: "cco-customer"
peer_workflow: "churn-collaboration"
shared_artefact: "churn-cohort-analysis"
handoff_step: 4
CLI surface:
cyberos-cuo execute <persona>/<workflow> # auto-detects pattern from frontmatter
→ dispatched to TimeCriticalHandler (when pattern: time_critical)
→ dispatched to PerInstanceHandler (when pattern: per_instance)
→ dispatched to MultiOutputHandler (when pattern: multi_output)
→ dispatched to SequentialApprovalHandler (when pattern: sequential_approval)
→ dispatched to PersonaPairHandler (when pattern: persona_pair)
§4 — Acceptance criteria
- workflow_pattern enum cardinality 6.
- Default pattern (linear) routes through existing execute_chain() unchanged — no perf regression for 185 affected workflows.
- TimeCriticalHandler emits sla_breach when duration > limit.
- TimeCriticalHandler bypasses any scheduling layer — invokes synchronously.
- PerInstanceHandler iterates exactly len(instance_descriptor) times.
- PerInstanceHandler fan-in summary
outcome=COMPLETED_BATCHwhen all succeed;outcome=PARTIALwhen any fail. - MultiOutputHandler renders final-step output once per recipient.
- MultiOutputHandler emits 1 memory row per recipient.
- SequentialApprovalHandler halts on approver failure.
- SequentialApprovalHandler resumes on approver success.
- PersonaPairHandler routes to peer at declared handoff_step.
- PersonaPairHandler shared_artefact content_hash matches across peer chains.
- All 8 new memory audit kinds emit through cyberos.core.writer.Writer.
- CLI
executeprints# dispatched to <HandlerClass>for non-linear patterns. - 9 affected workflows updated with correct
pattern:frontmatter. - Existing 21/22 tests still pass post-change.
- 6 new test files green (one per handler + dispatch).
- pyproject.toml version bumped to 3.0.0a4.
- CUO docs site §12 Roadmap updated — Phase 4 marked shipped.
- No workflow's skill_chain[] mutated at runtime.
§5 — Verification
# modules/cuo/tests/test_applier_paths.py
def test_dispatch_default_is_linear():
"""Workflows without a pattern: field route to LinearHandler (= existing execute_chain)."""
from cuo.core.handlers.dispatch import pick_handler
workflow_dict = {"frontmatter": {}, "body": "..."}
handler = pick_handler(workflow_dict)
assert handler.__class__.__name__ == "LinearHandler"
def test_dispatch_reads_pattern_frontmatter():
"""Workflows with pattern: time_critical route to TimeCriticalHandler."""
from cuo.core.handlers.dispatch import pick_handler
workflow_dict = {"frontmatter": {"pattern": "time_critical", "sla_minutes": 240}}
handler = pick_handler(workflow_dict)
assert handler.__class__.__name__ == "TimeCriticalHandler"
assert handler.sla_minutes == 240
# modules/cuo/tests/test_proposal_applier.py
def test_time_critical_emits_sla_breach_when_slow(tmp_memory):
"""If actual_duration > sla, memory gets a cuo.time_critical_sla_breach row."""
from cuo.core.handlers.time_critical import TimeCriticalHandler
handler = TimeCriticalHandler(sla_minutes=1) # 1 minute SLA
# Mock chain that takes 90 seconds
result = handler.execute(slow_chain_fixture, memory_root=tmp_memory)
breach_rows = [r for r in tmp_memory.audit_rows() if r.extra.get("kind") == "cuo.time_critical_sla_breach"]
assert len(breach_rows) == 1
assert breach_rows[0].extra["breach_severity"] > 0.5
# tests/test_per_instance_handler.py
def test_per_instance_iterates_once_per_account():
"""instance_descriptor with 5 accounts → 5 chain invocations + 1 summary."""
from cuo.core.handlers.per_instance import PerInstanceHandler
instances = [{"account_id": f"acct-{i}"} for i in range(5)]
handler = PerInstanceHandler(instance_descriptor=instances)
result = handler.execute(cso_sales_workflow_fixture)
assert result.outcome == "COMPLETED_BATCH"
assert len(result.per_instance) == 5
# tests/test_multi_output_handler.py
def test_multi_output_fanout_to_recipients():
"""3 recipients → final step output rendered 3 times + 3 memory rows."""
from cuo.core.handlers.multi_output import MultiOutputHandler
recipients = [
{"recipient_id": "vn-mst", "format": "xml", "delivery_method": "email"},
{"recipient_id": "vn-mof", "format": "pdf", "delivery_method": "portal"},
{"recipient_id": "vn-sbv", "format": "json", "delivery_method": "api"},
]
handler = MultiOutputHandler(output_recipients=recipients)
result = handler.execute(clo_legal_workflow_fixture, memory_root=tmp_memory)
fanout_rows = [r for r in tmp_memory.audit_rows() if r.extra.get("kind") == "cuo.multi_output_fanout"]
assert len(fanout_rows) == 3
# modules/cuo/tests/test_proposal_applier.py
def test_sequential_approval_halts_on_ethics_reject():
"""If ethics-sign-off chain fails, model-card-release does NOT execute."""
from cuo.core.handlers.sequential_approval import SequentialApprovalHandler
handler = SequentialApprovalHandler(gates=[{
"approver_persona": "chief-ethics-officer",
"approver_workflow": "per-model-card-ethics-sign-off"
}])
# Mock approver chain that fails
result = handler.execute(caio_per_model_card_release_fixture, approver_outcome="FAILED")
assert result.outcome == "BLOCKED"
halt_rows = [r for r in tmp_memory.audit_rows() if r.extra.get("kind") == "cuo.sequential_approval_halted"]
assert len(halt_rows) == 1
# modules/cuo/tests/test_proposal_applier.py
def test_persona_pair_handoff_at_declared_step():
"""At handoff_step, primary pauses + peer invoked + result threaded back."""
from cuo.core.handlers.persona_pair import PersonaPairHandler
handler = PersonaPairHandler(
peer_persona="chief-customer-officer",
peer_workflow="churn-collaboration",
shared_artefact="churn-cohort-analysis",
handoff_step=4,
)
result = handler.execute(cro_revenue_churn_fixture)
handoff_rows = [r for r in tmp_memory.audit_rows() if r.extra.get("kind") == "cuo.persona_pair_handoff"]
assert len(handoff_rows) >= 1
# Verify shared artefact content hash matches across both legs
primary_hash = result.shared_artefact_hash
peer_hash = result.peer_artefact_hash
assert primary_hash == peer_hash
§7 — Dependencies
Upstream: TASK-CUO-104 (topological chain walk), TASK-CUO-105 (per-step rollback — sequential_approval halt may trigger rollback of completed steps).
Cross-module: TASK-SKILL-001 (skill registry for peer-workflow lookup), TASK-MEMORY-111 (PII scrubbing for SLA-breach reason field).
Downstream: None — Phase 4 closes the supervisor design. Future work (TASK-CUO-107+) shifts to production hardening (retries, observability, multi-tenant).
§10 — Failure modes
| Failure | Detection | Outcome | Recovery |
|---|---|---|---|
Unknown pattern: value in workflow frontmatter | dispatch.py rejects | refuse to execute; emit cuo.handler_dispatch_failed | author fixes frontmatter |
| time_critical chain hangs past SLA | timer in TimeCriticalHandler | sla_breach row emitted; chain continues (don't kill, deliver late + audit) | operator reviews breach in memory |
| per_instance empty descriptor | empty list check | refuse to execute; outcome=BLOCKED | author populates descriptor |
| multi_output zero recipients | empty list check | refuse to execute; outcome=BLOCKED | author adds recipients |
| sequential_approval approver chain has no halting step | approver chain returns COMPLETED without explicit approval audit | treat as auto-approved + log warning | operator decides if approval is implicit-OK |
| persona_pair peer workflow not found | catalog lookup miss | outcome=FAILED; emit cuo.persona_pair_peer_not_found | author fixes peer_persona/peer_workflow |
| persona_pair shared_artefact hash mismatch | content_hash comparison | outcome=FAILED; emit cuo.persona_pair_artefact_drift | author reconciles peer workflows |
| Handler raises uncaught exception | supervisor try/except | outcome=FAILED with stack trace in notes | bug report + fix |
| Concurrent execution of same persona_pair from both sides | content_hash dedup | second invocation joins first's result | inherent |