Skip to content

feat: add project-type awareness and proxy metrics capabilities#79

Merged
sanmak merged 2 commits intomainfrom
feat/add-project-type-awareness-and-proxy-metrics
Mar 20, 2026
Merged

feat: add project-type awareness and proxy metrics capabilities#79
sanmak merged 2 commits intomainfrom
feat/add-project-type-awareness-and-proxy-metrics

Conversation

@sanmak
Copy link
Owner

@sanmak sanmak commented Mar 20, 2026

Summary

  • Project-type awareness: SpecOps now detects greenfield, brownfield, and migration projects — adapts init workflow with auto-init suggestions, project type classification (step 1.5), brownfield assisted steering (step 4.7), and greenfield adaptive Phase 1 (step 7.5). Adds a new migration vertical with domain vocabulary.
  • Proxy metrics: New core/metrics.md module captures token usage data (spec tokens, implementation tokens, rework ratio, etc.) during Phase 4 via step 2.5. Schema extended with optional metrics object. New docs/TOKEN-USAGE.md with benchmarks and ROI guidance.
  • Retroactive spec compliance: Older specs updated with Documentation Review sections and IssueID fields for enforcement gate consistency.

Changes

  • core/workflow.md — auto-init suggestion (step 1), greenfield adaptive Phase 1 (step 7.5), metrics capture (step 2.5 in Phase 4)
  • core/init.md — project type detection (step 1.5), brownfield assisted steering (step 4.7)
  • core/verticals.md — new migration vertical with domain vocabulary
  • core/metrics.md — new 6-step metrics capture procedure
  • core/templates/implementation.md — metrics summary placeholder
  • schema.json — migration vertical type, optional metrics object (7 integer fields)
  • spec-schema.json — metrics object schema for spec.json
  • generator/generate.py, generator/templates/*.j2 — metrics module integration
  • generator/validate.py — METRICS_MARKERS and INIT_MARKERS updates
  • platforms/*/ — regenerated outputs for all 4 platforms
  • docs/TOKEN-USAGE.md — new token usage documentation
  • docs/REFERENCE.md, docs/STRUCTURE.md, CLAUDE.md, README.md — documentation updates
  • .specops/project-type-awareness/ — full spec artifacts (requirements, design, implementation, tasks)
  • .specops/proxy-metrics/ — full spec artifacts
  • .specops/index.json, .specops/memory/ — spec registry and memory updates
  • tests/test_platform_consistency.py, tests/test_spec_schema.py — new test coverage
  • scripts/lint-spec-artifacts.py — linter updates

Test Plan

  • python3 generator/validate.py — all platform validations pass
  • shasum -a 256 -c CHECKSUMS.sha256 — all checksums verified
  • python3 generator/generate.py --all && git diff --exit-code platforms/ skills/ .claude-plugin/ — generated files fresh
  • python3 tests/check_schema_sync.py — schema structure valid
  • bash scripts/run-tests.sh — all 8 tests pass
  • Verify migration vertical appears in specops init workflow
  • Verify metrics capture triggers during Phase 4 completion
  • Verify auto-init suggestion when .specops.json is missing

Summary by CodeRabbit

  • New Features

    • Project-type detection during init (greenfield / brownfield / migration) with template pre-selection and assisted steering for brownfield
    • Proxy metrics captured at spec completion (artifact/token estimates, code-change and task counts, duration)
    • New migration vertical for re-platforming workflows
  • Documentation

    • New TOKEN-USAGE.md with metrics benchmarks and ROI guidance; updates to reference docs and templates
  • Tests

    • Added metrics and migration markers to consistency and schema tests

Greptile Summary

This PR adds two major capabilities to SpecOps — project-type awareness (greenfield/brownfield/migration detection that adapts the init and spec workflows) and proxy metrics capture (seven integer metrics written to spec.json at Phase 4 completion) — alongside a new migration vertical, retroactive spec compliance updates, and associated test coverage.

The implementation is thorough and well-integrated across all four platforms. A few issues are worth addressing:

  • Greenfield exclusion-list inconsistency (core/init.md Step 1.5 vs core/workflow.md Step 7.5): init.md correctly excludes pom.xml, build.gradle, Gemfile, composer.json, .editorconfig, .prettierrc, and .eslintrc.* from the source-file count, but workflow.md Step 7.5 omits those same files. A Java or Ruby project with only config files will be labelled Greenfield during specops init but Brownfield during a plain spec run, triggering an unnecessary codebase-exploration pass.
  • Dead YYYY-MM-DD validation branch in core/metrics.md: spec-schema.json enforces a full datetime format for created, making the date-only fallback unreachable. The documentation should match the schema.
  • Silent breaking change in lint-spec-artifacts.py: The version boundary for Documentation Review / IssueID enforcement was tightened from ≤ 1.3.0 to < 1.3.0, meaning v1.3.0-created specs are now subject to the gate. Downstream users with un-retrofitted v1.3.0 specs will see new CI failures without warning.
  • spec-schema.json metrics object lacks a required array: The workflow mandates all seven fields (defaulting failed ones to 0), but the schema accepts an empty {} object, creating a gap between intended and validated behaviour.

Confidence Score: 4/5

  • Safe to merge with minor follow-up fixes; no runtime-blocking defects, but the greenfield exclusion-list divergence should be resolved before the next release to avoid inconsistent project-type classification.
  • The core logic is sound, all platform outputs regenerated and validated, test suite expanded, and the previous review's wc -l portability fix is incorporated. The one P1 issue (greenfield exclusion-list divergence between init.md and workflow.md) causes inconsistent classification for Java/Ruby/PHP/editor-config-only repos but does not break existing workflows. The remaining P2 items are schema/documentation gaps with no runtime impact.
  • core/init.md and core/workflow.md — the greenfield source-file exclusion lists must be kept in sync; spec-schema.json — consider adding a required array inside the metrics object.

Important Files Changed

Filename Overview
core/init.md Adds Step 1.5 (project-type detection) and Step 4.7 (brownfield assisted steering); the config-only file exclusion list used for greenfield classification diverges from the equivalent list in workflow.md, risking inconsistent brownfield/greenfield detection across the two code paths.
core/metrics.md New module defining a 6-step proxy metrics capture procedure; the `wc -l
core/workflow.md Adds Step 7.5 greenfield detection, migration vertical keywords, auto-init suggestion when .specops.json is absent, and metrics capture step 2.5 in Phase 4; the greenfield exclusion list is narrower than the one in init.md.
spec-schema.json Adds the optional metrics object with seven integer fields and additionalProperties: false; no required array inside the metrics object means partially-populated or empty metrics blocks pass schema validation silently.
scripts/lint-spec-artifacts.py Version boundary for Documentation Review and IssueID gates changed from <= 1.3.0 to < 1.3.0, retroactively enforcing gates on v1.3.0 specs; downstream users with un-retrofitted v1.3.0 specs will encounter new CI failures without an upgrade notice.
generator/validate.py Adds METRICS_MARKERS constant and corresponding validation check; adds ### migration to VERTICAL_MARKERS; METRICS_MARKERS included in the cross-platform consistency loop. Changes are clean and well-structured.
schema.json Single-line change adding "migration" to the vertical enum — minimal, correct, and consistent with the new vertical definition in core/verticals.md.
core/verticals.md New migration vertical with domain vocabulary, template adaptations, and verification table entry; well-formed and consistent with existing vertical definitions.
tests/test_spec_schema.py Adds four targeted schema tests for the metrics object (full valid, backward-compat no-metrics, extra property rejection, negative value rejection); solid coverage of schema boundaries.
tests/test_platform_consistency.py Adds ### migration to vertical markers and a metrics group to REQUIRED_MARKERS; straightforward and mirrors the validate.py additions correctly.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["/specops &lt;description&gt;"] --> B{".specops.json exists?"}
    B -- No --> C["Auto-init suggestion\n(Step 1 — NEW)"]
    C -- "user chooses init" --> D["Init Mode workflow"]
    C -- "user chooses defaults" --> E["Continue with defaults"]
    B -- Yes --> E

    D --> D1["Step 1.5: Detect Project Type\n(NEW — init.md)"]
    D1 --> D2{"Count source files\n(excl. config-only)"}
    D2 -- "≤ 5 files" --> D3["Greenfield"]
    D2 -- "> 5 files" --> D4["Brownfield"]
    D2 -- "user override" --> D5["Migration"]
    D3 --> D6["Pre-select Builder template\nAdaptive Phase 1 in workflow"]
    D4 --> D7["Pre-select Standard template\nAssisted Steering — Step 4.7 NEW"]
    D5 --> D8["Standard template + migration vertical"]

    E --> F["Phase 1: Understand Context"]
    F --> G["Step 7: Detect vertical\n+ migration keywords NEW"]
    G --> H["Step 7.5: Greenfield detection\n(NEW — workflow.md)"]
    H -- "Greenfield" --> I["8g: Propose initial structure\n9g: Auto-populate steering files"]
    H -- "Brownfield/Migration" --> J["Step 8: Explore codebase\nStep 9: Identify affected files"]
    I --> K["Phase 2: Create Specification"]
    J --> K

    K --> L["Phase 4: Complete"]
    L --> M["Step 2.5: Capture Proxy Metrics\n(NEW — metrics.md)"]
    M --> M1["Collect artifact token estimate"]
    M --> M2["git diff --stat for code changes"]
    M --> M3["Count completed tasks"]
    M --> M4["Count verified AC checkboxes"]
    M --> M5["Calculate spec duration"]
    M1 & M2 & M3 & M4 & M5 --> N["Write metrics to spec.json"]
    N --> O["Step 3: Update memory"]
    O --> P["Spec completed ✓"]
Loading

Last reviewed commit: "fix: resolve PR revi..."

Greptile also left 2 inline comments on this PR.

Introduce two new features: (1) project-type detection that adapts SpecOps behavior for greenfield, brownfield, and migration projects with auto-init suggestions, assisted steering, and a new migration vertical; (2) proxy metrics module that captures token usage data during Phase 4 with schema support and TOKEN-USAGE.md documentation. Includes retroactive enforcement gate compliance for older specs.
Copilot AI review requested due to automatic review settings March 20, 2026 20:11
@coderabbitai
Copy link

coderabbitai bot commented Mar 20, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 789799fc-0790-4777-b249-98482af0d053

📥 Commits

Reviewing files that changed from the base of the PR and between 6a50443 and 71b911e.

📒 Files selected for processing (14)
  • .specops/memory/context.md
  • .specops/project-type-awareness/implementation.md
  • .specops/project-type-awareness/requirements.md
  • CHECKSUMS.sha256
  • core/init.md
  • core/metrics.md
  • core/workflow.md
  • generator/validate.py
  • platforms/claude/SKILL.md
  • platforms/codex/SKILL.md
  • platforms/copilot/specops.instructions.md
  • platforms/cursor/specops.mdc
  • skills/specops/SKILL.md
  • tests/test_platform_consistency.py

📝 Walkthrough

Walkthrough

Adds project-type awareness (greenfield/brownfield/migration) during init with adaptive workflow and assisted steering; and introduces proxy metrics capture at Phase 4 completion, storing a validated metrics object in spec.json and surfacing metrics in templates, docs, schema, and validation.

Changes

Cohort / File(s) Summary
Project-Type Awareness
.specops/project-type-awareness/*, core/init.md, core/workflow.md, core/verticals.md, core/templates/implementation.md
New spec, requirements, design, tasks, and implementation docs; added Step 1.5 project-type detection, Step 4.7 assisted steering, migration vertical, and Phase 1/Phase 4 workflow adaptations.
Proxy Metrics Feature
.specops/proxy-metrics/*, core/metrics.md, docs/TOKEN-USAGE.md, docs/REFERENCE.md, docs/STRUCTURE.md
New metrics design/requirements/implementation/tasks and core docs describing deterministic proxy metrics, capture procedure, benchmarks, and reference updates.
Schema & Tests
spec-schema.json, schema.json, tests/test_spec_schema.py, tests/test_platform_consistency.py
Added metrics schema (seven non-negative integers), expanded vertical enum with migration, and added tests/required markers for metrics and migration vertical.
Generator & Templates
generator/generate.py, generator/templates/claude.j2, .../cursor.j2, .../codex.j2, .../copilot.j2
Added metrics to shared template context and inserted {{ metrics }} into all platform templates.
Validation & Markers
generator/validate.py, tests/test_platform_consistency.py
Introduced METRICS_MARKERS, added metrics validation category and cross-platform marker enforcement.
Platform Skill Docs & Specs
platforms/*/SKILL.md, platforms/*/specops.*, skills/specops/SKILL.md
Updated platform skill/instruction docs to reflect init prompts, greenfield detection, assisted steering, migration vertical, task-tracking enforcement, and proxy metrics capture.
Specops Metadata & Memory
.specops/index.json, .specops/memory/*, .specops/memory/patterns.json
Registered project-type-awareness and proxy-metrics features; updated memory/context and pattern metadata.
Enforcement & Task Metadata
.specops/*/tasks.md, .specops/*/implementation.md
Retroactive Documentation Review entries and IssueID: FAILED — created before task tracking enforcement added across several spec journals/tasks.
Tooling & Docs Sync
scripts/lint-spec-artifacts.py, .claude/commands/docs-sync.md, CLAUDE.md, README.md, CHECKSUMS.sha256
Adjusted lint gating for version 1.3.0, updated docs-sync mapping to include core/metrics.md, README/TOKEN-USAGE link, and updated checksums.

Sequence Diagram

sequenceDiagram
    participant User
    participant Init
    participant Repo
    participant Steering
    participant Workflow
    participant Metrics
    participant SpecJSON

    User->>Init: Run /specops init (no .specops.json)
    Init->>Repo: Scan files (git ls-files / fallback)
    Repo-->>Init: file list, manifests, README
    alt Greenfield (≤5)
        Init->>User: Prompt confirm Greenfield
        Init->>Steering: Propose initial structure
    else Brownfield
        Init->>Steering: Extract content from README/manifests
        Steering-->>Init: Populated steering artifacts
        Init->>User: Notify review of steering/
    else Migration (override)
        Init->>Workflow: Set vertical = "migration"
    end

    User->>Workflow: Create/complete spec (Phase 1→4)
    Workflow->>Metrics: Phase 4 step 2.5 — run metrics capture
    Metrics->>Repo: Run git diff/stat and read artifacts
    Repo-->>Metrics: filesChanged, linesAdded/Removed
    Metrics->>Metrics: compute token estimate, task counts, duration
    Metrics->>SpecJSON: write/update `metrics` object
    SpecJSON-->>User: Spec completed with metrics
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

Poem

🐰
I hopped through README, files, and trees,
Counting sources with a twitchy breeze,
I poked at metrics, neat and spry—
Tokens, diffs, and minutes fly!
A little hop for SpecOps cheer.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% 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 PR title accurately summarizes the two main feature additions: project-type awareness and proxy metrics capabilities.
Description check ✅ Passed PR description is comprehensive and well-structured, covering all major changes, test plan results, and known issues.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/add-project-type-awareness-and-proxy-metrics

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

Copy link

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

🧹 Nitpick comments (2)
docs/TOKEN-USAGE.md (1)

51-53: Clarify zero-task handling in ratio formulas.

Line 51 can become undefined when tasksCompleted = 0. Add a guard rule (e.g., “if zero, report N/A”) so dashboards/calculations are consistent.

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

In `@docs/TOKEN-USAGE.md` around lines 51 - 53, The "Lines of code per task"
metric formula can divide by zero when tasksCompleted == 0; update the
calculation for "Lines of code per task" to explicitly guard against zero (e.g.,
if tasksCompleted === 0 return "N/A" or null) so dashboards and downstream
calculations remain consistent; also consider adding a similar guard for
"Acceptance criteria hit rate" when total_criteria == 0 to return "N/A" to avoid
undefined results.
platforms/cursor/specops.mdc (1)

3624-3625: Task completion metric can undercount due to case-sensitive matching.

Counting only **Status:** Completed misses lowercase/variant forms already tolerated elsewhere. Normalize or use case-insensitive matching for consistency.

Suggested text fix
-  - From the `tasks.md` content already loaded in step 1, count occurrences of `**Status:** Completed` (case-sensitive match)
+  - From the `tasks.md` content already loaded in step 1, count occurrences of completed status case-insensitively (`**Status:** Completed` / `**Status:** completed`)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@platforms/cursor/specops.mdc` around lines 3624 - 3625, The current counting
logic for tasksCompleted only matches the exact case `**Status:** Completed`,
which undercounts variants; update the step that counts occurrences (the code
that reads tasks.md in step 1 and computes tasksCompleted) to perform a
case-insensitive match (e.g., normalize the loaded tasks.md text to a single
case or use a case-insensitive regex) so that `**status:** completed` and other
case variants are included; ensure the stored variable name remains
tasksCompleted and that the matching still targets the `**Status:**` label
pattern to avoid false positives.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.specops/memory/context.md:
- Around line 41-45: Update the two future-dated headings in
.specops/memory/context.md so the timestamps match actual completion time:
change "project-type-awareness (feature) — 2026-03-21" and "proxy-metrics
(feature) — 2026-03-21" to "— 2026-03-20" (or the correct actual date). Ensure
any other occurrences of those exact heading strings or the same date in the
file are updated consistently to preserve chronological ordering and test
expectations.

In @.specops/project-type-awareness/implementation.md:
- Around line 28-31: The checklist line referencing `docs/REFERENCE.md` is
inconsistent with the journal that shows all tasks complete; update the
`docs/REFERENCE.md` entry in .specops/project-type-awareness/implementation.md
to either (a) mark it as completed (e.g., change "needs vertical enum update" to
"checked, vertical enum updated") or (b) explicitly record a follow-up/deviation
note (e.g., "deviation: pending enum migration, follow-up required") so the
document and journal agree; edit the `docs/REFERENCE.md` line accordingly and
ensure the wording matches the other entries' style.

In @.specops/project-type-awareness/requirements.md:
- Around line 4-5: The repo uses two inconsistent terms for the same project
type ("bluefield" vs "migration"); pick one (suggest "migration") and update all
references across requirements, implementation, tests, docs, constants, enums
and UI/CLI labels to that single term; specifically rename any ProjectType enum
entries, variables, function names (e.g., detectProjectType, projectType-aware
logic), config keys and docs that mention "bluefield" to "migration", and add
code-level backward-compatibility mapping or aliasing so inputs/flags/env vars
still accept "bluefield" and translate them to "migration" to avoid breaking
consumers.

In @.specops/project-type-awareness/tasks.md:
- Line 208: Update the stale acceptance-criteria checklist item that currently
reads "`bash scripts/run-tests.sh` reports all tests pass (7/7 pass, lint fail
is checkbox staleness — fixed)" to reflect the final result: change "7/7 pass"
to "8/8 pass" (keeping the rest of the text unchanged) so the artifact aligns
with the PR summary.

In @.specops/proxy-metrics/design.md:
- Around line 46-55: The fenced diagram block in
.specops/proxy-metrics/design.md is missing a language tag; update the opening
triple-backtick for the block that starts with "Phase 4 step 1 (verify criteria)
→ step 2 (finalize impl.md)" to include a language identifier (for example
change "```" to "```text") so the fenced block is typed and satisfies markdown
linting rules.

In @.specops/proxy-metrics/implementation.md:
- Around line 37-38: The completion timestamp in the header "### Session 1 — All
tasks completed (2026-03-21)" is future-dated; update that header in
.specops/proxy-metrics/implementation.md (the "Session 1 — All tasks completed"
line) to the correct current date (2026-03-20) or use a
deterministic/source-controlled timestamp format (e.g., run-date) to avoid
future dates being committed.

In `@core/init.md`:
- Around line 33-35: The classification rules currently only set "Brownfield"
when both source code file count > 5 and dependency manifests/docs exist,
leaving repos with >5 source files but no manifests undefined; update the
classification logic that determines project type so that if sourceFileCount > 5
it falls back to "Brownfield" (unless the user explicitly sets "Migration"),
while keeping "Greenfield" for ≤5 files and "Migration" only when explicitly
overridden; modify the function that computes the project type (the code that
checks "Greenfield", "Brownfield", "Migration" and the source file count /
manifests flags) to add this fallback branch and update any tests or docs
referencing the rules.

In `@core/workflow.md`:
- Around line 19-22: The workflow's ASK_USER branch lacks a non-interactive
fallback: when reading `.specops.json` and ASK_USER would prompt but
canAskInteractive is false, deterministically proceed with defaults and call
NOTIFY_USER (or equivalent) to inform the user that defaults were used and
recommend running `/specops init` later; update the decision logic around
ASK_USER and canAskInteractive to route to the defaults path + NOTIFY_USER
instead of blocking, and ensure the Init Mode redirection remains unchanged when
interactive prompts are allowed.

In `@generator/validate.py`:
- Around line 247-258: The comment above METRICS_MARKERS is stale/misplaced;
update the comment to correctly describe METRICS_MARKERS (e.g., "Proxy metrics
markers that MUST appear in every output") and move the existing "Feedback mode
markers..." comment so it precedes FEEDBACK_MARKERS, ensuring the comments now
match the constants METRICS_MARKERS and FEEDBACK_MARKERS respectively in
generator/validate.py.

In `@platforms/claude/SKILL.md`:
- Around line 3959-3960: The current count for tasksCompleted only matches the
exact string "**Status:** Completed"; update the logic that scans the loaded
tasks.md content to use a case-insensitive regex for the Status field and
normalize values before counting (e.g. match
/status:\s*(completed|complete|done)/i or similar) so that legacy/lowercase
variants are included; adjust the code that assigns tasksCompleted to increment
when the normalized status is one of the accepted completion tokens.
- Around line 3953-3954: The two git command usages that interpolate "<created>"
into shell strings (the `git log --oneline --after="<created>" -- . | wc -l` and
`git diff --stat HEAD~$(git log --oneline --after="<created>" -- . | wc -l) ...`
lines) must treat spec.json.created as untrusted input: stop performing direct
shell interpolation and instead pass the timestamp as a safe argument or escape
it properly. Modify the code that builds these commands to either (a) call git
with argument arrays (e.g., spawn/execFile) supplying the --after value as a
separate arg, or (b) robustly escape/validate the created value (allow only
ISO8601/timestamp chars) before injecting into the command; update the
documentation lines referencing those git commands to reflect the safer
invocation approach so the created value is never directly embedded into a shell
string.
- Around line 67-68: The greenfield detection currently only lists files at the
project root which misses nested source files; update both detection flows that
use the Glob tool to perform a recursive search (e.g., use a '**/*' pattern or
enable recursive mode) and then filter out excluded directories and config-only
filenames regardless of nesting. Ensure the file-counting step for "source code
files" applies to matched paths (filter by extensions or exclude config
filenames like LICENSE/README/package.json/etc. and directories .git/,
node_modules/, .venv/, vendor/, __pycache__, .specops/) so repositories with
code under subfolders (src/, app/, etc.) are correctly detected as
non-greenfield. Also adjust the two referenced flows (the one around the
project-root listing and the duplicate at 2434-2442) to use the same recursive
glob/filter logic.

In `@platforms/copilot/specops.instructions.md`:
- Around line 65-67: The greenfield detection logic in specops.instructions.md
currently counts only files at project root and may misclassify repos with code
in subdirectories; update the rule (the "List the contents..." / "If source code
file count ≤ 5..." lines) to recursively search common source directories (e.g.,
src/, app/, packages/, lib/, backend/, frontend/) and count source files across
the repo (still excluding .specops/, .git/, node_modules/, __pycache__/, .venv/,
vendor/ and config-only filenames), and change the conditional that skips steps
8-9 so it only triggers when the total recursive source-file count ≤ 5; ensure
the wording explicitly instructs treating repos with files under those common
dirs as brownfield so steps 8-9 are not skipped.

In `@skills/specops/SKILL.md`:
- Around line 3953-3956: Replace the current commit-count based diff logic that
runs `git diff --stat HEAD~N` (derived from `git log --oneline
--after="<created>" | wc -l`) with a time-window based query using `git log
--since="<created>" --numstat` and parse its output to compute filesChanged,
linesAdded and linesRemoved; ensure the code path that previously used the `git
diff --stat HEAD~N` command and any fallback that sets metrics to 0 is removed
or bypassed, handle an empty `--numstat` output by setting metrics to 0 and
emitting the existing message ("Could not compute git diff stats — metrics will
show 0 for code changes."), and make sure shallow-clone or zero-commit cases no
longer attempt `HEAD~N` so you avoid fatal revisions.

---

Nitpick comments:
In `@docs/TOKEN-USAGE.md`:
- Around line 51-53: The "Lines of code per task" metric formula can divide by
zero when tasksCompleted == 0; update the calculation for "Lines of code per
task" to explicitly guard against zero (e.g., if tasksCompleted === 0 return
"N/A" or null) so dashboards and downstream calculations remain consistent; also
consider adding a similar guard for "Acceptance criteria hit rate" when
total_criteria == 0 to return "N/A" to avoid undefined results.

In `@platforms/cursor/specops.mdc`:
- Around line 3624-3625: The current counting logic for tasksCompleted only
matches the exact case `**Status:** Completed`, which undercounts variants;
update the step that counts occurrences (the code that reads tasks.md in step 1
and computes tasksCompleted) to perform a case-insensitive match (e.g.,
normalize the loaded tasks.md text to a single case or use a case-insensitive
regex) so that `**status:** completed` and other case variants are included;
ensure the stored variable name remains tasksCompleted and that the matching
still targets the `**Status:**` label pattern to avoid false positives.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: afde8142-eca5-4e0e-a720-cd46a2b7becc

📥 Commits

Reviewing files that changed from the base of the PR and between 73833d0 and 6a50443.

📒 Files selected for processing (50)
  • .claude/commands/docs-sync.md
  • .specops/index.json
  • .specops/install-integrity-verification/implementation.md
  • .specops/install-integrity-verification/tasks.md
  • .specops/memory/context.md
  • .specops/memory/patterns.json
  • .specops/project-type-awareness/design.md
  • .specops/project-type-awareness/implementation.md
  • .specops/project-type-awareness/requirements.md
  • .specops/project-type-awareness/spec.json
  • .specops/project-type-awareness/tasks.md
  • .specops/proxy-metrics/design.md
  • .specops/proxy-metrics/implementation.md
  • .specops/proxy-metrics/requirements.md
  • .specops/proxy-metrics/spec.json
  • .specops/proxy-metrics/tasks.md
  • .specops/steering/product.md
  • .specops/task-delegation/implementation.md
  • .specops/task-delegation/tasks.md
  • .specops/workflow-enforcement-gates/implementation.md
  • .specops/workflow-enforcement-gates/tasks.md
  • .specops/writing-quality-rules/implementation.md
  • .specops/writing-quality-rules/tasks.md
  • CHECKSUMS.sha256
  • CLAUDE.md
  • README.md
  • core/init.md
  • core/metrics.md
  • core/templates/implementation.md
  • core/verticals.md
  • core/workflow.md
  • docs/REFERENCE.md
  • docs/STRUCTURE.md
  • docs/TOKEN-USAGE.md
  • generator/generate.py
  • generator/templates/claude.j2
  • generator/templates/codex.j2
  • generator/templates/copilot.j2
  • generator/templates/cursor.j2
  • generator/validate.py
  • platforms/claude/SKILL.md
  • platforms/codex/SKILL.md
  • platforms/copilot/specops.instructions.md
  • platforms/cursor/specops.mdc
  • schema.json
  • scripts/lint-spec-artifacts.py
  • skills/specops/SKILL.md
  • spec-schema.json
  • tests/test_platform_consistency.py
  • tests/test_spec_schema.py

Comment on lines +41 to +45
### project-type-awareness (feature) — 2026-03-21
6 tasks completed, 0 deviations from design, 0 blockers. Made SpecOps project-type-aware across greenfield, brownfield, and bluefield projects: (1) migration vertical in `core/verticals.md` with domain vocabulary (Migration Requirements, Migration Architecture, Cutover Plan, Coexistence Strategy) + schema/validator/test updates, (2) auto-init suggestion in `core/workflow.md` step 1 when `.specops.json` missing, (3) project type detection in `core/init.md` step 1.5 (auto-classifies greenfield/brownfield, migration override), (4) brownfield assisted steering in `core/init.md` step 4.7 (auto-populates from README/deps), (5) greenfield adaptive Phase 1 in `core/workflow.md` step 7.5 (replaces hollow codebase exploration with structure proposal and steering auto-population). All 8 tests pass.

### proxy-metrics (feature) — 2026-03-21
8 tasks completed, 0 deviations from design, 0 blockers. New `core/metrics.md` module with 6-step metrics capture procedure using abstract operations. Integrated into Phase 4 as step 2.5 (sub-step notation per project convention — no renumbering). Generator pipeline wired for all 4 platforms with 8 METRICS_MARKERS. Schema extended with optional `metrics` object (7 integer fields). Documentation: `docs/TOKEN-USAGE.md` with benchmarks and ROI guidance, updates to REFERENCE.md, README.md, STRUCTURE.md, CLAUDE.md. All 8 tests pass.
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Avoid future-dated memory entries.

These entries are stamped 2026-03-21, which is ahead of March 20, 2026. Please align dates with actual completion time for reliable project memory chronology.

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

In @.specops/memory/context.md around lines 41 - 45, Update the two future-dated
headings in .specops/memory/context.md so the timestamps match actual completion
time: change "project-type-awareness (feature) — 2026-03-21" and "proxy-metrics
(feature) — 2026-03-21" to "— 2026-03-20" (or the correct actual date). Ensure
any other occurrences of those exact heading strings or the same date in the
file are updated consistently to preserve chronological ordering and test
expectations.

Comment on lines +4 to +5
SpecOps currently assumes a brownfield (existing codebase) context for every project. Phase 1 steps 8-9 are hollow on empty repos, init creates empty steering files regardless of existing docs, and there is no vertical for migration/re-platforming. This feature makes SpecOps project-type-aware across greenfield, brownfield, and bluefield projects with five targeted changes.

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Unify project-type terminology (bluefield vs migration).

Line 4 introduces “bluefield projects,” while requirements and implementation use “migration.” Pick one term to avoid ambiguity in workflow/spec behavior.

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

In @.specops/project-type-awareness/requirements.md around lines 4 - 5, The repo
uses two inconsistent terms for the same project type ("bluefield" vs
"migration"); pick one (suggest "migration") and update all references across
requirements, implementation, tests, docs, constants, enums and UI/CLI labels to
that single term; specifically rename any ProjectType enum entries, variables,
function names (e.g., detectProjectType, projectType-aware logic), config keys
and docs that mention "bluefield" to "migration", and add code-level
backward-compatibility mapping or aliasing so inputs/flags/env vars still accept
"bluefield" and translate them to "migration" to avoid breaking consumers.

**Acceptance Criteria:**
- [x] `python3 generator/generate.py --all` succeeds
- [x] `python3 generator/validate.py` reports 0 errors
- [x] `bash scripts/run-tests.sh` reports all tests pass (7/7 pass, lint fail is checkbox staleness — fixed)
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Update stale test-count evidence in acceptance criteria.

This line says 7/7 pass, but the PR summary reports all 8 tests passing. Keep the task artifact aligned with the final validation result.

Suggested text fix
-- [x] `bash scripts/run-tests.sh` reports all tests pass (7/7 pass, lint fail is checkbox staleness — fixed)
+- [x] `bash scripts/run-tests.sh` reports all tests pass (8/8 pass)
📝 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
- [x] `bash scripts/run-tests.sh` reports all tests pass (7/7 pass, lint fail is checkbox staleness — fixed)
- [x] `bash scripts/run-tests.sh` reports all tests pass (8/8 pass)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.specops/project-type-awareness/tasks.md at line 208, Update the stale
acceptance-criteria checklist item that currently reads "`bash
scripts/run-tests.sh` reports all tests pass (7/7 pass, lint fail is checkbox
staleness — fixed)" to reflect the final result: change "7/7 pass" to "8/8 pass"
(keeping the rest of the text unchanged) so the artifact aligns with the PR
summary.

Comment on lines +46 to +55
```
Phase 4 step 1 (verify criteria) → step 2 (finalize impl.md)
→ step 2.5 (capture metrics):
READ_FILE spec artifacts → count chars → specArtifactTokensEstimate
RUN_COMMAND git diff --stat → filesChanged, linesAdded, linesRemoved
Parse tasks.md → tasksCompleted, acceptanceCriteriaVerified
Compute timestamps → specDurationMinutes
EDIT_FILE spec.json → add metrics object
→ step 3 (memory update) → step 4 (docs check) → step 5 (completion gate)
```
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add a language identifier to the fenced block.

The diagram fence is untyped; add a language tag (e.g., text) to satisfy markdown linting and keep docs clean.

🧰 Tools
🪛 markdownlint-cli2 (0.21.0)

[warning] 46-46: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

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

In @.specops/proxy-metrics/design.md around lines 46 - 55, The fenced diagram
block in .specops/proxy-metrics/design.md is missing a language tag; update the
opening triple-backtick for the block that starts with "Phase 4 step 1 (verify
criteria) → step 2 (finalize impl.md)" to include a language identifier (for
example change "```" to "```text") so the fenced block is typed and satisfies
markdown linting rules.

Comment on lines +3959 to +3960
- From the `tasks.md` content already loaded in step 1, count occurrences of `**Status:** Completed` (case-sensitive match)
- Store as `tasksCompleted`
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Task completion counting is overly strict.

Counting only exact **Status:** Completed can undercount legacy/lowercase statuses and skew metrics.

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

In `@platforms/claude/SKILL.md` around lines 3959 - 3960, The current count for
tasksCompleted only matches the exact string "**Status:** Completed"; update the
logic that scans the loaded tasks.md content to use a case-insensitive regex for
the Status field and normalize values before counting (e.g. match
/status:\s*(completed|complete|done)/i or similar) so that legacy/lowercase
variants are included; adjust the code that assigns tasksCompleted to increment
when the normalized status is one of the accepted completion tokens.

Comment on lines +3953 to +3956
- Use the Bash tool to run(`git log --oneline --after="<created>" -- . | wc -l`) to check for commits in the spec timeframe
- Use the Bash tool to run(`git diff --stat HEAD~$(git log --oneline --after="<created>" -- . | wc -l) 2>/dev/null || echo "0 files changed"`) to get the diff summary
- Parse the summary line for `filesChanged`, `linesAdded`, `linesRemoved`
- If the git command fails or returns no output, set all three values to 0 and Display a message to the user("Could not compute git diff stats — metrics will show 0 for code changes.")
Copy link

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:

#!/bin/bash
# Verify where the current algorithm can miscount metrics.
# 1) Show commit count since each spec's created timestamp.
# 2) Show the current HEAD~N diff-stat result.
# 3) Show a safer comparison using git log --numstat over the same window.

set -euo pipefail

fd -p "spec.json" .specops | while read -r specjson; do
  created="$(jq -r '.created // empty' "$specjson")"
  [ -z "$created" ] && continue

  echo "=== $specjson ==="
  n="$(git log --oneline --after="$created" -- . | wc -l | tr -d ' ')"
  echo "commits_since_created=$n"

  echo "-- current_method --"
  git diff --stat "HEAD~$n" 2>/dev/null || echo "current_method_failed"

  echo "-- safer_window_numstat --"
  git log --since="$created" --numstat --pretty=tformat: -- . 2>/dev/null \
    | awk 'NF==3 {files+=1; add+=$1; del+=$2} END {print "files="files", added="add", removed="del"}'
  echo
done

Repository: sanmak/specops

Length of output: 449


🏁 Script executed:

cat -n skills/specops/SKILL.md | sed -n '3950,3960p'

Repository: sanmak/specops

Length of output: 1015


🏁 Script executed:

#!/bin/bash
# Fixed verification script with corrected awk syntax
set -euo pipefail

if [ -d ".specops" ]; then
  fd -p "spec.json" .specops | head -3 | while read -r specjson; do
    created="$(jq -r '.created // empty' "$specjson")"
    [ -z "$created" ] && continue

    echo "=== $specjson ==="
    n="$(git log --oneline --after="$created" -- . | wc -l)"
    echo "commits_since_created=$n"

    echo "-- Testing git diff --stat HEAD~$n --"
    if [ "$n" -gt 0 ]; then
      git diff --stat "HEAD~$n" -- . 2>&1 || echo "FAILED: git diff --stat HEAD~$n"
    else
      echo "N=0 case - using HEAD"
      git diff --stat HEAD -- . 2>&1 || echo "FAILED: git diff --stat HEAD"
    fi

    echo "-- git log numstat window --"
    git log --since="$created" --numstat --pretty=format: -- . 2>/dev/null | awk 'NF {files++; add+=$1; del+=$2} END {print "files=" files ", added=" add ", removed=" del}' || echo "numstat failed"
    echo
  done
else
  echo ".specops directory not found"
fi

Repository: sanmak/specops

Length of output: 755


🏁 Script executed:

# Search for actual implementation of the git diff algorithm in the codebase
rg "git diff --stat" -A 5 -B 5 --type md --type sh

Repository: sanmak/specops

Length of output: 20719


🏁 Script executed:

# Check if there's a Bash script that implements the metrics collection logic
fd -e sh | head -20 | xargs rg "filesChanged|linesAdded|linesRemoved" -l

Repository: sanmak/specops

Length of output: 42


git diff --stat HEAD~N is unreliable for proxy metrics—use time-based window instead.

The algorithm computes N from git log --oneline --after="<created>" then runs git diff --stat HEAD~N. This fails in practice:

  1. N=0 case: When no commits exist after the timestamp, HEAD~0 is invalid
  2. Insufficient history: In shallow clones or repositories with fewer commits than N, the command fails fatally
  3. Non-deterministic metrics: The fallback sets all metrics to 0, providing no actual insight

Verification confirms: git diff --stat HEAD~1 fails across multiple specs with fatal: bad revision 'HEAD~1'. A safer approach uses git log --since="<created>" --numstat to directly query the time window, which reliably calculates files changed, lines added, and lines removed without depending on commit count.

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

In `@skills/specops/SKILL.md` around lines 3953 - 3956, Replace the current
commit-count based diff logic that runs `git diff --stat HEAD~N` (derived from
`git log --oneline --after="<created>" | wc -l`) with a time-window based query
using `git log --since="<created>" --numstat` and parse its output to compute
filesChanged, linesAdded and linesRemoved; ensure the code path that previously
used the `git diff --stat HEAD~N` command and any fallback that sets metrics to
0 is removed or bypassed, handle an empty `--numstat` output by setting metrics
to 0 and emitting the existing message ("Could not compute git diff stats —
metrics will show 0 for code changes."), and make sure shallow-clone or
zero-commit cases no longer attempt `HEAD~N` so you avoid fatal revisions.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR extends SpecOps’ core workflow and generated platform instruction sets to (1) adapt behavior based on detected project type (greenfield/brownfield/migration) and (2) capture proxy “token usage” / productivity metrics at spec completion, with accompanying schema + documentation updates.

Changes:

  • Add a new migration vertical across workflow/verticals docs, config schema, generator validation, and platform consistency tests.
  • Introduce a new core/metrics.md module and wire it into the generator/templates + validation; extend spec-schema.json with an optional metrics object.
  • Update init/workflow instructions to detect project type and adjust Phase 1 behavior (greenfield) and steering population (brownfield), plus retroactive spec artifact compliance updates.

Reviewed changes

Copilot reviewed 50 out of 50 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
tests/test_spec_schema.py Adds schema validation tests for the new optional metrics object.
tests/test_platform_consistency.py Adds required markers for migration and Proxy Metrics presence across platforms.
spec-schema.json Extends spec.json schema with optional metrics object (7 integer fields).
skills/specops/SKILL.md Updates the generated/general SpecOps skill output with project-type and metrics workflow additions.
scripts/lint-spec-artifacts.py Adjusts enforcement version boundary logic for legacy-spec skipping.
schema.json Adds migration to the .specops.json config vertical enum.
platforms/cursor/specops.mdc Regenerated Cursor output including migration + project type + metrics content.
platforms/copilot/specops.instructions.md Regenerated Copilot output including migration + project type + metrics content.
platforms/codex/SKILL.md Regenerated Codex output including migration + project type + metrics content.
platforms/claude/SKILL.md Regenerated Claude output including migration + project type + metrics content.
generator/validate.py Adds new required markers for migration and Proxy Metrics and validates their presence.
generator/templates/cursor.j2 Wires the metrics module into generated Cursor output.
generator/templates/copilot.j2 Wires the metrics module into generated Copilot output.
generator/templates/codex.j2 Wires the metrics module into generated Codex output.
generator/templates/claude.j2 Wires the metrics module into generated Claude output.
generator/generate.py Adds metrics to the common render context so templates can include it.
docs/TOKEN-USAGE.md New documentation describing proxy metrics, benchmarks, and ROI guidance.
docs/STRUCTURE.md Documents the new core/metrics.md module in the repository structure.
docs/REFERENCE.md Documents the metrics object fields and adds migration to the vertical enum list.
core/workflow.md Adds auto-init suggestion, greenfield detection (step 7.5), migration keywords, and metrics capture (Phase 4 step 2.5).
core/verticals.md Adds migration vertical adaptation rules and vocabulary verification entry.
core/templates/implementation.md Adds Project state placeholder to Phase 1 context summary.
core/metrics.md New module defining the Proxy Metrics capture procedure and safety notes.
core/init.md Adds project type detection (step 1.5), migration vertical suggestion, and brownfield assisted steering (step 4.7).
README.md Adds a top-level section pointing to proxy metrics documentation.
CLAUDE.md Updates developer docs to include metrics module and task tracking linter scope.
CHECKSUMS.sha256 Regenerates checksums for updated generated/artifact files.
.specops/writing-quality-rules/tasks.md Retroactively updates IssueID fields for task-tracking enforcement consistency.
.specops/writing-quality-rules/implementation.md Retroactively adds Documentation Review section.
.specops/workflow-enforcement-gates/tasks.md Retroactively updates IssueID fields for task-tracking enforcement consistency.
.specops/workflow-enforcement-gates/implementation.md Retroactively adds Documentation Review section.
.specops/task-delegation/tasks.md Retroactively adds IssueID fields for task-tracking enforcement consistency.
.specops/task-delegation/implementation.md Retroactively adds Documentation Review section.
.specops/steering/product.md Updates the product steering doc to reflect 7 verticals including migration.
.specops/proxy-metrics/tasks.md Adds the full spec artifact tasks for proxy metrics work.
.specops/proxy-metrics/spec.json Adds the proxy-metrics spec metadata.
.specops/proxy-metrics/requirements.md Adds proxy metrics requirements (feature spec).
.specops/proxy-metrics/implementation.md Adds completion journal and documentation review record for proxy metrics.
.specops/proxy-metrics/design.md Adds design rationale and integration plan for proxy metrics.
.specops/project-type-awareness/tasks.md Adds the full spec artifact tasks for project type awareness work.
.specops/project-type-awareness/spec.json Adds the project-type-awareness spec metadata.
.specops/project-type-awareness/requirements.md Adds requirements for project-type-aware workflow (note: contains “bluefield” terminology).
.specops/project-type-awareness/implementation.md Adds completion journal and documentation review record for project type awareness.
.specops/project-type-awareness/design.md Adds design rationale for project type detection and migration vertical approach.
.specops/memory/patterns.json Updates repository memory patterns counts/spec lists to include the new specs.
.specops/memory/context.md Adds completed-spec summaries for new features (note: contains “bluefield” terminology).
.specops/install-integrity-verification/tasks.md Retroactively adds IssueID fields for task-tracking enforcement consistency.
.specops/install-integrity-verification/implementation.md Retroactively adds Documentation Review section.
.specops/index.json Registers the new completed specs in the spec index.
.claude/commands/docs-sync.md Adds docs-sync mapping for the new core/metrics.md module.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +165 to 172
# Parse version — skip if < 1.3.0 (gate introduced at 1.3.0)
try:
parts = [int(x) for x in created_with.split(".")]
if len(parts) == 3 and (
parts[0] < 1
or (parts[0] == 1 and parts[1] < 3)
or (parts[0] == 1 and parts[1] == 3 and parts[2] == 0)
):
continue
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

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

The skip logic was changed to enforce the docs review gate starting at version 1.3.0, but the function’s docstring above still describes skipping specs with specopsCreatedWith <= 1.3.0 (and says 1.3.0 specs predate enforcement). Update the docstring/comments to match the new < 1.3.0 behavior so future readers don’t misinterpret the gate boundary.

Copilot uses AI. Check for mistakes.
Comment on lines +179 to +188
"metrics": [
"## Proxy Metrics",
"### Metrics Capture Procedure",
"### Metrics Safety",
"specArtifactTokensEstimate",
"filesChanged",
"linesAdded",
"tasksCompleted",
"acceptanceCriteriaVerified",
],
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

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

The platform consistency markers for the Proxy Metrics section don’t include all metrics fields (notably linesRemoved and specDurationMinutes), even though these are part of the metrics schema and described in the metrics module. Add the missing markers so the consistency test ensures all platforms include the full metrics definition.

Copilot uses AI. Check for mistakes.
Comment on lines +59 to +62
7.5. **Greenfield detection**: Determine if this is a greenfield project:
- LIST_DIR(`.`) the project root. Count source code files (exclude `.specops/`, `.git/`, `node_modules/`, `__pycache__/`, `.venv/`, `vendor/`). Config-only files (`.gitignore`, `LICENSE`, `README.md`, `package.json`, `pyproject.toml`, `Cargo.toml`, `go.mod`, `tsconfig.json`, `Makefile`, `Dockerfile`) do not count as source code files.
- If source code file count ≤ 5 (only config/scaffold files present), this is a greenfield project.
- If greenfield is detected, skip steps 8-9 and instead execute:
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

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

Greenfield detection relies on LIST_DIR('.') to count source code files, but LIST_DIR is defined as listing directory contents and (as written here) doesn’t specify recursion. This can misclassify typical repos where code lives under src/ (few root files) as greenfield and incorrectly skip steps 8–9. Make the scan explicitly recursive (or prefer RUN_COMMAND(git ls-files ...) when canAccessGit is true, with a LIST_DIR recursive fallback) so the heuristic counts repo-wide source files.

Copilot uses AI. Check for mistakes.
Copy link
Owner Author

Choose a reason for hiding this comment

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

Fixed in 71b911e.

core/init.md Outdated
Comment on lines +27 to +28
- LIST_DIR(`.`) the project root (exclude `.git/`, `node_modules/`, `__pycache__/`, `.venv/`, `vendor/`, `.specops/`)
- Count source code files — files that are NOT config-only files (`.gitignore`, `LICENSE`, `README.md`, `package.json`, `pyproject.toml`, `Cargo.toml`, `go.mod`, `pom.xml`, `build.gradle`, `Gemfile`, `composer.json`, `tsconfig.json`, `Makefile`, `Dockerfile`, `.editorconfig`, `.prettierrc`, `.eslintrc.*`)
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

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

Project type detection uses LIST_DIR('.') to count source code files, but doesn’t specify a recursive scan. With code under nested dirs (e.g., src/), this can undercount and incorrectly classify brownfield projects as greenfield. Consider mirroring the repo-map discovery approach: use RUN_COMMAND(git ls-files ...) when available, otherwise LIST_DIR recursively with exclusions, so the count reflects the whole repo.

Suggested change
- LIST_DIR(`.`) the project root (exclude `.git/`, `node_modules/`, `__pycache__/`, `.venv/`, `vendor/`, `.specops/`)
- Count source code files — files that are NOT config-only files (`.gitignore`, `LICENSE`, `README.md`, `package.json`, `pyproject.toml`, `Cargo.toml`, `go.mod`, `pom.xml`, `build.gradle`, `Gemfile`, `composer.json`, `tsconfig.json`, `Makefile`, `Dockerfile`, `.editorconfig`, `.prettierrc`, `.eslintrc.*`)
- Prefer using version control metadata when available:
- RUN_COMMAND(`git ls-files`) from the project root to list tracked files.
- From this list, exclude files under `.git/`, `node_modules/`, `__pycache__/`, `.venv/`, `vendor/`, `.specops/`.
- If `git ls-files` is not available or fails (e.g., not a Git repo), fall back to a filesystem scan:
- LIST_DIR(`.`, recursive = true, excludeDirs = [`.git`, `node_modules`, `__pycache__`, `.venv`, `vendor`, `.specops`]) to discover all files in the project.
- From the resulting file list (from either git or LIST_DIR), count source code files — files that are NOT config-only files (`.gitignore`, `LICENSE`, `README.md`, `package.json`, `pyproject.toml`, `Cargo.toml`, `go.mod`, `pom.xml`, `build.gradle`, `Gemfile`, `composer.json`, `tsconfig.json`, `Makefile`, `Dockerfile`, `.editorconfig`, `.prettierrc`, `.eslintrc.*`).

Copilot uses AI. Check for mistakes.
Comment on lines +116 to +119
#### Step 4.7: Assisted Steering Population (Brownfield)

If the confirmed project type from Step 1.5 is **brownfield**, check for existing documentation to pre-populate the steering file templates. Only populate files that still contain placeholder text (bracket-enclosed placeholders like `[One-sentence description`, `[Who uses this`, `[What makes this`, `[Primary language`). Skip this step entirely if all three steering files already have non-placeholder content or if the project type is not brownfield.

Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

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

Step 4.7 refers to the project type as brownfield (lowercase), while Step 1.5 presents options as Brownfield/Greenfield/Migration. Use consistent casing/values for the project type label throughout the init workflow to avoid ambiguity about the stored value and conditional checks.

Copilot uses AI. Check for mistakes.
Copy link
Owner Author

Choose a reason for hiding this comment

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

Fixed in 71b911e.

Comment on lines 18 to 21
"vertical": {
"type": "string",
"enum": ["backend", "frontend", "fullstack", "infrastructure", "data", "library", "builder"],
"enum": ["backend", "frontend", "fullstack", "infrastructure", "data", "library", "builder", "migration"],
"description": "Project vertical that influences spec template adaptation. Auto-detected when not set."
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

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

PR description mentions adding an optional metrics object to schema.json, but this change only updates the vertical enum here. Since metrics belongs to spec.json (spec-schema.json), either update the PR description/changelog to match reality or add the missing schema change if it was intended.

Copilot uses AI. Check for mistakes.
# Feature: Project-Type-Aware Workflow

## Overview
SpecOps currently assumes a brownfield (existing codebase) context for every project. Phase 1 steps 8-9 are hollow on empty repos, init creates empty steering files regardless of existing docs, and there is no vertical for migration/re-platforming. This feature makes SpecOps project-type-aware across greenfield, brownfield, and bluefield projects with five targeted changes.
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

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

This spec’s overview calls the third project type “bluefield”, but the rest of the workflow and schema use “migration” (greenfield/brownfield/migration). Rename “bluefield” here (or define it explicitly if it’s intended) to keep terminology consistent with the implemented feature.

Suggested change
SpecOps currently assumes a brownfield (existing codebase) context for every project. Phase 1 steps 8-9 are hollow on empty repos, init creates empty steering files regardless of existing docs, and there is no vertical for migration/re-platforming. This feature makes SpecOps project-type-aware across greenfield, brownfield, and bluefield projects with five targeted changes.
SpecOps currently assumes a brownfield (existing codebase) context for every project. Phase 1 steps 8-9 are hollow on empty repos, init creates empty steering files regardless of existing docs, and there is no vertical for migration/re-platforming. This feature makes SpecOps project-type-aware across greenfield, brownfield, and migration projects with five targeted changes.

Copilot uses AI. Check for mistakes.
Copy link
Owner Author

Choose a reason for hiding this comment

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

Fixed in 71b911e.

8 tasks completed, 0 deviations from design, 0 blockers. Implemented 3-layer enforcement for plan mode → SpecOps automation: (1) enhanced `core/from-plan.md` with file path input (Branch B) and platform auto-discovery (Branch C using `planFileDirectory`), (2) added step 10.5 post-plan-acceptance gate to `core/workflow.md` with protocol breach enforcement, (3) added Step 8 SpecOps handoff to `.claude/commands/resume-plan.md`. Added `planFileDirectory: "~/.claude/plans"` to Claude's `platform.json`. Updated FROM_PLAN_MARKERS in `generator/validate.py` with "auto-discovery" and "planFileDirectory". All 4 platform outputs regenerated, all 8 tests pass.

### project-type-awareness (feature) — 2026-03-21
6 tasks completed, 0 deviations from design, 0 blockers. Made SpecOps project-type-aware across greenfield, brownfield, and bluefield projects: (1) migration vertical in `core/verticals.md` with domain vocabulary (Migration Requirements, Migration Architecture, Cutover Plan, Coexistence Strategy) + schema/validator/test updates, (2) auto-init suggestion in `core/workflow.md` step 1 when `.specops.json` missing, (3) project type detection in `core/init.md` step 1.5 (auto-classifies greenfield/brownfield, migration override), (4) brownfield assisted steering in `core/init.md` step 4.7 (auto-populates from README/deps), (5) greenfield adaptive Phase 1 in `core/workflow.md` step 7.5 (replaces hollow codebase exploration with structure proposal and steering auto-population). All 8 tests pass.
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

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

This memory entry describes project types as greenfield/brownfield/bluefield, but the implemented workflow uses greenfield/brownfield/migration. Update the terminology here to match the actual project-type labels to avoid confusing future readers relying on memory/context summaries.

Suggested change
6 tasks completed, 0 deviations from design, 0 blockers. Made SpecOps project-type-aware across greenfield, brownfield, and bluefield projects: (1) migration vertical in `core/verticals.md` with domain vocabulary (Migration Requirements, Migration Architecture, Cutover Plan, Coexistence Strategy) + schema/validator/test updates, (2) auto-init suggestion in `core/workflow.md` step 1 when `.specops.json` missing, (3) project type detection in `core/init.md` step 1.5 (auto-classifies greenfield/brownfield, migration override), (4) brownfield assisted steering in `core/init.md` step 4.7 (auto-populates from README/deps), (5) greenfield adaptive Phase 1 in `core/workflow.md` step 7.5 (replaces hollow codebase exploration with structure proposal and steering auto-population). All 8 tests pass.
6 tasks completed, 0 deviations from design, 0 blockers. Made SpecOps project-type-aware across greenfield, brownfield, and migration projects: (1) migration vertical in `core/verticals.md` with domain vocabulary (Migration Requirements, Migration Architecture, Cutover Plan, Coexistence Strategy) + schema/validator/test updates, (2) auto-init suggestion in `core/workflow.md` step 1 when `.specops.json` missing, (3) project type detection in `core/init.md` step 1.5 (auto-classifies greenfield/brownfield, migration override), (4) brownfield assisted steering in `core/init.md` step 4.7 (auto-populates from README/deps), (5) greenfield adaptive Phase 1 in `core/workflow.md` step 7.5 (replaces hollow codebase exploration with structure proposal and steering auto-population). All 8 tests pass.

Copilot uses AI. Check for mistakes.
Comment on lines +246 to +257
# Feedback mode markers that MUST appear in every output
# Proxy metrics markers that MUST appear in every output
METRICS_MARKERS = [
"## Proxy Metrics",
"### Metrics Capture Procedure",
"### Metrics Safety",
"specArtifactTokensEstimate",
"filesChanged",
"linesAdded",
"tasksCompleted",
"acceptanceCriteriaVerified",
]
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

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

METRICS_MARKERS omits some metrics fields that the workflow/module requires (e.g., linesRemoved, specDurationMinutes). This weakens the validator by allowing platform outputs to silently miss parts of the Proxy Metrics module while still passing validation. Expand METRICS_MARKERS to cover all metrics fields that are documented/expected so the check fully protects the feature.

Copilot uses AI. Check for mistakes.
…metrics markers, terminology

- Add ISO-8601 validation and `| tr -d ' '` to metrics git commands for shell safety
- Switch greenfield detection from LIST_DIR to git ls-files for recursive source file counting
- Add fallback classification for repos with >5 source files but no manifests
- Fix stale comment and add missing linesRemoved/specDurationMinutes to METRICS_MARKERS
- Normalize bluefield → migration terminology in spec artifacts and memory
- Fix ambiguous docs review entry in implementation journal
- Capitalize Brownfield consistently in init.md
@sanmak sanmak merged commit 83a1c98 into main Mar 20, 2026
10 of 11 checks passed
Comment on lines +165 to 171
# Parse version — skip if < 1.3.0 (gate introduced at 1.3.0)
try:
parts = [int(x) for x in created_with.split(".")]
if len(parts) == 3 and (
parts[0] < 1
or (parts[0] == 1 and parts[1] < 3)
or (parts[0] == 1 and parts[1] == 3 and parts[2] == 0)
):
Copy link

Choose a reason for hiding this comment

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

P2 Version boundary change is a silent breaking change for existing users

Dropping the or (parts[0] == 1 and parts[1] == 3 and parts[2] == 0) clause means that specs created with SpecOps v1.3.0 are now subject to the Documentation Review and IssueID enforcement gates. Within this repository the retroactive spec updates cover all in-tree artifacts, but any downstream user who has repos with v1.3.0-created specs (not retrofitted) will get unexpected CI failures the next time they pull an updated version of SpecOps.

This is worth calling out explicitly in the CHANGELOG or as a migration note so users know to check their existing v1.3.0 specs before upgrading.

Comment on lines +114 to 155
"metrics": {
"type": "object",
"description": "Proxy productivity metrics captured at spec completion (Phase 4)",
"properties": {
"specArtifactTokensEstimate": {
"type": "integer",
"minimum": 0,
"description": "Estimated tokens of spec artifacts (total chars / 4)"
},
"filesChanged": {
"type": "integer",
"minimum": 0,
"description": "Number of files changed during implementation"
},
"linesAdded": {
"type": "integer",
"minimum": 0,
"description": "Lines added during implementation"
},
"linesRemoved": {
"type": "integer",
"minimum": 0,
"description": "Lines removed during implementation"
},
"tasksCompleted": {
"type": "integer",
"minimum": 0,
"description": "Count of tasks with Completed status"
},
"acceptanceCriteriaVerified": {
"type": "integer",
"minimum": 0,
"description": "Count of checked acceptance criteria checkboxes"
},
"specDurationMinutes": {
"type": "integer",
"minimum": 0,
"description": "Elapsed minutes from spec creation to completion"
}
},
"additionalProperties": false
}
Copy link

Choose a reason for hiding this comment

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

P2 metrics object has no required array — empty object passes validation

core/metrics.md step 6 instructs: "If any individual metric could not be computed, set its value to 0 rather than omitting it," which implies a fully-populated object. However, the schema has no required list inside the metrics object, so {"metrics": {}} is schema-valid. This creates a gap between the prescribed behaviour (all seven fields always present) and what validation enforces.

Consider adding:

"required": [
  "specArtifactTokensEstimate",
  "filesChanged",
  "linesAdded",
  "linesRemoved",
  "tasksCompleted",
  "acceptanceCriteriaVerified",
  "specDurationMinutes"
]

inside the metrics object definition, so any partially-written metrics block is flagged by test_spec_schema.py rather than silently accepted.

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.

2 participants