diff --git a/templates/commands/constitution.md b/templates/commands/constitution.md index 7b2f3684fb..431045ecc0 100644 --- a/templates/commands/constitution.md +++ b/templates/commands/constitution.md @@ -109,7 +109,12 @@ Follow this execution flow: - Ensure each Principle section: succinct name line, paragraph (or bullet list) capturing non‑negotiable rules, explicit rationale if not obvious. - Ensure Governance section lists amendment procedure, versioning policy, and compliance review expectations. -4. Produce a Sync Impact Report (prepend as an HTML comment at top of the constitution file after update): +4. Produce a Sync Impact Report as an HTML comment at the top of the constitution file after update. + This report is temporary scratch material for human review of the amendment, not governance + content; it is expected to be removed before the amended constitution file is committed. + - If the file already starts with an HTML comment (e.g. a Sync Impact Report left over because + it was not removed before a prior commit), remove it entirely before adding the new one. The + file must never carry more than one Sync Impact Report; replace, never stack. - Version change: old → new - List of modified principles (old title → new title if renamed) - Added sections diff --git a/tests/test_constitution_template_sync_report.py b/tests/test_constitution_template_sync_report.py new file mode 100644 index 0000000000..42310eb8c8 --- /dev/null +++ b/tests/test_constitution_template_sync_report.py @@ -0,0 +1,24 @@ +"""Covers #4431: /constitution must not stack Sync Impact Report comments. + +The Outline step that produces the Sync Impact Report only said to "prepend" +it as an HTML comment, with no instruction to remove a previous one. Every +run of /constitution therefore added another comment block on top of the +last, growing the raw constitution file (and the token cost of reading it) +without bound. +""" + +from pathlib import Path + +REPO_ROOT = Path(__file__).parent.parent +CONSTITUTION_TEMPLATE = REPO_ROOT / "templates" / "commands" / "constitution.md" + + +def test_sync_impact_report_step_instructs_removing_prior_report(): + content = CONSTITUTION_TEMPLATE.read_text(encoding="utf-8") + step = content.split("Produce a Sync Impact Report", 1)[1].split("\n\n", 1)[0] + assert "remove" in step.lower(), ( + "Step 4 must instruct removing/replacing any existing Sync Impact " + "Report comment before adding the new one, otherwise reports stack " + "on every /constitution run" + ) + assert "never stack" in step.lower() or "not stack" in step.lower()