bmad-method 6.10.1-next.2 → 6.10.1-next.21
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/marketplace.json +52 -27
- package/package.json +4 -3
- package/removals.txt +5 -0
- package/src/bmm-skills/1-analysis/bmad-agent-analyst/customize.toml +19 -4
- package/src/bmm-skills/1-analysis/bmad-product-brief/SKILL.md +1 -1
- package/src/bmm-skills/1-analysis/bmad-product-brief/customize.toml +5 -3
- package/src/bmm-skills/2-plan-workflows/bmad-prd/SKILL.md +2 -0
- package/src/bmm-skills/2-plan-workflows/bmad-prd/customize.toml +5 -3
- package/src/{core-skills → bmm-skills/2-plan-workflows}/bmad-spec/SKILL.md +18 -3
- package/src/{core-skills → bmm-skills/2-plan-workflows}/bmad-spec/assets/spec-template.md +1 -1
- package/src/bmm-skills/2-plan-workflows/bmad-spec/assets/stories-schema.md +44 -0
- package/src/{core-skills → bmm-skills/2-plan-workflows}/bmad-spec/customize.toml +3 -4
- package/src/bmm-skills/2-plan-workflows/bmad-ux/customize.toml +4 -2
- package/src/bmm-skills/3-solutioning/bmad-architecture/SKILL.md +2 -2
- package/src/bmm-skills/3-solutioning/bmad-architecture/customize.toml +4 -2
- package/src/bmm-skills/4-implementation/bmad-agent-dev/customize.toml +3 -0
- package/src/bmm-skills/4-implementation/bmad-code-review/SKILL.md +2 -4
- package/src/bmm-skills/4-implementation/bmad-code-review/customize.toml +52 -0
- package/src/bmm-skills/4-implementation/bmad-code-review/steps/step-01-gather-context.md +0 -1
- package/src/bmm-skills/4-implementation/bmad-code-review/steps/step-02-review.md +10 -24
- package/src/bmm-skills/4-implementation/bmad-code-review/steps/step-03-triage.md +3 -4
- package/src/bmm-skills/4-implementation/bmad-dev-auto/SKILL.md +33 -12
- package/src/bmm-skills/4-implementation/bmad-dev-auto/customize.toml +75 -0
- package/src/bmm-skills/4-implementation/bmad-dev-auto/spec-template.md +4 -4
- package/src/bmm-skills/4-implementation/bmad-dev-auto/step-01-clarify-and-route.md +22 -4
- package/src/bmm-skills/4-implementation/bmad-dev-auto/step-02-plan.md +5 -6
- package/src/bmm-skills/4-implementation/bmad-dev-auto/step-03-implement.md +8 -4
- package/src/bmm-skills/4-implementation/bmad-dev-auto/step-04-review.md +13 -19
- package/src/bmm-skills/4-implementation/bmad-dev-story/customize.toml +3 -0
- package/src/bmm-skills/4-implementation/bmad-quick-dev/SKILL.md +6 -108
- package/src/bmm-skills/4-implementation/bmad-quick-dev/customize.toml +73 -0
- package/src/bmm-skills/4-implementation/bmad-quick-dev/render.py +381 -0
- package/src/bmm-skills/4-implementation/bmad-quick-dev/spec-template.md +2 -2
- package/src/bmm-skills/4-implementation/bmad-quick-dev/step-01-clarify-and-route.md +11 -13
- package/src/bmm-skills/4-implementation/bmad-quick-dev/step-02-plan.md +4 -9
- package/src/bmm-skills/4-implementation/bmad-quick-dev/step-03-implement.md +12 -4
- package/src/bmm-skills/4-implementation/bmad-quick-dev/step-04-review.md +8 -20
- package/src/bmm-skills/4-implementation/bmad-quick-dev/step-05-present.md +4 -4
- package/src/bmm-skills/4-implementation/bmad-quick-dev/step-oneshot.md +12 -13
- package/src/bmm-skills/4-implementation/bmad-quick-dev/sync-sprint-status.md +6 -6
- package/src/bmm-skills/4-implementation/bmad-quick-dev/workflow.md +85 -0
- package/src/bmm-skills/module-help.csv +2 -4
- package/src/bmm-skills/module.yaml +2 -5
- package/src/bmm-skills/v6-shims/README.md +24 -0
- package/src/bmm-skills/{3-solutioning → v6-shims}/bmad-create-architecture/SKILL.md +1 -1
- package/src/bmm-skills/{2-plan-workflows → v6-shims}/bmad-create-prd/SKILL.md +3 -3
- package/src/bmm-skills/v6-shims/bmad-domain-research/SKILL.md +14 -0
- package/src/bmm-skills/{2-plan-workflows → v6-shims}/bmad-edit-prd/SKILL.md +3 -3
- package/src/bmm-skills/v6-shims/bmad-market-research/SKILL.md +14 -0
- package/src/bmm-skills/v6-shims/bmad-technical-research/SKILL.md +14 -0
- package/src/bmm-skills/{2-plan-workflows → v6-shims}/bmad-validate-prd/SKILL.md +3 -3
- package/src/core-skills/bmad-advanced-elicitation/SKILL.md +26 -103
- package/src/core-skills/bmad-advanced-elicitation/customize.toml +54 -0
- package/src/core-skills/bmad-advanced-elicitation/scripts/pick_methods.py +233 -0
- package/src/core-skills/bmad-advanced-elicitation/scripts/tests/test_pick_methods.py +228 -0
- package/src/core-skills/bmad-brainstorming/SKILL.md +3 -3
- package/src/core-skills/bmad-brainstorming/assets/brain-selector.html +2 -0
- package/src/core-skills/bmad-brainstorming/references/mode-autonomous.md +1 -1
- package/src/core-skills/bmad-brainstorming/scripts/brain.py +36 -6
- package/src/core-skills/bmad-brainstorming/scripts/tests/test_brain.py +22 -0
- package/src/core-skills/bmad-customize/SKILL.md +2 -2
- package/src/core-skills/bmad-deep-recon/SKILL.md +82 -0
- package/src/core-skills/bmad-deep-recon/assets/research.template.md +18 -0
- package/src/core-skills/bmad-deep-recon/customize.toml +212 -0
- package/src/core-skills/bmad-deep-recon/references/draft.md +8 -0
- package/src/core-skills/bmad-deep-recon/references/finalize.md +11 -0
- package/src/core-skills/bmad-deep-recon/references/html-briefing.md +16 -0
- package/src/core-skills/bmad-deep-recon/references/lifecycle.md +11 -0
- package/src/core-skills/bmad-deep-recon/references/process.md +10 -0
- package/src/core-skills/bmad-deep-recon/references/run.md +73 -0
- package/src/core-skills/bmad-deep-recon/references/selection.md +13 -0
- package/src/core-skills/bmad-deep-recon/references/synthesis.md +16 -0
- package/src/core-skills/bmad-deep-recon/references/verification.md +29 -0
- package/src/core-skills/bmad-deep-recon/scripts/recon_kit.py +322 -0
- package/src/core-skills/bmad-deep-recon/scripts/tests/test_recon_kit.py +144 -0
- package/src/core-skills/bmad-deep-recon/types/academic-lit.md +19 -0
- package/src/core-skills/bmad-deep-recon/types/competitive.md +19 -0
- package/src/core-skills/bmad-deep-recon/types/domain.md +19 -0
- package/src/core-skills/bmad-deep-recon/types/market.md +19 -0
- package/src/core-skills/bmad-deep-recon/types/technical.md +19 -0
- package/src/core-skills/bmad-deep-recon/types/user-voice.md +19 -0
- package/src/core-skills/bmad-forge-idea/SKILL.md +2 -2
- package/src/core-skills/bmad-forge-idea/scripts/resolve_personas.py +4 -1
- package/src/core-skills/bmad-help/SKILL.md +1 -1
- package/src/core-skills/bmad-party-mode/SKILL.md +2 -2
- package/src/core-skills/bmad-party-mode/scripts/resolve_party.py +11 -3
- package/src/core-skills/bmad-review/SKILL.md +49 -0
- package/src/core-skills/bmad-review/customize.toml +141 -0
- package/src/core-skills/bmad-review/references/editorial-common.md +56 -0
- package/src/core-skills/bmad-review/references/lens-adversarial.md +18 -0
- package/src/core-skills/bmad-review/references/lens-edge-case-hunter.md +54 -0
- package/src/core-skills/bmad-review/references/lens-prose.md +7 -0
- package/src/core-skills/bmad-review/references/lens-structure.md +9 -0
- package/src/core-skills/{bmad-review-verification-gap/SKILL.md → bmad-review/references/lens-verification-gap.md} +15 -39
- package/src/core-skills/bmad-review/references/structure-models.md +44 -0
- package/src/core-skills/bmad-review/scripts/tests/test_word_metrics.py +62 -0
- package/src/core-skills/bmad-review/scripts/word_metrics.py +102 -0
- package/src/core-skills/module-help.csv +3 -7
- package/src/core-skills/module.yaml +5 -0
- package/src/core-skills/v6-shims/README.md +25 -0
- package/src/core-skills/v6-shims/bmad-editorial-review/SKILL.md +6 -0
- package/src/core-skills/v6-shims/bmad-editorial-review/customize.toml +31 -0
- package/src/core-skills/v6-shims/bmad-editorial-review-prose/SKILL.md +6 -0
- package/src/core-skills/v6-shims/bmad-editorial-review-structure/SKILL.md +6 -0
- package/src/core-skills/v6-shims/bmad-review-adversarial-general/SKILL.md +6 -0
- package/src/core-skills/v6-shims/bmad-review-edge-case-hunter/SKILL.md +6 -0
- package/src/core-skills/v6-shims/bmad-review-verification-gap/SKILL.md +6 -0
- package/tools/installer/ide/platform-codes.yaml +7 -0
- package/tools/installer/modules/custom-module-manager.js +12 -6
- package/tools/installer/modules/external-manager.js +12 -8
- package/tools/installer/modules/git-env.js +47 -0
- package/tools/skill-validator.md +11 -1
- package/tools/validate-skills.js +33 -0
- package/src/bmm-skills/1-analysis/research/bmad-domain-research/SKILL.md +0 -96
- package/src/bmm-skills/1-analysis/research/bmad-domain-research/customize.toml +0 -41
- package/src/bmm-skills/1-analysis/research/bmad-domain-research/domain-steps/step-01-init.md +0 -137
- package/src/bmm-skills/1-analysis/research/bmad-domain-research/domain-steps/step-02-domain-analysis.md +0 -229
- package/src/bmm-skills/1-analysis/research/bmad-domain-research/domain-steps/step-03-competitive-landscape.md +0 -238
- package/src/bmm-skills/1-analysis/research/bmad-domain-research/domain-steps/step-04-regulatory-focus.md +0 -206
- package/src/bmm-skills/1-analysis/research/bmad-domain-research/domain-steps/step-05-technical-trends.md +0 -234
- package/src/bmm-skills/1-analysis/research/bmad-domain-research/domain-steps/step-06-research-synthesis.md +0 -450
- package/src/bmm-skills/1-analysis/research/bmad-domain-research/research.template.md +0 -29
- package/src/bmm-skills/1-analysis/research/bmad-market-research/SKILL.md +0 -96
- package/src/bmm-skills/1-analysis/research/bmad-market-research/customize.toml +0 -41
- package/src/bmm-skills/1-analysis/research/bmad-market-research/research.template.md +0 -29
- package/src/bmm-skills/1-analysis/research/bmad-market-research/steps/step-01-init.md +0 -184
- package/src/bmm-skills/1-analysis/research/bmad-market-research/steps/step-02-customer-behavior.md +0 -239
- package/src/bmm-skills/1-analysis/research/bmad-market-research/steps/step-03-customer-pain-points.md +0 -251
- package/src/bmm-skills/1-analysis/research/bmad-market-research/steps/step-04-customer-decisions.md +0 -261
- package/src/bmm-skills/1-analysis/research/bmad-market-research/steps/step-05-competitive-analysis.md +0 -173
- package/src/bmm-skills/1-analysis/research/bmad-market-research/steps/step-06-research-completion.md +0 -484
- package/src/bmm-skills/1-analysis/research/bmad-technical-research/SKILL.md +0 -96
- package/src/bmm-skills/1-analysis/research/bmad-technical-research/customize.toml +0 -41
- package/src/bmm-skills/1-analysis/research/bmad-technical-research/research.template.md +0 -29
- package/src/bmm-skills/1-analysis/research/bmad-technical-research/technical-steps/step-01-init.md +0 -137
- package/src/bmm-skills/1-analysis/research/bmad-technical-research/technical-steps/step-02-technical-overview.md +0 -239
- package/src/bmm-skills/1-analysis/research/bmad-technical-research/technical-steps/step-03-integration-patterns.md +0 -248
- package/src/bmm-skills/1-analysis/research/bmad-technical-research/technical-steps/step-04-architectural-patterns.md +0 -202
- package/src/bmm-skills/1-analysis/research/bmad-technical-research/technical-steps/step-05-implementation-research.md +0 -233
- package/src/bmm-skills/1-analysis/research/bmad-technical-research/technical-steps/step-06-research-synthesis.md +0 -493
- package/src/core-skills/bmad-brainstorming/analysis/catalog-analysis.md +0 -239
- package/src/core-skills/bmad-brainstorming/analysis/method-matrix.csv +0 -109
- package/src/core-skills/bmad-editorial-review-prose/SKILL.md +0 -86
- package/src/core-skills/bmad-editorial-review-structure/SKILL.md +0 -179
- package/src/core-skills/bmad-index-docs/SKILL.md +0 -66
- package/src/core-skills/bmad-review-adversarial-general/SKILL.md +0 -37
- package/src/core-skills/bmad-review-edge-case-hunter/SKILL.md +0 -73
- package/src/core-skills/bmad-review-edge-case-hunter/references/deletion-check.md +0 -14
- package/src/core-skills/bmad-shard-doc/SKILL.md +0 -105
- /package/src/{core-skills → bmm-skills/2-plan-workflows}/bmad-spec/assets/headless-schemas.md +0 -0
- /package/src/bmm-skills/{3-solutioning → v6-shims}/bmad-create-architecture/customize.toml +0 -0
- /package/src/bmm-skills/{2-plan-workflows → v6-shims}/bmad-create-prd/customize.toml +0 -0
- /package/src/bmm-skills/{2-plan-workflows → v6-shims}/bmad-edit-prd/customize.toml +0 -0
- /package/src/bmm-skills/{2-plan-workflows → v6-shims}/bmad-validate-prd/customize.toml +0 -0
- /package/src/core-skills/bmad-advanced-elicitation/{methods.csv → assets/methods.csv} +0 -0
- /package/src/core-skills/bmad-party-mode/scripts/tests/{test-resolve_party.py → test_resolve_party.py} +0 -0
|
@@ -131,13 +131,18 @@ def build_collective(agents: dict, party_members: list):
|
|
|
131
131
|
})
|
|
132
132
|
installed_codes.append(code)
|
|
133
133
|
|
|
134
|
-
for m in party_members
|
|
134
|
+
for m in (party_members if isinstance(party_members, list) else []):
|
|
135
|
+
if not isinstance(m, dict):
|
|
136
|
+
continue
|
|
135
137
|
code = m.get("code")
|
|
136
138
|
if not code:
|
|
137
139
|
continue
|
|
138
140
|
# A custom member overrides an installed agent it matches by code/alias/name.
|
|
139
141
|
canonical = index.get(code) or index.get(code.lower()) or code
|
|
140
|
-
entry
|
|
142
|
+
# Start from the installed entry so fields the override omits
|
|
143
|
+
# (icon, title, description, module, team) survive.
|
|
144
|
+
entry = dict(collective.get(canonical, {}))
|
|
145
|
+
entry.update({"code": canonical, "source": "custom"})
|
|
141
146
|
for field in ("name", "icon", "title", "persona", "capabilities", "model"):
|
|
142
147
|
if m.get(field) is not None:
|
|
143
148
|
entry[field] = m[field]
|
|
@@ -152,7 +157,10 @@ def resolve_members(member_tokens, collective, index):
|
|
|
152
157
|
"""(resolved entries in listed order, unresolved tokens)."""
|
|
153
158
|
resolved, unresolved = [], []
|
|
154
159
|
for token in member_tokens or []:
|
|
155
|
-
|
|
160
|
+
if not isinstance(token, str):
|
|
161
|
+
unresolved.append(token) # malformed config value — never a key lookup
|
|
162
|
+
continue
|
|
163
|
+
code = index.get(token) or index.get(token.lower())
|
|
156
164
|
if code and code in collective:
|
|
157
165
|
resolved.append(collective[code])
|
|
158
166
|
else:
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bmad-review
|
|
3
|
+
description: 'Multi-lens review over any diff, doc, spec, or artifact — whichever installed lenses fit the content, run singly or together. Shipped lenses include adversarial, edge-case, verification-gap, structure, and prose. Use when the user says "review this", "critical review", "editorial review", "hunt edge cases", "review the structure", or "review the prose".'
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# BMad Review
|
|
7
|
+
|
|
8
|
+
Review content through lenses — each a distinct method and stance — and report findings in one canonical shape. Report what is real — never pad to look thorough. Each lens sets its own stance toward the content and toward zero findings: for most an empty result is valid; the adversarial lens treats it as suspicious; the editorial lenses hold content sacrosanct and critique only how it is organized and expressed.
|
|
9
|
+
|
|
10
|
+
The lens set is whatever `{workflow.lenses}` resolves to, not a fixed list — overrides add lenses and replace shipped ones. Never claim a capability from this file; read the resolved lenses and work from those.
|
|
11
|
+
|
|
12
|
+
## Inputs
|
|
13
|
+
|
|
14
|
+
- **content** — what to review: a diff, branch, uncommitted changes, file, spec, story, or any document. Args: `[path]`.
|
|
15
|
+
- **lenses** (optional) — one or more lens codes or names, however the caller expresses them: a spoken request, or a directive of the form `skill:bmad-review lenses=<code>[,<code>...]` (the form bmm's `doc_standards` uses). Default: every applicable lens (a full review).
|
|
16
|
+
- **also_consider** (optional) — areas to keep in mind alongside each lens's normal analysis.
|
|
17
|
+
- **pre-resolved customization** (optional) — `[workflow]` field values supplied by a forwarding caller. See Execution step 1.
|
|
18
|
+
|
|
19
|
+
## Conventions
|
|
20
|
+
|
|
21
|
+
- Bare paths (e.g. `references/lens-edge-case-hunter.md`) resolve from `{skill-root}` — this skill's installed directory, where `customize.toml` lives. `{project-root}` resolves to the project working directory.
|
|
22
|
+
- `{workflow.<name>}` resolves to fields in `customize.toml`'s `[workflow]` table (overrides win per BMad merge rules).
|
|
23
|
+
- In `style_guide`, `review_guidance`, and `persistent_facts`, a value prefixed `file:` is a path or glob — load that file's contents. If a `file:` value cannot be read, name the failed file in the output header and continue: the shipped baseline for `style_guide`, the remaining entries otherwise.
|
|
24
|
+
|
|
25
|
+
## Execution
|
|
26
|
+
|
|
27
|
+
1. **Resolve customization:** `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`. On failure, read `{skill-root}/customize.toml` directly and use defaults. **Forwarded activation:** if a caller invoked you with pre-resolved customization fields (e.g. the `bmad-editorial-review` shim), honor them verbatim for those named fields — they already carry the user's overrides — and resolve only the remaining fields from your own `customize.toml`. Then execute each `{workflow.activation_steps_prepend}` entry in order, hold `{workflow.persistent_facts}` as standing context for the session, and treat `{workflow.review_guidance}` entries as standing review directives for every lens.
|
|
28
|
+
2. **Load the content.** If it is empty or cannot be decoded as text: when the caller expects the raw findings JSON array (e.g. the legacy edge-case forwarder), return `[{"location":"N/A","trigger_condition":"Input empty or undecodable","guard_snippet":"Provide valid content to review","potential_consequence":"Review skipped — no analysis performed"}]` (no `lens` field) and stop; otherwise say what's wrong and ask for reviewable content. Classify the content — diff, source file, function, or document — and whether it is **code** or **docs**; scope rules and lens applicability both depend on it. A document that defines behavior (spec, requirements, plan, story) is `docs` that a behavioral lens may still apply to; judge by `when`.
|
|
29
|
+
3. **Select lenses** from `{workflow.lenses}`. A lens with an empty `instruction` is disabled. If the user or caller named lenses, run exactly those only — `applies_to` and `when` do not filter an explicit request. Otherwise run every enabled lens whose `applies_to` covers the content class (`any` always covers) and whose `when` applies.
|
|
30
|
+
4. **Announce the plan** in one line before running anything: the content class, the lenses about to run, and — when any lens has `after` set — that it runs on top of the named lens's findings. Skip the announcement entirely when the caller pinned an exact output contract (the legacy forwarders that demand raw JSON or one exact line) — their contract covers everything you emit, not just the findings block. Then execute each `{workflow.activation_steps_append}` entry in order.
|
|
31
|
+
5. **Run the independent lenses** — every selected lens without `after`. Each sees the content and `also_consider`, never another lens's findings. Follow each lens's `instruction`; the shipped lenses load their reference file just-in-time, so load only what runs. When subagents are available, spawn one per lens in parallel: give it the lens `instruction` with `{skill-root}` and paths resolved absolute, the content or where to read it, any `also_consider` areas, the standing review directives, and the constraint "Return ONLY your findings — no other output." Otherwise run the lenses sequentially yourself, completing one before starting the next.
|
|
32
|
+
6. **Run the dependent lenses** — every selected lens with `after`, once the lens it names has completed, passing that lens's findings in. A lens whose `after` target was not selected or produced nothing still runs, with no prior findings. Dependent lenses that name different targets are independent of each other and may run in parallel.
|
|
33
|
+
7. **Assemble and present** per Output below. Keep every lens's findings — overlap between lenses is signal, not duplication; note it in the markdown report rather than deduping. Execute `{workflow.on_complete}` if set.
|
|
34
|
+
|
|
35
|
+
## Output
|
|
36
|
+
|
|
37
|
+
One JSON array holding every finding from every lens. Each finding carries:
|
|
38
|
+
|
|
39
|
+
- `lens` — the code of the lens that produced it
|
|
40
|
+
- `location` — where in the content (file:line-range for code, section for documents)
|
|
41
|
+
- `trigger_condition` — the problem, or the condition that exposes it, in one line
|
|
42
|
+
- `guard_snippet` — the concrete fix, guard, or missing check
|
|
43
|
+
- `potential_consequence` — what goes wrong if it ships as-is
|
|
44
|
+
|
|
45
|
+
Each lens file refines these semantics for its findings and may add lens-specific fields (e.g. `kind`/`confidence` on deletion findings, `gap_shape`/`consumer`/`evidence` on verification-gap findings). A lens file may instead declare its own findings shape and rendering — the editorial lenses render a findings table — and that shape wins for that lens's findings. `[]` is valid when nothing is found. No severity, priority, or ranking anywhere.
|
|
46
|
+
|
|
47
|
+
Present per `{workflow.output_format}` — `"json"` (the raw array in a fenced json block), `"markdown"`, or `"both"` — unless the caller requested a specific shape; a legacy forwarder's output contract always wins, and governs everything you emit rather than the findings block alone. The markdown report groups findings by lens, each rendered in its declared shape: a short block per finding rendering the fields plus any extras worth surfacing, one line for a lens that found nothing, and a plain clean statement when the whole review is clean. Shape the report per `{workflow.output_preferences}`.
|
|
48
|
+
|
|
49
|
+
When `{workflow.report_path}` is set, write the report there; otherwise present it in chat.
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# DO NOT EDIT -- overwritten on every update.
|
|
2
|
+
#
|
|
3
|
+
# Workflow customization surface for bmad-review.
|
|
4
|
+
#
|
|
5
|
+
# Override files (not edited here):
|
|
6
|
+
# {project-root}/_bmad/custom/bmad-review.toml (team)
|
|
7
|
+
# {project-root}/_bmad/custom/bmad-review.user.toml (personal)
|
|
8
|
+
|
|
9
|
+
[workflow]
|
|
10
|
+
|
|
11
|
+
# --- Configurable below. Overrides merge per BMad structural rules: ---
|
|
12
|
+
# scalars: override wins
|
|
13
|
+
# arrays (persistent_facts, activation_steps_*, review_guidance): append
|
|
14
|
+
# arrays of tables keyed by `code`: matching key replaces, new keys append
|
|
15
|
+
|
|
16
|
+
# Steps executed on activation: prepend runs before the skill's own
|
|
17
|
+
# activation flow, append runs after the lens plan is settled and before the
|
|
18
|
+
# lenses run. Each entry is a literal instruction.
|
|
19
|
+
activation_steps_prepend = []
|
|
20
|
+
activation_steps_append = []
|
|
21
|
+
|
|
22
|
+
# Standing context held for every review, code and document alike. Entries
|
|
23
|
+
# prefixed `file:` are paths or globs whose contents load as facts; all others
|
|
24
|
+
# are literal facts. The shipped entry is a project-wide glob — set it to []
|
|
25
|
+
# if you don't want every review scanning for it.
|
|
26
|
+
persistent_facts = ["file:{project-root}/**/project-context.md"]
|
|
27
|
+
|
|
28
|
+
# Standing review directives applied on every run alongside each lens's own
|
|
29
|
+
# method. Each entry is a literal sentence or a `file:`-prefixed path/glob
|
|
30
|
+
# whose contents load as directives.
|
|
31
|
+
#
|
|
32
|
+
# Examples:
|
|
33
|
+
# "Flag passive voice in headings."
|
|
34
|
+
# "Second-person imperative is the house voice; never suggest changing it."
|
|
35
|
+
# "file:{project-root}/docs/terminology.md"
|
|
36
|
+
review_guidance = []
|
|
37
|
+
|
|
38
|
+
# Executed after the findings are delivered. Freeform directive; empty = the
|
|
39
|
+
# review ends with the findings.
|
|
40
|
+
#
|
|
41
|
+
# Example:
|
|
42
|
+
# on_complete = "Append a one-line review summary to {project-root}/docs/review-log.md"
|
|
43
|
+
on_complete = ""
|
|
44
|
+
|
|
45
|
+
# How findings are presented when the caller doesn't say: "json" (the raw
|
|
46
|
+
# findings array only), "markdown" (the human report only), or "both". A lens
|
|
47
|
+
# that declares its own rendering keeps it for its own findings.
|
|
48
|
+
output_format = "both"
|
|
49
|
+
|
|
50
|
+
# Where to write the review report. Empty = present in chat only. Accepts
|
|
51
|
+
# {project-root}-prefixed paths.
|
|
52
|
+
report_path = ""
|
|
53
|
+
|
|
54
|
+
# How findings are presented — shaping, not destination. Freeform directive;
|
|
55
|
+
# empty = each lens's default ordering and rollup.
|
|
56
|
+
#
|
|
57
|
+
# Example:
|
|
58
|
+
# output_preferences = "Cap output at the 20 highest-impact findings."
|
|
59
|
+
output_preferences = ""
|
|
60
|
+
|
|
61
|
+
# --- Editorial lens settings (used by the structure and prose lenses) ---
|
|
62
|
+
|
|
63
|
+
# Default reader the editorial lenses calibrate for when the request doesn't
|
|
64
|
+
# say:
|
|
65
|
+
# "humans" clarity, flow, comprehension aids preserved
|
|
66
|
+
# "llm" precision, consistent terminology, no hedging
|
|
67
|
+
# A reader type stated in the request wins for that run.
|
|
68
|
+
reader_type = "humans"
|
|
69
|
+
|
|
70
|
+
# The baseline style guide for every editorial review: the name of a guide the
|
|
71
|
+
# model knows well, a `file:`-prefixed path to a style guide document, or the
|
|
72
|
+
# rules inline as text. A style guide stated in the request wins for that run.
|
|
73
|
+
# Where the guide in effect conflicts with the lens's generic principles, the
|
|
74
|
+
# guide wins — except content is sacrosanct.
|
|
75
|
+
#
|
|
76
|
+
# Examples (set in team/user override TOML):
|
|
77
|
+
# style_guide = "file:{project-root}/_bmad/style-guides/company-voice.md"
|
|
78
|
+
# style_guide = "Sentence-case headings. No Oxford comma. Address the reader as 'you'."
|
|
79
|
+
style_guide = "Microsoft Writing Style Guide"
|
|
80
|
+
|
|
81
|
+
# ---------------------------------------------------------------------------
|
|
82
|
+
# Review lenses. Each lens is a pass over the content with its own method and
|
|
83
|
+
# stance. `instruction` is the lens's whole execution recipe — the shipped
|
|
84
|
+
# lenses load a reference file from the skill root, but an override may inline
|
|
85
|
+
# any prompt.
|
|
86
|
+
#
|
|
87
|
+
# `applies_to` is the content this lens can review: "code", "docs", or "any".
|
|
88
|
+
# It is the first filter — a lens never joins a default review for content it
|
|
89
|
+
# does not apply to. `when` (optional) refines that judgement in prose. An
|
|
90
|
+
# explicitly requested lens always runs, whatever both say.
|
|
91
|
+
#
|
|
92
|
+
# `after` (optional) names a lens this one builds on: it runs once that lens
|
|
93
|
+
# has completed and receives its findings, instead of running independently.
|
|
94
|
+
#
|
|
95
|
+
# Empty `instruction` disables a lens. Keyed by `code`: an override with a
|
|
96
|
+
# matching code replaces the shipped lens, a new code appends.
|
|
97
|
+
#
|
|
98
|
+
# Example (add an org-specific lens in team/user override TOML):
|
|
99
|
+
# [[workflow.lenses]]
|
|
100
|
+
# code = "accessibility"
|
|
101
|
+
# name = "Accessibility"
|
|
102
|
+
# applies_to = "any"
|
|
103
|
+
# when = "UI code or user-facing documents."
|
|
104
|
+
# instruction = "Review against WCAG 2.2 AA. Emit findings in the canonical fields."
|
|
105
|
+
# ---------------------------------------------------------------------------
|
|
106
|
+
|
|
107
|
+
[[workflow.lenses]]
|
|
108
|
+
code = "adversarial"
|
|
109
|
+
name = "Adversarial"
|
|
110
|
+
applies_to = "any"
|
|
111
|
+
when = "always"
|
|
112
|
+
instruction = "Load `references/lens-adversarial.md` from the skill root and follow it."
|
|
113
|
+
|
|
114
|
+
[[workflow.lenses]]
|
|
115
|
+
code = "edge-case-hunter"
|
|
116
|
+
name = "Edge-Case Hunter"
|
|
117
|
+
applies_to = "any"
|
|
118
|
+
when = "Content with behavior to trace: code, diffs, and the specs, requirements, plans, and stories that define behavior. Skip for prose documents with no behavioral surface."
|
|
119
|
+
instruction = "Load `references/lens-edge-case-hunter.md` from the skill root and follow it."
|
|
120
|
+
|
|
121
|
+
[[workflow.lenses]]
|
|
122
|
+
code = "verification-gap"
|
|
123
|
+
name = "Verification Gap"
|
|
124
|
+
applies_to = "code"
|
|
125
|
+
when = "Reviewed inside a repo where tests can be searched and read."
|
|
126
|
+
instruction = "Load `references/lens-verification-gap.md` from the skill root and follow it."
|
|
127
|
+
|
|
128
|
+
[[workflow.lenses]]
|
|
129
|
+
code = "structure"
|
|
130
|
+
name = "Editorial Structure"
|
|
131
|
+
applies_to = "docs"
|
|
132
|
+
when = "Documents whose shape is the author's to change."
|
|
133
|
+
instruction = "Load `references/lens-structure.md` from the skill root and follow it."
|
|
134
|
+
|
|
135
|
+
[[workflow.lenses]]
|
|
136
|
+
code = "prose"
|
|
137
|
+
name = "Editorial Prose"
|
|
138
|
+
applies_to = "docs"
|
|
139
|
+
after = "structure"
|
|
140
|
+
when = "Documents being copy-edited."
|
|
141
|
+
instruction = "Load `references/lens-prose.md` from the skill root and follow it."
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Editorial Lenses — Common Ground
|
|
2
|
+
|
|
3
|
+
Shared by the `structure` and `prose` lenses. Load this once; when both lenses run, the setup below is done once and serves both.
|
|
4
|
+
|
|
5
|
+
## Stance
|
|
6
|
+
|
|
7
|
+
Review a document as a clinical editor and return suggested fixes the author can accept or reject row by row. Two passes: **structure** (cuts, merges, moves, condensing — does the document's shape serve its purpose?) then **prose** (copy-edit for communication issues that impede comprehension). Which of the two run, and in what order, is decided by lens selection — see the skill's Execution section.
|
|
8
|
+
|
|
9
|
+
**Content is sacrosanct.** Never challenge ideas — only how they're organized and expressed. Propose, don't execute: the author decides what to accept.
|
|
10
|
+
|
|
11
|
+
The baseline style guide is `{workflow.style_guide}`; a style guide stated in the request wins over the configured one for that run. Where the style guide in effect conflicts with a generic principle here — including the reader calibration — the style guide wins. Nothing overrides content being sacrosanct.
|
|
12
|
+
|
|
13
|
+
## Setup
|
|
14
|
+
|
|
15
|
+
1. Gather inputs: the content (required — a path or pasted text), plus whatever the request states: purpose, target audience, length target, reader type, style guide. If no reviewable content was provided, say so and stop. Request-level values win; `{workflow.reader_type}` and `{workflow.style_guide}` fill what the request leaves unstated. Treat `{workflow.review_guidance}` entries as standing review directives.
|
|
16
|
+
2. When the content is a file, get exact word counts — document total and per heading section — via `uv run {skill-root}/scripts/word_metrics.py <path>` (`--help` documents the output), and ground every word-impact estimate and the reduction summary in those numbers. If the content was pasted or the script cannot run, estimate and mark the numbers as estimates.
|
|
17
|
+
3. Infer purpose and audience from the content and standing context when not provided, and open the output with your one-sentence read — "this document exists to help [audience] accomplish [goal]" — so the author can correct a wrong premise before acting on the findings.
|
|
18
|
+
|
|
19
|
+
## Reader calibration
|
|
20
|
+
|
|
21
|
+
Calibrate every finding to the reader type — stated in the request, else `{workflow.reader_type}`.
|
|
22
|
+
|
|
23
|
+
**humans** (default) — optimize for clarity, flow, and natural progression. These elements serve comprehension and engagement; preserve them unless clearly wasteful, and flag any recommendation that would cut one:
|
|
24
|
+
|
|
25
|
+
- Visual aids: diagrams, images, and flowcharts anchor understanding
|
|
26
|
+
- Expectation-setting: "What You'll Learn" helps readers confirm they're in the right place
|
|
27
|
+
- Reader's journey: organize content as a linear progression, not a database
|
|
28
|
+
- Mental models: overview before details prevents cognitive overload
|
|
29
|
+
- Warmth: encouraging tone reduces anxiety for new users
|
|
30
|
+
- Whitespace: admonitions and callouts provide visual breathing room
|
|
31
|
+
- Summaries: recaps help retention; they're reinforcement, not redundancy
|
|
32
|
+
- Examples: concrete illustrations make abstract concepts accessible
|
|
33
|
+
- Engagement: flow techniques (transitions, variety) are functional, not fluff — they maintain attention
|
|
34
|
+
|
|
35
|
+
**llm** — optimize for precision and unambiguity. An LLM-targeted document may run longer where explicitness pays and shorter where warmth was cut:
|
|
36
|
+
|
|
37
|
+
- Dependency-first: define concepts before usage to minimize hallucination risk
|
|
38
|
+
- Cut emotional language, encouragement, and orientation sections
|
|
39
|
+
- Reference well-known standards ("conventional commits", "REST APIs") instead of re-teaching them; be explicit where a concept is not well-known — and either way, ground the expectation with an example
|
|
40
|
+
- Consistent terminology: same word for same concept throughout
|
|
41
|
+
- No hedging ("might", "could", "generally") — direct statements
|
|
42
|
+
- Prefer structured formats (tables, lists, YAML) over prose
|
|
43
|
+
- Unambiguous references: no unclear antecedents ("it", "this", "the above")
|
|
44
|
+
|
|
45
|
+
## Findings shape
|
|
46
|
+
|
|
47
|
+
The editorial lenses render as a findings table rather than the canonical JSON fields. One findings table serves both passes:
|
|
48
|
+
|
|
49
|
+
| Pass | Original Text | Revised Text | Changes |
|
|
50
|
+
| --------- | ----------------------------------------------------- | --------------------------------------------- | -------------------------------------------------------------------- |
|
|
51
|
+
| structure | §Setup — full section (~180 words) | MERGE into §Installation | Duplicates the install steps; one source of truth (saves ~150 words) |
|
|
52
|
+
| prose | The system will processes data and it handles errors. | The system processes data and handles errors. | Fixed subject-verb agreement; removed redundant "it" |
|
|
53
|
+
|
|
54
|
+
Structure rows name the section or passage in **Original Text** and carry the tagged disposition (with move target or condensed rewrite) in **Revised Text**; prose rows quote the exact text and its revision. Order rows by comprehension impact; when a long document would produce more rows than an author can realistically act on, present the highest-impact rows and roll the rest into one closing line — "N further minor fixes; ask to expand." Above the table, give the purpose/audience read plus — when the structure pass ran — the chosen structure model. When the structure pass ran, close with a summary: total recommendations, estimated reduction (words and % of original, computed from the word-metrics counts) if all are accepted, whether a provided length target is met, and any comprehension trade-offs (cuts that sacrifice reader engagement for brevity). A pass that finds nothing is a valid result; say so.
|
|
55
|
+
|
|
56
|
+
Shape the table per `{workflow.output_preferences}`.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Adversarial Lens
|
|
2
|
+
|
|
3
|
+
You are a cynical, jaded reviewer with zero patience for sloppy work. The content was submitted by a clueless weasel and you expect to find problems. Be skeptical of everything. Look for what's missing, not just what's wrong. Use a precise, professional tone — no profanity or personal attacks.
|
|
4
|
+
|
|
5
|
+
This lens is attitude-driven and general-purpose: weaknesses, gaps, inconsistencies, unstated assumptions, unsupported claims, missing error handling, unaddressed risks — whatever the content type exposes. If `also_consider` areas were provided, weigh them alongside the normal analysis.
|
|
6
|
+
|
|
7
|
+
Review with extreme skepticism — assume problems exist. Find at least ten issues to fix or improve in the provided content. Every finding must point at something concrete in the content. Zero findings is suspicious for this lens — re-analyze before concluding, or ask for guidance; never return an empty result on the first pass.
|
|
8
|
+
|
|
9
|
+
## Findings shape
|
|
10
|
+
|
|
11
|
+
Emit each finding with the canonical fields:
|
|
12
|
+
|
|
13
|
+
- `location` — where in the content (file:line for code, section or heading for documents, "general" when it spans the whole artifact)
|
|
14
|
+
- `trigger_condition` — the problem, in one line
|
|
15
|
+
- `guard_snippet` — the concrete fix or improvement
|
|
16
|
+
- `potential_consequence` — what goes wrong if it ships unaddressed
|
|
17
|
+
|
|
18
|
+
No severity, priority, or ranking.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Edge-Case Lens
|
|
2
|
+
|
|
3
|
+
You are a pure path tracer. Never comment on whether the content is good or bad; only list missing handling. Your method is exhaustive path enumeration — mechanically walk every branch, not hunt by intuition. Report ONLY paths and conditions that lack handling — discard handled ones silently. Do not editorialize or add filler.
|
|
4
|
+
|
|
5
|
+
**MANDATORY: Execute the steps below IN EXACT ORDER. DO NOT skip steps or change the sequence. Each action within a step is a REQUIRED action to complete that step.**
|
|
6
|
+
|
|
7
|
+
**Scope rules:**
|
|
8
|
+
|
|
9
|
+
- When the content is a diff, scan only the diff hunks and list boundaries that are directly reachable from the changed lines and lack an explicit guard in the diff.
|
|
10
|
+
- When it is not a diff (full file, function, or document), the entire provided content is the scope.
|
|
11
|
+
- Ignore the rest of the codebase unless the provided content explicitly references external functions.
|
|
12
|
+
|
|
13
|
+
## Step 1: Exhaustive path analysis
|
|
14
|
+
|
|
15
|
+
Walk every branching path and boundary condition within scope — report only unhandled ones.
|
|
16
|
+
|
|
17
|
+
- If `also_consider` areas were provided, incorporate them into the analysis
|
|
18
|
+
- Walk all branching paths: control flow (conditionals, loops, error handlers, early returns) and domain boundaries (where values, states, or conditions transition). Derive the relevant edge classes from the content itself — don't rely on a fixed checklist. Examples: missing else/default, unguarded inputs, off-by-one loops, arithmetic overflow, implicit type coercion, race conditions, timeout gaps
|
|
19
|
+
- Consider implicit branches: the diff special-cases or changes the handling of one or more members of a fixed set of values — enums, status codes, sentinels, type tags, flags, value ranges. The rest of the set is implicit branches (e.g. the diff changes the `RED` and `YELLOW` cases of a `RED`/`YELLOW`/`GREEN` enum; `GREEN` is the implicit branch)
|
|
20
|
+
- For each path: determine whether the content handles it
|
|
21
|
+
- Collect only the unhandled paths as findings — discard handled ones silently
|
|
22
|
+
|
|
23
|
+
## Step 2: Validate completeness
|
|
24
|
+
|
|
25
|
+
- Revisit every edge class from Step 1 — e.g., missing else/default, null/empty inputs, off-by-one loops, arithmetic overflow, implicit type coercion, race conditions, timeout gaps
|
|
26
|
+
- Add any newly found unhandled paths to findings; discard confirmed-handled ones
|
|
27
|
+
|
|
28
|
+
## Step 3: Deletion check
|
|
29
|
+
|
|
30
|
+
Runs only when the diff removed or replaced meaningful code (ignore pure renames and whitespace). Subordinate to the edge-case pass; findings are usually few or none.
|
|
31
|
+
|
|
32
|
+
For each chunk of removed or replaced code, ask: did it carry behavior or a contract that the change neither re-established nor intentionally retired? Add a finding for any resulting regression, orphaned reference, or newly-dead code. Skip anything already covered by your edge-case findings. Add nothing if nothing qualifies.
|
|
33
|
+
|
|
34
|
+
Deletion findings go in the same array with the four standard fields plus:
|
|
35
|
+
|
|
36
|
+
- `kind`: `"deletion"`
|
|
37
|
+
- `confidence`: `"high"`, `"medium"`, or `"low"` — these are inferences; rate them
|
|
38
|
+
|
|
39
|
+
For a deletion finding the standard fields read as: `location` = the removed item; `trigger_condition` = the behavior or contract it enforced; `guard_snippet` = where or how to re-establish it; `potential_consequence` = the regression or orphan.
|
|
40
|
+
|
|
41
|
+
## Findings shape
|
|
42
|
+
|
|
43
|
+
Each edge-case finding contains exactly these four fields:
|
|
44
|
+
|
|
45
|
+
```json
|
|
46
|
+
[{
|
|
47
|
+
"location": "file:start-end (or file:line when single line, or file:hunk when exact line unavailable)",
|
|
48
|
+
"trigger_condition": "one-line description (max 15 words)",
|
|
49
|
+
"guard_snippet": "minimal code sketch that closes the gap (single-line escaped string, no raw newlines or unescaped quotes)",
|
|
50
|
+
"potential_consequence": "what could actually go wrong (max 15 words)"
|
|
51
|
+
}]
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
An empty array is valid when nothing is found. Do not assign severity labels, rankings, or priority levels.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Prose Lens
|
|
2
|
+
|
|
3
|
+
Load `references/editorial-common.md` from the skill root first and follow it — stance, setup, reader calibration, and findings shape are shared with the structure lens. When the structure lens ran ahead of this one, its findings are supplied to you; when this lens runs alone, there are none and the clauses below that depend on them do not apply.
|
|
4
|
+
|
|
5
|
+
You are a clinical copy-editor: precise, professional, neither warm nor cynical. First analyze the style, tone, and voice of the text and note intentional stylistic choices to preserve (informal tone, technical jargon, rhetorical patterns). Then copy-edit for communication issues that impede comprehension — never rewrite for preference, and apply the smallest fix that achieves clarity. Fix prose within the existing structure (shape problems belong to the structure pass). Skip code blocks, frontmatter, and structural markup. Preserve the author's voice and the stylistic choices you noted. When the structure pass ran, skip passages it tagged CUT, and attach fixes inside MERGE'd passages to the surviving location. Deduplicate: the same issue in several places is one row listing all locations, and merge overlapping fixes into single entries so no suggestions conflict. Phrase uncertain fixes as "Consider: …?" rather than definitive changes.
|
|
6
|
+
|
|
7
|
+
Emit rows with `Pass` = `prose`.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Structure Lens
|
|
2
|
+
|
|
3
|
+
Load `references/editorial-common.md` from the skill root first and follow it — stance, setup, reader calibration, and findings shape are shared with the prose lens.
|
|
4
|
+
|
|
5
|
+
You are a structural editor focused on high-value density. Brevity is clarity: concise writing respects limited attention spans and enables effective scanning. Every section must justify its existence — cut anything that delays understanding. True redundancy is failure — but comprehension sets the floor: optimize for the minimum words that maintain understanding. Front-load value: critical information comes first; nice-to-know comes last (or goes).
|
|
6
|
+
|
|
7
|
+
Load `references/structure-models.md`, pick the model matching the document's purpose, and evaluate the document against it. Hunt for: sections that don't serve the stated purpose, true redundancy (identical information with no reinforcement value), scope violations (content that belongs in a different document), buried critical information, premature detail, missing scaffolding, and the classic anti-patterns — FAQs that should be inline, appendices that should be cut, overviews that repeat the body verbatim. For human readers, also assess pacing: is there enough whitespace and visual variety to maintain attention? Tag each finding CUT, MERGE, MOVE, CONDENSE, QUESTION, or PRESERVE (explicitly keep something that looks cuttable but serves comprehension), and state its word impact from the word-metrics counts. If a length target was provided, assess whether the recommendations meet it.
|
|
8
|
+
|
|
9
|
+
Emit rows with `Pass` = `structure`.
|
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
name: bmad-review-verification-gap
|
|
3
|
-
description: 'Review a code change for changed behavior that could regress without reliable verification catching it. Use when checking whether a change is adequately verified.'
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Verification Gap Review
|
|
1
|
+
# Verification-Gap Lens
|
|
7
2
|
|
|
8
3
|
**Goal:** Find changed behavior that could break without reliable verification catching it. Ask one question — "if the behavior this change is supposed to produce broke where it's actually used, would verification fail?" Do not hunt for correctness bugs, but report genuine problems you notice while tracing verification.
|
|
9
4
|
|
|
@@ -13,7 +8,7 @@ The main verification gap shapes are:
|
|
|
13
8
|
2. **Missing-adoption gap:** a place that should now use the new behavior doesn't; it handles the same case its own way, or not at all, and no test would flag the omission.
|
|
14
9
|
3. **Broken-verification gap:** a test appears to cover the changed behavior, but would not actually protect it because it is skipped, flaky, not run in the normal verification path, or too weak to observe the regression.
|
|
15
10
|
|
|
16
|
-
## Evidence
|
|
11
|
+
## Evidence rules
|
|
17
12
|
|
|
18
13
|
- Read a test before claiming what it covers, runs, asserts, or misses.
|
|
19
14
|
- Before claiming no test exists, search the whole repo by the symbol under test and by import references; expected file locations are not enough.
|
|
@@ -21,11 +16,11 @@ The main verification gap shapes are:
|
|
|
21
16
|
- In a finding, say what you actually checked — "none of the tests I read cover this" — and show how far you looked. Say a test doesn't exist anywhere only when the symbol/import-reference search actually shows that.
|
|
22
17
|
- Do not assign severity, confidence, priority, or ranking.
|
|
23
18
|
|
|
24
|
-
## Review
|
|
19
|
+
## Review sequence
|
|
25
20
|
|
|
26
21
|
### Step 1: Screen for behavioral change
|
|
27
22
|
|
|
28
|
-
If the change is non-behavioral, stop here and output the
|
|
23
|
+
If the change is non-behavioral, stop here and return zero findings (`[]`); when the output format includes a markdown report, note there that the change is non-behavioral (a caller's exact zero-findings output contract wins over this note). Call it non-behavioral only when the changed code does not alter return values, thrown errors, caller-visible side effects, or observable state (including iteration order and emitted messages). After the changed code meets that test, stop; do not inspect callers or tests for extra confirmation.
|
|
29
24
|
|
|
30
25
|
Common non-behavioral examples: formatting, comments, whitespace; pure renames; trivial getters/setters and pass-throughs; type-only or compiler-enforced changes with no runtime effect; etc.
|
|
31
26
|
|
|
@@ -70,37 +65,18 @@ Before writing a finding, re-open the specific tests or search results the findi
|
|
|
70
65
|
|
|
71
66
|
Do not report: compiler/type-checker-enforced cases; behavior already verified by an integration, contract, or e2e test; implementation-detail or mock-only tests; low coverage or a missing test file by itself; legacy untested code the change did not affect.
|
|
72
67
|
|
|
73
|
-
Report genuine problems you noticed while tracing verification, even if they are not verification gaps
|
|
74
|
-
|
|
75
|
-
## OUTPUT FORMAT
|
|
76
|
-
|
|
77
|
-
Emit each verification-gap finding as one block. No general advice, no severity or confidence.
|
|
78
|
-
|
|
79
|
-
```markdown
|
|
80
|
-
### <one-line title naming the gap>
|
|
81
|
-
|
|
82
|
-
- **Changed surface:** the exact behavior or contract that changed — `file:line`.
|
|
83
|
-
- **Impacted consumer or site:** named concretely with `file:line` (e.g. "the `createInvoice` mutation used by the billing dashboard at `billing/dashboard.ts:88`," not "callers of this function").
|
|
84
|
-
- **Existing test evidence:**
|
|
85
|
-
- `Regression gap`: what the relevant test actually asserts, with `file:line`; or, if none, the symbol/import-reference searches run and their result.
|
|
86
|
-
- `Missing-adoption gap`: tests for the impacted site, and whether any assert it adopts the new behavior.
|
|
87
|
-
- `Broken-verification gap`: the apparent test or verification path, and why it does not count.
|
|
88
|
-
- **Missing verification:** the precise assertion or check that's absent.
|
|
89
|
-
- **Demonstration:**
|
|
90
|
-
- `Regression gap` / `Broken-verification gap`: the concrete regression that would ship undetected, and why the tests you checked would not fail.
|
|
91
|
-
- `Missing-adoption gap`: the case the site mishandles by not adopting the new behavior, and that none of the tests you read assert adoption.
|
|
92
|
-
- **Consequence:** the concrete thing that ships wrong — a regression the checked evidence would not catch, or a site that should use the new behavior and doesn't.
|
|
93
|
-
- **Suggested test shape:** (optional) the kind of test that would close the gap, fit to the repo's own way of verifying — don't impose a generic test pyramid.
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
If you noticed genuine non-gap problems while tracing verification, append:
|
|
68
|
+
Report genuine problems you noticed while tracing verification, even if they are not verification gaps — emit them as findings with `gap_shape: "other"`. This permits reporting what you already reached, not extra hunting.
|
|
97
69
|
|
|
98
|
-
|
|
99
|
-
## Other findings
|
|
70
|
+
## Findings shape
|
|
100
71
|
|
|
101
|
-
|
|
102
|
-
```
|
|
72
|
+
Emit each gap with the canonical fields plus this lens's extras:
|
|
103
73
|
|
|
104
|
-
|
|
74
|
+
- `location` — the changed surface: the exact behavior or contract that changed, `file:line`
|
|
75
|
+
- `trigger_condition` — the gap, in one line
|
|
76
|
+
- `guard_snippet` — the missing verification: the precise assertion or check that's absent, optionally with the test shape that would close it, fit to the repo's own way of verifying — don't impose a generic test pyramid
|
|
77
|
+
- `potential_consequence` — the concrete thing that ships wrong: the regression the checked evidence would not catch, or the site that should use the new behavior and doesn't, with why the tests you checked would not fail
|
|
78
|
+
- `gap_shape` — `"regression-gap"`, `"missing-adoption-gap"`, `"broken-verification-gap"`, or `"other"`
|
|
79
|
+
- `consumer` — the impacted consumer or site, named concretely with `file:line` (e.g. "the `createInvoice` mutation used by the billing dashboard at `billing/dashboard.ts:88`", not "callers of this function")
|
|
80
|
+
- `evidence` — what you actually checked: what the relevant test asserts with `file:line`; or, if none, the symbol/import-reference searches run and their result; for a broken-verification gap, the apparent test and why it does not count
|
|
105
81
|
|
|
106
|
-
`No verification gaps found.`
|
|
82
|
+
For `gap_shape: "other"` findings the four canonical fields suffice (description only); `consumer` and `evidence` are optional. An empty array is valid when the change is non-behavioral or every changed behavior is verified. When this lens comes up clean and a markdown report is presented, its clean statement for this lens is exactly: `No verification gaps found.`
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Structure Models
|
|
2
|
+
|
|
3
|
+
Reference shapes for the structure pass. Pick the one matching the document's purpose and evaluate the document against its rules; a document that fits none cleanly is judged against the closest model, with the mismatch itself noted as a finding when the shape fights the purpose.
|
|
4
|
+
|
|
5
|
+
## Tutorial/Guide (Linear)
|
|
6
|
+
|
|
7
|
+
**Applicability:** Tutorials, detailed guides, how-to articles, walkthroughs
|
|
8
|
+
|
|
9
|
+
- Prerequisites: setup/context MUST precede action
|
|
10
|
+
- Sequence: steps follow strict chronological or logical dependency order
|
|
11
|
+
- Goal-oriented: clear "Definition of Done" at the end
|
|
12
|
+
|
|
13
|
+
## Reference/Database
|
|
14
|
+
|
|
15
|
+
**Applicability:** API docs, glossaries, configuration references, cheat sheets
|
|
16
|
+
|
|
17
|
+
- Random access: no narrative flow required; the reader jumps to a specific item
|
|
18
|
+
- MECE: topics are Mutually Exclusive and Collectively Exhaustive
|
|
19
|
+
- Consistent schema: every item follows an identical structure (e.g., Signature → Params → Returns)
|
|
20
|
+
|
|
21
|
+
## Explanation (Conceptual)
|
|
22
|
+
|
|
23
|
+
**Applicability:** Deep dives, architecture overviews, conceptual guides, whitepapers, project context
|
|
24
|
+
|
|
25
|
+
- Abstract to concrete: Definition → Context → Implementation/Example
|
|
26
|
+
- Scaffolding: complex ideas built on established foundations
|
|
27
|
+
|
|
28
|
+
## Prompt/Task Definition (Functional)
|
|
29
|
+
|
|
30
|
+
**Applicability:** BMad skills and workflows, prompts, system instructions, agent definitions
|
|
31
|
+
|
|
32
|
+
- Meta-first: inputs, usage constraints, and context defined before instructions
|
|
33
|
+
- Separation of concerns: instructions (logic) separate from data (content)
|
|
34
|
+
- Explicit flow: execution order is stated, never implied
|
|
35
|
+
|
|
36
|
+
## Strategic/Context (Pyramid)
|
|
37
|
+
|
|
38
|
+
**Applicability:** PRDs, research reports, proposals, decision records
|
|
39
|
+
|
|
40
|
+
- Top-down: conclusion/status/recommendation starts the document
|
|
41
|
+
- Grouping: supporting context grouped logically below the headline
|
|
42
|
+
- Ordering: most critical information first
|
|
43
|
+
- MECE: arguments/groups are Mutually Exclusive and Collectively Exhaustive
|
|
44
|
+
- Evidence: data supports arguments, never leads
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# /// script
|
|
3
|
+
# requires-python = ">=3.10"
|
|
4
|
+
# ///
|
|
5
|
+
"""Tests for word_metrics.py."""
|
|
6
|
+
|
|
7
|
+
import sys
|
|
8
|
+
import unittest
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
|
|
12
|
+
|
|
13
|
+
from word_metrics import section_metrics, word_count
|
|
14
|
+
|
|
15
|
+
DOC = """Intro line before any heading.
|
|
16
|
+
|
|
17
|
+
# Title
|
|
18
|
+
|
|
19
|
+
Two words here indeed.
|
|
20
|
+
|
|
21
|
+
## Section A
|
|
22
|
+
|
|
23
|
+
Alpha beta gamma.
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
# not a heading
|
|
27
|
+
fenced words ignored as headings
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Section B
|
|
31
|
+
|
|
32
|
+
Delta epsilon.
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class WordMetricsTest(unittest.TestCase):
|
|
37
|
+
def test_word_count(self):
|
|
38
|
+
self.assertEqual(word_count("one two three\nfour"), 4)
|
|
39
|
+
self.assertEqual(word_count(""), 0)
|
|
40
|
+
|
|
41
|
+
def test_sections_split_on_headings(self):
|
|
42
|
+
sections = section_metrics(DOC)
|
|
43
|
+
headings = [s["heading"] for s in sections]
|
|
44
|
+
self.assertEqual(headings, ["(preamble)", "Title", "Section A", "Section B"])
|
|
45
|
+
|
|
46
|
+
def test_fenced_heading_not_a_section(self):
|
|
47
|
+
sections = section_metrics(DOC)
|
|
48
|
+
self.assertNotIn("not a heading", [s["heading"] for s in sections])
|
|
49
|
+
|
|
50
|
+
def test_section_words_counted(self):
|
|
51
|
+
sections = {s["heading"]: s["words"] for s in section_metrics(DOC)}
|
|
52
|
+
self.assertEqual(sections["Section B"], 2)
|
|
53
|
+
# Section A body includes the fenced block's tokens
|
|
54
|
+
self.assertGreater(sections["Section A"], 3)
|
|
55
|
+
|
|
56
|
+
def test_empty_preamble_dropped(self):
|
|
57
|
+
sections = section_metrics("# Only\n\nwords here\n")
|
|
58
|
+
self.assertEqual([s["heading"] for s in sections], ["Only"])
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
if __name__ == "__main__":
|
|
62
|
+
unittest.main()
|