T-5Z0H-lint-status-enum-strings-in-prose
Status: closed/superseded · Impact: medium · Complexity: small
Auto-generated from a /sdlc:task-work post-mortem. Review and
promote to open/ready before picking up.
Status-shaped string tokens (planning/needs-definition,
open/ready, closed/done, etc.) appear in dozens of prose files
under apps/sdlc/lib/model/entities/ and apps/sdlc/skills/.
Nothing prevents a typo or a stale spelling from sitting in prose
indefinitely — the drift only bites when a script consumes that exact
string. A small linter under .claude/skills/project-check/ that
asserts every status-shaped token against the task schema’s status
enum would catch this class of drift on every project-check tick.
| Location | Role today |
|---|---|
apps/sdlc/lib/model/entities/task/schema.ts#TaskSchema | Single source of truth for the status enum (Zod z.enum). |
apps/sdlc/lib/model/entity.ts#loadEntitySchema | Registry projection that exposes each entity’s Zod schema as JSON; how existing checks read schemas. |
.claude/skills/project-check/ | Houses the bun-TS check_*.ts linters run by /sdlc:project-check; none checks status tokens in prose. |
apps/sdlc/lib/model/entities/ | Entity prose (.md) and scripts (.ts) carry status-shaped tokens with no guard. |
apps/sdlc/skills/ | Same exposure across skill docs and scripts. |
Proposed
Section titled “Proposed”A new .claude/skills/project-check/check_status_enum_prose.ts
script that:
- Loads the canonical status enum from the task schema
(
apps/sdlc/lib/model/entities/task/schema.ts), via the registry’sloadEntitySchemaprojection ascheck_entities.tsdoes. - Scans every
.mdand.tsfile underapps/sdlc/lib/model/entities/andapps/sdlc/skills/for tokens matching the status-shape regex (e.g.\b(planning|open|in-progress|closed)/[a-z-]+\bplus barein-progress). - Reports any token that is not in the enum, with file path and line number.
- Exits non-zero on any unknown token.
Wire it into .claude/skills/project-check/SKILL.md so each
/sdlc:project-check run includes the gate.
Approach
Section titled “Approach”- Author the script as a bun-TS
check_*.tslike the existing checks in.claude/skills/project-check/. - Run it once against the current tree, fix whatever drift it
surfaces, then wire it into
project-check/SKILL.md. - Add a
check_status_enum_prose.test.tsalongside the existing per-check tests in.claude/skills/project-check/tests/.
Files to touch
Section titled “Files to touch”| Location | Kind | Change |
|---|---|---|
.claude/skills/project-check/check_status_enum_prose.ts | new | The status-enum prose linter. |
.claude/skills/project-check/SKILL.md | modify | List the new check. |
.claude/skills/project-check/tests/check_status_enum_prose.test.ts | new | Clean-tree and deliberate-typo cases. |
Acceptance criteria
Section titled “Acceptance criteria”- AC-1: A fresh
/sdlc:project-checkinvocation runs the new status-enum check and exits 0 on a clean tree. - AC-2: Introducing a deliberate typo (e.g.
planning/need-definition) into any tracked.mdor.tsfile underapps/sdlc/lib/model/entities/orapps/sdlc/skills/causes the check to exit non-zero with the file path and line number. - AC-3: No status-enum drift remains in the tree after this task ships (the first run’s findings are fixed in the same PR).
Out of scope
Section titled “Out of scope”- Linting status strings in user-authored docs under
docs/planning/<type>/— those are validated by the frontmatter validator already. - Other prose-invariant linting (covered by separate tasks).
Dependencies
Section titled “Dependencies”- none
Discovery context
Section titled “Discovery context”Spawned by a /sdlc:task-work post-mortem of
T-4W64-extract-ensure-ready-mutate-script on 2026-05-21, after a
stale proposed/needs-definition token sat unnoticed in
implementation-ready.md: the skill’s test harness asserted the same
misspelled string, so prose and tests were internally consistent while
both disagreed with the schema — the schema was never consulted. That
instance is fixed; the class of drift is still unguarded.