Files
state-hub/docs/workplan-state-model-proposal.md

6.0 KiB

Workplan State Model Proposal

Date: 2026-05-17 Status: proposed

Problem

State Hub currently mixes three different vocabularies for the same lifecycle:

  • Workstream API/schema: todo, active, blocked, completed, archived
  • Workplan consistency scripts: active, completed, archived
  • Dashboard overview modes: active, accepted, finished, blocked, stalled, oldies

This makes file-backed workplans harder to reason about. A workplan can be a good proposal but not ready to execute; a ready workplan can become stale after the repo changes; parked backlog work should not clutter the current work view.

Task status should remain separate. Tasks can keep using todo, in_progress, blocked, done, and cancelled.

Proposed Canonical Workplan States

These states should be valid in workplan frontmatter, the workstream API, the database, consistency checks, and the dashboard.

State Meaning Current-view behavior
proposed A plan exists, but it must be reviewed against the current repo state before execution. Hidden from active execution views by default; visible in planning/review views.
ready The plan has been reviewed and is ready to execute against the current repo state. Visible in "ready to pick up" views.
active Work has started and should appear in current work views. Visible in current execution views.
blocked Work cannot proceed until a dependency, decision, or human intervention clears. Visible in current execution views and blocked views.
backlog Intentionally parked for later; not currently being reviewed or executed. Hidden from current work views by default.
finished Implementation is complete and the workplan is closed. Hidden from current work views; visible in completed/history views.
archived Historical record, no longer part of normal planning or current execution. Hidden except in archive/history views.

Recommended normal path:

backlog -> proposed -> ready -> active -> finished -> archived
                    \          \
                     \          -> blocked -> active
                      -> backlog

Staleness And Health Labels

stalled, oldies, and stale should be derived health labels, not stored lifecycle states.

Label Derivation Recommended UI name
stale ready workplan was reviewed against an older repo state. Needs review
stalled active or blocked workplan has had no meaningful progress after a threshold. Stalled
oldies Old planning item with no progress. Replace with proposed, backlog, or needs review depending on intent.

For ready workplans, add optional frontmatter:

reviewed_at: "YYYY-MM-DD"
reviewed_by: "human-or-agent"
reviewed_against_commit: "<git-sha>"
context_paths:
  - "path/or/glob"

Initial consistency behavior:

  • If a workplan is ready and reviewed_against_commit differs from repo HEAD, report a warning: "ready workplan may be stale".
  • If context_paths are present, only warn when files under those paths changed since reviewed_against_commit.
  • In --fix mode, optionally move stale ready workplans back to proposed and record a progress event. This should be guarded behind an explicit flag at first, because automatic demotion can be surprising.

UI Cleanup

Replace the current overview mode set:

active, accepted, finished, blocked, stalled, oldies

with stored status filters plus health filters:

proposed, ready, active, blocked, backlog, finished, archived
needs review, stalled

Specific cleanup:

  • Rename accepted to finished if it currently means DB completed.
  • Stop using finished as a derived "no open tasks" pseudo-state. Show that as a badge such as all tasks done or ready to close.
  • Remove oldies as a lifecycle term. It is charming, but it blurs backlog, stale proposal, and neglected active work into one bucket.
  • Keep stalled as a health filter/badge, not as a status value.

Compatibility And Migration

For one migration window, accept legacy aliases in parsers and API clients:

Legacy value Canonical value
todo ready for workstreams with no started tasks; otherwise active
completed finished
accepted finished
oldies not stored; classify as proposed or backlog manually
stalled not stored; derive from timestamps/progress

The consistency engine should normalize legacy file values before comparison, but write back canonical values when it changes files.

Implementation Work

  1. Add a shared WORKPLAN_STATUSES / WORKSTREAM_STATUSES constant used by API schemas, consistency scripts, validation scripts, and dashboard code.
  2. Update api/schemas/workstream.py to allow the canonical state set.
  3. Update scripts/consistency_check.py and scripts/validate_repo_adr.py: accept the canonical states, map legacy aliases, and add stale-ready checks.
  4. Add a migration that rewrites existing DB values: completed -> finished; classify todo as ready or active.
  5. Update dashboard overview modes and docs: stored statuses become filters; stalled and needs review become health filters.
  6. Update project registration templates and AGENTS/CLAUDE guidance so new repos use the canonical frontmatter states.
  7. Add tests for parsing, normalization, stale-ready detection, API validation, and dashboard filter classification.

Acceptance Criteria

  • A file-backed workplan can use proposed, ready, active, blocked, backlog, finished, or archived without consistency warnings.
  • Dashboard labels match stored lifecycle states and do not invent lifecycle terms.
  • stalled and needs review appear as derived health labels.
  • A ready workplan can be flagged as stale after relevant repo changes.
  • Legacy completed and todo workstreams are migrated or normalized without breaking existing data.