Skip to content

chore(repo-standard): scaffold in-progress compliance artifacts - #48

Open
owkwo-bot wants to merge 1 commit into
mainfrom
chore/repo-standard-stage-prototype
Open

owkwo-bot wants to merge 1 commit into
mainfrom
chore/repo-standard-stage-prototype

Conversation

@owkwo-bot

@owkwo-bot owkwo-bot commented Aug 19, 2026

Copy link
Copy Markdown
Collaborator

Summary by Sourcery

Scaffold the repository’s Spec Kit compliance infrastructure and end-to-end spec-driven development workflow.

New Features:

  • Add the initial Spec Kit workflow scaffold for generating feature specifications, implementation plans, and task lists.
  • Provide reusable templates for specifications, plans, tasks, constitutions, and checklists.
  • Add a full specify-to-implement workflow with review gates and integration support.

Bug Fixes:

  • Improve feature and repository context resolution, including explicit project overrides and persisted feature state.
  • Make JSON and integration metadata handling robust across environments with parser fallbacks.

Enhancements:

  • Add shared shell utilities for feature paths, template resolution and composition, command formatting, prerequisite checks, and safe JSON handling.
  • Support sequential or timestamped feature naming with dry-run, JSON output, custom names, and existing-branch options.

Documentation:

  • Add the repository constitution defining development principles, constraints, governance, and Spec Kit workflow.

Chores:

  • Add placeholder Spec Kit state, integration, and workflow registry artifacts for future compliance tooling.

Summary by cubic

Scaffolds the Spec‑Driven Development workflow and governance. Adds .specify manifests, templates, bash helpers, and a ratified constitution; updates .gitignore to allowlist only graphify-out/graph.json and graphify-out/GRAPH_REPORT.md.

  • No runtime code changed; this is repo tooling and documentation.
  • Enables /speckit.specify → /speckit.plan → /speckit.tasks → /speckit.implement via integration manifests (default copilot, speckit v0.12.18) and a bundled speckit workflow registry.
  • Adds cross‑platform bash scripts: common.sh, check-prerequisites.sh, create-new-feature.sh, setup-plan.sh, setup-tasks.sh. Scripts persist .specify/feature.json by default; use --no-persist (paths) or --paths-only to avoid writes.
  • Improves robustness: jq and python3 are optional; fallbacks (awk/grep) parse .specify/integration.json and templates. get_invoke_separator supports “.” and “-”.
  • Introduces .specify/memory/constitution.md (TDD gates, one epic in flight) and authoring templates for spec.md, plan.md, tasks.md, and checklists.
  • Migration action: If you use graphify, ensure outputs are named graphify-out/graph.json and graphify-out/GRAPH_REPORT.md; other files in graphify-out/ are ignored.
  • Reviewer focus: shell quoting and path resolution in common.sh; feature state persistence to .specify/feature.json; task template resolution in setup-tasks.sh. Test: bash .specify/scripts/bash/check-prerequisites.sh --paths-only --json.

Written for commit 48d32e8. Summary will update on new commits.

Review in cubic

Add graphify allowlist behavior-compliant .gitignore block and scaffold the required .specify tree for in-progress stage compliance.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@sourcery-ai

sourcery-ai Bot commented Aug 19, 2026

Copy link
Copy Markdown

Reviewer's Guide

This PR scaffolds Spec Kit (Speckit) compliance and workflow artifacts for the repo: shared bash utilities for feature path resolution and template lookup, commands for creating and managing feature specs/plans/tasks, default templates for core docs and governance, plus Speckit workflow and integration configuration files.

Sequence diagram for creating a new Spec Kit feature (create-new-feature.sh and common.sh)

sequenceDiagram
    actor User
    participant create_new_feature_sh as create-new-feature.sh
    participant common_sh as common.sh
    participant filesystem as Filesystem

    User->>create_new_feature_sh: invoke with feature_description
    create_new_feature_sh->>create_new_feature_sh: parse CLI args
    create_new_feature_sh->>common_sh: get_repo_root
    common_sh-->>create_new_feature_sh: REPO_ROOT
    create_new_feature_sh->>filesystem: mkdir -p specs
    create_new_feature_sh->>create_new_feature_sh: generate BRANCH_NAME
    create_new_feature_sh->>filesystem: mkdir -p specs/BRANCH_NAME
    create_new_feature_sh->>common_sh: resolve_template spec-template
    common_sh-->>create_new_feature_sh: template path
    create_new_feature_sh->>filesystem: cp spec-template -> spec.md
    create_new_feature_sh->>common_sh: _persist_feature_json REPO_ROOT FEATURE_DIR
    common_sh-->>filesystem: write .specify/feature.json
    create_new_feature_sh-->>User: BRANCH_NAME, SPEC_FILE, FEATURE_NUM
Loading

File-Level Changes

Change Details Files
Introduce shared bash utilities that standardize repo root discovery, feature directory resolution, template lookup/composition, JSON-safe output, and Speckit command formatting.
  • Added robust get_repo_root logic that prefers .specify markers and supports SPECIFY_INIT_DIR overrides for CI/non-interactive use.
  • Implemented feature path resolution helpers (get_feature_paths, read_feature_json_feature_directory, _persist_feature_json) with persistence to .specify/feature.json and safe fallbacks across jq/python3/grep-sed.
  • Added invoke separator resolution and Speckit command formatter (get_invoke_separator, format_speckit_command) with multi-parser JSON handling and caching.
  • Implemented a JSON string escape helper and small file/dir check helpers for consistent CLI output.
  • Added template resolution and composition helpers (resolve_template, resolve_template_content) that honor overrides, presets (with priority/strategy metadata), extensions, and core templates.
.specify/scripts/bash/common.sh
Add a create-new-feature CLI that generates numbered or timestamped feature branches/directories under specs/, applies naming rules, and seeds spec files from templates.
  • Implemented argument parsing with support for JSON output, dry-run mode, branch-number override, timestamp-based naming, and short-name customization.
  • Added branch name generation logic that filters stop words, preserves acronyms, enforces GitHub’s length limit, and avoids octal interpretation of numeric prefixes.
  • Created logic to scan existing specs/NNN-* directories to determine the next sequential feature number while avoiding timestamp-prefixed directories.
  • Integrated template resolution to copy spec-template into the new feature’s spec.md when available, falling back to an empty file and emitting warnings otherwise.
  • Persisted feature directory metadata to .specify/feature.json and printed shell export hints so subsequent commands can locate current feature state.
.specify/scripts/bash/create-new-feature.sh
Add consolidated prerequisite and setup scripts that validate feature documentation state, expose feature paths, and wire in tasks/plan templates for downstream Spec Kit commands.
  • Introduced check-prerequisites.sh to resolve feature paths (with optional non-persist mode), validate presence of feature directory and plan/tasks files depending on flags, and report available docs in JSON or human-readable form.
  • Added setup-tasks.sh to validate feature spec/plan presence, resolve tasks-template via the override stack, and expose template path plus available docs (JSON/text) for /speckit.tasks.
  • Added setup-plan.sh to resolve feature paths, ensure feature directory, copy plan-template if missing (with fallback to empty file), and output key paths/branch info in JSON or text formats.
.specify/scripts/bash/check-prerequisites.sh
.specify/scripts/bash/setup-tasks.sh
.specify/scripts/bash/setup-plan.sh
Seed core Spec Kit markdown templates for tasks, feature specs, implementation plans, constitutions, and checklists aligned with the repo’s spec-driven development workflow.
  • Added tasks-template.md describing phased, user-story-centric task organization, parallelizable work markers, and implementation strategy guidance for /speckit.tasks output.
  • Added spec-template.md defining prioritized, independently testable user stories, functional requirements, success criteria, edge cases, and assumptions for /speckit.specify.
  • Added plan-template.md outlining technical context, project structure patterns, complexity tracking, and documentation layout for /speckit.plan.
  • Added constitution-template.md and checklist-template.md providing generic, fill-in governance and checklist scaffolding for future specialization.
  • Created Iklo-specific constitution.md under .specify/memory to codify repo principles, constraints, workflows, and governance used by Speckit agents and scripts.
.specify/templates/tasks-template.md
.specify/templates/spec-template.md
.specify/templates/plan-template.md
.specify/templates/constitution-template.md
.specify/templates/checklist-template.md
.specify/memory/constitution.md
Configure Speckit workflows and integration metadata so the repo can run the full specify → plan → tasks → implement cycle with review gates and multiple compatible AI integrations.
  • Added a speckit workflow.yml describing the four-phase SDD workflow, input schema, integration selection (including auto mode), and review gates between spec, plan, and tasks.
  • Introduced workflow-registry.json and init-options.json placeholders to register workflows and capture initialization options for Spec Kit.
  • Added Speckit integration manifests (speckit.manifest.json, copilot.manifest.json) and integration.json to describe available integrations, defaults, and integration-specific metadata.
  • Created empty integration and init artifacts under .specify to align the repo with Spec Kit’s expected directory structure and future tooling configuration.
.specify/workflows/speckit/workflow.yml
.specify/workflows/workflow-registry.json
.specify/init-options.json
.specify/integration.json
.specify/integrations/speckit.manifest.json
.specify/integrations/copilot.manifest.json
.specify/memory/.constitution-template.json

Possibly linked issues

  • #chore: adopt repo-standard (stage=in-progress): PR implements the repo-standard .specify bootstrap and constitution artifacts requested in the in-progress adoption issue.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai

coderabbitai Bot commented Aug 19, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 17fe972c-a5c3-4734-84bd-adbf67ac7ffc


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@codacy-production

Copy link
Copy Markdown

Not up to standards ⛔

🔴 Issues 1 medium

Alerts:
⚠ 1 issue (≤ 0 issues of at least minor severity)

Results:
1 new issue

Category Results
Performance 1 medium

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hey - I've found 2 issues

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path=".specify/scripts/bash/create-new-feature.sh" line_range="211-212" />
<code_context>
+        BRANCH_NUMBER=$((HIGHEST + 1))
+    fi
+
+    # Force base-10 interpretation to prevent octal conversion (e.g., 010 → 8 in octal, but should be 10 in decimal)
+    FEATURE_NUM=$(printf "%03d" "$((10#$BRANCH_NUMBER))")
+    BRANCH_NAME="${FEATURE_NUM}-${BRANCH_SUFFIX}"
+fi
</code_context>
<issue_to_address>
**issue (bug_risk):** Branch number is not validated as numeric before arithmetic expansion, which can cause a hard failure with an opaque error if the input is malformed.

If `--number` receives a non-numeric value (e.g. `1a`), `$((10#$BRANCH_NUMBER))` will raise an arithmetic error and terminate the script under `set -e`, with only a generic bash error shown to the user. Consider validating `BRANCH_NUMBER` up front (e.g. `[[ $BRANCH_NUMBER =~ ^[0-9]+$ ]] || ...`) and emitting a clear, user-friendly message before performing the arithmetic/printf formatting.
</issue_to_address>

### Comment 2
<location path=".specify/scripts/bash/create-new-feature.sh" line_range="216-219" />
<code_context>
+    BRANCH_NAME="${FEATURE_NUM}-${BRANCH_SUFFIX}"
+fi
+
+# GitHub enforces a 244-byte limit on branch names
+# Validate and truncate if necessary
+MAX_BRANCH_LENGTH=244
+if [ ${#BRANCH_NAME} -gt $MAX_BRANCH_LENGTH ]; then
+    # Calculate how much we need to trim from suffix
+    # Account for prefix length: timestamp (15) + hyphen (1) = 16, or sequential (3) + hyphen (1) = 4
</code_context>
<issue_to_address>
**suggestion:** The branch length check uses character count, not byte count, so multi-byte UTF-8 names can exceed GitHub’s 244-byte limit while appearing within the threshold.

`${#BRANCH_NAME}` counts characters, but GitHub’s limit is in bytes. With non-ASCII characters, a branch that appears under 244 characters can still exceed 244 bytes. To enforce the GitHub limit accurately, compute the byte length (e.g. `LC_ALL=C printf '%s' "$BRANCH_NAME" | wc -c`) and base truncation on that value.

Suggested implementation:

```
# GitHub enforces a 244-byte limit on branch names
# Validate and truncate if necessary (byte-based, not character-based)
MAX_BRANCH_LENGTH=244
BRANCH_NAME_BYTES=$(LC_ALL=C printf '%s' "$BRANCH_NAME" | wc -c)
if [ "$BRANCH_NAME_BYTES" -gt "$MAX_BRANCH_LENGTH" ]; then
    # Calculate how much we need to trim from suffix (in bytes)
    # Account for prefix length: timestamp (15) + hyphen (1) = 16, or sequential (3) + hyphen (1) = 4
    # FEATURE_NUM and the hyphen are ASCII-only, so character count == byte count here
    PREFIX_LENGTH_BYTES=$(( ${#FEATURE_NUM} + 1 ))
    MAX_SUFFIX_LENGTH_BYTES=$((MAX_BRANCH_LENGTH - PREFIX_LENGTH_BYTES))

    # Truncate suffix by bytes
    TRUNCATED_SUFFIX=$(LC_ALL=C printf '%s' "$BRANCH_SUFFIX" | cut -b 1-"$MAX_SUFFIX_LENGTH_BYTES")
    # Remove trailing hyphen if truncation created one
    TRUNCATED_SUFFIX=$(echo "$TRUNCATED_SUFFIX" | sed 's/-$//')

    ORIGINAL_BRANCH_NAME="$BRANCH_NAME"
    BRANCH_NAME="${FEATURE_NUM}-${TRUNCATED_SUFFIX}"

```

If there are any other length checks on branch names elsewhere in the script or codebase, they should be updated similarly to use byte-based measurement (e.g., `LC_ALL=C printf '%s' | wc -c`) to match GitHub’s 244-byte limit and avoid issues with multi-byte UTF-8 characters.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +211 to +212
# Force base-10 interpretation to prevent octal conversion (e.g., 010 → 8 in octal, but should be 10 in decimal)
FEATURE_NUM=$(printf "%03d" "$((10#$BRANCH_NUMBER))")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

issue (bug_risk): Branch number is not validated as numeric before arithmetic expansion, which can cause a hard failure with an opaque error if the input is malformed.

If --number receives a non-numeric value (e.g. 1a), $((10#$BRANCH_NUMBER)) will raise an arithmetic error and terminate the script under set -e, with only a generic bash error shown to the user. Consider validating BRANCH_NUMBER up front (e.g. [[ $BRANCH_NUMBER =~ ^[0-9]+$ ]] || ...) and emitting a clear, user-friendly message before performing the arithmetic/printf formatting.

Comment on lines +216 to +219
# GitHub enforces a 244-byte limit on branch names
# Validate and truncate if necessary
MAX_BRANCH_LENGTH=244
if [ ${#BRANCH_NAME} -gt $MAX_BRANCH_LENGTH ]; 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.

suggestion: The branch length check uses character count, not byte count, so multi-byte UTF-8 names can exceed GitHub’s 244-byte limit while appearing within the threshold.

${#BRANCH_NAME} counts characters, but GitHub’s limit is in bytes. With non-ASCII characters, a branch that appears under 244 characters can still exceed 244 bytes. To enforce the GitHub limit accurately, compute the byte length (e.g. LC_ALL=C printf '%s' "$BRANCH_NAME" | wc -c) and base truncation on that value.

Suggested implementation:

# GitHub enforces a 244-byte limit on branch names
# Validate and truncate if necessary (byte-based, not character-based)
MAX_BRANCH_LENGTH=244
BRANCH_NAME_BYTES=$(LC_ALL=C printf '%s' "$BRANCH_NAME" | wc -c)
if [ "$BRANCH_NAME_BYTES" -gt "$MAX_BRANCH_LENGTH" ]; then
    # Calculate how much we need to trim from suffix (in bytes)
    # Account for prefix length: timestamp (15) + hyphen (1) = 16, or sequential (3) + hyphen (1) = 4
    # FEATURE_NUM and the hyphen are ASCII-only, so character count == byte count here
    PREFIX_LENGTH_BYTES=$(( ${#FEATURE_NUM} + 1 ))
    MAX_SUFFIX_LENGTH_BYTES=$((MAX_BRANCH_LENGTH - PREFIX_LENGTH_BYTES))

    # Truncate suffix by bytes
    TRUNCATED_SUFFIX=$(LC_ALL=C printf '%s' "$BRANCH_SUFFIX" | cut -b 1-"$MAX_SUFFIX_LENGTH_BYTES")
    # Remove trailing hyphen if truncation created one
    TRUNCATED_SUFFIX=$(echo "$TRUNCATED_SUFFIX" | sed 's/-$//')

    ORIGINAL_BRANCH_NAME="$BRANCH_NAME"
    BRANCH_NAME="${FEATURE_NUM}-${TRUNCATED_SUFFIX}"

If there are any other length checks on branch names elsewhere in the script or codebase, they should be updated similarly to use byte-based measurement (e.g., LC_ALL=C printf '%s' | wc -c) to match GitHub’s 244-byte limit and avoid issues with multi-byte UTF-8 characters.

@cubic-dev-ai cubic-dev-ai Bot left a comment

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.

14 issues found across 19 files

Confidence score: 3/5

  • The scaffolded constitution.md governs a different project, references nonexistent instruction/ADR files, and requires unavailable make test, which can mislead contributors and reviewers about project standards—replace it with repository-specific guidance and the actual test command.
  • setup-plan.sh silently accepts unknown options, allowing typoed commands to report success while producing unintended plans—validate and reject unsupported arguments.
  • Error handling in common.sh can mask an invalid SPECIFY_INIT_DIR, accept a feature_directory from malformed JSON, and ignore .registry priorities when Python is unavailable, leading to incorrect paths or lower-priority templates—preserve failures, validate the full document, and retain registry ordering in fallback resolution.
  • create-new-feature.sh can collide in timestamp mode and accepts invalid numbers or an empty cleaned short name, causing failed reruns or unexpected directories such as 001-—validate positive decimal inputs and use collision-resistant, nonempty names.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name=".specify/scripts/bash/setup-plan.sh">

<violation number="1" location=".specify/scripts/bash/setup-plan.sh:21">
P2: Unknown arguments are silently ignored because `ARGS` is never consumed; a typo still creates a plan and exits successfully. Reject unsupported options like `setup-tasks.sh` does.</violation>
</file>

<file name=".specify/scripts/bash/common.sh">

<violation number="1" location=".specify/scripts/bash/common.sh:122">
P2: When `feature.json` is malformed but still contains a `feature_directory` line, this fallback accepts that value after jq/Python reject the file. Return empty for parse failures or validate the entire document before using the text fallback, otherwise setup scripts can resolve paths from invalid state.</violation>

<violation number="2" location=".specify/scripts/bash/common.sh:239">
P2: When `SPECIFY_INIT_DIR` is invalid, `get_repo_root` fails but this `local` assignment masks the failure. `get_invoke_separator` and `format_speckit_command` then silently produce default output; split declaration from assignment and propagate the status in both helpers.</violation>

<violation number="3" location=".specify/scripts/bash/common.sh:446">
P2: When Python is unavailable, template resolution ignores `.registry` priorities and can select a lower-priority preset. Preserve registry ordering in the fallback instead of scanning preset directories alphabetically.</violation>
</file>

<file name=".specify/scripts/bash/create-new-feature.sh">

<violation number="1" location=".specify/scripts/bash/create-new-feature.sh:50">
P2: When callers pass a non-decimal or non-positive `--number`, the script evaluates expressions and accepts zero, creating an unexpected feature directory. Validate the value as a positive decimal integer before assigning `BRANCH_NUMBER`.</violation>

<violation number="2" location=".specify/scripts/bash/create-new-feature.sh:188">
P2: When `--short-name` contains no alphanumeric characters, this creates a feature directory named only with the numeric prefix. Reject an empty cleaned suffix instead of creating `001-`.</violation>

<violation number="3" location=".specify/scripts/bash/create-new-feature.sh:202">
P2: When timestamp-mode creation is repeated within one second for the same feature, `FEATURE_NUM` collides and the second command fails despite the help text saying to rerun for a new timestamp. Add collision-resistant precision or retry until the generated feature directory is unused.</violation>
</file>

<file name=".specify/workflows/speckit/workflow.yml">

<violation number="1" location=".specify/workflows/speckit/workflow.yml:37">
P3: The `scope` input (default "full", enum backend-only/frontend-only) is never referenced by any step, so selecting a scope has no effect on the workflow. The four command steps and both gates only read `inputs.spec` and `inputs.integration`; a user picking "frontend-only" still gets the identical full cycle. Either wire `scope` into the relevant step `args`/conditionals, or drop it from `inputs` so it doesn't present a misleading option.</violation>
</file>

<file name=".specify/templates/plan-template.md">

<violation number="1" location=".specify/templates/plan-template.md:50">
P3: The feature path placeholder is inconsistent within this file: the header reads `/specs/[###-feature-name]/spec.md` (and `[###-feature-name]` in the branch), while the Documentation tree uses `specs/[###-feature]/` and drops the leading slash. Since generated plans are filled from this template, pick one placeholder name and one path form and use it everywhere, matching `/specs/[###-feature-name]/` from the header and tasks-template.md.</violation>
</file>

<file name=".specify/memory/constitution.md">

<violation number="1" location=".specify/memory/constitution.md:1">
P2: This scaffolded constitution is content from the wrong project. The doc is titled "Iklo Constitution" and governs Iklo (a language/shell/live-image runtime, with kebab-case identifiers, sigils, and grammar rules), but this repo is `rsenna/guiltty`, a Rust terminal-graphics library (per `repo.toml` and `README.md`). The `rsenna/iklo/issues` links and "Iklo"/grammar constraints don't apply here and will mislead every reader who follows this as the governing standard. Rewrite the document to describe this repo's actual project, or place it in a template that is instantiated per-repo with the correct project name.</violation>

<violation number="2" location=".specify/memory/constitution.md:12">
P2: The constitution says a feature is not done "until `make test` is green", but this repo has no Makefile — the test command is `cargo test --workspace` (see AGENTS.md/README). Point readers at the real command so the gate is actionable.</violation>

<violation number="3" location=".specify/memory/constitution.md:42">
P2: The constitution links to instruction and ADR files that don't exist here: `.github/instructions/rust.instructions.md`, `.github/instructions/self-explanatory-code-commenting.instructions.md`, and `specs/decisions/ADR-0001-substrate-boundary.md` (`.github/instructions` is absent; `specs/decisions` is empty). Broken links in a compliance document make the referenced rules unverifiable. Either add these files in this PR or fix the links to existing references.</violation>
</file>

<file name=".specify/integrations/copilot.manifest.json">

<violation number="1" location=".specify/integrations/copilot.manifest.json:6">
P2: The copilot manifest records content hashes for 21 files (.github/agents/*.agent.md, .github/prompts/*.prompt.md, .vscode/settings.json) that are not present in the repository. A hash-based integrity/compliance ledger that references files that never get committed cannot be verified on a fresh checkout, so the scaffold is not reproducible from this PR alone. Install the copilot integration's files (or whatever produces these) in the same change, or drop the manifest entries until the files exist.</violation>
</file>

<file name=".specify/templates/tasks-template.md">

<violation number="1" location=".specify/templates/tasks-template.md:201">
P3: The "Parallel Example" fenced block is tagged ```bash but its contents ("Task: \"Contract test ...\"") are placeholder prose, not valid shell. Tagging it as bash misrepresents it as executable code; either drop the language tag or retitle it as a plain example block.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

exit 0
;;
*)
ARGS+=("$arg")

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.

P2: Unknown arguments are silently ignored because ARGS is never consumed; a typo still creates a plan and exits successfully. Reject unsupported options like setup-tasks.sh does.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .specify/scripts/bash/setup-plan.sh, line 21:

<comment>Unknown arguments are silently ignored because `ARGS` is never consumed; a typo still creates a plan and exits successfully. Reject unsupported options like `setup-tasks.sh` does.</comment>

<file context>
@@ -0,0 +1,83 @@
+            exit 0
+            ;;
+        *)
+            ARGS+=("$arg")
+            ;;
+    esac
</file context>

}

get_invoke_separator() {
local repo_root="${1:-$(get_repo_root)}"

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.

P2: When SPECIFY_INIT_DIR is invalid, get_repo_root fails but this local assignment masks the failure. get_invoke_separator and format_speckit_command then silently produce default output; split declaration from assignment and propagate the status in both helpers.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .specify/scripts/bash/common.sh, line 239:

<comment>When `SPECIFY_INIT_DIR` is invalid, `get_repo_root` fails but this `local` assignment masks the failure. `get_invoke_separator` and `format_speckit_command` then silently produce default output; split declaration from assignment and propagate the status in both helpers.</comment>

<file context>
@@ -0,0 +1,704 @@
+}
+
+get_invoke_separator() {
+    local repo_root="${1:-$(get_repo_root)}"
+    if [[ "${_SPECIFY_INVOKE_SEPARATOR_CACHE_REPO_ROOT:-}" == "$repo_root" && -n "${_SPECIFY_INVOKE_SEPARATOR_CACHE_VALUE:-}" ]]; then
+        printf '%s\n' "$_SPECIFY_INVOKE_SEPARATOR_CACHE_VALUE"
</file context>

if [[ -z "$_fd" ]]; then
# Last-resort single-line grep/sed fallback. The `|| true` guards against
# grep returning 1 (no match) aborting under `set -e` / `pipefail`.
_fd=$( { grep -E '"feature_directory"[[:space:]]*:' "$fj" 2>/dev/null || true; } \

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.

P2: When feature.json is malformed but still contains a feature_directory line, this fallback accepts that value after jq/Python reject the file. Return empty for parse failures or validate the entire document before using the text fallback, otherwise setup scripts can resolve paths from invalid state.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .specify/scripts/bash/common.sh, line 122:

<comment>When `feature.json` is malformed but still contains a `feature_directory` line, this fallback accepts that value after jq/Python reject the file. Return empty for parse failures or validate the entire document before using the text fallback, otherwise setup scripts can resolve paths from invalid state.</comment>

<file context>
@@ -0,0 +1,704 @@
+    if [[ -z "$_fd" ]]; then
+        # Last-resort single-line grep/sed fallback. The `|| true` guards against
+        # grep returning 1 (no match) aborting under `set -e` / `pipefail`.
+        _fd=$( { grep -E '"feature_directory"[[:space:]]*:' "$fj" 2>/dev/null || true; } \
+            | head -n 1 \
+            | sed -E 's/^[^:]*:[[:space:]]*"([^"]*)".*$/\1/' )
</file context>

# Generate branch name
if [ -n "$SHORT_NAME" ]; then
# Use provided short name, just clean it up
BRANCH_SUFFIX=$(clean_branch_name "$SHORT_NAME")

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.

P2: When --short-name contains no alphanumeric characters, this creates a feature directory named only with the numeric prefix. Reject an empty cleaned suffix instead of creating 001-.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .specify/scripts/bash/create-new-feature.sh, line 188:

<comment>When `--short-name` contains no alphanumeric characters, this creates a feature directory named only with the numeric prefix. Reject an empty cleaned suffix instead of creating `001-`.</comment>

<file context>
@@ -0,0 +1,301 @@
+# Generate branch name
+if [ -n "$SHORT_NAME" ]; then
+    # Use provided short name, just clean it up
+    BRANCH_SUFFIX=$(clean_branch_name "$SHORT_NAME")
+else
+    # Generate from description with smart filtering
</file context>
Suggested change
BRANCH_SUFFIX=$(clean_branch_name "$SHORT_NAME")
BRANCH_SUFFIX=$(clean_branch_name "$SHORT_NAME")
if [ -z "$BRANCH_SUFFIX" ]; then
echo 'Error: --short-name must contain at least one alphanumeric character' >&2
exit 1
fi


# Determine branch prefix
if [ "$USE_TIMESTAMP" = true ]; then
FEATURE_NUM=$(date +%Y%m%d-%H%M%S)

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.

P2: When timestamp-mode creation is repeated within one second for the same feature, FEATURE_NUM collides and the second command fails despite the help text saying to rerun for a new timestamp. Add collision-resistant precision or retry until the generated feature directory is unused.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .specify/scripts/bash/create-new-feature.sh, line 202:

<comment>When timestamp-mode creation is repeated within one second for the same feature, `FEATURE_NUM` collides and the second command fails despite the help text saying to rerun for a new timestamp. Add collision-resistant precision or retry until the generated feature directory is unused.</comment>

<file context>
@@ -0,0 +1,301 @@
+
+# Determine branch prefix
+if [ "$USE_TIMESTAMP" = true ]; then
+    FEATURE_NUM=$(date +%Y%m%d-%H%M%S)
+    BRANCH_NAME="${FEATURE_NUM}-${BRANCH_SUFFIX}"
+else
</file context>

"version": "0.12.18",
"installed_at": "2026-07-17T15:07:12.587971+00:00",
"files": {
".github/agents/speckit.analyze.agent.md": "07e1e9f997bce9e06d3823ecf1ed315bb62381b81e7d6a7aef19c5087c320e70",

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.

P2: The copilot manifest records content hashes for 21 files (.github/agents/.agent.md, .github/prompts/.prompt.md, .vscode/settings.json) that are not present in the repository. A hash-based integrity/compliance ledger that references files that never get committed cannot be verified on a fresh checkout, so the scaffold is not reproducible from this PR alone. Install the copilot integration's files (or whatever produces these) in the same change, or drop the manifest entries until the files exist.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .specify/integrations/copilot.manifest.json, line 6:

<comment>The copilot manifest records content hashes for 21 files (.github/agents/*.agent.md, .github/prompts/*.prompt.md, .vscode/settings.json) that are not present in the repository. A hash-based integrity/compliance ledger that references files that never get committed cannot be verified on a fresh checkout, so the scaffold is not reproducible from this PR alone. Install the copilot integration's files (or whatever produces these) in the same change, or drop the manifest entries until the files exist.</comment>

<file context>
@@ -0,0 +1,28 @@
+  "version": "0.12.18",
+  "installed_at": "2026-07-17T15:07:12.587971+00:00",
+  "files": {
+    ".github/agents/speckit.analyze.agent.md": "07e1e9f997bce9e06d3823ecf1ed315bb62381b81e7d6a7aef19c5087c320e70",
+    ".github/agents/speckit.clarify.agent.md": "595ae8988179a91780ce10e258afcccaa313b0924a79e720c66226e31af7ec00",
+    ".github/agents/speckit.constitution.agent.md": "e0d1d7c237d4657914dcccb6ea0c3a3a10d8d1d9a36b198282e22b3d0b9a55e5",
</file context>

# python3 succeeded but registry has no presets — nothing to search
else
# python3 failed (missing, or registry parse error) — fall back to unordered directory scan
for preset in "$presets_dir"/*/; do

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.

P2: When Python is unavailable, template resolution ignores .registry priorities and can select a lower-priority preset. Preserve registry ordering in the fallback instead of scanning preset directories alphabetically.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .specify/scripts/bash/common.sh, line 446:

<comment>When Python is unavailable, template resolution ignores `.registry` priorities and can select a lower-priority preset. Preserve registry ordering in the fallback instead of scanning preset directories alphabetically.</comment>

<file context>
@@ -0,0 +1,704 @@
+                # python3 succeeded but registry has no presets — nothing to search
+            else
+                # python3 failed (missing, or registry parse error) — fall back to unordered directory scan
+                for preset in "$presets_dir"/*/; do
+                    [ -d "$preset" ] || continue
+                    local candidate="$preset/templates/${template_name}.md"
</file context>

type: string
default: "auto"
prompt: "Integration to use (e.g. claude, copilot, gemini; 'auto' uses the project's initialized integration)"
scope:

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.

P3: The scope input (default "full", enum backend-only/frontend-only) is never referenced by any step, so selecting a scope has no effect on the workflow. The four command steps and both gates only read inputs.spec and inputs.integration; a user picking "frontend-only" still gets the identical full cycle. Either wire scope into the relevant step args/conditionals, or drop it from inputs so it doesn't present a misleading option.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .specify/workflows/speckit/workflow.yml, line 37:

<comment>The `scope` input (default "full", enum backend-only/frontend-only) is never referenced by any step, so selecting a scope has no effect on the workflow. The four command steps and both gates only read `inputs.spec` and `inputs.integration`; a user picking "frontend-only" still gets the identical full cycle. Either wire `scope` into the relevant step `args`/conditionals, or drop it from `inputs` so it doesn't present a misleading option.</comment>

<file context>
@@ -0,0 +1,77 @@
+    type: string
+    default: "auto"
+    prompt: "Integration to use (e.g. claude, copilot, gemini; 'auto' uses the project's initialized integration)"
+  scope:
+    type: string
+    default: "full"
</file context>

### Documentation (this feature)

```text
specs/[###-feature]/

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.

P3: The feature path placeholder is inconsistent within this file: the header reads /specs/[###-feature-name]/spec.md (and [###-feature-name] in the branch), while the Documentation tree uses specs/[###-feature]/ and drops the leading slash. Since generated plans are filled from this template, pick one placeholder name and one path form and use it everywhere, matching /specs/[###-feature-name]/ from the header and tasks-template.md.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .specify/templates/plan-template.md, line 50:

<comment>The feature path placeholder is inconsistent within this file: the header reads `/specs/[###-feature-name]/spec.md` (and `[###-feature-name]` in the branch), while the Documentation tree uses `specs/[###-feature]/` and drops the leading slash. Since generated plans are filled from this template, pick one placeholder name and one path form and use it everywhere, matching `/specs/[###-feature-name]/` from the header and tasks-template.md.</comment>

<file context>
@@ -0,0 +1,113 @@
+### Documentation (this feature)
+
+```text
+specs/[###-feature]/
+├── plan.md              # This file (/speckit.plan command output)
+├── research.md          # Phase 0 output (/speckit.plan command)
</file context>
Suggested change
specs/[###-feature]/
specs/[###-feature-name]/


## Parallel Example: User Story 1

```bash

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.

P3: The "Parallel Example" fenced block is tagged ```bash but its contents ("Task: "Contract test ..."") are placeholder prose, not valid shell. Tagging it as bash misrepresents it as executable code; either drop the language tag or retitle it as a plain example block.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .specify/templates/tasks-template.md, line 201:

<comment>The "Parallel Example" fenced block is tagged ```bash but its contents ("Task: \"Contract test ...\"") are placeholder prose, not valid shell. Tagging it as bash misrepresents it as executable code; either drop the language tag or retitle it as a plain example block.</comment>

<file context>
@@ -0,0 +1,252 @@
+
+## Parallel Example: User Story 1
+
+```bash
+# Launch all tests for User Story 1 together (if tests requested):
+Task: "Contract test for [endpoint] in tests/contract/test_[name].py"
</file context>
Suggested change
```bash
```text

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