feat: support mixed identifier convergence
Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a053ff-1d6f-7fe2-ac1c-a6eb40a42a0c
This commit is contained in:
parent
4901b6d623
commit
5789e8c520
5 changed files with 313 additions and 11 deletions
|
|
@ -420,7 +420,10 @@ def main(argv: list[str] | None = None) -> int:
|
|||
action="append",
|
||||
default=[],
|
||||
dest="projection_api_bases",
|
||||
help="Require current UUID=200 and derived UUID=404 on this projection",
|
||||
help=(
|
||||
"Classify legacy/derived UUID presence on this projection; both-present "
|
||||
"and neither-present mappings are refused"
|
||||
),
|
||||
)
|
||||
p_id_batch.add_argument("--output", default=None)
|
||||
p_id_batch.add_argument("--force", action="store_true")
|
||||
|
|
@ -445,6 +448,18 @@ def main(argv: list[str] | None = None) -> int:
|
|||
action="store_true",
|
||||
help="Write files; without this flag only validate and report",
|
||||
)
|
||||
p_id_projection = identifier_sub.add_parser(
|
||||
"migration-projection",
|
||||
help="Apply or reverse one sealed repository migration on the primary hub",
|
||||
)
|
||||
p_id_projection.add_argument("--plan", required=True)
|
||||
p_id_projection.add_argument("--repo", required=True)
|
||||
p_id_projection.add_argument("--confirm-plan-sha256", required=True)
|
||||
p_id_projection.add_argument("--api-base", required=True)
|
||||
p_id_projection.add_argument("--expected-instance-label", default="railliance01")
|
||||
p_id_projection.add_argument(
|
||||
"--direction", choices=["forward", "reverse"], default="forward"
|
||||
)
|
||||
|
||||
p_sbom = sub.add_parser(
|
||||
"sbom",
|
||||
|
|
@ -925,6 +940,7 @@ def main(argv: list[str] | None = None) -> int:
|
|||
derive_work_record_uuid,
|
||||
load_fleet_namespace,
|
||||
migrate_repository_identifier_files,
|
||||
migrate_repository_projection,
|
||||
plan_identifier_migration,
|
||||
plan_identifier_migration_batch,
|
||||
scan_live_identifier_collisions,
|
||||
|
|
@ -972,6 +988,22 @@ def main(argv: list[str] | None = None) -> int:
|
|||
except (OSError, TypeError, ValueError, json.JSONDecodeError) as exc:
|
||||
print(json.dumps({"ok": False, "error": str(exc)}, indent=2))
|
||||
return 1
|
||||
elif args.identifier_command == "migration-projection":
|
||||
try:
|
||||
plan = json.loads(Path(args.plan).read_text(encoding="utf-8"))
|
||||
if not isinstance(plan, dict):
|
||||
raise TypeError("migration plan must be a JSON object")
|
||||
result = migrate_repository_projection(
|
||||
plan,
|
||||
repo_slug=args.repo,
|
||||
confirm_plan_sha256=args.confirm_plan_sha256,
|
||||
api_base=args.api_base,
|
||||
direction=args.direction,
|
||||
expected_instance_label=args.expected_instance_label,
|
||||
)
|
||||
except (OSError, TypeError, ValueError, json.JSONDecodeError) as exc:
|
||||
print(json.dumps({"ok": False, "error": str(exc)}, indent=2))
|
||||
return 1
|
||||
elif args.identifier_command == "migration-batch-plan":
|
||||
try:
|
||||
plan = json.loads(Path(args.plan).read_text(encoding="utf-8"))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue