48 lines
1.5 KiB
Python
48 lines
1.5 KiB
Python
#!/usr/bin/env python3
|
|
"""wiki_quorum.py — N개 adversarial verdict 블록의 결정론 quorum tally CLI.
|
|
|
|
사용:
|
|
python3 wiki_quorum.py vote1.md vote2.md vote3.md
|
|
cat votes.md | python3 wiki_quorum.py --stdin # '---' 구분 멀티블록
|
|
exit: 1 if any KILL/UNVERIFIED, else 0.
|
|
"""
|
|
from __future__ import annotations
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
|
import wiki_rules
|
|
|
|
|
|
def main():
|
|
args = sys.argv[1:]
|
|
if "--stdin" in args:
|
|
blob = sys.stdin.read()
|
|
blocks = [b for b in blob.split("\n---\n") if "wiki-verdict" in b]
|
|
else:
|
|
blocks = []
|
|
for a in args:
|
|
try:
|
|
blocks.append(Path(a).read_text(encoding="utf-8"))
|
|
except Exception as e:
|
|
print(f"파일 읽기 실패: {a} — {e}", file=sys.stderr)
|
|
if not blocks:
|
|
print("verdict 블록 입력 없음", file=sys.stderr)
|
|
sys.exit(2)
|
|
per = wiki_rules.tally_quorum(blocks)
|
|
print(f"== Quorum tally: N={len(blocks)} votes, {len(per)} findings ==")
|
|
print("| finding | keep | down | reject | abstain | decision |")
|
|
print("|---|---|---|---|---|---|")
|
|
bad = 0
|
|
for fid in sorted(per):
|
|
r = per[fid]
|
|
if r["decision"] in ("KILL", "UNVERIFIED"):
|
|
bad += 1
|
|
print(f"| {fid} | {r['keep']} | {r['downgrade']} | {r['reject']} | {r['abstain']} | {r['decision']} |")
|
|
print(f"\nKILL/UNVERIFIED: {bad} / {len(per)}")
|
|
sys.exit(1 if bad else 0)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|