bmad 6.11

This commit is contained in:
2026-08-14 17:08:24 +02:00
parent 0edaef0be7
commit 373857c868
268 changed files with 26063 additions and 0 deletions
@@ -0,0 +1,8 @@
# Draft
Build a deep-research prompt the user runs themselves — in conversation, fast, not a project. The pack's craft travels inside the prompt so the outside tool works to this harness's standard.
1. Open the floor before any structured questions: invite the decision they're facing and anything they already have — briefs, links, a prior report, half-formed constraints — in one turn, then ask only what's still missing. Nail the **decision**, topic, and type; load the pack. Ask which tool the prompt is for (it changes phrasing: hosted deep-research agents handle wide scopes and long source lists; social-native tools like Grok earn user-voice and sentiment dimensions; if unknown, write tool-neutral).
2. Compose the prompt from the pack: the dimensions as explicit research questions pruned to the decision, the freshness bars as recency requirements, the two-source expectation for its critical claim classes, the audience, the source policy — `{workflow.preferred_sources}` named as sources to prefer, `{workflow.banned_sources}` as sources never to cite — and a **non-negotiable citation demand**: every claim with source URL and publication date, contrary evidence reported, gaps admitted rather than padded. Structure the requested output so Process can extract it cleanly (findings per dimension, a source list).
3. Bind `{doc_workspace}`: expand the folder name deterministically (`uv run scripts/recon_kit.py slug "<topic>" --type <type> --pattern "{workflow.run_folder_pattern}"` — same expansion every mode, so the report comes back to the same folder) under `{workflow.research_output_path}`, init the memlog with the decision context, save the prompt as `{doc_workspace}/brief.md`, and present it paste-ready in chat.
4. Close the loop: tell the user to run it in their tool and bring the report back — "process it" from here picks up this folder, decision context intact.
@@ -0,0 +1,11 @@
# Finalize
Every mode ends here once `research.md` is assembled.
1. `research.md` is complete per `references/synthesis.md`: decision-first summary, findings, contrary evidence where found, recommendations with downstream bindings, source appendix, staleness map. Frontmatter metadata (`type`, `topic`, `decision`, `source`, `status`, dates) is what lets every downstream consumer trust it without reprocessing.
2. **Citation check — mechanical, then semantic.** Run `uv run scripts/recon_kit.py citations {doc_workspace}/research.md` — it diffs inline `[n]` markers against the appendix and lists dangling markers and orphaned rows exactly; fix what it reports. Then a fresh-context subagent does only the judgment half: does each cited source actually say what the text claims? It never rewrites findings — a claim whose source doesn't back it gets its confidence downgraded and the mismatch logged as an `event`.
3. Render per `{workflow.output_format}` (see `references/html-briefing.md`): `auto` renders the briefing page on interactive runs, skips on headless/skill-invoked; `html`/`both` always; `md` never. `research.md` always exists — the briefing is its regenerable face.
4. Polish: apply each `{workflow.doc_standards}` entry (a `skill:`, `file:`, or plain-text directive) to `research.md`.
5. Execute each `{workflow.external_handoffs}` entry (NotebookLM, Confluence, …) — invoke the named tool, surface returned URLs; skip and flag unavailable tools.
6. Tell the user what exists and where — report, briefing, imports, memlog — plus what the staleness map says to re-check and when, and that Refresh/Deepen handle it. Invoke `bmad-help` to suggest the next step.
7. Run `{workflow.on_complete}` if non-empty — a string is one instruction, an array is a sequence.
@@ -0,0 +1,16 @@
# HTML Briefing
Generate `research-briefing.html` in `{doc_workspace}` after `research.md` is final, when `{workflow.output_format}` calls for it: `"auto"` renders on interactive runs and skips on headless/skill-invoked runs (the md is always there to render from later), `"html"`/`"both"` always render, `"md"` never. The page is a full-fidelity presentation of the report, never a second source of truth — same claims, same numbers, same citations; nothing is lost by reading it instead of the markdown.
## Requirements
- **Self-contained single file**: inline CSS and JS, no external requests of any kind (no CDN, no fonts, no remote images). It must render from a `file://` open, offline, forever.
- **Structure**: a header (topic, type, decision, date, depth, verification level) → the executive summary as the opening card → sticky table of contents → dimension sections → contrary evidence (when present) → recommendations → collapsible source appendix → staleness map.
- **Confidence is visual**: every claim carries its badge — verified / medium / low / `unverified` / disputed — color-coded with the status text always present (never color alone). Unverified and disputed must be *more* prominent than verified, not less.
- **Sources are live**: inline `[n]` markers link to the appendix row; appendix rows link out to the source URL. Source URLs are untrusted content — never hand-escape them: generate the appendix table with `uv run scripts/recon_kit.py escape-sources {doc_workspace}/research.md` and embed its `html` output, which escapes every cell, anchors each row (`id="src-n"`), and links only validated `http(s)` URLs (anything else renders as plain text; the script lists it in `invalid_urls`). Apply the same escape discipline to any other source-derived text you place in attributes.
- **Charts sparingly**: only where the data genuinely benefits (market size trajectory, decision matrix scores) — simple inline SVG, labeled axes, no library.
- **Responsive and theme-aware**: readable on a phone; respect `prefers-color-scheme` for light/dark.
## Theme
`{workflow.html_theme}` governs: a `file:` path loads a theme/brand spec to follow; inline text is applied as directives; empty means the shipped default — neutral, professional, generous whitespace, system font stack, one restrained accent color. Whatever the theme, the confidence-badge semantics above are non-negotiable.
@@ -0,0 +1,11 @@
# Refresh and Deepen
Lifecycle intents on an existing run folder.
## Refresh
Read `research.md` and `.memlog.md` — never re-research from scratch. Build the refresh set mechanically: assemble the claims (`claim`, `class`, `pub_date`) from the ledger, map the pack's freshness bars to a months-per-class JSON, and run `uv run scripts/recon_kit.py staleness <claims.json> --windows '<map>'` — the stale flags are the candidate set. Confirm it in one exchange, re-verify just those claims, and deliver a **delta report** (confirmed / changed / overturned, new sources) appended to `research.md` with the frontmatter `updated` bumped. Claims outside the set keep their status. An overturned load-bearing claim triggers an explicit warning naming the downstream artifacts that consumed it.
## Deepen
Drill into one dimension or add a new one without touching the rest: mini plan gate, acquire → verify for that slice only (or a drafted follow-up prompt when the user's tool is better placed), merge into `research.md`, update only the synthesis sections the new material affects — a deepening that changes no conclusion says so.
@@ -0,0 +1,10 @@
# Process
For a report the user names or drops ("there's a research report at <path>, process it"):
1. **File it.** Find or create the run folder: if a drafted brief for this topic exists, that folder is the target; otherwise infer type and topic from the report (confirm in one line), bind `{doc_workspace}` (expand the folder name with `uv run scripts/recon_kit.py slug` as in Draft), and init the memlog. Move or copy the original into `{doc_workspace}/imports/` untouched — full fidelity is preserved there, and nowhere else.
2. **Record provenance** in the memlog: what produced it (which tool or firm), when (ask if not evident — production date drives staleness), and what the user wants decided from it.
3. **Extract.** A subagent (fresh context, firewall rules) reads the import and pulls every claim bearing on the decision into digest files under `{doc_workspace}/digests/` — standard shape `{claim, source, publisher, pub_date, accessed, confidence, class}`, keeping the original's citations (the cited source is the publisher; the import is the via). Multiple imports each get their own digest; contradictions between them are findings, not noise.
4. **Check against the pack**: which of the type's dimensions the material covers, which are open, where its claims fall inside two-source classes but rest on one publisher. Verification per the resolved `validation` level (`references/verification.md`) — at `normal` this is a spot-check of the load-bearing claims only, minutes not hours.
5. **Distill** into `research.md` per `references/synthesis.md` — the succinct, cited, decision-first summary with full metadata frontmatter (topic, type, decision, `source:` provenance, dates, status). This is the artifact downstream skills read; nobody ever reprocesses the import. Open dimensions are listed honestly with a one-line route: draft a follow-up prompt, or a targeted Run on the gap.
6. Finalize per `references/finalize.md`.
@@ -0,0 +1,73 @@
# Run
Native research, when chosen: resolve effort, hold the plan gate, then run the acquisition loop once per dimension of the approved plan, in plan order.
## Effort
Three knobs bundled in a **preset**; any knob pins individually, and **what the user says in the request beats both**.
| Preset (`{workflow.preset}`) | subagents | sources/round | depth |
|---|---|---|---|
| `quick` | low (2) | 5 | 1 |
| `standard` (default) | normal (3) | 8 | 2 |
| `deep` | high (6) | 12 | 3 |
- **subagents** — parallel assistants: `none` (0 — inline, sequential; also the no-subagent-harness fallback), `low` (2), `normal` (3), `high` (6, cap 10 — beyond the 35 sweet spot only for genuinely wide work).
- **max_sources_per_round** — distinct sources actually read per dimension per round (cap 25).
- **max_depth** — rounds per dimension: initial pass plus lead-following follow-ups (cap 5). A cap, not a quota — dimensions stop early on coverage or novelty exhaustion.
- **validation** (orthogonal to preset, default `normal`) — rigor rises `normal` < `high` < `max`; level semantics live in `references/verification.md`. Verification happens per dimension as material lands, never as an end-of-run rewrite pass.
`{workflow.subagent_models}` is an ordered model preference for assistants — first available wins; empty means harness default. Keep the lead on the strongest model; researchers at most one tier down; judgment work never on the smallest tier.
## The plan gate
The one hard stop, kept light: decision, type and pack-derived dimensions pruned to it, shape, the **decomposition topology***breadth-first* (independent sub-questions: assistants split the dimensions), *depth-first* (one question that needs several perspectives: assistants split by angle or methodology, not by dimension), or *straightforward* (a focused ask: one assistant, a handful of calls, no fan-out — never overinvest in a simple query) — knobs in force and where each came from, which search surfaces exist (harness web search; installed search-shaped MCP tools; `{workflow.external_sources}` — check, don't assume), whether to run the fan-out as a workflow when the harness offers orchestration and `{workflow.use_workflows}` allows, and an honest time estimate (a standard run is minutes; deep runs are tens of minutes and many times the tokens).
Present as a compact checklist, get approval, then: bind `{doc_workspace}` under `{workflow.research_output_path}` — expand the folder name with `uv run scripts/recon_kit.py slug "<topic>" --type <type> --pattern "{workflow.run_folder_pattern}"` so the same topic always resolves to the same folder — seed `research.md` from `{workflow.research_template}`, init the memlog (`uv run {project-root}/_bmad/scripts/memlog.py init --workspace {doc_workspace} --field topic="<topic>" --field type="<type>" --field decision="<decision>" --field preset="<preset>"`), log the approved plan as a `decision`, and tell the user the path.
Each dimension then runs in **rounds** — up to the resolved `max_depth` — and the report grows as material lands: the user watches the document build, not a spinner. Every digest is written to `{doc_workspace}/digests/` the moment it exists — one file per assistant per round (`<dimension>-r<round>-<n>.md`), the digest shape below, raw enough to re-derive from.
## Rounds and lead-following
Round 1 pursues the plan's questions **broad-first**: short, wide queries to map what exists, narrowing as the shape emerges — not long specific queries that return nothing. After each round, harvest the leads: new entities worth chasing, unexpected connections, contradictions between sources, and questions the round opened. Contradictions get priority. Promising leads become the next round's brief; note mid-course discoveries in the checkpoint so the user sees the turn happening.
A dimension stops before its round cap when either holds:
- **Coverage** — its plan questions are answered, with the critical claims confirmed per the resolved `validation` level.
- **Novelty exhaustion** — a full round surfaced no new load-bearing claim or lead.
Say which one ended it. Hitting the round cap with open questions is reported as an open question, never silently dropped.
**Stop-and-write valve.** If the run is dragging well past the plan gate's estimate — rounds queuing, budgets mostly spent — stop spawning, synthesize from the digests already on disk, and report the remainder as open questions with a route (a Deepen later, or a drafted prompt for the user's own tool). A shorter honest report beats a longer stale one.
## The fan-out
Fan out researcher assistants for the round — concurrency per the resolved `subagents` level, split by the plan's **topology**: breadth-first gives each assistant independent sub-questions; depth-first gives each a distinct perspective or methodology on the *same* question; straightforward is one assistant with a small budget — never fan out what one focused assistant answers. Each assistant runs behind the **research firewall**: it gets its brief and nothing else — no project files, no ambient context. The brief contains:
- the questions it owns, the decision they serve, and the topic
- its search surfaces (specialized tools first — installed search-shaped MCP tools, `{workflow.external_sources}` entries whose directive matches — then generic search), plus `{workflow.preferred_sources}` first / `{workflow.banned_sources}` never
- the pack's source craft and freshness bars, and the source-quality card below
- its budgets — sources (the round's share of `max_sources_per_round`) and tool calls, scaled to its task: under 5 for a simple lookup, ~5 medium, ~10 hard, 15 for genuinely multi-part, 20 never exceeded. Either budget spent → synthesize what it has
- the query craft: short queries (roughly five words or fewer) beat hyper-specific ones that return nothing; broaden when results are sparse, narrow when abundant; never repeat an identical query on the same tool; after every tool result, pause and evaluate — what did this add, what gap remains, what's the best next query — before firing again
- the epistemics rules verbatim, and the return contract: a digest, not raw results — findings as claims, each with `{claim, source, publisher, pub_date, accessed, confidence, class}`, plus leads worth chasing and what it looked for and could not find
**On each return, write the digest to `{doc_workspace}/digests/` before doing anything else with it.**
Spawn assistants on `{workflow.subagent_models}` when set (first available wins); otherwise the harness default — judgment work never drops to the smallest tier. When subagents are unavailable (or `subagents` is `none`), run the same rounds yourself, sequentially, under the same budgets and the same files-first discipline.
When workflow orchestration was approved at the plan gate, run the fan-out as a workflow: dimensions as parallel pipelines, assistants returning structured digests. The budgets, digest contract, firewall, and stopping rules apply unchanged — and however the acquisition parallelizes, digests land as files and the lead alone writes `research.md`, committing sections in plan order.
## Source quality
One card, applied by every assistant and the lead alike. Prefer **primary sources** — filings, regulator text, official documentation, original papers, a company's own reported numbers — over aggregators and secondary reporting. Red flags that downgrade confidence on sight: speculative language ("could", "may", projections in future tense presented as findings), marketing register, passive voice with unnamed sources, cherry-picked or unsourced numbers, and aggregators recycling a single upstream report (that's one publisher, however many domains echo it). Answer engines (Perplexity Sonar, Grok, and kin) are aggregators too, however good the synthesis: chase their citations and cite those, never the engine. Conflicts resolve by recency, consistency with adjacent established facts, and publisher quality — never by averaging.
## Synthesize the dimension
When a dimension's rounds are done:
1. Verify at landing per `references/verification.md` — at `normal` validation this is a spot-check of the dimension's load-bearing claims, not a sweep.
2. Write the dimension's section per the pack's skeleton from its digest files — findings woven into prose answering the dimension's questions, every load-bearing claim cited inline `[n]`, confidence flagged where below high, contradictions reported with both sides cited. Append to `research.md` and add its sources to the running source table.
3. Log one memlog line per source batch (`--type source`) and one per load-bearing claim worth tracking for refresh — `--type claim`, text in the machine-readable shape `ref=[n] status=<verified|unverified|disputed|overturned> class=<class> pub=<YYYY-MM> — <claim>` so `scripts/recon_kit.py tally` and `staleness` can read the ledger; a later status change is a fresh claim line with the same `ref=` (last status wins).
4. Checkpoint: one or two lines in chat — what the dimension found, anything surprising, anything unresolved. Keep moving unless the user speaks up; a mid-run scope change is logged as a `decision` and the plan adjusts. Headless: skip checkpoints entirely.
When all dimensions are done, proceed to `references/synthesis.md` for final assembly.
@@ -0,0 +1,13 @@
# The Select Shape
When the decision is **choose between candidates** — technologies, vendors, libraries, platforms, agencies, anything — this method layers over whichever research type fits the subject. The type pack still governs sources, craft, and freshness; this shape governs the flow and the verdict.
1. **Requirements frame.** What must the winner do, under what constraints — scale, compliance, budget, team skills, existing stack, exit-cost tolerance? Split hard gates from weighted preferences and set the weights. Sources: the project itself (brief, PRD, spine, `{workflow.persistent_facts}`, codebase) and the user — web research does not set requirements. **Agree the frame before any candidate research runs**; interactive runs confirm it even though the plan gate approved the dimension list.
2. **Candidate screen.** Establish the credible field — leaders, strong challengers, one wildcard — and cut anything failing a hard gate. Screen to 35 finalists; record the cuts and why. Screening sources ≤ 6 months old — this field moves.
3. **Evidence per criterion.** Score finalists against the frame using the type pack's dimensions and craft, verified against current versions/offerings. Cite every contested cell; where vendor claims and independent experience diverge, the divergence is a finding.
4. **Cost & lock-in.** Total cost over the product's horizon — license/subscription, hosting, operational load, learning curve — and the cost of leaving. Current pricing pages read directly (≤ 3 mo, always); pricing-change history — a vendor that repriced once will again; migration-away accounts for real exit costs.
5. **Verdict.** The weighted decision matrix — show the scoring, not just totals; a matrix the user can re-weight is worth more than a verdict they must trust. Then: the pick; the named runner-up and the conditions under which it wins instead; the strongest argument against the pick (from the red-team pass when it ran); the cheapest reversibility hedge (abstraction seam, pilot scope, exit test).
**Two-source classes (added to the type's own):** pricing figures; performance/scale numbers; any cell that decides between the top two finalists.
**Staleness:** a selection report older than two quarters should be refreshed before anyone acts on it — say so in the report.
@@ -0,0 +1,16 @@
# Synthesis
The report answers the decision — whether the material came from a native Run or a processed import. **Succinct is the contract**: findings and verdicts, not essays; rationale lives in the memlog; a reader gets the decision-relevant truth in minutes. For Process mode this is the whole point — the summary is what downstream consumers read so nobody reprocesses the original, and sections with nothing behind them collapse to a line rather than pad.
Assemble `research.md` in this order, shaped by `{workflow.audience}` and written in `{document_output_language}`:
1. **Executive summary** — decision-first: what the evidence says to do, the two or three findings that drive that answer, and the biggest caveat. One page maximum, readable standalone. Written last, placed first.
2. **Dimension sections** — already written during the loop; now reconciled: consistent terminology, no duplicated ground, verification statuses and any corrections from the pass applied to the text.
3. **Cross-dimension insights** — what only the *combination* shows (e.g. the market is growing but the regulatory dimension caps the reachable segment; the technically superior option loses on ecosystem health). This section is the harness earning its keep — if there are no cross-dimension insights, say so rather than manufacture them.
4. **Contrary evidence** — when the red-team pass ran and found material; the strongest surviving counter-arguments, cited.
5. **Recommendations** — each bound to the decision and, where the project has them, to the downstream artifact that consumes it (per the pack's `Feeds` entries: brief section, PRD input, architecture constraint). Each recommendation names its confidence basis; a recommendation resting on low-confidence or disputed claims says so in the same sentence.
6. **Open questions** — what the research could not answer, and what it would take to answer each.
7. **Source appendix** — the numbered source table: `[n] | claim/finding it supports | publisher | pub date | accessed | confidence`, the publisher cell a markdown link to the source URL. Every inline `[n]` resolves here.
8. **Staleness map** — the claims that age fastest, computed not hand-derived: build the claims list (`claim`, `class`, `pub_date`) from the ledger, map the pack's freshness bars to months per class, and run `uv run scripts/recon_kit.py staleness <claims.json> --windows '<map>'` — render its re-check dates and close by noting the earliest. This is Refresh's work order.
Update the frontmatter (`status: complete`, `updated`, and the verified/unverified counts from `uv run scripts/recon_kit.py tally {doc_workspace}/.memlog.md` — never hand-counted), log a final `event` in the memlog, and proceed to `references/finalize.md`.
@@ -0,0 +1,29 @@
# Verification
The trust layer — the same rules whatever produced the material (a native run's digests or a processed import). Verification happens **as material lands**, per dimension, in fresh-context verifier subagents reading digest files — never as an end-of-run rewrite pass over an hour of accumulated context. Late-pass rewrites degrade reports; landing-time checks improve them.
## The claims ledger
The memlog `claim` entries are the ledger: every claim a decision could rest on, with its class (each pack names its classes — quantitative sizes, pricing, versions/compatibility, regulatory assertions, …), source, publisher, publication date, and status. New claims enter `unverified`; on a Refresh or Deepen run, claims outside the run's scope keep their prior status from the memlog — only new and in-scope claims are (re)checked.
## Levels
Per the resolved `validation` level (request > knob > default `normal`):
- **normal** — spot-check the **load-bearing claims only**: the handful per dimension the recommendation actually rests on. One independent-source check each, at landing. Everything else ships with its single source cited and confidence marked honestly. Fast by design.
- **high** — cross-check every claim in the pack's *two-source classes*, and run the red-team pass on major conclusions regardless of `{workflow.red_team}`.
- **max** — cross-check every ledger claim, run the red-team pass below at full breadth (every major conclusion), and primary-source-priority ranking: where a primary source (filing, regulator text, official docs, original paper) exists, secondary reporting alone does not verify.
Verifier assistants run behind the research firewall on `{workflow.subagent_models}` when set; judgment work never drops to the smallest tier.
**Independent** means a different publisher with different underlying data or reporting — not a syndication, quote, or republication of the first source, and not the same vendor's marketing in two places. An imported report counts as one publisher regardless of how many sources it cites internally; two imports from different tools agreeing is genuine confirmation, and their disagreement is a finding.
Outcomes per claim: **verified** (independent source agrees within tolerance — for quantitative claims, same order of magnitude and direction), **disputed** (independent sources materially disagree — report both figures, both cited; never average), **unverified** (no independent check within budget — the claim stays, flagged, and joins the staleness map), or **overturned** (the weight of evidence contradicts it — corrected in the text, original noted). Every status change lands in the memlog as a fresh `claim` line with the same `ref=` and the new status — last status wins, which is how `scripts/recon_kit.py tally` reads the ledger. A verification outcome adjusts status and flags — it never licenses rewriting a finding's substance beyond what the new evidence says.
Confidence rendered in the report: **high** (verified, fresh, credible publishers), **medium** (single credible source, fresh), **low** (stale, weak publisher, or disputed) — plus the explicit `unverified` flag. Confidence is per-claim, never per-section.
## Red-team pass
The single adversarial mechanism — no other verifier duplicates it. Off by default (`{workflow.red_team}` = `"off"`; `"offer"` proposes it at the plan gate, `"on"` always runs; `high` validation includes it for major conclusions, `max` runs it at full breadth). When it runs: for each major conclusion, a **fresh-context** skeptic subagent — the conclusion and a search budget, no supporting evidence, no run context — hunts for disconfirming evidence: the bear case, failed attempts, contrary data, the strongest good-faith argument the conclusion is wrong.
What comes back is weighed, not appended: a conclusion that survives gets its strongest counter-argument acknowledged in the synthesis; one that doesn't is revised before the report states it. Material findings land in a **Contrary Evidence** section with full citation discipline. Zero findings after a real search is itself reportable — say what was searched for and not found.