docs: residual handoff in hub docs, AGENTS, and templates
Some checks failed
CI Smoke / host-smoke (push) Successful in 1s
CI Smoke / container-smoke (push) Has been cancelled

Align agent close/workplan finish with fleet residual convention
(live work records, origin residual + origin_ref). Reference pages for
work-records and intakes; session and workplan templates updated.
This commit is contained in:
tegwick 2026-07-22 18:15:45 +02:00
parent b5747d1104
commit f8bd74e27e
10 changed files with 480 additions and 30 deletions

View file

@ -97,8 +97,12 @@ curl -s -X PATCH "http://127.0.0.1:8000/tasks/<task_id>" \
**Close:**
1. Update workplan file task statuses to reflect progress
2. Log: `POST /progress/` with a summary of what changed
3. After workplan file changes, run:
2. If finishing a workplan: hand off **residuals** as live work records first
(intake with `origin: residual` + `origin_ref: <WP-id>`, or a next workplan /
decision / engagement). Do not park leftovers only in prose or `SCOPE.md`.
Canon: `the-custodian/canon/standards/work-record-types_v0.1.md` § Residuals.
3. Log: `POST /progress/` with a summary of what changed (name handoff ids)
4. After workplan file changes, run:
```bash
statehub fix-consistency
```
@ -219,6 +223,11 @@ Task description text.
Status progression: `todo``progress``done`; use `wait` for waiting/blocked work and `cancel` for stopped work.
**Residuals when finishing:** actionable leftovers become live work records
before `status: finished` — usually an intake (`origin: residual`,
`origin_ref: STATE-WP-NNNN`) or a spawned workplan. Residual is a *role*,
not a kind. Fleet list lives on State Hub, not in `SCOPE.md`.
To create a new workplan:
1. Write the file following the format above
2. Run `statehub fix-consistency` locally; ask the operator only if the CLI or

View file

@ -0,0 +1,179 @@
---
title: Intakes — Reference
---
# Intakes — Reference
An **intake** is a work-record kind for a **spark**: an idea, finding,
directive, or request that is not yet a workplan, task, decision, or
engagement. Intakes hold early signal until someone vets, routes, and either
promotes or closes them.
Canon: `the-custodian/canon/standards/work-record-types_v0.1.md`
(`kind: intake`, id scheme `{PREFIX}-IN-NNNN`).
Umbrella: [Work Records](/docs/work-records).
Intakes **replace** the retired hub **suggestion** backlog for new work. See
[Suggestions (legacy)](/docs/suggestions).
---
## Lifecycle
```text
open -> vetted -> routed -> closed(promoted | declined | absorbed)
```
| Status | Meaning |
|--------|---------|
| **open** | Captured; not yet fully vetted |
| **vetted** | Reviewed; structure and intent are clear enough to route |
| **routed** | Assigned a destination / owner path; eligible for promotion |
| **closed** | Terminal; requires an **outcome** |
| Outcome (only when `closed`) | Meaning |
|------------------------------|---------|
| **promoted** | Became another work record; `promoted_to` holds the new canonical id |
| **declined** | Explicitly not pursued |
| **absorbed** | Already covered by existing work; no new record needed |
Database constraints (what the API enforces):
- At least one of `topic_id`, `workplan_id`, or `repo_id` is set (scope).
- `closed` requires `outcome`.
- `outcome = promoted` requires `promoted_to`.
Route action: only from `open` or `vetted``routed`.
Close action: from `open`, `vetted`, or `routed``closed`.
---
## Fields that matter
| Field | Role |
|-------|------|
| `title` / `description` | Human-readable content |
| `lane` | Autonomy lane: `green` \| `blue` \| `yellow` \| `orange` \| `red` |
| `status` / `outcome` | Lifecycle |
| `origin` / `origin_ref` | Where the spark came from. **Residuals:** `origin: residual` (or `handoff`) and `origin_ref: <parent-WP-id>` (e.g. `BINKY-WP-0006`). Also e.g. `legacy-suggestion:<uuid>`, mail-triage ids |
| `promoted_to` | Canonical id of the record this became after promotion |
| `source_repo_path` | Repo-relative path of the YAML block / file when file-authored |
| `routed_note` | Free-text routing context |
| `notes` | Append-only note list via `POST /intakes/{id}/notes` |
Identity: hub rows use UUIDv7 primary keys. File-backed blocks use fleet ids
such as `CUST-IN-0004` and receive `state_hub_intake_id` write-back from
`fix-consistency`.
---
## How intakes enter the hub
**1. File-backed (preferred for lasting work)**
Author a schema-valid YAML block in any repo markdown file (canon schemas under
`the-custodian/canon/standards/schemas/work-records/`). Commit, then run
`statehub fix-consistency` so the hub registers the record and writes the UUID
back.
**2. Hub API / MCP (capture path)**
```text
create_intake(title=..., topic_id=... | workplan_id=... | repo_id=..., lane="green", ...)
# REST: POST /intakes/
```
```text
list_intakes(status="open")
route_intake(intake_id, routed_note=...)
close_intake(intake_id, outcome="declined"|"absorbed"|"promoted", promoted_to=...)
```
REST mirrors: `GET/POST /intakes/`, `PATCH /intakes/{id}`,
`POST /intakes/{id}/route`, `POST /intakes/{id}/close`,
`POST /intakes/{id}/notes`.
---
## Promotion (intake → another kind)
Promotion is the sanctioned path from a **routed** intake into a durable
work-record kind:
```text
intake.routed → workplan | task | decision | engagement
```
Implemented by:
```bash
# via CLI (statehub entrypoint wraps scripts/promote_intake.py)
statehub promote-intake <intake-id-or-uuid> --to workplan --repo <path>
statehub promote-intake <id> --to task --workplan-file workplans/….md
statehub promote-intake <id> --to decision --target-file <md>
statehub promote-intake <id> --to engagement --target-file <md>
```
What the promotion transition does today:
1. Validates the intake is **routed**.
2. Writes the target artefact (ADR-001 workplan file, task block, or
decision/engagement YAML block).
3. Sets intake `promoted_to` and closes with `outcome=promoted`.
4. Sets `origin: intake:<…>` on the new record for back-link.
5. Registers / syncs with the hub where a hub entity exists.
**Engagements:** promotion can write the file block; a first-class hub
engagement entity is not present yet — the CLI reports that limitation rather
than inventing silent hub rows.
Closing with `outcome=promoted` by hand is supported for after-the-fact
recording, but the promote CLI is the intended path for both artefacts.
---
## What is not wired yet
These are present limitations of the current hub surface (not aspirations):
| Area | Current behaviour |
|------|-------------------|
| **Dashboard** | No dedicated Intakes page yet; legacy [Suggestions](/suggestions) still reads the old table |
| **Next-steps / summary** | `ranked_suggestions` and open-suggestion signals in `GET /state/summary` and `get_next_steps` still read the **suggestion** table, not intakes |
| **WSJF on intakes** | Suggestion WSJF fields (`base_value`, `relevance`, …) are not part of the intake model |
| **Task-flow YAML** | Workplan, task, and contribution have `flows/*.yaml`; intake advances via dedicated route/close endpoints rather than `advance_workstation` |
Use `GET /intakes/` or MCP `list_intakes` for the live backlog.
---
## Residuals as intakes
When a workplan finishes with leftover work that is not large enough for an
immediate child workplan, author an **intake** with:
```yaml
origin: residual
origin_ref: BINKY-WP-0006 # parent workplan id
lane: green # or blue/yellow/…
status: open # or vetted/routed when ready
```
Promote with `statehub promote-intake` when structure is ready (e.g. to a
workplan). Listing open residual intakes across domains is a State Hub read
concern (`list_intakes` + origin filters; planned `statehub residuals` CLI).
See [Work Records — Residuals](/docs/work-records#residuals-role-not-kind).
## Relation to other kinds
| Kind | Boundary |
|------|----------|
| **workplan / task** | Durable planned work; intake is the pre-plan capture form |
| **decision** | Approval package; an intake may promote *into* a decision |
| **contribution** | Outbound third-party artefact — different entity; not an intake outcome |
| **suggestion (legacy)** | Superseded capture mechanism; do not create new ones |
| **residual** | Not a kind — role of intake/WP/decision with `origin: residual` |
---
*Intakes are a fresh entity (CUST-WP-0061), not a rename of `suggestions`.*

View file

@ -0,0 +1,164 @@
---
title: Work Records — Reference
---
# Work Records — Reference
A **work record** is any identified, lifecycle-bearing coordination artefact
indexed by State Hub. Workplans and tasks are work records; so are intakes,
decisions, engagements, and register entries. The term is the shared umbrella
for planning, execution, and coordination — not a separate product surface.
Fleet canon (normative):
`the-custodian/canon/standards/work-record-types_v0.1.md` and the machine
registry `work-record-types.yaml`. This page describes what State Hub
implements and exposes today.
---
## Kind registry (closed list)
| Kind | Id scheme (typical) | Meaning in State Hub today |
|------|---------------------|----------------------------|
| **workplan** | `{PREFIX}-WP-NNNN` | Structured, dependency-bearing body of work; file under `workplans/` (ADR-001) |
| **task** | `{WP-ID}-TNN` · `ADHOC-YYYY-MM-DD-TNN` | Smallest executable unit; lives in a workplan file |
| **intake** | `{PREFIX}-IN-NNNN` | Spark: idea, finding, directive, or request before it is a plan/task |
| **decision** | `{PREFIX}-DEC-YYYY-NNN` (file) · hub decision entity | Approval package / recorded choice |
| **engagement** | `{PREFIX}-ENG-YYYY-NNN` | Scheduled external interaction (file-backed; hub entity not yet first-class) |
| **register-entry** | `RISK-…`, `TD-…`, `CAP-…`, `CCR-…`, `ADR-…` | Risks, debt, capability requests, credential change requests, ADRs |
Unregistered id patterns are rejected by CI and `statehub fix-consistency`
(sidetrack detector). New kinds are added only via the canon registry.
**Not a work-record kind today:** **contributions** (outbound third-party BR/FR/EP/UPR
artifacts). They remain a separate hub entity and dashboard surface — see
[Contributions](/docs/contributions).
---
## Conventional spine
Every work record carries the same conceptual fields (kind-specific fields
extend them; they do not replace them):
| Field | Role |
|-------|------|
| `id` | Human/agent canonical name (`STATE-WP-0074`, `CUST-IN-0004`, …) |
| `uuid` | Hub-assigned identity for relations and history (UUIDv7 for new intake and related entities; older tables may still use UUIDv4) |
| `kind` | One of the registered kinds |
| `lane` | Autonomy lane (`green``red`) where the entity supports it |
| `status` | Kind-specific lifecycle position |
| `owner` | Agent or human |
| `repo` | Owning repo (ADR-001 / ADR-005 anchor) |
| `tags` | Policy and derived labels — not lifecycle states |
| `created` / `updated` | Dates |
Hub write-back of UUIDs into source files uses the familiar
`state_hub_*_id` fields (for workplans the frontmatter key is still
`state_hub_workstream_id` for compatibility).
---
## Abstract lifecycles
| Kind | Lifecycle (stored `status` / outcome) |
|------|----------------------------------------|
| task | `wait → todo → progress → done \| cancel` |
| workplan | `proposed → ready → active → blocked → backlog → finished → archived` |
| intake | `open → vetted → routed → closed(promoted \| declined \| absorbed)` |
| decision | Canon file lifecycle: `prepared → resolved(…)`; hub decision page still uses its own status vocabulary — see [Decisions](/docs/decisions) |
| engagement | `queued → prepared → done` (file convention) |
| register-entry | Per existing register conventions |
Detail pages:
- [Workplan Lifecycle](/docs/workstream-lifecycle)
- [Tasks](/docs/tasks)
- [Intakes](/docs/intakes)
- [Decisions](/docs/decisions)
---
## Source files, registration, and index
1. **Workplans and tasks** are authored in dedicated `workplans/*.md` files
(ADR-001). `fix-consistency` (C-06 and related checks) registers them and
writes hub IDs back into the files.
2. **Intakes, decisions, and engagements** may appear as schema-valid YAML
blocks in any repo markdown file. `fix-consistency` registers intake and
decision blocks and writes `state_hub_intake_id` (and decision IDs) back when
present.
3. **Generated index:** each repo may have a `WORK-RECORDS.md` (or equivalent)
produced by fix-consistency — a read-only orientation table of indexed
records and their source paths. Do not hand-edit it.
4. The hub remains a **read model** for formal structure: files are source of
truth for workplans/tasks; hub-first bootstrap tools exist but are not the
steady-state path.
Promotion from intake to another kind is a first-class operation
(`statehub promote-intake` / `scripts/promote_intake.py`): it writes the target
artefact, sets `promoted_to` / `origin` links, and closes the intake as
`promoted`. Manual copy-paste between kinds is treated as a process defect.
---
## Residuals (role, not kind)
**Residual** means work deliberately left when finishing a workplan. It is
**not** a kind in the registry. Do not invent a parallel residuals file or park
leftovers only in `SCOPE.md` or finished-workplan prose.
| Shape | Capture as | Links |
|-------|------------|--------|
| Parkable Green/Blue | **intake** | `origin: residual` (or `handoff`), `origin_ref: <parent-WP-id>` |
| Multi-step | **workplan** (next WP) | Name parent WP; promote from residual intake when useful |
| Founder gate / time | **decision** / **engagement** | Same origin fields when from residual intake |
| Persistent gap | **register-entry** | Cross-link parent in notes |
**Before** setting a workplan to `finished`, promote each actionable residual
into a live record. Optional narrative under the closing task is fine for
humans; the backlog is the work record. Fleet listing (intakes + open WPs with
those origin fields) belongs on State Hub — future `statehub residuals` /
`GET …` filters — not in domain repos. Canon:
`the-custodian/canon/standards/work-record-types_v0.1.md` § Residuals.
---
## Tags vs status
| Class | Examples | Rule |
|-------|----------|------|
| **Derived tags** | `stalled`, `stale`, `orphaned`, … | Computed; not written as workplan `status` |
| **Policy tags** | `needs-human`, `automatable`, `compliance-relevant`, `residual`, … | Assigned under policy |
Situational labels are tags (or derived health filters). Lifecycle position is
`status` only. Workplan health filters `needs_review` and `stalled` are
documented under [Workplan Lifecycle](/docs/workstream-lifecycle).
---
## Legacy names still visible in State Hub
| Legacy surface | Current meaning |
|----------------|-----------------|
| **workstream** | Compatibility name for **workplan** (some frontmatter keys, retired or metered API aliases) |
| **suggestion** | Prework-record hub entity for gated needs; **mutations retired** (HTTP 410). Use **intake**. Reads may remain for history. See [Suggestions (legacy)](/docs/suggestions). |
| Dashboard **Suggestions** page | Still lists the legacy table via `GET /suggestions/`; open backlog has been migrated to file-backed intakes |
---
## Related APIs (orientation)
| Kind / surface | Primary REST | MCP (preferred) |
|----------------|--------------|-----------------|
| workplan | `GET/POST/PATCH /workplans/` | `list_workplans`, `create_workplan`, `update_workplan` |
| task | `GET/PATCH /tasks/` | `list_tasks`, `create_task`, `update_task_status` |
| intake | `GET/POST /intakes/`, `…/route`, `…/close` | `create_intake`, `list_intakes`, `route_intake`, `close_intake` |
| decision | `/decisions/` | `record_decision`, `resolve_decision` |
| contribution (not a work-record kind) | `/contributions/` | `register_contribution` |
| suggestion (legacy, read-only writes) | `GET /suggestions/` | mutation tools return 410 |
---
*Canon and registry live in `the-custodian`. State Hub implements registration,
read model, flow evaluation for some kinds, and the intake promotion CLI.*

View file

@ -1,30 +1,39 @@
---
title: Workplan Lifecycle - Reference
title: Workplan Lifecycle Reference
---
# Workplan Lifecycle - Reference
# Workplan Lifecycle Reference
A workplan is an information object that occupies a named lifecycle state.
The stored `status` field keeps that state, while the task-flow engine derives
which other states are reachable and which exit assertions are blocking
movement. Dashboard health filters such as `needs_review` and `stalled` are
derived labels, not stored lifecycle values.
A **workplan** is a work-record kind: a structured, dependency-bearing body of
work. In State Hub it is an information object whose current position is the
stored `status` field. The task-flow engine can derive which other positions
are reachable and which exit assertions are blocking movement.
Umbrella vocabulary: [Work Records](/docs/work-records).
File convention: ADR-001 / [Workplans](/docs/workstreams).
The product term is **workplan**. **Workstream** remains a legacy compatibility
name in some fields (notably frontmatter `state_hub_workstream_id`) and
historical URLs; it refers to the same entity.
---
## Stored Lifecycle States
## Stored lifecycle states
| State | Source | Meaning |
|---|---|---|
| **proposed** | DB `status = proposed` | Plan exists, but must be reviewed against current repo state |
| **ready** | DB `status = ready` | Plan has been reviewed and is ready to execute |
| **active** | DB `status = active` | Work is in progress |
| **blocked** | DB `status = blocked` | Work cannot proceed until a dependency, decision, or input clears |
| **backlog** | DB `status = backlog` | Intentionally parked so it stays out of current work views |
| **finished** | DB `status = finished` | Implementation is complete |
| **archived** | DB `status = archived` | Historical record outside normal planning and execution |
| **proposed** | `status = proposed` | Plan exists, but must be reviewed against current repo state |
| **ready** | `status = ready` | Plan has been reviewed and is ready to execute |
| **active** | `status = active` | Work is in progress |
| **blocked** | `status = blocked` | Work cannot proceed until a dependency, decision, or input clears |
| **backlog** | `status = backlog` | Intentionally parked so it stays out of current work views |
| **finished** | `status = finished` | Implementation is complete |
| **archived** | `status = archived` | Historical record outside normal planning and execution |
Normal progression:
These values are the canonical set for workplan frontmatter, the workplan API,
consistency checks, and dashboard status filters.
Normal progression (informal path; the flow definition may constrain moves):
```text
backlog -> proposed -> ready -> active -> finished -> archived
@ -33,22 +42,37 @@ backlog -> proposed -> ready -> active -> finished -> archived
-> backlog
```
Flow definition: `flows/workplan.yaml` (`entity_type: workplan`). Notable
assertions in the live definition:
- Entering **finished** requires all child tasks in `done` or `cancel`.
- **blocked** / leaving **active** can depend on dependency workplans reaching
`finished` or `archived`.
**Residuals on finish (process, not a flow assertion yet):** before
`status: finished`, any intentional leftover work must be captured as a **live
work record** (intake with `origin: residual` + `origin_ref: <this-WP-id>`, or
a spawned child workplan / decision / engagement / register entry). Prose in
the finished file is narrative only — not the fleet backlog. See
[Work Records — Residuals](/docs/work-records#residuals-role-not-kind) and
fleet canon `work-record-types_v0.1.md` § Residuals.
---
## Health Labels
## Health labels (not stored status)
| Label | Source | Meaning |
|---|---|---|
| **needs_review** | Ready-review metadata + git diff | A `ready` workplan may be stale because relevant files changed since review |
| **stalled** | Task counts + timestamp | Work started, but there has been no meaningful progress after the threshold |
`needs_review` and `stalled` can appear beside lifecycle states. They should
not be written into workplan frontmatter or directly into the workplan
`status` field.
`needs_review` and `stalled` can appear beside lifecycle states. They are not
written into workplan frontmatter `status` and are not workplan lifecycle
values.
---
## Ready Review Metadata
## Ready review metadata
Ready workplans may include optional frontmatter:
@ -67,7 +91,17 @@ behind explicit tooling, not done silently.
---
## Flow Operations
## Relation to tasks and intakes
| Relation | What happens today |
|----------|--------------------|
| **Tasks** | Own lifecycle (`wait` / `todo` / `progress` / `done` / `cancel`). Starting real work (`todo``progress`) can activate a parent workplan that is still in `proposed`, `ready`, or `backlog`. |
| **Intake promotion** | A routed intake can be promoted into a new workplan (or task/decision/engagement) via `scripts/promote_intake.py` / `statehub promote-intake`. The intake closes as `promoted` with `promoted_to` set to the new canonical id. |
| **File backing** | Workplans originate as repo files; the hub indexes them. Manual hub-only create tools exist for bootstrap; steady-state structure is file → `fix-consistency`. |
---
## Flow operations
```text
get_flow_state(entity_type="workplan", entity_id="<uuid>")
@ -82,5 +116,15 @@ curl -X PATCH http://127.0.0.1:8000/workplans/<uuid>/ \
-d '{"status": "finished"}'
```
Workplans are never hard-deleted. Use `finished` for completed
implementation and `archived` for historical records outside normal planning.
Preferred list/update routes are under `/workplans/`. Some older
`/workstreams/` aliases were retired (410) or remain metered; see
`docs/workplan-terminology-transition.md`.
Workplans are not hard-deleted in normal operation. Use `finished` for
completed implementation and `archived` for historical records outside normal
planning.
---
*Workstation* in API/tool names means the current lifecycle label of an
information object — for workplans that label is the `status` field.

View file

@ -44,3 +44,16 @@ Use `proposed` for a new plan that still needs review, `ready` after it has
been checked against the current repo state, and `finished` when implementation
is complete. `stalled` and `needs_review` are derived health labels, not stored
frontmatter statuses.
### Residuals when finishing
If work remains after a plan is complete, **do not** leave it only as prose or
in `SCOPE.md`. Before `status: finished`, hand off each actionable residual as
a live work record:
- parkable Green/Blue → **intake** with `origin: residual`, `origin_ref: <WP-id>`
- multi-step → **new workplan** (optional promote from residual intake)
- founder gate/time → **decision** / **engagement**
Canon: `the-custodian/canon/standards/work-record-types_v0.1.md` § Residuals.
Hub index/list: State Hub (not domain-local residual files).

View file

@ -12,8 +12,12 @@ Sanctioned writes (cross-cutting coordination — not bootstrap-only):
| Use Case | Tools |
|---|---|
| **Resolving Decisions** | `resolve_decision()` |
| **Next Steps + demand signals** | `get_next_steps()` — derived steps; bumps relevance on surfaced open suggestions |
| **Suggestion backlog** | `create_suggestion()`, `vet_suggestion()`, `decline_suggestion()`, `promote_suggestion_to_task()`, `bump_suggestion_relevance()` |
| **Next Steps + demand signals** | `get_next_steps()` — derived steps (open **suggestion** signals still come from the legacy table when any remain open) |
| **Intake (work-record kind)** | `create_intake()`, `list_intakes()`, `route_intake()`, `close_intake()` — sparks/findings; promote with `statehub promote-intake` / `scripts/promote_intake.py`. **Residuals** from finished workplans are intakes (or child WPs) with `origin: residual` + `origin_ref: <WP-id>` — not a separate kind; see work-record-types § Residuals |
| **Suggestion backlog (legacy)** | `create_suggestion()`, `vet_suggestion()`, `decline_suggestion()`, `promote_suggestion_to_task()`, `bump_suggestion_relevance()`**retired (HTTP 410)**; use intake tools |
Work-record umbrella (kinds, ids, lifecycles): fleet canon
`work-record-types_v0.1.md`; dashboard reference `/docs/work-records`.
All other mutate tools are **bootstrap-only**: use them during First Session Protocol
to give a freshly-registered project its initial workplan structure.

View file

@ -97,8 +97,12 @@ curl -s -X PATCH "http://127.0.0.1:8000/tasks/<task_id>" \
**Close:**
1. Update workplan file task statuses to reflect progress
2. Log: `POST /progress/` with a summary of what changed
3. After workplan file changes, run:
2. If finishing a workplan: hand off **residuals** as live work records first
(intake with `origin: residual` + `origin_ref: <WP-id>`, or a next workplan /
decision / engagement). Do not park leftovers only in prose or `SCOPE.md`.
Canon: `the-custodian/canon/standards/work-record-types_v0.1.md` § Residuals.
3. Log: `POST /progress/` with a summary of what changed (name handoff ids)
4. After workplan file changes, run:
```bash
statehub fix-consistency
```
@ -174,6 +178,11 @@ Task description text.
Status progression: `todo` → `progress` → `done`; use `wait` for waiting/blocked work and `cancel` for stopped work.
**Residuals when finishing:** actionable leftovers become live work records
before `status: finished` — usually an intake (`origin: residual`,
`origin_ref: {WP_PREFIX}-NNNN`) or a spawned workplan. Residual is a *role*,
not a kind. Fleet list lives on State Hub, not in `SCOPE.md`.
To create a new workplan:
1. Write the file following the format above
2. Run `statehub fix-consistency` locally; ask the operator only if the CLI or

View file

@ -66,6 +66,14 @@ If no workplans: follow First Session Protocol (`first-session.md`).
> see `workplan-convention.md` (compatibility footnote).
**Session close:**
1. Update workplan/task statuses in repo files.
2. If marking a workplan **finished**: hand off residuals as **live work
records** first (intake with `origin: residual` + `origin_ref: <WP-id>`, or
a child workplan / decision / engagement). Do not leave actionable leftovers
only as prose or in `SCOPE.md`. See work-record-types § Residuals.
3. Log progress (below).
4. `statehub fix-consistency` when workplan/queue files changed.
With MCP tools:
```
add_progress_event(summary="...", topic_id="{TOPIC_ID}", workplan_id="<uuid>")

View file

@ -38,6 +38,22 @@ state_hub_task_id: "<uuid>" # written by fix-consistency — do not edit
Status progression is `todo` → `progress` → `done`; use `wait` for waiting or
blocked work and `cancel` for stopped work.
### Residuals (role, not kind)
When finishing a workplan, **actionable leftovers must become live work
records** before `status: finished`. Residual is not a registered kind and
must not be parked only in `SCOPE.md` or finished-file prose.
| Shape | Capture as | Links |
| --- | --- | --- |
| Small Green/Blue parkable | intake (queue YAML / `*-IN-*`) | `origin: residual`, `origin_ref: {WP_PREFIX}-NNNN` |
| Multi-step | next workplan | name parent WP; optional promote from residual intake |
| Founder gate / time | decision / engagement | same origin fields when from residual intake |
Fleet listing of residuals is a State Hub concern (`list_intakes` + origin
filters; planned `statehub residuals`). Canon:
`the-custodian/canon/standards/work-record-types_v0.1.md` § Residuals.
Workplan frontmatter carries `state_hub_workstream_id` — a legacy field name
kept for compatibility; it holds the hub workplan UUID and is written by
fix-consistency. Do not edit or rename it.

View file

@ -21,6 +21,10 @@ work structure in the hub when a workplan file is the canon.
task updates. Use `update_task_status(...)` for one-off changes.
5. Close with one concise `add_progress_event(...)`, then run the repo's
`make fix-consistency REPO=<repo-slug>` command when workplan files changed.
6. If finishing a workplan with leftovers: create **residual** work records
first (intake with `origin: residual` + `origin_ref: <WP-id>`, or a child
workplan). Residual is a role, not a kind; do not leave backlog only in
finished-file prose or `SCOPE.md`. Canon: work-record-types § Residuals.
## High-Frequency MCP Signatures