"""Seed constraint_primitives#N placeholders into an existing sim-rtl-flow ledger. The `constraint_primitives` node was added to the graph after this run started. Replay is keyed by `#`, so a run whose ledger predates the node rewinds to the first unrecorded `constraint_primitives#1` instead of resuming where it left off. Seeding one placeholder per module round that already happened lets the replay walk straight through to the real pending key. The placeholders record the truth: those rounds went to Vivado WITHOUT any constraint injection, because the step did not exist yet. The first round that runs after the migration gets a real injection. Usage: python migrate_constraint_ledger.py [--apply] Without --apply it only prints what it would do. """ from __future__ import annotations import json import sys from pathlib import Path PLACEHOLDER = { "success": True, "gate_passed": True, "artifacts": [], "notes": ( "迁移占位:这一轮模块处理发生在『约束原语』步骤并入 sim-rtl-flow 之前," "当时并未做任何综合属性注入,该轮 Vivado 跑的是未注入的 RTL。" "本条只为让 replay 走过历史轮次;之后的每一轮都会真正执行注入。" ), "timing_met": True, "hil_passed": True, "needs_code_change": False, "change_scope": "none", "affected_modules": [], "metadata": { "migration_placeholder": True, "injected": {}, "unmatched": [], "spec_path": "", "spec_hash": "", }, } def main(argv: list[str]) -> int: if len(argv) < 3: print(__doc__) return 2 run_dir = Path(argv[1]) count = int(argv[2]) apply = "--apply" in argv ledger_path = run_dir / "ledger.json" ledger = json.loads(ledger_path.read_text(encoding="utf-8")) added = [] for n in range(1, count + 1): key = f"constraint_primitives#{n}" if key in ledger: print(f" skip {key} (already recorded)") continue ledger[key] = dict(PLACEHOLDER) added.append(key) print(f"ledger: {ledger_path}") print(f"would add: {added}") if not apply: print("(dry run — pass --apply to write)") return 0 backup = ledger_path.with_suffix(".json.pre_constraint_migration") if not backup.exists(): backup.write_text( json.dumps( json.loads(ledger_path.read_text(encoding="utf-8")), ensure_ascii=False, indent=2, ), encoding="utf-8", ) print(f"backup -> {backup}") ledger_path.write_text( json.dumps(ledger, ensure_ascii=False, indent=2), encoding="utf-8" ) print(f"applied {len(added)} placeholder(s)") return 0 if __name__ == "__main__": raise SystemExit(main(sys.argv))