@qball-inc/the-bulwark 1.2.0 → 1.3.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.
Files changed (40) hide show
  1. package/.claude-plugin/plugin.json +50 -42
  2. package/CHANGELOG.md +102 -30
  3. package/CONTRIBUTING.md +52 -0
  4. package/README.md +97 -328
  5. package/hooks/hooks.json +100 -88
  6. package/package.json +46 -46
  7. package/scripts/hooks/bulwark-permission-hook.sh +306 -0
  8. package/skills/anthropic-validator/SKILL.md +6 -0
  9. package/skills/anthropic-validator/references/skills-checklist.md +2 -1
  10. package/skills/anthropic-validator/references/skills-validation.md +2 -1
  11. package/skills/assertion-patterns/SKILL.md +3 -0
  12. package/skills/bug-magnet-data/SKILL.md +3 -0
  13. package/skills/bulwark-brainstorm/SKILL.md +8 -0
  14. package/skills/bulwark-research/SKILL.md +8 -0
  15. package/skills/bulwark-scaffold/SKILL.md +75 -2
  16. package/skills/bulwark-statusline/SKILL.md +3 -1
  17. package/skills/bulwark-verify/SKILL.md +9 -0
  18. package/skills/code-review/SKILL.md +72 -89
  19. package/skills/code-review/references/diagnostic-schema.md +119 -0
  20. package/skills/component-patterns/SKILL.md +3 -0
  21. package/skills/continuous-feedback/SKILL.md +9 -0
  22. package/skills/create-skill/SKILL.md +9 -0
  23. package/skills/create-subagent/SKILL.md +7 -0
  24. package/skills/fix-bug/SKILL.md +4 -0
  25. package/skills/governance-protocol/SKILL.md +1 -0
  26. package/skills/init/SKILL.md +6 -0
  27. package/skills/issue-debugging/SKILL.md +3 -0
  28. package/skills/mock-detection/SKILL.md +5 -0
  29. package/skills/pipeline-templates/SKILL.md +3 -0
  30. package/skills/plan-creation/SKILL.md +10 -0
  31. package/skills/plan-to-tasks/SKILL.md +8 -0
  32. package/skills/product-ideation/SKILL.md +6 -0
  33. package/skills/session-handoff/SKILL.md +4 -0
  34. package/skills/setup-lsp/SKILL.md +6 -0
  35. package/skills/spec-drift-check/SKILL.md +8 -5
  36. package/skills/subagent-output-templating/SKILL.md +2 -0
  37. package/skills/subagent-prompting/SKILL.md +2 -0
  38. package/skills/test-audit/SKILL.md +10 -0
  39. package/skills/test-classification/SKILL.md +5 -0
  40. package/skills/test-fixture-creation/SKILL.md +6 -0
@@ -1,5 +1,13 @@
1
1
  ---
2
2
  name: bulwark-research
3
+ allowed-tools:
4
+ - AskUserQuestion
5
+ - Bash
6
+ - Glob
7
+ - Read
8
+ - Skill
9
+ - Task
10
+ - Write
3
11
  version: 1.0.1
4
12
  description: Structured multi-viewpoint research using 5 parallel Sonnet sub-agents. Use when deep research is needed on a complex topic before implementation planning.
5
13
  user-invocable: true
@@ -2,8 +2,15 @@
2
2
  name: bulwark-scaffold
3
3
  description: Initialize Bulwark infrastructure in a project: language-aware Justfile (8 langs), bun + eval-framework toolchain, logs/ subdirectories, and optional hooks.
4
4
  when_to_use: Use when the user asks to set up Bulwark in a project, scaffold a Justfile, configure Bulwark hooks, or initialize the eval framework. Do NOT auto-invoke during normal development — this writes files, runs installers, and modifies .gitignore. Also invoked by the Bulwark init skill when scaffolding is selected.
5
- argument-hint: "[--force] [--no-hooks] [--dry-run] [--lang=<node|python|rust|go|kotlin|swift|shell|generic>]"
5
+ argument-hint: "[--force] [--no-hooks] [--with-permission-hook] [--dry-run] [--lang=<node|python|rust|go|kotlin|swift|shell|generic>]"
6
6
  user-invocable: true
7
+ allowed-tools:
8
+ - AskUserQuestion
9
+ - Bash
10
+ - Edit
11
+ - Glob
12
+ - Read
13
+ - Write
7
14
  version: 1.0.1
8
15
  author: "Ashay Kubal @ Qball Inc."
9
16
  ---
@@ -20,7 +27,7 @@ Initialize Bulwark infrastructure in a project by generating Justfile templates,
20
27
 
21
28
  You are the orchestrator. Follow every item in order. Do NOT return to the user until all applicable items are checked.
22
29
 
23
- - [ ] **Step 1 — Parse arguments**: `--force`, `--no-hooks`, `--dry-run`, `--lang=<...>` extracted from `$ARGUMENTS`
30
+ - [ ] **Step 1 — Parse arguments**: `--force`, `--no-hooks`, `--with-permission-hook`, `--dry-run`, `--lang=<...>` extracted from `$ARGUMENTS`
24
31
  - [ ] **Step 2 — Detect project language**: If `--lang` not supplied, project files inspected (`package.json`, `pyproject.toml`, `Cargo.toml`, `go.mod`, etc.); defaults to `generic` when no signal found
25
32
  - [ ] **Step 3 — `just` runtime check**: `command -v just` runs; if missing, follow Step 3 install path
26
33
  - [ ] **Step 3.5a — `bun` runtime check**: `bash <resolved-installer-path> --verify` invoked (NOT `command -v bun` — that bypasses version check); follow Step 3.5 install path if exit non-zero
@@ -31,6 +38,7 @@ You are the orchestrator. Follow every item in order. Do NOT return to the user
31
38
  - [ ] **Step 6 — `logs/` subdirectories**: `diagnostics/`, `validations/`, `debug-reports/` created
32
39
  - [ ] **Step 7 — `.gitignore`**: Bulwark log patterns appended idempotently
33
40
  - [ ] **Step 8 — Hooks**: If plugin-level hooks active, SKIP `.claude/settings.json` hook injection (anti-duplication)
41
+ - [ ] **Step 8a — Permission hook (opt-in)**: ONLY if `--with-permission-hook` — confirm trust (AskUserQuestion), merge `PreToolUse` entry into `.claude/settings.json`, copy `bulwark-permission-hook.sh`, record choice. Default (no flag) = NOT installed
34
42
  - [ ] **Step 9 — Scaffold log**: `logs/scaffold-{ts}.yaml` written with top-level `reviewed_files: [...]` (Stop-hook contract)
35
43
  - [ ] **Step 10 — Report results**: User-facing summary emitted listing files written, installer outcomes, and any skipped steps
36
44
 
@@ -45,6 +53,7 @@ You are the orchestrator. Follow every item in order. Do NOT return to the user
45
53
  **Options:**
46
54
  - `--force` - Overwrite existing Justfile (creates backup)
47
55
  - `--no-hooks` - Skip hook configuration (hooks are generated by default)
56
+ - `--with-permission-hook` - Also install the opt-in PreToolUse permission-bypass hook (auto-approves Bulwark's own bundled-asset reads/edits/scripts). Default: NOT installed
48
57
  - `--dry-run` - Show what would be generated without writing files
49
58
  - `--lang=<node|python|rust|go|kotlin|swift|shell|generic>` - Override language detection
50
59
 
@@ -52,6 +61,7 @@ You are the orchestrator. Follow every item in order. Do NOT return to the user
52
61
  - `/bulwark-scaffold` - Full scaffold with Justfile + logs/ + hooks
53
62
  - `/bulwark-scaffold --force` - Overwrite existing Justfile
54
63
  - `/bulwark-scaffold --no-hooks` - Skip hook configuration
64
+ - `/bulwark-scaffold --with-permission-hook` - Scaffold + install the opt-in permission-bypass hook
55
65
  - `/bulwark-scaffold --dry-run` - Preview changes
56
66
 
57
67
  ---
@@ -63,6 +73,7 @@ You are the orchestrator. Follow every item in order. Do NOT return to the user
63
73
  Extract options from `$ARGUMENTS`:
64
74
  - `--force` → FORCE_OVERWRITE=true
65
75
  - `--no-hooks` → SKIP_HOOKS=true
76
+ - `--with-permission-hook` → WITH_PERMISSION_HOOK=true (default: false)
66
77
  - `--dry-run` → DRY_RUN=true
67
78
  - `--lang=X` → LANG_OVERRIDE=X
68
79
 
@@ -194,6 +205,10 @@ If DRY_RUN is true, display preview and exit:
194
205
  - scripts/hooks/enforce-quality.sh
195
206
  - scripts/hooks/suggest-pipeline-stop.sh
196
207
  {ENDIF}
208
+ {IF WITH_PERMISSION_HOOK}
209
+ - scripts/hooks/bulwark-permission-hook.sh
210
+ - .claude/settings.json (PreToolUse permission-bypass entry — merged independently of --no-hooks)
211
+ {ENDIF}
197
212
 
198
213
  **Would update:**
199
214
  - .gitignore (add Bulwark patterns)
@@ -365,6 +380,56 @@ Check if `.claude/settings.json` exists:
365
380
 
366
381
  Create parent directories as needed (`mkdir -p`).
367
382
 
383
+ ### Step 8a: Optional Permission-Bypass Hook (opt-in)
384
+
385
+ ONLY if `WITH_PERMISSION_HOOK` is true (the `--with-permission-hook` flag). Default (no flag) → **SKIP this entire step**; the permission hook is NOT installed and nothing below runs. Set `PERMISSION_HOOK=not_requested` and continue to Step 9.
386
+
387
+ This installs `bulwark-permission-hook.sh` as a **project-scope** `PreToolUse` hook that auto-approves Read/Edit/Bash operations on **Bulwark's own bundled assets** — skipping the per-file permission prompts CC raises on plugin-bundled files the user already trusted at install. It is a scoped workaround for upstream CC permission bugs (retire when `#29285` lands; see `docs/reference/hooks.md`).
388
+
389
+ **Runs independently of `SKIP_HOOKS`** — a user may pass `--no-hooks --with-permission-hook` (no governance hooks, but yes permission-bypass). If Step 8 was skipped and `.claude/settings.json` does not exist, create it here.
390
+
391
+ **1. Confirm the trust decision (REQUIRED — security-sensitive).** Installing a permission-bypass hook is a trust decision, so confirm explicitly even though the flag was passed. Use **AskUserQuestion**:
392
+
393
+ > **Install the Bulwark permission-bypass hook?**
394
+ > It auto-approves Read/Edit/Bash on Bulwark's **own bundled assets** (under the plugin cache root / `${CLAUDE_PLUGIN_ROOT}`), so you stop seeing permission prompts for them. Everything else still prompts as normal. **Writes are never auto-approved.** Path-traversal that escapes the plugin root is denied. Requires trusting Bulwark at install level.
395
+ >
396
+ > Options: **Install** / **Skip**
397
+
398
+ If the user picks **Skip** (or declines): do NOT install; set `PERMISSION_HOOK=declined`; continue to Step 9.
399
+
400
+ **2. On Install:**
401
+
402
+ **a. Idempotency check.** If `.claude/settings.json` already registers `bulwark-permission-hook.sh` under `PreToolUse`, skip re-adding (set `PERMISSION_HOOK=already_present`) and proceed to step (c) to ensure the script copy exists.
403
+
404
+ **b. Merge the `PreToolUse` entry** into `.claude/settings.json` (create the file and/or the `hooks` key if absent; preserve all existing settings — same merge discipline as Step 8):
405
+
406
+ ```json
407
+ {
408
+ "hooks": {
409
+ "PreToolUse": [
410
+ {
411
+ "matcher": "Read|Edit|Bash",
412
+ "hooks": [
413
+ {
414
+ "type": "command",
415
+ "command": "${CLAUDE_PROJECT_DIR}/scripts/hooks/bulwark-permission-hook.sh",
416
+ "timeout": 5
417
+ }
418
+ ]
419
+ }
420
+ ]
421
+ }
422
+ }
423
+ ```
424
+
425
+ **c. Copy the hook script:** copy `scripts/hooks/bulwark-permission-hook.sh` to `${CLAUDE_PROJECT_DIR}/scripts/hooks/` and ensure it is executable (`chmod +x`). Create parent dirs with `mkdir -p`.
426
+
427
+ **d.** Set `PERMISSION_HOOK=installed`.
428
+
429
+ **Why there is no env-var gate in the project entry:** the hook self-gates on `$CLAUDE_PLUGIN_OPTION_ENABLE_PERMISSION_BYPASS`, but project-scope installs do not set that var — the script treats an **unset** gate as **active** (`bulwark-permission-hook.sh` opt-in gate), so the entry's presence in `settings.json` IS the opt-in. (The env-var gate only matters for the plugin-level install, which defaults it to `false`.)
430
+
431
+ **3. Record the choice** in the scaffold log (Step 9): add `scripts/hooks/bulwark-permission-hook.sh` to `reviewed_files` when copied, and set `actions.permission_hook.action` to the `PERMISSION_HOOK` value.
432
+
368
433
  ### Step 9: Write Scaffold Log
369
434
 
370
435
  Write to `logs/scaffold-{YYYYMMDD-HHMMSS}.yaml`:
@@ -410,6 +475,11 @@ actions:
410
475
  action: created|merged|skipped
411
476
  path: .claude/settings.json
412
477
  skipped_reason: {reason if skipped}
478
+ permission_hook:
479
+ # --with-permission-hook opt-in (Step 8a). not_requested when the flag is absent.
480
+ action: installed|declined|already_present|not_requested
481
+ path: .claude/settings.json
482
+ script: scripts/hooks/bulwark-permission-hook.sh
413
483
 
414
484
  summary: |
415
485
  Scaffold complete for {DETECTED_LANG} project.
@@ -427,6 +497,7 @@ Present summary to user:
427
497
  **logs/:** Created with subdirectories (diagnostics, validations, debug-reports)
428
498
  **.gitignore:** {updated|created|unchanged}
429
499
  **Hooks:** {created|merged|skipped (--no-hooks)}
500
+ **Permission hook:** {installed|declined|already present|not installed}
430
501
  **Governance:** {installed|skipped} - Protocol injected at session start
431
502
 
432
503
  Run `just` to see available recipes:
@@ -469,6 +540,7 @@ invocation: "{full command}"
469
540
  inputs:
470
541
  force: {true|false}
471
542
  no_hooks: {true|false}
543
+ with_permission_hook: {true|false}
472
544
  dry_run: {true|false}
473
545
  lang_override: {value or null}
474
546
  detection:
@@ -479,5 +551,6 @@ outputs:
479
551
  logs_created: {true|false}
480
552
  gitignore_updated: {true|false}
481
553
  hooks_configured: {true|false}
554
+ permission_hook_configured: {true|false}
482
555
  errors: []
483
556
  ```
@@ -6,9 +6,11 @@ argument-hint: "<init|minimal|developer|cost>"
6
6
  arguments: subcommand
7
7
  user-invocable: true
8
8
  allowed-tools:
9
+ - AskUserQuestion
9
10
  - Bash
10
- - Read
11
11
  - Edit
12
+ - Read
13
+ - Task
12
14
  version: 1.0.2
13
15
  author: "Ashay Kubal @ Qball Inc."
14
16
  ---
@@ -6,6 +6,15 @@ skills:
6
6
  - assertion-patterns
7
7
  - component-patterns
8
8
  - bug-magnet-data
9
+ allowed-tools:
10
+ - AskUserQuestion
11
+ - Bash
12
+ - Glob
13
+ - Grep
14
+ - Read
15
+ - Skill
16
+ - Task
17
+ - Write
9
18
  version: 1.0.1
10
19
  author: "Ashay Kubal @ Qball Inc."
11
20
  ---
@@ -5,7 +5,13 @@ user-invocable: true
5
5
  skills:
6
6
  - subagent-prompting
7
7
  - subagent-output-templating
8
- version: 1.1.0
8
+ allowed-tools:
9
+ - Bash
10
+ - Glob
11
+ - Grep
12
+ - Read
13
+ - Write
14
+ version: 1.2.0
9
15
  author: "Ashay Kubal @ Qball Inc."
10
16
  ---
11
17
 
@@ -43,6 +49,7 @@ This skill references supporting files. Understanding what's required vs optiona
43
49
  | **Pattern references** | `references/{section}-patterns.md` | **REQUIRED** | Always load for each enabled section |
44
50
  | **Framework patterns** | `frameworks/{detected}.md` | **CONDITIONALLY REQUIRED** | If framework detected → MUST load; if not detected → skip |
45
51
  | **Examples** | `examples/anti-patterns/*.ts`, `examples/recommended/*.ts` | OPTIONAL | For calibration on ambiguous cases; kept for model portability |
52
+ | **Diagnostic schema** | `references/diagnostic-schema.md` | **REQUIRED for Phase 3** | When emitting the diagnostic log (full schema, field rules, examples, Stage-5 aggregation) |
46
53
 
47
54
  **Fallback behavior:**
48
55
  - If framework detected → Loading `frameworks/{name}.md` is REQUIRED
@@ -78,21 +85,31 @@ This skill references supporting files. Understanding what's required vs optiona
78
85
  **CRITICAL**: All three phases are REQUIRED. Do not skip any phase.
79
86
 
80
87
  ```
81
- Phase 1: Static Analysis (Deterministic)
82
- ├── Run: just typecheckcapture output
83
- ├── Run: just lint capture output
84
- └── If failures: STOP, return to user (fail fast)
85
-
86
- Phase 2: LLM Review (Judgment-Based)
87
- ├── Load references/{section}-patterns.md for each enabled section (REQUIRED)
88
+ Phase 1: Static Analysis (Deterministic, language-aware)
89
+ ├── For each file in scope, detect language from extension run matching recipe(s):
90
+ ├── .ts/.tsx/.js/.jsx just typecheck ; just lint
91
+ │ ├── .py → just typecheck-py ; just lint-py
92
+ │ ├── .sh/.bash → just lint (shellcheck)
93
+ │ ├── .json → just validate-json
94
+ ├── .yaml/.yml → just validate-yaml
95
+ │ └── (other/unknown) → just typecheck ; just lint (project default)
96
+ ├── Tool present AND reports problems → STOP, return to user (fail fast)
97
+ └── Tool absent (recipe prints "… not installed; skipping") → log warning, continue (graceful degrade)
98
+
99
+ Phase 2: LLM Review (Judgment-Based, applicability-gated)
100
+ ├── Detect each file's language (extends Framework Detection — same mechanism, per-file)
101
+ ├── For each (section, language): consult the Language Applicability table
102
+ │ ├── ✅ apply normally · partial apply + Caveat · ❌ skip (record skip_rationale)
103
+ ├── Load references/{section}-patterns.md for each APPLIED section (REQUIRED)
88
104
  ├── If framework detected: Load frameworks/{detected}.md (REQUIRED)
89
105
  ├── If no framework detected: Skip framework patterns
90
- ├── Apply each enabled section using loaded patterns
106
+ ├── Apply each applied section using loaded patterns
91
107
  └── Output findings to user
92
108
 
93
109
  Phase 3: Write Diagnostic Log (REQUIRED)
94
110
  ├── Write to: logs/diagnostics/code-review-{timestamp}.yaml
95
- ├── Include: invocation details, static analysis results, findings summary
111
+ ├── Include: invocation details, static analysis results, findings summary,
112
+ │ language_applicability (per-file applied/skipped sections)
96
113
  └── This phase is MANDATORY - do not return to user without completing it
97
114
  ```
98
115
 
@@ -121,6 +138,25 @@ Each section is independently referenceable by pipeline agents via `--section=<n
121
138
  | Linting | Style requiring judgment | Complexity, naming, structure | Important-Suggestion |
122
139
  | Coding Standards | Conventions & architecture | Patterns, documentation | Important-Suggestion |
123
140
 
141
+ ### Language Applicability
142
+
143
+ Not every section applies to every language. Before running a section on a file, detect the file's language (see [Framework Detection](#framework-detection)) and consult this table. This prevents hallucinated findings (e.g., "type safety" on a bash script) and wasted passes.
144
+
145
+ | Section | TS/JS | Python | Bash | JSON/YAML | Rust | Go | Java/Kotlin | Reason |
146
+ |---------|-------|--------|------|-----------|------|-----|-------------|--------|
147
+ | **Security** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | OWASP concepts are language-agnostic |
148
+ | **Type Safety** | ✅ | partial | ❌ | ❌ | ✅ | ✅ | ✅ | TS/Python/Rust/Go/JVM have type systems; bash + data formats don't |
149
+ | **Linting** | ✅ | ✅ | ✅ if shellcheck | partial | ✅ if clippy | ✅ if golangci-lint | ✅ if ktlint | Always conceptually applicable; tool varies |
150
+ | **Coding Standards** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | CS1–CS4 from Rules.md are language-agnostic |
151
+
152
+ **Section-selection rule** — for each file in scope:
153
+ 1. Detect language from file extension (this extends [Framework Detection](#framework-detection) — same mechanism, file-level granularity).
154
+ 2. For each of the 4 sections, look up the (section, language) cell:
155
+ - **✅** — apply the section normally.
156
+ - **partial** — apply with reduced scope and attach a `Caveat` to any finding (e.g., Python type hints are optional, not enforced; data formats have schema-shaped structure, not a type system).
157
+ - **❌** — skip the section; record the file + skipped section in the Phase 3 diagnostic's `language_applicability.sections_skipped` with a `skip_rationale`.
158
+ 3. Record applied + skipped sections per file in the Phase 3 diagnostic (`language_applicability` field — see [Diagnostic Output](#diagnostic-output-required)).
159
+
124
160
  ---
125
161
 
126
162
  ## Security
@@ -298,6 +334,26 @@ fastapi → fastapi
298
334
  (none of above) → (no framework)
299
335
  ```
300
336
 
337
+ ### Language Detection (Per-File)
338
+
339
+ Framework detection above is **project-level** (which `frameworks/{name}.md` to load). Language detection is **file-level**: it drives the Phase 1 recipe to run and the Language Applicability lookup (which sections apply). It **extends** this mechanism — same detection pass, finer granularity — rather than introducing a parallel detection paradigm.
340
+
341
+ ```
342
+ extension → language
343
+ ──────────────────────────────────────────────
344
+ .ts .tsx .js .jsx .mjs .cjs → typescript/javascript
345
+ .py .pyi → python
346
+ .sh .bash → bash
347
+ .json → json (data format)
348
+ .yaml .yml → yaml (data format)
349
+ .rs → rust
350
+ .go → go
351
+ .java .kt .kts → java/kotlin
352
+ (unrecognized) → project default (apply all sections)
353
+ ```
354
+
355
+ For each file: detect language → run the matching Phase 1 recipe → gate each section through the [Language Applicability](#language-applicability) table.
356
+
301
357
  ### Override
302
358
  Use `--framework=<name>` to override detection.
303
359
 
@@ -393,86 +449,13 @@ Write diagnostic output to:
393
449
  logs/diagnostics/code-review-{timestamp}.yaml
394
450
  ```
395
451
 
396
- Format:
397
- ```yaml
398
- diagnostic:
399
- skill: code-review
400
- timestamp: 2026-01-31T12:00:00Z
401
- invocation:
402
- mode: comprehensive | quick
403
- sections_run: [security, type_safety, linting, standards]
404
- framework_detected: react
405
- framework_override: null
406
- files_count: 5
407
- lines_total: 450
408
- static_analysis:
409
- typecheck: passed | failed | skipped
410
- lint: passed | failed | skipped
411
- findings_summary:
412
- critical: 1
413
- important: 3
414
- suggestion: 5
415
- duration_ms: 1200
416
- # Files reviewed (top-level field — consumed by the Stop hook for per-file
417
- # pipeline-recursion suppression). MUST be a flat list of paths relative
418
- # to ${CLAUDE_PROJECT_DIR}. Empty list `[]` is valid if the diagnostic
419
- # was emitted with no specific file scope. Missing field = strict mode
420
- # disables suppression for this log.
421
- reviewed_files:
422
- - src/auth/token.ts
423
- - src/api/users.ts
424
-
425
- # Followup edits expected (top-level field — consumed by the Stop hook
426
- # grace-window logic, P10.22). OPTIONAL list-of-mappings. Emit one entry
427
- # per file that received at least one critical or important finding.
428
- # Subsequent edits to a listed file within grace_window_seconds of this
429
- # log being written are treated as pre-covered (no re-fire).
430
- followup_edits_expected:
431
- - file: src/auth/token.ts
432
- grace_window_seconds: 1800
433
- finding_ids: [SEC-001]
434
- rationale: "1 critical (SQL injection); user-applied fix expected within grace window"
435
- ```
436
-
437
- ---
438
-
439
- ## Followup Edits Expected (Stop Hook Grace Window — P10.22)
440
-
441
- **Purpose**: When a code-review run produces actionable findings (severity `critical` or `important`), the user typically applies fixes immediately after reviewing the output. Without this metadata, those fix-edits trigger a fresh Stop hook fire because the pipeline log was written BEFORE the fix-edits — recursion. The `followup_edits_expected` field tells the Stop hook coverage check that edits to the listed files within the grace window are pre-covered.
442
-
443
- **When to emit** — emit one entry per file with at least one finding of severity `critical` or `important`. Files with `suggestion`-only findings do NOT need a followup entry (suggestions are cosmetic and user-driven).
444
-
445
- **Field schema**:
446
- - `file` (required) — path relative to `${CLAUDE_PROJECT_DIR}`. Must match exactly the path used in `reviewed_files` for the same file.
447
- - `grace_window_seconds` (optional, default 1800) — duration in seconds after this log is written during which subsequent edits to the file are treated as covered. 1800 (30 min) accommodates user deliberation + multi-fix application.
448
- - `finding_ids` (optional, informational) — list of finding identifiers driving the followup expectation. Used for diagnostic clarity; not consulted by coverage logic.
449
- - `rationale` (optional, informational) — human-readable explanation. Surfaced in diagnostic output.
450
-
451
- **When NOT to emit** — if a review pass produces zero `critical` or `important` findings, omit the field entirely (or emit `followup_edits_expected: []`). Suggestions-only output should NOT register followup expectations.
452
-
453
- **Example**:
454
- ```yaml
455
- followup_edits_expected:
456
- - file: src/auth/token.ts
457
- grace_window_seconds: 1800
458
- finding_ids: [SEC-001]
459
- rationale: "1 critical SQL injection finding; user-applied fix expected"
460
- - file: src/api/users.ts
461
- grace_window_seconds: 1800
462
- finding_ids: [TYPE-001, SEC-002]
463
- rationale: "1 important type-safety + 1 important auth check"
464
- ```
465
-
466
- **Pipeline-stage emission**: when code-review runs as a pipeline (`SecurityReviewer |> TypeSafetyReviewer |> LintReviewer |> StandardsReviewer |> ReviewSynthesizer`), each section reviewer emits its own `followup_edits_expected` in its sectional output (per `templates/output-pipeline.yaml`). The orchestrator's Stage 5 ReviewSynthesizer aggregates across all 4 reviewer logs into the consolidated `logs/diagnostics/code-review-{timestamp}.yaml`.
467
-
468
- **Stage 5 aggregation algorithm** — consolidate the 4 sectional `followup_edits_expected` lists into one top-level list:
469
- 1. **Group by `file`** (string equality on path). For each unique file mentioned in any of the 4 reviewer logs:
470
- 2. **Union `finding_ids`** across all reviewer entries for that file (deduplicate; preserve order: security first, then type_safety, linting, standards).
471
- 3. **Max `grace_window_seconds`** — take the largest grace window declared by any reviewer for that file. Reviewers with stricter (smaller) windows are subsumed by reviewers with longer windows.
472
- 4. **Concatenate `rationale`** with `; ` separator, prefixed by section name (e.g., `"security: 1 critical (SQL inj); type_safety: 1 important (any usage)"`).
473
- 5. **Skip files with zero entries** — if no reviewer emitted a followup for a file, do not include it in the synthesized list.
452
+ The log MUST include these top-level fields:
453
+ - `diagnostic` — skill / timestamp / invocation / static_analysis / findings_summary.
454
+ - `reviewed_files` — flat list of reviewed paths relative to `${CLAUDE_PROJECT_DIR}` (Stop-hook per-file suppression contract; `[]` is valid, missing field = strict no-suppress).
455
+ - `language_applicability` (P10.21) — per-file `detected_language` + `sections_applied` / `sections_skipped` (+ `skip_rationale`); record `partial` by suffixing the section (e.g. `type_safety_partial`).
456
+ - `followup_edits_expected` (P10.22) — one entry per file with a `critical`/`important` finding; omit or `[]` for suggestions-only runs.
474
457
 
475
- Emit the aggregated list as the top-level `followup_edits_expected` field of the synthesis log. The Stop hook's `coverage_check.py:parse_followup_edits_expected()` reads this consolidated field directly; per-reviewer logs are also scanned independently, so partial coverage is preserved if synthesis is skipped.
458
+ **Full schema, field rules, worked examples, and the pipeline Stage-5 aggregation algorithm live in [`references/diagnostic-schema.md`](references/diagnostic-schema.md) load it when emitting Phase 3 output.**
476
459
 
477
460
  ---
478
461
 
@@ -0,0 +1,119 @@
1
+ # Diagnostic Schema (Phase 3 Output)
2
+
3
+ Full schema, field rules, and examples for the code-review Phase 3 diagnostic log. Load this when emitting diagnostic output. The SKILL.md `## Diagnostic Output` section carries the binding contract (where to write + which top-level fields are mandatory); this file is the detailed reference.
4
+
5
+ Write diagnostic output to: `logs/diagnostics/code-review-{timestamp}.yaml` (ISO-8601 timestamp, hyphens for filename safety).
6
+
7
+ ---
8
+
9
+ ## Full Format
10
+
11
+ ```yaml
12
+ diagnostic:
13
+ skill: code-review
14
+ timestamp: 2026-01-31T12:00:00Z
15
+ invocation:
16
+ mode: comprehensive | quick
17
+ sections_run: [security, type_safety, linting, standards]
18
+ framework_detected: react
19
+ framework_override: null
20
+ files_count: 5
21
+ lines_total: 450
22
+ static_analysis:
23
+ typecheck: passed | failed | skipped
24
+ lint: passed | failed | skipped
25
+ findings_summary:
26
+ critical: 1
27
+ important: 3
28
+ suggestion: 5
29
+ duration_ms: 1200
30
+
31
+ # Files reviewed (top-level field — consumed by the Stop hook for per-file
32
+ # pipeline-recursion suppression). MUST be a flat list of paths relative
33
+ # to ${CLAUDE_PROJECT_DIR}. Empty list `[]` is valid if the diagnostic
34
+ # was emitted with no specific file scope. Missing field = strict mode
35
+ # disables suppression for this log.
36
+ reviewed_files:
37
+ - src/auth/token.ts
38
+ - src/api/users.ts
39
+
40
+ # Language applicability (top-level field — P10.21). Per-file record of which
41
+ # review sections were applied vs skipped, the detected language, and a rationale
42
+ # for any skip. Lets pipeline orchestration + audits confirm that, e.g., Type
43
+ # Safety was deliberately skipped on a bash file rather than silently missed.
44
+ # `partial` is recorded by suffixing the section name (e.g., type_safety_partial).
45
+ language_applicability:
46
+ - file: scripts/foo.py
47
+ detected_language: python
48
+ sections_applied: [security, type_safety_partial, linting, standards]
49
+ sections_skipped: []
50
+ - file: scripts/foo.sh
51
+ detected_language: bash
52
+ sections_applied: [security, linting, standards]
53
+ sections_skipped: [type_safety]
54
+ skip_rationale: "Bash has no static type system"
55
+
56
+ # Followup edits expected (top-level field — consumed by the Stop hook
57
+ # grace-window logic, P10.22). OPTIONAL list-of-mappings. Emit one entry
58
+ # per file that received at least one critical or important finding.
59
+ # Subsequent edits to a listed file within grace_window_seconds of this
60
+ # log being written are treated as pre-covered (no re-fire).
61
+ followup_edits_expected:
62
+ - file: src/auth/token.ts
63
+ grace_window_seconds: 1800
64
+ finding_ids: [SEC-001]
65
+ rationale: "1 critical (SQL injection); user-applied fix expected within grace window"
66
+ ```
67
+
68
+ ---
69
+
70
+ ## Followup Edits Expected (Stop Hook Grace Window — P10.22)
71
+
72
+ **Purpose**: When a code-review run produces actionable findings (severity `critical` or `important`), the user typically applies fixes immediately after reviewing the output. Without this metadata, those fix-edits trigger a fresh Stop hook fire because the pipeline log was written BEFORE the fix-edits — recursion. The `followup_edits_expected` field tells the Stop hook coverage check that edits to the listed files within the grace window are pre-covered.
73
+
74
+ **When to emit** — emit one entry per file with at least one finding of severity `critical` or `important`. Files with `suggestion`-only findings do NOT need a followup entry (suggestions are cosmetic and user-driven).
75
+
76
+ **Field schema**:
77
+ - `file` (required) — path relative to `${CLAUDE_PROJECT_DIR}`. Must match exactly the path used in `reviewed_files` for the same file.
78
+ - `grace_window_seconds` (optional, default 1800) — duration in seconds after this log is written during which subsequent edits to the file are treated as covered. 1800 (30 min) accommodates user deliberation + multi-fix application.
79
+ - `finding_ids` (optional, informational) — list of finding identifiers driving the followup expectation. Used for diagnostic clarity; not consulted by coverage logic.
80
+ - `rationale` (optional, informational) — human-readable explanation. Surfaced in diagnostic output.
81
+
82
+ **When NOT to emit** — if a review pass produces zero `critical` or `important` findings, omit the field entirely (or emit `followup_edits_expected: []`). Suggestions-only output should NOT register followup expectations.
83
+
84
+ **Example**:
85
+ ```yaml
86
+ followup_edits_expected:
87
+ - file: src/auth/token.ts
88
+ grace_window_seconds: 1800
89
+ finding_ids: [SEC-001]
90
+ rationale: "1 critical SQL injection finding; user-applied fix expected"
91
+ - file: src/api/users.ts
92
+ grace_window_seconds: 1800
93
+ finding_ids: [TYPE-001, SEC-002]
94
+ rationale: "1 important type-safety + 1 important auth check"
95
+ ```
96
+
97
+ **Pipeline-stage emission**: when code-review runs as a pipeline (`SecurityReviewer |> TypeSafetyReviewer |> LintReviewer |> StandardsReviewer |> ReviewSynthesizer`), each section reviewer emits its own `followup_edits_expected` in its sectional output (per `templates/output-pipeline.yaml`). The orchestrator's Stage 5 ReviewSynthesizer aggregates across all 4 reviewer logs into the consolidated `logs/diagnostics/code-review-{timestamp}.yaml`.
98
+
99
+ **Stage 5 aggregation algorithm** — consolidate the 4 sectional `followup_edits_expected` lists into one top-level list:
100
+ 1. **Group by `file`** (string equality on path). For each unique file mentioned in any of the 4 reviewer logs:
101
+ 2. **Union `finding_ids`** across all reviewer entries for that file (deduplicate; preserve order: security first, then type_safety, linting, standards).
102
+ 3. **Max `grace_window_seconds`** — take the largest grace window declared by any reviewer for that file. Reviewers with stricter (smaller) windows are subsumed by reviewers with longer windows.
103
+ 4. **Concatenate `rationale`** with `; ` separator, prefixed by section name (e.g., `"security: 1 critical (SQL inj); type_safety: 1 important (any usage)"`).
104
+ 5. **Skip files with zero entries** — if no reviewer emitted a followup for a file, do not include it in the synthesized list.
105
+
106
+ Emit the aggregated list as the top-level `followup_edits_expected` field of the synthesis log. The Stop hook's `coverage_check.py:parse_followup_edits_expected()` reads this consolidated field directly; per-reviewer logs are also scanned independently, so partial coverage is preserved if synthesis is skipped.
107
+
108
+ ---
109
+
110
+ ## Language Applicability (P10.21)
111
+
112
+ Per-file record of which review sections ran. Shape:
113
+ - `file` — path relative to `${CLAUDE_PROJECT_DIR}` (match `reviewed_files`).
114
+ - `detected_language` — from file extension (see SKILL.md `## Framework Detection` → Language Detection).
115
+ - `sections_applied` — list of applied sections; record `partial` applicability by suffixing the section name (e.g., `type_safety_partial`).
116
+ - `sections_skipped` — list of skipped sections.
117
+ - `skip_rationale` (when any section skipped) — one-line reason (e.g., `"Bash has no static type system"`).
118
+
119
+ In **pipeline-stage** output (`templates/output-pipeline.yaml`), each reviewer records ITS single section's per-file `decision` (applied | partial | skipped); ReviewSynthesizer (Stage 5) consolidates these into the `sections_applied`/`sections_skipped` shape above.
@@ -2,6 +2,9 @@
2
2
  name: component-patterns
3
3
  description: Per-component-type verification approaches. Use when generating verification scripts for different component types.
4
4
  user-invocable: false
5
+ allowed-tools:
6
+ - Read
7
+ - Write
5
8
  version: 1.0.0
6
9
  author: "Ashay Kubal @ Qball Inc."
7
10
  ---
@@ -5,6 +5,15 @@ user-invocable: true
5
5
  argument-hint: "<target-skill-or-path> [--sources <paths>] [--since <session-N>]"
6
6
  skills:
7
7
  - subagent-prompting
8
+ allowed-tools:
9
+ - AskUserQuestion
10
+ - Bash
11
+ - Glob
12
+ - Grep
13
+ - Read
14
+ - Skill
15
+ - Task
16
+ - Write
8
17
  version: 1.0.0
9
18
  author: "Ashay Kubal @ Qball Inc."
10
19
  ---
@@ -1,5 +1,14 @@
1
1
  ---
2
2
  name: create-skill
3
+ allowed-tools:
4
+ - AskUserQuestion
5
+ - Bash
6
+ - Glob
7
+ - Grep
8
+ - Read
9
+ - Skill
10
+ - Task
11
+ - Write
3
12
  version: 1.2.5
4
13
  author: "Ashay Kubal @ Qball Inc."
5
14
  description: Generates Claude Code skills from requirements using adaptive interview, complexity classification, and iterative validation. Use when creating new skills, scaffolding skill structure, or generating skills with sub-agent orchestration.
@@ -6,6 +6,13 @@ argument-hint: "<description-or-name> [--doc <requirements-path>]"
6
6
  skills:
7
7
  - subagent-prompting
8
8
  - anthropic-validator
9
+ allowed-tools:
10
+ - AskUserQuestion
11
+ - Bash
12
+ - Read
13
+ - Skill
14
+ - Task
15
+ - Write
9
16
  version: 1.0.0
10
17
  author: "Ashay Kubal @ Qball Inc."
11
18
  ---
@@ -2,6 +2,10 @@
2
2
  name: fix-bug
3
3
  description: Run the Fix Validation pipeline to investigate, fix, and validate a bug. Ensures deterministic pipeline execution with IssueAnalyzer, FixWriter, TestWriter (conditional), TestAudit (conditional), and FixValidator stages.
4
4
  user-invocable: true
5
+ allowed-tools:
6
+ - Read
7
+ - Skill
8
+ - Task
5
9
  version: 1.0.0
6
10
  author: "Ashay Kubal @ Qball Inc."
7
11
  ---
@@ -2,6 +2,7 @@
2
2
  name: governance-protocol
3
3
  description: Session governance protocol injected at startup via SessionStart hook
4
4
  user-invocable: false
5
+ allowed-tools: []
5
6
  version: 1.0.0
6
7
  author: "Ashay Kubal @ Qball Inc."
7
8
  ---
@@ -3,6 +3,12 @@ name: init
3
3
  description: Initialize, verify, or update Bulwark governance in a project. Sets up CLAUDE.md, rules.md, and optional tooling (statusline, LSP, scaffold). --update reviews canonical template changes interactively per-section.
4
4
  user-invocable: true
5
5
  argument-hint: "[--scope=project|user] [--verify | --update] [target-dir]"
6
+ allowed-tools:
7
+ - AskUserQuestion
8
+ - Bash
9
+ - Read
10
+ - Skill
11
+ - Write
6
12
  version: 1.2.0
7
13
  author: "Ashay Kubal @ Qball Inc."
8
14
  ---
@@ -2,6 +2,9 @@
2
2
  name: issue-debugging
3
3
  description: Systematic methodology for issue debugging including root cause analysis, impact mapping, tiered validation plans, and confidence assessment. Use when analyzing bugs, fixing issues, or validating fixes.
4
4
  user-invocable: false
5
+ allowed-tools:
6
+ - Read
7
+ - Write
5
8
  version: 1.0.0
6
9
  author: "Ashay Kubal @ Qball Inc."
7
10
  ---
@@ -2,6 +2,11 @@
2
2
  name: mock-detection
3
3
  description: Deep mock appropriateness analysis for Test Audit pipeline
4
4
  user-invocable: false
5
+ allowed-tools:
6
+ - Bash
7
+ - Read
8
+ - Task
9
+ - Write
5
10
  version: 1.0.1
6
11
  author: "Ashay Kubal @ Qball Inc."
7
12
  ---