docs(STATE-WP-0079): retirement freeze policy, close T01
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s

States the four admissible reasons for a change to state-hub during
retirement -- preserve compatibility, enable extraction, reduce scope, fix
operational risk -- and the inadmissible case: establishing new permanent
ownership in the component being retired.

The operative test is 'where does this live after cutover?', not 'is this a
good change?' Most inadmissible changes are good changes; STATE-WP-0080's
retarget to RMGR-WP-0004 is the worked example.

Enforced by review rather than new automation: a freeze-checker built inside
State Hub would itself be new permanent automation here, so the policy would
violate itself. New tables/routes/MCP tools are the one hard stop.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
tegwick 2026-08-20 07:20:56 +02:00
parent 93e95f93e7
commit 64b71320e7
3 changed files with 104 additions and 3 deletions

View file

@ -3,7 +3,8 @@
Status: active convention (STATE-WP-0076 policies; STATE-WP-0077 recording + soft visibility) Status: active convention (STATE-WP-0076 policies; STATE-WP-0077 recording + soft visibility)
Related: `dashboard/src/docs/work-records.md`, `policies/intake-doc.md`, Related: `dashboard/src/docs/work-records.md`, `policies/intake-doc.md`,
`policies/work-item-dor.md`, `policies/workstream-dod.md`, `policies/work-item-dor.md`, `policies/workstream-dod.md`,
`policies/repo-doi.md`, `policies/service-dom.md` `policies/repo-doi.md`, `policies/service-dom.md`,
`policies/retirement-freeze.md`
## Purpose ## Purpose

View file

@ -0,0 +1,87 @@
# Retirement Freeze Policy
**Policy key:** `retirement-freeze`
**applies_to:** every change to `state-hub` from 2026-08-20 until the archive
window closes
**Assessment outcomes:** `Freeze-Ok` | `Freeze-Failed`
**Owner task:** `STATE-WP-0079-T01`
**Related:** `docs/retirement-cutover-slice-plan.md`, `SHR-INV-0001`,
decision `747011c6`, `prj-state-hub-retirement/GOAL.md`
## Why this exists
State Hub is being retired: its 425 inventoried surfaces move, are replaced, or
are retired under `STATE-WP-0079`. A retiring component attracts a specific
failure — work lands here because this is where the code already is, and each
such change quietly re-establishes State Hub as the permanent owner of something
the program is trying to relocate. Every one of those makes the cutover larger
and the archive later.
The freeze does not stop work. It constrains *what kind* of work is admissible.
## The rule
A change to `state-hub` is admissible only if it does at least one of:
1. **Preserves compatibility** — keeps existing callers working across a cutover
step (adapters, dual-run shims, writeback reconciliation).
2. **Enables extraction** — makes a capability easier to move to its inventoried
owner (seam-cutting, dependency untangling, contract extraction).
3. **Reduces scope** — deletes, retires, or delegates a surface.
4. **Fixes operational risk** — corrects a defect that would cause data loss,
corrupt evidence, or break a live caller before cutover.
A change is **inadmissible** if it establishes new permanent ownership here:
a new capability, a new authority, a new durable schema, or new automation whose
natural home is one of the receiving owners.
## The load-bearing case
The four admissible reasons are deliberately broad, and reason 4 is the one that
will be stretched. The test is not "is this a good change?" — most inadmissible
changes are good changes. The test is **"where does this live after cutover?"**
If the answer is "an owner repo," build it there and let State Hub adapt to it.
If the answer is "nowhere, it disappears at archive," it is admissible here.
If the answer is "State Hub, indefinitely," it is inadmissible regardless of merit.
Worked example, from this program: `STATE-WP-0080` was drafted as a full
flavor-awareness implementation inside `statehub_register.py`. It was good work
and it fixed a real defect. It was still inadmissible — repository standards
land in `repo-manager` after cutover — so it was retargeted to a guard plus a
delegation, and the implementation moved to `RMGR-WP-0004`.
## Enforcement
**By review, not by new automation.** Building a freeze-checker inside State Hub
would be new permanent automation in the component being retired — the policy
would violate itself. The gate is applied where changes are already reviewed:
| Point | Gate |
| --- | --- |
| New workplan in `workplans/` | Goal statement names which of the four reasons applies, or the plan is retargeted to an owner repo |
| Task marked `progress` on a non-trivial change | Same question, answered in the task body |
| Cutover slice execution (`STATE-WP-0079-T04`) | Slices are admissible by construction — they are reasons 13 |
| Any new table, route, or MCP tool | Presumed inadmissible; requires an explicit note saying why it dies at archive |
The last row is the only hard stop. New durable surface is exactly what the
freeze exists to prevent, so it carries a presumption against, and the burden
sits with the change.
## What the freeze does not cover
- **Receiving repos.** `repo-manager`, `hub-core`, `activity-core`, `ops-hub`,
and `fin-hub` are building the successor surfaces; they are unconstrained by
this policy and should be where new capability lands.
- **Work records.** Workplans, ADRs, decision docs, and evidence files in this
repo are the retirement program's own record. Writing them is reason 2 or 3.
- **`keep` items.** The 45 `keep`-dispositioned surfaces (`schema-history`,
ops-bridge connectivity, and the rest) stay operational until the freeze
window; maintaining them is reason 1.
## Interaction with the quality gates
Freeze admissibility is orthogonal to DoR/DoD (`docs/work-record-quality-gates.md`).
A workplan can be `DoR-Ok` and still `Freeze-Failed` — well-specified work in the
wrong repo is the exact failure this policy catches. Assess freeze first: it
decides *whether* the work belongs here, before DoR asks whether it is ready.

View file

@ -42,7 +42,7 @@ Expand pilot list here as cutover progresses; do not add new checkout mutators i
```task ```task
id: STATE-WP-0079-T01 id: STATE-WP-0079-T01
status: todo status: done
priority: high priority: high
state_hub_task_id: "375c0b66-98b0-4d5b-98dd-4ad2883a4051" state_hub_task_id: "375c0b66-98b0-4d5b-98dd-4ad2883a4051"
``` ```
@ -51,6 +51,19 @@ Document and enforce: changes during retirement must preserve compatibility,
enable extraction, reduce scope, or fix operational risk — not establish new enable extraction, reduce scope, or fix operational risk — not establish new
permanent ownership (INTENT retirement status). permanent ownership (INTENT retirement status).
**Result (2026-08-20):** `policies/retirement-freeze.md`, following the existing
`policies/` convention. States the four admissible reasons, the inadmissible
case (new permanent ownership here), and the operative test — *where does this
live after cutover?* — since most inadmissible changes are otherwise good
changes. Uses `STATE-WP-0080`'s retarget as the worked example.
**Enforced by review, not by new automation.** A freeze-checker built inside
State Hub would be new permanent automation in the component being retired, so
the policy would violate itself. Gates attach to points where changes are
already reviewed: new workplan goal statements, non-trivial task starts, and
slice execution. New tables, routes, or MCP tools carry a presumption against
and are the one hard stop.
## Capability strangler plan ## Capability strangler plan
```task ```task
@ -169,7 +182,7 @@ evidence, stop service, archive repo read-only. Residuals → live owners.
## Acceptance ## Acceptance
- [ ] Freeze policy documented - [x] Freeze policy documented
- [x] Strangler plan covers all inventory capabilities - [x] Strangler plan covers all inventory capabilities
- [x] prj-/GOAL.md register path works - [x] prj-/GOAL.md register path works
- [ ] Move/replace slices evidenced with tests/counts - [ ] Move/replace slices evidenced with tests/counts