Skip to content

Commit adfc9f1

Browse files
committed
fix: guard constitution command scope
Assisted-by: GitHub Copilot (model: GPT-5.6 Sol, autonomous) Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: be3f0d7d-2774-4ba2-b741-efbb4870148a
1 parent 470ac5b commit adfc9f1

3 files changed

Lines changed: 61 additions & 0 deletions

File tree

presets/lean/commands/speckit.constitution.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,21 @@ description: Create or update the project constitution.
88
$ARGUMENTS
99
```
1010

11+
## Scope Guard
12+
13+
This command's own work is limited to creating or updating the project constitution and
14+
propagating constitution-driven changes to dependent Spec Kit artifacts.
15+
16+
- Treat feature implementation, code generation, refactoring, build, and deployment requests as
17+
non-governance intents. You **MUST NOT** execute them.
18+
- You **MUST NOT** create, modify, or delete application source files or other artifacts
19+
unrelated to the constitution workflow.
20+
- If an instruction could be either constitution content or a non-governance intent, ask for
21+
clarification before making changes.
22+
- After updating the constitution, list each deferred intent in a `Next Actions` section with an
23+
appropriate follow-up Spec Kit command, such as `/speckit.specify`, but do not invoke it.
24+
- Omit `Next Actions` when there are no non-governance intents.
25+
1126
## Outline
1227

1328
1. Create or update the project constitution and store it in `.specify/memory/constitution.md`.

templates/commands/constitution.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,25 @@ $ARGUMENTS
1414

1515
You **MUST** consider the user input before proceeding (if not empty).
1616

17+
## Scope Guard
18+
19+
This command's own work is limited to updating the project constitution and propagating
20+
constitution-driven changes to the dependent artifacts identified in this command.
21+
22+
- Classify every part of the user input as either constitution content or a separate,
23+
non-governance intent.
24+
- If the input includes feature implementation, code generation, refactoring, building, or
25+
deployment requests, you **MUST NOT** execute them. Extract them as deferred intents instead.
26+
- You **MUST NOT** create, modify, or delete application source files, feature routes,
27+
components, tests, deployment files, or other artifacts unrelated to the constitution
28+
workflow and its required propagation.
29+
- If it is unclear whether an instruction is constitution content, ask for clarification before
30+
making changes.
31+
- After completing the constitution update, include a `Next Actions` section for each deferred
32+
intent. List the original intent and suggest the appropriate follow-up Spec Kit command, such
33+
as `/speckit.specify`, without invoking it.
34+
- If there are no non-governance intents, omit the `Next Actions` section.
35+
1736
## Pre-Execution Checks
1837

1938
**Check for extension hooks (before constitution update)**:
@@ -104,6 +123,7 @@ Follow this execution flow:
104123
- New version and bump rationale.
105124
- Any files flagged for manual follow-up.
106125
- Suggested commit message (e.g., `docs: amend constitution to vX.Y.Z (principle additions + governance update)`).
126+
- A `Next Actions` section for any deferred non-governance intents.
107127
108128
Formatting & Style Requirements:
109129

tests/test_presets.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5381,6 +5381,9 @@ def test_disable_corrupted_registry_entry(self, project_dir, pack_dir):
53815381

53825382

53835383
LEAN_PRESET_DIR = Path(__file__).parent.parent / "presets" / "lean"
5384+
CORE_CONSTITUTION_COMMAND = (
5385+
Path(__file__).parent.parent / "templates" / "commands" / "constitution.md"
5386+
)
53845387

53855388
LEAN_COMMAND_NAMES = [
53865389
"speckit.specify",
@@ -5391,6 +5394,29 @@ def test_disable_corrupted_registry_entry(self, project_dir, pack_dir):
53915394
]
53925395

53935396

5397+
@pytest.mark.parametrize(
5398+
"command_path",
5399+
[
5400+
CORE_CONSTITUTION_COMMAND,
5401+
LEAN_PRESET_DIR / "commands" / "speckit.constitution.md",
5402+
],
5403+
ids=["core", "lean"],
5404+
)
5405+
def test_constitution_commands_guard_against_non_governance_work(command_path):
5406+
"""Constitution commands defer non-governance work instead of executing it."""
5407+
content = command_path.read_text()
5408+
lower_content = content.lower()
5409+
5410+
assert "## Scope Guard" in content
5411+
assert "**MUST NOT**" in content
5412+
assert "application source files" in content
5413+
assert "non-governance intent" in content
5414+
assert "`Next Actions`" in content
5415+
assert "/speckit.specify" in content
5416+
assert "omit" in lower_content
5417+
assert "do not invoke it" in lower_content or "without invoking it" in lower_content
5418+
5419+
53945420
class TestLeanPreset:
53955421
"""Tests for the lean preset that ships with the repo."""
53965422

0 commit comments

Comments
 (0)