import sys
import yaml
from pathlib import Path
def indent(text: str, spaces: int = 4) -> str:
prefix = " " * spaces
return "\n".join(prefix + line if line else "" for line in text.split("\n"))
def bullet_list(items: list, level: int = 0) -> str:
prefix = " " * level
return "\n".join(f"{prefix}- {item}" for item in items)
def numbered_list(items: list) -> str:
return "\n".join(f"{i}. {item}" for i, item in enumerate(items, 1))
def render_constitution(data: dict, model_id: str = "codewhale") -> str:
out = []
preamble = data.get("preamble", "")
out.append(preamble.replace("{model_id}", model_id).strip())
out.append("")
const = data.get("constitution", {})
a1 = const.get("article_1_identity", {})
out.append("### Article I — The Identity of the Agent")
out.append("")
out.append(a1.get("text", "").strip())
out.append("")
for rule in a1.get("rules", []):
out.append(rule)
out.append("")
a2 = const.get("article_2_truth", {})
out.append("### Article II — The Primacy of Truth")
out.append("")
out.append(a2.get("text", "").strip())
out.append("")
if a2.get("non_negotiable"):
out.append(f"This Article is non-negotiable. {a2.get('note', '')}")
out.append("")
a3 = const.get("article_3_user_agency", {})
out.append("### Article III — The Agency of the User")
out.append("")
out.append(a3.get("text", "").strip())
out.append("")
for g in a3.get("guidance", []):
out.append(g)
out.append("")
a4 = const.get("article_4_action", {})
out.append("### Article IV — The Duty of Action")
out.append("")
out.append(a4.get("text", "").strip())
out.append("")
a5 = const.get("article_5_verification", {})
out.append("### Article V — The Discipline of Verification")
out.append("")
out.append(a5.get("text", "").strip())
out.append("")
a6 = const.get("article_6_legacy", {})
out.append("### Article VI — The Legacy of Coordination")
out.append("")
out.append(a6.get("text", "").strip())
out.append("")
deeper = a6.get("deeper", "")
if deeper:
out.append(deeper.strip())
out.append("")
a7 = const.get("article_7_hierarchy", {})
out.append("### Article VII — The Hierarchy of Law")
out.append("")
out.append(a7.get("text", "").strip())
out.append("")
for level in a7.get("levels", []):
out.append(f"{level['tier']}. **{level['name']}.** {level.get('note', '')}")
out.append("")
out.append("---")
out.append("")
statutes = data.get("statutes", {})
out.append("## STATUTES (Tier 2)")
out.append("")
lang = statutes.get("language", {})
out.append("## Language")
out.append("")
out.append(lang.get("text", "").strip())
out.append("")
if lang.get("override_rule"):
out.append(lang["override_rule"].strip())
out.append("")
for g in lang.get("guidance", []):
out.append(g)
out.append("")
out.append("")
fmt = statutes.get("output_formatting", {})
out.append("## Output Formatting")
out.append("")
out.append(fmt.get("text", "").strip())
out.append("")
if fmt.get("table_rule"):
out.append(fmt["table_rule"].strip())
out.append("")
vp = statutes.get("verification_principle", {})
out.append("## Verification Principle")
out.append("")
out.append(vp.get("text", "").strip())
out.append("")
for check in vp.get("checks", []):
out.append(f"- **{check.split(':')[0]}**: {':'.join(check.split(':')[1:]).strip()}" if ':' in check else f"- {check}")
out.append("")
for rule in vp.get("rules", []):
out.append(rule)
out.append("")
ed = statutes.get("execution_discipline", {})
out.append("## Execution Discipline (Tier 2 Statute)")
out.append("")
tp = ed.get("tool_persistence", [])
if tp:
out.append("<tool_persistence>")
out.append(bullet_list(tp))
out.append("</tool_persistence>")
out.append("")
out.append("<mandatory_tool_use>")
out.append(ed.get("mandatory_tool_use", "").strip())
out.append("</mandatory_tool_use>")
out.append("")
out.append("<act_dont_ask>")
out.append(ed.get("act_dont_ask", "").strip())
out.append("</act_dont_ask>")
out.append("")
out.append("<verification>")
out.append(ed.get("verify_changes", "").strip())
out.append("</verification>")
out.append("")
out.append("<missing_context>")
out.append(ed.get("missing_context", "").strip())
out.append("</missing_context>")
out.append("")
tue = statutes.get("tool_use_enforcement", {})
out.append("## Tool-use enforcement")
out.append("")
out.append(tue.get("text", "").strip())
out.append("")
out.append("---")
out.append("")
regs = data.get("regulations", {})
out.append("## REGULATIONS (Tier 3)")
out.append("")
comp = regs.get("composition", {})
out.append("## Composition Pattern for Multi-Step Work")
out.append("")
out.append(comp.get("text", "").strip())
out.append("")
for i, step in enumerate(comp.get("steps", []), 1):
out.append(f"{i}. {step}")
out.append("")
sub = regs.get("sub_agent_strategy", {})
out.append("## Sub-Agent Strategy")
out.append("")
out.append(sub.get("text", "").strip())
out.append("")
for pattern in sub.get("patterns", []):
out.append(f"- {pattern}")
out.append("")
pf = regs.get("parallel_first", {})
out.append("## Parallel-First Heuristic")
out.append("")
out.append(pf.get("text", "").strip())
out.append("")
rlm = regs.get("rlm_usage", {})
out.append("## RLM — How to Use It")
out.append("")
out.append(rlm.get("text", "").strip())
out.append("")
for pattern in rlm.get("patterns", []):
out.append(f"**{pattern.split(' — ')[0]}** — {' — '.join(pattern.split(' — ')[1:])}" if ' — ' in pattern else f"- {pattern}")
out.append("")
for rule in rlm.get("rules", []):
out.append(f"- {rule}")
out.append("")
cm = regs.get("context_management", {})
out.append("## Context Management")
out.append("")
out.append(cm.get("text", "").strip())
out.append("")
for v4 in cm.get("v4_characteristics", []):
out.append(f"- {v4}")
out.append("")
tb = regs.get("thinking_budget", {})
out.append("## Thinking Budget")
out.append("")
out.append(tb.get("text", "").strip())
out.append("")
out.append("| Task type | Thinking depth | Rationale |")
out.append("|-----------|---------------|-----------|")
for item in tb.get("levels", []):
out.append(f"| {item['task']} | {item['depth']} | |")
out.append("")
out.append("---")
out.append("")
ev = data.get("evidence", {})
out.append("## EVIDENCE (Tier 6)")
out.append("")
toolbox = ev.get("toolbox", {})
out.append("## Toolbox (fast reference — tool descriptions are authoritative)")
out.append("")
for category, tools in toolbox.items():
label = category.replace("_", " ").title()
tool_str = ", ".join(f"`{t}`" for t in tools if not t.startswith("gh "))
if label == "Github":
tool_str = ", ".join(t for t in tools)
out.append(f"- **{label}**: {tool_str}")
out.append("")
ts = ev.get("tool_selection", {})
out.append("## Tool Selection Guide")
out.append("")
for name, desc in ts.items():
full_name = name.replace("_", " ").title()
out.append(f"### `{name}`")
out.append(desc.strip())
out.append("")
sdp = ev.get("subagent_done_protocol", {})
out.append("## Internal Sub-agent Completion Events")
out.append("")
out.append(sdp.get("text", "").strip())
out.append("")
out.append("---")
out.append("")
cr = data.get("compaction_relay", {})
if cr.get("conditional"):
out.append("<!-- COMPACTION_RELAY_PLACEHOLDER -->")
out.append("")
out.append("## Compaction Relay — Tier 9 (Precedent)")
out.append("")
out.append("The conversation above this point has been compacted.")
out.append("Below is a structured summary of what was discussed and decided.")
out.append("")
for key in ["goal", "constraints"]:
val = cr.get("template", {}).get(key, "")
title = key.replace("_", " ").title()
out.append(f"### {title}")
out.append(val)
out.append("")
progress = cr.get("template", {}).get("progress", {})
if progress:
out.append("### Progress")
out.append("")
for subkey in ["done", "in_progress", "blocked"]:
val = progress.get(subkey, "")
title = subkey.replace("_", " ").title()
out.append(f"#### {title}")
out.append(val)
out.append("")
for key in ["key_decisions", "next_step"]:
val = cr.get("template", {}).get(key, "")
title = key.replace("_", " ").title()
out.append(f"### {title}")
out.append(val)
out.append("")
out.append(cr.get("template", {}).get("staleability", "").strip())
out.append("")
out.append("---")
out.append("")
recap = data.get("authority_recap", {}).get("text", "")
out.append("## Authority Recap")
out.append("")
out.append(recap.strip())
return "\n".join(out)
def main():
yaml_path = Path(__file__).parent / "constitution.yaml"
model_id = "codewhale"
args = sys.argv[1:]
i = 0
while i < len(args):
if args[i] == "--yaml" and i + 1 < len(args):
yaml_path = Path(args[i + 1])
i += 2
elif args[i] == "--model" and i + 1 < len(args):
model_id = args[i + 1]
i += 2
else:
i += 1
if not yaml_path.exists():
print(f"Error: {yaml_path} not found", file=sys.stderr)
sys.exit(1)
with open(yaml_path) as f:
data = yaml.safe_load(f)
rendered = render_constitution(data, model_id)
print(rendered)
import re
words = len(re.findall(r'\S+', rendered))
lines = rendered.count('\n') + 1
print(f"\n<!-- Stats: {lines} lines, ~{words} words -->", file=sys.stderr)
if __name__ == "__main__":
main()