Skip to content

Add spec-kit integration and rewrite spec-kit-auto skill#30

Open
jeremyeder wants to merge 1 commit intoambient-code:mainfrom
jeremyeder:feature/add-spec-kit-auto-skill
Open

Add spec-kit integration and rewrite spec-kit-auto skill#30
jeremyeder wants to merge 1 commit intoambient-code:mainfrom
jeremyeder:feature/add-spec-kit-auto-skill

Conversation

@jeremyeder
Copy link
Copy Markdown
Collaborator

Summary

  • Rewrites spec-kit-auto skill to call actual spec-kit slash commands (/speckit.specify, /speckit.plan, /speckit.tasks, /speckit.analyze, /speckit.implement) instead of referencing superpowers skills
  • Adds spec-kit installation: commands, scripts, templates, and constitution
  • Keeps lint/security/finish phases inline in the skill (not spec-kit commands)

Test plan

  • Verify /speckit.specify is available as a slash command
  • Verify /speckit.plan, /speckit.tasks, /speckit.analyze, /speckit.implement are available
  • Run spec-kit-auto skill end-to-end with a feature description to confirm it chains the commands correctly

🤖 Generated with Claude Code

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 29, 2026

Walkthrough

Introduces a comprehensive specification-driven development framework called "Spec-Kit" with Claude plugin integration, nine command specifications spanning the complete feature lifecycle (specify → plan → tasks → analyze → implement), bash utility scripts for path/prerequisite resolution, markdown templates for artifacts, and an autonomous end-to-end skill definition.

Changes

Cohort / File(s) Summary
Claude Plugin & Skill
.claude-plugin/plugin.json, .claude/skills/spec-kit-auto/SKILL.md
Defines a "reference" plugin (v1.0.0) for AI-assisted development patterns and a Spec-Kit Auto skill with a fixed 7-phase pipeline (Specify → Plan → Tasks → Analyze → Implement → Lint/Security → Finish), including quality gates and rationalizations for non-negotiable behavior constraints.
Command Specifications
.claude/commands/speckit.{specify,clarify,plan,tasks,checklist,analyze,implement,constitution,taskstoissues}.md
Defines nine command workflows for spec-driven development: specify (create feature specs), clarify (interactive spec refinement), plan (implementation planning), tasks (generate action items), checklist (requirements validation), analyze (cross-artifact consistency), implement (execution), constitution (governance rules), and taskstoissues (GitHub issue sync). Each includes extension hooks, prerequisite validation, structured input/output, and detailed control flow.
Initialization & Configuration
.specify/init-options.json, .specify/memory/constitution.md
Adds initialization settings (Claude provider, spec-kit v0.4.3, sequential branch numbering) and a constitution template with sections for principles, constraints, governance, and amendment rules.
Bash Utility Scripts
.specify/scripts/bash/{common,check-prerequisites,create-new-feature,setup-plan,update-agent-context}.sh
Implements five utility scripts: common.sh (shared path resolution, git detection, template resolution, JSON safety helpers), check-prerequisites.sh (feature context validation with JSON output), create-new-feature.sh (branch creation and spec initialization with numbering logic), setup-plan.sh (plan file setup), and update-agent-context.sh (agent metadata extraction and file generation/updates).
Markdown Templates
.specify/templates/{spec-template,plan-template,tasks-template,checklist-template,constitution-template,agent-file-template}.md
Provides six structured templates for feature specs (with user stories, functional requirements, success criteria), implementation plans (technical context, project structure, complexity tracking), tasks (phase-based with parallelization markers), requirements checklists, project constitution, and agent context files (with active technologies, recent changes, style guides).

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant CLI as /speckit Command
    participant Hooks as Extension Hooks
    participant Scripts as Bash Scripts
    participant Templates as Templates
    participant Artifacts as Spec/Plan/<br/>Tasks/etc.
    participant Analysis as Analysis Engine
    participant Agent as AI Agent
    
    User->>CLI: Invoke /speckit.specify
    CLI->>Hooks: Execute hooks.before_specify
    Hooks-->>CLI: Complete
    CLI->>Scripts: run create-new-feature.sh
    Scripts->>Artifacts: Create SPEC_DIR & spec.md
    Artifacts-->>Scripts: Branch & paths
    Scripts-->>CLI: Metadata
    CLI->>Agent: Generate spec from input
    Agent->>Templates: Load spec-template.md
    Templates-->>Agent: Template
    Agent->>Artifacts: Write spec.md
    Agent->>Artifacts: Create requirements checklist
    Agent-->>CLI: Spec ready
    CLI->>Hooks: Execute hooks.after_specify
    Hooks-->>CLI: Complete
    
    User->>CLI: Invoke /speckit.clarify
    CLI->>Agent: Interactive Q&A on ambiguities
    Agent->>Artifacts: Update spec.md incrementally
    Artifacts-->>Agent: Validated
    Agent-->>CLI: Clarifications complete
    
    User->>CLI: Invoke /speckit.plan
    CLI->>Hooks: Execute hooks.before_plan
    CLI->>Scripts: run setup-plan.sh
    Scripts->>Artifacts: Create plan.md from template
    CLI->>Agent: Generate plan from spec & context
    Agent->>Artifacts: Write plan.md
    Agent-->>CLI: Plan ready
    CLI->>Hooks: Execute hooks.after_plan
    
    User->>CLI: Invoke /speckit.tasks
    CLI->>Scripts: run check-prerequisites.sh
    Scripts->>Artifacts: Validate spec/plan/tasks paths
    CLI->>Agent: Generate tasks from plan/spec
    Agent->>Templates: Load tasks-template.md
    Agent->>Artifacts: Write tasks.md (phased, parallelizable)
    Agent-->>CLI: Tasks ready
    
    User->>CLI: Invoke /speckit.analyze
    CLI->>Scripts: Verify prerequisites & load artifacts
    CLI->>Analysis: Cross-artifact consistency check
    Analysis->>Artifacts: Read spec.md, plan.md, tasks.md
    Analysis-->>CLI: Findings (duplication, ambiguity, coverage gaps)
    CLI-->>User: Report with severity & remediation prompts
    
    User->>CLI: Invoke /speckit.implement
    CLI->>Scripts: Check prerequisites & task completion
    CLI->>Agent: Execute tasks phase-by-phase
    Agent->>Artifacts: Mark tasks as [X]
    Agent-->>CLI: Completion report
    CLI->>Hooks: Execute hooks.after_implement
    
    User->>SKILL: Activate Spec-Kit Auto skill
    SKILL->>CLI: Call /speckit.specify
    SKILL->>CLI: Call /speckit.plan
    SKILL->>CLI: Call /speckit.tasks
    SKILL->>CLI: Call /speckit.analyze (quality gate loop)
    alt CRITICAL Issues Found
        SKILL->>Agent: Remediate issues
        SKILL->>CLI: Re-run /speckit.analyze
    end
    SKILL->>CLI: Call /speckit.implement
    SKILL->>Scripts: Run linters & security review
    SKILL->>Agent: Run full test suite
    SKILL->>Agent: Commit & merge/PR
    SKILL-->>User: Feature complete
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 57.89% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The pull request title accurately describes the main changes: adding spec-kit integration and rewriting the spec-kit-auto skill to use actual slash commands.
Description check ✅ Passed The pull request description clearly explains the changes: rewriting the skill to call spec-kit slash commands, adding spec-kit installation files, and keeping lint/security phases inline.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

Install spec-kit commands, scripts, and templates from github/spec-kit.
Add spec-kit-auto skill that autonomously chains /speckit.specify,
/speckit.plan, /speckit.tasks, /speckit.analyze, and /speckit.implement
with inline lint/security/finish phases.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jeremyeder jeremyeder force-pushed the feature/add-spec-kit-auto-skill branch from d021c5b to 63e4b95 Compare March 29, 2026 02:43
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 16

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.claude-plugin/plugin.json:
- Around line 1-6: Remove or fix the invalid "skills" configuration in the
plugin manifest: open plugin.json and delete the "skills": "auto" entry (or
replace it with a valid path string like "./skills/" if you want explicit
discovery), ensuring the top-level manifest no longer contains an invalid
"skills" value; the key to change is the "skills" property in plugin.json.

In @.claude/commands/speckit.analyze.md:
- Line 112: The sentence "one requires Next.js while other specifies Vue" is
missing an article; update the text in the string where this phrase appears to
read either "one requires Next.js while the other specifies Vue" or "one
requires Next.js while another specifies Vue" to fix the grammar (search for the
exact fragment "one requires Next.js while other specifies Vue" in the file and
replace it accordingly).

In @.claude/commands/speckit.constitution.md:
- Around line 45-50: Update the "Consistency propagation checklist" so it scans
the live command specs directory instead of only the template path: replace or
augment the bullet that references `.specify/templates/commands/*.md` to include
`.claude/commands/*.md` (and/or both paths) so the actual runtime command files
(including this file) are validated; edit the checklist heading "Consistency
propagation checklist" and the specific bullet mentioning
`.specify/templates/commands/*.md` to explicitly call out
`.claude/commands/*.md` as a source to check for agent-specific names and
outdated references.

In @.claude/commands/speckit.implement.md:
- Around line 25-44: The fenced examples under the "Extension Hooks" section
(both the optional and the "**Mandatory hook** (`optional: false`):" block) are
missing a blank line before/after the triple-backtick fences and lack a language
identifier; add a blank line above and below each ``` fence and add an
appropriate language tag (e.g., ```markdown or ```text) to each fence so CI
markdown linting passes, and fix the ordered list restart in the later block
(the list that restarts at "10." around the content covering lines ~171-197) by
renumbering it to continue from "1." consistent with the repo style.
- Around line 134-145: The consumer in speckit.implement currently assumes
phases "Setup/Tests/Core/Integration/Polish" but speckit.tasks (from
.claude/commands/speckit.tasks.md) emits "Setup, Foundational, <one phase per
user story>, Polish", so update the phase-parsing in speckit.implement to read
the actual phase list from speckit.tasks output (symbol: speckit.tasks) instead
of using the hard-coded array; normalize or map any nonstandard phase names
(e.g., map "Foundational" and per-user-story phases into the pipeline ordering)
and enforce the existing rules (TDD test-before-implementation, file-based
sequentiality, parallel [P] grouping) when executing phases so no sections are
skipped or misclassified.

In @.claude/commands/speckit.plan.md:
- Line 57: The documentation for the setup-plan step omits one emitted JSON
field; update the text around the `.specify/scripts/bash/setup-plan.sh --json`
invocation to list all five JSON fields the script emits—FEATURE_SPEC,
IMPL_PLAN, SPECS_DIR, BRANCH, and HAS_GIT—so callers and maintainers see the
full interface; modify the sentence that currently lists four fields to include
HAS_GIT and, if present, add a short note explaining HAS_GIT indicates whether
the repo has a git workspace.

In @.claude/commands/speckit.specify.md:
- Around line 122-124: The script create-new-feature.sh currently returns only
BRANCH_NAME, SPEC_FILE, and FEATURE_NUM but later writes to
FEATURE_DIR/checklists/requirements.md without deriving FEATURE_DIR; update the
script to derive FEATURE_DIR from SPEC_FILE (e.g., compute FEATURE_DIR=$(dirname
"$SPEC_FILE") or extract the feature directory path from the SPEC_FILE value)
before the checklist write, or include FEATURE_DIR in the JSON output alongside
BRANCH_NAME, SPEC_FILE, and FEATURE_NUM so the checklist step uses that explicit
FEATURE_DIR when creating FEATURE_DIR/checklists/requirements.md.
- Around line 73-82: Update the examples in .claude/commands/speckit.specify.md
to stop passing the description twice and to use the script's actual flags;
specifically, change invocations of create-new-feature.sh that include
"$ARGUMENTS" plus a literal description to pass only a single description
argument (so FEATURE_DESCRIPTION="${ARGS[*]}" won't duplicate text) and replace
any PowerShell-style flags like -Json, -ShortName, -Timestamp with the script's
supported GNU-style flags --json, --short-name, --timestamp when demonstrating
both sequential and timestamp modes.

In @.claude/commands/speckit.taskstoissues.md:
- Around line 16-17: The workflow currently says "extract the path to tasks" but
the JSON from check-prerequisites.sh only contains FEATURE_DIR and
AVAILABLE_DOCS; update the instruction to explicitly construct or locate
tasks.md by either (A) building the path as FEATURE_DIR + "/tasks.md" or (B)
searching the AVAILABLE_DOCS array for "tasks.md" and, if found, prefixing it
with FEATURE_DIR to form an absolute path; mention the exact JSON keys
FEATURE_DIR and AVAILABLE_DOCS and the filename tasks.md, require absolute
paths, and prefer option B (search AVAILABLE_DOCS first then fallback to
constructing FEATURE_DIR/tasks.md).

In @.specify/scripts/bash/common.sh:
- Around line 44-45: The assignment using command substitution masks failures;
refactor by declaring the variable first and then assigning the output in a
separate command so failures preserve their exit codes—e.g., replace the
combined declaration for script_dir (the line using CDPATH="" cd "$(dirname
"${BASH_SOURCE[0]}")" && pwd) with a separate declaration and assignment
pattern, and apply the same change to the other flagged spots (the similar
command substitutions at the other occurrences referenced in the comment) so
each command substitution is executed in its own statement to avoid masking
return values.
- Around line 158-165: The glob loop over "$specs_dir"/"$prefix"-* can yield the
literal pattern when there are no matches; update the block around matches,
specs_dir, prefix and the for loop to either enable nullglob locally (shopt -s
nullglob; ...; shopt -u nullglob) so the for loop is skipped when there are no
matches, or add an explicit check after globbing (e.g., test whether the first
globbed entry equals the pattern) and skip the loop if so; ensure you modify the
code that builds the matches array (matches+= and the for dir in ...) so it no
longer adds the literal pattern when there are no real directories.

In @.specify/scripts/bash/create-new-feature.sh:
- Around line 76-80: Replace the xargs-based trimming
(FEATURE_DESCRIPTION=$(echo "$FEATURE_DESCRIPTION" | xargs)) because xargs
treats quotes and apostrophes as shell syntax; instead trim whitespace using
bash parameter expansion so apostrophes remain intact: perform leading-space
removal with
FEATURE_DESCRIPTION="${FEATURE_DESCRIPTION#"${FEATURE_DESCRIPTION%%[![:space:]]*}"}"
and trailing-space removal with
FEATURE_DESCRIPTION="${FEATURE_DESCRIPTION%"${FEATURE_DESCRIPTION##*[![:space:]]}"}"
(then keep the existing if [ -z "$FEATURE_DESCRIPTION" ]; then ... check). This
removes external tools that mis-handle quotes and preserves inputs like "I'm
Groot".

In @.specify/scripts/bash/setup-plan.sh:
- Around line 41-50: The current fallback creates an empty plan file (touch
"$IMPL_PLAN") which can confuse downstream consumers; replace that with writing
a minimal placeholder into IMPL_PLAN (e.g., a short header and brief
instructions) so tools have predictable content. Update the branch where
TEMPLATE is missing in the block that uses resolve_template and variables
TEMPLATE and IMPL_PLAN to write a minimal structured header (like "# Plan" plus
a one-line placeholder) into the file instead of touching it, and keep the
existing warning echo.
- Around line 7-24: Remove the unused ARGS array: delete the ARGS=()
initialization and the default case that appends to it (the case branch using
ARGS+=("$arg")) inside the for loop, leaving only the recognized flag handling
(--json and --help); ensure no other code references ARGS (if there are, either
wire those references to use "$@" or implement intended handling for leftover
positional args instead).

In @.specify/scripts/bash/update-agent-context.sh:
- Around line 465-483: The script always appends new_change_entry into the "##
Recent Changes" block without checking for duplicates; modify the logic in the
block that handles "## Recent Changes" so that before echoing new_change_entry
you scan the existing changes in that section (use in_changes_section to iterate
lines until the next "## " heading) and only add new_change_entry if it is not
already present (compare the exact string), leaving existing_changes_count logic
intact so you still keep only the first two existing entries when writing to
temp_file.
- Around line 316-356: The sed replacements are not escaping replacement-side
metacharacters (& and \), corrupting inserted values (e.g.,
get_commands_for_language output); before building the substitutions array,
create escaped replacement variables (e.g., escaped_project_name,
escaped_current_date, escaped_tech_stack, escaped_commands,
escaped_language_conventions, escaped_recent_change, escaped_project_structure)
by running each through a replacement-escaping step (sed 's/[&\]/\\&/g' or
equivalent parameter expansion), then use those escaped_* symbols in the
substitutions array (which is iterated by the sed -e "$substitution" loop) so
the right-hand side of "s|...|...|" is safe; update references to project_name,
current_date, tech_stack, commands, language_conventions, recent_change, and
project_structure accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: ac8c7d2f-ca5f-4737-a0ed-e34b109242da

📥 Commits

Reviewing files that changed from the base of the PR and between 7371e50 and 63e4b95.

📒 Files selected for processing (24)
  • .claude-plugin/plugin.json
  • .claude/commands/speckit.analyze.md
  • .claude/commands/speckit.checklist.md
  • .claude/commands/speckit.clarify.md
  • .claude/commands/speckit.constitution.md
  • .claude/commands/speckit.implement.md
  • .claude/commands/speckit.plan.md
  • .claude/commands/speckit.specify.md
  • .claude/commands/speckit.tasks.md
  • .claude/commands/speckit.taskstoissues.md
  • .claude/skills/spec-kit-auto/SKILL.md
  • .specify/init-options.json
  • .specify/memory/constitution.md
  • .specify/scripts/bash/check-prerequisites.sh
  • .specify/scripts/bash/common.sh
  • .specify/scripts/bash/create-new-feature.sh
  • .specify/scripts/bash/setup-plan.sh
  • .specify/scripts/bash/update-agent-context.sh
  • .specify/templates/agent-file-template.md
  • .specify/templates/checklist-template.md
  • .specify/templates/constitution-template.md
  • .specify/templates/plan-template.md
  • .specify/templates/spec-template.md
  • .specify/templates/tasks-template.md

Comment on lines +1 to +6
{
"name": "reference",
"version": "1.0.0",
"description": "AI-assisted development patterns and skills for the Ambient Code reference repository.",
"skills": "auto"
} No newline at end of file
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

Claude plugin.json schema skills auto configuration

💡 Result:

The plugin.json schema for Claude Code (Anthropic's terminal-based AI coding tool) defines the manifest for plugins that extend functionality with skills, agents, hooks, MCP servers, etc. It is located at .claude-plugin/plugin.json in the plugin root directory. The manifest is optional; without it, Claude Code auto-discovers components in default locations (e.g., skills/ directory) and uses the directory name as the plugin name. Complete schema from official Claude Code documentation: { "name": "plugin-name", "version": "1.2.0", "description": "Brief plugin description", "author": { "name": "Author Name", "email": "author@example.com", "url": "https://github.com/author" }, "homepage": "https://docs.example.com/plugin", "repository": "https://github.com/author/plugin", "license": "MIT", "keywords": ["keyword1", "keyword2"], "commands": ["./custom/commands/special.md"], "agents": "./custom/agents/", "skills": "./custom/skills/", "hooks": "./config/hooks.json", "mcpServers": "./mcp-config.json", "outputStyles": "./styles/", "lspServers": "./.lsp.json" } Required field: name (kebab-case string, unique identifier and namespace prefix for skills like /plugin-name:skill). Skills auto-configuration: Skills (in skills/ directories) are automatically discovered and loaded by Claude Code from multiple scopes: project (.claude/skills/), user (~/.claude/skills/), plugins, etc. Claude invokes them model-autonomously based on descriptions/context, or via slash commands (/skill-name). No manual configuration needed beyond placing SKILL.md files with YAML frontmatter (e.g., description, disable-model-invocation: true). Higher-priority scopes override lower ones; plugin skills are namespaced to avoid conflicts. For IDE validation/autocomplete, community tools like claudelint provide plugin-manifest.schema.json; unofficial schemas exist on GitHub (e.g., hesreallyhim/claude-code-json-schema). settings.json uses official SchemaStore schema: "$schema": "https://json.schemastore.org/claude-code-settings.json". Official sources: Claude Code Docs (plugins reference, create plugins, skills, settings). No direct JSON Schema URI published by Anthropic for plugin.json.

Citations:


Remove the invalid "skills" configuration.

The value "skills": "auto" is not valid per the Claude Code plugin schema. According to the official documentation, the "skills" field should either be omitted (for automatic discovery in default locations like skills/) or set to a path string (e.g., "./custom/skills/"). Remove or replace this field with a valid path.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.claude-plugin/plugin.json around lines 1 - 6, Remove or fix the invalid
"skills" configuration in the plugin manifest: open plugin.json and delete the
"skills": "auto" entry (or replace it with a valid path string like "./skills/"
if you want explicit discovery), ensuring the top-level manifest no longer
contains an invalid "skills" value; the key to change is the "skills" property
in plugin.json.

- Terminology drift (same concept named differently across files)
- Data entities referenced in plan but absent in spec (or vice versa)
- Task ordering contradictions (e.g., integration tasks before foundational setup tasks without dependency note)
- Conflicting requirements (e.g., one requires Next.js while other specifies Vue)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Minor grammar improvement.

The phrase "one requires Next.js while other specifies Vue" is missing an article. Consider: "one requires Next.js while the other specifies Vue" or "one requires Next.js while another specifies Vue".

📝 Suggested fix
-- Conflicting requirements (e.g., one requires Next.js while other specifies Vue)
+- Conflicting requirements (e.g., one requires Next.js while the other specifies Vue)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- Conflicting requirements (e.g., one requires Next.js while other specifies Vue)
- Conflicting requirements (e.g., one requires Next.js while the other specifies Vue)
🧰 Tools
🪛 LanguageTool

[grammar] ~112-~112: Ensure spelling is correct
Context: ...ments (e.g., one requires Next.js while other specifies Vue) ### 5. Severity Assignm...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.claude/commands/speckit.analyze.md at line 112, The sentence "one requires
Next.js while other specifies Vue" is missing an article; update the text in the
string where this phrase appears to read either "one requires Next.js while the
other specifies Vue" or "one requires Next.js while another specifies Vue" to
fix the grammar (search for the exact fragment "one requires Next.js while other
specifies Vue" in the file and replace it accordingly).

Comment on lines +45 to +50
4. Consistency propagation checklist (convert prior checklist into active validations):
- Read `.specify/templates/plan-template.md` and ensure any "Constitution Check" or rules align with updated principles.
- Read `.specify/templates/spec-template.md` for scope/requirements alignment—update if constitution adds/removes mandatory sections or constraints.
- Read `.specify/templates/tasks-template.md` and ensure task categorization reflects new or removed principle-driven task types (e.g., observability, versioning, testing discipline).
- 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.
- Read any runtime guidance docs (e.g., `README.md`, `docs/quickstart.md`, or agent-specific guidance files if present). Update references to principles changed.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Scan the live command specs, not a template-only path.

This propagation step reads .specify/templates/commands/*.md, but the command files introduced in this PR live under .claude/commands/*.md — including this file. As written, constitution updates will skip the workflow definitions that actually run and can leave them out of sync with amended principles.

Suggested fix
-   - 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.
+   - Read each command file in `.claude/commands/*.md` (including this one) to verify no outdated references remain when generic guidance is required.
+   - If the project also ships command templates under `.specify/templates/commands/*.md`, validate those too.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
4. Consistency propagation checklist (convert prior checklist into active validations):
- Read `.specify/templates/plan-template.md` and ensure any "Constitution Check" or rules align with updated principles.
- Read `.specify/templates/spec-template.md` for scope/requirements alignment—update if constitution adds/removes mandatory sections or constraints.
- Read `.specify/templates/tasks-template.md` and ensure task categorization reflects new or removed principle-driven task types (e.g., observability, versioning, testing discipline).
- 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.
- Read any runtime guidance docs (e.g., `README.md`, `docs/quickstart.md`, or agent-specific guidance files if present). Update references to principles changed.
4. Consistency propagation checklist (convert prior checklist into active validations):
- Read `.specify/templates/plan-template.md` and ensure any "Constitution Check" or rules align with updated principles.
- Read `.specify/templates/spec-template.md` for scope/requirements alignment—update if constitution adds/removes mandatory sections or constraints.
- Read `.specify/templates/tasks-template.md` and ensure task categorization reflects new or removed principle-driven task types (e.g., observability, versioning, testing discipline).
- Read each command file in `.claude/commands/*.md` (including this one) to verify no outdated references remain when generic guidance is required.
- If the project also ships command templates under `.specify/templates/commands/*.md`, validate those too.
- Read any runtime guidance docs (e.g., `README.md`, `docs/quickstart.md`, or agent-specific guidance files if present). Update references to principles changed.
🧰 Tools
🪛 LanguageTool

[style] ~49-~49: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ..., versioning, testing discipline). - Read each command file in `.specify/template...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[style] ~50-~50: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...when generic guidance is required. - Read any runtime guidance docs (e.g., `READM...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.claude/commands/speckit.constitution.md around lines 45 - 50, Update the
"Consistency propagation checklist" so it scans the live command specs directory
instead of only the template path: replace or augment the bullet that references
`.specify/templates/commands/*.md` to include `.claude/commands/*.md` (and/or
both paths) so the actual runtime command files (including this file) are
validated; edit the checklist heading "Consistency propagation checklist" and
the specific bullet mentioning `.specify/templates/commands/*.md` to explicitly
call out `.claude/commands/*.md` as a source to check for agent-specific names
and outdated references.

Comment on lines +25 to +44
```
## Extension Hooks

**Optional Pre-Hook**: {extension}
Command: `/{command}`
Description: {description}

Prompt: {prompt}
To execute: `/{command}`
```
- **Mandatory hook** (`optional: false`):
```
## Extension Hooks

**Automatic Pre-Hook**: {extension}
Executing: `/{command}`
EXECUTE_COMMAND: {command}

Wait for the result of the hook command before proceeding to the Outline.
```
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

This file is still blocking Documentation Validation.

The hook example fences in these sections are missing blank lines and a language, and Line 171 restarts the ordered list at 10. instead of the repo's 1. style. The pipeline failures already point at these exact regions, so CI stays red until they are normalized.

Also applies to: 171-197

🧰 Tools
🪛 GitHub Actions: Documentation Validation

[error] 25-25: markdownlint-cli2 failed (markdownlint MD031/blanks-around-fences): Fenced code blocks should be surrounded by blank lines [Context: "```"].

🪛 GitHub Check: lint-markdown

[failure] 44-44: Fenced code blocks should be surrounded by blank lines
.claude/commands/speckit.implement.md:44 MD031/blanks-around-fences Fenced code blocks should be surrounded by blank lines [Context: "```"] https://github.com/DavidAnson/markdownlint/blob/v0.33.0/doc/md031.md


[failure] 36-36: Fenced code blocks should have a language specified
.claude/commands/speckit.implement.md:36 MD040/fenced-code-language Fenced code blocks should have a language specified [Context: " ```"] https://github.com/DavidAnson/markdownlint/blob/v0.33.0/doc/md040.md


[failure] 36-36: Fenced code blocks should be surrounded by blank lines
.claude/commands/speckit.implement.md:36 MD031/blanks-around-fences Fenced code blocks should be surrounded by blank lines [Context: "```"] https://github.com/DavidAnson/markdownlint/blob/v0.33.0/doc/md031.md


[failure] 34-34: Fenced code blocks should be surrounded by blank lines
.claude/commands/speckit.implement.md:34 MD031/blanks-around-fences Fenced code blocks should be surrounded by blank lines [Context: "```"] https://github.com/DavidAnson/markdownlint/blob/v0.33.0/doc/md031.md


[failure] 25-25: Fenced code blocks should have a language specified
.claude/commands/speckit.implement.md:25 MD040/fenced-code-language Fenced code blocks should have a language specified [Context: " ```"] https://github.com/DavidAnson/markdownlint/blob/v0.33.0/doc/md040.md


[failure] 25-25: Fenced code blocks should be surrounded by blank lines
.claude/commands/speckit.implement.md:25 MD031/blanks-around-fences Fenced code blocks should be surrounded by blank lines [Context: "```"] https://github.com/DavidAnson/markdownlint/blob/v0.33.0/doc/md031.md

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.claude/commands/speckit.implement.md around lines 25 - 44, The fenced
examples under the "Extension Hooks" section (both the optional and the
"**Mandatory hook** (`optional: false`):" block) are missing a blank line
before/after the triple-backtick fences and lack a language identifier; add a
blank line above and below each ``` fence and add an appropriate language tag
(e.g., ```markdown or ```text) to each fence so CI markdown linting passes, and
fix the ordered list restart in the later block (the list that restarts at "10."
around the content covering lines ~171-197) by renumbering it to continue from
"1." consistent with the repo style.

Comment on lines +134 to +145
5. Parse tasks.md structure and extract:
- **Task phases**: Setup, Tests, Core, Integration, Polish
- **Task dependencies**: Sequential vs parallel execution rules
- **Task details**: ID, description, file paths, parallel markers [P]
- **Execution flow**: Order and dependency requirements

6. Execute implementation following the task plan:
- **Phase-by-phase execution**: Complete each phase before moving to the next
- **Respect dependencies**: Run sequential tasks in order, parallel tasks [P] can run together
- **Follow TDD approach**: Execute test tasks before their corresponding implementation tasks
- **File-based coordination**: Tasks affecting the same files must run sequentially
- **Validation checkpoints**: Verify each phase completion before proceeding
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Parse the phase structure that speckit.tasks actually generates.

.claude/commands/speckit.tasks.md:76-87,193-200 produces Setup, Foundational, one phase per user story, and Polish. This consumer is hard-coded to Setup/Tests/Core/Integration/Polish, so the end-to-end tasks → implement flow described in the PR will misclassify or skip whole sections.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.claude/commands/speckit.implement.md around lines 134 - 145, The consumer
in speckit.implement currently assumes phases
"Setup/Tests/Core/Integration/Polish" but speckit.tasks (from
.claude/commands/speckit.tasks.md) emits "Setup, Foundational, <one phase per
user story>, Polish", so update the phase-parsing in speckit.implement to read
the actual phase list from speckit.tasks output (symbol: speckit.tasks) instead
of using the hard-coded array; normalize or map any nonstandard phase names
(e.g., map "Foundational" and per-user-story phases into the pipeline ordering)
and enforce the existing rules (TDD test-before-implementation, file-based
sequentiality, parallel [P] grouping) when executing phases so no sections are
skipped or misclassified.

Comment on lines +76 to +80
# Trim whitespace and validate description is not empty (e.g., user passed only whitespace)
FEATURE_DESCRIPTION=$(echo "$FEATURE_DESCRIPTION" | xargs)
if [ -z "$FEATURE_DESCRIPTION" ]; then
echo "Error: Feature description cannot be empty or contain only whitespace" >&2
exit 1
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, locate and examine the script file
find . -name "create-new-feature.sh" -type f

Repository: ambient-code/reference

Length of output: 111


🏁 Script executed:

# Check if the file exists at the specified path
if [ -f ".specify/scripts/bash/create-new-feature.sh" ]; then
    echo "=== File found. Reading lines 70-85 to get context ==="
    sed -n '70,85p' ".specify/scripts/bash/create-new-feature.sh"
fi

Repository: ambient-code/reference

Length of output: 708


🏁 Script executed:

# Search for documentation that mentions apostrophes or "I'm Groot"
rg -i "apostrophe|i'm|feature description" --type md --type txt --type sh -B 2 -A 2 | head -100

Repository: ambient-code/reference

Length of output: 48


🏁 Script executed:

# Test xargs behavior with apostrophes
echo "Testing xargs with apostrophes:"
echo "I'm Groot" | xargs echo "Result:"

Repository: ambient-code/reference

Length of output: 213


🏁 Script executed:

# Test the alternative sed-based approach
echo "Testing sed-based trimming:"
test_string="  I'm Groot  "
result=$(printf '%s' "$test_string" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
echo "Input: '$test_string'"
echo "Output: '$result'"

Repository: ambient-code/reference

Length of output: 136


🏁 Script executed:

# Search for documentation files that mention feature descriptions or apostrophes
find . -type f \( -name "*.md" -o -name "*.txt" -o -name "README*" \) | head -20

Repository: ambient-code/reference

Length of output: 824


🏁 Script executed:

# Search for any mentions of apostrophes or example inputs in command documentation
rg "I'm|apostrophe|feature.description|create-new-feature" -B 2 -A 2 2>/dev/null | head -150

Repository: ambient-code/reference

Length of output: 48


🏁 Script executed:

# Check if there are other instances of echo | xargs in bash scripts
rg "echo.*\|.*xargs" --type sh

Repository: ambient-code/reference

Length of output: 48


🏁 Script executed:

# Look at the full script to understand context better
wc -l ".specify/scripts/bash/create-new-feature.sh"

Repository: ambient-code/reference

Length of output: 113


🏁 Script executed:

# Read more of the script to see how it's called and documented
head -50 ".specify/scripts/bash/create-new-feature.sh"

Repository: ambient-code/reference

Length of output: 1438


🏁 Script executed:

# Search for any markdown or text files that mention the create-new-feature command or script
rg "create-new-feature|create_new_feature" -B 3 -A 3

Repository: ambient-code/reference

Length of output: 48


🏁 Script executed:

# Search in command directories specifically
find . -path "*/.specify/*" -o -path "*/.claude/*" | grep -i "doc\|readme\|spec" | xargs grep -l "create.*feature\|feature.*description" 2>/dev/null

Repository: ambient-code/reference

Length of output: 324


🏁 Script executed:

# Check the full help text of the script
sed -n '30,60p' ".specify/scripts/bash/create-new-feature.sh"

Repository: ambient-code/reference

Length of output: 1459


🏁 Script executed:

# Search for any example usage or documentation in comments
grep -n "example\|Example\|EXAMPLE\|usage\|Usage" ".specify/scripts/bash/create-new-feature.sh"

Repository: ambient-code/reference

Length of output: 317


🏁 Script executed:

# Get the full examples section from the script
sed -n '57,65p' ".specify/scripts/bash/create-new-feature.sh"

Repository: ambient-code/reference

Length of output: 424


🏁 Script executed:

# Check the documentation files that mention create-new-feature for example usage
grep -A 10 -B 2 "create-new-feature" "./.claude/commands/speckit.specify.md" 2>/dev/null | head -30

Repository: ambient-code/reference

Length of output: 1401


🏁 Script executed:

# Check the skill documentation
grep -A 10 -B 2 "create-new-feature" "./.specify/skills/spec-kit-auto/SKILL.md" 2>/dev/null | head -30

Repository: ambient-code/reference

Length of output: 48


🏁 Script executed:

# Search for any mention of special characters, apostrophes, or quotes in documentation
rg "apostrophe|special.character|I'm|shouldn't|don't|'s " --type md

Repository: ambient-code/reference

Length of output: 2428


🏁 Script executed:

# Check if there are other instances of echo | xargs pattern in the codebase
rg "\|.*xargs" --type sh -A 1 -B 1

Repository: ambient-code/reference

Length of output: 48


🏁 Script executed:

# Test what actually gets passed to the script with apostrophes
# Simulate calling the script with an apostrophe in a quoted argument
test_input="I'm Groot"
echo "Testing: echo \"$test_input\" | xargs"
echo "$test_input" | xargs echo "Result:" 2>&1

Repository: ambient-code/reference

Length of output: 198


🏁 Script executed:

# Verify the exact scenario: quoted string with apostrophe passed as argument
bash -c '
ARGS=()
arg="I'"'"'m Groot"
ARGS+=("$arg")
FEATURE_DESCRIPTION="${ARGS[*]}"
echo "Feature description: $FEATURE_DESCRIPTION"
echo "$FEATURE_DESCRIPTION" | xargs echo "After xargs:" 2>&1
' || echo "Script failed with exit code: $?"

Repository: ambient-code/reference

Length of output: 227


🏁 Script executed:

# Test that the sed-based approach handles this correctly under set -e
bash -c '
set -e
ARGS=()
arg="I'"'"'m Groot"
ARGS+=("$arg")
FEATURE_DESCRIPTION="${ARGS[*]}"
echo "Feature description: $FEATURE_DESCRIPTION"
# Original approach
echo "$FEATURE_DESCRIPTION" | xargs > /dev/null 2>&1 || echo "xargs failed as expected"
# Sed approach
FEATURE_DESCRIPTION=$(printf "%s" "$FEATURE_DESCRIPTION" | sed -e "s/^[[:space:]]*//" -e "s/[[:space:]]*$//")
echo "After sed fix: $FEATURE_DESCRIPTION"
echo "Script continued successfully!"
'

Repository: ambient-code/reference

Length of output: 177


xargs fails on documented input patterns containing apostrophes.

The script's help text and documentation (e.g., ./.claude/commands/speckit.specify.md) indicate that inputs like "I'm Groot" are valid and supported. However, xargs treats quotes as shell syntax, causing it to fail with "unmatched single quote" on any feature description containing an apostrophe. Under set -e, this hard failure breaks the script on exactly the input shape the docs tell users to use.

Suggested fix
-# Trim whitespace and validate description is not empty (e.g., user passed only whitespace)
-FEATURE_DESCRIPTION=$(echo "$FEATURE_DESCRIPTION" | xargs)
+# Trim leading/trailing whitespace without reparsing quotes/backslashes
+FEATURE_DESCRIPTION=$(printf '%s' "$FEATURE_DESCRIPTION" \
+    | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.specify/scripts/bash/create-new-feature.sh around lines 76 - 80, Replace
the xargs-based trimming (FEATURE_DESCRIPTION=$(echo "$FEATURE_DESCRIPTION" |
xargs)) because xargs treats quotes and apostrophes as shell syntax; instead
trim whitespace using bash parameter expansion so apostrophes remain intact:
perform leading-space removal with
FEATURE_DESCRIPTION="${FEATURE_DESCRIPTION#"${FEATURE_DESCRIPTION%%[![:space:]]*}"}"
and trailing-space removal with
FEATURE_DESCRIPTION="${FEATURE_DESCRIPTION%"${FEATURE_DESCRIPTION##*[![:space:]]}"}"
(then keep the existing if [ -z "$FEATURE_DESCRIPTION" ]; then ... check). This
removes external tools that mis-handle quotes and preserves inputs like "I'm
Groot".

Comment on lines +7 to +24
ARGS=()

for arg in "$@"; do
case "$arg" in
--json)
JSON_MODE=true
;;
--help|-h)
echo "Usage: $0 [--json]"
echo " --json Output results in JSON format"
echo " --help Show this help message"
exit 0
;;
*)
ARGS+=("$arg")
;;
esac
done
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Unused ARGS array.

The ARGS array is populated with unrecognized arguments (line 21) but never used. Either remove it or document intended future use.

♻️ Remove unused array
 # Parse command line arguments
 JSON_MODE=false
-ARGS=()

 for arg in "$@"; do
     case "$arg" in
         --json) 
             JSON_MODE=true 
             ;;
         --help|-h) 
             echo "Usage: $0 [--json]"
             echo "  --json    Output results in JSON format"
             echo "  --help    Show this help message"
             exit 0 
             ;;
-        *) 
-            ARGS+=("$arg") 
-            ;;
+        *)
+            echo "ERROR: Unknown option '$arg'. Use --help for usage." >&2
+            exit 1
+            ;;
     esac
 done
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
ARGS=()
for arg in "$@"; do
case "$arg" in
--json)
JSON_MODE=true
;;
--help|-h)
echo "Usage: $0 [--json]"
echo " --json Output results in JSON format"
echo " --help Show this help message"
exit 0
;;
*)
ARGS+=("$arg")
;;
esac
done
for arg in "$@"; do
case "$arg" in
--json)
JSON_MODE=true
;;
--help|-h)
echo "Usage: $0 [--json]"
echo " --json Output results in JSON format"
echo " --help Show this help message"
exit 0
;;
*)
echo "ERROR: Unknown option '$arg'. Use --help for usage." >&2
exit 1
;;
esac
done
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.specify/scripts/bash/setup-plan.sh around lines 7 - 24, Remove the unused
ARGS array: delete the ARGS=() initialization and the default case that appends
to it (the case branch using ARGS+=("$arg")) inside the for loop, leaving only
the recognized flag handling (--json and --help); ensure no other code
references ARGS (if there are, either wire those references to use "$@" or
implement intended handling for leftover positional args instead).

Comment on lines +41 to +50
# Copy plan template if it exists
TEMPLATE=$(resolve_template "plan-template" "$REPO_ROOT") || true
if [[ -n "$TEMPLATE" ]] && [[ -f "$TEMPLATE" ]]; then
cp "$TEMPLATE" "$IMPL_PLAN"
echo "Copied plan template to $IMPL_PLAN"
else
echo "Warning: Plan template not found"
# Create a basic plan file if template doesn't exist
touch "$IMPL_PLAN"
fi
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Empty plan file fallback may cause confusion.

When the template is not found, an empty plan.md is created. Downstream commands expecting content may fail silently or produce unexpected results. Consider writing a minimal header or structured placeholder instead.

♻️ Create minimal placeholder instead of empty file
 else
     echo "Warning: Plan template not found"
     # Create a basic plan file if template doesn't exist
-    touch "$IMPL_PLAN"
+    cat > "$IMPL_PLAN" << 'EOF'
+# Implementation Plan
+
+<!-- Plan template not found. Please add plan content here. -->
+EOF
 fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.specify/scripts/bash/setup-plan.sh around lines 41 - 50, The current
fallback creates an empty plan file (touch "$IMPL_PLAN") which can confuse
downstream consumers; replace that with writing a minimal placeholder into
IMPL_PLAN (e.g., a short header and brief instructions) so tools have
predictable content. Update the branch where TEMPLATE is missing in the block
that uses resolve_template and variables TEMPLATE and IMPL_PLAN to write a
minimal structured header (like "# Plan" plus a one-line placeholder) into the
file instead of touching it, and keep the existing warning echo.

Comment on lines +316 to +356
# Perform substitutions with error checking using safer approach
# Escape special characters for sed by using a different delimiter or escaping
local escaped_lang=$(printf '%s\n' "$NEW_LANG" | sed 's/[\[\.*^$()+{}|]/\\&/g')
local escaped_framework=$(printf '%s\n' "$NEW_FRAMEWORK" | sed 's/[\[\.*^$()+{}|]/\\&/g')
local escaped_branch=$(printf '%s\n' "$CURRENT_BRANCH" | sed 's/[\[\.*^$()+{}|]/\\&/g')

# Build technology stack and recent change strings conditionally
local tech_stack
if [[ -n "$escaped_lang" && -n "$escaped_framework" ]]; then
tech_stack="- $escaped_lang + $escaped_framework ($escaped_branch)"
elif [[ -n "$escaped_lang" ]]; then
tech_stack="- $escaped_lang ($escaped_branch)"
elif [[ -n "$escaped_framework" ]]; then
tech_stack="- $escaped_framework ($escaped_branch)"
else
tech_stack="- ($escaped_branch)"
fi

local recent_change
if [[ -n "$escaped_lang" && -n "$escaped_framework" ]]; then
recent_change="- $escaped_branch: Added $escaped_lang + $escaped_framework"
elif [[ -n "$escaped_lang" ]]; then
recent_change="- $escaped_branch: Added $escaped_lang"
elif [[ -n "$escaped_framework" ]]; then
recent_change="- $escaped_branch: Added $escaped_framework"
else
recent_change="- $escaped_branch: Added"
fi

local substitutions=(
"s|\[PROJECT NAME\]|$project_name|"
"s|\[DATE\]|$current_date|"
"s|\[EXTRACTED FROM ALL PLAN.MD FILES\]|$tech_stack|"
"s|\[ACTUAL STRUCTURE FROM PLANS\]|$project_structure|g"
"s|\[ONLY COMMANDS FOR ACTIVE TECHNOLOGIES\]|$commands|"
"s|\[LANGUAGE-SPECIFIC, ONLY FOR LANGUAGES IN USE\]|$language_conventions|"
"s|\[LAST 3 FEATURES AND WHAT THEY ADDED\]|$recent_change|"
)

for substitution in "${substitutions[@]}"; do
if ! sed -i.bak -e "$substitution" "$temp_file"; then
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, locate and examine the file
find . -name "update-agent-context.sh" -type f

Repository: ambient-code/reference

Length of output: 113


🏁 Script executed:

# Check the file exists and look at the specified lines
if [ -f "./.specify/scripts/bash/update-agent-context.sh" ]; then
  wc -l ./.specify/scripts/bash/update-agent-context.sh
fi

Repository: ambient-code/reference

Length of output: 117


🏁 Script executed:

# Get the context around lines 316-356
sed -n '310,360p' ./.specify/scripts/bash/update-agent-context.sh | cat -n

Repository: ambient-code/reference

Length of output: 2695


🏁 Script executed:

# Search for the get_commands_for_language function
rg "get_commands_for_language" -A 20 ./.specify/scripts/bash/update-agent-context.sh

Repository: ambient-code/reference

Length of output: 1610


🏁 Script executed:

# Check if there's any escaping applied to the right-hand-side variables before sed
rg "escaped_commands\|escaped_project_name\|escaped_tech_stack\|escaped_recent_change" ./.specify/scripts/bash/update-agent-context.sh

Repository: ambient-code/reference

Length of output: 48


🏁 Script executed:

# Test sed behavior with & in replacement text
cat > /tmp/test_sed.sh << 'EOF'
#!/bin/bash

# Create test template
cat > /tmp/template.txt << 'TEMPLATE'
Commands: [COMMANDS]
Language: [LANGUAGE]
TEMPLATE

# Test case 1: Python commands with &&
commands="cd src && pytest && ruff check ."
echo "Test 1: Python commands with &&"
echo "Input: $commands"
cp /tmp/template.txt /tmp/output.txt
sed -i "s|\[COMMANDS\]|$commands|" /tmp/output.txt
echo "Output:"
cat /tmp/output.txt
echo "---"

# Test case 2: Language with & character
language="C&C++"
echo "Test 2: Language with &"
echo "Input: $language"
cp /tmp/template.txt /tmp/output.txt
sed -i "s|\[LANGUAGE\]|$language|" /tmp/output.txt
echo "Output:"
cat /tmp/output.txt
echo "---"

# Test case 3: What should happen - properly escaped
commands="cd src && pytest && ruff check ."
# Escape & and \ for sed replacement text
escaped_commands=$(printf '%s\n' "$commands" | sed 's/[&\]/\\&/g')
echo "Test 3: Properly escaped commands"
echo "Escaped input: $escaped_commands"
cp /tmp/template.txt /tmp/output.txt
sed -i "s|\[COMMANDS\]|$escaped_commands|" /tmp/output.txt
echo "Output:"
cat /tmp/output.txt
EOF

bash /tmp/test_sed.sh

Repository: ambient-code/reference

Length of output: 502


Escape replacement strings for sed & and \ metacharacters.

The replacement-side variables ($project_name, $current_date, $tech_stack, $commands, $language_conventions, $recent_change, $project_structure) are not escaped for sed replacement metacharacters. The & character in sed replacement text represents the matched pattern, and \ is the escape character.

This causes immediate corruption: get_commands_for_language returns cd src && pytest && ruff check . for Python, which produces cd src [COMMANDS][COMMANDS] pytest [COMMANDS][COMMANDS] ruff check . instead of the intended text. Similarly, any input containing & (e.g., project names like "C&C++") will be corrupted. The escaping applied to escaped_lang, escaped_framework, and escaped_branch is only for the pattern side (left of |), not the replacement side.

Each replacement variable must be escaped with sed 's/[&\]/\\&/g' before use in the substitution expressions.

🧰 Tools
🪛 Shellcheck (0.11.0)

[warning] 318-318: Declare and assign separately to avoid masking return values.

(SC2155)


[info] 318-318: Expressions don't expand in single quotes, use double quotes for that.

(SC2016)


[warning] 319-319: Declare and assign separately to avoid masking return values.

(SC2155)


[info] 319-319: Expressions don't expand in single quotes, use double quotes for that.

(SC2016)


[warning] 320-320: Declare and assign separately to avoid masking return values.

(SC2155)


[info] 320-320: Expressions don't expand in single quotes, use double quotes for that.

(SC2016)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.specify/scripts/bash/update-agent-context.sh around lines 316 - 356, The
sed replacements are not escaping replacement-side metacharacters (& and \),
corrupting inserted values (e.g., get_commands_for_language output); before
building the substitutions array, create escaped replacement variables (e.g.,
escaped_project_name, escaped_current_date, escaped_tech_stack,
escaped_commands, escaped_language_conventions, escaped_recent_change,
escaped_project_structure) by running each through a replacement-escaping step
(sed 's/[&\]/\\&/g' or equivalent parameter expansion), then use those escaped_*
symbols in the substitutions array (which is iterated by the sed -e
"$substitution" loop) so the right-hand side of "s|...|...|" is safe; update
references to project_name, current_date, tech_stack, commands,
language_conventions, recent_change, and project_structure accordingly.

Comment on lines +465 to +483
if [[ "$line" == "## Recent Changes" ]]; then
echo "$line" >> "$temp_file"
# Add new change entry right after the heading
if [[ -n "$new_change_entry" ]]; then
echo "$new_change_entry" >> "$temp_file"
fi
in_changes_section=true
changes_entries_added=true
continue
elif [[ $in_changes_section == true ]] && [[ "$line" =~ ^##[[:space:]] ]]; then
echo "$line" >> "$temp_file"
in_changes_section=false
continue
elif [[ $in_changes_section == true ]] && [[ "$line" == "- "* ]]; then
# Keep only first 2 existing changes
if [[ $existing_changes_count -lt 2 ]]; then
echo "$line" >> "$temp_file"
((existing_changes_count++))
fi
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Avoid duplicating the same branch in ## Recent Changes.

This block always prepends new_change_entry when the section exists and never checks whether that exact line is already present. Re-running the script on the same feature produces duplicate history and pushes older entries out of the retained top-three window.

Suggested fix
         if [[ "$line" == "## Recent Changes" ]]; then
             echo "$line" >> "$temp_file"
-            # Add new change entry right after the heading
-            if [[ -n "$new_change_entry" ]]; then
+            # Add the current branch once, but don't duplicate it on reruns
+            if [[ -n "$new_change_entry" ]] && ! grep -Fqx "$new_change_entry" "$target_file"; then
                 echo "$new_change_entry" >> "$temp_file"
             fi
             in_changes_section=true
             changes_entries_added=true
             continue
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if [[ "$line" == "## Recent Changes" ]]; then
echo "$line" >> "$temp_file"
# Add new change entry right after the heading
if [[ -n "$new_change_entry" ]]; then
echo "$new_change_entry" >> "$temp_file"
fi
in_changes_section=true
changes_entries_added=true
continue
elif [[ $in_changes_section == true ]] && [[ "$line" =~ ^##[[:space:]] ]]; then
echo "$line" >> "$temp_file"
in_changes_section=false
continue
elif [[ $in_changes_section == true ]] && [[ "$line" == "- "* ]]; then
# Keep only first 2 existing changes
if [[ $existing_changes_count -lt 2 ]]; then
echo "$line" >> "$temp_file"
((existing_changes_count++))
fi
if [[ "$line" == "## Recent Changes" ]]; then
echo "$line" >> "$temp_file"
# Add the current branch once, but don't duplicate it on reruns
if [[ -n "$new_change_entry" ]] && ! grep -Fqx "$new_change_entry" "$target_file"; then
echo "$new_change_entry" >> "$temp_file"
fi
in_changes_section=true
changes_entries_added=true
continue
elif [[ $in_changes_section == true ]] && [[ "$line" =~ ^##[[:space:]] ]]; then
echo "$line" >> "$temp_file"
in_changes_section=false
continue
elif [[ $in_changes_section == true ]] && [[ "$line" == "- "* ]]; then
# Keep only first 2 existing changes
if [[ $existing_changes_count -lt 2 ]]; then
echo "$line" >> "$temp_file"
((existing_changes_count++))
fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.specify/scripts/bash/update-agent-context.sh around lines 465 - 483, The
script always appends new_change_entry into the "## Recent Changes" block
without checking for duplicates; modify the logic in the block that handles "##
Recent Changes" so that before echoing new_change_entry you scan the existing
changes in that section (use in_changes_section to iterate lines until the next
"## " heading) and only add new_change_entry if it is not already present
(compare the exact string), leaving existing_changes_count logic intact so you
still keep only the first two existing entries when writing to temp_file.

@jeremyeder
Copy link
Copy Markdown
Collaborator Author

Code review

Found 1 issue:

  1. Broken file path reference: line 49 instructs to "Read each command file in .specify/templates/commands/*.md" but this directory does not exist. The actual command files are in .claude/commands/. This will cause the constitution update procedure to fail when following its own instructions.

- Read `.specify/templates/tasks-template.md` and ensure task categorization reflects new or removed principle-driven task types (e.g., observability, versioning, testing discipline).
- 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.
- Read any runtime guidance docs (e.g., `README.md`, `docs/quickstart.md`, or agent-specific guidance files if present). Update references to principles changed.

🤖 Generated with Claude Code

- If this code review was useful, please react with 👍. Otherwise, react with 👎.

jeremyeder added a commit to jeremyeder/reference that referenced this pull request Apr 1, 2026
- Fix broken path reference in speckit.constitution.md
  (.specify/templates/commands/*.md → .claude/commands/speckit.*.md)
- Regenerate .repomap.txt to reflect new files
- Add .worktrees/ to .gitignore

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant