Skip to content

Commit 4afbd87

Browse files
jin-joungjjoung1128claude
authored
fix: preserve constitution.md during reinitialization (#1541) (#1553)
Moves constitution template from memory/ to templates/ to prevent overwrites when spec-kit is reinitialized with a different AI agent. Changes: - Move memory/constitution.md to templates/constitution-template.md - Update CLI to copy template to memory/ only on first initialization - Update constitution command to reference correct paths with .specify/ prefix - Preserve existing constitution.md when reinitializing project The CLI now checks if .specify/memory/constitution.md exists: - If it exists: preserve it (no overwrite) - If it doesn't exist: copy from .specify/templates/constitution-template.md This allows users to customize their constitution without losing changes when adding support for additional AI agents or reinitializing. Fixes #1541 Co-authored-by: jjoung1128 <jinwoong.joung@gmail.com> Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent b562438 commit 4afbd87

File tree

3 files changed

+48
-8
lines changed

3 files changed

+48
-8
lines changed

src/specify_cli/__init__.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -942,6 +942,41 @@ def ensure_executable_scripts(project_path: Path, tracker: StepTracker | None =
942942
for f in failures:
943943
console.print(f" - {f}")
944944

945+
def ensure_constitution_from_template(project_path: Path, tracker: StepTracker | None = None) -> None:
946+
"""Copy constitution template to memory if it doesn't exist (preserves existing constitution on reinitialization)."""
947+
memory_constitution = project_path / ".specify" / "memory" / "constitution.md"
948+
template_constitution = project_path / ".specify" / "templates" / "constitution-template.md"
949+
950+
# If constitution already exists in memory, preserve it
951+
if memory_constitution.exists():
952+
if tracker:
953+
tracker.add("constitution", "Constitution setup")
954+
tracker.skip("constitution", "existing file preserved")
955+
return
956+
957+
# If template doesn't exist, something went wrong with extraction
958+
if not template_constitution.exists():
959+
if tracker:
960+
tracker.add("constitution", "Constitution setup")
961+
tracker.error("constitution", "template not found")
962+
return
963+
964+
# Copy template to memory directory
965+
try:
966+
memory_constitution.parent.mkdir(parents=True, exist_ok=True)
967+
shutil.copy2(template_constitution, memory_constitution)
968+
if tracker:
969+
tracker.add("constitution", "Constitution setup")
970+
tracker.complete("constitution", "copied from template")
971+
else:
972+
console.print(f"[cyan]Initialized constitution from template[/cyan]")
973+
except Exception as e:
974+
if tracker:
975+
tracker.add("constitution", "Constitution setup")
976+
tracker.error("constitution", str(e))
977+
else:
978+
console.print(f"[yellow]Warning: Could not initialize constitution: {e}[/yellow]")
979+
945980
@app.command()
946981
def init(
947982
project_name: str = typer.Argument(None, help="Name for your new project directory (optional if using --here, or use '.' for current directory)"),
@@ -1108,6 +1143,7 @@ def init(
11081143
("zip-list", "Archive contents"),
11091144
("extracted-summary", "Extraction summary"),
11101145
("chmod", "Ensure scripts executable"),
1146+
("constitution", "Constitution setup"),
11111147
("cleanup", "Cleanup"),
11121148
("git", "Initialize git repository"),
11131149
("final", "Finalize")
@@ -1128,6 +1164,8 @@ def init(
11281164

11291165
ensure_executable_scripts(project_path, tracker=tracker)
11301166

1167+
ensure_constitution_from_template(project_path, tracker=tracker)
1168+
11311169
if not no_git:
11321170
tracker.start("git")
11331171
if is_git_repo(project_path):

templates/commands/constitution.md

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,13 @@ You **MUST** consider the user input before proceeding (if not empty).
1616

1717
## Outline
1818

19-
You are updating the project constitution at `/memory/constitution.md`. This file is a TEMPLATE containing placeholder tokens in square brackets (e.g. `[PROJECT_NAME]`, `[PRINCIPLE_1_NAME]`). Your job is to (a) collect/derive concrete values, (b) fill the template precisely, and (c) propagate any amendments across dependent artifacts.
19+
You are updating the project constitution at `.specify/memory/constitution.md`. This file is a TEMPLATE containing placeholder tokens in square brackets (e.g. `[PROJECT_NAME]`, `[PRINCIPLE_1_NAME]`). Your job is to (a) collect/derive concrete values, (b) fill the template precisely, and (c) propagate any amendments across dependent artifacts.
20+
21+
**Note**: If `.specify/memory/constitution.md` does not exist yet, it should have been initialized from `.specify/templates/constitution-template.md` during project setup. If it's missing, copy the template first.
2022

2123
Follow this execution flow:
2224

23-
1. Load the existing constitution template at `/memory/constitution.md`.
25+
1. Load the existing constitution at `.specify/memory/constitution.md`.
2426
- Identify every placeholder token of the form `[ALL_CAPS_IDENTIFIER]`.
2527
**IMPORTANT**: The user might require less or more principles than the ones used in the template. If a number is specified, respect that - follow the general template. You will update the doc accordingly.
2628

@@ -41,10 +43,10 @@ Follow this execution flow:
4143
- Ensure Governance section lists amendment procedure, versioning policy, and compliance review expectations.
4244

4345
4. Consistency propagation checklist (convert prior checklist into active validations):
44-
- Read `/templates/plan-template.md` and ensure any "Constitution Check" or rules align with updated principles.
45-
- Read `/templates/spec-template.md` for scope/requirements alignment—update if constitution adds/removes mandatory sections or constraints.
46-
- Read `/templates/tasks-template.md` and ensure task categorization reflects new or removed principle-driven task types (e.g., observability, versioning, testing discipline).
47-
- Read each command file in `/templates/commands/*.md` (including this one) to verify no outdated references (agent-specific names like CLAUDE only) remain when generic guidance is required.
46+
- Read `.specify/templates/plan-template.md` and ensure any "Constitution Check" or rules align with updated principles.
47+
- Read `.specify/templates/spec-template.md` for scope/requirements alignment—update if constitution adds/removes mandatory sections or constraints.
48+
- Read `.specify/templates/tasks-template.md` and ensure task categorization reflects new or removed principle-driven task types (e.g., observability, versioning, testing discipline).
49+
- Read each command file in `.specify/templates/commands/*.md` (including this one) to verify no outdated references (agent-specific names like CLAUDE only) remain when generic guidance is required.
4850
- Read any runtime guidance docs (e.g., `README.md`, `docs/quickstart.md`, or agent-specific guidance files if present). Update references to principles changed.
4951

5052
5. Produce a Sync Impact Report (prepend as an HTML comment at top of the constitution file after update):
@@ -61,7 +63,7 @@ Follow this execution flow:
6163
- Dates ISO format YYYY-MM-DD.
6264
- Principles are declarative, testable, and free of vague language ("should" → replace with MUST/SHOULD rationale where appropriate).
6365

64-
7. Write the completed constitution back to `/memory/constitution.md` (overwrite).
66+
7. Write the completed constitution back to `.specify/memory/constitution.md` (overwrite).
6567

6668
8. Output a final summary to the user with:
6769
- New version and bump rationale.
@@ -79,4 +81,4 @@ If the user supplies partial updates (e.g., only one principle revision), still
7981

8082
If critical info missing (e.g., ratification date truly unknown), insert `TODO(<FIELD_NAME>): explanation` and include in the Sync Impact Report under deferred items.
8183

82-
Do not create a new template; always operate on the existing `/memory/constitution.md` file.
84+
Do not create a new template; always operate on the existing `.specify/memory/constitution.md` file.
File renamed without changes.

0 commit comments

Comments
 (0)