Skip to content

Restore .specify directory#944

Merged
jeremyeder merged 4 commits intomainfrom
restore/specify-directory
Mar 17, 2026
Merged

Restore .specify directory#944
jeremyeder merged 4 commits intomainfrom
restore/specify-directory

Conversation

@jeremyeder
Copy link
Copy Markdown
Contributor

Summary

Restored files

Memory:

  • .specify/memory/constitution.md
  • .specify/memory/constitution_update_checklist.md
  • .specify/memory/orginal/architecture.md
  • .specify/memory/orginal/capabilities.md

Scripts:

  • .specify/scripts/bash/check-prerequisites.sh
  • .specify/scripts/bash/check-task-prerequisites.sh
  • .specify/scripts/bash/common.sh
  • .specify/scripts/bash/create-new-feature.sh
  • .specify/scripts/bash/get-feature-paths.sh
  • .specify/scripts/bash/setup-plan.sh
  • .specify/scripts/bash/update-agent-context.sh

Templates:

  • .specify/templates/agent-file-template.md
  • .specify/templates/checklist-template.md
  • .specify/templates/plan-template.md
  • .specify/templates/spec-template.md
  • .specify/templates/tasks-template.md

Files restored from commit 702cf503 (the parent of #680's merge).

🤖 Generated with Claude Code

The .specify directory (memory, scripts, templates) was inadvertently
removed in #680 (chore: remove root-level cruft). This restores all 16
files to their state prior to that merge and removes the .specify/
entry from .gitignore.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 17, 2026

Walkthrough

A .specify/ directory is now tracked, adding governance docs (constitution), templates, and a set of Bash workflow scripts for feature branch creation, prerequisite checks, plan setup, and AI agent context management.

Changes

Cohort / File(s) Summary
Repo config
/.gitignore
Removed the rule ignoring .specify/, so the .specify/ tree is now tracked.
Governance & Governance tooling
.specify/memory/constitution.md, .specify/memory/constitution_update_checklist.md
Added a full ACP Constitution (10 principles, development/governance rules, deployment/monitoring/security guidance) and a checklist for propagating constitution updates. Large, policy-heavy docs — review for sensitive or prescriptive policy text.
Core Bash library
.specify/scripts/bash/common.sh
New shared helper functions for repo/branch resolution, feature path discovery, and basic file/dir checks used by downstream scripts. Review for branch-name parsing and non-git fallbacks.
Feature lifecycle scripts
.specify/scripts/bash/create-new-feature.sh, .specify/scripts/bash/get-feature-paths.sh, .specify/scripts/bash/setup-plan.sh
New automation for creating feature branches/directories, resolving feature paths, and bootstrapping plan.md from templates. Check git interaction, branch-number calculation, truncation logic, and template fallbacks.
Prerequisite validators
.specify/scripts/bash/check-prerequisites.sh, .specify/scripts/bash/check-task-prerequisites.sh
Scripts to validate feature-level prerequisites (docs, tasks, contracts). Provide JSON and human-readable outputs. Verify messaging and error codes.
Agent context management
.specify/scripts/bash/update-agent-context.sh, .specify/templates/agent-file-template.md
Large script to generate/update per-agent context files from plan.md using a template; supports multiple agent targets and atomic writes. High-complexity; inspect parsing, substitution, and file-safety behavior.
Specification & plan templates
.specify/templates/spec-template.md, .specify/templates/plan-template.md, .specify/templates/tasks-template.md, .specify/templates/checklist-template.md
Added comprehensive templates for specs, implementation plans, tasks, and checklists. Review placeholders, required-field guidance, and any default/example content that might be checked into repo.

Sequence Diagram(s)

sequenceDiagram
    participant User as User
    participant Script as create-new-feature.sh
    participant Git as Git
    participant FS as Filesystem
    rect rgba(200,200,255,0.5)
    User->>Script: invoke (options, description)
    Script->>Script: compute branch number & suffix
    alt Git available
        Script->>Git: check remote/local branches
        Git-->>Script: branch info
        Script->>Git: create & checkout branch
        Git-->>Script: confirmation
    else No Git
        Script->>FS: warn, skip git steps
    end
    Script->>FS: create feature dir & populate spec/plan from templates
    Script-->>User: output JSON or summary (BRANCH_NAME, SPEC_FILE, FEATURE_NUM)
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 48.39% 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 title 'Restore .specify directory' clearly and concisely describes the main change in the changeset: restoring the .specify directory and its files that were inadvertently removed.
Description check ✅ Passed The description is directly related to the changeset, providing a clear summary of restored files, their locations, and the source commit. It effectively explains the restoration action and lists all relevant files.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch restore/specify-directory
📝 Coding Plan
  • Generate coding plan for human review comments

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

jeremyeder and others added 2 commits March 17, 2026 15:43
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jeremyeder jeremyeder marked this pull request as ready for review March 17, 2026 22:44
Copy link
Copy Markdown
Contributor

@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: 23

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

Inline comments:
In @.specify/memory/constitution_update_checklist.md:
- Around line 77-81: Update the Template Sync Status block under "Template Sync
Status" by refreshing the "Last sync check" date and the "Templates aligned"
status to reflect the current state or add a clear TODO note to verify alignment
after restoration; specifically modify the "Last sync check:" line and the "-
Templates aligned:" line (or append a TODO below them) to either a current date
and correct status or a mark like "TBD — verify after restore" so the checklist
accurately represents the restored .specify directory.

In @.specify/memory/constitution.md:
- Line 147: Update the internal reference "vTeam" to "ACP" in the constitution
text: replace the phrase "session execution time for vTeam" (and any other
occurrences of "vTeam" in this document) with "session execution time for ACP"
to align with the Naming & Legacy Migration guidance and keep documentation/log
messages consistent.
- Around line 416-417: Replace the placeholder tokens [CONSTITUTION_VERSION],
[RATIFICATION_DATE], and [LAST_AMENDED_DATE] in the footer line that currently
reads "**Version**: [CONSTITUTION_VERSION] | **Ratified**: [RATIFICATION_DATE] |
**Last Amended**: [LAST_AMENDED_DATE]" with the actual values from the header
changelog (e.g., set [CONSTITUTION_VERSION] → v1.0.0 and [RATIFICATION_DATE] and
[LAST_AMENDED_DATE] → 2025-11-13 as appropriate) so the footer matches the
documented changelog entries.

In @.specify/scripts/bash/check-prerequisites.sh:
- Line 82: The eval invocation using command substitution should be quoted to
prevent word splitting and globbing: change the eval $(get_feature_paths) call
so the substitution from get_feature_paths is quoted (i.e., use eval "..."
around the $(get_feature_paths) result) and ensure get_feature_paths outputs a
single well-formed string; update the call site where eval and get_feature_paths
are used to use the quoted form to avoid accidental word splitting or filename
expansion.

In @.specify/scripts/bash/check-task-prerequisites.sh:
- Around line 1-15: The script is hard to read because many constructs are
compressed onto single lines; refactor check-task-prerequisites.sh to use
multi-line, indented statements for the for loop/case that sets JSON_MODE, the
SCRIPT_DIR assignment and source call, the eval $(get_feature_paths) and
check_feature_branch call, and all subsequent conditionals (the
FEATURE_DIR/IMPL_PLAN checks and the JSON_MODE branch). Expand the docs array
construction (the docs variable, the [[ -f "$RESEARCH" ]] etc. checks and the
json_docs formatting) into clear sequential if/[[...]] blocks and move the
check_file/check_dir calls onto their own lines so functions like check_file,
check_dir and symbols FEATURE_DIR, IMPL_PLAN, RESEARCH, DATA_MODEL,
CONTRACTS_DIR, QUICKSTART, json_docs are easy to locate and read.
- Line 7: The eval invocation uses unquoted command substitution which can cause
word splitting; update the call in the script so eval uses a quoted command
substitution: change eval $(get_feature_paths) to eval "$(get_feature_paths)" so
the output of the get_feature_paths function is treated as a single string and
not split by the shell.
- Line 8: The call to check_feature_branch is missing its second parameter so it
never receives the $has_git_repo flag; update the invocation
check_feature_branch "$CURRENT_BRANCH" || exit 1 to pass the repo-present
boolean (for example check_feature_branch "$CURRENT_BRANCH" "$HAS_GIT_REPO" ||
exit 1) so the function defined in common.sh (check_feature_branch) gets both
$branch and $has_git_repo and can correctly show warnings for non-git
repositories.

In @.specify/scripts/bash/common.sh:
- Line 10: Several local variables use combined declaration+command-substitution
which masks the command exit status; change these to first declare the local
(e.g., local script_dir) and then assign the value on the next line
(script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)") so the
substitution's exit code is preserved. Apply this pattern for get_repo_root call
(replace local repo_root=$(get_repo_root) with local repo_root followed by
repo_root="$(get_repo_root)"), for dirname (local dirname; dirname="$(basename
"$dir")"), and the variable assignments inside get_feature_paths (declare locals
first, then assign the command substitution results on separate lines). Ensure
you update all occurrences of script_dir, repo_root, dirname, and the variables
in get_feature_paths accordingly.
- Around line 119-124: The current else branch logs an error about multiple
matches but then echoes a path and leaves a zero exit status (using variables
prefix, matches, specs_dir, branch_name), so callers can't detect failure;
change the behavior to not return a bogus path and instead fail with a non-zero
status: remove the final echo of "$specs_dir/$branch_name" and replace it with a
non-zero return (e.g., return 1 if this is inside a function, or exit 1 if it's
top-level script) so callers can detect the error condition and handle it
explicitly.

In @.specify/scripts/bash/create-new-feature.sh:
- Around line 91-94: The current assignments to local variables remote_branches
and local_branches using command substitution mask the exit status of git
ls-remote and git branch; change create-new-feature.sh to declare the variables
first (e.g., local remote_branches local local_branches), then assign with
command substitution (remote_branches="$(git ls-remote --heads origin ...)" and
local_branches="$(git branch ... )"), capture the exit code after each git
command (e.g., rc=$? ) and handle non-zero rc (log/exit) to ensure failures from
git ls-remote or git branch are detected and propagated.
- Line 99: The pipeline that builds spec_dirs using find | xargs | sed is unsafe
for filenames with spaces or special chars; update the command that assigns
spec_dirs to use a null-delimited find output and null-safe xargs (i.e., use
find ... -print0 and xargs -0) or an equivalent while-read -d '' loop so
basenames are extracted reliably, then apply the same sed and sort steps on
those null-safe tokens; modify the assignment to spec_dirs to use this null-safe
approach (referencing the spec_dirs variable and the existing find invocation)
so filenames with whitespace or newlines are handled correctly.
- Around line 104-107: The loop that checks numeric maxima (for num in
$remote_branches $local_branches $spec_dirs) compares "$num" to "$max_num" with
[ "$num" -gt "$max_num" ], which can fail if $num is empty or non-numeric;
change the logic in that loop to first validate/coerce $num to an integer (e.g.,
default to 0 when empty and only perform the numeric comparison when $num
matches a digits-only regex) before running the "-gt" comparison against
max_num, updating max_num accordingly; ensure you reference the variables num
and max_num and the for-loop block when applying the fix so non-numeric inputs
are safely handled.
- Line 251: The script currently exports SPECIFY_FEATURE from BRANCH_NAME
(export SPECIFY_FEATURE="$BRANCH_NAME") but exporting only affects child
processes and won't persist in the caller's shell; update the user-facing
message that references SPECIFY_FEATURE/echo to clearly state the variable is
only set for this script's subprocesses and won't remain in the user's
environment, and add optional guidance that users should source the script
(source ./create-new-feature.sh) or use eval to persist the variable if they
intend it to be set in their interactive shell.

In @.specify/scripts/bash/get-feature-paths.sh:
- Line 5: The command substitution used in the script is unquoted and can cause
unwanted word splitting; update the invocation of get_feature_paths so the
result is quoted before passing to eval (i.e., change the eval
$(get_feature_paths) call to quote the substitution), ensuring you reference the
get_feature_paths command and the eval invocation when making the change.
- Line 6: The call to check_feature_branch in get-feature-paths.sh is missing
the second argument (has_git_repo) that common.sh's check_feature_branch(branch,
has_git_repo) expects; update the invocation in get-feature-paths.sh to pass a
boolean/flag indicating whether we're inside a git repo (for example pass an
existing variable like "$HAS_GIT_REPO" or the result of a check such as "$(git
rev-parse --is-inside-work-tree >/dev/null 2>&1 && echo true || echo false)") so
check_feature_branch "$CURRENT_BRANCH" "$HAS_GIT_REPO" (or equivalent) is used
and the function can correctly validate branch names in git repos.

In @.specify/scripts/bash/setup-plan.sh:
- Line 31: The command substitution used to set feature paths is unquoted which
allows word splitting for paths with spaces; update the eval invocation that
runs get_feature_paths (the eval $(get_feature_paths) call) to quote the
substitution so it reads eval "$(get_feature_paths)" to preserve whitespace and
special characters in returned paths and prevent corrupted variable assignments.
- Around line 51-53: The JSON branch in setup-plan.sh currently uses printf to
interpolate variables (JSON_MODE block) which doesn't escape JSON-special
characters; replace the printf with a safe JSON builder such as jq: in the
JSON_MODE conditional, invoke jq -n with --arg for each variable (e.g., --arg
FEATURE_SPEC "$FEATURE_SPEC" --arg IMPL_PLAN "$IMPL_PLAN" --arg SPECS_DIR
"$FEATURE_DIR" --arg BRANCH "$CURRENT_BRANCH" --arg HAS_GIT "$HAS_GIT") and emit
an object {FEATURE_SPEC:$FEATURE_SPEC, IMPL_PLAN:$IMPL_PLAN,
SPECS_DIR:$SPECS_DIR, BRANCH:$BRANCH, HAS_GIT:$HAS_GIT}; this ensures values are
properly escaped and safe for JSON output.

In @.specify/scripts/bash/update-agent-context.sh:
- Around line 233-241: The get_project_structure function prints literal "\n"
sequences with echo which is unreliable; change it to use printf and emit real
newlines (e.g., printf "backend\nfrontend\ntests/\n" and printf "src\ntests/\n"
for the non-web branch) so downstream substitution at the later use (the code
that expects actual newlines around line 349) works portably and consistently.
- Line 412: Remove the unused local variable file_ended from the script—locate
the declaration "local file_ended=false" in update-agent-context.sh (within the
function that manipulates the file stream) and delete that line so no unused
variables remain; ensure no other references to file_ended exist before
committing.
- Around line 720-721: The usage string printed by log_info is missing the "roo"
agent; update the usage output (the log_info call that currently lists agents)
to include "roo" and also add "roo" to the script header/agent list at the top
of the file (around the existing header on line 38), ensuring consistency with
the update_specific_agent function which already handles the roo agent.
- Around line 67-74: Multiple agent constants (AGENTS_FILE, AMP_FILE, Q_FILE)
point to the same path causing duplicate work in update_all_existing_agents();
fix by deduplicating file paths or tracking processed files: update the
update_all_existing_agents() function to build a unique list/set of target paths
(derived from AGENTS_FILE, AMP_FILE, Q_FILE, WINDSURF_FILE, KILOCODE_FILE,
AUGGIE_FILE, ROO_FILE, CODEBUDDY_FILE) before iterating, or maintain a
processed_files set and skip a file if already processed when encountering it
again, ensuring each physical file is updated only once.
- Line 56: The eval line using get_feature_paths is unquoted and can split paths
with spaces; update the eval invocation that currently calls get_feature_paths
so the command substitution is wrapped in quotes (i.e., quote the result of
get_feature_paths when passing it to eval) to prevent word-splitting and
preserve paths with spaces.
- Around line 302-304: Split the declaration and assignment for escaped_lang,
escaped_framework, and escaped_branch so a failing command substitution isn't
masked by the local declaration: first declare each variable with separate local
statements (local escaped_lang; local escaped_framework; local escaped_branch)
and then assign them using the existing printf | sed substitutions
(escaped_lang=$(printf ...), escaped_framework=$(printf ...),
escaped_branch=$(printf ...)). This preserves and surfaces the true exit status
of the command substitutions used to produce escaped_lang, escaped_framework,
and escaped_branch.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 883ef057-3401-4837-8d52-d95ea4f34b9d

📥 Commits

Reviewing files that changed from the base of the PR and between 6a487e0 and 01b2a02.

📒 Files selected for processing (15)
  • .gitignore
  • .specify/memory/constitution.md
  • .specify/memory/constitution_update_checklist.md
  • .specify/scripts/bash/check-prerequisites.sh
  • .specify/scripts/bash/check-task-prerequisites.sh
  • .specify/scripts/bash/common.sh
  • .specify/scripts/bash/create-new-feature.sh
  • .specify/scripts/bash/get-feature-paths.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/plan-template.md
  • .specify/templates/spec-template.md
  • .specify/templates/tasks-template.md
💤 Files with no reviewable changes (1)
  • .gitignore

Comment on lines +77 to +81
## Template Sync Status

Last sync check: 2025-07-16
- Constitution version: 2.1.1
- Templates aligned: ❌ (missing versioning, observability details)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Sync status appears outdated or inconsistent.

The last sync check is dated 2025-07-16 with templates marked as misaligned (❌). Since this PR is restoring the .specify directory, consider updating the sync status to reflect the current state or adding a TODO to verify alignment after restoration.

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

In @.specify/memory/constitution_update_checklist.md around lines 77 - 81,
Update the Template Sync Status block under "Template Sync Status" by refreshing
the "Last sync check" date and the "Templates aligned" status to reflect the
current state or add a clear TODO note to verify alignment after restoration;
specifically modify the "Last sync check:" line and the "- Templates aligned:"
line (or append a TODO below them) to either a current date and correct status
or a mark like "TBD — verify after restore" so the checklist accurately
represents the restored .specify directory.

Comment on lines +416 to +417
**Version**: [CONSTITUTION_VERSION] | **Ratified**: [RATIFICATION_DATE] | **Last Amended**: [LAST_AMENDED_DATE]
<!-- Example: Version: 2.1.1 | Ratified: 2025-06-13 | Last Amended: 2025-07-16 -->
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Footer contains unfilled placeholder tokens.

The version footer uses placeholders [CONSTITUTION_VERSION], [RATIFICATION_DATE], and [LAST_AMENDED_DATE] while the header changelog already documents these values (v1.0.0, 2025-11-13). Consider populating these fields for consistency.

Proposed fix based on changelog
-**Version**: [CONSTITUTION_VERSION] | **Ratified**: [RATIFICATION_DATE] | **Last Amended**: [LAST_AMENDED_DATE]
-<!-- Example: Version: 2.1.1 | Ratified: 2025-06-13 | Last Amended: 2025-07-16 -->
+**Version**: 1.0.0 | **Ratified**: 2025-11-13 | **Last Amended**: 2025-11-13
📝 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
**Version**: [CONSTITUTION_VERSION] | **Ratified**: [RATIFICATION_DATE] | **Last Amended**: [LAST_AMENDED_DATE]
<!-- Example: Version: 2.1.1 | Ratified: 2025-06-13 | Last Amended: 2025-07-16 -->
**Version**: 1.0.0 | **Ratified**: 2025-11-13 | **Last Amended**: 2025-11-13
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.specify/memory/constitution.md around lines 416 - 417, Replace the
placeholder tokens [CONSTITUTION_VERSION], [RATIFICATION_DATE], and
[LAST_AMENDED_DATE] in the footer line that currently reads "**Version**:
[CONSTITUTION_VERSION] | **Ratified**: [RATIFICATION_DATE] | **Last Amended**:
[LAST_AMENDED_DATE]" with the actual values from the header changelog (e.g., set
[CONSTITUTION_VERSION] → v1.0.0 and [RATIFICATION_DATE] and [LAST_AMENDED_DATE]
→ 2025-11-13 as appropriate) so the footer matches the documented changelog
entries.

source "$SCRIPT_DIR/common.sh"

# Get feature paths and validate branch
eval $(get_feature_paths)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Quote command substitution to prevent word splitting.

Proposed fix
-eval $(get_feature_paths)
+eval "$(get_feature_paths)"
📝 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
eval $(get_feature_paths)
eval "$(get_feature_paths)"
🧰 Tools
🪛 Shellcheck (0.11.0)

[warning] 82-82: Quote this to prevent word splitting.

(SC2046)

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

In @.specify/scripts/bash/check-prerequisites.sh at line 82, The eval invocation
using command substitution should be quoted to prevent word splitting and
globbing: change the eval $(get_feature_paths) call so the substitution from
get_feature_paths is quoted (i.e., use eval "..." around the
$(get_feature_paths) result) and ensure get_feature_paths outputs a single
well-formed string; update the call site where eval and get_feature_paths are
used to use the quoted form to avoid accidental word splitting or filename
expansion.

Comment on lines +1 to +15
#!/usr/bin/env bash
set -e
JSON_MODE=false
for arg in "$@"; do case "$arg" in --json) JSON_MODE=true ;; --help|-h) echo "Usage: $0 [--json]"; exit 0 ;; esac; done
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/common.sh"
eval $(get_feature_paths)
check_feature_branch "$CURRENT_BRANCH" || exit 1
if [[ ! -d "$FEATURE_DIR" ]]; then echo "ERROR: Feature directory not found: $FEATURE_DIR"; echo "Run /specify first."; exit 1; fi
if [[ ! -f "$IMPL_PLAN" ]]; then echo "ERROR: plan.md not found in $FEATURE_DIR"; echo "Run /plan first."; exit 1; fi
if $JSON_MODE; then
docs=(); [[ -f "$RESEARCH" ]] && docs+=("research.md"); [[ -f "$DATA_MODEL" ]] && docs+=("data-model.md"); ([[ -d "$CONTRACTS_DIR" ]] && [[ -n "$(ls -A "$CONTRACTS_DIR" 2>/dev/null)" ]]) && docs+=("contracts/"); [[ -f "$QUICKSTART" ]] && docs+=("quickstart.md");
json_docs=$(printf '"%s",' "${docs[@]}"); json_docs="[${json_docs%,}]"; printf '{"FEATURE_DIR":"%s","AVAILABLE_DOCS":%s}\n' "$FEATURE_DIR" "$json_docs"
else
echo "FEATURE_DIR:$FEATURE_DIR"; echo "AVAILABLE_DOCS:"; check_file "$RESEARCH" "research.md"; check_file "$DATA_MODEL" "data-model.md"; check_dir "$CONTRACTS_DIR" "contracts/"; check_file "$QUICKSTART" "quickstart.md"; fi
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider formatting for readability.

The entire script is compressed into single-line statements, making it difficult to read and maintain. The other scripts in this PR (e.g., setup-plan.sh, check-prerequisites.sh) use multi-line formatting for similar logic.

🧰 Tools
🪛 Shellcheck (0.11.0)

[info] 6-6: Not following: ./common.sh was not specified as input (see shellcheck -x).

(SC1091)


[warning] 7-7: Quote this to prevent word splitting.

(SC2046)


[style] 12-12: Use { ..; } instead of (..) to avoid subshell overhead.

(SC2235)

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

In @.specify/scripts/bash/check-task-prerequisites.sh around lines 1 - 15, The
script is hard to read because many constructs are compressed onto single lines;
refactor check-task-prerequisites.sh to use multi-line, indented statements for
the for loop/case that sets JSON_MODE, the SCRIPT_DIR assignment and source
call, the eval $(get_feature_paths) and check_feature_branch call, and all
subsequent conditionals (the FEATURE_DIR/IMPL_PLAN checks and the JSON_MODE
branch). Expand the docs array construction (the docs variable, the [[ -f
"$RESEARCH" ]] etc. checks and the json_docs formatting) into clear sequential
if/[[...]] blocks and move the check_file/check_dir calls onto their own lines
so functions like check_file, check_dir and symbols FEATURE_DIR, IMPL_PLAN,
RESEARCH, DATA_MODEL, CONTRACTS_DIR, QUICKSTART, json_docs are easy to locate
and read.

Comment on lines +67 to +74
AGENTS_FILE="$REPO_ROOT/AGENTS.md"
WINDSURF_FILE="$REPO_ROOT/.windsurf/rules/specify-rules.md"
KILOCODE_FILE="$REPO_ROOT/.kilocode/rules/specify-rules.md"
AUGGIE_FILE="$REPO_ROOT/.augment/rules/specify-rules.md"
ROO_FILE="$REPO_ROOT/.roo/rules/specify-rules.md"
CODEBUDDY_FILE="$REPO_ROOT/CODEBUDDY.md"
AMP_FILE="$REPO_ROOT/AGENTS.md"
Q_FILE="$REPO_ROOT/AGENTS.md"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Multiple agents share the same file path, causing redundant updates.

AGENTS_FILE, AMP_FILE, and Q_FILE all point to $REPO_ROOT/AGENTS.md. In update_all_existing_agents() (lines 661-694), after AGENTS_FILE is processed, the same file would be updated again when checking Q_FILE since they reference the same path.

Consider either:

  1. Deduplicating the file paths before processing in update_all_existing_agents()
  2. Tracking which files have already been updated to skip duplicates
🔧 Proposed approach for deduplication
 update_all_existing_agents() {
     local found_agent=false
+    local -A processed_files=()
     
     # Check each possible agent file and update if it exists
     if [[ -f "$CLAUDE_FILE" ]]; then
         update_agent_file "$CLAUDE_FILE" "Claude Code"
         found_agent=true
+        processed_files["$CLAUDE_FILE"]=1
     fi
     
     # ... similar for other agents ...
     
-    if [[ -f "$Q_FILE" ]]; then
+    if [[ -f "$Q_FILE" ]] && [[ -z "${processed_files[$Q_FILE]:-}" ]]; then
         update_agent_file "$Q_FILE" "Amazon Q Developer CLI"
         found_agent=true
     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 67 - 74, Multiple
agent constants (AGENTS_FILE, AMP_FILE, Q_FILE) point to the same path causing
duplicate work in update_all_existing_agents(); fix by deduplicating file paths
or tracking processed files: update the update_all_existing_agents() function to
build a unique list/set of target paths (derived from AGENTS_FILE, AMP_FILE,
Q_FILE, WINDSURF_FILE, KILOCODE_FILE, AUGGIE_FILE, ROO_FILE, CODEBUDDY_FILE)
before iterating, or maintain a processed_files set and skip a file if already
processed when encountering it again, ensuring each physical file is updated
only once.

Comment on lines +233 to +241
get_project_structure() {
local project_type="$1"

if [[ "$project_type" == *"web"* ]]; then
echo "backend/\\nfrontend/\\ntests/"
else
echo "src/\\ntests/"
fi
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Use printf instead of echo for escape sequences.

echo behavior with escape sequences is inconsistent across shells. Use printf for reliable output.

♻️ Proposed fix
 get_project_structure() {
     local project_type="$1"
     
     if [[ "$project_type" == *"web"* ]]; then
-        echo "backend/\\nfrontend/\\ntests/"
+        printf '%s\n' "backend/" "frontend/" "tests/"
     else
-        echo "src/\\ntests/"
+        printf '%s\n' "src/" "tests/"
     fi
 }

Note: The current approach attempts to embed literal \n for later substitution (line 349), but using actual newlines would be more reliable and portable.

📝 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
get_project_structure() {
local project_type="$1"
if [[ "$project_type" == *"web"* ]]; then
echo "backend/\\nfrontend/\\ntests/"
else
echo "src/\\ntests/"
fi
}
get_project_structure() {
local project_type="$1"
if [[ "$project_type" == *"web"* ]]; then
printf '%s\n' "backend/" "frontend/" "tests/"
else
printf '%s\n' "src/" "tests/"
fi
}
🧰 Tools
🪛 Shellcheck (0.11.0)

[info] 237-237: echo may not expand escape sequences. Use printf.

(SC2028)


[info] 239-239: echo may not expand escape sequences. Use printf.

(SC2028)

🤖 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 233 - 241, The
get_project_structure function prints literal "\n" sequences with echo which is
unreliable; change it to use printf and emit real newlines (e.g., printf
"backend\nfrontend\ntests/\n" and printf "src\ntests/\n" for the non-web branch)
so downstream substitution at the later use (the code that expects actual
newlines around line 349) works portably and consistently.

Comment on lines +302 to +304
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')
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Declare and assign separately to avoid masking return values.

When declaration and assignment happen on the same line, a failed command substitution's exit code is masked by the local declaration succeeding.

♻️ Proposed fix
-    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')
+    local escaped_lang
+    escaped_lang=$(printf '%s\n' "$NEW_LANG" | sed 's/[\[\.*^$()+{}|]/\\&/g')
+    local escaped_framework
+    escaped_framework=$(printf '%s\n' "$NEW_FRAMEWORK" | sed 's/[\[\.*^$()+{}|]/\\&/g')
+    local escaped_branch
+    escaped_branch=$(printf '%s\n' "$CURRENT_BRANCH" | sed 's/[\[\.*^$()+{}|]/\\&/g')
📝 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
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')
local escaped_lang
escaped_lang=$(printf '%s\n' "$NEW_LANG" | sed 's/[\[\.*^$()+{}|]/\\&/g')
local escaped_framework
escaped_framework=$(printf '%s\n' "$NEW_FRAMEWORK" | sed 's/[\[\.*^$()+{}|]/\\&/g')
local escaped_branch
escaped_branch=$(printf '%s\n' "$CURRENT_BRANCH" | sed 's/[\[\.*^$()+{}|]/\\&/g')
🧰 Tools
🪛 Shellcheck (0.11.0)

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

(SC2155)


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

(SC2016)


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

(SC2155)


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

(SC2016)


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

(SC2155)


[info] 304-304: 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 302 - 304, Split
the declaration and assignment for escaped_lang, escaped_framework, and
escaped_branch so a failing command substitution isn't masked by the local
declaration: first declare each variable with separate local statements (local
escaped_lang; local escaped_framework; local escaped_branch) and then assign
them using the existing printf | sed substitutions (escaped_lang=$(printf ...),
escaped_framework=$(printf ...), escaped_branch=$(printf ...)). This preserves
and surfaces the true exit status of the command substitutions used to produce
escaped_lang, escaped_framework, and escaped_branch.

Update constitution to reflect that the vTeam → ACP rename is complete
for docs/UI/code, but Kubernetes API group, CRDs, and container image
names must NOT be renamed without explicit instruction.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@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: 1

♻️ Duplicate comments (1)
.specify/memory/constitution.md (1)

396-397: ⚠️ Potential issue | 🟡 Minor

Populate footer metadata placeholders with actual values.

Line 396 still uses [CONSTITUTION_VERSION], [RATIFICATION_DATE], and [LAST_AMENDED_DATE], which makes the footer inconsistent with the declared changelog values in the header block.

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

In @.specify/memory/constitution.md around lines 396 - 397, Footer still
contains placeholder tokens [CONSTITUTION_VERSION], [RATIFICATION_DATE], and
[LAST_AMENDED_DATE]; replace each placeholder in the footer line with the actual
version and dates that match the header/changelog block (use the declared
Version, Ratified date and Last Amended date from the header) so the footer is
consistent with the document metadata.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.specify/memory/constitution.md:
- Line 275: Update the heading text that currently reads "Frontend Code
(NextJS)" to use the canonical framework name "Next.js"; locate the header
string "Frontend Code (NextJS)" in the constitution.md content and replace
"NextJS" with "Next.js" so the document and searchability use the standard
naming.

---

Duplicate comments:
In @.specify/memory/constitution.md:
- Around line 396-397: Footer still contains placeholder tokens
[CONSTITUTION_VERSION], [RATIFICATION_DATE], and [LAST_AMENDED_DATE]; replace
each placeholder in the footer line with the actual version and dates that match
the header/changelog block (use the declared Version, Ratified date and Last
Amended date from the header) so the footer is consistent with the document
metadata.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 55b2eaca-1ee6-4c49-b324-ffc268c048b9

📥 Commits

Reviewing files that changed from the base of the PR and between 01b2a02 and 62ab861.

📒 Files selected for processing (1)
  • .specify/memory/constitution.md

@jeremyeder jeremyeder merged commit f108a1e into main Mar 17, 2026
7 checks passed
@jeremyeder jeremyeder deleted the restore/specify-directory branch March 17, 2026 23:02
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