bigpowers 2.54.0 → 2.56.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.pi/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "bigpowers",
3
- "version": "2.54.0",
4
- "description": "72 skills — 72 agent skills synthesizing 17 years of software engineering discipline into a prescriptive methodology for solo developers",
3
+ "version": "2.56.0",
4
+ "description": "73 skills — 72 agent skills synthesizing 17 years of software engineering discipline into a prescriptive methodology for solo developers",
5
5
  "keywords": [
6
6
  "pi-package"
7
7
  ],
@@ -0,0 +1,79 @@
1
+ ---
2
+ description: "Deterministic traceability quality gate — reads coverage matrix + blind-spot data, applies decision rules with oracle confidence downgrade, emits PASS/CONCERNS/FAIL/WAIVED verdict. Use before release-branch to gate merges on traceability."# story: e38s06
3
+ ---
4
+
5
+
6
+ # Gate Trace
7
+
8
+ Deterministic quality gate that combines traceability coverage and blind-spot data into a single PASS/FAIL/CONCERNS/WAIVED decision before release.
9
+
10
+ ## Decision Rules
11
+
12
+ | Rule | Condition | Verdict |
13
+ |------|-----------|---------|
14
+ | R1 | Any undone story with 0 code tags | FAIL |
15
+ | R2 | Any story done but no verify evidence | CONCERNS |
16
+ | R3 | P0 story (top WSJF quartile) with 0% coverage | FAIL |
17
+ | R4 | Overall coverage < 60% | CONCERNS |
18
+ | R5 | Overall ≥ 80% + no critical gaps + all verify → PASS | PASS |
19
+
20
+ ## Oracle Confidence Downgrade
21
+
22
+ TEA-inspired: if trace links rely on heuristics rather than explicit tags, confidence drops.
23
+
24
+ | Heuristic Ratio | Downgrade |
25
+ |-----------------|-----------|
26
+ | > 50% links from heuristics (file-name or task-reference) | One level (PASS→CONCERNS, CONCERNS→FAIL) |
27
+ | > 80% links from heuristics | Two levels (PASS→FAIL, CONCERNS→FAIL) |
28
+
29
+ ## Process
30
+
31
+ 1. **Pre-flight:** Ensure `scripts/trace-stories.sh --json` has been run (produces `specs/traceability-matrix.json`). If not present, run it.
32
+ 2. Ensure `scripts/check-blind-spots.sh` has been run (produces `specs/blind-spots.json`). If not present, run it.
33
+ 3. Read `specs/traceability-matrix.json` and `specs/blind-spots.json`.
34
+ 4. Apply decision rules R1–R5 in order (first match wins).
35
+ 5. Apply oracle confidence downgrade based on the heuristic link ratio from the matrix's `oracle_stats`.
36
+ 6. Output verdict + rationale to stdout.
37
+ 7. Update `specs/execution-status.yaml` with gate-trace result.
38
+
39
+ ## Verdict Semantics
40
+
41
+ | Verdict | Meaning | Action |
42
+ |---------|---------|--------|
43
+ | PASS | All gates satisfied | Proceed with merge |
44
+ | CONCERNS | Non-critical issues found | Requires explicit human override in `state.yaml` |
45
+ | FAIL | Critical traceability gap | Block merge — fix gap first |
46
+ | WAIVED | Cannot evaluate (missing inputs) | Skip gate — data not available |
47
+
48
+ ## Output Format
49
+
50
+ ```yaml
51
+ gate_trace:
52
+ verdict: PASS|CONCERNS|FAIL|WAIVED
53
+ generated_at: "<ISO 8601>"
54
+ rationale: "<human-readable explanation>"
55
+ heuristic_ratio: <0.0–1.0>
56
+ downgrade_applied: <true|false>
57
+ ```
58
+
59
+ ## Integration Points
60
+
61
+ - **release-branch SKILL.md** — pre-PR gate (FAIL blocks merge).
62
+ - **sync-skills.yml** — CI gate (FAIL blocks pipeline).
63
+ - **verify-work SKILL.md** — runs blind-spot checks; gate-trace consumes the result.
64
+
65
+ ## References
66
+
67
+ - BMAD TEA traceability approach (market survey 2026-07-02).
68
+ - scripts/trace-stories.sh (e38s01) — produces traceability-matrix.json.
69
+ - scripts/check-blind-spots.sh (e38s04) — produces blind-spots.json.
70
+ - specs/execution-status.yaml — output target for gate result.
71
+
72
+ ## Verify
73
+
74
+ → verify: `test -f skills/gate-trace/SKILL.md && grep -q 'PASS.*CONCERNS.*FAIL.*WAIVED' skills/gate-trace/SKILL.md && echo "OK: gate-trace skill created" || echo "FAIL"`
75
+
76
+ ## Handoff
77
+
78
+ Gate: READY → next: release-branch (final step before merge)
79
+ Writes: state.yaml handoff.next_skill = release-branch
@@ -11,21 +11,19 @@ Finalize a completed feature branch: verify coverage gates, integrate onto `main
11
11
 
12
12
  ## Additional modes
13
13
 
14
- - `--hotfix`: Emergency fix. Cherry-pick to main plus immediate tag. Skip PR in solo profile.
15
- - `--squash-state`: Squashes all intermediate `chore(state):` commits on the feature branch into a single clean commit before merging. Use this to reduce noise in the main git repository history.
14
+ - `--hotfix`: Cherry-pick to main + tag. Skip PR in solo.
15
+ - `--squash-state`: Squash `chore(state):` commits before merge.
16
16
 
17
17
  ## Integrate mode
18
18
 
19
- Read `specs/state.yaml` key `workflow_mode` first (`team-pr` | `solo-git`). Fall back to sniffing `profiles/solo-git.md` only when the key is absent.
19
+ Read `specs/state.yaml` key `workflow_mode` (`team-pr` | `solo-git`). Fall back to `profiles/solo-git.md`.
20
20
 
21
21
  | Mode | When | Ship path |
22
22
  |------|------|-----------|
23
- | **solo-local** | `workflow_mode: solo-git` (or `profiles/solo-git.md` present as fallback) | Auto-detect: if `scripts/land-branch.sh` exists → use it; else → fallback (see Step 5) |
23
+ | **solo-local** | `workflow_mode: solo-git` | Auto: `scripts/land-branch.sh` if present, else fallback (Step 5) |
24
24
  | **team-pr** | `workflow_mode: team-pr` (default) | `gh pr create` → `gh pr merge --squash` |
25
25
 
26
- If unsure and working alone, prefer **solo-local**.
27
-
28
- > **Auto-detect note:** The solo-local path first checks if `scripts/land-branch.sh` exists and is executable. If present, the script handles the full squash-merge workflow. If absent, the built-in fallback sequence runs instead.
26
+ If unsure, prefer **solo-local**.
29
27
 
30
28
  ## Process
31
29
 
@@ -51,6 +49,10 @@ git log main...HEAD --oneline | grep -vE "^[a-f0-9]+ (feat|fix|docs|style|refact
51
49
 
52
50
  If REVIEW.md is missing or stale → run `security-review` inline. Findings block the merge unless documented in EXCEPTIONS.md.
53
51
 
52
+ ### 2b. Traceability gate
53
+
54
+ Run `gate-trace` before merge. FAIL blocks merge; CONCERNS requires explicit override in `specs/state.yaml` (`traceability_override: CONCERNS accepted, reason: <explanation>`). WAIVED if no matrix available.
55
+
54
56
  ### 3. Diff review
55
57
 
56
58
  - [ ] All commits intentional, no secrets, CONVENTIONS.md compliance
@@ -61,20 +63,14 @@ Options: **Release (solo-local)** / **Open PR** / **Keep branch** / **Discard**
61
63
 
62
64
  ### 5. Solo-local integrate
63
65
 
64
- Run `commit-message` to produce the squash commit subject. Then auto-detect the integration path:
66
+ Run `commit-message` for the squash subject, then land:
65
67
 
66
- **Path A — `scripts/land-branch.sh` exists (happy path):**
67
68
  ```bash
69
+ # Path A (preferred):
68
70
  bash scripts/land-branch.sh <task-slug> "feat(scope): description"
71
+ # Path B (fallback if land-branch.sh missing): see REFERENCE.md
69
72
  ```
70
73
 
71
- **Path B — `scripts/land-branch.sh` missing (fallback):**
72
- See [REFERENCE.md](REFERENCE.md)
73
-
74
- **Report which path was taken.** Print exactly:
75
- - `"used land-branch.sh"` if Path A
76
- - `"used fallback merge (land-branch.sh not found)"` if Path B
77
-
78
74
  ### 6. Create PR (team-pr only)
79
75
 
80
76
  See [REFERENCE.md](REFERENCE.md) for the full PR body template and gh commands.
@@ -34,6 +34,7 @@ Review answers "is the code good?"; Verify answers "does the built thing do what
34
34
  3. **AGENTS.md preflight** — before running default checks, call `bash scripts/bp-read-agents.sh` to detect project-specific commands. If `BP_PREFLIGHT` is set, run it instead of the default mechanical gates (or in addition to them if the project requires both). Output: `"Using preflight from AGENTS.md: <cmd>"`. Fall back to `CLAUDE.md` commands if AGENTS.md is absent.
35
35
  4. Mechanical gates: build → typecheck → lint → tests (from `CLAUDE.md` or AGENTS.md).
36
36
  5. **Security scan** — run `security-review` against the git diff (working tree vs merge-base). Parse findings report. If any HIGH findings with confidence ≥ 8 exist → **block the gate**. Write findings to `specs/security/REVIEW.md`. Allow documented exceptions via `specs/security/EXCEPTIONS.md`. MEDIUM/LOW findings warn but don't block.
37
+ 5a. **Blind-spot check** — run `bash scripts/check-blind-spots.sh`. This detects structural quality gaps (verify-gap, test-gap, stale-tag, etc.) beyond percentage coverage. If any HIGH-severity findings exist → **block the verify-work PASS gate**. Findings are written to `specs/blind-spots.json`. MEDIUM/LOW findings warn but don't block.
37
38
  6. **Step-by-step UAT** — one user-observable action at a time.
38
39
  7. **Gaps loop** — failures → log → `plan-work` → re-verify. Unaddressed HIGH findings from step 5 feed into this loop alongside other quality gaps.
39
40
 
@@ -0,0 +1,81 @@
1
+ ---
2
+ name: gate-trace
3
+ description: "\"Deterministic traceability quality gate — reads coverage matrix + blind-spot data, applies decision rules with oracle confidence downgrade, emits PASS/CONCERNS/FAIL/WAIVED verdict. Use before release-branch to gate merges on traceability.\"# story: e38s06"
4
+ model: haiku
5
+ ---
6
+
7
+
8
+ # Gate Trace
9
+
10
+ Deterministic quality gate that combines traceability coverage and blind-spot data into a single PASS/FAIL/CONCERNS/WAIVED decision before release.
11
+
12
+ ## Decision Rules
13
+
14
+ | Rule | Condition | Verdict |
15
+ |------|-----------|---------|
16
+ | R1 | Any undone story with 0 code tags | FAIL |
17
+ | R2 | Any story done but no verify evidence | CONCERNS |
18
+ | R3 | P0 story (top WSJF quartile) with 0% coverage | FAIL |
19
+ | R4 | Overall coverage < 60% | CONCERNS |
20
+ | R5 | Overall ≥ 80% + no critical gaps + all verify → PASS | PASS |
21
+
22
+ ## Oracle Confidence Downgrade
23
+
24
+ TEA-inspired: if trace links rely on heuristics rather than explicit tags, confidence drops.
25
+
26
+ | Heuristic Ratio | Downgrade |
27
+ |-----------------|-----------|
28
+ | > 50% links from heuristics (file-name or task-reference) | One level (PASS→CONCERNS, CONCERNS→FAIL) |
29
+ | > 80% links from heuristics | Two levels (PASS→FAIL, CONCERNS→FAIL) |
30
+
31
+ ## Process
32
+
33
+ 1. **Pre-flight:** Ensure `scripts/trace-stories.sh --json` has been run (produces `specs/traceability-matrix.json`). If not present, run it.
34
+ 2. Ensure `scripts/check-blind-spots.sh` has been run (produces `specs/blind-spots.json`). If not present, run it.
35
+ 3. Read `specs/traceability-matrix.json` and `specs/blind-spots.json`.
36
+ 4. Apply decision rules R1–R5 in order (first match wins).
37
+ 5. Apply oracle confidence downgrade based on the heuristic link ratio from the matrix's `oracle_stats`.
38
+ 6. Output verdict + rationale to stdout.
39
+ 7. Update `specs/execution-status.yaml` with gate-trace result.
40
+
41
+ ## Verdict Semantics
42
+
43
+ | Verdict | Meaning | Action |
44
+ |---------|---------|--------|
45
+ | PASS | All gates satisfied | Proceed with merge |
46
+ | CONCERNS | Non-critical issues found | Requires explicit human override in `state.yaml` |
47
+ | FAIL | Critical traceability gap | Block merge — fix gap first |
48
+ | WAIVED | Cannot evaluate (missing inputs) | Skip gate — data not available |
49
+
50
+ ## Output Format
51
+
52
+ ```yaml
53
+ gate_trace:
54
+ verdict: PASS|CONCERNS|FAIL|WAIVED
55
+ generated_at: "<ISO 8601>"
56
+ rationale: "<human-readable explanation>"
57
+ heuristic_ratio: <0.0–1.0>
58
+ downgrade_applied: <true|false>
59
+ ```
60
+
61
+ ## Integration Points
62
+
63
+ - **release-branch SKILL.md** — pre-PR gate (FAIL blocks merge).
64
+ - **sync-skills.yml** — CI gate (FAIL blocks pipeline).
65
+ - **verify-work SKILL.md** — runs blind-spot checks; gate-trace consumes the result.
66
+
67
+ ## References
68
+
69
+ - BMAD TEA traceability approach (market survey 2026-07-02).
70
+ - scripts/trace-stories.sh (e38s01) — produces traceability-matrix.json.
71
+ - scripts/check-blind-spots.sh (e38s04) — produces blind-spots.json.
72
+ - specs/execution-status.yaml — output target for gate result.
73
+
74
+ ## Verify
75
+
76
+ → verify: `test -f skills/gate-trace/SKILL.md && grep -q 'PASS.*CONCERNS.*FAIL.*WAIVED' skills/gate-trace/SKILL.md && echo "OK: gate-trace skill created" || echo "FAIL"`
77
+
78
+ ## Handoff
79
+
80
+ Gate: READY → next: release-branch (final step before merge)
81
+ Writes: state.yaml handoff.next_skill = release-branch
@@ -13,21 +13,19 @@ Finalize a completed feature branch: verify coverage gates, integrate onto `main
13
13
 
14
14
  ## Additional modes
15
15
 
16
- - `--hotfix`: Emergency fix. Cherry-pick to main plus immediate tag. Skip PR in solo profile.
17
- - `--squash-state`: Squashes all intermediate `chore(state):` commits on the feature branch into a single clean commit before merging. Use this to reduce noise in the main git repository history.
16
+ - `--hotfix`: Cherry-pick to main + tag. Skip PR in solo.
17
+ - `--squash-state`: Squash `chore(state):` commits before merge.
18
18
 
19
19
  ## Integrate mode
20
20
 
21
- Read `specs/state.yaml` key `workflow_mode` first (`team-pr` | `solo-git`). Fall back to sniffing `profiles/solo-git.md` only when the key is absent.
21
+ Read `specs/state.yaml` key `workflow_mode` (`team-pr` | `solo-git`). Fall back to `profiles/solo-git.md`.
22
22
 
23
23
  | Mode | When | Ship path |
24
24
  |------|------|-----------|
25
- | **solo-local** | `workflow_mode: solo-git` (or `profiles/solo-git.md` present as fallback) | Auto-detect: if `scripts/land-branch.sh` exists → use it; else → fallback (see Step 5) |
25
+ | **solo-local** | `workflow_mode: solo-git` | Auto: `scripts/land-branch.sh` if present, else fallback (Step 5) |
26
26
  | **team-pr** | `workflow_mode: team-pr` (default) | `gh pr create` → `gh pr merge --squash` |
27
27
 
28
- If unsure and working alone, prefer **solo-local**.
29
-
30
- > **Auto-detect note:** The solo-local path first checks if `scripts/land-branch.sh` exists and is executable. If present, the script handles the full squash-merge workflow. If absent, the built-in fallback sequence runs instead.
28
+ If unsure, prefer **solo-local**.
31
29
 
32
30
  ## Process
33
31
 
@@ -53,6 +51,10 @@ git log main...HEAD --oneline | grep -vE "^[a-f0-9]+ (feat|fix|docs|style|refact
53
51
 
54
52
  If REVIEW.md is missing or stale → run `security-review` inline. Findings block the merge unless documented in EXCEPTIONS.md.
55
53
 
54
+ ### 2b. Traceability gate
55
+
56
+ Run `gate-trace` before merge. FAIL blocks merge; CONCERNS requires explicit override in `specs/state.yaml` (`traceability_override: CONCERNS accepted, reason: <explanation>`). WAIVED if no matrix available.
57
+
56
58
  ### 3. Diff review
57
59
 
58
60
  - [ ] All commits intentional, no secrets, CONVENTIONS.md compliance
@@ -63,20 +65,14 @@ Options: **Release (solo-local)** / **Open PR** / **Keep branch** / **Discard**
63
65
 
64
66
  ### 5. Solo-local integrate
65
67
 
66
- Run `commit-message` to produce the squash commit subject. Then auto-detect the integration path:
68
+ Run `commit-message` for the squash subject, then land:
67
69
 
68
- **Path A — `scripts/land-branch.sh` exists (happy path):**
69
70
  ```bash
71
+ # Path A (preferred):
70
72
  bash scripts/land-branch.sh <task-slug> "feat(scope): description"
73
+ # Path B (fallback if land-branch.sh missing): see REFERENCE.md
71
74
  ```
72
75
 
73
- **Path B — `scripts/land-branch.sh` missing (fallback):**
74
- See [REFERENCE.md](REFERENCE.md)
75
-
76
- **Report which path was taken.** Print exactly:
77
- - `"used land-branch.sh"` if Path A
78
- - `"used fallback merge (land-branch.sh not found)"` if Path B
79
-
80
76
  ### 6. Create PR (team-pr only)
81
77
 
82
78
  See [REFERENCE.md](REFERENCE.md) for the full PR body template and gh commands.
@@ -36,6 +36,7 @@ Review answers "is the code good?"; Verify answers "does the built thing do what
36
36
  3. **AGENTS.md preflight** — before running default checks, call `bash scripts/bp-read-agents.sh` to detect project-specific commands. If `BP_PREFLIGHT` is set, run it instead of the default mechanical gates (or in addition to them if the project requires both). Output: `"Using preflight from AGENTS.md: <cmd>"`. Fall back to `CLAUDE.md` commands if AGENTS.md is absent.
37
37
  4. Mechanical gates: build → typecheck → lint → tests (from `CLAUDE.md` or AGENTS.md).
38
38
  5. **Security scan** — run `security-review` against the git diff (working tree vs merge-base). Parse findings report. If any HIGH findings with confidence ≥ 8 exist → **block the gate**. Write findings to `specs/security/REVIEW.md`. Allow documented exceptions via `specs/security/EXCEPTIONS.md`. MEDIUM/LOW findings warn but don't block.
39
+ 5a. **Blind-spot check** — run `bash scripts/check-blind-spots.sh`. This detects structural quality gaps (verify-gap, test-gap, stale-tag, etc.) beyond percentage coverage. If any HIGH-severity findings exist → **block the verify-work PASS gate**. Findings are written to `specs/blind-spots.json`. MEDIUM/LOW findings warn but don't block.
39
40
  6. **Step-by-step UAT** — one user-observable action at a time.
40
41
  7. **Gaps loop** — failures → log → `plan-work` → re-verify. Unaddressed HIGH findings from step 5 feed into this loop alongside other quality gaps.
41
42
 
package/CHANGELOG.md CHANGED
@@ -1,3 +1,22 @@
1
+ # [2.56.0](https://github.com/danielvm-git/bigpowers/compare/v2.55.0...v2.56.0) (2026-07-03)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * trim release-branch SKILL.md to 146 lines (cap 150) ([6c91813](https://github.com/danielvm-git/bigpowers/commit/6c91813012ce64b3e0fa90f3c11afa5b67559d9c))
7
+
8
+
9
+ ### Features
10
+
11
+ * **e38:** spec-to-code traceability gate — matrix, blind-spots, CI/CD integration ([ffeb843](https://github.com/danielvm-git/bigpowers/commit/ffeb8435a91ad2d278a490670bf2f1561df60135))
12
+
13
+ # [2.55.0](https://github.com/danielvm-git/bigpowers/compare/v2.54.0...v2.55.0) (2026-07-03)
14
+
15
+
16
+ ### Features
17
+
18
+ * **planning:** add e43 MCP Semantic Context Server (7 stories, 13 BCP) ([cf61d5c](https://github.com/danielvm-git/bigpowers/commit/cf61d5c23e20133fb07a9ee04f9a98dbdf9e12b8))
19
+
1
20
  # [2.54.0](https://github.com/danielvm-git/bigpowers/compare/v2.53.0...v2.54.0) (2026-07-03)
2
21
 
3
22
 
package/CLAUDE.md CHANGED
@@ -1,3 +1,5 @@
1
+ # story: e38s08
2
+
1
3
  # bigpowers — Claude Code
2
4
 
3
5
  Read CONVENTIONS.md before any GitHub or git operation.
@@ -21,6 +23,7 @@ Stack: Markdown / Bash (documentation-based; skills integrate with Claude Code,
21
23
  | CI platform | GitHub Actions (`.github/workflows/publish.yml`, `sync-skills.yml`) |
22
24
  | Compliance | `npm run compliance` |
23
25
  | Golden Suite | `bash scripts/run-golden-suite.sh` |
26
+ | Traceability | `bash scripts/trace-stories.sh --strict` | grep for story tags (traceability check) |
24
27
 
25
28
  ### Pre-Merge Checklist
26
29
 
package/CONVENTIONS.md CHANGED
@@ -1,3 +1,5 @@
1
+ # story: e38s08
2
+
1
3
  # Conventions
2
4
 
3
5
  ## Conventional Commits & Semantic Versioning
@@ -51,6 +53,7 @@ You are operating within the `bigpowers` spec-driven development methodology.
51
53
  - Use `investigate-bug` for bug reports before writing a fix.
52
54
  - **Verification Mandate:** Every story implementation MUST end with a step-by-step manual verification script provided to the user. You must wait for the user to confirm behavioral correctness (UAT) before declaring the story done or moving to the next.
53
55
  - **Verification:** You MUST verify every change with tests. Code generation without a corresponding plan in `specs/` is strictly forbidden.
56
+ - **Traceability Mandate:** Every story MUST have at least one `story: eNNsNN` tag in its implementing code or test file. `trace-stories.sh --strict` runs in CI to enforce this. Untagged stories fail the CI traceability gate.
54
57
  - **Stream Continuity:** When writing large files or long documents, you MUST output continuously in chunks of ~200 lines. Do not pause between sections. Continue immediately until complete. If you need time to process, emit a placeholder comment or heading rather than going silent to prevent stream idle timeouts.
55
58
 
56
59
  ## specs/ — All Planning Output Goes Here
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  ![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)
4
4
  ![npm version](https://img.shields.io/npm/v/bigpowers.svg)
5
- ![Skills](https://img.shields.io/badge/skills-72-brightgreen.svg)
5
+ ![Skills](https://img.shields.io/badge/skills-73-brightgreen.svg)
6
6
 
7
7
  **Agent skills synthesizing 17 years of software engineering discipline — from Clean Code to AI-native architecture — into a single, prescriptive methodology for solo developers.**
8
8
 
package/SKILL-INDEX.md CHANGED
@@ -3,7 +3,7 @@
3
3
  > **DO NOT EDIT** — This file is auto-generated by `scripts/generate-skill-index.sh`.
4
4
  > Edit `SKILL.md` source files or `skills-lock.json` instead. Run `bash scripts/sync-skills.sh` to regenerate.
5
5
 
6
- **Skills:** 72
6
+ **Skills:** 73
7
7
 
8
8
  ---
9
9
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bigpowers",
3
- "version": "2.54.0",
3
+ "version": "2.56.0",
4
4
  "description": "72 agent skills synthesizing 17 years of software engineering discipline into a prescriptive methodology for solo developers",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -0,0 +1,349 @@
1
+ #!/usr/bin/env bash
2
+ # story: e38s04
3
+ # check-blind-spots.sh — TEA-inspired heuristic blind-spot detector
4
+ # Reads execution-status.yaml + traceability-matrix.json, runs 6 structural
5
+ # quality checks beyond percentage coverage, and emits specs/blind-spots.json.
6
+ #
7
+ # Checks:
8
+ # a. verify-gap — story done but no verification evidence
9
+ # b. test-gap — code tagged but no test file references
10
+ # c. epic-orphan — capsule task with no story tag anywhere
11
+ # d. stale-tag — story done but tag still in code
12
+ # e. double-tag — same file tagged with multiple stories
13
+ # f. bootstrap-testless — new story without test-related tag or files
14
+ #
15
+ # Severities: HIGH / MEDIUM / LOW
16
+ #
17
+ # Usage:
18
+ # bash scripts/check-blind-spots.sh # full scan, emit JSON
19
+ # bash scripts/check-blind-spots.sh --help # this message
20
+ #
21
+ # Exit codes:
22
+ # 0 — no HIGH-severity findings
23
+ # 1 — one or more HIGH-severity findings (or input files missing)
24
+
25
+ set -euo pipefail
26
+
27
+ REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
28
+ BLIND_SPOTS_JSON="$REPO_ROOT/specs/blind-spots.json"
29
+ EXEC_STATUS="$REPO_ROOT/specs/execution-status.yaml"
30
+ MATRIX_JSON="$REPO_ROOT/specs/traceability-matrix.json"
31
+ VERIFICATIONS_DIR="$REPO_ROOT/specs/verifications"
32
+ EPICS_DIR="$REPO_ROOT/specs/epics"
33
+
34
+ while [[ $# -gt 0 ]]; do
35
+ case "$1" in
36
+ --help|-h)
37
+ cat <<'USAGE'
38
+ Usage: check-blind-spots.sh [flags]
39
+
40
+ Run 6 heuristic blind-spot checks on the codebase.
41
+
42
+ Flags:
43
+ --help Print this message and exit.
44
+
45
+ Checks:
46
+ verify-gap Story done, no verify evidence.
47
+ test-gap Code tagged, no test file references.
48
+ epic-orphan Capsule task with no story tag.
49
+ stale-tag Done story, tag still in code.
50
+ double-tag File tagged with multiple stories.
51
+ bootstrap-testless New story without test coverage.
52
+
53
+ Output: specs/blind-spots.json
54
+
55
+ Exit codes:
56
+ 0 No HIGH-severity findings.
57
+ 1 One or more HIGH-severity findings (or input files missing).
58
+ USAGE
59
+ exit 0
60
+ ;;
61
+ *)
62
+ echo "check-blind-spots.sh: unknown flag: $1" >&2
63
+ echo "Try --help for usage." >&2
64
+ exit 1
65
+ ;;
66
+ esac
67
+ done
68
+
69
+ # ---------------------------------------------------------------------------
70
+ # Input existence checks
71
+ # ---------------------------------------------------------------------------
72
+ if [[ ! -f "$EXEC_STATUS" ]]; then
73
+ echo "check-blind-spots.sh: execution-status.yaml: not found at $EXEC_STATUS" >&2
74
+ exit 1
75
+ fi
76
+
77
+ # ---------------------------------------------------------------------------
78
+ # Detector logic (Python stdlib only)
79
+ # ---------------------------------------------------------------------------
80
+ python3 - "$REPO_ROOT" "$BLIND_SPOTS_JSON" "$EXEC_STATUS" "$MATRIX_JSON" "$VERIFICATIONS_DIR" "$EPICS_DIR" <<'PYEOF'
81
+ import json, os, re, sys
82
+ from pathlib import Path
83
+ from datetime import datetime, timezone
84
+
85
+ ROOT = Path(sys.argv[1])
86
+ BLIND_SPOTS_JSON = Path(sys.argv[2])
87
+ EXEC_STATUS = Path(sys.argv[3])
88
+ MATRIX_JSON = Path(sys.argv[4])
89
+ VERIFICATIONS_DIR = Path(sys.argv[5])
90
+ EPICS_DIR = Path(sys.argv[6])
91
+
92
+ findings: list[dict] = []
93
+
94
+ # -----------------------------------------------------------------------
95
+ # Parse execution-status.yaml → flat dict of story_id → status
96
+ # -----------------------------------------------------------------------
97
+ def parse_exec_status(path: Path) -> dict[str, str]:
98
+ status: dict[str, str] = {}
99
+ if not path.exists():
100
+ return status
101
+ text = path.read_text(encoding="utf-8")
102
+ lines = text.splitlines()
103
+ in_dev_status = False
104
+ for line in lines:
105
+ stripped = line.strip()
106
+ if stripped.startswith("development_status:"):
107
+ in_dev_status = True
108
+ continue
109
+ if not in_dev_status:
110
+ # Stop if we hit another top-level key
111
+ if stripped and not stripped.startswith(" ") and not stripped.startswith("#"):
112
+ if ":" in stripped:
113
+ in_dev_status = False
114
+ continue
115
+ if ":" in stripped and not stripped.startswith("#"):
116
+ # Lines like ' e38s04: "done"'
117
+ m = re.match(r'\s+(\S+):\s*"([^"]*)"', stripped)
118
+ if m:
119
+ status[m.group(1)] = m.group(2)
120
+ return status
121
+
122
+ dev_status = parse_exec_status(EXEC_STATUS)
123
+
124
+ # -----------------------------------------------------------------------
125
+ # Read traceability matrix (if available)
126
+ # -----------------------------------------------------------------------
127
+ matrix_data: dict | None = None
128
+ if MATRIX_JSON.exists():
129
+ matrix_data = json.loads(MATRIX_JSON.read_text(encoding="utf-8"))
130
+
131
+ # Build indexes from matrix
132
+ tagged_files: dict[str, list[str]] = {} # story_id → [files]
133
+ file_story_counts: dict[str, set[str]] = {} # file → set of story_ids
134
+ if matrix_data:
135
+ for s in matrix_data.get("stories", []):
136
+ sid = s["id"]
137
+ for link in s.get("links", []):
138
+ f = link["file"]
139
+ tagged_files.setdefault(sid, []).append(f)
140
+ file_story_counts.setdefault(f, set()).add(sid)
141
+
142
+ # Enumerate all tracked code files (skip .git, node_modules, specs/)
143
+ CODE_EXTENSIONS = {".sh", ".py", ".js", ".ts", ".jsx", ".tsx", ".md", ".yaml", ".yml", ".cjs", ".mjs", ".json"}
144
+ SKIP_DIRS = {".git", "node_modules", ".cursor", ".gemini", ".pi", "specs", "dist", "build", "__pycache__", ".bigpowers"}
145
+
146
+ def is_code_file(p: Path) -> bool:
147
+ return p.suffix in CODE_EXTENSIONS and not any(s in p.parts for s in SKIP_DIRS)
148
+
149
+ all_code_files: list[str] = []
150
+ for root, dirs, files in os.walk(str(ROOT)):
151
+ # Prune skip dirs
152
+ dirs[:] = [d for d in dirs if d not in SKIP_DIRS]
153
+ rel_root = str(Path(root).relative_to(ROOT))
154
+ for fname in files:
155
+ fpath = Path(root) / fname
156
+ if is_code_file(fpath):
157
+ all_code_files.append(str(fpath.relative_to(ROOT)))
158
+
159
+ # -----------------------------------------------------------------------
160
+ # Helper: find test files for a given code file
161
+ # -----------------------------------------------------------------------
162
+ TEST_PATTERNS = [
163
+ re.compile(r"(^|/)test(s)?/", re.IGNORECASE),
164
+ re.compile(r"(^|/)__tests__/", re.IGNORECASE),
165
+ re.compile(r"\.test\.", re.IGNORECASE),
166
+ re.compile(r"\.spec\.", re.IGNORECASE),
167
+ re.compile(r"_test\.", re.IGNORECASE),
168
+ re.compile(r"test_", re.IGNORECASE),
169
+ ]
170
+
171
+ def has_test_files(code_files: list[str]) -> bool:
172
+ """Check if any file in the repo looks like a test for the given code files."""
173
+ for cf in code_files:
174
+ cf_path = Path(cf)
175
+ cf_dir = cf_path.parent
176
+ cf_stem = cf_path.stem
177
+ for tf in all_code_files:
178
+ tp = Path(tf)
179
+ # Same directory test file
180
+ if tp.parent == cf_dir:
181
+ for pat in TEST_PATTERNS:
182
+ if pat.search(tp.name) and cf_stem in tp.name:
183
+ return True
184
+ # Tests dir sibling
185
+ test_dir_names = ["tests", "test", "__tests__"]
186
+ for tdn in test_dir_names:
187
+ test_dir = cf_dir / tdn
188
+ if str(test_dir) in tf:
189
+ if cf_stem in tp.name:
190
+ return True
191
+ return False
192
+
193
+ # -----------------------------------------------------------------------
194
+ # Check A: verify-gap — story done but no verify evidence
195
+ # -----------------------------------------------------------------------
196
+ for sid, sstatus in dev_status.items():
197
+ if sstatus == "done":
198
+ verify_file = VERIFICATIONS_DIR / f"{sid}-verify.yaml"
199
+ if not verify_file.exists():
200
+ findings.append({
201
+ "check": "verify-gap",
202
+ "story_id": sid,
203
+ "severity": "HIGH",
204
+ "description": f"Story {sid} is marked done but no verification evidence exists at specs/verifications/{sid}-verify.yaml",
205
+ "remediation": f"Run verify-work for {sid} or create the verification evidence file"
206
+ })
207
+
208
+ # -----------------------------------------------------------------------
209
+ # Check B: test-gap — code tagged but no test file references
210
+ # -----------------------------------------------------------------------
211
+ for sid, files in tagged_files.items():
212
+ if dev_status.get(sid) in ("done", "active"):
213
+ if not has_test_files(files):
214
+ # Only flag if there are actual code files (not just docs)
215
+ code_only = [f for f in files if Path(f).suffix in {".sh", ".py", ".js", ".ts", ".jsx", ".tsx"} and "SKILL.md" not in f]
216
+ if code_only:
217
+ findings.append({
218
+ "check": "test-gap",
219
+ "story_id": sid,
220
+ "severity": "MEDIUM",
221
+ "description": f"Story {sid} has {len(code_only)} tagged code file(s) with no matching test files",
222
+ "remediation": f"Add test coverage for the tagged files: {', '.join(code_only[:3])}"
223
+ })
224
+
225
+ # -----------------------------------------------------------------------
226
+ # Check C: epic-orphan — capsule task with no story tag in any code file
227
+ # -----------------------------------------------------------------------
228
+ if EPICS_DIR.exists():
229
+ for epic_dir in sorted(EPICS_DIR.iterdir()):
230
+ if not epic_dir.is_dir() or epic_dir.name == "archive":
231
+ continue
232
+ epic_yaml = epic_dir / "epic.yaml"
233
+ if not epic_yaml.exists():
234
+ continue
235
+ # Extract story IDs from epic capsule task files
236
+ for task_file in sorted(epic_dir.glob("e*[0-9]-tasks.yaml")):
237
+ # e.g., e38s04-tasks.yaml → e38s04
238
+ sid_match = re.match(r"(e\d+s\d+)", task_file.name)
239
+ if not sid_match:
240
+ continue
241
+ sid = sid_match.group(1)
242
+ # Check if story has any tagged files (explicit or heuristic)
243
+ sstatus = dev_status.get(sid, "backlog")
244
+ if sstatus in ("done", "active") and sid not in tagged_files:
245
+ findings.append({
246
+ "check": "epic-orphan",
247
+ "story_id": sid,
248
+ "severity": "LOW",
249
+ "description": f"Story {sid} has capsule tasks but no story tags found in any code file",
250
+ "remediation": f"Add `// story: {sid}` tags to implementing files"
251
+ })
252
+
253
+ # -----------------------------------------------------------------------
254
+ # Check D: stale-tag — story done but tag still in code
255
+ # -----------------------------------------------------------------------
256
+ stale_from_matrix: set[str] = set()
257
+ if matrix_data:
258
+ stale_from_matrix = set(matrix_data.get("summary", {}).get("stale_tags", []))
259
+
260
+ for sid in stale_from_matrix:
261
+ findings.append({
262
+ "check": "stale-tag",
263
+ "story_id": sid,
264
+ "severity": "LOW",
265
+ "description": f"Story {sid} is marked done but still has story tags in code",
266
+ "remediation": f"Remove `// story: {sid}` tags from files or confirm the story should remain done"
267
+ })
268
+
269
+ # -----------------------------------------------------------------------
270
+ # Check E: double-tag — same file tagged with multiple stories
271
+ # -----------------------------------------------------------------------
272
+ for fpath, sids in file_story_counts.items():
273
+ if len(sids) > 1:
274
+ findings.append({
275
+ "check": "double-tag",
276
+ "file": fpath,
277
+ "severity": "MEDIUM",
278
+ "description": f"File '{fpath}' is tagged with multiple stories: {', '.join(sorted(sids))}",
279
+ "remediation": "Review whether this file genuinely implements multiple stories. If it's a shared utility, this is acceptable."
280
+ })
281
+
282
+ # -----------------------------------------------------------------------
283
+ # Check F: bootstrap-testless — new story (active/recent) without test evidence
284
+ # -----------------------------------------------------------------------
285
+ recent_threshold = 5 # flag active/done stories in the last 5 stories if no tests
286
+ active_and_recent = []
287
+ for sid in sorted(dev_status.keys()):
288
+ if dev_status[sid] in ("active",):
289
+ active_and_recent.append(sid)
290
+
291
+ for sid in active_and_recent:
292
+ # Check if story has tagged code AND no test files for those
293
+ if sid in tagged_files:
294
+ code_files = tagged_files[sid]
295
+ code_only = [f for f in code_files if Path(f).suffix in {".sh", ".py", ".js", ".ts", ".jsx", ".tsx"} and "SKILL.md" not in f]
296
+ if code_only and not has_test_files(code_files):
297
+ findings.append({
298
+ "check": "bootstrap-testless",
299
+ "story_id": sid,
300
+ "severity": "HIGH",
301
+ "description": f"Active story {sid} has {len(code_only)} tagged code file(s) but no test files detected",
302
+ "remediation": f"Add test files for: {', '.join(code_only[:3])}"
303
+ })
304
+
305
+ # -----------------------------------------------------------------------
306
+ # De-duplicate findings (same check + story_id)
307
+ # -----------------------------------------------------------------------
308
+ seen: set[tuple] = set()
309
+ deduped: list[dict] = []
310
+ for f in findings:
311
+ key = (f["check"], f.get("story_id", f.get("file", "")))
312
+ if key not in seen:
313
+ seen.add(key)
314
+ deduped.append(f)
315
+ findings = deduped
316
+
317
+ # -----------------------------------------------------------------------
318
+ # Emit blind-spots.json
319
+ # -----------------------------------------------------------------------
320
+ high_count = sum(1 for f in findings if f["severity"] == "HIGH")
321
+ medium_count = sum(1 for f in findings if f["severity"] == "MEDIUM")
322
+ low_count = sum(1 for f in findings if f["severity"] == "LOW")
323
+
324
+ blind_spots = {
325
+ "generated_at": datetime.now(timezone.utc).isoformat(),
326
+ "version": "1.0",
327
+ "summary": {
328
+ "total_findings": len(findings),
329
+ "high": high_count,
330
+ "medium": medium_count,
331
+ "low": low_count
332
+ },
333
+ "findings": findings
334
+ }
335
+
336
+ BLIND_SPOTS_JSON.parent.mkdir(parents=True, exist_ok=True)
337
+ BLIND_SPOTS_JSON.write_text(json.dumps(blind_spots, indent=2), encoding="utf-8")
338
+
339
+ # Print summary to stdout
340
+ print(f"check-blind-spots.sh: {len(findings)} findings ({high_count} HIGH, {medium_count} MEDIUM, {low_count} LOW)")
341
+ for f in findings:
342
+ print(f" [{f['severity']}] {f['check']}: {f['description'][:100]}")
343
+
344
+ if high_count > 0:
345
+ print(f"\n⚠️ {high_count} HIGH-severity finding(s) — review specs/blind-spots.json")
346
+ sys.exit(1)
347
+
348
+ sys.exit(0)
349
+ PYEOF
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env bash
2
+ # story: e38s01
2
3
  # trace-stories.sh — deterministic spec-to-code coverage matrix builder
3
4
  # Parses specs/release-plan.yaml + specs/execution-status.yaml, greps the
4
5
  # codebase for story: eNNsNN tags, cross-references, and emits a coverage matrix.
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: build-epic
3
+ # story: e38s02
3
4
  model: sonnet
4
5
  effort: standard
5
6
  description: Eight-step epic build cycle — reads state.yaml, execution-status.yaml, and one epic capsule; updates status via bp-yaml-set or direct edit. Resume mode runs one step per invocation. Use instead of ad-hoc execute-plan for release work.
@@ -0,0 +1,82 @@
1
+ ---
2
+ name: gate-trace
3
+ description: "Deterministic traceability quality gate — reads coverage matrix + blind-spot data, applies decision rules with oracle confidence downgrade, emits PASS/CONCERNS/FAIL/WAIVED verdict. Use before release-branch to gate merges on traceability."
4
+ # story: e38s06
5
+ model: haiku
6
+ effort: light
7
+ ---
8
+
9
+ # Gate Trace
10
+
11
+ Deterministic quality gate that combines traceability coverage and blind-spot data into a single PASS/FAIL/CONCERNS/WAIVED decision before release.
12
+
13
+ ## Decision Rules
14
+
15
+ | Rule | Condition | Verdict |
16
+ |------|-----------|---------|
17
+ | R1 | Any undone story with 0 code tags | FAIL |
18
+ | R2 | Any story done but no verify evidence | CONCERNS |
19
+ | R3 | P0 story (top WSJF quartile) with 0% coverage | FAIL |
20
+ | R4 | Overall coverage < 60% | CONCERNS |
21
+ | R5 | Overall ≥ 80% + no critical gaps + all verify → PASS | PASS |
22
+
23
+ ## Oracle Confidence Downgrade
24
+
25
+ TEA-inspired: if trace links rely on heuristics rather than explicit tags, confidence drops.
26
+
27
+ | Heuristic Ratio | Downgrade |
28
+ |-----------------|-----------|
29
+ | > 50% links from heuristics (file-name or task-reference) | One level (PASS→CONCERNS, CONCERNS→FAIL) |
30
+ | > 80% links from heuristics | Two levels (PASS→FAIL, CONCERNS→FAIL) |
31
+
32
+ ## Process
33
+
34
+ 1. **Pre-flight:** Ensure `scripts/trace-stories.sh --json` has been run (produces `specs/traceability-matrix.json`). If not present, run it.
35
+ 2. Ensure `scripts/check-blind-spots.sh` has been run (produces `specs/blind-spots.json`). If not present, run it.
36
+ 3. Read `specs/traceability-matrix.json` and `specs/blind-spots.json`.
37
+ 4. Apply decision rules R1–R5 in order (first match wins).
38
+ 5. Apply oracle confidence downgrade based on the heuristic link ratio from the matrix's `oracle_stats`.
39
+ 6. Output verdict + rationale to stdout.
40
+ 7. Update `specs/execution-status.yaml` with gate-trace result.
41
+
42
+ ## Verdict Semantics
43
+
44
+ | Verdict | Meaning | Action |
45
+ |---------|---------|--------|
46
+ | PASS | All gates satisfied | Proceed with merge |
47
+ | CONCERNS | Non-critical issues found | Requires explicit human override in `state.yaml` |
48
+ | FAIL | Critical traceability gap | Block merge — fix gap first |
49
+ | WAIVED | Cannot evaluate (missing inputs) | Skip gate — data not available |
50
+
51
+ ## Output Format
52
+
53
+ ```yaml
54
+ gate_trace:
55
+ verdict: PASS|CONCERNS|FAIL|WAIVED
56
+ generated_at: "<ISO 8601>"
57
+ rationale: "<human-readable explanation>"
58
+ heuristic_ratio: <0.0–1.0>
59
+ downgrade_applied: <true|false>
60
+ ```
61
+
62
+ ## Integration Points
63
+
64
+ - **release-branch SKILL.md** — pre-PR gate (FAIL blocks merge).
65
+ - **sync-skills.yml** — CI gate (FAIL blocks pipeline).
66
+ - **verify-work SKILL.md** — runs blind-spot checks; gate-trace consumes the result.
67
+
68
+ ## References
69
+
70
+ - BMAD TEA traceability approach (market survey 2026-07-02).
71
+ - scripts/trace-stories.sh (e38s01) — produces traceability-matrix.json.
72
+ - scripts/check-blind-spots.sh (e38s04) — produces blind-spots.json.
73
+ - specs/execution-status.yaml — output target for gate result.
74
+
75
+ ## Verify
76
+
77
+ → verify: `test -f skills/gate-trace/SKILL.md && grep -q 'PASS.*CONCERNS.*FAIL.*WAIVED' skills/gate-trace/SKILL.md && echo "OK: gate-trace skill created" || echo "FAIL"`
78
+
79
+ ## Handoff
80
+
81
+ Gate: READY → next: release-branch (final step before merge)
82
+ Writes: state.yaml handoff.next_skill = release-branch
@@ -1,3 +1,4 @@
1
+ <!-- story: e38s07 -->
1
2
  ---
2
3
  name: release-branch
3
4
  model: haiku
@@ -13,21 +14,19 @@ Finalize a completed feature branch: verify coverage gates, integrate onto `main
13
14
 
14
15
  ## Additional modes
15
16
 
16
- - `--hotfix`: Emergency fix. Cherry-pick to main plus immediate tag. Skip PR in solo profile.
17
- - `--squash-state`: Squashes all intermediate `chore(state):` commits on the feature branch into a single clean commit before merging. Use this to reduce noise in the main git repository history.
17
+ - `--hotfix`: Cherry-pick to main + tag. Skip PR in solo.
18
+ - `--squash-state`: Squash `chore(state):` commits before merge.
18
19
 
19
20
  ## Integrate mode
20
21
 
21
- Read `specs/state.yaml` key `workflow_mode` first (`team-pr` | `solo-git`). Fall back to sniffing `profiles/solo-git.md` only when the key is absent.
22
+ Read `specs/state.yaml` key `workflow_mode` (`team-pr` | `solo-git`). Fall back to `profiles/solo-git.md`.
22
23
 
23
24
  | Mode | When | Ship path |
24
25
  |------|------|-----------|
25
- | **solo-local** | `workflow_mode: solo-git` (or `profiles/solo-git.md` present as fallback) | Auto-detect: if `scripts/land-branch.sh` exists → use it; else → fallback (see Step 5) |
26
+ | **solo-local** | `workflow_mode: solo-git` | Auto: `scripts/land-branch.sh` if present, else fallback (Step 5) |
26
27
  | **team-pr** | `workflow_mode: team-pr` (default) | `gh pr create` → `gh pr merge --squash` |
27
28
 
28
- If unsure and working alone, prefer **solo-local**.
29
-
30
- > **Auto-detect note:** The solo-local path first checks if `scripts/land-branch.sh` exists and is executable. If present, the script handles the full squash-merge workflow. If absent, the built-in fallback sequence runs instead.
29
+ If unsure, prefer **solo-local**.
31
30
 
32
31
  ## Process
33
32
 
@@ -53,6 +52,10 @@ git log main...HEAD --oneline | grep -vE "^[a-f0-9]+ (feat|fix|docs|style|refact
53
52
 
54
53
  If REVIEW.md is missing or stale → run `security-review` inline. Findings block the merge unless documented in EXCEPTIONS.md.
55
54
 
55
+ ### 2b. Traceability gate
56
+
57
+ Run `gate-trace` before merge. FAIL blocks merge; CONCERNS requires explicit override in `specs/state.yaml` (`traceability_override: CONCERNS accepted, reason: <explanation>`). WAIVED if no matrix available.
58
+
56
59
  ### 3. Diff review
57
60
 
58
61
  - [ ] All commits intentional, no secrets, CONVENTIONS.md compliance
@@ -63,20 +66,14 @@ Options: **Release (solo-local)** / **Open PR** / **Keep branch** / **Discard**
63
66
 
64
67
  ### 5. Solo-local integrate
65
68
 
66
- Run `commit-message` to produce the squash commit subject. Then auto-detect the integration path:
69
+ Run `commit-message` for the squash subject, then land:
67
70
 
68
- **Path A — `scripts/land-branch.sh` exists (happy path):**
69
71
  ```bash
72
+ # Path A (preferred):
70
73
  bash scripts/land-branch.sh <task-slug> "feat(scope): description"
74
+ # Path B (fallback if land-branch.sh missing): see REFERENCE.md
71
75
  ```
72
76
 
73
- **Path B — `scripts/land-branch.sh` missing (fallback):**
74
- See [REFERENCE.md](REFERENCE.md)
75
-
76
- **Report which path was taken.** Print exactly:
77
- - `"used land-branch.sh"` if Path A
78
- - `"used fallback merge (land-branch.sh not found)"` if Path B
79
-
80
77
  ### 6. Create PR (team-pr only)
81
78
 
82
79
  See [REFERENCE.md](REFERENCE.md) for the full PR body template and gh commands.
@@ -1,3 +1,4 @@
1
+ <!-- story: e38s05 -->
1
2
  ---
2
3
  name: verify-work
3
4
  description: Multi-phase UAT gate — cold-start smoke, build, typecheck, lint, tests, step-by-step manual verification, gaps-closure loop. Use after execute-plan or develop-tdd, before audit-code.
@@ -36,6 +37,7 @@ Review answers "is the code good?"; Verify answers "does the built thing do what
36
37
  3. **AGENTS.md preflight** — before running default checks, call `bash scripts/bp-read-agents.sh` to detect project-specific commands. If `BP_PREFLIGHT` is set, run it instead of the default mechanical gates (or in addition to them if the project requires both). Output: `"Using preflight from AGENTS.md: <cmd>"`. Fall back to `CLAUDE.md` commands if AGENTS.md is absent.
37
38
  4. Mechanical gates: build → typecheck → lint → tests (from `CLAUDE.md` or AGENTS.md).
38
39
  5. **Security scan** — run `security-review` against the git diff (working tree vs merge-base). Parse findings report. If any HIGH findings with confidence ≥ 8 exist → **block the gate**. Write findings to `specs/security/REVIEW.md`. Allow documented exceptions via `specs/security/EXCEPTIONS.md`. MEDIUM/LOW findings warn but don't block.
40
+ 5a. **Blind-spot check** — run `bash scripts/check-blind-spots.sh`. This detects structural quality gaps (verify-gap, test-gap, stale-tag, etc.) beyond percentage coverage. If any HIGH-severity findings exist → **block the verify-work PASS gate**. Findings are written to `specs/blind-spots.json`. MEDIUM/LOW findings warn but don't block.
39
41
  6. **Step-by-step UAT** — one user-observable action at a time.
40
42
  7. **Gaps loop** — failures → log → `plan-work` → re-verify. Unaddressed HIGH findings from step 5 feed into this loop alongside other quality gaps.
41
43
 
package/skills-lock.json CHANGED
@@ -23,7 +23,7 @@
23
23
  },
24
24
  "build-epic": {
25
25
  "description": "Eight-step epic build cycle — reads state.yaml, execution-status.yaml, and one epic capsule; updates status via bp-yaml-set or direct edit. Resume mode runs one step per invocation. Use instead of ad-hoc execute-plan for release work.",
26
- "sha256": "3d2337356c24ee55",
26
+ "sha256": "5abf6858c529996c",
27
27
  "path": "skills/build-epic/SKILL.md"
28
28
  },
29
29
  "change-request": {
@@ -126,6 +126,11 @@
126
126
  "sha256": "ce4781244b970a14",
127
127
  "path": "skills/fix-bug/SKILL.md"
128
128
  },
129
+ "gate-trace": {
130
+ "description": "\"Deterministic traceability quality gate — reads coverage matrix + blind-spot data, applies decision rules with oracle confidence downgrade, emits PASS/CONCERNS/FAIL/WAIVED verdict. Use before release-branch to gate merges on traceability.\"# story: e38s06",
131
+ "sha256": "15ca25acd70b90dd",
132
+ "path": "skills/gate-trace/SKILL.md"
133
+ },
129
134
  "grill-me": {
130
135
  "description": "Interactive assumption-surfacing Q&A that stress-tests a plan through relentless questioning until every decision is resolved. Use when user wants to challenge a plan, validate decisions from conversation/context, or mentions \"grill me\". For doc-grounded variant, use grill-with-docs.",
131
136
  "sha256": "8ef90da0f127f2fd",
@@ -213,7 +218,7 @@
213
218
  },
214
219
  "release-branch": {
215
220
  "description": "Make the merge/PR/keep/discard decision for a feature branch, verify coverage gates, create the PR with gh, and clean up the worktree. Use when a feature is done and ready to ship, or when user says \"release\", \"merge\", or \"open a PR\".",
216
- "sha256": "170166b534697f55",
221
+ "sha256": "354267f0f4b593b5",
217
222
  "path": "skills/release-branch/SKILL.md"
218
223
  },
219
224
  "request-review": {
@@ -338,7 +343,7 @@
338
343
  },
339
344
  "verify-work": {
340
345
  "description": "Multi-phase UAT gate — cold-start smoke, build, typecheck, lint, tests, step-by-step manual verification, gaps-closure loop. Use after execute-plan or develop-tdd, before audit-code.",
341
- "sha256": "9176edfb256f07bc",
346
+ "sha256": "b2828b807467e5c7",
342
347
  "path": "skills/verify-work/SKILL.md"
343
348
  },
344
349
  "visual-dashboard": {