Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
15ff640
docs(topics): lock bug-finding-skill interview Brief
claude Aug 23, 2026
d33af74
docs(topics): fold final audit-round resolutions into bug-finding Brief
claude Aug 23, 2026
b6fb072
docs(topics): draft bug-finding plan + design early-exit resolution
claude Aug 23, 2026
e8f58bb
Merge remote-tracking branch 'origin/main' into claude/bug-finding-sk…
claude Aug 23, 2026
c7b2ea2
docs(topics): finalize bug-finding plan after dual stress-test
claude Aug 23, 2026
2132c63
feat(bug-report): add scan skill — proactive two-stage bug hunting
claude Aug 23, 2026
b5b1a1f
docs(topics): mark bug-finding Phase 1 done — verifier pass 10/10
claude Aug 23, 2026
75015bd
feat(bug-report): extend setup to check|apply for the tracked lane co…
claude Aug 23, 2026
2f5fba0
docs(topics): mark bug-finding Phase 2 done — verifier pass 10/10
claude Aug 23, 2026
a0f6863
chore(bug-report): bump to 0.8.0 — changelog, readme, regenerated docs
claude Aug 23, 2026
d4c261e
docs(bug-report): scope the write usage heading now that scan has its…
claude Aug 23, 2026
52f6d3e
docs(topics): mark bug-finding Phases 3-4 done — verifier pass 8/8, g…
claude Aug 23, 2026
71129da
Merge remote-tracking branch 'origin/main' into claude/bug-finding-sk…
claude Aug 23, 2026
11e673d
docs(topics): prune bug-finding contract slice before merge
claude Aug 23, 2026
e63c9cb
fix(bug-report): enforce filing_posture, harden cursor rung 2 and set…
claude Aug 23, 2026
5bbc94e
Merge remote-tracking branch 'origin/main' into claude/bug-finding-sk…
claude Aug 23, 2026
a6732f4
fix(bug-report): align residual cursor/posture wording with the revie…
claude Aug 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/SKILL-CHEAT-SHEET.md
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ owned by [docs/CATALOG-TAXONOMY.md](CATALOG-TAXONOMY.md).

| Skill | Plugin | Cadence | What it does |
| --- | --- | --- | --- |
| [`/bug-report:scan`](../plugins/bug-report/skills/scan/SKILL.md) | `bug-report` | daily | Proactively hunt resting code for unobserved bugs, verify adversarially, report read-only |
| [`/claude-ops:audit-install-state`](../plugins/claude-ops/skills/audit-install-state/SKILL.md) | `claude-ops` | weekly | Audit a Claude Code install directory — what is there, what the product manages, what is stale |
| [`/claude-ops:audit-performance`](../plugins/claude-ops/skills/audit-performance/SKILL.md) | `claude-ops` | continuous | Capture slowness evidence while slow — version, sweep health, tree walk, sessions, fleet |
| [`/claude-ops:audit-skill-visibility`](../plugins/claude-ops/skills/audit-skill-visibility/SKILL.md) | `claude-ops` | weekly | Which skills the model can actually see, which are starved, and which are unobservable |
Expand Down
1 change: 1 addition & 0 deletions docs/conventions/config-cascade/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ open.
| `source-control` | `.claude/source-control.md` | all three | conforms (per-key override, #660); enforcement reads team-tracked only per [`commit-convention`](../commit-convention/README.md); loop-lane keys (`babysit_loop_*`, read by the source-control babysit lane; the work-items lanes tie in via the loop-lane convention only) ride the same surface, with the merge-rung key in the policy-floor class — standing raises bind from the team-tracked layer only, and the one named single-invocation exception is an explicitly typed argument rather than a config value in any layer, per [`loop-lane`](../loop-lane/README.md) |
| `toolchain` / `ecosystem-commands` | `.claude/ecosystems/<ecosystem>.yaml` | all three | conforms |
| `codebase-health` | `.claude/codebase-health.md` | all three | conforms (concatenating, with a declared empty-list opt-out) |
| `bug-report` | `.claude/bug-report.md` | all three | conforms; `lanes` concatenate and deduplicate by lane `name`, with a declared empty-list opt-out that also drops the bundled defaults, and `filing_posture` is a nearest-wins scalar. Keys owned by the plugin's `reference/config.md`, which also partitions them from the plugin's `output_dir` `userConfig` option — that option is never a key in this surface, and a layer declaring it is reported as an inert unknown key. Written (team layer only) by `/bug-report:setup apply`, read by `/bug-report:scan` |
| `github` | `.claude/github/` (`routing.yaml` per-key override, `conventions.md` concatenating) | all three | conforms; policy-floor inversion on write-posture routing keys, declared in the plugin's `change-routing.md` |
| `autonomy` | `.claude/autonomy/binding.json` | all three, plus an org rung | declared deviation |
| `standards` (`planning`, `review`) | `<standards_dir>/`, rooted by `.claude/standards.yaml` | all three | precedence inversion ratified via policy-floor class (#649); layer location outside `.claude/` still observed, not ratified |
Expand Down
1 change: 1 addition & 0 deletions docs/conventions/plugin-data-report-keying/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ holds every project's artifact under the same deletable root.
| `claude-config:audit-instructions` | Keyed, plus rule 3 on the delta computation |
| `claude-memory:audit` | Keyed on write **and** on both read paths (`report`, `fix`), plus rule 3 |
| `bug-report:write` / `bug-report:setup` | Keyed by project-root **basename** — rule 1c's worked example; not migrated |
| `bug-report:scan` | Same key, same tree, one timestamped file per run — it reuses `write`'s Step 4 path precedence rather than resolving its own, so it inherits rule 1c's basename collision unmigrated instead of introducing a second scheme (and, like `write`, lands outside this tree entirely when the operator configures `output_dir`). Its reports carry a cursor metadata block the next bare run reads back to pick a lane: a read-back artifact under rule 2, and a rule 3 surface, since the newest report at the derived key is the cursor's only authority and a colliding key would rotate lanes off another checkout's history. Absent at the key is the documented zero state — rotation falls through to the date-derived lane floor, never to an unkeyed path |
| `claude-config:unhobble` | Different solution, same problem: keys by `<experiment-id>` whose basename is *a label*, and records the canonical checkout identity (absolute worktree path, and the origin URL when one exists) **in the manifest**, verifying it before every later phase. Verification instead of a keyed path; acceptable because the artifact is never *served* — a mismatch aborts and names the conflicting path |
| `docs/conventions/topic-docs/` non-repo fallback | Keyed by **topic slug**, not project (`${CLAUDE_PLUGIN_DATA}/topic-docs/<slug>/`, the non-interactive branch when no project root resolves) — an instance of the gap, recorded here rather than silently declared conformant |
| `machine-health:audit` | Not keyed — roots are passed in by the caller, deliberately, per that skill's own inherited-variable hazard. Cited above for retention shape only |
Expand Down
4 changes: 3 additions & 1 deletion plugins/bug-report/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
"name": "bug-report",
"version": "0.7.4",
"version": "0.8.0",
"description": "Produces a structured five-field bug report — title, steps to reproduce, expected vs actual, severity with justification, and suggested fix location — from an informal defect description. Read-only by default: it emits the report and never edits code, opens a PR, or files an issue on its own.",
"author": {
"name": "Melodic Software",
Expand All @@ -12,6 +12,8 @@
"bug",
"bug-report",
"defect",
"scan",
"bug-hunting",
"triage",
"issue",
"workflow",
Expand Down
50 changes: 50 additions & 0 deletions plugins/bug-report/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,56 @@
All notable changes to the `bug-report` plugin are documented here. Format follows
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this plugin uses semantic versioning.

## [0.8.0]

### Added

- **`scan` — proactive bug hunting over resting code.** A third skill,
`/bug-report:scan`, that looks for defects **nobody has observed yet**: no diff, no failing test,
no stack trace, no comment marker required. One invocation is one bounded pass — hunt a target
(`/bug-report:scan <path|feature|diff>`) or, bare, the next lane in a rotation, then stop. Findings
come out in this plugin's existing five-field shape, each labeled `reproduced` or
`verified-by-reading`.
- **Recall and precision are separated into two stages.** Per-lens hunter subagents are told to be
generous; a **separate fresh-context verification gate** is told to refute, and only candidates
that survive it reach the report. The agent that discovers a candidate never grades it, refuted
candidates are retained in the report with their refuting argument rather than silently dropped,
and refill waves after a fully refuted wave are capped. Five V1 lenses ship in
`skills/scan/context/lenses.md`: contract-vs-body mismatch, boundary and edge cases, cross-file
consistency drift, state and concurrency hazards, and git-hotspot-guided reads.
- **Bare invocation is read-only toward the repository; filing needs `--track`.** A bare run never
edits, branches, pushes, or files. `--track` files verified findings through the `work-items` seam
as **raw intake** — duplicate search first, `needs-triage` resolved from the consumer's live label
set across both label axes, no label creation, and a body provenance line the lane cursor later
reads. It degrades to report-only with a printed notice when no tracker resolves. `--dry-run`
persists nothing and advances nothing.
- **Rotation state is derived statelessly, never from `.work/`.** Bare runs pick their lane down a
three-rung ladder — tracker filing history, then the newest report carrying a valid rotation cursor
block, resolved through the same directory precedence persistence uses, then a deterministic
date-derived floor — so a fresh clone rotates
correctly with zero stored state. The run reports which rung it used. Per-run budget: stop at 3
verified findings or a complete lane sample, at most 10 candidates per wave, at most 2 refill
waves. A lane sample being complete is never reported as the lane being bug-free.
- **`reference/config.md` — the single home for the `.claude/bug-report.md` key contract.** Layers
and resolution order, per-key merge semantics declared beside the keys they govern (`lanes`
concatenate with an explicit empty-list opt-out; `filing_posture` is a nearest-wins scalar), the
file format, and the key partition rule that keeps `output_dir` a native `userConfig` value and out
of the cascade file. Both `scan` and `setup` cite it; neither restates it.

### Changed

- **`setup` is no longer check-only: it is now `check | apply`.** The plugin gained a second
configuration surface — the tracked, cascade-layered `.claude/bug-report.md` that `scan` reads for
its lanes and filing posture — which dissolves the check-only carve-out 0.5.0 adopted. `check`
still inspects both surfaces read-only; `apply` writes or updates that one tracked file and
nothing else, drafting lane candidates from the repository, confirming them one decision at a
time, updating conservatively rather than overwriting, and verifying against the file on disk
afterward. `output_dir` is unchanged: it stays a personal `userConfig` value that Claude Code's
own configuration prompt owns, and this skill still never writes it.
- **Convention registries record the new surfaces.** The config-cascade convention gains a
`bug-report` implementers row, and the plugin-data report-keying row now covers `scan` as a
slug-keyed producer of findings reports and cursor metadata alongside `write`'s `--file` reports.

## [0.7.4]

### Changed
Expand Down
69 changes: 60 additions & 9 deletions plugins/bug-report/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
# bug-report

A Claude Code plugin that turns an informal defect description into a structured,
five-field bug report — **read-only by default**. It captures; it does not fix,
open a PR, or file an issue on its own.
A Claude Code plugin for the front of the bug lifecycle — **read-only by default**.
It finds defects and captures them in a structured, five-field report; it does not
fix them, open a PR, or file an issue on its own.

Invoke it with `/bug-report:write <description>` (or let Claude reach for it
| Skill | What it does |
|---|---|
| `/bug-report:write` | Turns an informal defect description — one you already observed — into the five-field report. |
| `/bug-report:scan` | Hunts for defects **nobody has observed yet** in resting code, verifies each candidate adversarially, and reports what survives. |
| `/bug-report:setup` | `check` inspects both configuration surfaces read-only; `apply` writes the tracked lane config `scan` reads. |

Invoke `/bug-report:write <description>` (or let Claude reach for it
when you describe a defect). The five fields are:

1. **Title** — present tense, one line
Expand All @@ -25,7 +31,7 @@ when you describe a defect). The five fields are:
- **Routes non-defects away.** Feature requests, investigations, and generic chores
are recognized and pointed elsewhere rather than forced into the bug shape.

## Usage
## Usage — `/bug-report:write`

```text
/bug-report:write [--file] [--quick|--full] [--no-survey] <bug description>
Expand All @@ -39,17 +45,62 @@ when you describe a defect). The five fields are:
| `--no-survey` | Trust the description; ask only when a field would otherwise be invented |
| `--file` | Persist the report to a file (see Configuration), then offer to file it in a tracker |

## Hunting bugs nobody has reported yet

`/bug-report:write` needs a defect you already noticed. `/bug-report:scan` needs nothing —
no diff, no failing test, no stack trace, no comment marker. It reads resting code and
looks for what is wrong in it.

```text
/bug-report:scan [<path|feature|diff>] [--lane <name>] [--track] [--dry-run]
```

| Flag | Effect |
|------|--------|
| (none) | Rotate: self-select the next lane from the tracked lane config, hunt it, report |
| `<path\|feature\|diff>` | Hunt exactly that scope — no rotation |
| `--lane <name>` | Hunt the named lane's globs |
| `--track` | File the verified findings as raw intake through the `work-items` seam |
| `--dry-run` | Report to stdout only — persists nothing, advances no rotation |

One invocation is **one bounded pass**, which makes it usable interactively, from a loop,
or as a daily routine. Two properties are worth knowing before you rely on it:

- **Recall and precision are separated.** Per-lens hunter subagents are told to be generous;
a separate fresh-context gate is then told to *refute* every candidate they produced. Only
survivors reach the report, each labeled `reproduced` or `verified-by-reading`, and refuted
candidates stay in the report with the argument that killed them.
- **A bare run is read-only toward your repository and stays within a budget** — it stops at
three verified findings or a complete lane sample. Filing happens only when you pass
`--track`, and a complete lane sample is never reported as the lane being bug-free.

Verified findings are handed off, not fixed here: root-causing routes to `/debugging:debug`,
and anything security-relevant routes to the `review:security-review` lane.

## Configuration

One optional personal `userConfig` value, prompted by Claude Code at enable time:
Two surfaces with two different owners.

**Personal — one optional `userConfig` value**, prompted by Claude Code at enable time:

| Option | Type | Effect |
|--------|------|--------|
| `output_dir` | directory | Where `--file` writes reports. **Leave unset** and reports go to the plugin's own persistent data directory. Set it to a path in your repository if you want bug reports committed alongside your code. |

Run `/bug-report:setup` to validate this choice interactively. It reads the rendered option,
recommends the uncommitted default, and routes changes through Claude Code's plugin configuration
prompt. Current releases ignore plugin `userConfig` values placed in project or local settings.
Claude Code owns this value: current releases ignore plugin `userConfig` values placed in
project or local settings, and changes route through Claude Code's own configuration prompt.

**Team — the tracked `.claude/bug-report.md`**, which `/bug-report:scan` reads for its lanes
(`lanes`) and its filing policy (`filing_posture`). It is layered per the marketplace's
config-cascade convention — a user-global file, this tracked team file, and a gitignored local
overlay. All layers are optional: with no config at all, `scan` rotates over bundled generic
default lanes. Keys, defaults, layer order, and per-key merge semantics live in
[`reference/config.md`](reference/config.md), their single home.

Run `/bug-report:setup` to work on either surface. `check` (the default) reports both read-only:
the rendered `output_dir` and which layer supplied each lane config value. `apply` writes the
tracked file and nothing else — it drafts lane candidates from your repository, confirms them one
at a time, and never touches settings, `pluginConfigs`, the local overlay, or your `.gitignore`.

Project-specific conventions — naming, areas, tracker choice, priority labels — are
read from the **consuming project's own `CLAUDE.md` / rules**; the plugin imposes
Expand Down
Loading