add-task-status · git:20260711.db9d2ef · 2026-07-11 · sha256 2c5f18913b6fb840
add-task-status git:20260711.db9d2efA
Immutable. This exact content is served forever at /api/v1/blob/2c5f18913b6fb840.
---
name: add-task-status
description: Use when adding a value to a task/team/agent status union in agent-teams. The landmine is that there is NO exhaustiveness guard anywhere, so a new status silently falls through dispatch gating, readiness, scope-holding, and every status filter — and you must first know WHICH surface's state machine you are extending.
---
# Add a Task/Team/Agent Status Value
An ordered procedure. Two hazards: the classic and runtime surfaces have
SEPARATE, incompatible status unions, and neither has a `never`/exhaustive
switch, so a new value fails open (silently skipped) rather than failing to
compile.
## Steps
1. **Decide which surface.** `src/types.ts` (classic:
`pending→in_progress→completed|failed`) and `src/runtime/types.ts`
(runtime: 7-state) are different type families with the same names. A
value added to one does NOTHING for the other. Read
`harness/knowledge/core-lifecycle.md` "Two surfaces" first. Most new
protocol work is runtime.
2. **Add the union member** (`TaskStatus`/`TeamStatus`/`AgentStatus` in the
chosen `types.ts`).
3. **Audit every place that branches on the union — there is NO compiler
help.** For a runtime `TaskStatus` value, walk at minimum:
- `isTaskReady` (`runtime/team-runtime.ts:1606-1608`) — is a task in the
new status a dependency that should block dependents?
- `holdsScope` (`:632-634`) — does the new status hold a file scope?
- `dispatchReadyTasks` gating (`:602-773`) — can a task in this status be
dispatched, and does it filter it out where it should?
- the terminal-state checks (`done`/`failed` early-returns in
`completeTask`/`cancelTask`/`checkRoundCompletion` `:1753-1777`) — is
the new status terminal? round-completion counts terminal tasks.
- every `.filter(t => t.status === ...)` / `status !== 'done'` site.
A miss here is the classic silent-fallthrough bug: the task just never
gets picked up, or gets picked up when it shouldn't, with no error.
4. **Transition guards.** If the status is terminal, add it to the
`done`/`failed` early-return guards — and note the existing asymmetry
(`known-defects.md §8`): `blockTask`/`failTask` currently lack those
guards. Don't copy the gap.
5. **Host rendering.** The runtime host (canvas-workspace) renders status;
an unrendered status shows as unknown/blank. Update the host mapping.
6. **Update docs + tests.** Reflect the new state in
`docs/contracts.md`/`core-lifecycle.md`; add a `team-runtime.test.ts`
case exercising its dispatch/readiness behavior (the suite tests state
transitions richly — follow its fake-clock + store pattern).
## Done when
The union member exists on the correct surface; every readiness/scope/
dispatch/terminal branch has been consciously audited (not assumed); the
host renders it; docs and a transition test land with it.