diff --git a/.claude/rules/workplan-convention.md b/.claude/rules/workplan-convention.md index 2eefa9f..3f7995f 100644 --- a/.claude/rules/workplan-convention.md +++ b/.claude/rules/workplan-convention.md @@ -11,6 +11,18 @@ Use `proposed` for a newly drafted plan, `ready` after review against current repo state, and `finished` when implementation is complete. `stalled` and `needs_review` are derived health labels, not stored statuses. +Optional frontmatter (STATE-WP-0092): + +```yaml +flavor: planning | implementation | refactoring | extension | residual +depends_on: + - STATE-WP-0092 +``` + +Unset `flavor` is not residual. Do not implement `flavor: residual` unless +demand or risk has promoted it to another flavor. `depends_on` lists +blocker **workplan** ids; that is the field C-20 indexes. + Closed workplans may be moved to `workplans/archived/` with a completion-date prefix: `YYMMDD-CUST-WP-NNNN-.md`. The frontmatter id remains unchanged; the prefix is only for quick visual reference. diff --git a/AGENTS.md b/AGENTS.md index 5c99d2d..5c04338 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -102,9 +102,10 @@ curl -s -X PATCH "http://127.0.0.1:8000/tasks/" \ **Close:** 1. Update workplan file task statuses to reflect progress 2. If finishing a workplan: hand off **residuals** as live work records first - (intake with `origin: residual` + `origin_ref: `, or a next workplan / - decision / engagement). Do not park leftovers only in prose or `SCOPE.md`. - Canon: `canon/standards/work-record-types_v0.1.md` § Residuals. + (intake with `origin: residual` + `origin_ref: `, or a next workplan + with `flavor: residual`). Do not park leftovers only in prose or `SCOPE.md`. + Do not implement residuals unless promoted. Canon: + `canon/standards/work-record-types_v0.1.md` § Flavor. 3. Log: `POST /progress/` with a summary of what changed (name handoff ids) 4. After workplan file changes, run: ```bash @@ -206,6 +207,8 @@ owner: codex topic_slug: ... created: "YYYY-MM-DD" updated: "YYYY-MM-DD" +flavor: planning | implementation | refactoring | extension | residual +depends_on: [] # workplan ids this plan waits on (STATE-WP-0092) state_hub_workstream_id: "" # written by fix-consistency — do not edit --- ``` @@ -233,9 +236,10 @@ Status progression: `todo` → `progress` → `done`; use `wait` for waiting/blo **Residuals when finishing:** actionable leftovers become live work records before `status: finished` — usually an intake (`origin: residual`, -`origin_ref: CUST-WP-NNNN`) or a spawned workplan. Residual is a *role*, -not a kind. Fleet list lives on State Hub, not in `SCOPE.md`. Canon: -`canon/standards/work-record-types_v0.1.md` § Residuals. +`origin_ref: CUST-WP-NNNN`) or a spawned workplan with `flavor: residual`. +Residual is a **flavor**, not a kind. Default hub open-workplan views omit +residuals; do not implement them unless demand or risk promotes the flavor. +Canon: `canon/standards/work-record-types_v0.1.md` § Flavor. To create a new workplan: 1. Write the file following the format above diff --git a/canon/standards/schemas/work-records/spine.schema.json b/canon/standards/schemas/work-records/spine.schema.json index 76f42d9..afc3aa1 100644 --- a/canon/standards/schemas/work-records/spine.schema.json +++ b/canon/standards/schemas/work-records/spine.schema.json @@ -19,6 +19,12 @@ "type": "array", "items": { "type": "string", "pattern": "^[a-z0-9-]+$" } }, + "flavor": { + "enum": ["planning", "implementation", "refactoring", "extension", "residual"] + }, + "flavor_promotion_reason": { + "enum": ["demand", "risk"] + }, "owner": { "type": "string", "minLength": 2 @@ -32,7 +38,14 @@ "owner": { "$ref": "#/$defs/owner" }, "tags": { "$ref": "#/$defs/tags" }, "uuid": { "$ref": "#/$defs/uuid" }, - "created_at": { "$ref": "#/$defs/date" } + "created_at": { "$ref": "#/$defs/date" }, + "flavor": { "$ref": "#/$defs/flavor" }, + "flavor_promotion_reason": { "$ref": "#/$defs/flavor_promotion_reason" }, + "flavor_promoted_from": { "$ref": "#/$defs/flavor" }, + "depends_on": { + "type": "array", + "items": { "type": "string", "minLength": 3 } + } } } } diff --git a/canon/standards/work-record-types.yaml b/canon/standards/work-record-types.yaml index 1c78e6f..b3d49c8 100644 --- a/canon/standards/work-record-types.yaml +++ b/canon/standards/work-record-types.yaml @@ -1,7 +1,7 @@ # Machine copy of canon/standards/work-record-types_v0.1.md (kind registry). # CI and fix-consistency validate id patterns against this file. # New kinds/prefixes land here by canon PR only. -version: "0.1" +version: "0.2" status: active kinds: - kind: workplan @@ -105,14 +105,25 @@ kinds: spine_fields: required: [id, kind, lane, status, owner, repo] hub_assigned: [uuid] - optional: [tags, created, updated] + optional: [tags, created, updated, flavor, flavor_promotion_reason, flavor_promoted_from, depends_on] lanes: [green, blue, yellow, orange, red] +flavors: + - planning + - implementation + - refactoring + - extension + - residual +flavor_promotion_reasons: + - demand + - risk +# Flavor is a bucket on workplan and task, orthogonal to kind. residual is a +# flavor, not a kind. Unset flavor is not residual. See +# work-record-types_v0.1.md § Flavor. tags: derived: [stalled, stale, overdue-decision, budget-breached, orphaned] policy: [automatable, needs-human, unclear-implementation, red-adjacent, compliance-relevant, residual] -# Residual is a *role*, not a kind: capture as intake/workplan/decision/… -# with origin: residual|handoff and origin_ref: . See -# work-record-types_v0.1.md § Residuals. +# origin: residual|handoff remains provenance on intakes and promoted children. +# Default open-workplan views key off flavor: residual, not origin. origin_values_recommended: residual: residual handoff: handoff diff --git a/canon/standards/work-record-types_v0.1.md b/canon/standards/work-record-types_v0.1.md index 8dc5e02..d62c859 100644 --- a/canon/standards/work-record-types_v0.1.md +++ b/canon/standards/work-record-types_v0.1.md @@ -4,16 +4,17 @@ type: standard title: "Work Record Types & Identity (Fleet) v0.1" domain: custodian status: accepted -version: "0.1" +version: "0.2" owner: the-custodian -revision: "accepted-1" -last_reviewed: "2026-08-31" +revision: "accepted-2" +last_reviewed: "2026-09-14" review_interval: 6m created: "2026-07-20" -updated: "2026-08-23" +updated: "2026-09-14" scope: fleet related_workplans: - CUST-WP-0060 + - STATE-WP-0092 supersedes: none machine_copy: canon/standards/work-record-types.yaml --- @@ -24,6 +25,9 @@ machine_copy: canon/standards/work-record-types.yaml > `research/WorkOrchestrationArchitectureDraft.md` v0.2 (founder-reviewed > 2026-07-20). Extends — does not replace — > `workplan-terminology-fleet_v0.1.md` and ADR-001/ADR-005. +> +> Flavor and residual default-exclusion ratified 2026-09-14 by founder +> instruction to execute STATE-WP-0092. Flavor is orthogonal to kind. ## Purpose @@ -148,7 +152,27 @@ per-work-kind gates (e.g. compliance tasks cannot exit `progress` without an evidence link). Profiles are YAML in repos, in the same reconciliation loop. -## Residuals (role, not kind) +## Flavor (bucket, not kind) + +**Flavor** is a closed list on **workplan** and **task**, orthogonal to +kind and to lifecycle `status`. It says *what kind of demand this is*, +not whether it is open. + +| Flavor | Meaning | +| --- | --- | +| `planning` | analysis, design, policy, sequencing | +| `implementation` | building the accepted requirement | +| `refactoring` | internal change that does not add capability | +| `extension` | additive change to an existing capability | +| `residual` | leftover after a parent finished; not deemed as valuable as the main functional and non-functional requirements | + +Unset flavor is **not** residual. Historic records without `flavor:` stay +relevant until backfill classifies them (`CUST-WP-0072`). Do not +auto-classify. + +Unknown flavor values fail closed (rejected on write; consistency WARN). + +### Residuals (flavor, plus provenance role) A **residual** is work intentionally left after a workplan (or large task bundle) finishes. It is **not** a registered kind — inventing a parallel @@ -156,29 +180,55 @@ bundle) finishes. It is **not** a registered kind — inventing a parallel prose is a process defect. Residuals must be **live work records** so the hub can list them across repos and domains. +On workplans and tasks the live classification is `flavor: residual`. +`origin: residual` (or `handoff`) on intakes and promoted children remains +**provenance**, not the default-view switch. + | Residual shape | Capture as | Required links | | --- | --- | --- | | Small Green/Blue follow-up, parkable | **intake** (e.g. AWQ / `*-IN-*`) | `origin: residual`, `origin_ref: ` | -| Multi-step / dependency-bearing | **workplan** (spawn next WP) | body or frontmatter names parent WP; optional `origin`/`origin_ref` when promoted from intake | +| Multi-step / dependency-bearing | **workplan** with `flavor: residual` | body or frontmatter names parent WP; `origin`/`origin_ref` when spawned from a finished parent | | Needs founder choice | **decision** | same origin fields when created from residual intake | | Needs founder time window | **engagement** | same | | Persistent gap / risk | **register-entry** (risk, tech debt, …) | cross-link parent WP in notes | +**Default views omit residuals.** State Hub open-workplan lists +(`/state/summary` `open_workplans`, `/state/next_steps`, `/state/deps`, +dashboard open widgets) and agent “should we implement this?” **do not +consider** `flavor: residual` unless an explicit include is set +(`include_residuals=true` or `flavor=residual`). Residuals are not equal +open demand. Totals still report `residual_open` so the count cannot hide. + +**Promotion** is a first-class transition: `flavor: residual` → +`planning` | `implementation` | `refactoring` | `extension` when **demand** +or **risk** meets the leftover. Record `flavor_promotion_reason: +demand | risk` and optional `flavor_promoted_from: residual` in the file, +then `fix-consistency`. After promotion the record is no longer residual +and re-enters the default view. + **Close discipline for finished workplans:** 1. Short residual **narrative** may remain under the closing task (human context). 2. **Before** `status: finished`, each residual that is still actionable - becomes a live record (intake and/or child workplan). Prose alone is not - the backlog. + becomes a live record (intake and/or child workplan with + `flavor: residual`). Prose alone is not the backlog. 3. Progress milestone may name the handoff ids. 4. `statehub fix-consistency` so the index (`WORK-RECORDS.md`, hub) reflects the handoff. -**Fleet list (future CLI):** filter open/vetted/routed intakes (and ready/ -active workplans) with `origin ∈ {residual, handoff}` and optional -`topic_id` / `repo` / `origin_ref`. Implementation home for that query is -**state-hub** (`statehub residuals` / API), not domain repos. +**Fleet list:** filter `flavor: residual` on workplans/tasks and intakes +with `origin ∈ {residual, handoff}` via State Hub (`GET /workplans/?flavor=residual`, +`GET /state/summary?include_residuals=true`). Implementation home is +**state-hub**, not domain-local residual files. + +### `depends_on` (workplan frontmatter) + +Workplan frontmatter `depends_on` is the canonical list of **workplan ids** +this plan waits on. State Hub indexes those edges (C-20). Legacy keys +`depends_on_workplans` and `depends_on_tasks` remain aliases until a +legacy-meter retires them. Task-block `depends_on` continues to name +sibling tasks; it is not a substitute for workplan-level edges. ## Source files, index, and views diff --git a/canon/standards/workplan-terminology-fleet_v0.1.md b/canon/standards/workplan-terminology-fleet_v0.1.md index 495b834..9c79093 100644 --- a/canon/standards/workplan-terminology-fleet_v0.1.md +++ b/canon/standards/workplan-terminology-fleet_v0.1.md @@ -4,19 +4,20 @@ type: standard title: "Workplan Terminology (Fleet) v0.1" domain: custodian status: accepted -version: "0.2" +version: "0.3" owner: the-custodian -revision: "accepted-1" -last_reviewed: "2026-08-31" +revision: "accepted-2" +last_reviewed: "2026-09-14" review_interval: 6m created: "2026-07-08" -updated: "2026-07-20" +updated: "2026-09-14" scope: fleet related_workplans: - CUST-WP-0055 - STATE-WP-0054 - STATE-WP-0069 - CUST-WP-0060 + - STATE-WP-0092 supersedes: none --- @@ -63,6 +64,19 @@ intake kind (state-hub suggestions table: read-only legacy pending close-out). This file keeps its `_v0.1` name for reference stability; the frontmatter `version` field is authoritative. +## Flavor and depends_on (v0.3 addendum, STATE-WP-0092) + +Workplans and tasks may carry **flavor**: `planning`, `implementation`, +`refactoring`, `extension`, or `residual`. Flavor is a bucket, not a kind +and not a status. `residual` leftovers are live records but are **not** +equal to main functional/non-functional demand. Default State Hub open +views omit them until demand or risk promotes the flavor. + +Workplan frontmatter `depends_on` is the canonical list of blocker +workplan ids. Prefer that spelling over `depends_on_workplans`. + +Normative detail: `work-record-types_v0.1.md` § Flavor. + Use **workplan** in human-facing prose: `SCOPE.md`, `AGENTS.md`, `INTENT.md`, README, workplan bodies, operator runbooks, and agent session guidance.