@qball-inc/the-bulwark 1.2.1 → 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.
- package/.claude-plugin/plugin.json +50 -42
- package/CHANGELOG.md +72 -30
- package/CONTRIBUTING.md +52 -0
- package/README.md +97 -373
- package/hooks/hooks.json +100 -88
- package/package.json +46 -46
- package/scripts/hooks/bulwark-permission-hook.sh +306 -0
- package/skills/anthropic-validator/SKILL.md +6 -0
- package/skills/anthropic-validator/references/skills-checklist.md +2 -1
- package/skills/anthropic-validator/references/skills-validation.md +2 -1
- package/skills/assertion-patterns/SKILL.md +3 -0
- package/skills/bug-magnet-data/SKILL.md +3 -0
- package/skills/bulwark-brainstorm/SKILL.md +8 -0
- package/skills/bulwark-research/SKILL.md +8 -0
- package/skills/bulwark-scaffold/SKILL.md +75 -2
- package/skills/bulwark-statusline/SKILL.md +3 -1
- package/skills/bulwark-verify/SKILL.md +9 -0
- package/skills/code-review/SKILL.md +72 -89
- package/skills/code-review/references/diagnostic-schema.md +119 -0
- package/skills/component-patterns/SKILL.md +3 -0
- package/skills/continuous-feedback/SKILL.md +9 -0
- package/skills/create-skill/SKILL.md +9 -0
- package/skills/create-subagent/SKILL.md +7 -0
- package/skills/fix-bug/SKILL.md +4 -0
- package/skills/governance-protocol/SKILL.md +1 -0
- package/skills/init/SKILL.md +6 -0
- package/skills/issue-debugging/SKILL.md +3 -0
- package/skills/mock-detection/SKILL.md +5 -0
- package/skills/pipeline-templates/SKILL.md +3 -0
- package/skills/plan-creation/SKILL.md +10 -0
- package/skills/plan-to-tasks/SKILL.md +8 -0
- package/skills/product-ideation/SKILL.md +6 -0
- package/skills/session-handoff/SKILL.md +4 -0
- package/skills/setup-lsp/SKILL.md +6 -0
- package/skills/spec-drift-check/SKILL.md +8 -5
- package/skills/subagent-output-templating/SKILL.md +2 -0
- package/skills/subagent-prompting/SKILL.md +2 -0
- package/skills/test-audit/SKILL.md +10 -0
- package/skills/test-classification/SKILL.md +5 -0
- 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
|
```
|
|
@@ -5,7 +5,13 @@ user-invocable: true
|
|
|
5
5
|
skills:
|
|
6
6
|
- subagent-prompting
|
|
7
7
|
- subagent-output-templating
|
|
8
|
-
|
|
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
|
-
├──
|
|
83
|
-
├──
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
├──
|
|
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
|
|
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
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
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
|
-
|
|
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
|
---
|
package/skills/fix-bug/SKILL.md
CHANGED
|
@@ -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
|
---
|
package/skills/init/SKILL.md
CHANGED
|
@@ -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
|
---
|