prj-state-hub-retirement/DECISIONS.md
tegwick c6bccebe55 Core Hub is off CoulombCore; gitea is the last dependent
core-hub executed CORE-WP-0011 overnight, one day after choosing the interim
path. core-hub-api runs 1/1 on railiance01, the hub.coulomb.social Ingress is
there, DNS resolves to 92.205.62.239 and /healthz returns 200. The
core-hub-staging tunnel is retired from the map.

The larger of the two blockers on the 2026-08-31 decommission is closed, and it
closed because continuity was decoupled from architecture — CORE-WP-0010 and
HUB-WP-0004 remain open and no longer sit on the critical path. That was
core-hub's argument rather than this project's, and it is the transferable
lesson: when a hard date meets an unresolved design question, move the running
thing and leave the question where it was.

gitea.coulomb.social is now the only name resolving to CoulombCore. kaizen-agentic
is done; reuse-surface, the whynot-design npm lane and issue-core's legacy target
remain.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 16:29:17 +02:00

8.1 KiB

Decision Log

Auto-generated by the Custodian State Hub.

Restore the previously-live seven-action tenant-engine image rather than rebuild

Date: 2026-08-16
Decided by: grok

The four-action regression is a pin problem, not a policy-authoring problem. Image sha256:9320df39 was CI-built from e9911eb, previously live 2026-08-11, and confirmed by tenant-engine on 2026-08-13. The tenant-engine policy has not changed since that commit. A new image would re-bake unrelated later packages and would not be the artifact already verified. TEN-WP-0006 guardrail actions stay out of this restore.


Use the guardrail read/write split now: flex-auth may read, may not set

Date: 2026-08-16
Decided by: grok

TEN-WP-0006 split the actions so a PDP can read ceilings without changing them, and their tests call the read as actor=flex-auth. Leaving both actions on the single tenant-engine subject would keep the seam unused and leave the intended reader failing unknown_subject. This is a real difference: flex-auth set is denied action_not_granted. An ops write subject is out of scope; writes stay on the existing tenant-engine identity.


Generation 2 was retired correctly; the correction matters more than the finding

2026-08-20. SHR-WP-0002's first draft asserted that inter-hub had "retired itself by attrition", inferring it from three true observations: no ~/inter-hub repo, a dead CoulombCore endpoint, and a railiance01 Deployment scaled 0/0.

The inference was wrong. core-hub/workplans/archived/260708-CORE-WP-0007-haskell-retirement.md records that CORE-WP-0005 closed the production cutover gates on 2026-07-03 — hub.coulomb.social serving Core Hub, Inter-Hub compatibility, staging import and dual-run smokes all closed — and that Haskell/IHP retirement followed on 2026-07-08 after a stabilization window and explicit operator approval to retire the Inter-Hub rollback deployment. The 0/0 Deployment is that rollback standby, at its designed end state.

Recorded because the failure mode generalises: live documents described a retirement that had already happened, and the completed evidence was in an archived workplan. core-hub/SCOPE.md still lists cutover planning as in scope. A reader checking current files would reach the wrong conclusion, as this project did. Retirement evidence needs to be discoverable from the live record, not only from the archive — a requirement that applies directly to the State Hub retirement this project is planning.

The real finding survived the correction and sharpened: the gen-3 runtime serves from the host being decommissioned.

CoulombCore decommission date: end of August 2026

2026-08-20, operator. CoulombCore is to be retired by 2026-08-31. This project treats that as a hard external constraint, not a target.

Eleven days. That materially decides SHR-WP-0002-T03: absorbing Core Hub directly into hub-core depends on CORE-WP-0010HUB-WP-0004, the latter still holding an open decision on whether hub-core becomes a runtime at all. Finishing an architecture decision and a production migration inside eleven days is not a plan, it is a hope. The project's recommendation to core-hub is therefore the interim move (rmgr rapp wrap onto railiance01, absorb into hub-core afterwards on a calm schedule) — the pattern issue-core used one week earlier. The choice remains core-hub's; the reasoning is recorded either way.

What is actually still on CoulombCore

Established by resolving the public service names and inspecting railiance01, 2026-08-20:

Service Status Consequence of shutdown
hub.coulomb.social → Core Hub Production since 2026-07-03 Loss of the gen-3 interaction framework. Tracked, SHR-WP-0002-T03
gitea.coulomb.social → container registry Live (200) Not tracked anywhere before today. See below

bao, forgejo, policy, risk and reuse all resolve to railiance01 already.

The registry dependency nobody had written down

gitea.coulomb.social is a container registry on CoulombCore, and two workloads running on railiance01 pull their images from it:

  • reuse/Deployment/reuse-surfacegitea.coulomb.social/coulomb/reuse-surface:e3ae22e
  • state-hub/Job/state-hub-alembic-initgitea.coulomb.social/coulomb/state-hub:f2e042a

Checked across Deployments, StatefulSets, DaemonSets, Jobs and CronJobs; those two are the whole set.

This fails in the most inconvenient way available. Running pods survive decommission because their images are already pulled locally — so nothing breaks on the day. The failure arrives at the next restart, reschedule, node reboot or scale-up, as ImagePullBackOff, at a moment chosen by circumstance rather than by us.

Corrected 2026-08-20, same day. The first version of this entry treated both references as equally live and said State Hub would be "unable to run its schema migration". That overstated it, and the two cases are not alike:

  • reuse-surface is the real one. A live Deployment pulling gitea.coulomb.social/coulomb/reuse-surface:e3ae22e — a commit from 2026-07-07 18:25, now 22 commits behind main (2026-07-30). Its CI moved to REGISTRY: forgejo.coulomb.social at 21:25 the same day, three hours later, and has been publishing :latest and :main-<short> there ever since. The producer migrated; the consumer never did.
  • state-hub is largely a false alarm. Its Deployment already runs forgejo.coulomb.social/coulomb/state-hub:main-d8808bf — correctly migrated, current tag scheme. The only gitea reference is a completed one-shot Job (state-hub-alembic-init, 1 succeeded, completions 1, created 2026-07-06) that does not re-run on its own. It matters only if something recreates it from a chart template still carrying the old image, which is worth fixing but is not an outage waiting to happen.

The correction is recorded rather than edited away because the method produced it: enumerating workload image references found both, and only checking each one's liveness separated a live staleness from a historical artifact. An image reference is not a dependency until something can act on it.

forgejo.coulomb.social already runs on railiance01, so the destination exists and the work is retag, push, update manifest. Routed to railiance-platform.

Generalisation worth keeping: the decommission inventory was built from tunnels and workplans, and both missed this. A host is not free of dependents because nothing tunnels to it — it is free when nothing pulls, resolves or authenticates against it either.

2026-08-21: Core Hub is off CoulombCore; the registry is the last dependent

core-hub-api serves from railiance01 (Deployment 1/1, Ingress 15h, hub.coulomb.social92.205.62.239, /healthz 200). CORE-WP-0011 was executed overnight, one day after the decision to take the interim path.

The larger of the two blockers on the 2026-08-31 decommission is therefore closed, and it closed because continuity was decoupled from architecture. CORE-WP-0010/HUB-WP-0004 — the library-vs-thin-host question — remain open and no longer sit on the critical path. That decoupling was core-hub's argument, not this project's, and it is the transferable lesson: when a hard external date meets an unresolved design question, move the running thing and leave the question where it was.

Remaining CoulombCore surface: gitea.coulomb.social alone. It serves an OCI registry, a PyPI index and an npm registry. Known dependents:

Dependent State
kaizen-agentic (PyPI) DoneKAIZEN-WP-0010, verified clean install from forgejo
reuse-surface (OCI and live federation) Open — the one that breaks on the day, no reply yet
whynot-design-npm-publish (npm, ops-warden lane) Open — routes to a registry that will not exist
issue-core legacy PyPI target Open — trivial, a trap rather than an outage

inter-hub-coulombcore remains in the tunnel map by deliberate choice: the service is scaled to zero everywhere, and scaled-to-zero is not retired. It carries no traffic, so it does not block the date.