init: company-haness 설계
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
"""arm-manifest 로드 + pre-flight 검증. arm 정체성은 full commit hash 로 pin, arm C 는 실제
|
||||
resolve 되는 profile 이 전부 active 여야(draft fallback 0) 완전한 P3-B arm 으로 인정한다."""
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
import yaml
|
||||
|
||||
from . import paths
|
||||
|
||||
_ACT_REL = "org-os/00-role-registry/method-contract-activations.yaml"
|
||||
|
||||
|
||||
def load():
|
||||
with open(os.path.join(paths.controller_dir(), "arm-manifest.yaml"), encoding="utf-8") as f:
|
||||
return yaml.safe_load(f)
|
||||
|
||||
|
||||
def git_state(commit):
|
||||
r = subprocess.run(["git", "cat-file", "-e", commit + "^{commit}"],
|
||||
cwd=paths.ROOT, capture_output=True, text=True)
|
||||
return {"exists": r.returncode == 0, "clean": r.returncode == 0}
|
||||
|
||||
|
||||
def _show(commit, relpath):
|
||||
r = subprocess.run(["git", "show", f"{commit}:{relpath}"],
|
||||
cwd=paths.ROOT, capture_output=True, text=True)
|
||||
return r.stdout if r.returncode == 0 else None
|
||||
|
||||
|
||||
def _unwrap_roles(data):
|
||||
"""실제 registry 는 `method-contract-activations: {version, roles: {role: {methods:...}}}`
|
||||
로 감싸져 있다. 과거/대안 형식(top-level `activations:` 키, 또는 role 이 바로 top-level에
|
||||
오는 bare mapping)도 함께 허용해 스키마 변화에 견고하게 대응한다."""
|
||||
if not isinstance(data, dict):
|
||||
return {}
|
||||
for key in ("method-contract-activations", "activations"):
|
||||
nested = data.get(key)
|
||||
if isinstance(nested, dict):
|
||||
data = nested
|
||||
break
|
||||
roles = data.get("roles")
|
||||
if isinstance(roles, dict):
|
||||
return roles
|
||||
# bare role mapping(래퍼 없이 role 이 바로 top-level) — dict 값만 role record 로 취급
|
||||
return {k: v for k, v in data.items() if isinstance(v, dict)}
|
||||
|
||||
|
||||
def active_methods_at(commit):
|
||||
"""그 commit 의 activation registry 를 읽어 {role: [active method-id]}."""
|
||||
body = _show(commit, _ACT_REL)
|
||||
if not body:
|
||||
return {}
|
||||
data = yaml.safe_load(body) or {}
|
||||
out = {}
|
||||
for role, rec in _unwrap_roles(data).items():
|
||||
if not isinstance(rec, dict):
|
||||
continue
|
||||
methods = rec.get("methods")
|
||||
if not isinstance(methods, dict):
|
||||
continue
|
||||
act = [m for m, d in methods.items()
|
||||
if isinstance(d, dict) and d.get("status") == "active"]
|
||||
if act:
|
||||
out[role] = act
|
||||
return out
|
||||
|
||||
|
||||
def command_exists_at(commit, name):
|
||||
return _show(commit, f".claude/commands/{name}.md") is not None
|
||||
|
||||
|
||||
def preflight(man=None):
|
||||
man = man or load()
|
||||
v = []
|
||||
arms = man["arms"]
|
||||
for a in ("A", "B", "C"):
|
||||
c = arms[a]["commit"]
|
||||
st = git_state(c)
|
||||
if not st["exists"]:
|
||||
v.append(f"arm {a}: commit {c[:8]} 부재")
|
||||
continue
|
||||
for cmd in man.get("required-commands", ["ground", "decide", "design-direction"]):
|
||||
if not command_exists_at(c, cmd):
|
||||
v.append(f"arm {a}: command /{cmd} 부재({c[:8]})")
|
||||
# arm B: P3-B active 미혼입
|
||||
if arms["B"]["commit"] and sum(len(x) for x in active_methods_at(arms["B"]["commit"]).values()) > 0:
|
||||
v.append("arm B: P3-B active 계약 혼입(구조이동 arm 아님)")
|
||||
# arm C: 요구 profile 전부 active(draft fallback 0)
|
||||
amC = active_methods_at(arms["C"]["commit"])
|
||||
for spec in man.get("pilot-invoked-methods", []):
|
||||
role = spec["role"]
|
||||
for mid in spec["methods"]:
|
||||
if mid not in amC.get(role, []):
|
||||
v.append(f"arm C: {role}/{mid} 가 active 아님(draft fallback — 완전한 P3-B arm 아님)")
|
||||
return v
|
||||
|
||||
|
||||
def drift(man, resolved_method_plan):
|
||||
"""수기 pilot-invoked-methods 와 dry-run resolved plan 대조. resolved 에 있으나 manifest 에
|
||||
없는 (role, method) 를 위반으로 반환."""
|
||||
declared = {(s["role"], m) for s in man.get("pilot-invoked-methods", []) for m in s["methods"]}
|
||||
v = []
|
||||
for r in resolved_method_plan or []:
|
||||
key = (r.get("role-id"), r.get("method-id"))
|
||||
if key not in declared:
|
||||
v.append(f"drift: resolved {key} 가 manifest pilot-invoked-methods 에 없음")
|
||||
return v
|
||||
Reference in New Issue
Block a user