state-hub/workplans/STATE-WP-0085-repository-lineage-preserving-rename.md
tegwick 8988a093f2
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
feat: persist repository rename identity
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a049a4-ee9f-78e1-9d66-2cb0f9bea3e3
2026-08-28 22:08:21 +02:00

21 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-28 2026-08-28 codex 41d80429a7 DoR-Ok 2026-08-28 codex
CUST-ADR-012
STATE-WP-0083
STATE-WP-0084
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:

  1. A rename does not create a second managed_repos row.
  2. The State Hub repository UUID is unchanged.
  3. The Forgejo repository numeric ID and selected source commit are unchanged.
  4. Existing workplan IDs, task IDs, hub UUIDs, progress events, decisions, and token events are unchanged.
  5. Existing work-record prefixes and filenames are not re-keyed merely because the repository slug changes.
  6. The old slug remains a durable alias. Historical records are not mass rewritten to pretend the old name never existed.
  7. Every phase is idempotent and resumable. A retry reports the achieved phase rather than applying a second rename.
  8. No old clone, alias, route, or rollback input is removed before verification succeeds and the target repository's migration workplan authorises cleanup.
  9. Forge redirects are compatibility evidence, not a substitute for updating canonical remotes and consumers.
  10. 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-auth to access-engine rehearsal and generated repository workplan as the first adoption handoff.

Out of scope

  • Executing the live flex-auth Forgejo 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 become access-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-auth can be preflighted as State Hub UUID fda8ad85-a7d7-4055-8f21-902a533e59df and Forgejo repository ID 42 without 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: todo
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.

Make State Hub reads and routing alias-aware

id: STATE-WP-0085-T04
status: todo
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.

Add the State Hub CLI and HelixForge orchestration contract

id: STATE-WP-0085-T05
status: todo
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.

Generate a target-repository migration workplan

id: STATE-WP-0085-T06
status: todo
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:

  1. local/forge cleanliness and immutable baseline capture;
  2. repository metadata and workplan-frontmatter preparation;
  3. explicit product/runtime naming decisions;
  4. consumer, CI, package, deployment, credential-routing, fabric, SBOM, and documentation inventory;
  5. State Hub preflight and approval evidence;
  6. Forgejo rename;
  7. State Hub identity rebind;
  8. fresh-clone registration and fix-consistency;
  9. identity, work-record, telemetry, route, build, and deployment verification;
  10. rollback decision points and commands;
  11. 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-auth plan keeps the FLEX-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.

Prove failure recovery and telemetry continuity

id: STATE-WP-0085-T07
status: todo
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.

Document operations and repository-boundary handoffs

id: STATE-WP-0085-T08
status: todo
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.

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 42 plus 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.