215 lines
7.7 KiB
Markdown
215 lines
7.7 KiB
Markdown
---
|
||
id: STATE-WP-0080
|
||
type: workplan
|
||
title: "statehub register: project-repository flavor awareness"
|
||
domain: infotech
|
||
repo: state-hub
|
||
status: active
|
||
owner: codex
|
||
topic_slug: infotech
|
||
created: "2026-08-16"
|
||
updated: "2026-08-16"
|
||
parent_project: prj-state-hub-retirement
|
||
parent_workplan: SHR-WP-0001
|
||
related:
|
||
- CFED-WP-0001
|
||
- SHR-WP-0001
|
||
state_hub_workstream_id: "bbfce36a-0b19-462f-af78-167f9eb89b86"
|
||
---
|
||
|
||
# statehub register: project-repository flavor awareness
|
||
|
||
## Goal
|
||
|
||
Make `statehub register` aware of the `prj-` project-repository flavor so that
|
||
scaffolding a project repo produces conformant files instead of files the
|
||
governing standard calls an anti-pattern.
|
||
|
||
This is the residual recorded in `SHR-WP-0001-T01`:
|
||
|
||
> Residual tooling gap: `statehub register` still scaffolds `INTENT.md` for
|
||
> ordinary repos — capture under a state-hub child workplan when T05 maps
|
||
> implementation streams (do not invent `INTENT.md` on `prj-` repos).
|
||
|
||
It has now been hit twice — once when founding `prj-state-hub-retirement`, and
|
||
again on 2026-08-16 founding `prj-canon-federation`, where the scaffolded
|
||
`INTENT.md` and a generic `PRJ-WP-0001-statehub-bootstrap.md` both had to be
|
||
deleted by hand before the first `fix-consistency` run.
|
||
|
||
## Root cause
|
||
|
||
`statehub_register.py` (872 lines) contains **no reference to
|
||
`.repo-classification.yaml`, `category`, or `repo_flavor`**. It has no way to
|
||
distinguish a project repository from a durable product repository, so:
|
||
|
||
- `KEY_CONTEXT_FILES` (`:25`) lists `INTENT.md` as a primary context file;
|
||
- `:248` writes `INTENT.md` unconditionally when absent;
|
||
- `:786`–`:790` treat a missing intent as a hard error, prompting interactively
|
||
and exiting with `ERROR: Intent is required to create INTENT.md.`;
|
||
- `:269` writes `{WP_PREFIX}-0001-statehub-bootstrap.md` with a prefix defaulted
|
||
from the repo slug (`:78`, `_default_wp_prefix`), yielding `PRJ-WP-` for every
|
||
`prj-` repo rather than a project-derived prefix;
|
||
- the generated `.custodian-brief.md` (`:634`) and templates (`:461`, `:509`,
|
||
`:525`, `:569`) all instruct agents to read `INTENT.md`.
|
||
|
||
The governing standard is
|
||
`the-custodian/canon/standards/project-repository-flavor_v0.1.md`, which states:
|
||
|
||
> Tooling that scaffolds repositories (e.g. `statehub register`) MUST treat
|
||
> `GOAL.md` + `repo_flavor: project` as sufficient purpose documentation for
|
||
> `prj-` repos and MUST NOT require inventing an `INTENT.md` that pretends the
|
||
> project is a permanent product.
|
||
|
||
and names shipping both `INTENT.md` and `GOAL.md` an explicit anti-pattern.
|
||
|
||
## Detect repository flavor
|
||
|
||
```task
|
||
id: STATE-WP-0080-T01
|
||
status: todo
|
||
priority: high
|
||
state_hub_task_id: "6b01a939-7d60-4a0c-90db-af8e31c45359"
|
||
```
|
||
|
||
Give the register path a flavor signal. Read `.repo-classification.yaml`
|
||
`category` when present, and `GOAL.md` frontmatter `repo_flavor` as a secondary
|
||
signal; fall back to the `prj-` directory/slug prefix. Surface the result as a
|
||
single value threaded through inference and scaffolding.
|
||
|
||
Treat classification as authoritative when present and disagreeing with the slug
|
||
prefix, and warn on the mismatch rather than guessing silently.
|
||
|
||
## Scaffold GOAL.md instead of INTENT.md for project repos
|
||
|
||
```task
|
||
id: STATE-WP-0080-T02
|
||
status: wait
|
||
priority: high
|
||
state_hub_task_id: "bd6a9069-b455-4f5e-b1a5-4a87d014e8f6"
|
||
```
|
||
|
||
For project-flavor repos:
|
||
|
||
- do not write `INTENT.md`, and do not prompt for intent (`:786`–`:790`);
|
||
- accept an existing `GOAL.md` as sufficient purpose documentation;
|
||
- when `GOAL.md` is absent, scaffold one from a template carrying the four
|
||
sections the standard requires — Outcome, Invariants, Success gates, Project
|
||
retirement — plus the recommended frontmatter (`repo`, `repo_flavor`,
|
||
`project_status`, `started`, `reviewed`);
|
||
- error only if neither `GOAL.md` nor enough input to generate one exists.
|
||
|
||
For all other flavors, behaviour is unchanged.
|
||
|
||
## Fix workplan prefix inference
|
||
|
||
```task
|
||
id: STATE-WP-0080-T03
|
||
status: wait
|
||
priority: medium
|
||
state_hub_task_id: "b141b378-10d0-4865-a67b-159806bcf037"
|
||
```
|
||
|
||
`_default_wp_prefix` derives `PRJ-WP-` from any `prj-`-prefixed slug, which is
|
||
wrong for every project repo: the standard requires a prefix derived from the
|
||
project, not the flavor marker (`SHR-WP-` for State Hub Retirement, `CFED-WP-`
|
||
for canon federation).
|
||
|
||
For project-flavor repos, strip the `prj-` marker before deriving, and prompt or
|
||
require `--wp-prefix` rather than emitting a flavor-derived default. A prefix
|
||
collision across two `prj-` repos is the failure this prevents.
|
||
|
||
## Decide the bootstrap workplan for project repos
|
||
|
||
```task
|
||
id: STATE-WP-0080-T04
|
||
status: wait
|
||
priority: medium
|
||
state_hub_task_id: "d933ae91-ad40-4a88-9ce3-90872cd1f3d7"
|
||
```
|
||
|
||
`:269` writes a generic `statehub-bootstrap` workplan. For project repos this
|
||
competes with the foundation workplan the project actually needs — in both real
|
||
cases it was deleted immediately.
|
||
|
||
Either skip it for project flavor, or replace it with a foundation-workplan
|
||
template shaped by the standard (confirm conventions, inventory participants,
|
||
map child workplans, define gates). Prefer skipping unless T05's template work
|
||
shows the foundation shape is genuinely reusable.
|
||
|
||
## Update generated templates and briefs
|
||
|
||
```task
|
||
id: STATE-WP-0080-T05
|
||
status: wait
|
||
priority: medium
|
||
state_hub_task_id: "9eb5ddb5-28d9-4244-8a4f-8fe2a50b5d27"
|
||
```
|
||
|
||
Make every generated artifact flavor-correct:
|
||
|
||
- `KEY_CONTEXT_FILES` (`:25`) — include `GOAL.md`;
|
||
- `.custodian-brief.md` orientation line (`:634`) — `GOAL.md` for project repos;
|
||
- `AGENTS.md` / `CLAUDE.md` / `scripts/project_rules/` templates (`:461`,
|
||
`:509`, `:525`, `:569`) — session start order `GOAL.md` → `SCOPE.md` →
|
||
history → active workplans, per the standard's agent conventions;
|
||
- `_ensure_context_files` (`:431`) — do not treat missing `INTENT.md` as a gap
|
||
on project repos.
|
||
|
||
Confirm `make update-agent-instructions` regenerates conformant files for an
|
||
existing `prj-` repo, not just at first registration.
|
||
|
||
## Add a conformance check
|
||
|
||
```task
|
||
id: STATE-WP-0080-T06
|
||
status: wait
|
||
priority: low
|
||
state_hub_task_id: "3467ae11-1301-46ab-9e7e-75c4f55f53fe"
|
||
```
|
||
|
||
The standard ships a conformance checklist that is currently only human-checked.
|
||
Add a consistency check that flags a project-flavor repo which ships `INTENT.md`
|
||
alongside `GOAL.md`, is missing a required file, or uses a flavor-derived
|
||
workplan prefix.
|
||
|
||
Advisory severity is sufficient — this is a convention violation, not data
|
||
corruption. Follow the existing `C-NN` numbering and register it in the
|
||
consistency-check catalog.
|
||
|
||
## Cover with tests
|
||
|
||
```task
|
||
id: STATE-WP-0080-T07
|
||
status: wait
|
||
priority: medium
|
||
state_hub_task_id: "126ddd07-df9d-4b65-a651-fff0ad2d4074"
|
||
```
|
||
|
||
Extend `tests/test_statehub_register_cli.py`:
|
||
|
||
- registering a `prj-` repo with `category: project` writes `GOAL.md`, no
|
||
`INTENT.md`, and no flavor-derived prefix;
|
||
- registering an ordinary product repo is byte-identical to today's output
|
||
(regression guard — this workplan must not change durable-repo behaviour);
|
||
- classification/slug mismatch warns rather than silently choosing;
|
||
- re-running register on an existing conformant `prj-` repo is idempotent.
|
||
|
||
## Carry the fix forward past State Hub retirement
|
||
|
||
```task
|
||
id: STATE-WP-0080-T08
|
||
status: wait
|
||
priority: medium
|
||
state_hub_task_id: "405526b7-b133-4746-aab5-6301c1a0b72e"
|
||
```
|
||
|
||
State Hub is being retired (`STATE-WP-0079`, `prj-state-hub-retirement`).
|
||
Repository scaffolding and representation are slated to land in `repo-manager`.
|
||
|
||
Record where this flavor logic belongs after retirement and link it to the
|
||
inventory disposition for the register path, so the fix is not stranded in a
|
||
component scheduled for removal. If `repo-manager` is close enough to take it,
|
||
prefer implementing there and leaving `statehub register` with a thin
|
||
flavor-guard rather than a full templating path.
|
||
|
||
Coordinate through `SHR-WP-0001` rather than duplicating its task list.
|