5.5 KiB
| id | type | title | domain | status | version | owner | revision | last_reviewed | review_interval | created | updated | scope | related_workplans | supersedes | |||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| canon-task-wait-qualifiers | standard | Task Wait Qualifiers v0.1 | custodian | accepted | 0.1 | the-custodian | accepted-1 | 2026-09-28 | 6m | 2026-09-28 | 2026-09-28 | fleet |
|
none |
Task Wait Qualifiers v0.1
Purpose
A task in status: wait must say what it waits for in a form the fleet can
read without a person. Two kinds of wait exist and need different handling:
- External commitment — the task waits for another workplan or task to reach a terminal state. It clears on its own; the waiting side observes.
- Human gate — the task waits for a decision, approval, attended privileged action or operator-provisioned credential. Nothing in the fleet clears it; a person does.
wait stays the only stored status for both. The kind is a derived state
computed from qualifier keys, in the same way stalled and needs_review
are derived labels rather than stored statuses (ADR-001 workplan convention).
Founder decision 2026-09-28 (CUST-WP-0074): derived states, not two new
stored statuses. Reason: a qualifier is additive — existing files stay valid
and a consistency warning migrates them one workplan at a time — whereas new
statuses force every consumer (hub enum, fix-consistency rank logic, Fabric
open-task set, ralph-workplan, dashboards) to change at once.
Shape
No new task-block keys. Three keys that task blocks already carry become meaningful together:
# External commitment → derived state: waiting-external
status: wait
depends_on: [FLEX-WP-0020] # workplan id, or task id (KEY-WP-0035-T02)
blocking_reason: "access-engine rename must land first"
# Human gate → derived state: needs-human
status: wait
needs_human: true
blocking_reason: "operator must provision NC_WEBDAV/AGE creds to OpenBao"
decision_id: CCR-2026-0004 # optional, when a tracked decision exists
A task may carry both (derived state: both). decision_id is the id of a
hub decision or a change request; it is optional and never a substitute for
needs_human: true.
Rules
- A
waittask carries adepends_onlist,needs_human: true, or both. Neither → consistency WARN (unqualified wait), not auto-fixable. blocking_reasonstays required forwait. The hub API already refuseswaitwithout it; the file must carry it so the hub can be rebuilt from files.- An external commitment is satisfied when every
depends_ontarget is terminal: task targetsdoneorcancel, workplan targetsfinishedorarchived(coordination-model v0.2 §5 commitment rule). A task stillwaitafter satisfaction → consistency WARN (blocker satisfied). Targets the hub cannot resolve produce no warning. - A human gate is satisfied by the person's recorded action in the task text,
or — when
decision_idis set — by that decision resolving, which raises the same WARN. - Workplan
blockedstays stored. The hub derivesblocked-humanwhen any wait task is a human gate, elseblocked-externalwhen any is an external commitment, elsenone. "Everything waiting on a person" is therefore one query, not a reading exercise. - A wait on a repo that has no workplan id yet is an external commitment
with the repo named in
blocking_reasonand in the workplan-levelblocked_on:field (watched by C-25). Upgrade to adepends_onid as soon as the owner returns one. - A human-gate task is never leased to a worker. Coordination tooling treats
needs_human: trueas a stop, not a wake condition.
Scope of depends_on
- Workplan-frontmatter
depends_on(C-20) is unchanged: it declares workplan-level blockers. - Task-block
depends_onis the commitment surface this standard adds. It is indexed into the same hub dependency table with the waiting task as the from side. related:is context, never a commitment.
Derived state names
| Stored | Qualifier | Derived task state | Hub field |
|---|---|---|---|
wait |
depends_on only |
waiting-external |
wait_kind: external |
wait |
needs_human: true only |
needs-human |
wait_kind: human |
wait |
both | both | wait_kind: both |
wait |
neither | unqualified (WARN) | wait_kind: unqualified |
Workplan: blocked_kind ∈ human | external | none, null unless
status: blocked.
Consumers
- state-hub — fix-consistency indexes task-block
depends_on, emits the two warnings, syncsneeds_human/blocking_reason/decision_idfrom file to hub, exposeswait_kindandblocked_kindon the read model. - coordination-engine —
cross-owner-wait-modeenters from task-blockdepends_on; the ontology gains commitmentkind: decisionfor human gates. - railiance-fabric — the coordination graph colours commitment edges and human-gate nodes distinctly and offers a needs-human-only view.
- ralph-workplan — the loop never picks up a
needs_humantask and its "all tasks done" retirement rule is unaffected.
Migration
Existing wait tasks without a qualifier remain valid files. The unqualified
WARN drives the backfill (CUST-WP-0074-T05), gate roots first. Do not
touch flavor: residual workplans.
Review
Proposal-then-review. Acceptance is recorded in CUST-WP-0074-T01; on
acceptance set status: accepted, revision: accepted-1.