init: llm-wiki-haness 하네스 설계
This commit is contained in:
+80
@@ -0,0 +1,80 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import pathlib
|
||||
import re
|
||||
import shlex
|
||||
import subprocess
|
||||
|
||||
ROOT = pathlib.Path(__file__).resolve().parents[5]
|
||||
LANES = ROOT / "docs/superpowers/specs/2026-07-18-keycloak-branch-note-consistency/lanes"
|
||||
FINDING = re.compile(r"^###\s+(L[1-4]-F\d{2})\b")
|
||||
commands: dict[str, list[tuple[pathlib.Path, int, str]]] = {}
|
||||
inventory: list[tuple[str, str]] = []
|
||||
|
||||
for lane in sorted(LANES.glob("lane-0[1-4]-*.md")):
|
||||
current = None
|
||||
for line_number, raw in enumerate(lane.read_text(encoding="utf-8").splitlines(), 1):
|
||||
match = FINDING.match(raw)
|
||||
if match:
|
||||
current = match.group(1)
|
||||
commands.setdefault(current, [])
|
||||
continue
|
||||
row = re.match(r"^\| (?:\x60)?(raw/branch-notes/[^\x60|]+\.md)(?:\x60)? \| (READ_FULL|NOT_READ|BLOCKED) \|", raw)
|
||||
if row:
|
||||
inventory.append((row.group(1), row.group(2)))
|
||||
candidate = raw.strip()
|
||||
if candidate.startswith("$ "):
|
||||
candidate = candidate[2:]
|
||||
if current and candidate.startswith(("grep ", "sed ")):
|
||||
commands[current].append((lane, line_number, candidate))
|
||||
|
||||
expected = (
|
||||
[f"L1-F{i:02d}" for i in range(1, 15)]
|
||||
+ [f"L2-F{i:02d}" for i in range(1, 10)]
|
||||
+ [f"L3-F{i:02d}" for i in range(1, 17)]
|
||||
+ [f"L4-F{i:02d}" for i in range(1, 22)]
|
||||
)
|
||||
passed = 0
|
||||
verified_output_lines = 0
|
||||
failures = []
|
||||
no_commands = []
|
||||
|
||||
for finding_id in expected:
|
||||
if not commands.get(finding_id):
|
||||
no_commands.append(finding_id)
|
||||
continue
|
||||
for lane, line_number, command in commands[finding_id]:
|
||||
try:
|
||||
argv = shlex.split(command)
|
||||
except ValueError as exc:
|
||||
failures.append(f"{finding_id}:{lane.name}:{line_number}:parse:{exc}")
|
||||
continue
|
||||
if not argv or argv[0] not in {"grep", "sed"}:
|
||||
failures.append(f"{finding_id}:{lane.name}:{line_number}:unsafe")
|
||||
continue
|
||||
paths = []
|
||||
for token in argv[1:]:
|
||||
if token.endswith(".md"):
|
||||
path = pathlib.Path(token)
|
||||
paths.append((path if path.is_absolute() else ROOT / path).resolve())
|
||||
if not paths or any(ROOT not in path.parents for path in paths):
|
||||
failures.append(f"{finding_id}:{lane.name}:{line_number}:path")
|
||||
continue
|
||||
result = subprocess.run(argv, cwd=ROOT, text=True, capture_output=True)
|
||||
if result.returncode != 0 or not result.stdout.strip():
|
||||
failures.append(f"{finding_id}:{lane.name}:{line_number}:exit={result.returncode}")
|
||||
continue
|
||||
passed += 1
|
||||
verified_output_lines += len([line for line in result.stdout.splitlines() if line.strip()])
|
||||
|
||||
print(f"inventory_rows={len(inventory)}")
|
||||
print(f"inventory_unique={len(set(path for path, _ in inventory))}")
|
||||
print(f"read_full={sum(status == 'READ_FULL' for _, status in inventory)}")
|
||||
print(f"finding_ids={len(commands)}")
|
||||
print(f"expected_finding_ids={len(expected)}")
|
||||
print(f"commands_passed={passed}")
|
||||
print(f"commands_failed={len(failures)}")
|
||||
print(f"verified_output_lines={verified_output_lines}")
|
||||
print(f"findings_without_commands={len(no_commands)}")
|
||||
if failures:
|
||||
print("failures=" + " || ".join(failures))
|
||||
Reference in New Issue
Block a user