<DelegationChain> is the composite behind the
delegation-chain workflow: a <Sequence> of
seven phases running in <Parallel> with a live-edit signal listener. Every
phase is reactive: it re-derives its slice of the delegation tree from the
dc* output rows on each render, so fan-out materializes level by level as
rows land, and user edits or probe findings replan the affected subtree
without restarting anything.
delegationSchemas in createSmithers and pass the matching
outputs subset. Tiers are labels only; missing tiers fall back to the
nearest configured tier in tierOrder. When budget.maxMinutes is set the
whole chain is wrapped in <Aspects> with a wall-clock latencySlo; dollar
budgets are enforced by per-leaf guard tasks over rolled-up dcExec actuals
(hard error over the limit, warning row at 80%).
Phase composites
Each phase is exported separately for standalone use and takesDelegationSharedProps (plus the extras noted):
| Component | Phase | Extra props |
|---|---|---|
<GoalRefinement> | Question forecast, prefetched forms, one durable question at a time, refined-prompt approval | prompt, maxQuestions, prefetchDepth |
<DelegationPlanning> | Recursive decomposition fan-out until the frontier is all leaves | prompt? (standalone root brief; otherwise waits for the approved goal) |
<DelegationPreview> | Zero-backpressure expected-output previews, skippable via dc-skip-preview | none |
<BackpressurePlanning> | Every node declares gates and dependencies before execution | none |
<DeriskLoop> | Risk probes, findings to the nearest parent, replan/reaffirm cascades | none |
<DelegationExecution> | Dependency-ordered leaf pipelines: exec, gates, approvals, developer previews, budget guards | maxAttempts |
<DelegationScoring> | Run-level score digest plus the satisfaction poll | none |
<DelegationEditListener> | Re-arming dc-edit signal wait feeding the derisk loop | until?, maxEdits |
Output tables
delegationSchemas (from smithers-orchestrator) registers every table;
DelegationOutputs is the matching prop shape. dcApproval is only needed
with an approvalPolicy, dcBudget only with a budget, and dcScore only
with run-level scorers.
| Table | One row per |
|---|---|
dcGoal | Refined goal (prompt, assumptions, questions asked) |
dcQuestion | Rendered question form / resolved answer |
dcForecast | The goal agent’s upfront question batch (internal) |
dcGoalApproval | The human’s { approved, refinedPrompt } decision |
dcPlan | A delegating node’s plan: children, risks, estimates; replans append superseding rows |
dcPreview | A leaf’s never-executed expected output |
dcGates | A node’s declared gates and logical dependencies |
dcProbe | A probe’s finding (planImpact: changes / confirms / none) |
dcReplan | A replan decision (invalidated or reaffirmed) with its trigger |
dcExec | One execution attempt, with best-effort actual usage and the measured commitRange |
dcReview | A review/check gate verdict for one attempt |
dcDevPreview | A developer-preview build (builtOk is required to pass) |
dcApproval | An approval-gate decision |
dcEdit | A live user edit (signal payload) |
dcSkip | The skip-previews signal payload |
dcPoll | The end-of-run poll answers |
dcBudget | A budget-guard checkpoint (ok or warn) |
dcScore | The run-level scoring digest |
Physical node ids
Every task id followsdc:<logicalId>:<phase> (the dc prefix is
idPrefix). Logical ids are /-separated paths (root/core/reducer); in
physical ids the / is encoded as : because node ids only allow
[a-zA-Z0-9:_-]. Row logicalId fields keep the / form. Phases:
- Goal:
dc:goal:forecast,dc:goal:forms:question-<seq>,dc:goal:question-<seq>(the durable human answer),dc:goal:goal,dc:goal:approve - Planning:
dc:<logicalId>:plan, replan versionsdc:<logicalId>:plan-<k> - Previews:
dc:<logicalId>:preview - Gates:
dc:<logicalId>:gates - Derisk:
dc:<logicalId>:probe-<n>,dc:<logicalId>:replan-<k> - Execution:
dc:<logicalId>:exec,dc:<logicalId>:review-<i>(reviews then checks, in declared order),dc:<logicalId>:approval-<i>,dc:<logicalId>:dev-preview(thendev-preview-2, …),dc:<logicalId>:budget - Scoring:
dc:root:score,dc:root:poll
Signals
Two fixed durable signal names (exported asDC_EDIT_SIGNAL and
DC_SKIP_PREVIEW_SIGNAL):
dc-editwith payload{ editId, logicalId, editedOutput, note? }. Each delivered edit writes adcEditrow that the derisk loop treats exactly like a plan-changing probe finding.dc-skip-previewwith payload{ skipped: true }. Once adcSkiprow exists, no further preview tasks mount.
Gates
AdcGates row declares an ordered list of gates:
dcExec.commitRange values
with instructions to inspect the commits themselves; chunk-level reviews get
the union of their subtree’s ranges (exec agents are wrapped with the
exported withCommitRange, which measures the working-copy commit before and
after the attempt, jj first with a git fallback). preview gates build a
developer preview after execution; builtOk: false fails the attempt like a
failed review. The gates prompt requires the root node to declare a
slideshow preview, so a run always ends showable.
UI side
smithers-orchestrator/gateway-react exports the matching read model:
useDelegationChain folds a
run’s dc* rows into a DelegationGraph (nodes with status, versions,
attention rollups, budget rollup, phase) and returns the submitEdit,
skipPreviews, answerHuman, and submitPoll actions. The pure reducer
foldDelegation is exported for tests and non-React use.
Notes
- Approval gates require
outputs.dcApproval;<DelegationExecution>throwsINVALID_INPUTif the policy produced approval gates without it. dcPlan.orchestration("tasks" | "workflow") is reserved for planned higher-order orchestration (a node authoring its own workflow as its execution strategy); it is accepted and ignored today. The fold store behinduseDelegationChainruns on Effect.ts behind the frozen hook signature.- Scoring wiring:
scorers.exec/scorers.reviewride the exec and review tasks;scorers.runrides the digest task. The delegation scorers live insmithers-orchestrator/scorers(see the scorer reference).