From 64b71320e72c0e3e3d3b819ddf13e47668e03627 Mon Sep 17 00:00:00 2001 From: tegwick Date: Thu, 20 Aug 2026 07:20:56 +0200 Subject: [PATCH] docs(STATE-WP-0079): retirement freeze policy, close T01 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 --- docs/work-record-quality-gates.md | 3 +- policies/retirement-freeze.md | 87 +++++++++++++++++++ .../STATE-WP-0079-retirement-strangler.md | 17 +++- 3 files changed, 104 insertions(+), 3 deletions(-) create mode 100644 policies/retirement-freeze.md diff --git a/docs/work-record-quality-gates.md b/docs/work-record-quality-gates.md index d339362..addefd6 100644 --- a/docs/work-record-quality-gates.md +++ b/docs/work-record-quality-gates.md @@ -3,7 +3,8 @@ Status: active convention (STATE-WP-0076 policies; STATE-WP-0077 recording + soft visibility) Related: `dashboard/src/docs/work-records.md`, `policies/intake-doc.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 diff --git a/policies/retirement-freeze.md b/policies/retirement-freeze.md new file mode 100644 index 0000000..f17f25f --- /dev/null +++ b/policies/retirement-freeze.md @@ -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 1–3 | +| 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. diff --git a/workplans/STATE-WP-0079-retirement-strangler.md b/workplans/STATE-WP-0079-retirement-strangler.md index 8d9416c..dafe128 100644 --- a/workplans/STATE-WP-0079-retirement-strangler.md +++ b/workplans/STATE-WP-0079-retirement-strangler.md @@ -42,7 +42,7 @@ Expand pilot list here as cutover progresses; do not add new checkout mutators i ```task id: STATE-WP-0079-T01 -status: todo +status: done priority: high 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 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 ```task @@ -169,7 +182,7 @@ evidence, stop service, archive repo read-only. Residuals → live owners. ## Acceptance -- [ ] Freeze policy documented +- [x] Freeze policy documented - [x] Strangler plan covers all inventory capabilities - [x] prj-/GOAL.md register path works - [ ] Move/replace slices evidenced with tests/counts