- 21.2B: resolve_cwd returns repo_identity (git:<path> stripped) not scaffold_location; worktree override; unknown project raises; no repo → refuse; 8 held-outs incl. old-bug reproduction. - 21.2C: wait_guard covers time.sleep(N) (inline + heredoc), polling loops (while/until + status on full command), repeated delay+status; 7 new held-outs; legitimate cases still pass. - 21.2D: canonical hook source at config/mimo-hooks/event-wait-guard.ts; scripts/install_mimo_hook.py verifies hash; drift test detects canonical↔installed divergence. - 21.2G: programme_gates.py — mandatory gates end in PASS/BLOCKED/ WAIVED_BY_USER only; GateDemotionError prevents mandatory→optional demotion; 6 held-outs.
45 lines
1.4 KiB
Python
Executable File
45 lines
1.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""install_mimo_hook.py — T21.2 §21.2D: canonical MiMo hook installer.
|
|
|
|
Canonical source: config/mimo-hooks/event-wait-guard.ts
|
|
Target: ~/.mimocode/hooks/event-wait-guard.ts
|
|
Verifies hash after install. Detects drift in both directions."""
|
|
import hashlib
|
|
import shutil
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
CANONICAL = Path(__file__).resolve().parent.parent / "config" / "mimo-hooks" / "event-wait-guard.ts"
|
|
TARGET = Path.home() / ".mimocode" / "hooks" / "event-wait-guard.ts"
|
|
|
|
|
|
def sha256(p: Path) -> str:
|
|
return hashlib.sha256(p.read_bytes()).hexdigest()
|
|
|
|
|
|
def main() -> int:
|
|
if not CANONICAL.is_file():
|
|
print(f"canonical source missing: {CANONICAL}")
|
|
return 1
|
|
canon_hash = sha256(CANONICAL)
|
|
if TARGET.is_file():
|
|
target_hash = sha256(TARGET)
|
|
if target_hash == canon_hash:
|
|
print(f"in-sync: {target_hash[:12]}")
|
|
return 0
|
|
print(f"DRIFT: canonical={canon_hash[:12]} installed={target_hash[:12]}")
|
|
else:
|
|
print(f"hook missing at {TARGET}")
|
|
TARGET.parent.mkdir(parents=True, exist_ok=True)
|
|
shutil.copy2(CANONICAL, TARGET)
|
|
installed_hash = sha256(TARGET)
|
|
if installed_hash != canon_hash:
|
|
print(f"INSTALL FAILED: hash mismatch after copy")
|
|
return 1
|
|
print(f"installed: {installed_hash[:12]}")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|