feat(projection): add workplan retirement columns, and record the migration gap
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
Build and Publish Multi-Context Image / build-and-push (push) Successful in 25s

Adds projection_retired_at, projection_retired_reason and derived_from_commit.
Retirement cannot be expressed by deletion — hub-native records reference
workplans with RESTRICT — nor by `status`, since an archived workplan was closed
by its owner while a retired one is simply no longer derived by the forge. Those
are different facts and must not share a field.

Discovered while applying this: central's schema is two revisions behind the
code it runs. review_contracts does not exist there although its migration ships
in the serving image, and there is no migration mechanism at all — bare uvicorn
CMD, no chart-declared job. Recorded as STATE-WP-0083-T07, which now blocks T03.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2583210@bnt-lap001
Assistant-Session: f2bff2d5-e9b2-4338-92ca-10282a927006
This commit is contained in:
tegwick 2026-08-25 23:49:13 +02:00
parent fd0d0d537b
commit 89ff2b2ea3
3 changed files with 95 additions and 0 deletions

View file

@ -214,3 +214,39 @@ heading. That is not a foundation for deletion.
Acceptance: task rows carry their canonical record id; the task diff for
`whitehat-security` reports clean; `the-custodian`'s task diff falls to something
manual inspection confirms.
## Restore a migration mechanism for central
```task
id: STATE-WP-0083-T07
status: todo
priority: high
```
**Central's schema is behind the code it is running, and nothing detects it.**
Discovered 2026-08-25 while preparing the retirement columns.
Central is at revision `b8d4f0a2c6e1`; the chain is
`b8d4f0a2c6e1 → c9e5a1b3d7f2 → d1a2b3c4e5f6`. The `review_contracts` table does
not exist on central even though the migration creating it ships inside the image
currently serving traffic. The code and the database disagree silently.
There is no migration mechanism. The image `CMD` is bare `uvicorn`, the Helm
chart declares no migration job, and the only evidence migrations ever ran was an
ad-hoc `state-hub-alembic-init` Job created outside the chart — deleted earlier
the same day as a retired-forge leftover. Deleting a completed Job removed a
historical record rather than a working mechanism, since Jobs do not re-run, but
it also removed the last visible sign that this gap existed.
This blocks `T03`: the retirement columns cannot reach central without it.
Needed: migrations as a declared part of the release — a chart-managed job or
init container that runs `alembic upgrade head` before the API serves — and a
check that surfaces a schema/code mismatch instead of leaving it silent. A
deployment that can run against a schema it was not built for is the same class
of defect as a projection that cannot name its source commit.
Acceptance: central reaches `head`; `review_contracts` exists; the mechanism is
declared in the chart; a mismatch between code and schema is reported rather than
tolerated.