Skip to content

Commit 4c0172a

Browse files
Demote private Make/Mise targets and fix xterm dimensions TypeError (#15)
# TLDR; Closes #13. Make and Mise targets prefixed with `_` are now sorted below public targets, separated by a divider, and rendered with a muted icon/label plus a "private" description marker. Also fixes an intermittent xterm `dimensions` TypeError by waiting for the shell process to spawn before `sendText`. # Details ## What Was Added - **`src/tree/PrivateTaskDecorationProvider.ts`** — new `FileDecorationProvider` registered on the `commandtree-private` URI scheme that paints private-task labels with `descriptionForeground`. Exports `buildPrivateTaskUri(taskId)`. - **`src/models/TaskItem.ts`** — `isPrivateTask`, `isPhonyTask` helpers, an optional `isPhony` flag on `CommandItem`/`MutableCommandItem`, and `resourceUri` support on `CommandTreeItem` (extracted into `applyOptionalProps` to keep the constructor lean). - **`src/discovery/make.ts`** — `.PHONY:` parser (`parsePhonyTargets`, with line-continuation support) that tags targets with `isPhony: true`. - **`src/tree/nodeFactory.ts`** — `createTaskNodes(tasks)` groups tasks and injects a `createDividerNode` between the last public task and the first private one. Private tasks get a muted `ThemeIcon`, a private `resourceUri`, and a ` private` marker appended to their description. - **`src/CommandTreeProvider.ts`** — comparators `comparePrivateTasks`, `compareHelpTasks`, `comparePhonyTasks`, `compareMakeTaskPriority` layered into all three sort modes (folder, type, name). Private tasks sort last; `help` pins to the top of Make targets; phony targets come before non-phony ones. - **E2E tests** in `src/test/e2e/treeview.e2e.test.ts`: - `Private Make And Mise Tasks` — writes fixture `Makefile` and `mise.toml` with mixed public/private targets, asserts divider position, ordering, `description` contains `private`, icon color `descriptionForeground`, and `resourceUri.scheme === "commandtree-private"`. - `Make Target Conventions` — asserts `help` is pinned first, phony public targets outrank non-phony ones, and pattern rules (`%.o`) / dot-prefixed special targets (`.DEFAULT`) stay hidden. ## What Was Changed - **`src/runners/TaskRunner.ts`** — `SHELL_INTEGRATION_TIMEOUT_MS` raised from 50 ms to 500 ms and the fallback path now awaits `terminal.processId` before calling `sendText`, avoiding the xterm `dimensions` TypeError when the viewport hasn't been laid out yet. Added exhaustive `never`-typed `default` branch in `formatParamValue`. - **`src/extension.ts`** — registers `PrivateTaskDecorationProvider` via `vscode.window.registerFileDecorationProvider`; returns `undefined` explicitly when there's no workspace root. - **`src/discovery/docker.ts`** — destructuring cleanup in `parseDockerComposeServices`. - **`src/test/e2e/execution.e2e.test.ts`** — `runInCurrentTerminal` tests now (a) write a marker file via the shell and assert the file exists + contains the echoed text (proves the command actually ran, not just that a terminal appeared), (b) watch VS Code's `renderer.log` and assert no `dimensions`/`TypeError` lines are written during the command, (c) assert the active terminal name and exit status. Timeouts bumped to 20 s to match the longer shell-integration wait. - **Skill docs** (`.claude/skills/*/SKILL.md`), `.github/workflows/ci.yml`, `Makefile`, `coverage-thresholds.json`, `eslint.config.mjs`, `Agents.md`, `Claude.md`, `.vscode/extensions.json`, `tools/check-coverage.mjs` — repo-standards polish bundled in. ## What Was Deleted Nothing of substance deleted from runtime code — some destructuring simplifications and one `allowed-tools` line removed from `submit-pr` SKILL frontmatter. ## How Tests Prove It Works - `src/test/e2e/treeview.e2e.test.ts::Private Make And Mise Tasks::make private targets sort after public ones and render muted` — asserts folder children are `[alpha_public, zeta_public, ─────, _beta_private, _omega_private]`, each private item has `description` containing `private`, icon `ThemeColor.id === "descriptionForeground"`, and `resourceUri.scheme === "commandtree-private"`. - `...::mise private tasks sort after public ones and render muted` — same assertions for `mise.toml`. - `...::Make Target Conventions::make help is pinned to the top, phony targets sort before non-phony ones, and special targets stay hidden` — asserts folder children are `[help, build, aaa_file, ─────, _private]` and `%.o` / `.DEFAULT` are absent. - `src/test/e2e/execution.e2e.test.ts::runInCurrentTerminal creates terminal when none exists` and `...reuses existing active terminal` — assert the marker file is written and `renderer.log` contains zero `dimensions`/`TypeError` lines during the run, proving `sendText` no longer hits the xterm layout race. ## Spec/Doc Changes - `.claude/skills/*/SKILL.md` updated to reference `make test` (fail-fast + coverage threshold) and the repo's actual Make targets — no behaviour spec changes. ## Breaking Changes None. New data (`isPhony`, `resourceUri`, divider node, `commandtree-private` URI scheme) is additive. Sort order changes are a UX improvement within existing sort modes and do not alter any public API. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: abdushakoor12 <abdushakoor009@gmail.com> Co-authored-by: Abdul Shakoor <60779242+abdushakoor12@users.noreply.github.com>
1 parent b42ea8c commit 4c0172a

31 files changed

Lines changed: 1159 additions & 268 deletions

.claude/skills/ci-prep/SKILL.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name: ci-prep
33
description: Prepares the current branch for CI by running the exact same steps locally and fixing issues. If CI is already failing, fetches the GH Actions logs first to diagnose. Use before pushing, when CI is red, or when the user says "fix ci".
44
argument-hint: "[--failing] [optional job name to focus on]"
55
---
6-
<!-- agent-pmo:5547fd2 -->
6+
<!-- agent-pmo:424c8f8 -->
77

88
# CI Prep
99

@@ -42,12 +42,12 @@ Read **every line** of `--log-failed` output. For each failure note the exact fi
4242

4343
## Step 2 — Analyze the CI workflow
4444

45-
1. Find the CI workflow file. Look in `.github/workflows/` for `ci.yml`.
45+
1. Find the CI workflow file. Look in `.github/workflows/` for `ci.yml` (this repo's CI workflow).
4646
2. Read the workflow file completely. Parse every job and every step.
47-
3. Extract the ordered list of commands the CI actually runs (e.g., `make fmt-check`, `make lint`, `make spellcheck`, `make test EXCLUDE_CI=true`, `make build`, `make package`).
48-
4. Note any environment variables, matrix strategies, or conditional steps that affect execution.
47+
3. Extract the ordered list of commands the CI actually runs. In this spec-compliant repo that is `make fmt CHECK=1 → make lint → make test make buildmake package` (REPO-STANDARDS-SPEC [MAKE-TARGETS] plus the repo-specific `package` target).
48+
4. Note any environment variables, matrix strategies, or conditional steps that affect execution. The separate `website` job runs Playwright tests against the 11ty site under `website/`.
4949

50-
**Do NOT assume the steps.** Extract what the CI *actually does*.
50+
**Do NOT assume the steps.** Extract what the CI *actually does*. If you find extra targets beyond the 7 in [MAKE-TARGETS] that are not already in the `Repo-Specific Targets` section, flag them — they should be consolidated by the agent-pmo skill.
5151

5252
## Step 3 — Run each CI step locally, in order
5353

@@ -60,15 +60,15 @@ Work through failures in this priority order:
6060

6161
For each command extracted from the CI workflow:
6262

63-
1. Run the command exactly as CI would run it.
63+
1. Run the command exactly as CI would run it (adjusting only for local environment differences like not needing `actions/checkout`).
6464
2. If the step fails, **stop and fix the issues** before continuing to the next step.
6565
3. After fixing, re-run the same step to confirm it passes.
6666
4. Move to the next step only after the current one succeeds.
6767

6868
### Hard constraints
6969

7070
- **NEVER modify test files** — fix the source code, not the tests
71-
- **NEVER add suppressions** (`// eslint-disable`, `// @ts-ignore`)
71+
- **NEVER add suppressions** (`// eslint-disable`, `@ts-ignore`, `@ts-nocheck`)
7272
- **NEVER use `any` in TypeScript** to silence type errors
7373
- **NEVER delete or ignore failing tests**
7474
- **NEVER remove assertions**
@@ -97,7 +97,7 @@ Once all CI steps pass locally:
9797
- Fix issues found in each step before moving to the next
9898
- Never skip steps or suppress errors
9999
- If the CI workflow has multiple jobs, run all of them (respecting dependency order)
100-
- Skip steps that are CI-infrastructure-only (checkout, setup-node, cache steps, artifact uploads) — focus on the actual build/test/lint commands
100+
- Skip steps that are CI-infrastructure-only (checkout, setup-node actions, cache steps, artifact uploads) — focus on the actual build/test/lint commands
101101

102102
## Success criteria
103103

.claude/skills/code-dedup/SKILL.md

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
name: code-dedup
33
description: Searches for duplicate code, duplicate tests, and dead code, then safely merges or removes them. Use when the user says "deduplicate", "find duplicates", "remove dead code", "DRY up", or "code dedup". Requires test coverage — refuses to touch untested code.
44
---
5-
<!-- agent-pmo:5547fd2 -->
5+
<!-- agent-pmo:424c8f8 -->
66

77
# Code Dedup
88

@@ -13,8 +13,8 @@ Carefully search for duplicate code, duplicate tests, and dead code across the r
1313
Before touching ANY code, verify these conditions. If any fail, stop and report why.
1414

1515
1. Run `make test` — all tests must pass. If tests fail, stop. Do not dedup a broken codebase.
16-
2. Run `make coverage-check` — coverage must meet the repo's threshold. If it doesn't, stop.
17-
3. Verify the project uses **static typing**. Check `tsconfig.json` has `"strict": true` — proceed.
16+
2. `make test` is fail-fast AND enforces the coverage threshold from `coverage-thresholds.json`. If anything fails, stop and fix it before deduping.
17+
3. This is a TypeScript repo. Confirm `tsconfig.json` has `"strict": true` (it does). Proceed.
1818

1919
## Steps
2020

@@ -34,16 +34,19 @@ Dedup Progress:
3434

3535
Before deciding what to touch, understand what is tested.
3636

37-
1. Run `make test` and `make coverage-check` to confirm green baseline
38-
2. Note the current coverage percentagethis is the floor. It must not drop.
37+
1. Run `make test` to confirm green baseline. `make test` is fail-fast AND enforces the coverage thresholds from `coverage-thresholds.json` (REPO-STANDARDS-SPEC [TEST-RULES], [COVERAGE-THRESHOLDS-JSON]). It exits non-zero on any test failure OR coverage shortfall.
38+
2. Note the current coverage percentagesthese are the floor. They must not drop.
3939
3. Identify which files/modules have coverage and which do not. Only files WITH coverage are candidates for dedup.
4040

4141
### Step 2 — Scan for dead code
4242

4343
Search for code that is never called, never imported, never referenced.
4444

4545
1. Look for unused exports, unused functions, unused classes, unused variables
46-
2. Check for `noUnusedLocals`/`noUnusedParameters` in tsconfig, look for unexported functions with zero references
46+
2. TypeScript-specific tooling:
47+
- `tsconfig.json` has `noUnusedLocals`/`noUnusedParameters` — the compiler already warns on unused locals/params
48+
- ESLint flags unused exports via `@typescript-eslint/no-unused-vars`
49+
- Look for unexported functions with zero references within the module
4750
3. For each candidate: **grep the entire codebase** for references (including tests, scripts, configs). Only mark as dead if truly zero references.
4851
4. List all dead code found with file paths and line numbers. Do NOT delete yet.
4952

@@ -54,7 +57,7 @@ Search for code blocks that do the same thing in multiple places.
5457
1. Look for functions/methods with identical or near-identical logic
5558
2. Look for copy-pasted blocks (same structure, maybe different variable names)
5659
3. Look for multiple implementations of the same algorithm or pattern
57-
4. Check across module boundaries — duplicates often hide in different packages
60+
4. Check across discovery providers in `src/discovery/` — duplicates often hide in similar providers
5861
5. For each duplicate pair: note both locations, what they do, and how they differ (if at all)
5962
6. List all duplicates found. Do NOT merge yet.
6063

@@ -63,8 +66,8 @@ Search for code blocks that do the same thing in multiple places.
6366
Search for tests that verify the same behavior.
6467

6568
1. Look for test functions with identical assertions against the same code paths
66-
2. Look for test fixtures/helpers that are duplicated across test files
67-
3. Look for integration tests that fully cover what a unit test also covers (keep the integration test, mark the unit test as redundant)
69+
2. Look for test fixtures/helpers duplicated across test files
70+
3. Look for integration tests that fully cover what a unit test also covers (keep the integration/E2E test, mark the unit test as redundant per CLAUDE.md rules)
6871
4. List all duplicate tests found. Do NOT delete yet.
6972

7073
### Step 5 — Apply changes (one at a time)
@@ -73,32 +76,33 @@ For each change, follow this cycle: **change → test → verify coverage → co
7376

7477
#### 5a. Remove dead code
7578
- Delete dead code identified in Step 2
76-
- After each deletion: run `make test` and `make coverage-check`
77-
- If tests fail or coverage drops: **revert immediately** and investigate
79+
- After each deletion: run `make test` (fail-fast + coverage + threshold all in one)
80+
- If `make test` exits non-zero: **revert immediately** and investigate
81+
- Dead code removal should never break tests or drop coverage
7882

7983
#### 5b. Merge duplicate code
8084
- For each duplicate pair: extract the shared logic into a single function/module
8185
- Update all call sites to use the shared version
82-
- After each merge: run `make test` and `make coverage-check`
83-
- If tests fail: **revert immediately**
86+
- After each merge: run `make test`
87+
- If tests fail: **revert immediately**. The duplicates may have subtle differences you missed.
88+
- If coverage drops: the shared code must have equivalent test coverage. Add tests if needed before proceeding.
8489

8590
#### 5c. Remove duplicate tests
8691
- Delete the redundant test (keep the more thorough one)
87-
- After each deletion: run `make coverage-check`
88-
- If coverage drops: **revert immediately**
92+
- After each deletion: run `make test`
93+
- If coverage drops below threshold, `make test` exits non-zero — **revert immediately**. The "duplicate" test was covering something the other wasn't.
8994

9095
### Step 6 — Final verification
9196

92-
1. Run `make test` — all tests must still pass
93-
2. Run `make coverage-check` — coverage must be >= the baseline from Step 1
94-
3. Run `make lint` and `make fmt-check` — code must be clean
95-
4. Report: what was removed, what was merged, final coverage vs baseline
97+
1. Run `make lint` — ESLint + cspell must pass
98+
2. Run `make test` — tests must pass AND coverage must remain ≥ the baseline from Step 1
99+
3. Report: what was removed, what was merged, final coverage vs baseline
96100

97101
## Rules
98102

99-
- **No test coverage = do not touch.** If a file has no tests covering it, leave it alone entirely.
100-
- **Coverage must not drop.** The coverage floor from Step 1 is sacred.
101-
- **One change at a time.** Make one dedup change, run tests, verify coverage. Never batch.
102-
- **When in doubt, leave it.** If two code blocks look similar but you're not 100% sure they're functionally identical, leave both.
103-
- **Preserve public API surface.** Do not change function signatures, class names, or module exports that external code depends on.
104-
- **Three similar lines is fine.** Only dedup when the shared logic is substantial (>10 lines) or when there are 3+ copies.
103+
- **No test coverage = do not touch.** If a file has no tests covering it, leave it alone entirely. You cannot safely dedup what you cannot verify.
104+
- **Coverage must not drop.** If removing or merging code causes coverage to decrease, revert and investigate. The coverage floor from Step 1 is sacred.
105+
- **One change at a time.** Make one dedup change, run tests, verify coverage. Never batch multiple dedup changes before testing.
106+
- **When in doubt, leave it.** If two code blocks look similar but you're not 100% sure they're functionally identical, leave both. False dedup is worse than duplication.
107+
- **Preserve public API surface.** Do not change exported function signatures, class names, or module exports. Internal refactoring only.
108+
- **Three similar lines is fine.** Do not create abstractions for trivial duplication. Only dedup when the shared logic is substantial (>10 lines) or when there are 3+ copies.

.claude/skills/spec-check/SKILL.md

Lines changed: 130 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name: spec-check
33
description: Audit spec/plan documents against the codebase. Ensures every spec section has implementing code, tests, and matching logic. Use when the user says "check specs", "spec audit", or "verify specs".
44
argument-hint: "[optional spec ID or filename filter]"
55
---
6-
<!-- agent-pmo:5547fd2 -->
6+
<!-- agent-pmo:424c8f8 -->
77

88
# spec-check
99

@@ -69,6 +69,21 @@ Use Glob to find candidate files, then use Grep to confirm they contain spec IDs
6969

7070
Spec IDs are **hierarchical descriptive slugs, NEVER numbered.** The format is `[GROUP-TOPIC]` or `[GROUP-TOPIC-DETAIL]`. The first word is the **group** — all sections sharing the same group MUST appear together in the spec's table of contents. IDs are uppercase, hyphen-separated, unique across the repo, and MUST NOT contain sequential numbers.
7171

72+
The hierarchy depth varies by repo: two words for simple repos (`[AUTH-LOGIN]`), three for most (`[AUTH-TOKEN-VERIFY]`), four for complex domains (`[AUTH-OAUTH-REFRESH-FLOW]`). The hierarchy mirrors the spec document's heading structure.
73+
74+
Examples of valid spec IDs (note how groups cluster):
75+
- `[AUTH-LOGIN]`, `[AUTH-TOKEN-VERIFY]`, `[AUTH-TOKEN-REFRESH]` — all in the AUTH group
76+
- `[CI-TIMEOUT]`, `[CI-LINT]`, `[CI-RELEASE]` — all in the CI group
77+
- `[LINT-ESLINT]`, `[LINT-RUFF]` — all in the LINT group
78+
- `[FEAT-DARK-MODE]`, `[FEAT-SEARCH-FILTER]` — all in the FEAT group
79+
80+
Examples of INVALID spec IDs:
81+
- `[SPEC-001]` — numbered, meaningless
82+
- `[FEAT-AUTH-01]` — trailing number
83+
- `[REQ-003]` — sequential index, no group hierarchy
84+
- `[CI-004]` — numbered, tells the reader nothing
85+
- `[TIMEOUT]` — no group prefix, ungrouped
86+
7287
For each file, extract every spec ID and its associated section title (the heading text after the ID) and the full section content (everything until the next heading of equal or higher level).
7388

7489
---
@@ -101,6 +116,34 @@ Search the entire codebase for the spec ID string, **excluding** these directori
101116

102117
Use Grep with the literal spec ID (e.g., `[AUTH-TOKEN-VERIFY]`) to find references in code files.
103118

119+
Code files should contain comments referencing the spec ID. The search must catch **all** comment styles across languages:
120+
121+
**C-style `//` comments** (JavaScript, TypeScript, Rust, C#, F#, Java, Kotlin, Go, Swift, Dart):
122+
- `// Implements [AUTH-TOKEN-VERIFY]`
123+
- `// [AUTH-TOKEN-VERIFY]`
124+
- `// Tests [AUTH-TOKEN-VERIFY]` (also counts as a code reference)
125+
- `/// Implements [AUTH-TOKEN-VERIFY]` (doc comments)
126+
127+
**Hash `#` comments** (Python, Ruby, Shell/Bash, YAML, TOML):
128+
- `# Implements [AUTH-TOKEN-VERIFY]`
129+
- `# [AUTH-TOKEN-VERIFY]`
130+
- `# Tests [AUTH-TOKEN-VERIFY]`
131+
132+
**HTML/XML comments** (HTML, CSS, SVG, XML, XAML, JSX templates):
133+
- `<!-- Implements [AUTH-TOKEN-VERIFY] -->`
134+
- `<!-- [AUTH-TOKEN-VERIFY] -->`
135+
136+
**ML-style comments** (F#, OCaml):
137+
- `(* Implements [AUTH-TOKEN-VERIFY] *)`
138+
139+
**Lua comments:**
140+
- `-- Implements [AUTH-TOKEN-VERIFY]`
141+
142+
**CSS comments:**
143+
- `/* Implements [AUTH-TOKEN-VERIFY] */`
144+
145+
**The key rule:** any comment in any language containing the exact spec ID string (e.g., `[AUTH-TOKEN-VERIFY]`) counts as a valid code reference. The Grep search uses the literal spec ID string, so it naturally matches all comment styles. Do NOT restrict the search to specific comment prefixes — just search for the spec ID string itself.
146+
104147
**If NO code files reference the spec ID:**
105148

106149
```
@@ -118,12 +161,72 @@ this spec section, then re-run spec-check.
118161
#### Check B: Tests reference the spec ID
119162

120163
Search test files for the spec ID. Test files are found in:
121-
- `src/test/`
164+
- `test/`
165+
- `tests/`
122166
- `**/*.test.*`
123167
- `**/*.spec.*`
168+
- `**/*_test.*`
169+
- `**/test_*.*`
170+
- `**/*Tests.*`
171+
- `**/*Test.*`
124172

125173
Use Grep to search these locations for the literal spec ID string.
126174

175+
Tests should contain the spec ID in comments, test names, or annotations. The search must catch **all** test frameworks across languages:
176+
177+
**JavaScript/TypeScript** (Jest, Mocha, Vitest, Playwright):
178+
- `// Tests [AUTH-TOKEN-VERIFY]`
179+
- `describe('[AUTH-TOKEN-VERIFY] Authentication flow', () => ...)`
180+
- `test('[AUTH-TOKEN-VERIFY] should verify token', () => ...)`
181+
- `it('[AUTH-TOKEN-VERIFY] verifies token', () => ...)`
182+
183+
**Python** (pytest, unittest):
184+
- `# Tests [AUTH-TOKEN-VERIFY]`
185+
- `def test_auth_token_verify_flow():`
186+
- `class TestAuthTokenVerify:`
187+
188+
**Rust:**
189+
- `// Tests [AUTH-TOKEN-VERIFY]`
190+
- `#[test] // Tests [AUTH-TOKEN-VERIFY]`
191+
192+
**C#** (xUnit, NUnit, MSTest):
193+
- `// Tests [AUTH-TOKEN-VERIFY]`
194+
- `[Fact] // Tests [AUTH-TOKEN-VERIFY]`
195+
- `[Test] // Tests [AUTH-TOKEN-VERIFY]`
196+
- `[TestMethod] // Tests [AUTH-TOKEN-VERIFY]`
197+
198+
**F#** (xUnit, Expecto):
199+
- `// Tests [AUTH-TOKEN-VERIFY]`
200+
- `[<Fact>] // Tests [AUTH-TOKEN-VERIFY]`
201+
- `testCase "[AUTH-TOKEN-VERIFY] description" <| fun () ->`
202+
203+
**Java/Kotlin** (JUnit, TestNG):
204+
- `// Tests [AUTH-TOKEN-VERIFY]`
205+
- `@Test // Tests [AUTH-TOKEN-VERIFY]`
206+
207+
**Go:**
208+
- `// Tests [AUTH-TOKEN-VERIFY]`
209+
- `func TestAuthTokenVerify(t *testing.T) { // Tests [AUTH-TOKEN-VERIFY]`
210+
211+
**Swift** (XCTest):
212+
- `// Tests [AUTH-TOKEN-VERIFY]`
213+
- `func testAuthTokenVerify() { // Tests [AUTH-TOKEN-VERIFY]`
214+
215+
**Dart** (flutter_test):
216+
- `// Tests [AUTH-TOKEN-VERIFY]`
217+
- `test('[AUTH-TOKEN-VERIFY] description', () { ... });`
218+
219+
**Ruby** (RSpec, Minitest):
220+
- `# Tests [AUTH-TOKEN-VERIFY]`
221+
- `describe '[AUTH-TOKEN-VERIFY] Authentication' do`
222+
- `it '[AUTH-TOKEN-VERIFY] verifies token' do`
223+
224+
**Shell** (bats, shunit2):
225+
- `# Tests [AUTH-TOKEN-VERIFY]`
226+
- `@test "[AUTH-TOKEN-VERIFY] description" {`
227+
228+
**The key rule:** same as Check A — search for the literal spec ID string in test files. Any occurrence of the exact spec ID in a test file counts. Do NOT restrict to specific patterns — just search for the spec ID string itself.
229+
127230
**If NO test files reference the spec ID:**
128231

129232
```
@@ -153,7 +256,26 @@ This is the most critical check. You must:
153256
- **Missing steps** — If the spec describes 5 steps but code only implements 3, that's a violation.
154257
- **Wrong defaults** — If the spec says "default to X" but code defaults to Y, that's a violation.
155258

156-
4. **If the code deviates from the spec**, report a detailed error with spec quotes and code references.
259+
4. **If the code deviates from the spec**, report a detailed error:
260+
261+
```
262+
SPEC VIOLATION: [AUTH-TOKEN-VERIFY] Code does not match spec.
263+
264+
SPEC SAYS:
265+
> "The authentication flow must verify the token expiry before checking permissions"
266+
> (from docs/specs/AUTH-SPEC.md, line 42)
267+
268+
CODE DOES:
269+
> `if (hasPermission(user)) { verifyToken(token); }` (src/auth.ts:42)
270+
271+
DEVIATION: The code checks permissions BEFORE verifying token expiry.
272+
The spec explicitly requires token expiry verification FIRST.
273+
274+
ACTION REQUIRED: Reorder the logic in src/auth.ts to verify token expiry
275+
before checking permissions, as specified in [AUTH-TOKEN-VERIFY].
276+
```
277+
278+
**STOP HERE. Do not continue to other specs.**
157279

158280
5. **If the code matches the spec**, this check passes. Move to the next spec.
159281

@@ -180,6 +302,8 @@ spec-check PASSED. All specs verified.
180302
| Spec ID | Title | Code References | Test References | Logic Match |
181303
|----------------|--------------------------|-----------------|-----------------|-------------|
182304
| [AUTH-TOKEN-VERIFY] | Authentication flow | src/auth.ts | tests/auth.test.ts | PASS |
305+
| [RATE-LIMIT-CONFIG] | Rate limiting | src/rate.ts | tests/rate.test.ts | PASS |
306+
| ... | ... | ... | ... | ... |
183307
184308
Checked N spec sections across M files. All have implementing code, tests, and matching logic.
185309
```
@@ -199,7 +323,7 @@ Checked N spec sections across M files. All have implementing code, tests, and m
199323

200324
- **Fail fast.** Stop on the first violation. One fix at a time.
201325
- **Be pedantic.** If the spec says it, the code must do it. No "close enough".
202-
- **Quote everything.** Always quote the spec text and the code in error messages.
326+
- **Quote everything.** Always quote the spec text and the code in error messages so the developer sees exactly what's wrong.
203327
- **Be actionable.** Every error must tell the developer what file to change and what to do.
204-
- **Exclude docs from code search.** Markdown files are documentation, not implementation.
205-
- **No numbered IDs.** Spec IDs are hierarchical descriptive slugs, NEVER sequential numbers.
328+
- **Exclude docs from code search.** Markdown files are documentation, not implementation. Only search actual code files for spec references.
329+
- **No numbered IDs.** Spec IDs are hierarchical descriptive slugs (`[AUTH-TOKEN-VERIFY]`), NEVER sequential numbers (`[SPEC-001]`). The first word is the group — sections sharing a group must be adjacent in the TOC. If you encounter numbered or ungrouped IDs, flag them as a violation.

0 commit comments

Comments
 (0)