Commit graph

180 commits

Author SHA1 Message Date
532583ce17 feat(projection): add the fleet reset as a loop over the repository form
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Build and Publish Multi-Context Image / build-and-push (push) Successful in 25s
ADR-012 decision 7 requires the fleet form to share the per-repository
implementation: the rarely-run wide operation must be the frequently-run narrow
one, or the wide one is trusted on the strength of never having been exercised.

Failure behaviour is the substance. A refusal does not stop the pass — aborting
on the first refusal means one unresolved repository blocks reconstruction
everywhere, which in practice means permanently. An error does not stop it
either. Each repository gets its own session so one failure cannot roll back
another's work, and only repositories that applied are committed.

Refs STATE-WP-0083-T04

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
2026-08-26 13:23:08 +02:00
76a7c7ed24 feat(workplan): reset diff is clean — zero retirements across five repositories
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Eleven files declared types canon does not define while the hub held each as a
workplan. Eight had their type corrected; three lacking identifiers were given
one continuing their repository sequence, preserving hub identifiers.

The diff now proposes no retirements anywhere tested. Nothing in the reset's
logic changed: the retirements disappeared because the sources were repaired.
The reset had been reporting the truth about a fleet whose files could not be
read.

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
2026-08-26 10:30:26 +02:00
7c45534115 feat(workplan): collision refusal verified live on net-kingdom
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Returns refused naming ADHOC-2026-08-23 and its holder, instead of
IntegrityError. Records that a first check against the cache returned refused
via the retirement path and was nearly reported as proof — the output looked
like success while testing nothing of the sort.

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
2026-08-26 10:21:43 +02:00
8404ab32f4 feat(workplan): record the post-repair reset diff and two findings
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
False retirements are gone: kontextual-engine 1 to 0, the-custodian 4 to 2.

The four records reported as hub-first with no backing file all had files, by
three different mechanisms — two with unterminated frontmatter, two declaring
type: feature. Each time 'the tool did not find it' was reported as 'it does not
exist'. Ten files in workplans/ declare a non-workplan type and need
disposition.

The reset crashes on net-kingdom with an IntegrityError where it should refuse:
ADHOC-2026-08-23 derives to an identifier another repository holds, which is the
collision CUST-WP-0066 documented. A refusal is actionable; a constraint
violation is a stack trace.

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
2026-08-26 08:35:59 +02:00
b47dd52c90 feat(workplan): close STATE-WP-0083-T08 — 18 files repaired, none unparseable
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Two shapes of one missing-newline defect: 16 with the closing delimiter fused
onto the last value, 2 with a value fused onto the following key. Only the
newline was inserted.

Forces a correction: state-hub-v0.1 and v0.2 were reported as hub-first records
with no backing file. They are CUST-WP-0000 and CUST-WP-0000b, which existed all
along and were unreadable — the claim came from a parser's silence rather than a
check against the directory.

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
2026-08-26 08:29:47 +02:00
6606660632 feat(workplan): open STATE-WP-0083-T08 — 18 files have unterminated frontmatter
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
Found by reviewing the reset diff before applying: it proposed retiring
kont-wp-0015, a live correctly-registered workplan. Cause is a closing --- fused
onto the last frontmatter value, so the frontmatter never terminates and the
whole body is swallowed. Any parser selecting on type: workplan sees nothing, so
the file is invisible rather than invalid.

18 files across citation-evidence, infospace-bench, kontextual-engine,
net-kingdom and others. Running the reset before repairing them would retire
live work: the derivation omits the workplan, so the reset reads its correct hub
record as no longer deriving.

Blocks the first production reset.

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
2026-08-26 08:22:52 +02:00
fb681b58f8 feat(workplan): close STATE-WP-0083-T06 — tasks carry canonical identity
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Central: 5248 of 5974 tasks identified, 5213 distinct, 35 duplicates. The
pre-apply check was uniqueness rather than volume — all 136 pending updates were
verified to take identities held by nothing else, which is the lesson from the
first attempt where a clean dry run concealed 51 non-unique ids.

The 35 remaining duplicates predate this work: 18 from a workplan registered
twice, 12 from archived RAILIANCE-WP files left unrenamed by the active-only
migration decision, 4 from unqualified ad-hoc ids.

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
2026-08-26 07:49:27 +02:00
8386a0b81a feat(workplan): record the central backfill and the short-task-id defect
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
5248 rows identified but only 5100 identities distinct: bare T01 task ids stored
as canonical gave every workplan's first task one identity, 51 ids across 148
rows. The backfill's conflict check could not see it — it detects one UUID
claimed by two ids, and this was the inverse — so it surfaced only because the
two counts did not reconcile.

Central now holds 5112 of 5974 identified, 5077 distinct. The remaining 34
duplicates are unqualified ad-hoc ids reused across repositories, the problem
CUST-WP-0066 closed for new records only.

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
2026-08-26 02:18:51 +02:00
8b207a991a feat(tasks): give task rows a canonical record identifier
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Build and Publish Multi-Context Image / build-and-push (push) Successful in 26s
Every work-record type carried a stable identifier except tasks, whose rows held
only id, workplan_id, title, status and priority — nothing connecting a row to
CUST-WP-0067-T01 in the file it came from. Matching was therefore by title, so a
renamed heading looked like one task vanishing and another appearing, and the
forge-derived reset had to refuse to touch tasks at all.

Adds tasks.record_id (nullable: no migration can invent an identity for an
existing row) and a backfill that reads the pairing from the repository files,
where a task declares both its canonical id and its projection UUID. 5516 pairs
across 121 repositories with zero conflicts; 4456 of 6073 cache task rows
identified.

Diff and reset now key on record_id where present, falling back to a
title-prefixed key so an unidentified row stays visibly unidentified.

Unknown stays unknown: a row the files do not claim keeps no identity and the
reset keeps refusing to act on it, and an existing identity is never
overwritten — a mismatch is recorded as a conflict rather than resolved.

Refs STATE-WP-0083-T06

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
2026-08-26 02:05:51 +02:00
43ffe883c3 feat(projection): reconcile a repository's projection against the forge
All checks were successful
CI Smoke / host-smoke (push) Successful in 1s
CI Smoke / container-smoke (push) Successful in 1s
Build and Publish Multi-Context Image / build-and-push (push) Successful in 26s
Implements ADR-012 decision 7 as amended (STATE-WP-0083-T03). Creates what the
forge has and the hub lacks, updates what differs, retires what no longer
derives. It never deletes: hub-native records reference workplans with ON DELETE
RESTRICT, and destroying a progress event to tidy a derived projection would
lose hub-native truth to fix a derived-state problem.

Retirement is refused by default. A record that stops deriving may mean a
deliberately deleted file or a caller pointed at the wrong branch; only the
caller can say which.

Verified against live data and rolled back: whitehat-security applied 5 updates
with no retirements; the-custodian refused, naming the four hub-first records
confirmed by hand to have no backing file.

Tasks of existing workplans are deliberately untouched — hub tasks carry no
canonical identifier, so matching is by title and a renamed heading would
destroy and recreate a record. Tasks are created only alongside a new workplan,
where nothing exists to mis-match. Tracked as T06.

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
2026-08-26 01:19:10 +02:00
6bb1fe823a feat(workplan): close STATE-WP-0083-T07 — central reports schema ok at head
All checks were successful
CI Smoke / host-smoke (push) Successful in 1s
CI Smoke / container-smoke (push) Successful in 1s
First execution failed in a way that proved the design: the pre-upgrade hook
applied both migrations and deleted itself on success, then the k3s tunnel
dropped before the API could roll. Schema was briefly ahead of code — the safe
direction, and why additive migrations were the right shape.

Records two gaps it exposed: a successful migration leaves no trace because of
the hook delete policy, and bridge status reported a dropped tunnel as
connected.

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
2026-08-26 01:10:58 +02:00
89ff2b2ea3 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
2026-08-25 23:49:13 +02:00
fd0d0d537b feat(projection): derive a repository's projection from the forge
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Build and Publish Multi-Context Image / build-and-push (push) Successful in 23s
Implements ADR-012 decisions 1 and 2 (STATE-WP-0083 T01, T02 partial). Central
clones the default branch from Forgejo and derives its own projection: 69
workplans and 459 tasks from the-custodian at d5013ae, identical across runs,
with the commit recorded as provenance.

Identifiers are derived in the ADR-007 namespace and verified against live
records, so a forge-derived projection and a preliminary overlay agree on
identity without reconciliation.

The diff first matched hub records by UUID and was badly wrong: most hub records
carry pre-ADR-007 random identifiers, so nearly everything appeared
simultaneously missing and stale, and a reset built on it would have destroyed
and recreated the entire projection. It now matches canonical record id, falling
back to the backing file. whitehat-security — bootstrapped straight from files —
now reports clean, which is the control.

Task-level comparison is deliberately not trusted: hub tasks carry no canonical
record id, only a title, so matching is by title. Recorded as T06; T03 is
limited to workplans until it lands.

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
2026-08-25 23:34:25 +02:00
6390b7bead feat(workplan): open STATE-WP-0083 for the forge-derived projection reset
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Implements ADR-012 decision 7. Placed in state-hub because central must do its
own reading: the pod can clone Forgejo anonymously, and driving this from Repo
Manager would push a workstation-computed projection into central, which
ADR-010 decision 5 forbids.

Also the only sanctioned removal path — the hub has no hard-delete for work
records by design.

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
2026-08-25 23:29:24 +02:00
3cb256ef5c fix(workplans): adopt ADR-007 derived identifiers for unregistered records
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
These workplans exist only in the retired local hub. Their random pre-ADR-007
identifiers are refused by C-06 as stale references, so they cannot be
registered. Deriving from the canonical record id takes no identity from
anything: central does not hold them and the old ids die with the cache.

Records central already holds were deliberately left untouched.

Refs CUST-WP-0068-T06

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2583210@bnt-lap001
Assistant-Session: f2bff2d5-e9b2-4338-92ca-10282a927006
2026-08-25 20:22:27 +02:00
2b2016f1df fix(workplan): point workplan at its authoritative projection id
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
The file carried an identifier minted by the retired local hub while central
held a different record for the same file — ADR-010's same-filename,
different-UUID duplicate-registration class.

Central is authoritative (ADR-010 decision 1) and decision 6 says to mitigate
by changing the repository file rather than editing central, so the file adopts
central's id. The cache-side id dies with the cache.

Refs CUST-WP-0068

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2583210@bnt-lap001
Assistant-Session: f2bff2d5-e9b2-4338-92ca-10282a927006
2026-08-25 17:37:52 +02:00
13ada219eb docs(workplan): record STATE-WP-0080's projection state after closing on central
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Central now reads finished, matching the file. Its task projection is still the
pre-retarget draft with four open tasks, because central never saw the
2026-08-16 retarget and none of this file's task identifiers exist there.

Left deliberately: re-registering would add eight records alongside eight stale
ones. Duplicate task identity resolution belongs to CUST-WP-0068.

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
2026-08-25 16:25:34 +02:00
0839e308d1 fix(workplan): point STATE-WP-0080 at its authoritative projection id
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
The file carried 03f38314, minted by the retired local hub. Central holds a
different record for the same file (bbfce36a) — ADR-010's "same filename,
different UUID" duplicate-registration class.

Central is authoritative (ADR-010 decision 1), and decision 6 says to mitigate
by changing the repository file rather than editing central, so the file adopts
central's id. The cache-side id dies with the cache.

Refs CUST-WP-0068

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
2026-08-25 16:23:12 +02:00
repo-manager
9bbe9e38ae chore(registrar): assign State Hub identifiers
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a02b22-9638-76d2-bbff-b7ea1770b118
2026-08-23 14:49:49 +02:00
a05a64bf0e fix(workplans): qualify State Hub daily identifier
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a02b22-9638-76d2-bbff-b7ea1770b118
2026-08-23 14:48:16 +02:00
284e28112d fix(project-rules): qualify ad-hoc record identifiers
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a02b22-9638-76d2-bbff-b7ea1770b118
2026-08-23 14:45:26 +02:00
fae2816199 fix(consistency): preserve repository domain in briefs
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a02b22-9638-76d2-bbff-b7ea1770b118
2026-08-23 13:57:22 +02:00
57c3e08103 fix(classification): harden registration updates
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Build and Publish Multi-Context Image / build-and-push (push) Successful in 26s
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a02b22-9638-76d2-bbff-b7ea1770b118
2026-08-23 11:30:36 +02:00
b0e1af24f9 fix(retirement): close projection and launch contract gaps
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Build and Publish Multi-Context Image / build-and-push (push) Successful in 23s
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a02b7c-1c49-76a0-955a-49e7b3ddfc0d
2026-08-23 00:52:18 +02:00
2d114be84d docs(review): record final full-suite pass
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a023c0-a0a3-7c03-b395-5a0d2757214d
2026-08-22 21:08:20 +02:00
598f6418e7 feat(review): add multi-owner contracts and receipts
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Build and Publish Multi-Context Image / build-and-push (push) Successful in 25s
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a023c0-a0a3-7c03-b395-5a0d2757214d
2026-08-22 20:57:51 +02:00
repo-manager
9e7e91300f chore(registrar): assign State Hub identifiers
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a023c0-a0a3-7c03-b395-5a0d2757214d
2026-08-22 18:16:06 +02:00
ceab9ce279 docs(review): add multi-owner contract workplan
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a023c0-a0a3-7c03-b395-5a0d2757214d
2026-08-22 18:02:36 +02:00
e2544b218d docs(retirement): record empty projection rebuild proof
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a023c0-a0a3-7c03-b395-5a0d2757214d
2026-08-22 12:31:41 +02:00
52a7d6bb73 docs(pilot): record registrar projection cutover
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a023c0-a0a3-7c03-b395-5a0d2757214d
2026-08-22 09:57:59 +02:00
697dd49390 feat(consistency): rebuild deterministic projection IDs
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Build and Publish Multi-Context Image / build-and-push (push) Successful in 26s
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a023c0-a0a3-7c03-b395-5a0d2757214d
2026-08-22 09:43:55 +02:00
cb1b028fd1 feat(identifiers): add reversible projection migration
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Build and Publish Multi-Context Image / build-and-push (push) Successful in 24s
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a023c0-a0a3-7c03-b395-5a0d2757214d
2026-08-22 00:27:48 +02:00
ce52e9d1e2 docs(retirement): own identifier projection migration
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a023c0-a0a3-7c03-b395-5a0d2757214d
2026-08-21 23:59:43 +02:00
repo-manager
ec780c05a2 chore(registrar): assign State Hub identifiers
All checks were successful
CI Smoke / host-smoke (push) Successful in 1s
CI Smoke / container-smoke (push) Successful in 1s
2026-08-21 21:53:39 +02:00
87f1296714 docs: STATE-WP-0081 cluster self-sufficiency and registrar fix
The registrar is broken by workstation coupling rather than beside it. Inside
the pod /home/tegwick mounts read-only despite the chart setting no readOnly
and securityContext being empty, so the sweep dies before it can mint. That
is why 12 sync requests queued and the newest custodian-sync commits are July.

Eight tasks: restore the write path, give the pod its own clone volume and
service identity, run non-root, correct 72 repo records still pointing at
/home/worsch with gitea remote_urls, serve the dashboard from the cluster,
write the boundary rule down, and close out the registrar.

End state: workstation coding agents push to forgejo, cluster infrastructure
reads from forgejo, neither reads the other's disk.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 16:13:38 +02:00
190bb41b89 docs(STATE-WP-0079): registrar bottleneck status check
The registrar is reachable and always was: state-hub-primary binds [::1]:8000
while the workstation API listens on 127.0.0.1:8000, so an IPv4 probe hits
the local hub and reads as a dead tunnel.

But the two databases have diverged by roughly a third -- 987 vs 649
workplans, 5710 vs 4037 tasks -- and the registrar runs pre-rename code. Nine
registrar sync requests from three agents have queued since 2026-08-20.

Re-checked the chain: RMGR-WP-0004-T08 is done, so RMGR-WP-0005-T03's stated
blocker has closed. Its substantive blocker has not -- ADR-007 Migration
option 2 permits historical identifier collisions, and UUIDv5 derivation from
a non-unique identifier manufactures collisions.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 00:20:44 +02:00
7adfe1369f docs(STATE-WP-0079): A2a executed, dual-run live for repo-manager pilot
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
First live cutover slice. Installed the shipped pilot config (writeback and
reconcile on, writeback_push off, scoped to repo-manager), reloaded the API
via its own --reload watcher rather than restarting the operator's process,
and confirmed reconcile routed through rmgr with a new mutation meter entry
(8 workplans, 53 tasks, 61 records).

Divergence check clean: the one-workplan delta against the hub is
RMGR-WP-0008, unregistered because this instance is not the identifier
registrar, not a dual-run divergence.

Slice sits at dual, not owner -- the hub stays authoritative until a full
sweep cycle shows zero divergence.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 09:10:55 +02:00
a824fd5dfe docs(STATE-WP-0079): A2 readiness detail and dual-run state
All checks were successful
CI Smoke / host-smoke (push) Successful in 1s
CI Smoke / container-smoke (push) Successful in 2s
Applied the A3 readiness check one level down. The State Hub adapter exposes
exactly three operations: rm_update_task_status, rm_reconcile, rm_scaffold.
No adapter for workplan CRUD, intake, decision, dependency or human-flag
records, and no repo-manager parser for them either.

A2 splits into A2a (task status + reconcile, ~6 items, receivable) and
A2b-A2e (~32 items, not receivable). A2a is the only slice in the plan
executable today -- roughly 6 of 425 inventory items.

Also records that dual-run is currently off entirely: no config file,
writeback and reconcile false, no pilot repos. The 23 metered mutations are
RMGR-WP-0002/0003 pilot residue. A2a's next step is operational, not code.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 08:50:01 +02:00
5f747fbc1e docs(STATE-WP-0079): correct repo-manager owner readiness, withdraw A3 recommendation
All checks were successful
CI Smoke / host-smoke (push) Successful in 1s
CI Smoke / container-smoke (push) Successful in 2s
The T02 slice plan marked all 167 repo-manager items receivable because
RMGR-WP-0001/0002/0003 are finished. That reads readiness off workplan
status, which is too coarse.

Verified against repo-manager/src/repo_manager/: those workplans delivered
work-record dual-run, repository observation, and scaffolding. parse/ holds
only workplan.py, and the source tree contains no reference to sbom,
repo_goal, contribution, technical_debt, or extension_point.

Only A1 (partial) and A2 are receivable -- 86 items, not 165. A3, A4 and A5
have no owner-side surface. A3 was recommended twice as the low-blast-radius
first cut; it is in fact the least ready slice in Wave A. Recommendation
withdrawn.

Critical path moves to repo-manager: a workplan there must build the
register, UI, and topic surfaces. Building them here is inadmissible under
policies/retirement-freeze.md. First executable slice is A2.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 08:46:04 +02:00
fb363b37d3 feat(STATE-WP-0079): retire the suggestion-backlog surface (slice E1)
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Build and Publish Multi-Context Image / build-and-push (push) Successful in 37s
History is archived fleet-side, so the read surface has no remaining job.

- api/routers/suggestions.py: whole prefix 410s with a pointer to intake and
  to the archive; the router drops from 176 lines to a stub
- mcp_server: the 6 suggestion tools removed outright rather than stubbed --
  a retired tool that still appears in the tool list costs every agent
  session context on every call, which is the opposite of retiring it
- write_idempotency: 5 /suggestions rules dropped
- dashboard: suggestions.md deleted, nav entry removed, reference.md and
  wsjf-triage.md updated; docs/suggestions.md rewritten as archive pointer
- tests: two tests pinned the old read-live behaviour and now pin the
  retirement contract instead

Tables stay: they are retire/archive in SHR-INV-0001 and are captured by the
final dump at T06.

Untouched, and worth knowing during cutover: ui-feedback.md / todo.md
'suggestions' are Shift+click dashboard feedback backed by technical_debt, a
different entity that shares the word. E3 (dashboard-meta) is that page; its
owner is state-hub-until-cutover so it retires at the T06 window, not now.

Full suite 612 passed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 08:11:14 +02:00
98af485cd5 docs(STATE-WP-0079): archive suggestion-backlog history, record E1 status
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Slice E1 was already half-retired: mutations 410 since CUST-WP-0061-T06,
reads held open only to keep the history reachable. That history is now
archived fleet-side, so the reads can go.

Records a dependency the inventory's 17-item count misses: the suggestions
dashboard page is live and referenced from index.md and wsjf-triage.md, so
E1's removal must sequence with the UI slices A4/B5 rather than ahead of them.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 07:42:00 +02:00
ecc10b1f9f docs(STATE-WP-0079): execute slice E2, retire 15 legacy interfaces
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Retires the 15 workstream->workplan aliases that meet the retirement
standard: verified replacement, no manual hold, zero calls in a 7-day
window, and silence past the volume-scaled quiet threshold. Meter now reads
16 retired / 4 legacy with 0 outstanding candidates.

The 4 held are the three six-figure read paths and GET /tasks/?workstream_id
which still has traffic -- the set where a premature retirement would do the
most damage. They clear as their quiet counters run.

Journalled fleet-side in the-custodian/docs/retired-legacy-interfaces.md so
the record outlives this repo's archive.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 07:28:54 +02:00
64b71320e7 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>
2026-08-20 07:20:56 +02:00
93e95f93e7 feat(legacy-meter): scale retirement quiet period to call volume
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 28s
A clean review window only proves an interface was silent for that window.
For a heavily used interface that is weak evidence -- an infrequent caller
can fall outside the window entirely, so the interface reads as retirable
while still having consumers.

_retirement_state now also requires silence since last_seen_at, scaled by
all-time volume (RETIREMENT_QUIET_LADDER): 7d under 100 calls, 30d under
10k, 60d above. Existing guards (retired / manual hold / replacement ref /
replacement verified / in-window traffic) still take precedence.

On the 2026-08-20 capture this makes 15 of 19 legacy interfaces retirable
and holds 4: the three six-figure /workstreams/ read paths, and
GET /tasks/?workstream_id which still has live traffic.

Unblocks the bulk of Wave E2 in the cutover slice plan. 7 new tests.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 07:13:44 +02:00
be7f2632c3 fix(legacy-meter): capture evidence over 7 days, not an 8-hour band
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
capture_legacy_meter_evidence.py fell back to hours=8 whenever --days was
omitted, and --hours itself defaulted to 8. Every unattended capture sampled
06:00Z-14:00Z while writing a file named weekly-review with cadence: weekly.
39 of 40 captures ran this way; only 2026-07-08 used a true 7-day window.

Calls outside the band were never sampled, so interfaces with live callers
reported as retirement candidates -- GET /tasks/?workstream_id was flagged on
2026-08-19 despite traffic on 2026-08-18.

Default the script to days=7; keep --hours for spot checks, documented as not
retirement evidence. Adds corrected capture for 2026-08-20 and records the
residual gap (candidate rule ignores last_seen_at) against STATE-WP-0079-T05.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 01:12:37 +02:00
613477b4d2 docs(STATE-WP-0079): cutover slice plan, close T02
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
Assign all 425 SHR-INV-0001 items to 19 slices across five waves plus Keep,
each with adapter flag, owner API, and rollback. Coverage computed against
the inventory rather than hand-counted.

Only Wave A (repo-manager, 165 items) is executable; B/D1/D2 are gated on
owner-side contracts still at proposed. Flags two findings for T04/T05: the
9 ops_dependency items cannot be strangled behind a flag, and the
legacy-meter weekly review window is 8h, not a week.

Also corrects the workplan status from proposed to active.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 23:44:27 +02:00
1655b34fcd docs: close STATE-WP-0080, move templating removal to STATE-WP-0079-T04
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
T01-T03 are done and T05-T08 were already handed to RMGR-WP-0004. T04's
gates (RMGR-WP-0004-T06, STATE-WP-0079-T04) remain open, and the task
always specified that removal land inside the 0079 strangler rather than
as an isolated breaking change. Cancel it here with a pointer, record the
inherited residual in 0079-T04, and mark the workplan finished.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 23:24:07 +02:00
05dba43cae docs: audit STATE-WP-0080 removal readiness 2026-08-19 19:13:25 +02:00
d8e0eddb22 feat: delegate project register; registrar-only ID minting
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Build and Publish Multi-Context Image / build-and-push (push) Successful in 39s
STATE-WP-0080-T02: statehub register routes project-flavor scaffolding
through rmgr scaffold and keeps only repo + host-path registration.
T01 refuse remains when GOAL.md is missing and --wp-prefix is not set.

RMGR-WP-0005-T01: C-06/C-11/C-32 skip mint+writeback unless this
instance is the identifier registrar (STATEHUB_REGISTRAR or railiance
hostname).
2026-08-18 21:51:30 +02:00
f564e99a14 fix: refuse to scaffold prj- repos from statehub register
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
STATE-WP-0080-T01: detect project flavor from classification, GOAL.md,
or a prj- slug, then exit pointing at rmgr scaffold. Durable-repo
write path is unchanged. Rebind 0080 hub IDs to the live workstream
and open T02 now that RMGR-WP-0004-T03 has landed.
2026-08-18 21:37:09 +02:00