9.7 KiB
| id | type | title | domain | repo | status | owner | topic_slug | flavor | created | updated | related | origin | origin_ref | state_hub_workstream_id | |||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| CUST-WP-0074 | workplan | Qualify task wait states: external commitment versus human gate | infotech | the-custodian | ready | the-custodian | custodian | planning | 2026-09-28 | 2026-09-28 |
|
analysis | the-custodian/history/20260928-blocked-workplan-graph.md | a442e062-9c91-5ac6-8f1d-35f2117b7069 |
Qualify task wait states: external commitment versus human gate
Why
On 2026-09-28 the hub held 105 blocked workplans (retired slugs excluded)
with 220 wait tasks between them. The blocker was recorded as prose in
the task text. Only 7 dependency edges existed in workplan_dependencies
across all open workplans, and only 5 of the 220 wait tasks set
needs_human. Nothing could answer "which of these only Bernd can
unblock" or "which clear on their own when FLEX-WP-0020 finishes"
without reading every task.
Reading them shows two different kinds of wait:
- Case A — external commitment. The task waits for another repo's
workplan or task to reach a terminal state. It clears by itself; the
waiting side only needs to observe. Example: five workplans wait on
the
flex-auth→access-enginerename (FLEX-WP-0020). - Case B — human gate. The task waits for a decision, an approval, an
attended privileged action, or a credential provisioned by an operator.
Nothing in the fleet clears it; a person does. Example: about 25
workplans sit behind one attended OpenBao provisioning session
(
CCR-2026-0004and the per-lane scoped applies).
Both are wait today. Founder decision 2026-09-28: keep wait as the
stored status and qualify it, deriving two visible states from the
qualifier. This follows the existing convention that stalled and
needs_review are derived labels, not stored statuses
(.claude/rules/workplan-convention.md). Two new stored statuses were
rejected: every consumer (hub enum, fix-consistency rank logic, Fabric
OPEN_TASK, ralph-workplan, dashboards) would have to change at once
across 1465 workplans, whereas a qualifier is additive and a WARN drives
migration one workplan at a time.
Analysis, gate roots and the extracted graph:
history/20260928-blocked-workplan-graph.md.
The shape
No new keys. Three keys that task blocks already carry become meaningful together:
# Case A — 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"
# Case B — 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
Rules:
- A
waittask carriesdepends_on(Case A),needs_human: true(Case B), or both. Neither → consistency WARN. blocking_reasonstays required forwait(the hub API already refuseswaitwithout it).- Case A is satisfied when every
depends_ontarget isdone,finishedorarchived— the coordination-model v0.2 commitment rule. A task stillwaitpast satisfaction → consistency WARN. - Case B is satisfied by a resolved decision or by the human's recorded
action in the task text; when
decision_idis set, resolution of that decision triggers the same WARN. - Workplan
blockedstays stored. The hub derivesblocked-externalwhen all its wait tasks are Case A,blocked-humanwhen any is Case B, so "everything waiting on a person" is one query. - A wait on a repo that has no workplan id yet stays Case A with the
repo named in
blocking_reasonand the workplan-levelblocked_on:field (C-25). Upgrade to adepends_onid as soon as the owner returns one.
The workplan-level depends_on (C-20) is unchanged. Task-level
depends_on is the new commitment surface; related: stays context.
Write the standard and update the convention
id: CUST-WP-0074-T01
status: progress
priority: high
state_hub_task_id: "82e9522b-bb69-52f4-b182-13ddfa8cd56e"
Owner: the-custodian.
2026-09-28: proposal committed — standard 11e6202 (status proposed),
convention edit in the same commit, ralph-workplan spec abea4cc.
Remaining: founder acceptance, then set the standard to accepted.
canon/standards/task-wait-qualifiers_v0.1.md: the shape above, the six rules, the derived-state names, and the satisfaction rule cross- referenced tocoordination-engine/spec/coordination-model-v0.2.md§5..claude/rules/workplan-convention.md: extend the task-block template and the status-progression paragraph; state thatwaitwithout a qualifier is a WARN once T02 ships.~/ralph-workplan/workplan-spec.md: same template extension, so the loop's "all tasks done" check is unaffected and it never picks up aneeds_humantask.- Human-gated: canon goes through proposal-then-review. Commit the proposal, then record the founder's acceptance here.
Hand off enforcement and indexing to state-hub
id: CUST-WP-0074-T02
status: todo
priority: high
state_hub_task_id: "e5a05f83-1db5-59a7-8cae-095237f50b7d"
Owner: state-hub. Founder 2026-09-28: implement directly from this plan,
no delegated STATE-WP workplan — keep the layer count down while getting
a grip on exactly this. Receipt (commits, checks, tests) is recorded here.
Requested:
- C-20 reads task-block
depends_on(workplan and task ids) and writesworkplan_dependenciesrows with the waiting task as the from side — the table hasto_task_id; check whether afrom_task_idcolumn is needed or whetherfrom_workplan_idplus description suffices. - New check (next free C-id):
waittask with neither task-blockdepends_onnorneeds_human: true→ WARN, not fixable. - New check:
waittask whose everydepends_ontarget is terminal, or whosedecision_idis resolved → WARN "blocker satisfied", not fixable. needs_human,blocking_reasonanddecision_idwritten from file to hub on sync (columns exist;decision_idmay need one).GET /tasks/andGET /workplans/expose a derivedwait_kind/blocked_kindfield per rule 5. Read model only — no new write route.
Acceptance: the four checks run green against this repo, and the derived
fields answer for CUST-WP-0074-T05 below.
Hand off the ontology addendum to coordination-engine
id: CUST-WP-0074-T03
status: done
priority: medium
state_hub_task_id: "87711ade-f9f8-5e7f-9c15-025e5c235b35"
Owner: coordination-engine.
Done 2026-09-28 (founder: implement directly, no delegated workplan).
Spec edits committed in coordination-engine 354e800, not pushed:
coordination-model-v0.2.md §5 gains kind: decision and task-scope
depends_on; cross-owner-wait-mode-v0.1.md entry 1 now keys on
task-block depends_on, prose is a fallback until T05, and the Act
section states that a human gate is never leased or woken.
spec/coordination-model-v0.2.md§5 gains commitmentkind: decisionfor Case B, obligor = the named human or decision id, satisfaction = decision resolved. Case A is the existingkind: completion.spec/cross-owner-wait-mode-v0.1.mdentry condition 1 changes from "names another repo, owner, or workplan id" in prose to task-blockdepends_on; the prose form remains a fallback until the T05 backfill is complete.- Human-gate cases must never be leased to a worker; make that explicit in the Act section.
Hand off the view to railiance-fabric
id: CUST-WP-0074-T04
status: todo
priority: medium
state_hub_task_id: "aaf60a09-ba58-578d-ba26-480d874c6b97"
Owner: railiance-fabric, under RAIL-FAB-WP-0029.
coordination_graph.pyreads task-blockdepends_onfor edges and the derivedwait_kindfor colour: external commitment versus human gate.- Chokepoint sizing already uses in-degree; add a filter for
needs-humanonly, so the operator's queue is one view. - Fabric remains a read of State Hub. No authoring.
Backfill the open wait tasks
id: CUST-WP-0074-T05
status: wait
priority: high
needs_human: false
depends_on: [CUST-WP-0074-T01, CUST-WP-0074-T02]
blocking_reason: "Standard must be accepted (T01) and the unqualified-wait WARN must exist (T02) before touching foreign workplan files."
state_hub_task_id: "03a9c033-470e-56cf-965f-a5b289dd71af"
Owner: the-custodian, following the CUST-WP-0072 backfill pattern:
edit files in each repo, commit, run fix-consistency, never patch the hub
directly.
- Start with the gate roots in the history record (R1–R8): qualifying those roughly 60 tasks turns the largest fan-outs into real edges.
- Case B tasks: set
needs_human: true; attachdecision_idwhere a CCR or hub decision exists (CCR-2026-0004covers the offsite-backup lane). - Case A tasks: convert the referenced id in the prose to
depends_on. - Leave
flavor: residualworkplans alone. - Done when the unqualified-wait WARN count for open workplans is zero.
Correct the mis-blocked workplans
id: CUST-WP-0074-T06
status: todo
priority: low
state_hub_task_id: "8c51fc11-b09b-598a-8866-7cc39f3f1ada"
Owner: the-custodian coordinates; each repo owner edits.
Six blocked workplans have no wait task at all (fluid-wp-0008,
fluid-wp-0009, ft-wp-0001, glas-wp-0015, key-wp-0013,
three-phoenix-ha-cluster); the FEP-WP-0002/0003/0004/0006/0008 chain
is self-ordering inside one repo; testdrive-jsui-publication waits on
a submodule init. Message each owner with the finding and the
qualifier rule. Do not edit their files or reassign their tasks. Record
the outcome per workplan here.