Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a049a4-ee9f-78e1-9d66-2cb0f9bea3e3
28 KiB
| id | type | title | domain | repo | status | owner | topic_slug | created | updated | reviewed_at | reviewed_by | reviewed_against_commit | quality_dor | quality_dor_at | quality_dor_by | related | state_hub_workstream_id | |||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| STATE-WP-0085 | workplan | Lineage-preserving repository rename workflow and adoption-plan generator | infotech | state-hub | active | codex | infotech | 2026-08-28 | 2026-08-29 | 2026-08-28 | codex | 41d80429a7 |
DoR-Ok | 2026-08-28 | codex |
|
4f5661de-5922-55d6-bd02-5dcb00b13f73 |
Lineage-preserving repository rename workflow and adoption-plan generator
Goal
Make a repository rename a governed identity migration instead of an archive-and-register operation. State Hub must preserve the repository UUID, workplan and task identities, progress, decisions, telemetry, SBOM history, and coordination history while the canonical Forgejo name, clone URL, and local paths change.
The capability must also generate a repository-native migration workplan that
the repository being renamed can adopt. flex-auth to access-engine is the
first intended adoption, but the implementation and template must be generic.
Why this exists
Repository names are currently used as both mutable labels and identity keys.
The durable relationships are already mostly correct: workplans and token
events point to managed_repos.id. The public repository API, file bindings,
message routing, interface-change affected lists, identifier-alias provenance,
fabric projections, local paths, and forge URLs still contain slug-shaped
references.
State Hub has no supported repository rename operation. Registering
access-engine as a new repository would split the history of Forgejo
repository id 42 and State Hub repository id
fda8ad85-a7d7-4055-8f21-902a533e59df. Updating the database row manually
would preserve some foreign keys but leave slug-only surfaces, retries, and
failure recovery undefined.
flex-auth is part of the NetKingdom security stack. Its repository identity,
container publishing, deployment references, policy consumers, credentials,
fabric declarations, and State Hub routing cannot be cut over safely as an
unrecorded sequence of shell commands.
Invariants
Every implementation and generated migration plan must preserve these facts:
- A rename does not create a second
managed_reposrow. - The State Hub repository UUID is unchanged.
- The Forgejo repository numeric ID and selected source commit are unchanged.
- Existing workplan IDs, task IDs, hub UUIDs, progress events, decisions, and token events are unchanged.
- Existing work-record prefixes and filenames are not re-keyed merely because the repository slug changes.
- The old slug remains a durable alias. Historical records are not mass rewritten to pretend the old name never existed.
- Every phase is idempotent and resumable. A retry reports the achieved phase rather than applying a second rename.
- No old clone, alias, route, or rollback input is removed before verification succeeds and the target repository's migration workplan authorises cleanup.
- Forge redirects are compatibility evidence, not a substitute for updating canonical remotes and consumers.
- An unreadable forge repository, changed repository ID, changed head, slug conflict, or incomplete projection stops before mutation.
Scope
In scope
- Durable forge identity and repository-slug aliases in State Hub.
- A preflight, apply, verify, resume, and rollback contract.
- Alias-aware lookup and routing for State Hub-owned surfaces.
- CLI/API surfaces suitable for later HelixForge orchestration.
- A generator for a target-repository rename workplan.
- Operator documentation, events, metrics, and failure evidence.
- A non-mutating
flex-authtoaccess-enginerehearsal and generated repository workplan as the first adoption handoff.
Out of scope
- Executing the live
flex-authForgejo rename in this State Hub workplan. - Deciding whether the product binary, Go module,
FLEX_AUTH_*environment variables, Kubernetes namespace, Helm releases, service DNS names, container package, or policy vocabulary also becomeaccess-engine. The generated target workplan must make those explicit decisions. - Rewriting historical prose, audit records, message bodies, or raw telemetry.
- A general Forgejo repository transfer between owners. The model may leave room for transfer, but owner transfer requires a separate reviewed contract.
- Direct secret retrieval or embedding a Forgejo credential in State Hub records, logs, templates, or command arguments.
Ownership and execution boundary
- State Hub owns repository identity, aliases, work-record continuity, routing compatibility, audit evidence, and verification.
- Forgejo remains authoritative for the Git repository and its immutable repository ID.
- HelixForge orchestration may later coordinate the Forgejo operation, State Hub phase transitions, and local-clone registration through the contracts delivered here. It must not bypass them with database writes.
- The target repository owns the generated migration workplan, consumer and deployment consequences, execution evidence, and final cleanup decision.
Capability implementation is Yellow-lane work. A live forge rename, canonical route switch, old-alias retirement, or old-checkout removal is Red-lane work and requires an explicit operator confirmation recorded by the target workplan.
Target lifecycle
draft
-> preflighted
-> forge-renamed
-> statehub-rebound
-> source-synced
-> consumers-verified
-> completed
Any achieved phase
-> retry same phase safely
-> rollback-preflight
-> rolled-back (when the old forge slug is still available)
The operation record reports incomplete phases as recoverable state. It must never collapse "Forgejo renamed, State Hub not rebound" into a generic error that leaves the operator guessing which action already happened.
Define the identity and failure contract
id: STATE-WP-0085-T01
status: done
priority: high
state_hub_task_id: "dbac0fdf-042e-51bf-937e-59d15e34cb14"
Record the architecture decision for mutable repository coordinates over an immutable repository identity. Define:
- State Hub repository UUID versus canonical slug and aliases;
- Forgejo provider, owner, immutable repository ID, canonical name, and URL;
- expected source commit and default branch at preflight;
- phase transitions, retry semantics, and rollback limits;
- which slug-shaped fields are mutable projections, immutable historical evidence, external-source projections, or live routing keys;
- the boundary between a repository rename and a product/runtime rename.
Inventory every State Hub model, API, CLI, event, dashboard query, edge outbox shape, and external projection that carries a repository slug. Classify each as foreign-key anchored, alias-resolved, reprojected, historically retained, or requiring a target-repo handoff.
Acceptance:
- the ADR contains the invariant and failure-state tables;
- every current slug-bearing surface has one named treatment and owner;
- an operation interrupted after each phase has a documented safe next action;
- owner transfer and product/runtime rename are explicitly outside this contract rather than silently half-supported.
Result (2026-08-28): accepted STATE-ADR-001 in
docs/adr/ADR-001-repository-rename-identity-contract.md. It defines immutable
State Hub and Forge identities, protected slug aliases, compare-and-set phase
semantics, retry and rollback limits, twelve named failure states, recovery from
every phase, and the treatment/owner inventory for persistence, REST, CLI, MCP,
consistency projections, dashboard queries, events, edge relay state, Forgejo,
local clones, and external consumers. Owner transfer and product/runtime rename
are explicit target-workplan boundaries.
Add durable forge identity, aliases, and rename operations
id: STATE-WP-0085-T02
status: done
priority: high
state_hub_task_id: "c9e6c8c5-c254-5f4d-982c-c161f6ed6d29"
Add the persistence needed to distinguish a repository from its current name. The exact normalization may be decided in T01, but it must represent:
- a forge provider/instance, owner, and immutable repository ID attached to the existing managed repository;
- one canonical slug plus durable prior-slug aliases;
- a rename operation with old/new coordinates, expected repository IDs and commits, current phase, actor, timestamps, evidence, and error state;
- uniqueness rules preventing one live slug or forge identity from resolving to two repository UUIDs.
Backfill must be non-destructive. Repositories whose forge identity cannot be proven remain unverified and cannot be renamed; absence is not guessed from the slug or initial Git commit.
Acceptance:
- migration upgrade and downgrade tests pass;
- the same old slug cannot be claimed by a different live repository while it is a protected alias;
flex-authcan be preflighted as State Hub UUIDfda8ad85-a7d7-4055-8f21-902a533e59dfand Forgejo repository ID42without changing either system;- no migration rewrites workplan, task, progress, decision, token, or SBOM identities.
Result (2026-08-28): migration f3c4d5e6a7b8 adds an explicitly unverified or
verified Forge identity per managed-repository UUID, a global canonical/alias
slug registry, and a phased rename-operation journal. Composite foreign keys
prevent operations for unverified or mismatched repository identities; partial
unique indexes reserve one canonical slug, one active operation per repository,
and one active target slug. Database history guards prevent verified Forge
identity, protected slug, and operation-assertion rewrites or deletion while
leaving phase/evidence/error progress updateable. Existing repositories are
backfilled only with an unverified marker and their current canonical slug;
Forge coordinates are not guessed. Both API and direct classification
registration create the same initial records. PostgreSQL tests prove protected
alias conflicts, unique Forge identity, active-operation locks, a non-mutating
flex-auth/Forgejo-id-42 preflight representation with all existing identities
preserved, isolated migration upgrade/downgrade, and full-chain migration. The
full Python suite passes (765 tests).
Implement preflight, apply, resume, verify, and rollback APIs
id: STATE-WP-0085-T03
status: done
priority: high
state_hub_task_id: "2cb4d7ac-0192-5d46-aa87-7412e99b0cef"
Provide repository-ID-addressed APIs for the lifecycle. Slug-addressed convenience routes may resolve through aliases, but the mutating operation must bind to the stable repository UUID and expected Forgejo ID.
Preflight reports, without mutation:
- current State Hub and Forgejo identity;
- old/new slug availability;
- local and registered host paths;
- source commit and projection readability;
- workplan/task/telemetry baselines and active work;
- affected messages, bindings, interface changes, SBOM data, services, capability entries, fabric nodes, and external handoffs;
- queued edge writes or active operations that make cutover unsafe;
- exact proposed mutations and retained historical values.
Apply performs only the requested phase and uses compare-and-set expectations. Verify compares immutable IDs, commits, counts, relationship checksums, routes, and projection results. Rollback first proves the old slug is available and reports what cannot be reversed automatically.
Acceptance:
- dry-run is byte-for-byte free of persistent changes;
- mutation requires a successful, unexpired preflight token or equivalent compare-and-set evidence plus explicit confirmation;
- repeating any completed phase is a no-op with the same operation ID;
- conflicting slug, wrong Forgejo ID, moved head, unreadable forge, or stale preflight fails closed;
- API tests interrupt and resume after every phase;
- the managed-repository UUID is asserted unchanged throughout.
Implemented 2026-08-29. UUID-addressed endpoints now verify immutable Forgejo
identity, produce HMAC-signed non-mutating preflights, create discoverable
operation journals, apply one compare-and-set phase at a time, verify baseline
identity continuity, and preflight/apply bounded rollback. The Forge adapter
uses authenticated absence proofs and a separate rename credential; API tests
replace it with an in-memory boundary and cannot touch live Forgejo. Resume
recognizes a Forge rename that committed before its journal phase, completed
phase replays are no-ops with the same operation UUID, and rollback recognizes
the corresponding unrecorded-Forge state. Baseline IDs must remain present
while append-only telemetry may grow during the operation. The follow-on
migration permits a protected alias to become canonical only for its own
operation in rollback-preflight; all other alias mutation remains rejected.
Tests cover dry-run persistence, expiry and confirmation, occupied slugs,
queued edge writes, wrong Forge ID, moved head/stale evidence, unreadable Forge,
phase interruption/replay, telemetry append continuity, rollback, trigger
guarding, and full migration upgrade/downgrade. The full Python suite passes
(771 tests).
Make State Hub reads and routing alias-aware
id: STATE-WP-0085-T04
status: done
priority: high
state_hub_task_id: "dcf7102e-ed7a-503e-bf78-db2149f72453"
Resolve prior slugs to the canonical repository identity without falsifying history. At minimum cover:
- repository lookup and dispatch;
- consistency registration and workplan file bindings;
- inbox reads and new-message routing;
- interface-change affected-repository queries;
- work-record identifier aliases;
- repository goals, capabilities, services, SBOM, and token summaries;
- dashboard and state-summary links;
- edge cache/outbox replay produced before or during cutover.
Historical messages keep their recorded sender and recipient. Queries through
the canonical slug include aliased history, and new messages use the canonical
slug. External-source projections such as railiance-fabric are reported as
handoffs and remain visibly stale until their owning source is updated and
reingested.
Acceptance:
- old and new slugs resolve to one repository UUID with canonical/alias status visible in the response;
- old-slug history is visible from the new repository without rewriting stored history;
- a queued old-slug write replays exactly once against the same repository;
- new bindings use the new slug while workplan and task UUIDs remain unchanged;
- external stale references are named rather than silently rewritten.
Implemented one protected-slug resolver and applied it across repository reads,
dispatch, consistency/path binding, inbox routing, interface changes,
work-record identifier migration, goals, capability and service catalogs, SBOM,
token summaries, Fabric projection reads, and dashboard links. Repository
responses expose requested/canonical slug, canonical-or-alias status, aliases,
and named stale external projections. Historical message and interface values
remain unchanged; new writes are canonicalized. An idempotent old-slug message
replay is proven to persist once, while workplan/task UUIDs and repository FKs
remain stable. Verification: 775 Python tests and the 70-page dashboard build
pass (the build retains one pre-existing /docs/intakes broken-link warning).
Add the State Hub CLI and HelixForge orchestration contract
id: STATE-WP-0085-T05
status: done
priority: high
state_hub_task_id: "d85da2ea-8037-5117-a41a-d400ca68bf10"
Expose a non-interactive, machine-readable CLI over the API lifecycle. The final spelling follows existing State Hub CLI conventions; it must provide the equivalent of:
statehub repo rename preflight <old> <new> --json
statehub repo rename apply <operation-id> --phase <phase> --confirm
statehub repo rename status <operation-id> --json
statehub repo rename verify <operation-id> --json
statehub repo rename rollback <operation-id> --confirm
The contract must make it possible for HelixForge to coordinate the Forgejo rename without receiving database access. Forgejo credentials follow the credential-routing catalog and must never be accepted as a command-line value that can appear in process listings.
Acceptance:
- JSON output is stable enough for orchestration and names the next safe action;
- human output distinguishes planned, achieved, failed, and rolled-back phases;
- every mutating command requires an operation ID and explicit confirmation;
- CLI retries preserve operation identity;
- no command logs credentials, authorization headers, or secret-bearing URLs.
Result (2026-08-29): added statehub repo rename
preflight/start/apply/status/verify/rollback commands over the
repository-ID-addressed lifecycle. The versioned
state-hub.repository-rename-cli.v1 JSON envelope reports lifecycle state and
the next safe command; human output distinguishes planned, achieved, failed,
and rolled-back operations. Preflight tokens are never printed and are passed
to start through an exclusive mode-0600 JSON file (or stdin). Evidence and
check inputs receive the same private-file guard, credential-bearing response
fields and URLs are redacted, and no Forgejo credential option exists.
Mutations require a client-owned operation UUID plus the exact rename or
rollback confirmation. State Hub accepts and globally resolves that UUID;
same-intent creation retries remain no-ops after token expiry or a canonical
slug rebind, while changed target/actor intent fails closed. Rollback preflight
and execution are deliberately separate. Wheel force-includes make the
declared statehub entry point installable outside the checkout. Verification:
789 repository tests and the 70-page dashboard build passed before the final
retry hardening; the resulting focused suites pass 14 CLI and 7 API tests, and
a clean wheel installation exposes the complete rename command tree. The
dashboard retains the pre-existing /docs/intakes broken-link warning.
Generate a target-repository migration workplan
id: STATE-WP-0085-T06
status: done
priority: high
state_hub_task_id: "154bdbb3-d3bf-5bac-85d7-eecd88545841"
Add a generator that inspects a registered repository and produces, without overwriting an existing file, a repository-native workplan for adopting a new name. It must use the established workplan prefix from the repository rather than deriving a new prefix from the proposed slug.
The generated plan must contain ordered tasks and gates for:
- local/forge cleanliness and immutable baseline capture;
- repository metadata and workplan-frontmatter preparation;
- explicit product/runtime naming decisions;
- consumer, CI, package, deployment, credential-routing, fabric, SBOM, and documentation inventory;
- State Hub preflight and approval evidence;
- Forgejo rename;
- State Hub identity rebind;
- fresh-clone registration and
fix-consistency; - identity, work-record, telemetry, route, build, and deployment verification;
- rollback decision points and commands;
- soak period, residual handoffs, and final old-checkout cleanup.
The template marks external tasks with their owning repository and never
claims that the target repo can close another repo's work. It starts the live
rename task in wait pending human approval.
Acceptance:
- generation is deterministic for the same preflight snapshot;
- the output passes workplan parsing and DoR/quality-debt checks;
- existing State Hub UUID fields are preserved when present and never invented;
- an existing output path is refused unless an explicit safe overwrite mode is separately designed;
- generated
flex-authplan keeps theFLEX-WP-prefix and includes every NetKingdom security-stack risk named in the preflight; - template snapshot tests cover repositories with active work, archived workplans, missing local paths, private forge visibility, and old aliases.
Result (2026-08-29): added statehub repo rename generate-workplan <old> <new> with a pure deterministic renderer over the registered repository,
captured rename preflight, indexed workplans, and visible repository metadata.
Prefix discovery uses the repository's declared convention when present and
otherwise requires one unambiguous prefix across active and archived workplan
records; it never derives a prefix from the proposed slug. Number allocation
includes archived records, so the fixed flex-auth snapshot selects
FLEX-WP-0019 while retaining FLEX-WP- task/work-record identity.
The generated ready/proposed plan carries DoR evidence and eleven ordered
tasks for baseline capture, metadata preparation, separate product/runtime
naming decisions, consumer/CI/package/deployment/credential/fabric/SBOM/docs
inventory, renewed preflight and approval, Forgejo rename, State Hub rebind,
fresh-clone registration, relationship-aware verification, rollback, soak,
residuals, and old-checkout cleanup. Live rename and destructive cleanup tasks
start in wait. Every captured blocker, warning, active work item, alias, and
external handoff is rendered; an ownership ledger requires exact repository
slugs and prohibits the target plan from closing another repository's work.
Tokens are omitted. Existing UUID-bearing files remain untouched, and no new
state_hub_workstream_id or state_hub_task_id is invented.
Output uses exclusive create with no overwrite/force mode; private preflight
files retain the mode-0600 input guard. Missing checkouts can render from
indexed records only with an explicit output path and remain visibly blocked
for baseline capture. Snapshot/parser/quality tests cover deterministic
flex-auth output, active work, archived numbering, missing paths, unreadable
private Forge state, old aliases, ambiguous prefixes, UUID preservation, and
overwrite refusal. Verification: 801 Python tests and the 70-page dashboard
build pass; a clean wheel installation exposes the generator command. The
dashboard retains the pre-existing /docs/intakes broken-link warning.
Prove failure recovery and telemetry continuity
id: STATE-WP-0085-T07
status: done
priority: high
state_hub_task_id: "5160ad75-d985-5559-895c-7f8012ea76bc"
Build the test and evidence matrix before a live adoption. Include injected failure after each lifecycle phase, stale preflight, double submission, conflicting rename, forge redirect, unavailable old slug for rollback, State Hub outage, edge-outbox replay, unreadable private repository, and a fresh clone whose remote points at the wrong repository ID.
Compare before/after baselines for repository UUID, workplans, tasks, progress, decisions, token events and totals, SBOM snapshots, active dispatch, aliases, messages, and file bindings. Evidence must distinguish a preserved count from a preserved relationship: equal row counts with records attached to a new UUID is a failure.
Acceptance:
- automated tests prove safe resume after every injected interruption;
- work-record and telemetry relationship checksums are unchanged;
- old-slug reads remain available through the alias;
- verification fails if a record is detached and recreated even when aggregate counts match;
- rename events and operational metrics expose phase duration, retries, failures, rollback, and verification outcome without secrets.
Result (2026-08-29): continuity baselines now retain immutable relationship
tuples and checksums for repository identity, workplans, tasks, progress,
decisions, token events and totals, SBOM, active dispatch, protected routes,
historical messages, and file bindings. Verification compares every original
relationship while permitting append-only history, and phase-aware route checks
prove the old slug remains an alias. Equal-count workplan/token replacements
attached to another repository are rejected. Fresh-clone evidence must attest
the expected Forge numeric ID and baseline head; Forge redirects are rejected
as the wrong coordinate. The operation journal records phase durations,
attempts, retries, failures by phase, rollback attempts/outcome, and verification
outcome. Credential-free phase/failure/verification/rollback/completion events
reference the durable journal without publishing tokens, operator evidence,
URLs, or error details. Automated coverage injects failure after every forward
phase and covers stale evidence, duplicate/conflicting requests, redirects,
rollback route loss and recovery, State Hub outage, edge replay, unreadable
Forge state, and wrong-clone identity. Evidence matrix:
docs/evidence/STATE-WP-0085-T07-repository-rename-recovery-matrix.md.
Verification: 810 Python tests and the 70-page dashboard build pass. One known
dashboard /docs/intakes to /suggestions broken-link warning and one existing
SQLAlchemy async cancellation warning remain outside this task.
Document operations and repository-boundary handoffs
id: STATE-WP-0085-T08
status: done
priority: medium
state_hub_task_id: "06b6cde4-0428-5467-b2db-d957fde3d8e9"
Document the operator workflow, API/CLI contract, dashboard interpretation, recovery playbook, and target-repository template. Include separate checklists for repository-only rename and broader product/runtime rename.
Define the handoff format for slug-bearing external sources. A handoff names the source repository, old/new slug, affected paths or graph IDs, required reingest/verification, owning workplan/task, and non-secret evidence. It does not mutate another repository or park the obligation only in prose.
Acceptance:
- an operator can determine the achieved phase and next safe command without reading source code;
- the runbook says which cleanup is deliberately last and why;
- rollback limitations and irreversible external effects are explicit;
- State Hub/Forgejo/HelixForge/target-repository ownership is unambiguous;
- examples use placeholder credentials and never secret values.
Result (2026-08-29): Delivered the operator runbook in
docs/repository-rename-operations.md, the dashboard reference in
dashboard/src/docs/repository-renames.md, and the versioned
state-hub.repository-rename-handoff.v1 schema plus placeholder-only example.
The generated target workplan now requires owner-backed handoff records and
exact fresh-clone/Forge-ID/head evidence before continuity completion. Focused
contract tests pass (29), as do all 813 Python tests and the 71-page dashboard
build. The existing /docs/intakes to /suggestions broken-link warning and
one existing async cancellation warning remain outside T08.
Generate and review the flex-auth adoption plan
id: STATE-WP-0085-T09
status: wait
priority: high
state_hub_task_id: "df34f6ec-d137-52d0-93c4-3756a821097f"
Blocked on T01-T08 and deployment of the capability.
Run the completed generator for flex-auth to access-engine, commit the
resulting FLEX-WP-* file in the target repository, and synchronize it into
State Hub before any live rename. Review it against the current Forgejo head,
State Hub baselines, active FLEX-WP-0017, NetKingdom security-stack
deployments, consumer repositories, fabric records, CI/image publishing, and
credential routes.
This task ends at an approved, repository-owned migration plan. The live
Forgejo rename and security-stack migration execute under that generated plan,
not under STATE-WP-0085.
Acceptance:
- the generated workplan is committed and has its own State Hub workplan UUID;
- it records DoR assessment and an explicit human gate for the live rename;
- preflight proves local and Forgejo commits match and captures Forgejo
repository ID
42plus the existing State Hub repository UUID; - rollback and "do not remove the old checkout yet" gates are actionable;
- every external consequence has a live work record or a named verification owner;
- no State Hub, Forgejo, local-clone, deployment, or consumer mutation has been performed merely to generate the plan.
Workplan completion
STATE-WP-0085 can finish only when T01-T08 are complete, T09 has produced the
reviewed repository-owned adoption plan, all implementation tests pass, and the
State Hub capability is deployed where the live migration will call it.
Any remaining product rename, external consumer change, deployment cutover, or
soak obligation must exist as a live record in its owning repository before
this workplan is marked finished. The successful flex-auth to
access-engine live cutover is deliberately not a completion criterion here;
it is the outcome of the generated target-repository workplan.