Skip to content

Preset constitution-template (strategy: replace) is not installed, and speckit.constitution is not preset-aware #3272

Description

@PechiSW

Summary

A preset that provides a constitution-template with strategy: replace does not get its constitution installed into the project, and the rendered speckit.constitution command is not preset-aware. So an organization that ships a fixed, ready-to-use constitution in a preset cannot get it installed without the agent re-authoring one.

Environment

  • Spec Kit CLI: 0.8.18 (the project's init-options.json recorded 0.8.18.dev0)
  • Agent integration: claude (also reproducible conceptually for other integrations)

What happens

After specify init followed by specify preset add with a preset that declares:

provides:
  templates:
    - type: "template"
      name: "constitution-template"
      file: "templates/constitution-template.md"
      replaces: "constitution-template"
      strategy: "replace"
  • .specify/templates/constitution-template.md is still the generic upstream placeholder (# [PROJECT_NAME] Constitution, [PRINCIPLE_1_NAME], ...).
  • .specify/memory/constitution.md is also the generic placeholder.
  • Only .specify/presets/<id>/templates/constitution-template.md carries the preset's content.

Separately, the rendered speckit.constitution command (from templates/commands/constitution.md) instructs the agent to treat .specify/memory/constitution.md as a template and fill the [PLACEHOLDER] tokens. So even running /speckit.constitution does not install the preset's document; it has the agent author principles.

Steps to reproduce

  1. Create a preset whose constitution-template entry has replaces: constitution-template, strategy: replace, and a complete, ready-to-use constitution as its content.
  2. specify init . --integration claude
  3. specify preset add --dev /path/to/preset
  4. Inspect .specify/templates/constitution-template.md and .specify/memory/constitution.md.

Expected

The preset's constitution-template (declared replace) should be the active template, and there should be a supported way for the preset's ratified constitution to land in .specify/memory/constitution.md without the agent re-authoring principles.

Actual

The live template and the memory file are the generic placeholder; the preset content is only in the presets/<id> copy; and speckit.constitution re-authors rather than installs.

Impact

For organizations with a fixed, ratified constitution, a developer who runs /speckit.constitution silently gets an AI-invented constitution, which then governs every Constitution Check gate in plan and analyze.

Suggested fix

Either:

  • honor strategy: replace for constitution-template when resolving .specify/memory/constitution.md during setup, or
  • document specify preset resolve constitution-template as the install path and make speckit.constitution preset-aware so a preset can override it to install/validate the preset's document rather than author one (presets can already override other commands such as a custom backlog command).

Activity

  1. github-actions commented on Jun 30, 2026

    @github-actions
    Contributor

    Bug assessment — preset-constitution-not-installed: Valid · severity high


    Bug Assessment: Preset constitution-template (strategy: replace) not installed

    Report (summarized)

    Reported by @PechiSW on Spec Kit CLI v0.8.18 with the claude integration. When a preset declares a constitution-template entry with strategy: replace, the preset's constitution content is never applied to .specify/templates/constitution-template.md or .specify/memory/constitution.md. Both files remain the generic upstream placeholder. The rendered speckit.constitution command then instructs the agent to author principles from scratch, silently producing an AI-invented constitution instead of the preset's ratified one.

    Symptom

    After specify init followed by specify preset add with a preset that provides a replacement constitution-template, .specify/memory/constitution.md still contains the generic [PROJECT_NAME] / [PRINCIPLE_1_NAME] placeholders instead of the preset's content. Running /speckit.constitution has the agent author new principles rather than install the preset's ratified document.

    Reproduction

    1. Create a preset with a constitution-template entry: type: "template", name: "constitution-template", strategy: "replace", pointing to a complete, ratified constitution file.
    2. Run specify init . --integration claude
    3. Run specify preset add --dev /path/to/preset
    4. Inspect .specify/templates/constitution-template.md — still the generic placeholder.
    5. Inspect .specify/memory/constitution.md — also the generic placeholder.
    6. Run /speckit.constitution — the agent authors principles from scratch.

    Also reproducible via specify init . --integration claude --preset /path/to/preset because the init flow runs ensure_constitution_from_template before the preset is installed.

    Suspected Code Paths

    • src/specify_cli/commands/init.py:33–69 (ensure_constitution_from_template) — copies .specify/templates/constitution-template.md → .specify/memory/constitution.md using a hardcoded path, ignoring the PresetResolver stack entirely.
    • src/specify_cli/commands/init.py:450 — ensure_constitution_from_template is called before preset installation at line 509. Even with --preset at init time, the memory file is seeded from the generic template before the preset arrives.
    • src/specify_cli/presets/__init__.py:589–685 (_register_commands) — only processes type == "command" entries. type == "template" entries (e.g. constitution-template) are copied to .specify/presets/<id>/ but never propagated to .specify/templates/ or .specify/memory/.
    • src/specify_cli/presets/__init__.py:1501–1618 (install_from_directory) — calls _register_commands and _register_skills; contains no step to apply type == "template" replacements to live project files.
    • src/specify_cli/presets/__init__.py:2632–2685 (PresetResolver.resolve) — correctly returns the preset's constitution-template as the highest-priority file when asked, but nothing calls it during install/init to seed .specify/memory/constitution.md.
    • templates/commands/constitution.md:54–119 — the speckit.constitution command operates on .specify/memory/constitution.md as a placeholder template to fill in; it has no preset-awareness and no install/copy mode.

    Root Cause Hypothesis

    The preset system has a structural gap between template storage and template installation. For type == "command" entries, _register_commands() writes the resolved content into agent command directories. For type == "template" entries, the files are stored in .specify/presets/<id>/ and PresetResolver can find them on demand — but no step in either specify init or specify preset add takes the resolved constitution-template and applies it to .specify/memory/constitution.md. Additionally, ensure_constitution_from_template is called before preset installation in the specify init --preset flow, so even fixing the propagation gap in isolation would still leave the ordering bug. Confidence: high.

    Proposed Remediation

    Preferred: Two-part fix.

    1. Fix ensure_constitution_from_template to use PresetResolver: Replace the hardcoded read from .specify/templates/constitution-template.md with a call to PresetResolver(project_path).resolve("constitution-template", "template"). This makes the function automatically pick up the preset's replacement when one is installed. If no preset overrides it, the resolver falls through to the core template as today.

    2. Reorder init flow: Move ensure_constitution_from_template(project_path, tracker=tracker) (currently init.py:450) to after the preset installation block (currently ending at init.py:577). This ensures the memory file is seeded from the already-resolved template stack rather than from the generic file.

    Additionally, add a post-install hook in install_from_directory (for type == "template" entries that include constitution-template) to re-seed .specify/memory/constitution.md if and only if the existing memory file is still the unmodified generic placeholder (detectable by the presence of [PROJECT_NAME] or [PRINCIPLE_1_NAME] tokens). This handles specify preset add on an existing project.

    Alternatives:

    • Document specify preset resolve constitution-template as the install path and add a specify preset apply-templates subcommand that writes resolved template content to memory. Trade-off: user must run an explicit extra step; easy to forget.
    • Make speckit.constitution check whether the resolved template has zero placeholder tokens and, if so, copy it into memory as-is (install mode). Trade-off: the command is a Markdown agent instruction, not Python; behavioural changes here are harder to enforce and test.

    Files likely to change:

    • src/specify_cli/commands/init.py
    • src/specify_cli/presets/__init__.py

    Tests to add or update:

    • New test: install a preset whose constitution-template has strategy: replace and a complete constitution; verify that ensure_constitution_from_template seeds .specify/memory/constitution.md with the preset's content (not the generic one).
    • New test: call install_from_directory on a project that already has a generic memory constitution; verify post-install hook re-seeds it from the preset template.
    • Existing test at tests/test_presets.py:2584 (which lists constitution-template in CORE_TEMPLATE_NAMES) should be extended to cover preset overrides of that name.

    Risks & Considerations

    • The re-seed logic in install_from_directory must guard against overwriting a constitution that has already been legitimately authored (i.e., one that no longer contains the generic [PROJECT_NAME] placeholder). Overwriting user-authored constitutions would be a regression.
    • Moving ensure_constitution_from_template after preset installation in init does not affect installs without a preset (no-op change for the common case).
    • PresetResolver is already used extensively in the preset system; using it inside ensure_constitution_from_template introduces a dependency from commands/init.py into presets/. This is a minor architectural concern but is consistent with how other commands (specify integration, etc.) reach into presets/.

    Open Questions

    • [NEEDS CLARIFICATION: Should specify preset add on a project whose constitution has already been authored (no placeholder tokens) warn the user that their authored constitution may differ from the preset's ratified version, or silently skip the re-seed?]
    • [NEEDS CLARIFICATION: Is speckit.constitution intentionally not preset-aware — i.e., is there a design decision that constitution authoring is always interactive regardless of preset content?]

    Posted on behalf of @mnriem by GitHub Copilot (model: claude-sonnet-4.6, autonomous)

    Generated by 🐛 Assess Bug from Labeled Issue for issue #3272 · 442.5 AIC · ⌖ 13.6 AIC · ⊞ 33.3K · ◷

  2. mnriem commented on Jun 30, 2026

    @mnriem
    Collaborator

    Deeper assessment — validated against a real preset

    I traced the preset template machinery end-to-end and validated it against @mnriem's working demo (spec-kit-pirate-speak-preset-demo). The bug is valid (high), but the root cause is narrower and different from both the original report and the earlier automated assessment.

    How preset templates actually resolve

    Preset type: template entries are never copied into .specify/templates/ or .specify/memory/. They live in .specify/presets/<id>/templates/ and are resolved on demand by resolve_template() (scripts/bash/common.sh), which walks a priority stack: overrides/ → presets/<id>/ (by registry priority) → extensions/ → core. strategy: replace means the preset layer wins resolution, not that any file is overwritten on disk. This is by design and works for spec/plan/tasks because their setup scripts (setup-plan.sh, setup-tasks.sh) call resolve_template.

    So the report's "Expected" — that .specify/templates/constitution-template.md be replaced — rests on an incorrect mental model. No preset template overwrites that file.

    Why the demo "works" is misleading

    In the demo, .specify/memory/constitution.md is a fully-authored pirate constitution, so the flow appears to work. But the structural fingerprint proves the preset's template was never used:

    File Headings
    Preset constitution-template.md ## Articles o' the Code, ### Article I:, ## Enforcement o' the Code
    Core constitution-template.md ## Core Principles, ### I., ## Governance
    Live memory/constitution.md ## Core Principles, ### I., ## Governance

    The live constitution carries the core template's skeleton, not the preset's. The pirate content came entirely from the preset's command override (speckit.constitution instructs "write in pirate speak"), which authored over a core-seeded memory file. The preset's constitution-template.md is inert — no code path ever reads it.

    The actual defect

    Constitution is the only template excluded from the resolution stack:

    • There is no setup-constitution.sh calling resolve_template.
    • ensure_constitution_from_template (src/specify_cli/commands/init.py:34) hardcodes a shutil.copy2 from the core .specify/templates/constitution-template.md, bypassing PresetResolver entirely.

    Therefore a preset's constitution-template can never influence the project unless the preset also overrides the command — and even then the command authors rather than installs, which doesn't satisfy the org-compliance use case (ship a fixed, ratified constitution with no AI authoring).

    Two clarifications to the earlier assessment

    1. "speckit.constitution is not preset-aware" is not accurate as stated. The command is fully overridable — the demo preset overrides it and it is preset-aware there. What's missing is an install-verbatim mode, not preset-awareness.
    2. The fix is provenance, not copying. Don't copy preset content into core files.

    Proposed fix

    1. Make ensure_constitution_from_template resolver-aware — resolve constitution-template through PresetResolver/resolve_template instead of the hardcoded core path. This single change makes a preset's constitution-template go live: a placeholder-style template gets filled by the command; a finished/ratified document gets seeded into memory verbatim (no authoring needed).
    2. Reorder init so ensure_constitution_from_template runs after preset installation (currently init.py:453, before the preset block at ~init.py:553), so specify init --preset seeds from the resolved stack.
    3. Guarded re-seed in install_from_directory for specify preset add on an existing project — re-seed memory from the resolved constitution-template only when the current memory file still contains generic placeholder tokens (e.g. [PROJECT_NAME]), so legitimately authored constitutions are never overwritten.

    Posted on behalf of @mnriem by GitHub Copilot (model: claude-opus-4.8, autonomous).

  3. added
    bug-fixTrigger the bug-fix agentic workflow
    and removed
    bug-fixTrigger the bug-fix agentic workflow
    on Jul 1, 2026
  4. github-actions commented on Jul 1, 2026

    @github-actions
    Contributor

    Bug assessment — preset-constitution-not-installed: Valid · severity high


    Bug Assessment: Preset constitution-template (strategy: replace) not installed

    Report (summarized)

    Reported by @PechiSW against Spec Kit CLI v0.8.18 / claude integration. When a preset provides a constitution-template with strategy: replace, the preset's content is never applied to .specify/memory/constitution.md. Both the live template and the memory file keep the generic upstream placeholders. Running /speckit.constitution then has the agent author principles from scratch instead of installing the preset's ratified document.

    Symptom

    After specify init + specify preset add with a replace-strategy constitution-template, .specify/memory/constitution.md retains the generic [PROJECT_NAME] / [PRINCIPLE_1_NAME] skeleton. Running /speckit.constitution treats the memory file as a blank template to author rather than a ratified document to install.

    Reproduction

    1. Create a preset with a constitution-template entry: type: "template", strategy: "replace", pointing to a complete, ratified constitution file.
    2. specify init . --integration claude
    3. specify preset add --dev /path/to/preset
    4. Inspect .specify/templates/constitution-template.md — still the generic core file (expected; presets never overwrite core templates).
    5. Inspect .specify/memory/constitution.md — also the generic placeholder (the bug: should contain the preset's content).
    6. Run /speckit.constitution — agent authors principles from scratch.

    Also reproducible via specify init . --integration claude --preset /path/to/preset because ensure_constitution_from_template runs before the preset block.

    Suspected Code Paths

    • src/specify_cli/commands/init.py:33–69 (ensure_constitution_from_template) — hardcodes shutil.copy2(template_constitution, memory_constitution) from the core .specify/templates/constitution-template.md path. No call to PresetResolver at any point. This is the primary root-cause site.
    • src/specify_cli/commands/init.py:450 — ensure_constitution_from_template is called here, before the preset installation block beginning at line 509. Even specify init --preset therefore seeds the memory file from the core template before the preset is installed.
    • src/specify_cli/presets/__init__.py:589–615 (_register_commands) — processes only type == "command" manifest entries. The type == "template" entries (including constitution-template) are stored in .specify/presets/<id>/templates/ but are never propagated to .specify/memory/ or .specify/templates/.
    • src/specify_cli/presets/__init__.py:1556–1618 (install_from_directory) — calls _register_commands and _register_skills; contains no step for type == "template" replacements into live project memory files.
    • src/specify_cli/presets/__init__.py:2632–2685 (PresetResolver.resolve) — correctly resolves preset templates when called (priority 2 in the stack: overrides → presets → extensions → core), but nothing invokes it for constitution-template during init or preset add.
    • src/specify_cli/presets/_commands.py:99,181,190,225 — preset_add calls install_from_directory with no post-install step to re-seed .specify/memory/constitution.md.
    • templates/commands/constitution.md:54–62 — the rendered command treats the memory file as a placeholder template to fill in, with no preset-aware install/copy mode.

    Root Cause Hypothesis

    There is a structural gap between template storage (preset type == "template" entries are copied into .specify/presets/<id>/ and are resolvable on demand) and template installation (nothing calls the resolver to seed .specify/memory/constitution.md from the winning resolution layer).

    For type == "command" entries, _register_commands() explicitly writes resolved content to agent command directories on every install. There is no equivalent step for type == "template" entries. Additionally, ensure_constitution_from_template bypasses PresetResolver entirely, so even if the ordering were fixed the resolver would still not be consulted.

    Prior comment by @mnriem (2026-06-30T17:28:08Z) correctly identifies that strategy: replace means the preset wins resolution, not that a file is overwritten on disk — that is by design and working for spec/plan/tasks because their setup scripts call resolve_template. Constitution has no such script. Confidence: high.

    Proposed Remediation

    Preferred — two-part Python fix:

    1. Make ensure_constitution_from_template resolver-aware (src/specify_cli/commands/init.py:33–69): replace the hardcoded read from .specify/templates/constitution-template.md with PresetResolver(project_path).resolve("constitution-template", "template"). If the resolver returns a path, use that; if it returns None, fall through to the current core path as a safety default. This single change makes a preset's constitution-template go live for both specify init --preset and any future re-seed.

    2. Reorder the init flow (src/specify_cli/commands/init.py): move the call to ensure_constitution_from_template (currently at line 450) to after the preset installation block (currently ending around line 577). For specify init --preset, this ensures the memory file is seeded from the already-resolved template stack. For installs without a preset the change is a no-op.

    3. Guarded re-seed in install_from_directory (src/specify_cli/presets/__init__.py): after _register_commands and _register_skills, call ensure_constitution_from_template (or its re-seedable variant) to re-seed .specify/memory/constitution.md only when (a) the manifest provides a constitution-template entry with strategy: replace AND (b) the current memory file still contains generic placeholder tokens (e.g. [PROJECT_NAME] or [PRINCIPLE_1_NAME]). Guard (b) protects legitimately authored constitutions from being overwritten on specify preset add.

    Alternatives:

    • Add a specify preset apply-templates subcommand that applies type == "template" entries to memory files. Trade-off: user must run an extra step, easy to forget; doesn't fix specify init --preset.
    • Make speckit.constitution check whether the resolved template has zero placeholder tokens and copy it as-is. Trade-off: the command is a Markdown agent prompt; behavioral enforcement is weak and untestable in Python.

    Files likely to change:

    • src/specify_cli/commands/init.py
    • src/specify_cli/presets/__init__.py
    • src/specify_cli/presets/_commands.py (possibly, if preset_add needs to import/call the re-seed helper)

    Tests to add or update:

    • New test: install a preset with type: "template", name: "constitution-template", strategy: "replace" pointing to a complete ratified file; call ensure_constitution_from_template; verify .specify/memory/constitution.md receives the preset's content.
    • New test: specify init --preset with the above preset; verify memory constitution matches preset content (tests ordering fix).
    • New test: call install_from_directory on a project with a generic (placeholder-containing) memory constitution; verify post-install re-seed produces the preset's content.
    • New test: call install_from_directory on a project with an authored (no placeholder tokens) memory constitution; verify the file is not overwritten.
    • Extend existing tests in tests/test_presets.py covering CORE_TEMPLATE_NAMES to assert constitution-template preset overrides are reflected in memory.

    Risks & Considerations

    • The re-seed guard (placeholder-token check) must be accurate: false negatives (authored constitutions that happen to retain some [...] tokens) risk overwriting real content. A conservative heuristic: check for both [PROJECT_NAME] and [PRINCIPLE_1_NAME] simultaneously.
    • Introducing PresetResolver as a dependency inside ensure_constitution_from_template (in commands/init.py) creates a cross-module import from commands/ → presets/. This is consistent with how other commands already import from presets/ and is not a structural regression.
    • The reorder of ensure_constitution_from_template in the init flow must not break the StepTracker ordering or the progress display for specify init without a preset.
    • No API surface changes; no migrations needed. The fix is purely internal behavior.

    Open Questions

    • [NEEDS CLARIFICATION: Should specify preset add on a project with an authored constitution emit a warning that the preset's ratified constitution differs from the project's current one, even when it skips the re-seed?]
    • [NEEDS CLARIFICATION: Is there a plan to generalize the re-seed mechanism to other type == "template" entries beyond constitution-template, or is constitution the only special-cased memory file?]

    Posted on behalf of @BenBtg by GitHub Copilot (model: claude-sonnet-4.6, autonomous)

    Generated by 🐛 Assess Bug from Labeled Issue for issue #3272 · 333 AIC · ⌖ 13.7 AIC · ⊞ 31.8K · ◷

  5. github-actions commented on Jul 1, 2026

    @github-actions
    Contributor

    Pull request created: #3297

    Generated by Fix Bug from Labeled Issue · 2K AIC · ⌖ 53.4 AIC · ⊞ 34K

  6. github-actions commented on Jul 1, 2026

    @github-actions
    Contributor

    A draft fix for this issue has been opened as PR #3297.

    Slug: preset-constitution-not-installed | Severity: high

    What changed

    Three-part fix addressing the structural gap between preset template storage and memory installation:

    1. ensure_constitution_from_template now uses PresetResolver — resolves constitution-template through the full preset priority stack instead of hardcoding the core template path, so a preset's replacement is picked up when seeding .specify/memory/constitution.md.

    2. Init flow reordered — the function is now called after the preset installation block, so specify init --preset seeds the memory file from the already-resolved stack rather than from the generic template that existed before the preset arrived.

    3. Post-install re-seed hook — install_from_directory now calls _maybe_reseed_constitution, which re-seeds the memory file from the preset's constitution-template when adding a preset to an existing project, but only when the memory file still contains generic placeholder tokens ([PROJECT_NAME] or [PRINCIPLE_1_NAME]). Legitimately authored constitutions are never overwritten.

    Next steps

    Please review the draft PR. If the project has the bug-test workflow configured (stage 3 of assess → fix → test), apply the corresponding label after the fix is approved to trigger automated test generation.

    Note: the fix-proposed label does not exist in this repository, so no status label was applied.

    Posted on behalf of @BenBtg by GitHub Copilot (model: claude-sonnet-4.6, autonomous).

    Generated by 🛠️ Fix Bug from Labeled Issue for issue #3272 · 2K AIC · ⌖ 53.4 AIC · ⊞ 34K · ◷

  7. 6 remaining items

  8. github-actions commented on Jul 1, 2026

    @github-actions
    Contributor

    Bug test — preset-constitution-not-installed: ✅ passing · 366 passed, 0 failed, 0 skipped · fix from PR #3297 (commit 0487a9a)


    Bug Test Report: Preset constitution-template (strategy: replace) not installed

    Summary

    All 8 tests added by the fix pass, and neither the full test_presets.py suite (334 tests) nor test_init_dir.py (24 tests) show any regressions. The three-part fix — PresetResolver integration in ensure_constitution_from_template, init-flow reorder, and the guarded _maybe_reseed_constitution post-install hook — is behaviourally correct per the test evidence.

    Test Results

    Metric Count
    Passed 366
    Failed 0
    Skipped 0
    Errored 0
    Duration ~21 s total (2.2 s focused, 5.6 s full presets, 12.6 s init_dir)

    Failures (if any)

    None.

    Focused tests (8/8 passed)

    Test Result
    TestConstitutionReseedOnPresetInstall::test_install_reseeds_generic_constitution_memory ✅ PASSED
    TestConstitutionReseedOnPresetInstall::test_install_reseeds_on_principle_placeholder ✅ PASSED
    TestConstitutionReseedOnPresetInstall::test_install_does_not_overwrite_authored_constitution ✅ PASSED
    TestConstitutionReseedOnPresetInstall::test_install_skips_reseed_when_no_constitution_template ✅ PASSED
    TestConstitutionReseedOnPresetInstall::test_install_skips_reseed_when_memory_absent ✅ PASSED
    TestEnsureConstitutionFromTemplate::test_uses_preset_constitution_when_available ✅ PASSED
    TestEnsureConstitutionFromTemplate::test_falls_back_to_core_template_without_preset ✅ PASSED
    TestEnsureConstitutionFromTemplate::test_skips_when_memory_already_exists ✅ PASSED

    Verification vs. Historical Fix

    Not applicable — this is an open bug with no prior merged fix to compare against. PR #3297 is the first proposed remediation.

    Notes & Caveats

    • Environment setup: PyPI is blocked in this CI environment (403 Forbidden on all pip index requests). pytest 9.1.1 was bootstrapped by downloading the source zip from api.github.com and installing dependencies (pluggy 1.6.0, iniconfig v2.1.0, packaging 24.2, pygments 2.20.0) via the same route. Project runtime dependencies (typer, click, rich, yaml, platformdirs, readchar, pathspec, json5) were sourced from the pre-installed miniconda 3.13 site-packages at /usr/share/miniconda/lib/python3.13/site-packages — all pure-Python and ABI-compatible with the PyPy 3.11 runtime in use.
    • Checked-out ref: git fetch origin "pull/3297/head:bug-test-fix" → SHA 0487a9a7fd2b08b4a3f52588de7921862f27c1b8.
    • Broader coverage: The full test_presets.py suite (334 tests, covering PresetManifest, PresetRegistry, PresetManager, TemplateResolver, ResolveContent, and all new constitution tests) passed in 5.6 s with no failures, confirming no regression in the preset system. test_init_dir.py (24 tests) also passed cleanly.
    • Not run: test_extensions.py, test_integrations/, and other unrelated suites were not run; they test code paths not touched by this PR.

    Posted on behalf of @BenBtg by GitHub Copilot (model: claude-sonnet-4.6, autonomous).

    Generated by 🧪 Test a Bug Fix from a Labeled Issue for issue #3272 · 3.3K AIC · ⌖ 43.3 AIC · ⊞ 34.5K · ◷

  9. reopened this on Jul 15, 2026
  10. github-actions commented on Jul 15, 2026

    @github-actions
    Contributor

    Bug test — preset-constitution-not-installed: ⚠️ inconclusive · 0 passed, 0 failed, 0 skipped · fix from PR #3297 (commit 5e1e310)


    Bug Test Report: Preset constitution-template (strategy: replace) not installed

    Summary

    The test suite could not be executed in this runner environment due to a setup failure: uv is not installed, PyPI is network-blocked by the AWF firewall (only archive.ubuntu.com and similar domains are allowed), and no Python environment with the required test dependencies (pytest, typer, click, etc.) exists. The result is inconclusive and reflects an infrastructure gap, not a failure of the fix itself.

    Important context: A prior bug-test run on 2026-07-01 (PR #3297 at commit 0487a9a) successfully ran 366 tests with 0 failures. Additionally, as of 2026-07-15, the source-code changes from the fix (init.py and presets/__init__.py) appear to already be on main (the PR's merge commit resolved conflicts "in favor of the provenance-based fix now on main"). The current PR head (5e1e310) differs from main only by one additional integration test: test_init_with_local_preset_seeds_manifest_constitution in tests/integrations/test_cli.py.

    Test Results

    Metric Count
    Passed N/A
    Failed N/A
    Skipped N/A
    Errored N/A
    Duration N/A — no run executed

    Failures (if any)

    None (no run executed).

    Code Inspection (in lieu of run)

    The PR adds one integration test in tests/integrations/test_cli.py:

    test_init_with_local_preset_seeds_manifest_constitution (lines 309–360):

    • Creates a local preset directory with a constitution-template entry (strategy: replace) pointing to a ratified markdown file.
    • Invokes specify init <project> --integration copilot --preset <preset_dir> via the CLI test runner.
    • Asserts exit_code == 0 and that .specify/memory/constitution.md contains exactly the preset's ratified content.

    This test directly exercises the primary bug scenario from the issue report. It is well-scoped and would be a valid regression gate for the fix.

    On main, tests/test_presets.py already contains dedicated constitution-seeding tests (lines ~2924–3290, approximately 10 test methods) covering: exact-core-constitution matching, wrap/compose strategy, priority stack, authored-constitution preservation, and removal/fallback scenarios. These tests were added by the earlier commits (0487a9a, e601a6e) and cover the three-part fix described in the assessment.

    Verification vs. Historical Fix

    Not applicable — this is a fresh bug with no prior historical fix referenced in the issue.

    Notes & Caveats

    • Environment/setup failure: uv is not available (which uv returns nothing), and PyPI package installation is blocked by the AWF network firewall (pypi.org is not in the allowDomains list). apt-get requires root/sudo which is sandbox-blocked. No Python environment has pytest, typer, or other required dependencies pre-installed. The PyPy 3.11.15 environment used by python3 has only pip, setuptools, cffi, greenlet, hpy installed.

    • Prior successful run on record: The 2026-07-01 bug-test run against PR test: cover preset constitution seeding through init CLI #3297 at commit 0487a9a passed all 366 tests with 0 failures. That run covered tests/test_presets.py::TestConstitutionReseedOnPresetInstall and tests/test_presets.py::TestEnsureConstitutionFromTemplate (8 focused tests) plus the full test_presets.py suite (334 tests) and test_init_dir.py (24 tests).

    • Source code already on main: The PR's merge commit (5e1e310) resolved implementation conflicts "in favor of the provenance-based fix now on main", meaning init.py and presets/__init__.py changes are already merged. This PR only brings the new test_init_with_local_preset_seeds_manifest_constitution integration test.

    • To unblock a real run: Add a copilot-setup-steps.yml to the repository that pre-installs uv (via curl -LsSf (astral.sh/redacted) | sh or the astral-sh/setup-uv action) so the bug-test workflow has a working Python environment before the agent runs.

    Unverified

    None.


    Posted on behalf of @BenBtg by GitHub Copilot (model: claude-sonnet-4.6, autonomous).

    Generated by 🧪 Test a Bug Fix from a Labeled Issue for issue #3272 · 2.4K AIC · ⌖ 11.1 AIC · ⊞ 34.5K · ◷

  11. BenBtg commented on Jul 15, 2026

    @BenBtg
    Contributor

    The production fix merged in #3276, and the end-to-end CLI regression coverage merged in #3297. Closing as completed.\n\nPosted on behalf of @BenBtg by GitHub Copilot (model: GPT-5.6 Sol).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions