From b08a5d43a0c8df93ce4777b9c03f002083d98275 Mon Sep 17 00:00:00 2001 From: tegwick Date: Fri, 28 Aug 2026 21:01:21 +0200 Subject: [PATCH] docs(workplan): plan lineage-preserving repository renames Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a049a4-ee9f-78e1-9d66-2cb0f9bea3e3 --- WORK-RECORDS.md | 10 + ...85-repository-lineage-preserving-rename.md | 462 ++++++++++++++++++ 2 files changed, 472 insertions(+) create mode 100644 workplans/STATE-WP-0085-repository-lineage-preserving-rename.md diff --git a/WORK-RECORDS.md b/WORK-RECORDS.md index aef17f1..49efa45 100644 --- a/WORK-RECORDS.md +++ b/WORK-RECORDS.md @@ -55,6 +55,7 @@ | workplan | STATE-WP-0082 | finished | — | workplans/STATE-WP-0082-multi-owner-review-contracts-and-receipts.md | | workplan | STATE-WP-0083 | active | — | workplans/STATE-WP-0083-forge-derived-projection-reset.md | | workplan | STATE-WP-0084 | active | — | workplans/STATE-WP-0084-forge-read-for-private-repositories.md | +| workplan | STATE-WP-0085 | ready | — | workplans/STATE-WP-0085-repository-lineage-preserving-rename.md | | task | STATE-WP-ADHOC-2026-06-04-T01 | done | — | workplans/ADHOC-2026-06-04.md | | task | STATE-WP-ADHOC-2026-07-01-T01 | done | — | workplans/ADHOC-2026-07-01.md | | task | STATE-WP-ADHOC-2026-07-01-T02 | done | — | workplans/ADHOC-2026-07-01.md | @@ -320,3 +321,12 @@ | task | STATE-WP-0084-T02 | progress | — | workplans/STATE-WP-0084-forge-read-for-private-repositories.md | | task | STATE-WP-0084-T03 | progress | — | workplans/STATE-WP-0084-forge-read-for-private-repositories.md | | task | STATE-WP-0084-T04 | wait | — | workplans/STATE-WP-0084-forge-read-for-private-repositories.md | +| task | STATE-WP-0085-T01 | todo | — | workplans/STATE-WP-0085-repository-lineage-preserving-rename.md | +| task | STATE-WP-0085-T02 | todo | — | workplans/STATE-WP-0085-repository-lineage-preserving-rename.md | +| task | STATE-WP-0085-T03 | todo | — | workplans/STATE-WP-0085-repository-lineage-preserving-rename.md | +| task | STATE-WP-0085-T04 | todo | — | workplans/STATE-WP-0085-repository-lineage-preserving-rename.md | +| task | STATE-WP-0085-T05 | todo | — | workplans/STATE-WP-0085-repository-lineage-preserving-rename.md | +| task | STATE-WP-0085-T06 | todo | — | workplans/STATE-WP-0085-repository-lineage-preserving-rename.md | +| task | STATE-WP-0085-T07 | todo | — | workplans/STATE-WP-0085-repository-lineage-preserving-rename.md | +| task | STATE-WP-0085-T08 | todo | — | workplans/STATE-WP-0085-repository-lineage-preserving-rename.md | +| task | STATE-WP-0085-T09 | wait | — | workplans/STATE-WP-0085-repository-lineage-preserving-rename.md | diff --git a/workplans/STATE-WP-0085-repository-lineage-preserving-rename.md b/workplans/STATE-WP-0085-repository-lineage-preserving-rename.md new file mode 100644 index 0000000..b5dff8a --- /dev/null +++ b/workplans/STATE-WP-0085-repository-lineage-preserving-rename.md @@ -0,0 +1,462 @@ +--- +id: STATE-WP-0085 +type: workplan +title: "Lineage-preserving repository rename workflow and adoption-plan generator" +domain: infotech +repo: state-hub +status: ready +owner: codex +topic_slug: infotech +created: "2026-08-28" +updated: "2026-08-28" +reviewed_at: "2026-08-28" +reviewed_by: codex +reviewed_against_commit: "41d80429a77ffeb640f4b34091ebee5c91585373" +quality_dor: DoR-Ok +quality_dor_at: "2026-08-28" +quality_dor_by: codex +related: + - CUST-ADR-012 + - STATE-WP-0083 + - STATE-WP-0084 +--- + +# 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 + +```text +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 + +```task +id: STATE-WP-0085-T01 +status: todo +priority: high +``` + +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. + +## Add durable forge identity, aliases, and rename operations + +```task +id: STATE-WP-0085-T02 +status: todo +priority: high +``` + +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. + +## Implement preflight, apply, resume, verify, and rollback APIs + +```task +id: STATE-WP-0085-T03 +status: todo +priority: high +``` + +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 + +```task +id: STATE-WP-0085-T04 +status: todo +priority: high +``` + +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 + +```task +id: STATE-WP-0085-T05 +status: todo +priority: high +``` + +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: + +```text +statehub repo rename preflight --json +statehub repo rename apply --phase --confirm +statehub repo rename status --json +statehub repo rename verify --json +statehub repo rename rollback --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 + +```task +id: STATE-WP-0085-T06 +status: todo +priority: high +``` + +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 + +```task +id: STATE-WP-0085-T07 +status: todo +priority: high +``` + +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 + +```task +id: STATE-WP-0085-T08 +status: todo +priority: medium +``` + +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 + +```task +id: STATE-WP-0085-T09 +status: wait +priority: high +``` + +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.