diff --git a/config/hub-record-authority.yaml b/config/hub-record-authority.yaml deleted file mode 100644 index 7d5f80a..0000000 --- a/config/hub-record-authority.yaml +++ /dev/null @@ -1,64 +0,0 @@ -schema: repo-manager.hub-record-authority.v1 -updated: "2026-08-21" -workplan_task: RMGR-WP-0005-T08 - -classes: - file-derived: - authority: repository - offline: write-and-commit-source-file - hub-native-append: - authority: hub-core - offline: append-to-idempotent-outbox - hub-native-control: - authority: owning-central-hub - offline: no-generic-replay - derived-cache: - authority: upstream-source - offline: rebuild-or-refresh - retired: - authority: archived-provenance - offline: reject-writes - -records: - agent_messages: {class: hub-native-control, owner: hub-core} - capability_catalog: {class: file-derived, owner: repo-manager, transition: retire-direct-db-writes} - capability_requests: {class: file-derived, owner: repo-manager, transition: register-entry-files} - contributions: {class: file-derived, owner: repo-manager} - decisions: {class: file-derived, owner: repo-manager, transition: retire-direct-db-writes} - doi_cache: {class: derived-cache, owner: repo-manager} - domain_goals: {class: hub-native-control, owner: hub-core} - domains: {class: hub-native-control, owner: hub-core} - extension_points: {class: file-derived, owner: repo-manager} - fabric_graph_edges: {class: derived-cache, owner: fin-hub} - fabric_graph_imports: {class: derived-cache, owner: fin-hub} - fabric_graph_nodes: {class: derived-cache, owner: fin-hub} - intake_notes: {class: file-derived, owner: repo-manager, transition: retire-direct-db-writes} - intakes: {class: file-derived, owner: repo-manager, transition: retire-direct-db-writes} - interface_changes: {class: hub-native-control, owner: hub-core} - legacy_interface_usage_buckets: {class: derived-cache, owner: hub-core} - legacy_interfaces: {class: derived-cache, owner: hub-core} - managed_repos: {class: file-derived, owner: repo-manager, note: composite-repository-projection} - progress_events: {class: hub-native-append, owner: hub-core} - repo_goals: {class: file-derived, owner: repo-manager} - sbom_entries: {class: derived-cache, owner: repo-manager} - sbom_snapshots: {class: derived-cache, owner: repo-manager} - service_catalog: {class: hub-native-control, owner: ops-hub} - service_cloud: {class: hub-native-control, owner: ops-hub} - service_first_party: {class: hub-native-control, owner: ops-hub} - service_self_hosted: {class: hub-native-control, owner: ops-hub} - service_third_party: {class: hub-native-control, owner: ops-hub} - suggestion_notes: {class: retired, owner: archive} - suggestion_relevance_bumps: {class: retired, owner: archive} - suggestions: {class: retired, owner: archive} - tasks: {class: file-derived, owner: repo-manager} - td_notes: {class: file-derived, owner: repo-manager} - technical_debt: {class: file-derived, owner: repo-manager} - token_events: {class: hub-native-append, owner: hub-core} - topics: {class: hub-native-control, owner: hub-core, transition: retire-legacy-topic-spine} - tpsc_catalog: {class: hub-native-control, owner: ops-hub} - tpsc_entries: {class: derived-cache, owner: repo-manager} - tpsc_snapshots: {class: derived-cache, owner: repo-manager} - workplan_dependencies: {class: file-derived, owner: repo-manager} - workplan_launch_requests: {class: hub-native-control, owner: activity-core} - workplans: {class: file-derived, owner: repo-manager} - write_idempotency_keys: {class: derived-cache, owner: hub-core} diff --git a/docs/evidence/RMGR-WP-0005-orphan-disposition-2026-08-21.md b/docs/evidence/RMGR-WP-0005-orphan-disposition-2026-08-21.md deleted file mode 100644 index 4cc51ca..0000000 --- a/docs/evidence/RMGR-WP-0005-orphan-disposition-2026-08-21.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -id: RMGR-EVIDENCE-0005-ORPHANS-20260821 -type: evidence -workplan_task: RMGR-WP-0005-T09 -created: "2026-08-21" -source: local State Hub at http://127.0.0.1:8000 ---- - -# Local-cache orphan disposition rebaseline - -The 2026-08-17 baseline of 28 workplans without `backing_filename` is stale. -On 2026-08-21 the local State Hub returned 224 unbound rows: - -| Status | Count | Disposition class | -| --- | ---: | --- | -| `active` | 1 | live, broken link | -| `blocked` | 1 | live, broken link | -| `proposed` | 3 | live, broken link | -| `ready` | 2 | live, broken link | -| `finished` | 201 | closed provenance | -| `archived` | 16 | closed provenance | - -Every one of the seven live rows has a matching repository file. There are no -confirmed live hub-first workplans in this snapshot. - -| Hub slug | Repository file | -| --- | --- | -| `nk-wp-0027` | `net-kingdom/workplans/NK-WP-0027-reef-placement-reconciliation.md` | -| `state-wp-0081` | `state-hub/workplans/STATE-WP-0081-cluster-self-sufficiency-and-registrar.md` | -| `railiance-wp-0022` | `railiance-platform/workplans/RAILIANCE-WP-0022-agent-high-risk-boundary-coverage.md` | -| `railiance-wp-0023` | `railiance-platform/workplans/RAILIANCE-WP-0023-hub-core-candidate-credential-lanes.md` | -| `rail-en-wp-0001` | `railiance-enablement/workplans/RAIL-EN-WP-0001-private-by-default-templates.md` | -| `rail-ho-wp-0010` | `railiance-infra/workplans/RAIL-HO-WP-0010-new-reef-ports-need-a-grant.md` | -| `ops-wp-0003` | `ops-hub/workplans/OPS-WP-0003-extension-contract-alignment.md` | - -The 217 closed rows remain cheap historical provenance. They need not be -reconstructed as files, but the cache-rebuild procedure must export or retain -them before replacing the local database. Repairing the seven live bindings is -the remaining prerequisite for T07. - -## Reproduction - -The counts came from `GET /workplans/`, selecting rows whose -`backing_filename` is null and grouping by status. Repository UUIDs were joined -to `GET /repos/`; canonical ids and exact titles were then searched in each -reported checkout. This evidence records no secret or credential value. diff --git a/docs/hub-record-authority_v1.md b/docs/hub-record-authority_v1.md deleted file mode 100644 index d5237d9..0000000 --- a/docs/hub-record-authority_v1.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -id: RMGR-CONTRACT-AUTHORITY-0001 -type: contract -title: "State Hub record authority and offline behaviour" -version: "1" -status: draft-reviewable -created: "2026-08-21" -updated: "2026-08-21" -workplan_task: RMGR-WP-0005-T08 ---- - -# State Hub record authority and offline behaviour v1 - -`config/hub-record-authority.yaml` classifies every table imported by the State -Hub model package on 2026-08-21. It is the machine-readable routing contract; -this document defines the meaning of its classes. - -| Class | Truth source | Offline behaviour | Central write rule | -| --- | --- | --- | --- | -| `file-derived` | Repository file and Git history | Change the source file and commit. The commit is the write. | Re-index after Git settles; reject direct state pushes. | -| `hub-native-append` | The named central hub | Append to an idempotent local outbox and replay. | Accept append-only events with a stable source identity. | -| `hub-native-control` | The named central hub | Do not apply generic append-only replay. Stay read-only unless the record type has an ordered, idempotent command contract. | Accept commands at the one authoritative owner. | -| `derived-cache` | A named upstream source, repository file, log, or runtime observation | Do not buffer. Rebuild or refresh. | Replaceable projection only. | -| `retired` | Archived provenance | Reject new writes. | Read-only until physical deletion. | - -The first class is ADR-010's file-derived side. The next two are subdivisions of -its hub-native side. This subdivision is necessary because the current schema -contains mutable control records: message read/archive markers, launch-request -status, service catalog changes, and domain/topic administration are not -append-only events and cannot safely be reconciled by unordered union. A generic -offline buffer is therefore valid only for `hub-native-append`. - -Several current State Hub REST endpoints still mutate records classified as -file-derived. Those endpoints are compatibility surfaces during extraction; -their existence does not confer authority. Decisions and intakes are -file-derived under the ratified work-record standard and Repo Manager's governed -commands, superseding ADR-010's older examples. - -`managed_repos` is a composite projection. Repository identity, purpose, and -classification derive from repository declarations and Forge; host paths and -observation timestamps are replaceable observations. No field in that row makes -the database a source of repository truth. - -## Consequences for the offline edge - -- Buffer only progress and token event appends under the generic replay path. -- Route file-derived commands to Repo Manager; when central is absent, commit - the file and let later indexing observe it. -- Keep control-plane commands online-only until their owning hub publishes - ordering and idempotency semantics. Queuing them in the append-only stream - would silently invent a conflict policy. -- Rebuild caches and reject writes to retired suggestion tables. - -This narrows the offline-buffer part of `STATE-WP-0068`; it does not authorize -changes in repositories owned by hub-core, activity-core, ops-hub, or fin-hub. diff --git a/docs/work-record-uuid-derivation_v1.md b/docs/work-record-uuid-derivation_v1.md index c54bd19..2affe4f 100644 --- a/docs/work-record-uuid-derivation_v1.md +++ b/docs/work-record-uuid-derivation_v1.md @@ -39,17 +39,8 @@ silently disambiguated with a repository slug. ```bash rmgr identifier derive --namespace --record-id RMGR-WP-0005 rmgr identifier preflight --root /path/to/fleet -rmgr identifier migration-plan --root /path/to/fleet \ - --namespace --output uuid-migration.json ``` -`migration-plan` is non-mutating. Its versioned JSON output preserves every -current-to-derived UUID mapping and marks each repository as one atomic apply -unit. A collision or malformed live identifier makes that whole repository -ineligible while leaving unaffected repositories visible in the plan. Existing -output files are not replaced unless `--force` is explicit. +Activation and bulk migration remain separate governed steps. Publishing this +function does not retroactively rewrite existing identifiers. -Activation and applying a bulk migration remain separate governed steps. -Publishing or planning this function does not retroactively rewrite existing -identifiers. The caller must supply the namespace explicitly until the current -fleet namespace is declared by the namespace owner under ADR-011. diff --git a/intakes/intakes.md b/intakes/intakes.md index ac9830d..08a7488 100644 --- a/intakes/intakes.md +++ b/intakes/intakes.md @@ -18,22 +18,3 @@ created: '2026-08-21T20:09:23.942286+00:00' updated: '2026-08-21T20:09:23.942286+00:00' state_hub_intake_id: "01a025f3-40b0-7243-8002-dbe4609a6245" ``` - -## RMGR-IN-0002 — Assign dormant shared prefixes before their next allocation - -```yaml -id: RMGR-IN-0002 -kind: intake -title: Assign dormant shared prefixes before their next allocation -status: open -origin: residual -origin_ref: RMGR-WP-0004 -priority: medium -owner: repo-manager -description: Before any new workplan is allocated under WHYNOT-WP, OPS-WP, or REPO-WP, - assign one owner and distinct successor prefixes to the other repositories. Historical - finished/archived files remain frozen. Re-run rmgr prefix-uniqueness and identifier - preflight after assignment. -created: '2026-08-21T20:34:42.177493+00:00' -updated: '2026-08-21T20:34:42.177493+00:00' -``` diff --git a/src/repo_manager/cli.py b/src/repo_manager/cli.py index 52b46ac..9a1e21e 100644 --- a/src/repo_manager/cli.py +++ b/src/repo_manager/cli.py @@ -286,14 +286,6 @@ def main(argv: list[str] | None = None) -> int: p_id_derive.add_argument("--record-id", required=True) p_id_preflight = identifier_sub.add_parser("preflight", help="Scan live identifier collisions") p_id_preflight.add_argument("--root", default=".") - p_id_plan = identifier_sub.add_parser( - "migration-plan", - help="Emit a non-mutating, per-repository old-to-derived UUID plan", - ) - p_id_plan.add_argument("--root", default=".") - p_id_plan.add_argument("--namespace", required=True) - p_id_plan.add_argument("--output", default=None, help="Write the provenance mapping as JSON") - p_id_plan.add_argument("--force", action="store_true", help="Replace an existing --output file") args = parser.parse_args(argv) @@ -577,11 +569,7 @@ def main(argv: list[str] | None = None) -> int: if not args.identifier_command: p_identifier.print_help() return 2 - from repo_manager.identifiers import ( - derive_work_record_uuid, - plan_identifier_migration, - scan_live_identifier_collisions, - ) + from repo_manager.identifiers import derive_work_record_uuid, scan_live_identifier_collisions if args.identifier_command == "derive": try: @@ -595,26 +583,8 @@ def main(argv: list[str] | None = None) -> int: "record_id": args.record_id, "uuid": str(derived), } - elif args.identifier_command == "preflight": - result = scan_live_identifier_collisions(Path(args.root)) else: - try: - result = plan_identifier_migration(Path(args.root), args.namespace) - except ValueError as exc: - print(json.dumps({"ok": False, "error": str(exc)}, indent=2)) - return 1 - if args.output: - output = Path(args.output) - if output.exists() and not args.force: - print( - json.dumps( - {"ok": False, "error": f"output exists: {output}; use --force to replace"}, - indent=2, - ) - ) - return 1 - output.parent.mkdir(parents=True, exist_ok=True) - output.write_text(json.dumps(result, indent=2) + "\n", encoding="utf-8") + result = scan_live_identifier_collisions(Path(args.root)) print(json.dumps(result, indent=2)) return 0 if result.get("ok") else 1 diff --git a/src/repo_manager/identifiers.py b/src/repo_manager/identifiers.py index 9781dda..c93f07e 100644 --- a/src/repo_manager/identifiers.py +++ b/src/repo_manager/identifiers.py @@ -33,33 +33,6 @@ def derive_work_record_uuid(namespace: str, identifier: str) -> uuid.UUID: return uuid.uuid5(DERIVATION_NAMESPACE_UUID, derivation_name(namespace, identifier)) -def _migration_mapping( - *, - namespace: str, - repo: Path, - path: str, - kind: str, - identifier: str, - current_uuid: str | None, -) -> dict[str, str | None]: - derived_uuid = str(derive_work_record_uuid(namespace, identifier)) - if not current_uuid: - action = "assign" - elif current_uuid == derived_uuid: - action = "unchanged" - else: - action = "replace" - return { - "repo": repo.name, - "path": path, - "kind": kind, - "record_id": identifier, - "current_uuid": current_uuid, - "derived_uuid": derived_uuid, - "action": action, - } - - def scan_live_identifier_collisions(root: Path) -> dict[str, Any]: """Report live workplan/task identifiers that cannot safely be derived.""" by_id: dict[str, list[dict[str, str]]] = defaultdict(list) @@ -93,99 +66,3 @@ def scan_live_identifier_collisions(root: Path) -> dict[str, Any]: "safe_to_derive": not collisions, } - -def plan_identifier_migration(root: Path, namespace: str) -> dict[str, Any]: - """Plan a live-record UUID migration without changing files or databases. - - The report is the durable old-to-derived mapping required by RMGR-WP-0005. - Eligibility is deliberately computed per repository: a repository with one - colliding or malformed live identifier is skipped as a whole. - """ - # Validate even for an empty fleet. - derivation_name(namespace, "RMGR-WP-0000") - root = root.resolve() - collision_report = scan_live_identifier_collisions(root) - collision_ids = set(collision_report["collisions"]) - repositories: list[dict[str, Any]] = [] - totals = {"repositories": 0, "eligible": 0, "skipped": 0, "records": 0, "replace": 0, "assign": 0, "unchanged": 0} - - for repo in iter_repo_roots(root): - mappings: list[dict[str, str | None]] = [] - blockers: list[dict[str, str]] = [] - for path in iter_workplan_files(repo): - parsed = parse_workplan_file(path, repo_root=repo) - if parsed.status not in LIVE_WORKPLAN_STATUSES: - continue - if not parsed.id: - blockers.append({"path": parsed.path, "reason": "live workplan has no canonical id"}) - continue - if parsed.id in collision_ids: - blockers.append({"path": parsed.path, "record_id": parsed.id, "reason": "live identifier collision"}) - try: - mappings.append( - _migration_mapping( - namespace=namespace, - repo=repo, - path=parsed.path, - kind="workplan", - identifier=parsed.id, - current_uuid=parsed.state_hub_workstream_id, - ) - ) - except ValueError as exc: - blockers.append({"path": parsed.path, "record_id": parsed.id, "reason": str(exc)}) - - for task in parsed.tasks: - if task.status in {"done", "cancel"}: - continue - if not task.id: - blockers.append({"path": parsed.path, "reason": "unfinished task has no canonical id"}) - continue - if task.id in collision_ids: - blockers.append({"path": parsed.path, "record_id": task.id, "reason": "live identifier collision"}) - try: - mappings.append( - _migration_mapping( - namespace=namespace, - repo=repo, - path=parsed.path, - kind="task", - identifier=task.id, - current_uuid=task.state_hub_task_id, - ) - ) - except ValueError as exc: - blockers.append({"path": parsed.path, "record_id": task.id, "reason": str(exc)}) - - if not mappings and not blockers: - continue - eligible = not blockers - repositories.append( - { - "repo": repo.name, - "path": str(repo), - "eligible": eligible, - "atomic_unit": True, - "blockers": blockers, - "mappings": mappings, - } - ) - totals["repositories"] += 1 - totals["eligible" if eligible else "skipped"] += 1 - totals["records"] += len(mappings) - for mapping in mappings: - totals[str(mapping["action"])] += 1 - - return { - "schema": "repo-manager.identifier-migration-plan.v1", - "ok": totals["skipped"] == 0, - "ready_to_apply": totals["skipped"] == 0, - "root": str(root), - "namespace": namespace.strip(), - "derivation_version": DERIVATION_VERSION, - "namespace_uuid": str(DERIVATION_NAMESPACE_UUID), - "scope": "live workplans and unfinished tasks", - "apply_policy": "all-or-nothing per repository", - "totals": totals, - "repositories": repositories, - } diff --git a/tests/test_hub_record_authority.py b/tests/test_hub_record_authority.py deleted file mode 100644 index af58161..0000000 --- a/tests/test_hub_record_authority.py +++ /dev/null @@ -1,59 +0,0 @@ -from pathlib import Path - -import yaml - -EXPECTED_STATE_HUB_TABLES = { - "agent_messages", - "capability_catalog", - "capability_requests", - "contributions", - "decisions", - "doi_cache", - "domain_goals", - "domains", - "extension_points", - "fabric_graph_edges", - "fabric_graph_imports", - "fabric_graph_nodes", - "intake_notes", - "intakes", - "interface_changes", - "legacy_interface_usage_buckets", - "legacy_interfaces", - "managed_repos", - "progress_events", - "repo_goals", - "sbom_entries", - "sbom_snapshots", - "service_catalog", - "service_cloud", - "service_first_party", - "service_self_hosted", - "service_third_party", - "suggestion_notes", - "suggestion_relevance_bumps", - "suggestions", - "tasks", - "td_notes", - "technical_debt", - "token_events", - "topics", - "tpsc_catalog", - "tpsc_entries", - "tpsc_snapshots", - "workplan_dependencies", - "workplan_launch_requests", - "workplans", - "write_idempotency_keys", -} - - -def test_every_state_hub_table_has_one_authority_class() -> None: - path = Path(__file__).parents[1] / "config" / "hub-record-authority.yaml" - document = yaml.safe_load(path.read_text(encoding="utf-8")) - classes = set(document["classes"]) - records = document["records"] - - assert set(records) == EXPECTED_STATE_HUB_TABLES - assert {record["class"] for record in records.values()} <= classes - assert all(record.get("owner") for record in records.values()) diff --git a/tests/test_identifiers.py b/tests/test_identifiers.py index 202d013..4171f6b 100644 --- a/tests/test_identifiers.py +++ b/tests/test_identifiers.py @@ -4,11 +4,7 @@ from pathlib import Path import pytest -from repo_manager.identifiers import ( - derive_work_record_uuid, - plan_identifier_migration, - scan_live_identifier_collisions, -) +from repo_manager.identifiers import derive_work_record_uuid, scan_live_identifier_collisions def _workplan(path: Path, identifier: str, status: str, task_status: str = "todo") -> None: @@ -52,48 +48,3 @@ def test_preflight_blocks_live_collision_but_ignores_archived_history(tmp_path: _workplan(two / "workplans" / "two.md", "SHARED-WP-0001", "archived") report = scan_live_identifier_collisions(tmp_path) assert report["ok"] is True - - -def test_migration_plan_preserves_mapping_and_is_atomic_per_repo(tmp_path: Path) -> None: - one = tmp_path / "one" - two = tmp_path / "two" - _workplan(one / "workplans" / "one.md", "ONE-WP-0001", "active") - _workplan(two / "workplans" / "two.md", "TWO-WP-0001", "ready", task_status="done") - - report = plan_identifier_migration(tmp_path, "fleet-a") - - assert report["ok"] is True - assert report["apply_policy"] == "all-or-nothing per repository" - assert report["totals"] == { - "repositories": 2, - "eligible": 2, - "skipped": 0, - "records": 3, - "replace": 0, - "assign": 3, - "unchanged": 0, - } - one_plan = next(item for item in report["repositories"] if item["repo"] == "one") - assert one_plan["atomic_unit"] is True - assert {item["record_id"] for item in one_plan["mappings"]} == { - "ONE-WP-0001", - "ONE-WP-0001-T01", - } - assert all(item["current_uuid"] is None for item in one_plan["mappings"]) - - -def test_migration_plan_skips_entire_repo_affected_by_collision(tmp_path: Path) -> None: - one = tmp_path / "one" - two = tmp_path / "two" - _workplan(one / "workplans" / "one.md", "SHARED-WP-0001", "active") - _workplan(one / "workplans" / "safe.md", "ONE-WP-0002", "active") - _workplan(two / "workplans" / "two.md", "SHARED-WP-0001", "ready") - - report = plan_identifier_migration(tmp_path, "fleet-a") - - assert report["ok"] is False - assert report["totals"]["skipped"] == 2 - one_plan = next(item for item in report["repositories"] if item["repo"] == "one") - assert one_plan["eligible"] is False - assert any(item["record_id"] == "ONE-WP-0002" for item in one_plan["mappings"]) - assert any(item["reason"] == "live identifier collision" for item in one_plan["blockers"]) diff --git a/workplans/RMGR-WP-0004-repository-standards-conformance.md b/workplans/RMGR-WP-0004-repository-standards-conformance.md index cdbf029..0b61aff 100644 --- a/workplans/RMGR-WP-0004-repository-standards-conformance.md +++ b/workplans/RMGR-WP-0004-repository-standards-conformance.md @@ -4,7 +4,7 @@ type: workplan title: "Repository standards conformance and governed scaffolding" domain: infotech repo: repo-manager -status: finished +status: active owner: codex topic_slug: infotech created: "2026-08-16" @@ -86,7 +86,7 @@ anti-patterns (`INTENT.md`+`GOAL.md`, `PRJ-WP-`). Index: ```task id: RMGR-WP-0004-T02 -status: done +status: progress priority: high state_hub_task_id: "2c9b0cb1-f0f0-40f7-83ef-1828298338d3" ``` @@ -106,14 +106,11 @@ Known first findings, both live today: - every `prj-` repo would collide on workplan prefix `PRJ-WP-`, because the prefix is derived from the flavor marker rather than from the project. -**Result (2026-08-21):** `rmgr conform` reports `missing` vs -`contradictory` and flags both known findings. The earlier C-15 gate is gone: +**Progress (2026-08-21):** `rmgr conform` reports `missing` vs +`contradictory` and flags both known findings. Remaining: call from the +consistency lane / STATE-WP-0080 guard. The earlier C-15 gate is gone: `RMGR-WP-0005-T06` is complete, so this task is no longer `todo` in substance. -The compatibility call is now live as State Hub consistency check C-35 -(`state-hub` commit `b9d9ffe`). It executes the Repo Manager command and -projects its findings without copying flavor rules into the retiring hub. - ## Own governed scaffolding ```task @@ -154,7 +151,7 @@ Durable flavors get `INTENT.md` and an optional foundation workplan. ```task id: RMGR-WP-0004-T04 -status: done +status: wait priority: medium state_hub_task_id: "8cd3ba11-b16b-4910-8bf6-651a24d47b8c" ``` @@ -169,13 +166,6 @@ running it on a `prj-` repo produces the standard's session order — This matters beyond first registration: regeneration runs fleet-wide, so a flavor-blind template silently re-breaks conformant repos. -Result (2026-08-21): current generator and fleet output were re-audited rather -than changed from the stale task premise. Templates are brief-first and contain -no `INTENT.md` assumption; the four `prj-` repositories have zero incorrect -purpose-document references. The two literal `INTENT.md` mentions explicitly -say project repositories use `GOAL.md`, which is the desired safeguard. -Repo Manager conformance is now the regeneration guard via C-35. - ## Accept the handoff from state-hub ```task @@ -303,7 +293,7 @@ ADR-007 § Migration. ```task id: RMGR-WP-0004-T09 -status: done +status: progress priority: high state_hub_task_id: "3a6ba954-4e35-4b2d-8dff-d3db84ed832c" ``` @@ -469,14 +459,6 @@ to the next free `KONT-WP-` number. every clash is against an archived file. Assign them before either repo allocates its next number, or they become live collisions. -Result (2026-08-21): all 11 records named by the live-collision section are now -terminal (`finished` or legacy `completed`). `rmgr identifier preflight --root -/home/worsch` sees 263 live identifiers across 113 repositories with zero -collisions, so T03's gate is cleared without rewriting frozen history. Dormant -future ownership for `WHYNOT-WP`, `OPS-WP`, and `REPO-WP` is handed off as live -residual `RMGR-IN-0002`; it must be resolved before the next allocation under -any of those prefixes. - ## Confirm the canon boundary ```task @@ -500,10 +482,3 @@ Result (2026-08-21): the seam is explicit in standards and Repo Manager implements conformance and governed mutation. The canon ADR for this workplan links the enforcement placement; no competing semantic standard was introduced here. - -## Closure - -Finished 2026-08-21. Standards modeling, conformance, governed scaffolding, -compatibility coverage, identifier uniqueness, prefix ownership, and the canon -boundary are live. Dormant prefix ownership is preserved as registered residual -`RMGR-IN-0002` rather than keeping this implementation workplan open. diff --git a/workplans/RMGR-WP-0005-registrar-consolidation-deterministic-ids.md b/workplans/RMGR-WP-0005-registrar-consolidation-deterministic-ids.md index a06c5e5..502e37f 100644 --- a/workplans/RMGR-WP-0005-registrar-consolidation-deterministic-ids.md +++ b/workplans/RMGR-WP-0005-registrar-consolidation-deterministic-ids.md @@ -313,9 +313,8 @@ derivation scope this task needs: checked against the live namespace and renumbered if it clashes. Build this check alongside derivation, not after. -The live-collision remediation tracked on `RMGR-WP-0004-T09` completed -2026-08-21. All 11 affected files are terminal history, and a fresh fleet -preflight found 263 live identifiers with zero collisions. +Remaining prerequisite is the live-collision remediation below, tracked on +`RMGR-WP-0004-T09`. 11 files, 5 identifiers. Progress (2026-08-21): the versioned derivation function and collision guard are implemented in Repo Manager and published as @@ -323,18 +322,15 @@ implemented in Repo Manager and published as `a4058507-5c4a-5a00-ab06-fffa4fb46009` and exact name bytes `\n`. `rmgr identifier derive|preflight` provides independent reproduction and a hard live-collision refusal, including the -unarchive hazard. `rmgr identifier migration-plan` now emits the versioned, -non-mutating old-to-derived mapping needed by T04 and refuses a whole repository -when any live record is unsafe. Activation is gated only on declaration of the -current fleet namespace boundary/name: ADR-011 intentionally leaves that an -open governance question, so Repo Manager does not infer it from a hostname. -No existing minted identifier was rewritten implicitly. +unarchive hazard. Activation remains correctly gated on T09's 11-file +remediation and declaration of the current N1 fleet namespace name; no existing +minted identifier was rewritten implicitly. ## Migrate the fleet ```task id: RMGR-WP-0005-T04 -status: progress +status: wait priority: high state_hub_task_id: "503a23a9-ede1-4cf1-bd32-e9669b84ce58" ``` @@ -350,14 +346,6 @@ value, update the database to match, and write the file. - Repositories with unresolved identifier collisions cannot migrate until `ADR-007` § Migration is ruled on; skip and report them rather than guessing. -**Progress (2026-08-21):** `rmgr identifier migration-plan --root ... ---namespace ... --output ...` implements the non-mutating first phase. Its -versioned JSON retains every current-to-derived UUID, labels the repository as -the atomic unit, and skips an entire affected repository on a collision or -malformed live identifier. Applying those plans remains gated on the namespace -declaration and a compatibility write path that updates file and central -projection together. - ## Retire the interim rule ```task @@ -400,7 +388,7 @@ portion of the divergence is redundant and needs no merge — only a rebuild. ```task id: RMGR-WP-0005-T08 -status: done +status: wait priority: high state_hub_task_id: "241cf058-2f3e-4d49-8cc9-5c714be4a1cf" ``` @@ -423,22 +411,11 @@ this split most of what it buffers does not need buffering, and only the append-only stream does. Re-examine before building further on it — this likely reduces its scope. -**Result (2026-08-21):** `config/hub-record-authority.yaml` classifies all 42 -tables imported by the current State Hub model package; a regression test keeps -the inventory explicit. `docs/hub-record-authority_v1.md` defines truth source, -offline behaviour, write rule, and target owner. The audit adapted the original -binary wording: hub-native origin contains both append-only events and mutable -control records. Only `progress_events` and `token_events` enter the generic -append/replay path; mutable message, launch, domain/topic, interface, and catalog -state requires an owner-specific ordered command or stays online-only. Decisions -and intakes are file-derived under the ratified work-record standard, superseding -ADR-010's older example list. - ## Disposition the orphaned hub-first records ```task id: RMGR-WP-0005-T09 -status: progress +status: wait priority: high state_hub_task_id: "d40cc4a8-4280-4940-ac1d-dc1049f1b678" ``` @@ -465,16 +442,6 @@ Note: one of these records is already labelled `SPURIOUS bootstrap (statehub register collision)` in `repo-manager`, independent corroboration of the `STATE-WP-0080` defect. -**Rebaselined 2026-08-21:** the local cache now has 224 rows without a backing -filename, not 28: 217 are closed (`finished`/`archived`) provenance and seven are -live. All seven live rows have matching files across `net-kingdom`, `state-hub`, -`railiance-platform`, `railiance-enablement`, `railiance-infra`, and `ops-hub`; -there are zero confirmed live hub-first rows in this snapshot. Exact ids and -paths are captured in -`docs/evidence/RMGR-WP-0005-orphan-disposition-2026-08-21.md`. Remaining work is -to repair those seven bindings and retain/export the 217 closed rows before T07 -replaces the cache. - ## Assign one authoritative hub per record ```task