Skip to content

Audit applications.status against the union, not just the typed module - #324

Merged
ProfessorPolymorphic merged 1 commit into
mainfrom
fix/registry-status-taxonomy
Jul 28, 2026
Merged

Audit applications.status against the union, not just the typed module#324
ProfessorPolymorphic merged 1 commit into
mainfrom
fix/registry-status-taxonomy

Conversation

@ProfessorPolymorphic

@ProfessorPolymorphic ProfessorPolymorphic commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

Rescoped. This PR originally fixed the stale STATUS_OPTIONS list — #323 landed that fix first, so everything duplicated has been dropped. What's left is the one part #323 doesn't cover.

The remaining gap

#323 closed the write path: the admin form is a select over PROJECT_STATUSES, and both registry endpoints 400 on anything outside the union. It did not close the read path — the rows already in the table.

npm run verify:portfolio reads lib/portfolio.ts, the typed seed source. applications.status is what /portfolio actually renders from, it's plain TEXT with no CHECK (deliberately — ADR 0001 makes a new state a re-seed rather than a migration), and publicStageFromStatus() buckets anything unrecognised as exploring. So a status that predates the constraint, or arrives via a hand-run UPDATE, renders as Exploring and no check sees it. #323 verified remote dev and prod by hand and found them clean; this is the check that means nobody has to do that again.

What changed

  • verify:portfolio reads applications.status and errors on any value outside the union. It needs a live database, so it runs only when DATABASE_URL is set — CI has none and prints that it skipped, rather than implying it passed. Run it against dev or prod.
  • VerificationProblem gains an optional observedStatus, so the report names the offending value. claimedStatus is pinned to ProjectStatus — which is precisely what a bad row doesn't have.
  • Two /docs/api-reference param descriptions that Make the ADR 0001 ladder the only lifecycle vocabulary #323's 400 outdated (the PATCH one still said out-of-union values "write successfully"; the POST one didn't mention the constraint at all).
  • The admin guide's status InfoBox now points at the audit as the way to find pre-taxonomy rows in bulk, instead of only describing the per-record select behaviour.

Verification

Against a local database: clean at 29 rows. A seeded Planned row is reported as [ERROR] stratplan (Planned) naming the value and the fix, and clears when the row goes. npm run build, npm run lint, and npm run verify:portfolio all pass.

🤖 Generated with Claude Code

#323 closed the write path — the admin form is a select over
PROJECT_STATUSES and both registry endpoints 400 on anything outside the
union. What neither it nor verify:portfolio covers is the rows already
in the table: the verifier reads lib/portfolio.ts, the typed seed
source, so a status that predates the constraint (or arrives by a
hand-run UPDATE) is invisible to it while publicStageFromStatus() files
it under "exploring" and /portfolio renders it as Exploring. #323
checked remote dev and prod by hand and found them clean; this is the
check that means nobody has to do that again.

verify:portfolio now reads applications.status directly and errors on
any value outside the union. It needs a live database, so it runs only
when DATABASE_URL is set — CI has none and says it skipped rather than
implying it passed. VerificationProblem gains an optional
observedStatus so the report can name the offending value; claimedStatus
is pinned to ProjectStatus, which is exactly what a bad row doesn't
have.

Also corrects two API-reference param descriptions that #323's 400
outdated, and points the admin guide's status InfoBox at the audit as
the way to find pre-taxonomy rows in bulk.

Verified against a local database: clean at 29 rows; a seeded `Planned`
row is reported as an error naming "Planned", and clears when the row
goes. build, lint, and verify:portfolio pass.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@ProfessorPolymorphic
ProfessorPolymorphic force-pushed the fix/registry-status-taxonomy branch from 5797b48 to f13b859 Compare July 28, 2026 17:55
@ProfessorPolymorphic ProfessorPolymorphic changed the title Make the registry status field speak the ADR 0001 taxonomy Audit applications.status against the union, not just the typed module Jul 28, 2026
@github-actions

Copy link
Copy Markdown

Vendored strategic-plan submodule is behind upstream

The vendored submodule pointer at vendor/strategic-plan is pinned to 434de6e, which was committed 119 day(s) ago (threshold: 14 days).

The submodule is pinned at upstream main HEAD, but that HEAD itself is older than the threshold. No action needed in this repo — upstream simply hasn't moved.

This is an advisory comment from strategic-plan-pr-summary.yml. It does not block the build. Threshold is configurable via the STALE_AFTER_DAYS workflow env var (currently 14). This comment is updated in place across pushes.

@ProfessorPolymorphic
ProfessorPolymorphic merged commit 3c3eb3b into main Jul 28, 2026
7 checks passed
@ProfessorPolymorphic
ProfessorPolymorphic deleted the fix/registry-status-taxonomy branch July 28, 2026 17:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant