feat(identifier): add reversible file migration

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a023c0-a0a3-7c03-b395-5a0d2757214d
This commit is contained in:
tegwick 2026-08-22 00:32:04 +02:00
parent 887943108e
commit 1d5b60346d
4 changed files with 354 additions and 2 deletions

View file

@ -8,6 +8,7 @@ import pytest
from repo_manager.identifiers import (
derive_work_record_uuid,
load_fleet_namespace,
migrate_repository_identifier_files,
plan_identifier_migration,
scan_live_identifier_collisions,
verify_identifier_migration_plan,
@ -138,3 +139,67 @@ def test_migration_verification_detects_tampering_and_source_drift(tmp_path: Pat
error["reason"] == "plan SHA-256 mismatch"
for error in verify_identifier_migration_plan(plan)["errors"]
)
def test_identifier_file_migration_dry_run_forward_and_reverse(tmp_path: Path) -> None:
repo = tmp_path / "one"
path = repo / "workplans" / "one.md"
_workplan(path, "ONE-WP-0001", "active")
old_workplan = "11111111-1111-4111-8111-111111111111"
old_task = "22222222-2222-4222-8222-222222222222"
original = path.read_text(encoding="utf-8")
original = original.replace(
"status: active\n---",
f'status: active\nstate_hub_workstream_id: "{old_workplan}"\n---',
).replace(
"status: todo\n```",
f'status: todo\nstate_hub_task_id: "{old_task}"\n```',
)
path.write_text(original, encoding="utf-8")
plan = plan_identifier_migration(tmp_path, "helixforge")
seal = plan["plan_sha256"]
report = migrate_repository_identifier_files(
plan,
repo_slug="one",
confirm_plan_sha256=seal,
)
assert report["executed"] is False
assert report["replacements"] == 2
assert path.read_text(encoding="utf-8") == original
report = migrate_repository_identifier_files(
plan,
repo_slug="one",
confirm_plan_sha256=seal,
execute=True,
)
assert report["executed"] is True
migrated = path.read_text(encoding="utf-8")
assert str(derive_work_record_uuid("helixforge", "ONE-WP-0001")) in migrated
assert str(derive_work_record_uuid("helixforge", "ONE-WP-0001-T01")) in migrated
assert old_workplan not in migrated
assert old_task not in migrated
report = migrate_repository_identifier_files(
plan,
repo_slug="one",
confirm_plan_sha256=seal,
direction="reverse",
execute=True,
)
assert report["direction"] == "reverse"
assert path.read_text(encoding="utf-8") == original
def test_identifier_file_migration_requires_exact_plan_confirmation(tmp_path: Path) -> None:
repo = tmp_path / "one"
_workplan(repo / "workplans" / "one.md", "ONE-WP-0001", "active")
plan = plan_identifier_migration(tmp_path, "helixforge")
with pytest.raises(ValueError, match="confirm-plan-sha256"):
migrate_repository_identifier_files(
plan,
repo_slug="one",
confirm_plan_sha256="0" * 64,
)