Add Bmad-Method files and some brand-design artifacts!
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
# Build Process
|
||||
|
||||
This is one loop, not a sequence of phases. It carries Build and Edit, because an edit is the same loop pointed at a skill that already exists. The order below is the usual order of discovery, but nothing forces you to march through it; you pursue whichever outcome the conversation is ready for and you revisit earlier ones as the picture sharpens. Each outcome is a thing you want to be true, not a step you check off.
|
||||
|
||||
Load `references/prompt-quality-canon.md` before anything else and hold it as the governing standard for every line you draft — this file deliberately does not restate it, so a section below that names a canon test expects you to already carry it.
|
||||
|
||||
Load `references/skill-quality-principles.md` alongside it for the BMad-specific knowledge the scanners verify against, and `references/standard-fields.md` for frontmatter and naming conventions. Load `references/producing-workflow-patterns.md` when the skill produces an artifact, runs across turns, or serves more than one intent (persona, intent modes, graceful degradation). Load `references/working-state-patterns.md` when the skill holds state across turns — it builds something revisable, or an existing skill already carries a `.memlog.md` or a structured working artifact. Load `references/complex-workflow-patterns.md` only when the skill is large enough to carve work out to `references/` (carve-out conventions, multi-stage routing, module metadata).
|
||||
|
||||
## Open by understanding why the user came
|
||||
|
||||
Before you read a single artifact, understand what the user is actually trying to get done and what "good" looks like to them. The open-floor invitation in activation does most of this work, so read what they dumped and mine the conversation history for the tools, the sequence, the corrections, and the inputs and outputs they have already shown you. Then ask only the gaps that remain. On an edit, this means reading the part of the existing skill the change touches and ignoring the rest, rather than re-deriving the whole spec.
|
||||
|
||||
## Ground it in real expertise
|
||||
|
||||
A skill drafted from the model's general knowledge ships generic procedure; the value is in what only this project knows. Ask for the sources that carry it: runbooks and internal docs, incident reports and their resolutions, code-review comments, version-control history, or a transcript of the task done by hand once — the corrections the user made along the way are exactly the gotchas the skill exists to encode. And when the skill is extracted from one worked example, make it teach the method rather than that instance's answer: the approach must generalize to the next input even where individual details stay specific.
|
||||
|
||||
## Harden the idea before you build it
|
||||
|
||||
A skill is cheap to generate and expensive to live with, so push on the idea before drafting rather than building the first description you hear. Pressure-test the shape: is this one skill or three, is it a skill at all or a one-off the user could just ask for directly, what is the single outcome and who consumes it, what real input does it run on, and where would it be thin or fail. Push back where the idea is half-formed, because a builder that accepts a vague idea ships a vague skill.
|
||||
|
||||
Calibrate to the user. When they arrive with a hardened, specific idea or say they want to move fast, confirm the shape and proceed without belaboring it. When the idea is raw, stay in the hardening conversation until the outcome and scope are clear, and for a genuinely exploratory idea offer `bmad-forge-idea` to pressure-test it or `bmad-brainstorming` to widen it before building.
|
||||
|
||||
Do not reduce this to a few multiple-choice questions and jump to building. The quiz-and-go feels efficient and skips the part that most determines whether the skill is worth building at all.
|
||||
|
||||
## Propose what the idea implies
|
||||
|
||||
Hardening cuts the idea down; this builds it out. Before drafting, offer what the user did not ask for but the outcome implies: the patterns in `references/skill-quality-principles.md` whose conditions this skill meets, the sibling intent the artifact obviously wants (update or validate beside create), the input it should accept that nobody mentioned. A line each with why it fits; the user picks, and the declines land in the memlog so a later session does not re-propose them. A builder that only executes the stated idea ships the user's first draft of it.
|
||||
|
||||
## Capture continuously into the memlog
|
||||
|
||||
As decisions and directions land, write them to `{target-skill-path}/.memlog.md` through `{project-root}/_bmad/scripts/memlog.py` (`init` once when the target is named, then `append --type <decision|direction|assumption|gap|note|event>` as things happen). For a new skill, propose a kebab-case name when the user did not give one; renaming later is a logged decision, not a redo. The memlog is the canonical process memory, the source for resume, and the trail you audit at handoff so the user can confirm their thinking was handled the way they meant. Capture as you go, not in a batch at the end, because the value is in catching the reasoning while it is still fresh.
|
||||
|
||||
## Write the minimal outcome-driven version first
|
||||
|
||||
For a new skill, scaffold with `uv run scripts/init_skill.py --name "<name>" --dest {bmad_builder_output_folder}` (add `--dirs references,scripts,assets` only for the directories this build needs, `--customizable` only after the customization ask lands yes); it normalizes the name, writes SKILL.md from the template, and returns JSON paths.
|
||||
|
||||
Draft the canon's small version: the smallest skill that could possibly work, written as destination rather than route. Everything else stays out until a comparison earns it. Default to writing the whole workflow inline in SKILL.md as named sections, carving per the canon's relevance test with the BMad carving conventions in `references/skill-quality-principles.md`.
|
||||
|
||||
## Run it on real input and reach for eval at the eval beat
|
||||
|
||||
A skill that has never run is a guess. Run the minimal version on the real, messy input the user actually has. This is the eval beat, and it is where you invoke `bmad-eval-runner`. Offer baseline mode to confirm the skill beats the bare model on the same input, because a skill that does not beat the bare model has no reason to exist. Offer trigger mode to harden the description against near-miss queries. Both are opt-in; surface them, explain what each one settles, and let the user decide.
|
||||
|
||||
Read the transcripts, not just the outputs. Three trace shapes each name their own fix: the model trying several approaches before one works means an instruction is too vague; the model following an instruction that does not apply to the input means it is too broad; the model stalling among alternatives means no default was named.
|
||||
|
||||
Eval cases live at `{target-skill-path}/evals/cases.json`. `{workflow.evals_required}` overrides the opt-in default. When it is empty (default), the modes stay opt-in as above. When it is set, evals are a ship gate: `"baseline"` requires a passing baseline run before the build is done; `"any"` requires at least one case to exist and pass. If a required run fails or cannot be produced, the build is blocked, not shipped.
|
||||
|
||||
## Add scaffolding only when a comparison demands it
|
||||
|
||||
Do not add structure on a hunch. Add it only when the canon's two-version comparison shows the minimal version failing on something concrete you can name. If you find yourself reaching for more structure, first ask whether a sharper outcome statement would have produced the same result; most of the time it would, so sharpen the sentence and skip the scaffold.
|
||||
|
||||
## Hunt for script opportunities throughout
|
||||
|
||||
This is the builder's differentiator, so keep it active the whole way through rather than treating it as a single checkpoint. Apply the determinism test and the signal-verb scan from `references/script-opportunities-reference.md` to anything the skill does, prefer native Python, and propose the pre-pass JSON pattern wherever the model would otherwise read raw files to extract facts a script could hand it. If eval transcripts show the model re-writing the same helper across runs, that is the signal to bundle it as a script once. List any non-stdlib dependency and confirm it with the user before relying on it.
|
||||
|
||||
## Decide customization with the explicit ask
|
||||
|
||||
`references/customize-toml-guide.md` owns this decision. Load it at this beat and follow it: ask its question once (interactive only, defaults no, headless defaults no), log the decision in the memlog, and emit what the guide says an accepted or declined answer emits.
|
||||
|
||||
## Wire the universal shape, strip ceremony, and ship
|
||||
|
||||
Wire in the shape every producing skill shares: a working-state strategy chosen for this skill (memlog, a structured working artifact, both, or neither — see `references/working-state-patterns.md`), a distillation at finalize for skills whose output feeds downstream consumers, projections produced on demand rather than maintained, polish gated on the user's temperament, and a reviewer gate for skills that produce something substantive. Then strip the ceremony. Confirm the skill passes its own leanness scanner before you hand it off, because the builder has no standing to teach leanness while shipping bloat.
|
||||
|
||||
Two org gates apply before ship. Check SKILL.md against the token tiers in `references/skill-quality-principles.md` (Length guidance): warn the user between `{workflow.skill_md_token_desired}` and `{workflow.skill_md_token_budget}`, and if it is over `{workflow.skill_md_token_budget}`, lift sections to `references/` until it is back under. And verify the skill satisfies every directive in `{workflow.build_standards}`; treat each as a required criterion, not a suggestion, and resolve any miss before handoff. When the skill is lean, within budget, conformant, runs on real input, and the user has signed off on the memlog audit, ship it.
|
||||
|
||||
## Handoff
|
||||
|
||||
Interactive: before handing off, run the lint gate over the built skill — `uv run scripts/quick_validate.py {target-skill-path}`, `uv run scripts/scan-path-standards.py {target-skill-path}`, and `uv run scripts/scan-scripts.py {target-skill-path}` — fix high or critical findings and re-run until clear (after three failed fix attempts, stop and surface it), and run unit tests if the built skill carries scripts. Then show what was built and the lint results, and **offer to run the full validation — the Analyze lenses in `references/scan-orchestration.md` — over the new skill** as the default next step, proactively rather than waiting to be asked. If the user accepts, run the Analyze flow and **open the resulting HTML report for them when it finishes** — that flow produces and opens the report, so do not stop at summarizing findings in chat. Then walk the memlog audit at `{target-skill-path}/.memlog.md` so they confirm their reasoning was handled the way they intended. Once the skill is delivered and the user has been told it is ready, run `{workflow.on_complete}` if non-empty (a string scalar is one instruction, an array is a sequence run in order).
|
||||
|
||||
Headless (`{headless_mode}=true`): call `set-complete` on the memlog and emit JSON only.
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "complete",
|
||||
"intent": "build",
|
||||
"skill": "{target-skill-path}",
|
||||
"memlog": "{target-skill-path}/.memlog.md"
|
||||
}
|
||||
```
|
||||
|
||||
Use `"intent": "edit"` for an existing skill. If the run is blocked by ambiguous intent that could not be inferred or by lint failures that would not clear, replace `"complete"` with `"blocked"` and add `"reason": "<one-line cause>"`. The memlog carries the detail.
|
||||
@@ -0,0 +1,29 @@
|
||||
# Complex Workflow Patterns
|
||||
|
||||
Routing mechanics for workflows whose SKILL.md grew past its token budget and had to carve work out to `references/`. The carve conventions themselves — descriptive names, standalone files, what stays in SKILL.md — live in `references/skill-quality-principles.md`, and the portable producing-skill patterns live in `references/producing-workflow-patterns.md`. This file is only what multi-stage routing adds.
|
||||
|
||||
## Multi-Stage Routing as an Earn-It Surface
|
||||
|
||||
Multi-stage routing is structure, and structure has to earn its place against a flatter alternative. Before splitting a workflow into routed stages, ask whether a single goal-driven SKILL.md with named sections would have produced the same result. Usually it would, so reach for explicit stages only when the workflow is large enough that SKILL.md cannot hold it within budget, or when stages have genuinely different resume and memory behavior.
|
||||
|
||||
When stages earn their place, name them descriptively and route by intent. The stage table near the bottom of SKILL.md is a reading aid that maps an intent to a location:
|
||||
|
||||
```markdown
|
||||
## Stages
|
||||
|
||||
| Stage | Intent it serves | Location |
|
||||
|-------|------------------|----------|
|
||||
| Ignition | Capture the raw concept, enforce customer-first thinking | SKILL.md (above) |
|
||||
| Press Release | Iterative drafting with hard coaching | `references/press-release.md` |
|
||||
| Customer FAQ | Surface devil's-advocate customer questions | `references/customer-faq.md` |
|
||||
```
|
||||
|
||||
The intent routing table is what makes the split worth its cost, because the model reads the user's intent and jumps straight to the stage that serves it rather than walking a fixed sequence. Stage order is a routing decision SKILL.md makes per run rather than something baked into the file names.
|
||||
|
||||
## Carved Files and the Memlog
|
||||
|
||||
Carved files reach the memlog by its resolved path rather than assuming in-context state, because compaction can drop SKILL.md before the carved file runs.
|
||||
|
||||
## Module Metadata Reference
|
||||
|
||||
BMad module workflows carry extended frontmatter metadata; see `references/standard-fields.md` for the field conventions. The workflow-builder captures module-capability metadata as handoff fields only and never authors module.yaml.
|
||||
@@ -0,0 +1,119 @@
|
||||
# customize.toml Guide
|
||||
|
||||
customize.toml is the only customizability mechanism a built skill ships with. There are no installer questions, no module.yaml embedding, no separate config.yaml authoring, and no settings or options concept inside the skill. When a skill needs end-user customization, it gets a customize.toml with the universal defaults baked in and the skill-specific points offered where they apply. When it does not, it ships fixed with hardcoded paths and no resolver step, and anyone who needs a change forks it.
|
||||
|
||||
This guide covers when to emit customize.toml, what goes in it, how overrides merge, and which mechanisms are forbidden.
|
||||
|
||||
## The Ask
|
||||
|
||||
Whether a skill gets a customize.toml is a decision made once during the build, interactive-only, defaulting to NO:
|
||||
|
||||
> Should this support end-user customization such as activation hooks, swappable templates, or output paths? If no, it ships fixed and anyone who needs changes forks it.
|
||||
|
||||
Default no. Most skills do not need a customization surface, and a surface nobody uses is friction the reader has to skip past. Headless runs also default to NO and emit customize.toml only when the invocation explicitly requests customization. Whatever is decided, log it in the memlog as a decision.
|
||||
|
||||
When the answer is no, emit no customize.toml, add no resolver step to activation, and use hardcoded paths throughout the skill. When the answer is yes, bake the universal defaults and offer the skill-specific points whose stages exist.
|
||||
|
||||
## DO-NOT-EDIT Header Convention
|
||||
|
||||
Every emitted customize.toml opens with a header that names the file as generated and points to the override files the user actually edits:
|
||||
|
||||
```toml
|
||||
# DO NOT EDIT -- overwritten on every update.
|
||||
#
|
||||
# Workflow customization surface for {skill-name}.
|
||||
# Team overrides: {project-root}/_bmad/custom/{skill-name}.toml
|
||||
# Personal overrides: {project-root}/_bmad/custom/{skill-name}.user.toml
|
||||
```
|
||||
|
||||
The customize.toml in the skill is the base. The user never edits it, because an update overwrites it. Edits go in the two override files, which the resolver merges over the base at activation. The header carries an inline note of the merge rules so a reader knows how an override will land without leaving the file.
|
||||
|
||||
## Universal Baked Defaults
|
||||
|
||||
When customization is accepted, these four points appear in nearly every producing skill, so they are baked in by default under `[workflow]`:
|
||||
|
||||
| Key | Type | Default | Purpose |
|
||||
|---|---|---|---|
|
||||
| `activation_steps_prepend` | array | `[]` | Steps to run before standard activation (pre-flight loads, compliance checks). Overrides append. |
|
||||
| `activation_steps_append` | array | `[]` | Steps to run after greet, before the workflow begins. Overrides append. |
|
||||
| `persistent_facts` | array | `["file:{project-root}/**/project-context.md"]` | Static facts loaded on activation and kept in mind for the whole run. Overrides append. |
|
||||
| `on_complete` | scalar | `""` | Instruction executed when the workflow reaches its terminal stage. Override wins. |
|
||||
|
||||
`persistent_facts` entries are each a literal sentence, a `skill:`-prefixed reference, or a `file:`-prefixed path or glob whose contents load as facts. The default glob picks up a project-context.md anywhere under the project root if one exists, and resolves to nothing when it does not.
|
||||
|
||||
## Offered-When-Relevant Points
|
||||
|
||||
Beyond the universal four, offer a point only when the matching stage exists in the skill. Offering an output-path knob to a skill that produces no artifact is a no-op surface the reader has to skip.
|
||||
|
||||
| Point | Offer when | Shape |
|
||||
|---|---|---|
|
||||
| `<purpose>_template` | The skill loads a template the user might want to swap | Scalar file path, e.g. `brief_template = "assets/brief-template.md"` |
|
||||
| `<purpose>_output_path` + `run_folder_pattern` | The skill produces artifacts to a writable destination | Paired scalars; the pattern names the per-run folder |
|
||||
| `doc_standards` | A finalize stage applies standards to human-consumed docs | Array of `skill:` / `file:` / plain-text directives |
|
||||
| `finalize_reviewers` | A review stage gates substantive output | Array of reviewer references |
|
||||
| `external_sources` | A stage pulls in outside inputs | Array of source references |
|
||||
| `external_handoffs` | A stage routes output onward | Array of handoff references, `tool:` for tool-style routing |
|
||||
|
||||
The four arrays (`doc_standards`, `finalize_reviewers`, `external_sources`, `external_handoffs`) encode standards, not options. They are append-only lists the resolver merges, not toggles that switch behavior on and off.
|
||||
|
||||
Entry convention for these arrays: each entry is a `skill:` reference, a `file:` reference, or plain text, with `tool:` used for handoff-style routing. Bare paths resolve from the skill root; use `{project-root}/...` to point at an org-owned resource elsewhere in the repo.
|
||||
|
||||
## Three-Layer Merge Rules
|
||||
|
||||
Three files compose at activation: the baked base in the skill, the team override (`{skill-name}.toml`), and the personal override (`{skill-name}.user.toml`). The resolver merges them in that order, last layer winning where the rules call for a winner, and falls back to reading the three files directly if no resolver is available.
|
||||
|
||||
| Value kind | Merge behavior |
|
||||
|---|---|
|
||||
| Scalar (string, number, bool) | Override wins, last layer applied wins |
|
||||
| Table | Deep-merge key by key |
|
||||
| Array of tables (entries with `code` or `id`) | Match on `code`/`id`: replace the matching entry, append the new ones |
|
||||
| Any other array | Append |
|
||||
|
||||
There is no removal mechanism by design. To suppress a baked default, override it by key (for a scalar) or fork the skill (for an array entry you cannot reach by key). An override file never shrinks a list, so a base reviewer or standard cannot be silently dropped downstream.
|
||||
|
||||
SKILL.md must reference resolved values as `{workflow.<name>}`, for example `{workflow.brief_template}` or `{workflow.output_path}`. A hardcoded path written beside a declared scalar silently no-ops the override, because the resolver fills `{workflow.<name>}` but the skill never reads it. The customization scanner flags exactly this hardcoded-path-beside-declared-scalar case.
|
||||
|
||||
## Forbidden Mechanisms
|
||||
|
||||
customize.toml is the sole config mechanism. The build flow never offers any of the following, and the customization scanner confirms none is present:
|
||||
|
||||
- Installer or install-time questions
|
||||
- module.yaml embedding or generation. The workflow-builder captures module-capability metadata as handoff fields only and never authors module.yaml.
|
||||
- A separate config.yaml authored by the skill for its own settings. (Reading the project's config.yaml at activation is not a customization surface; net-new skills are not generated with it, though a user may wire it in.)
|
||||
- Boolean-toggle config that switches behavior on and off
|
||||
- Any settings or options concept inside the built skill
|
||||
|
||||
Confirming script dependencies at build is also legitimate and stays, because it is a build-time check rather than a customization surface.
|
||||
|
||||
## Example
|
||||
|
||||
A complete customize.toml for an artifact-producing skill with a finalize stage:
|
||||
|
||||
```toml
|
||||
# DO NOT EDIT -- overwritten on every update.
|
||||
#
|
||||
# Workflow customization surface for bmad-product-brief.
|
||||
# Team overrides: {project-root}/_bmad/custom/bmad-product-brief.toml
|
||||
# Personal overrides: {project-root}/_bmad/custom/bmad-product-brief.user.toml
|
||||
|
||||
[workflow]
|
||||
|
||||
# --- Universal defaults. Merge: scalars override, arrays append. ---
|
||||
activation_steps_prepend = []
|
||||
activation_steps_append = []
|
||||
persistent_facts = ["file:{project-root}/**/project-context.md"]
|
||||
on_complete = ""
|
||||
|
||||
# --- Skill-specific points (stages present: template, output, finalize) ---
|
||||
brief_template = "assets/brief-template.md"
|
||||
output_path = "{planning_artifacts}/briefs"
|
||||
run_folder_pattern = "brief-{project_name}-{date}"
|
||||
|
||||
# Standards applied at finalize. Append-only; base entries cannot be removed.
|
||||
doc_standards = [
|
||||
"skill:bmad-editorial-review-structure",
|
||||
"skill:bmad-editorial-review-prose",
|
||||
]
|
||||
```
|
||||
|
||||
A skill that produces no artifact and has no finalize stage carries only the `[workflow]` block with the four universal defaults, and a skill that declined customization carries no customize.toml at all.
|
||||
@@ -0,0 +1,28 @@
|
||||
# Lens Contract
|
||||
|
||||
The return mechanics every scan lens shares. Your own spec file gives you the lane and the bar; this file is how the work comes back.
|
||||
|
||||
You receive compact pre-pass JSON and the skill path from the parent. Read the metrics first and open a raw file only for judgment a metric cannot settle. Return your findings to the parent in-context: never write a file or a per-subagent analysis document. The parent merges all lens returns and renders the report itself.
|
||||
|
||||
Return exactly this JSON and nothing else:
|
||||
|
||||
```json
|
||||
{
|
||||
"lens": "<your lens name>",
|
||||
"verdict": "<one line for this lens>",
|
||||
"findings": [
|
||||
{
|
||||
"id": "<lens>-<n>",
|
||||
"severity": "critical | high | medium | low",
|
||||
"title": "<short>",
|
||||
"location": "<file:region or file>",
|
||||
"evidence": "<what was observed>",
|
||||
"recommendation": "<the fix>"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
- `id` numbers sequentially within your lens (`<lens>-1`, `<lens>-2`), so every finding stays traceable after the merge.
|
||||
- The leanness lens alone adds `proposed_smallest` and `predicted_delta` to its defend-against-absence findings; every other lens and every other finding omits those keys.
|
||||
- If you find nothing, return an empty `findings` array with a verdict saying the skill passes your lens. Do not pad the list to look thorough — a weak finding that would not survive a real run is worse than no finding.
|
||||
@@ -0,0 +1,35 @@
|
||||
# Producing Workflow Patterns
|
||||
|
||||
Patterns for any skill that produces an artifact, runs across turns, or serves more than one intent — whether or not it ever carves work out to `references/`. A single-file SKILL.md needs most of these; carve-out is a separate concern handled in `references/complex-workflow-patterns.md`.
|
||||
|
||||
## Workflow Persona
|
||||
|
||||
BMad workflows treat the human operator as the expert. The agent facilitates by asking clarifying questions, presenting options with their trade-offs, and validating before any irreversible action. The operator knows the domain and the workflow knows the process. Drop this stance only when the user is building a simple utility skill or wants the skill to behave as an expert operator rather than a facilitator.
|
||||
|
||||
## Intent Modes: create, update, validate
|
||||
|
||||
A skill that serves more than one intent routes by mode rather than branching deep inside a single procedure. The three intents most producing skills land on are create, update, and validate.
|
||||
|
||||
Create starts a fresh run, inits the memlog, and walks discovery through finalize. Update resumes against an existing artifact, reads the memlog once to rebuild state, surfaces any conflict before applying changes, and appends new entries. Validate is read-only, grades the artifact against its own standards, and writes nothing the user has to keep.
|
||||
|
||||
Mode selection happens at activation from the user's intent, not from a quiz. If the intent is ambiguous, ask the one question that disambiguates, then route.
|
||||
|
||||
## Graceful Degradation
|
||||
|
||||
A workflow that depends on a prior artifact or an optional script should degrade rather than stop. Each dependency names a fallback, and the fallback is the path the skill takes when the dependency is absent rather than an error the user has to clear.
|
||||
|
||||
## Working state across turns
|
||||
|
||||
A multi-turn skill that builds something needs a way to hold state across turns and compaction: a memlog (the decision trail), a structured working artifact (the work-in-progress that transforms into the output), both, or neither. The choice and the full treatment live in `references/working-state-patterns.md`. Pick by the shape of the work and thread it through the intents at the points where each read or write matters. Confirm with user if interactive.
|
||||
|
||||
## Producing-Skill Checklist
|
||||
|
||||
Before finalizing a producing workflow:
|
||||
|
||||
- [ ] Facilitator persona treats the operator as the expert (unless deliberately an expert-operator utility)
|
||||
- [ ] Memory via memlog, with resume reading the file once on activation — or an explicit reason for skipping (simple utility, one-shot, purely conversational)
|
||||
- [ ] Intent boundary is clean where the skill serves create, update, and validate
|
||||
- [ ] Update mode reads the memlog first and surfaces conflicts before applying changes
|
||||
- [ ] Each external dependency names its degraded fallback inline
|
||||
- [ ] Final polish through a subagent polish step at the end
|
||||
- [ ] Finalize distills the run and confirms the memlog is complete
|
||||
@@ -0,0 +1,79 @@
|
||||
# Outcome-Driven Prompt Quality
|
||||
|
||||
Every line you write competes with the version of itself that was never written. This canon is how the winning version gets written: state the destination, then make every remaining line survive the tests. It applies to anything a model will read: a capability, a skill, a workflow, a whole flow.
|
||||
|
||||
## Write the destination, not the route
|
||||
|
||||
Know your own default. Asked to build a prompt, you will script the path — phased sequences, question banks, templates with mandatory sections — because elaborate scaffolding feels like diligence and reads like quality. That instinct is the central defect this canon exists to prevent. A script is your imagined transcript of one good session; real sessions diverge from it, and a model holding a script spends its intelligence on compliance instead of the problem.
|
||||
|
||||
Write the destination instead. A goal-stated prompt holds five things: the **stance** (who the model is and what relationship it keeps with the user), the **outcome** (the artifact or change that must exist), the **consumer** (who must act on that outcome without the conversation in the room), the **bar** (what the consumer needs to be true of it), and the **non-inferables** — persona, posture, institutional knowledge, wiring, the rules with real consequences. Then stop. The outcome and its consumer imply the process: a model that knows the PRD must be actionable by someone who was never in the room already knows to chase scope edges and untestable requirements, with no step list needed. The consumer is the highest-leverage line in any prompt, because completeness, rigor, and tone all derive from it.
|
||||
|
||||
The shape, in miniature — a complete facilitation skill, not an excerpt:
|
||||
|
||||
```text
|
||||
Act as the user's product-thinking partner: they hold the product knowledge;
|
||||
you hold the craft of drawing it out, pressure-testing it, and structuring it.
|
||||
You are not an interviewer with a form and not a ghostwriter.
|
||||
|
||||
The outcome is a PRD at {output_folder}/prd.md that a team — human or AI —
|
||||
can act on without this conversation in the room. That consumer sets the bar:
|
||||
every requirement traceable to a need and stated so someone could test whether
|
||||
it was met; scope edges explicit, including what is out; open questions named
|
||||
as open rather than papered over.
|
||||
|
||||
Open the floor before any structured work, and mine what you already hold
|
||||
before asking anything; then work the gaps a question or two at a time.
|
||||
Your value is the pushback: the user they forgot, the edge case that breaks
|
||||
the happy path, the scope that doubled in one sentence, the metric nobody
|
||||
can measure. A PRD that transcribes the first idea is a failure however
|
||||
well formatted.
|
||||
|
||||
Draft sections as the thinking firms up and show them; when one is
|
||||
confirmed, write it and move on.
|
||||
```
|
||||
|
||||
Everything a scripted version would add to this — discovery question lists, a section template, phase gates — subtracts adaptivity. The user who arrives with a full brief gets gap analysis instead of a question bank precisely because nothing scripted the opening.
|
||||
|
||||
## The tests
|
||||
|
||||
Hold these while you write or review. The sections below carry the mechanics that don't fit a line.
|
||||
|
||||
1. **The core test.** Would a capable model do this correctly without being told? If yes, cut. A line earns its place only by preventing a failure that would otherwise happen — if you cannot name what it produces that its absence would not, it is friction.
|
||||
2. **Truncate before you delete.** Most over-long lines hide a needed nudge wrapped in explanation the reader infers. Keep the instruction and the one clause of why it genuinely needs; drop the rest. "Open with an invitation to dump everything" survives; the paragraph on why dumping helps does not.
|
||||
3. **Keep the why behind a non-obvious goal.** A reader handed a goal without its reason cannot apply it to the case you did not foresee, and may optimize away a constraint it does not understand. A stripped why is under-writing, not leanness.
|
||||
4. **Write what survives as a goal.** State intent and let the model find the path. Reserve exact procedure for operations where a wrong move actually costs something — a precise script invocation, an API call with consequences.
|
||||
5. **Number only true sequences.** Numbering tells the reader order matters, and it will march the steps in order rather than adapt them. Where steps genuinely feed each other, number them; where they are independent obligations, use bullets; where the "steps" were never really separate, write one goal sentence.
|
||||
6. **Carve by relevance, not size.** The entry file is paid on every invocation; a reference is paid only when its branch fires. Carve content that only some branches need — one platform of five, edit but not create — and keep a routing map in the entry so the model knows what exists and when to load it. Don't carve what is too small to repay the indirection; a few branch-specific lines stay inline. Each carved file must stand alone, because the entry context can drop mid-flow, and references stay one level deep — entry routes to reference, never reference to reference.
|
||||
|
||||
## Who reads this
|
||||
|
||||
Your reader is a model whose entire world is what you wrote — no author in the room, no context but these files. Every test above is reader-relative: does the line change how that reader acts or judges? Cut what changes none of its moves: meta-explanation describing the system to itself, negative space ("what this no longer does"), restated facts, and mechanics that belong in the file that performs them.
|
||||
|
||||
## The two-version comparison
|
||||
|
||||
You cannot judge structure from inside a single run — the output looks the same whether the model did its best work or settled. Write the smallest version of what you are building, around five lines: the role, the outcome, the consumer of that outcome, and any rule whose absence has caused damage you can point to. Run both versions on the same input and read the verdict.
|
||||
|
||||
| What you see | What it means |
|
||||
| --- | --- |
|
||||
| Small one wins | The structure was a straitjacket. Cut it. |
|
||||
| They tie | The structure is decoration. Defend each line or kill it. |
|
||||
| Small one rougher but recoverable in a couple of turns | You bought convenience, not quality. Allowed, if you are honest about it. |
|
||||
| Small one materially worse and stays worse | The structure earned its keep, for now. |
|
||||
|
||||
When you cannot run both versions, the tests above and the habit below need no experiment — apply them line by line.
|
||||
|
||||
## The deeper floor
|
||||
|
||||
Below your small version sits the bare model, and that floor rises with every release. What survives is the work the model cannot do for itself: resolving file paths, holding downstream contracts, wiring systems that do not know about each other, carrying institutional knowledge that lives nowhere else. When a capability stops beating the bare model, retire it rather than patch it — the model has caught up to the work it was doing.
|
||||
|
||||
## Cheaper signals
|
||||
|
||||
Hold one variable steady, change another, watch the output:
|
||||
|
||||
- Same input five times. Nearly identical results mean you over-determined the work; wildly varying results mean you under-specified something you can now go find.
|
||||
- Very different inputs through the same prompt. Outputs that all look alike mean the template has gotten louder than the input.
|
||||
- A model marching through numbered steps in order rather than adapting them is structure constraining it.
|
||||
|
||||
## The habit
|
||||
|
||||
For each section of what you build: What single outcome do you want from it? What does the model already know how to do there — usually most of it? What does it genuinely need from you that it cannot infer — the persona, the default posture, the desired feeling or interaction, the wiring, the schemas, the rules with real consequences? Whatever remains is structure you are imposing, and you owe a clear account of what it buys. If you cannot name that, it is over-structure.
|
||||
@@ -0,0 +1,29 @@
|
||||
# Scan Lens: Architecture
|
||||
|
||||
You are a senior skill architect reviewing one BMad skill. Your lens is structure: frontmatter, file topology, progressive disclosure, and three-mode soundness. You decide whether the skill is wired so the executing agent reaches informed judgment instead of mechanical procedure-following, and whether what should exist exists and resolves.
|
||||
|
||||
Load `references/prompt-quality-canon.md` and `references/skill-quality-principles.md` first; the canon is the universal bar and the principles file the BMad-specific one. Cite their rules in findings rather than restating them. Load `references/lens-contract.md` for the return mechanics.
|
||||
|
||||
The pre-pass JSON you receive carries per-file token counts, frontmatter facts, structural signals, and the path-standards and workflow-integrity output.
|
||||
|
||||
## What this lens owns
|
||||
|
||||
Structure and topology, where a defect either breaks execution or pushes the agent into following steps it should reason through.
|
||||
|
||||
- **Frontmatter** holds `name` and `description` only, and the description follows the principles' two-part quoted-trigger format. Flag one that over-broadens (`Helps with PRDs`), because it hijacks unrelated conversations.
|
||||
- **File topology** matches the carve-out rule: branch-specific content and anything past SKILL.md's token tier moves to `references/` with descriptive names, one level deep, with a routing map in SKILL.md; everything else stays inline. Flag content every invocation pays for that only one branch needs, a carved file too small to repay its indirection, `*.md` workflow content sitting at skill root, and any SKILL-to-reference-to-reference nesting.
|
||||
- **Progressive disclosure** holds: SKILL.md routes to references by bare path, every referenced file exists, and each carved file survives on its own because compaction can drop SKILL.md mid-flow. Flag a carved file that leans on "as described in the overview" or "see SKILL.md" — the stage-references-SKILL.md failure in the principles file. Flag a multi-file SKILL.md missing its resolution-rules block.
|
||||
- **Three-mode soundness**, where the skill claims modes: Guided, Yolo, and Headless each route to a real path, the modes do not contradict each other, and the workflow-type claim matches the actual shape (a "complex" skill with everything inline gets reclassified; a "simple" one carrying carved references gets inlined or reclassified). Absence of modes is not itself a defect.
|
||||
- **Coherence**: earlier sections produce what later sections consume with no dead-end or overlap, complexity matches the task, and a principle stated in the Overview is actually enforced by the execution instructions. An implicit instruction that violates a stated principle is the most dangerous misalignment, because it reads as correct on a casual pass — trace promises through to behavior.
|
||||
|
||||
## Stay in your lane
|
||||
|
||||
Leanness scoring of individual lines belongs to the leanness lens, the script-versus-prompt boundary to determinism, customize.toml economics to customization, and missing or over-applied patterns to enhancement. Report only what a structural review catches.
|
||||
|
||||
## Severity
|
||||
|
||||
Anything that breaks execution or violates a stated promise is critical or high. Workflow content at skill root or a description that over-broadens is high. Coherence mismatches are medium. Style is low.
|
||||
|
||||
## Return
|
||||
|
||||
Return per `references/lens-contract.md` with `"lens": "architecture"`.
|
||||
@@ -0,0 +1,33 @@
|
||||
# Scan: Customization (customize.toml surface economics)
|
||||
|
||||
You are the customization-surface economist. You ask two questions no other scanner asks: what should be customizable but isn't, and what is exposed as customizable that shouldn't be. The surface is a cost the author owns forever, so a point that does not earn its place is friction, not flexibility.
|
||||
|
||||
Load `references/customize-toml-guide.md` before you start. It is the full spec — universal defaults, offered-when-relevant points, merge rules, forbidden mechanisms — and the rule that frames every call: the surface exposes only the points whose stages actually exist in this skill, names a real default for each, and lets the rare divergent case fork. Load `references/lens-contract.md` for the return mechanics.
|
||||
|
||||
If there is no `customize.toml`, scan the opportunity side only and judge whether the skill would benefit from opting in.
|
||||
|
||||
## Confirm customize.toml is the only mechanism
|
||||
|
||||
Before anything else, confirm customize.toml is the sole config mechanism present. Flag any other surface as a finding, because the rebuild allows nothing else: an installer or install-time question, a module.yaml the skill embeds or generates, a separate config.yaml the skill authors, a boolean-toggle config, or any settings or options concept living inside the built skill. Reading project config at activation and confirming script dependencies at build are not customization surfaces, so leave those alone.
|
||||
|
||||
## Too thin, which forces forks
|
||||
|
||||
A skill that bakes a path or a template it should have exposed forces anyone who needs a variation to copy the whole skill. Flag a hardcoded template path that should be a `<purpose>_template` scalar, each one separately rather than bundled. Flag a hardcoded output destination that an org would plausibly redirect as a `<purpose>_output_path`, weaker than a template so usually low unless the destination is clearly org-dependent. Flag a skill that produces an artifact and stops as a candidate for an `on_complete` hook, and flag a missing or empty `persistent_facts` when the BMad default glob would carry project context across the skill. When a skill has two or more hardcoded templates and no customize.toml at all, that is a high-opportunity case to opt in.
|
||||
|
||||
## Too loud, which builds a permutation forest
|
||||
|
||||
The opposite failure is worse, because a loud surface means the author never decided what the skill does and pushed that decision onto every installer. Flag three or more boolean toggles in one file, since the surface is doing the job a separate variant skill should do; recommend two skills or fewer knobs. Flag identity, communication style, or principles living in `[workflow]`, because those are agent-shape fields that belong with agent-builder, not on the workflow surface. Flag four or more `on_<event>` hooks, where workflow internals leak into the override surface so widely that a user can break the workflow's own contract. Flag opaque scalar names like `style_config` or a `mode` that is really a path, and point the author at the `<purpose>_template`, `<purpose>_output_path`, and `on_<event>` patterns instead.
|
||||
|
||||
## Merge correctness
|
||||
|
||||
A surface can be the right size and still be wired so the override silently does nothing. Flag arrays of tables that lack a `code` or `id` key, because the resolver cannot merge by key and falls back to append-only so a user can never replace an item. Flag mixed keying, where some tables carry `code` and others `id`, and tell the author to pick one. Flag a scalar that has no comment explaining when and why to override it.
|
||||
|
||||
The highest-value merge defect is a hardcoded path sitting beside a declared scalar. When customize.toml declares a value but SKILL.md hardcodes that same value instead of reading `{workflow.<name>}`, the override resolves correctly and then never reaches the place it was meant to change, so the user's customization is a silent no-op. Flag this as high and name the exact reference SKILL.md should use.
|
||||
|
||||
## Severity
|
||||
|
||||
A surface that breaks the contract or makes overrides silently no-op is high, which covers the hardcoded-path-beside-scalar case, the identity-in-`[workflow]` case, and any config mechanism other than customize.toml. A moderate opportunity or a moderate abuse is medium. A weak opportunity such as an output-path lift, or a small naming or comment nit, is low. Use `critical` only when a wiring defect will mislead at runtime, since most of this lens is opportunity and risk rather than breakage.
|
||||
|
||||
## What you return
|
||||
|
||||
Return per `references/lens-contract.md` with `"lens": "customization"`. The verdict names too thin, too loud, or about right, plus whether customize.toml is the sole mechanism present.
|
||||
@@ -0,0 +1,25 @@
|
||||
# Scan: Determinism (intelligence-placement boundary)
|
||||
|
||||
You are the intelligence-placement reviewer. Your lens is the boundary between what a script does and what a prompt does, and a defect is any line that crosses it in either direction.
|
||||
|
||||
Load `references/script-opportunities-reference.md` before you start; the determinism test, the signal-verb scan, and the pre-pass JSON pattern there are the bar. Every call comes down to one line: scripts handle plumbing (fetch, parse, validate, count, transform), prompts handle judgment (interpret, classify, decide). Load `references/lens-contract.md` for the return mechanics.
|
||||
|
||||
## The two leaks you hunt
|
||||
|
||||
An intelligence leak is a script reaching for meaning. The clearest tell is a regex or a string match deciding what content means rather than just where a delimiter sits. A script that splits on a token is fine; a script that infers intent, classifies tone, or judges quality from a pattern has taken on work the prompt should own, and it will be brittle the moment the input phrasing shifts.
|
||||
|
||||
A determinism leak is a prompt doing work that has one correct answer for a given input. The tells are counting items, validating structure against a schema, comparing two files for drift, checking that a frontmatter key exists, or reformatting structured data. If you could write a unit test that passes or fails on the operation, the LLM should not be doing it, because the model pays tokens to do unreliably what a script does for free and exactly.
|
||||
|
||||
When you catch a determinism leak, it is a script opportunity. Your recommendation names the determinism test and the signal-verb scan the author will apply when they push the work into native Python, and where the prompt currently reads a large raw file to extract a few facts, name the pre-pass JSON pattern so a script hands the model compact JSON instead.
|
||||
|
||||
## What stays in the prompt
|
||||
|
||||
Do not flag work that genuinely turns on meaning, tone, context, or ambiguity, because that is exactly where the model earns its place. Interpreting a messy user request, classifying a finding's severity from evidence, or deciding whether an instruction re-teaches native behavior all belong in the prompt and are not leaks.
|
||||
|
||||
## Severity
|
||||
|
||||
A leak that will fail or mislead at runtime is critical, for example a regex classifier that silently mishandles a common input shape. A heavy determinism leak the model pays for on every invocation, or an intelligence leak in a script that gates downstream behavior, is high. A moderate determinism leak the model could absorb cheaply is medium. A small parsing nicety that would be marginally cleaner as a script is low.
|
||||
|
||||
## What you return
|
||||
|
||||
Return per `references/lens-contract.md` with `"lens": "determinism"`. Quote the leaking operation in `evidence`, and in `recommendation` say which way it leaks and name the determinism test, the signal-verb scan, or the pre-pass JSON pattern the fix applies.
|
||||
@@ -0,0 +1,29 @@
|
||||
# Scan Lens: Enhancement (add or subtract)
|
||||
|
||||
You are the pattern lens on this review. You ask what named pattern is missing that would make the skill better, and you also ask where a pattern is over-applied and should come out. This lens cuts both ways. A pattern stamped onto a skill that does not need it is friction, and naming the removal is as much your job as naming the addition.
|
||||
|
||||
Load `references/skill-quality-principles.md` first. Its "Patterns BMad has seen pay off" section is the library you check the skill against, in both directions. Load `references/lens-contract.md` for the return mechanics.
|
||||
|
||||
You walk the skill end to end the way different real users would experience it: the first-timer, the expert who knows what they want, the user who arrived by accident or with the wrong intent, the user with technically valid but unexpected input, the user in a hostile environment where deps fail or files are missing, and the automator invoking the skill headless with pre-supplied inputs and expecting a usable return.
|
||||
|
||||
## What this lens owns, in both directions
|
||||
|
||||
The add direction. At each stage, find where the skill would confuse, frustrate, dead-end, or underwhelm a user, and where one named pattern would change that. Check the skill against the pattern library in the principles file rather than re-deriving it here. Flag a missing pattern only when adding it would materially improve the skill in a situation a real user hits, with a concrete suggestion for where it lands. In particular, a multi-turn skill that builds something must have a working-state strategy — a memlog, a structured working artifact, or both (see `references/working-state-patterns.md`); flag its absence where state would otherwise die on compaction or revisit. Also weigh headless readiness: for each interaction point, ask whether a parameter could replace the question or a default could replace a confirmation, and say whether the skill is headless-ready, easily adaptable, partially adaptable with a skip-to-build entry point, or fundamentally interactive because the value is the conversation. Fundamentally interactive is a fine answer, so flag it and move on.
|
||||
|
||||
The subtract direction. Find where a named pattern is over-applied for the work in front of it. Parallel review lenses fanned out for a one-file format operation, three-mode architecture wired onto a skill that only ever runs one way, dual-output where nothing downstream consumes the distillate, a memlog or an intermediate artifact bolted onto a one-shot or purely conversational skill, an open-floor opening on a skill whose single input is a file path: each is a pattern that earned its name elsewhere and is paying rent here for nothing. Recommend the removal and name what the skill loses by removing it, which should be little or nothing if the flag is right.
|
||||
|
||||
## Stay in your lane
|
||||
|
||||
Leave per-line leanness scoring to the leanness lens, the script-versus-prompt boundary to the determinism lens, customize.toml surface economics to the customization lens, and structural or topology defects to the architecture lens. Your findings are the ones only a pattern-level reading catches, in either direction.
|
||||
|
||||
## How to think
|
||||
|
||||
Go wide first, the weirdest user and the worst timing for additions, the most over-engineered stage for removals. Then temper. For each idea, ask whether there is a practical version that improves the skill. If yes, sharpen it to one suggestion. If not, drop it rather than padding the list. Prioritize by user impact, where preventing confusion outranks a nice-to-have, and removing dead ceremony outranks a marginal addition.
|
||||
|
||||
## Severity
|
||||
|
||||
A missing pattern that leaves a real user stuck is high. An over-applied pattern that adds surface and ceremony for no gain is high. A pattern that would smooth a less common path, or one whose removal is a marginal cleanup, is medium. Pure polish is low. Use the `opportunity` framing in the title where the finding is advisory rather than a defect.
|
||||
|
||||
## Return
|
||||
|
||||
Return per `references/lens-contract.md` with `"lens": "enhancement"`. Titles name add or remove, `evidence` names the pattern involved, and a removal recommendation states what is lost (which should be little or nothing if the flag is right).
|
||||
@@ -0,0 +1,36 @@
|
||||
# Scan Lens: Leanness
|
||||
|
||||
You are the leanness lens. Your question is whether every line in the skill under analysis beats its own absence, and whether what survives is written as a goal rather than a prescription. No other lens owns this, so a section other scanners would wave through as structurally sound can still fail here for being ceremony.
|
||||
|
||||
Load `references/prompt-quality-canon.md` first; it is the entire bar for this lens. Apply its tests — do not restate them in findings; cite them. Load `references/lens-contract.md` for the return mechanics.
|
||||
|
||||
Stay in this lane: structure and topology belong to the architecture lens, intelligence placement to determinism, customize.toml to customization, and missing patterns to enhancement. You judge whether what is present earns its place.
|
||||
|
||||
## Test 1: the core test
|
||||
|
||||
Run the canon's core test over each load-bearing instruction, truncating before deleting, and flagging a stripped why as under-writing rather than cutting further. The re-teach shapes that recur in skills:
|
||||
|
||||
- Scoring formulas, weighted calibration tables, and decision matrices for subjective judgment.
|
||||
- Format-the-output templates that teach markdown, greeting, or prompt assembly.
|
||||
- Defensive padding such as "make sure", "don't forget", and "remember to".
|
||||
- Meta-explanation describing the system to itself, and negative space narrating what it no longer does.
|
||||
- Mechanics for a tool the model already drives fluently, and downstream mechanics living in the wrong file.
|
||||
- "Why it matters" prose hung on an obvious check, and facts restated across sections.
|
||||
|
||||
## Test 2: defend against its own absence
|
||||
|
||||
This operationalizes the canon's two-version comparison. For each section or structural element, name the concrete dimension on which the elaborate version produces a better output than a roughly five-line version of the same intent would — material and durable, showing up on real input and across runs, not only in the abstract.
|
||||
|
||||
If you can name that dimension, the section earned its keep and you do not flag it. If you cannot, flag it as ceremony and do the work that lets the parent settle the question with a real run: write the smallest version yourself into `proposed_smallest`, and name what you predict would be lost (often nothing) in `predicted_delta`. The parent can route the finding to the eval-runner's variant mode, which runs the full section against your smallest version on the same input and returns a cut-or-keep verdict. When you genuinely expect no loss, say so and add "route to variant eval to confirm".
|
||||
|
||||
## Test 3: outcome vs prescription
|
||||
|
||||
Apply the canon's number-only-true-sequences test to each numbered step or rigid sequence. When the ordering is decoration, propose replacing it with one goal sentence and put that sentence in the recommendation. When the order guards against a named failure, the sequence stays unflagged, because that order is the value.
|
||||
|
||||
Also flag, as a yellow flag rather than a hard defect, ALL-CAPS ALWAYS/NEVER and stacked MUSTs — the author shouting where reasoning would carry the rule. Recommend reframing the shout as the failure the rule protects against, so the model understands why instead of bracing against a command.
|
||||
|
||||
## What you return
|
||||
|
||||
Return per `references/lens-contract.md` with `"lens": "leanness"`, adding `proposed_smallest` and `predicted_delta` on Test 2 findings only.
|
||||
|
||||
Severity guidance: a core-test re-teach of a few lines is usually low or medium, a whole ceremony section is high, and a numbered sequence that actively resists cutting because it reads as a real constraint is high. Reserve critical for friction that misleads the model into a wrong action, not merely a verbose one.
|
||||
@@ -0,0 +1,132 @@
|
||||
# Scan Orchestration
|
||||
|
||||
How Analyze runs: a deterministic pre-pass, five LLM lenses in parallel, you merge and synthesize in-context, and a script renders the report. `{target-skill-path}` is the skill under analysis.
|
||||
|
||||
## Run folder
|
||||
|
||||
Each analyze run owns `{target-skill-path}/.analysis/<YYYY-MM-DD-HHmm>/` (create it first). It receives `findings.json`, `skill-analysis-report.html`, and `skill-analysis-report.md`.
|
||||
|
||||
## Run the deterministic pre-pass first
|
||||
|
||||
Run these in parallel so the lenses read metrics instead of re-deriving them:
|
||||
|
||||
- `uv run scripts/prepass-prompt-metrics.py {target-skill-path}`: per-file token counts (via `scripts/count_tokens.py`), frontmatter facts, and structural signals as JSON.
|
||||
- `uv run scripts/prepass-workflow-integrity.py {target-skill-path}`: workflow-integrity checks as JSON.
|
||||
- `uv run scripts/scan-path-standards.py {target-skill-path}`: path-convention lint (bare-paths-from-root, no double-prefix, no `./`).
|
||||
- `uv run scripts/scan-scripts.py {target-skill-path}`: script-standards lint (PEP 723 metadata, shebangs, non-stdlib confirmation).
|
||||
|
||||
## Run the five lenses as parallel subagents
|
||||
|
||||
Hand each lens the pre-pass JSON and the skill path. Each loads the bar its own spec file names (the canon, the principles file, or its lane's spec) and returns its findings to you in-context.
|
||||
|
||||
| Lens | File | Owns |
|
||||
| --- | --- | --- |
|
||||
| Leanness | `references/scan-leanness.md` | The three minimal-baseline tests: the core test, the defend-against-its-own-absence test, the outcome-vs-prescription test. |
|
||||
| Architecture | `references/scan-architecture.md` | Structure, frontmatter, file topology, progressive disclosure, three-mode soundness. |
|
||||
| Determinism | `references/scan-determinism.md` | The intelligence-placement boundary: intelligence leaks and determinism leaks, cross-referenced to script opportunities. |
|
||||
| Customization | `references/scan-customization.md` | `customize.toml` surface economics, and confirmation that it is the only config mechanism present. |
|
||||
| Enhancement | `references/scan-enhancement.md` | Missing named patterns to add and over-applied patterns to cut. |
|
||||
|
||||
Each lens returns the JSON in `references/lens-contract.md`. The leanness lens also returns `proposed_smallest` and `predicted_delta` on defend-against-absence findings, which you can route to the eval-runner's variant mode for a cut-or-keep verdict.
|
||||
|
||||
## Apply the org gates
|
||||
|
||||
Two customize-driven gates run alongside the lenses, only when configured:
|
||||
|
||||
- **`{workflow.build_standards}`** — if non-empty, check the skill against each directive (`skill:`, `file:`, or plain text) and fold any miss into the findings as a conformance finding.
|
||||
- **`{workflow.evals_required}`** — if set, confirm the skill has the required evals (`"baseline"` or `"any"`); if not, add a high-severity finding.
|
||||
|
||||
## Author the synthesis layer
|
||||
|
||||
Merge the lens returns into one findings list, keeping each finding's `id`. You hold every finding in context, so no subagent is involved; never hand-write report HTML, and never edit the rendered file. The findings are the evidence; the synthesis is what a user must grasp in 30 seconds. All synthesis fields are yours to write:
|
||||
|
||||
- `verdict` — one line naming the overall state and the one or two findings that matter most.
|
||||
- `grade` — `excellent` (no high or critical, few medium), `good` (some high or several medium), `fair` (multiple high), `poor` (any critical). Lowercase.
|
||||
- `summary` — 2-3 sentences: the skill's primary strength and primary opportunity. This is the first thing the user reads.
|
||||
- `themes` — findings clustered by shared root cause, not by file. Ask: "if I fixed X, how many findings across lenses would that resolve?" 3-5 themes; findings that fit no theme stay ungrouped in `findings` only. Each theme's `action` is one coherent fix instruction for the whole cluster, and `finding_ids` lists the constituent findings so the report can show them under the theme.
|
||||
- `strengths` — what works and must be preserved, so a fix pass does not flatten it.
|
||||
- `recommendations` — ranked by leverage: rank 1 resolves the most findings for the least effort. `resolves` lists the finding ids it would clear.
|
||||
|
||||
## Schema (schema_version 2)
|
||||
|
||||
`findings.json` is one object:
|
||||
|
||||
```json
|
||||
{
|
||||
"schema_version": 2,
|
||||
"subject": "<skill path analyzed>",
|
||||
"generated": "<ISO date>",
|
||||
"verdict": "<one-line overall assessment>",
|
||||
"grade": "excellent | good | fair | poor",
|
||||
"summary": "<2-3 sentence narrative>",
|
||||
"standards": {
|
||||
"canon": "<absolute path to this builder's references/prompt-quality-canon.md>",
|
||||
"principles": "<absolute path to this builder's references/skill-quality-principles.md>",
|
||||
"scripts": "<absolute path to this builder's references/script-standards.md>"
|
||||
},
|
||||
"themes": [
|
||||
{
|
||||
"title": "<root-cause name>",
|
||||
"root_cause": "<what is happening and why it matters>",
|
||||
"finding_ids": ["leanness-1", "determinism-2"],
|
||||
"action": "<one coherent fix for the whole theme>"
|
||||
}
|
||||
],
|
||||
"strengths": ["<what works and should be preserved>"],
|
||||
"recommendations": [
|
||||
{ "rank": 1, "action": "<what to do>", "resolves": ["leanness-1"] }
|
||||
],
|
||||
"experience": {
|
||||
"journeys": [{ "name": "", "steps": "" }],
|
||||
"headless": "<one line on the skill's headless story>"
|
||||
},
|
||||
"findings": ["<every lens finding unchanged, per references/lens-contract.md>"]
|
||||
}
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- `standards` is always filled: resolve the three absolute paths from this builder's own `{skill-root}` at authoring time. The shell prepends them to every copied fix prompt, so the session that applies a fix holds the same bar that produced the findings.
|
||||
- `findings` carries every lens finding unchanged — keep each finding's `id`, `lens`, and `severity` so it stays traceable. Carry `proposed_smallest` and `predicted_delta` only when the leanness lens supplied them; omit the keys otherwise.
|
||||
- Severity counts are derived from the `findings` array by the script and the shell — there is no counts field to keep consistent.
|
||||
- `grade`, `summary`, `themes`, `strengths`, `recommendations`, and `experience` are optional: omit a key entirely rather than writing an empty placeholder. A clean pass is a real report — empty `findings`, a grade that reflects it, and a verdict saying the lenses passed.
|
||||
- Keep `evidence` and `recommendation` to a sentence or two; the shell shows them in a collapsible row, not a document.
|
||||
|
||||
## Write and render
|
||||
|
||||
Write the object to `{run-folder}/findings.json` and render:
|
||||
|
||||
```bash
|
||||
uv run scripts/render_report.py {run-folder}/findings.json --shell assets/report-shell.html -o {run-folder}/skill-analysis-report.html --md {run-folder}/skill-analysis-report.md
|
||||
```
|
||||
|
||||
If the script refuses, fix `findings.json` and re-run; never hand-edit the HTML. Open the HTML report for the user — it is the deliverable of Analyze; do not replace it with a chat summary of the findings. The markdown twin is the archival artifact of the same data.
|
||||
|
||||
The shell fails loud: a malformed island shows the parse-error banner, an unfilled shell shows a placeholder banner, and an empty findings array with a real subject renders an explicit no-findings panel — never a blank page and never fabricated findings.
|
||||
|
||||
## Record the run
|
||||
|
||||
Append one memlog event carrying the grade (init the memlog first if `{target-skill-path}/.memlog.md` does not exist):
|
||||
|
||||
```bash
|
||||
uv run {project-root}/_bmad/scripts/memlog.py append --path {target-skill-path}/.memlog.md --type event --text "analyze: grade <grade>, <c> critical / <h> high / <m> medium / <l> low, report .analysis/<timestamp>/skill-analysis-report.html"
|
||||
```
|
||||
|
||||
## Present
|
||||
|
||||
**IF `{headless_mode}=true`:** emit
|
||||
|
||||
```json
|
||||
{
|
||||
"headless_mode": true,
|
||||
"status": "complete",
|
||||
"skill": "{target-skill-path}",
|
||||
"grade": "excellent | good | fair | poor",
|
||||
"html_report": "{target-skill-path}/.analysis/<timestamp>/skill-analysis-report.html",
|
||||
"md_report": "{target-skill-path}/.analysis/<timestamp>/skill-analysis-report.md",
|
||||
"memlog": "{target-skill-path}/.memlog.md",
|
||||
"counts": { "critical": 0, "high": 0, "medium": 0, "low": 0 }
|
||||
}
|
||||
```
|
||||
|
||||
**IF interactive:** present the grade, the one-line verdict, the severity tally, and the top themes. Point to the HTML report path, say it opened, and offer to walk through findings, apply a fix, or route a leanness finding's `proposed_smallest` to a variant eval.
|
||||
@@ -0,0 +1,57 @@
|
||||
# Script Opportunities Reference
|
||||
|
||||
Hunting for deterministic work to push out of prompts and into native Python is the builder's differentiator. Neither competing skill-creator does it. A prompt that asks the model to count, parse, validate, or diff is paying generation cost on every run for an answer a script gives once, exactly, for free. The hunt is always on, not a finalize-time afterthought.
|
||||
|
||||
This file covers the determinism test that decides script-or-prompt, the signal-verb scan that surfaces candidates inside a draft, the opportunity categories, the pre-pass JSON pattern, and the transcript-detected repeated-work signal that eval runs expose. Reference `references/script-standards.md` for the full authoring conventions (PEP 723, output schema, testing).
|
||||
|
||||
## The line that decides it
|
||||
|
||||
Scripts handle deterministic operations. Prompts handle judgment. If a check has clear pass/fail criteria and the same input always yields the same output, it belongs in a script, and a prompt that does it instead is friction that does not beat its own absence.
|
||||
|
||||
## The determinism test
|
||||
|
||||
Run three questions over any step you are about to write as a prompt instruction:
|
||||
|
||||
1. Given identical input, will it always produce identical output? If yes, it is a script candidate.
|
||||
2. Could you write a unit test with an expected output? If yes, it is definitely a script.
|
||||
3. Does it require interpreting meaning, tone, or context? If yes, keep it as a prompt.
|
||||
|
||||
The boundary between the two:
|
||||
|
||||
| Scripts handle | Prompts handle |
|
||||
| --- | --- |
|
||||
| Fetch, transform, validate | Interpret, classify when ambiguous |
|
||||
| Count, parse, compare | Create, decide on incomplete info |
|
||||
| Extract, format, check structure | Evaluate quality, synthesize meaning |
|
||||
|
||||
## The signal-verb scan
|
||||
|
||||
When a draft's instructions contain these verbs, look for a script first: validate, count, extract, convert, transform, compare, scan for, check structure, against schema, graph or map dependencies, list all, detect pattern, diff or changes between. Each one names work that produces the same answer every time, so paying a model to do it is waste.
|
||||
|
||||
## Opportunity categories
|
||||
|
||||
| Category | What it does | Example |
|
||||
| --- | --- | --- |
|
||||
| Validation | Check structure, format, schema, naming | Confirm frontmatter fields exist |
|
||||
| Data extraction | Pull structured data without interpreting meaning | Extract every `{variable}` reference from markdown |
|
||||
| Transformation | Convert between known formats | Markdown table to JSON |
|
||||
| Metrics | Count, tally, aggregate | Token count per file via count_tokens.py |
|
||||
| Comparison | Diff, cross-reference, verify consistency | Cross-ref prompt names against SKILL.md references |
|
||||
| Structure checks | Verify directory layout, file existence | Confirm a skill folder has its required files |
|
||||
| Dependency analysis | Trace references, imports, relationships | Build a skill reference graph |
|
||||
| Pre-processing | Extract compact data from large files before the model reads them | Pre-extract file metrics into JSON for a scanner |
|
||||
| Post-processing | Verify model output meets structural requirements | Confirm generated YAML parses |
|
||||
|
||||
## The pre-pass JSON pattern
|
||||
|
||||
When a workflow stage would otherwise have the model read raw files to gather facts (line counts, token counts, frontmatter values, file inventories, reference lists), write a pre-pass script that does the reading and emits compact JSON, then have the prompt consume the JSON instead. The model reasons over metrics rather than burning context on raw bytes, the facts are exact rather than estimated, and the stage runs cheaper. The Analyze scanners use this pattern: deterministic pre-pass and lint scripts run first and hand each scanner compact JSON, so the scanners read numbers, not whole files.
|
||||
|
||||
## The transcript-detected repeated-work signal
|
||||
|
||||
The eval-runner produces transcripts when a skill runs on real input. Read them for the same helper being re-derived run after run. If the model writes a small parser, a counter, a format converter, or a validation snippet inline on turn after turn, that work is deterministic by definition (it produces the same code each time) and it is paying generation cost every run. Bundle it once as a script the skill calls, and the repeated inline derivation disappears.
|
||||
|
||||
This is the strongest possible evidence for a script, because it is not a guess about what the model might do, it is the model demonstrably doing the same deterministic thing repeatedly. When a baseline or quality eval run shows this pattern, the recommendation is a named script, and the next eval run should show the inline derivation gone.
|
||||
|
||||
## Authoring the script
|
||||
|
||||
Once a candidate is confirmed, `references/script-standards.md` owns how to write it: native Python over bash, stdlib-first, PEP 723 metadata, `uv run` for declared dependencies, a graceful fallback when an optional dependency's import is unavailable, and the `--help`/output/exit-code/testing checklist. One tip worth carrying into the prompt: point it at `scripts/foo.py --help` instead of inlining the interface, so the interface stays defined once and the prompt stays short.
|
||||
@@ -0,0 +1,93 @@
|
||||
# Script Creation Standards
|
||||
|
||||
When building scripts for a skill, follow these standards to ensure portability and zero-friction execution. Skills must work across macOS, Linux, and Windows (native, Git Bash, and WSL).
|
||||
|
||||
## Python Over Bash
|
||||
|
||||
**Always favor Python for script logic.** Bash is not portable — it fails or behaves inconsistently on Windows (Git Bash is MSYS2-based, not a full Linux shell; WSL bash can conflict with Git Bash on PATH; PowerShell is a different language entirely). Python with `uv run` works identically on all platforms.
|
||||
|
||||
**Safe bash commands** — these work reliably across all environments and are fine to use directly:
|
||||
|
||||
- `git`, `gh` — version control and GitHub CLI
|
||||
- `uv run` — Python script execution with automatic dependency handling
|
||||
- `npm`, `npx`, `pnpm` — Node.js ecosystem
|
||||
- `mkdir -p` — directory creation
|
||||
|
||||
**Everything else should be Python** — piping, `jq`, `grep`, `sed`, `awk`, `find`, `diff`, `wc`, and any non-trivial logic. Even `sed -i` behaves differently on macOS vs Linux. If it's more than a single safe command, write a Python script.
|
||||
|
||||
## Favor the Standard Library
|
||||
|
||||
Always prefer Python's standard library over external dependencies. The stdlib is pre-installed everywhere, requires no `uv run`, and has zero supply-chain risk. Common stdlib modules that cover most script needs:
|
||||
|
||||
- `json` — JSON parsing and output
|
||||
- `pathlib` — cross-platform path handling
|
||||
- `re` — pattern matching
|
||||
- `argparse` — CLI interface
|
||||
- `collections` — counters, defaultdicts
|
||||
- `difflib` — text comparison
|
||||
- `ast` — Python source analysis
|
||||
- `csv`, `xml.etree` — data formats
|
||||
|
||||
Only pull in external dependencies when the stdlib genuinely cannot do the job (e.g., `tiktoken` for accurate token counting, `pyyaml` for YAML parsing, `jsonschema` for schema validation). **External dependencies must be confirmed with the user during the build process** — they add install-time cost, supply-chain surface, and require `uv` to be available.
|
||||
|
||||
When a script does rely on a non-stdlib dependency, give it a graceful fallback for when the import is unavailable. `count_tokens.py` is the model: it uses `tiktoken` when present and a chars-over-four estimate when absent, so the script still produces a usable answer rather than crashing.
|
||||
|
||||
## PEP 723 Inline Metadata (Required)
|
||||
|
||||
Every Python script MUST include a PEP 723 metadata block. For scripts with external dependencies, use the `uv run` shebang:
|
||||
|
||||
```python
|
||||
#!/usr/bin/env -S uv run --script
|
||||
# /// script
|
||||
# requires-python = ">=3.10"
|
||||
# dependencies = ["pyyaml>=6.0", "jsonschema>=4.0"]
|
||||
# ///
|
||||
```
|
||||
|
||||
For scripts using only the standard library, use a plain Python shebang but still include the metadata block:
|
||||
|
||||
```python
|
||||
#!/usr/bin/env python3
|
||||
# /// script
|
||||
# requires-python = ">=3.10"
|
||||
# ///
|
||||
```
|
||||
|
||||
**Key rules:**
|
||||
|
||||
- The shebang MUST be line 1 — before the metadata block
|
||||
- Always include `requires-python`
|
||||
- List all external dependencies with version constraints
|
||||
- Never use `requirements.txt`, `pip install`, or expect global package installs
|
||||
- The shebang is a Unix convenience only — cross-platform invocation always uses `uv run scripts/foo.py`
|
||||
|
||||
## Invocation in SKILL.md
|
||||
|
||||
How a built skill's SKILL.md should reference its scripts (bare path from the skill root, per the path conventions):
|
||||
|
||||
- **All scripts:** `uv run scripts/foo.py {args}` — consistent invocation regardless of whether the script has external dependencies
|
||||
|
||||
`uv run` reads the PEP 723 metadata, silently caches dependencies in an isolated environment, and runs the script — no user prompt, no global install. Like `npx` for Python.
|
||||
|
||||
## Graceful Degradation
|
||||
|
||||
Skills may run in environments where Python or `uv` is unavailable (e.g., claude.ai web). Scripts should be the fast, reliable path — but the skill must still deliver its outcome when execution is not possible.
|
||||
|
||||
**Pattern:** When a script cannot execute, the LLM performs the equivalent work directly. The script's `--help` documents what it checks, making this fallback natural. Design scripts so their logic is understandable from their help output and the skill's context.
|
||||
|
||||
In SKILL.md, frame script steps as outcomes, not just commands:
|
||||
|
||||
- Good: "Validate path conventions (run `scripts/scan-paths.py --help` for details)"
|
||||
- Avoid: "Execute `uv run scripts/scan-paths.py`" with no context about what it does
|
||||
|
||||
## Script Interface Standards
|
||||
|
||||
- Implement `--help` via `argparse` (single source of truth for the script's API)
|
||||
- Accept target path as a positional argument
|
||||
- `-o` flag for output file (default to stdout)
|
||||
- Diagnostics and progress to stderr
|
||||
- Exit codes: 0=pass, 1=fail, 2=error
|
||||
- `--verbose` flag for debugging
|
||||
- Output valid JSON to stdout
|
||||
- No interactive prompts, no network dependencies
|
||||
- Tests in `scripts/tests/`
|
||||
@@ -0,0 +1,106 @@
|
||||
# Skill Quality Principles
|
||||
|
||||
BMad-specific knowledge for skills the builder produces. Loaded at build time so the author works to the bar from the start, and at analysis time so the lenses verify against the same bar. The universal bar — the destination shape, the tests, the two-version comparison, the reader, the habit — lives in `references/prompt-quality-canon.md`; load it alongside this file, apply it, and never restate it. What follows is only what the bare model would not know: BMad conventions, wiring, and the patterns and failure shapes BMad has paid for.
|
||||
|
||||
## Naming
|
||||
- Skill name = folder name (kebab-case)
|
||||
- Module skill: `{module-code}-{name}` (e.g. `bmm-create-prd`, `cis-brainstorm`)
|
||||
- Standalone: `{name}`
|
||||
- The `bmad-` prefix is reserved for official BMad creations
|
||||
|
||||
## Description format
|
||||
Two parts: `[5-8 word summary]. [Use when user says 'specific phrase' or 'specific phrase'.]`
|
||||
|
||||
Quote the trigger phrases. Default to conservative (explicit) triggering, since most BMad skills are explicitly invoked. Organic triggering is reserved for skills that should activate on context (e.g. "Trigger when code imports the anthropic SDK").
|
||||
|
||||
Bad: `Helps with PRDs and product requirements.` It is too vague and will hijack unrelated conversations.
|
||||
|
||||
## Path conventions
|
||||
All file references in a skill use bare paths from the skill root. The canonical Resolution rules block, stamped into any SKILL.md that references multiple internal files:
|
||||
|
||||
```
|
||||
## Resolution rules
|
||||
- Bare paths and `{skill-root}` (e.g. `references/press-release.md`) resolve from this skill's installed directory.
|
||||
- `{project-root}` → the project working directory.
|
||||
- `{skill-name}` → the skill directory's basename.
|
||||
```
|
||||
|
||||
Additional rules:
|
||||
- Forward slashes only (cross-platform).
|
||||
- Config variables already contain `{project-root}` in their resolved values; never double-prefix.
|
||||
- `references/` is for prompt content carved out of SKILL.md. `assets/` is for templates and other static content the workflow loads. `scripts/` is for deterministic code. Never put workflow content directly at skill root.
|
||||
|
||||
## Customization (customize.toml)
|
||||
customize.toml is the only customization mechanism — no installer questions, no module.yaml authoring, no boolean-toggle config, no settings concept inside a built skill. The full spec (the ask, universal defaults, offered-when-relevant points, three-layer merge rules, forbidden mechanisms) lives in `references/customize-toml-guide.md`. The wiring rule worth carrying everywhere: SKILL.md must read declared values as `{workflow.<name>}` — a hardcoded path beside a declared scalar silently no-ops the override.
|
||||
|
||||
## Intelligence placement
|
||||
Scripts handle plumbing (fetch, parse, validate, count, transform); prompts handle judgment (interpret, classify, decide). Crossing the boundary in either direction is a defect: a script using regex to decide what content means leaks intelligence into the script, and a prompt counting items or validating structure leaks determinism into the LLM. The determinism test, the signal-verb scan, and the pre-pass JSON pattern live in `references/script-opportunities-reference.md`.
|
||||
|
||||
## Workflows: inline first, carve by relevance
|
||||
Default: write the entire workflow as named sections in SKILL.md (`## Discovery`, `## Constraints`, `## Finalize`, and so on). A multi-stage coaching workflow can live in one SKILL.md. Carving follows the canon's test: carve what only some branches need or what pushes SKILL.md past its token tier, keep a routing map in SKILL.md, and leave inline what is too small to repay the indirection. When you carve:
|
||||
- **Descriptive filenames.** `references/press-release.md`, `references/customer-faq.md`, never `01-press-release.md`; the carve-out is a section, not a "step," and SKILL.md routes by name.
|
||||
- Each carved-out file works standalone, since context compaction can drop SKILL.md mid-flow. No "as described in the overview."
|
||||
- Progression conditions, where they exist, must be testable ("when X is captured, route to Y"). "When ready" is vague.
|
||||
- The file uses `{communication_language}` (and `{document_output_language}` if it produces a doc).
|
||||
- There are NO exit hooks in the system. Don't add `## On Exit` sections, because they would never run.
|
||||
- **Gotchas stay in SKILL.md.** A rule whose trigger the model cannot recognize — a soft-delete column that poisons queries, a health endpoint that lies, three names for one ID — never carves to a reference however branch-specific it is, because the model cannot load a file for a situation it does not know it is in. When a user corrects a running skill, the cheapest durable fix is appending that correction as a gotcha line.
|
||||
|
||||
## Headless mode
|
||||
When a skill supports headless invocation, the memlog absorbs every assumption made without the user: intent inference, proposed names, customization defaults, conflict resolutions, lint-fix calls, anything the user would have weighed in on interactively. Append these as typed `assumption` and `decision` entries through `{project-root}/_bmad/scripts/memlog.py` as they happen. The JSON return is the smallest set of paths the caller needs (typically `skill` plus the memlog path, plus the report path for analysis flows); the memlog carries the reasoning. `status` is `complete` or `blocked`; on `blocked`, include a one-line `reason` and still return the memlog path so the caller can read the detail. Without this discipline, headless silently buries its calls and the audit trail breaks on the next session.
|
||||
|
||||
## Subagent constraints
|
||||
- Subagents CANNOT spawn other subagents. Chain through the parent.
|
||||
- Don't read files in the parent if you can delegate the read; the parent stays lean.
|
||||
- Subagent prompts must specify the exact return format and an "ONLY return X" constraint, or you get verbose prose back.
|
||||
- **The implicit-read trap:** language like "review", "acknowledge", or "summarize what you have" causes the parent to read files even when you didn't ask for it. If a later stage delegates document analysis, earlier stages must NOT use that language. Use "note paths for subagent scanning; don't read them now".
|
||||
|
||||
## Length guidance
|
||||
Length is measured in tiktoken tokens through `scripts/count_tokens.py` (`cl100k_base`, with a chars/4 fallback when tiktoken is unavailable). There is no line-count gate anywhere. The canon's tests still apply to every line; budgets are a guardrail, not the goal.
|
||||
|
||||
SKILL.md is tiered against two org-configurable thresholds, `{workflow.skill_md_token_desired}` (default 2000) and `{workflow.skill_md_token_budget}` (default 3000). The hard tier sits deliberately under the Agent Skills spec's 5,000-token recommendation, and the budget is a drift guardrail, not the leanness bar — the canon's tests still cut a ceremonial line in a 900-token file:
|
||||
|
||||
- **Under desired** — on target; no action.
|
||||
- **Between desired and budget** — warn the user that SKILL.md is getting heavy and name the section most worth lifting, but do not block.
|
||||
- **Over budget** — a hard finding. Bring it back under budget through progressive disclosure: lift the largest self-contained section to `references/` or `assets/` and leave a one-line pointer, rather than compressing prose into something the model has to decode. Repeat until under `{workflow.skill_md_token_budget}`.
|
||||
|
||||
| File kind | Token budget |
|
||||
| --- | --- |
|
||||
| SKILL.md | `{workflow.skill_md_token_desired}` aim / `{workflow.skill_md_token_budget}` hard |
|
||||
| Multi-branch reference | ~4500 |
|
||||
| Single-purpose reference | ~9000 |
|
||||
|
||||
When any reference file runs past its budget, lift a section the same way.
|
||||
|
||||
## Patterns BMad has seen pay off
|
||||
Institutional names for patterns the LLM won't generate by default:
|
||||
|
||||
- **Open-floor opening**: Conversational skills start with an explicit invitation for the user to share everything they have (goals, references, examples, paths to artifacts) before any structured Q&A. The dump replaces most of the question script that would otherwise follow, and the agent then asks only what's missing. The form adapts to the input: a vague request gets "tell me everything", a path or URL gets "what do you want focused on?". It costs almost nothing token-wise and drastically improves the conversational feel.
|
||||
- **Soft-gate elicitation**: "Anything else, or shall we move on?" at natural transitions. Users always remember one more thing when given a graceful exit.
|
||||
- **Intent-before-ingestion**: Understand why the user is here before scanning artifacts, because without intent the scanning is noise.
|
||||
- **Capture-don't-interrupt**: Out-of-scope insights mid-flow get captured silently rather than redirected. Users in flow share their best material unprompted.
|
||||
- **Dual-output**: Human artifact plus an LLM distillate, when the artifact will feed downstream agents.
|
||||
- **Parallel review lenses**: Fan out two or three review subagents (skeptic, opportunity-spotter, a contextually-chosen lens) before finalizing a significant artifact.
|
||||
- **Three-mode architecture**: Guided, Yolo, Headless. Not every skill needs all three, but considering it during design prevents lock-in.
|
||||
- **Graceful degradation**: Subagent-dependent features fall back to sequential when subagents are unavailable.
|
||||
- **Plan-validate-execute**: For batch or destructive operations, produce an intermediate plan artifact, validate it against the source of truth with a script whose errors name the fix ("field 'signature_date' not found — available: …"), and only then execute. The validation script is the load-bearing piece, because it lets the model self-correct before anything irreversible runs.
|
||||
- **Working state across turns**: a multi-turn skill that builds something holds state as a memlog (the decision trail), a structured working artifact (the work-in-progress that transforms into the output), both, or neither. The choice and the full treatment live in `references/working-state-patterns.md`.
|
||||
|
||||
## Writing
|
||||
- One term per concept; pick it and stick to it.
|
||||
- A default, not a menu: when several tools or approaches would work, name one and demote the alternatives to an escape-hatch clause ("use X; for scanned input use Y"). A list of equal options makes the model spend its turn choosing instead of working.
|
||||
- Third person in descriptions ("Processes files", not "I help process files").
|
||||
- Descriptive file names (`form-validation-rules.md`, not `doc2.md`).
|
||||
|
||||
## Failure Modes With Body Count
|
||||
|
||||
- **Description over-broadens** → Skill hijacks unrelated conversations. Fix: quote trigger phrases.
|
||||
- **Vague progression conditions** ("when ready") → Stage never advances or advances early. Fix: testable conditions.
|
||||
- **Stage references SKILL.md** ("as above") → Breaks on compaction. Fix: make stages self-contained.
|
||||
- **Subagent prompt without explicit return format** → Verbose prose responses. Fix: "Return ONLY {schema}. No other output."
|
||||
- **Parent reads then delegates analysis** → Context bloat that makes the delegation pointless. Fix: delegate the read.
|
||||
- **Implicit-read trap** in a stage that precedes subagent delegation → Parent reads everything anyway. Fix: explicit "don't read these now".
|
||||
- **Boolean toggles in customize.toml** → Author didn't decide what the skill does; the surface becomes a permutation forest. Fix: pick a default and let users fork if they want the other shape.
|
||||
- **Hardcoded path in SKILL.md while customize.toml declares the scalar** → Override silently does nothing. Fix: SKILL.md must read `{workflow.<name>}`.
|
||||
- **Identity, communication style, or principles in `[workflow]`** → The workflow wants to be an agent. Fix: point the author at agent-builder and remove it from the workflow surface.
|
||||
- **Multi-turn producing skill with no working-state strategy** → state lives only in the conversation and dies on compaction or revisit. Fix: choose a memlog or a structured working artifact (`references/working-state-patterns.md`).
|
||||
- **Working-state strategy buried under ceremony** → a memlog-discipline enumeration or a meta `## Workspace` section pays the pattern's cost without its value. Fix: thread it through the intents at the points that matter; `bmad-product-brief` is the model.
|
||||
@@ -0,0 +1,120 @@
|
||||
# Standard Fields and Naming Conventions
|
||||
|
||||
Frontmatter, body fields, stage and hook naming, the Overview shapes, and path rules for skills the builder produces. The description format lives in `references/skill-quality-principles.md` and the full customize.toml surface lives in `references/customize-toml-guide.md`; this file points to them rather than restating them.
|
||||
|
||||
## Frontmatter fields
|
||||
|
||||
Only these two fields go in the YAML frontmatter block:
|
||||
|
||||
| Field | Description | Example |
|
||||
| --- | --- | --- |
|
||||
| `name` | Full skill name, hyphen-case, same as the folder name | `validate-json`, `cis-brainstorm` |
|
||||
| `description` | A 5-8 word summary, then a trigger clause naming what the user says | See Description format below |
|
||||
|
||||
Nothing else belongs in frontmatter. Role, stages, hooks, and config all live in the body or in customize.toml.
|
||||
|
||||
## Body fields
|
||||
|
||||
These describe the skill inside SKILL.md, never in frontmatter:
|
||||
|
||||
| Field | Description | Example |
|
||||
| --- | --- | --- |
|
||||
| `role-guidance` | A brief expertise primer | "Act as a senior DevOps engineer" |
|
||||
| `module-code` | Module code, only when the skill ships inside a module | `bmb`, `cis` |
|
||||
| `input-format` | What the skill accepts | JSON file path, stdin text |
|
||||
| `output-format` | What the skill returns | Validated JSON, error report |
|
||||
| `composability` | How other skills call this one | "Called by quality scanners for validation" |
|
||||
|
||||
### Module capability handoff
|
||||
|
||||
When the skill ships inside a module, capture these as handoff fields for the module builder; the workflow-builder never authors module.yaml.
|
||||
|
||||
| Field | Description |
|
||||
| --- | --- |
|
||||
| `phase-name` | The module phase this skill belongs to |
|
||||
| `after` / `before` | Ordering hints relative to sibling skills in the phase |
|
||||
| `is-required` | Whether the phase requires this skill to complete |
|
||||
|
||||
## Stage naming
|
||||
|
||||
Stages get descriptive names that say what the stage is for, never numbered prefixes: a number implies a fixed order the model must march through and fights the outcome-driven shape, so name the stage by its goal and let routing or prose carry the order where it matters.
|
||||
|
||||
| Prefer | Over |
|
||||
| --- | --- |
|
||||
| `discover`, `plan`, `build` | `01-discover`, `02-plan`, `03-build` |
|
||||
| `gather-input`, `draft`, `finalize` | `step-1-gather`, `step-2-draft` |
|
||||
|
||||
The same rule covers stage files on disk: `discover.md`, not `01-discover.md`. When a stage genuinely must precede another (a later stage consumes an earlier stage's output), state the dependency in the prose so the constraint is explicit, rather than relying on a number to imply it.
|
||||
|
||||
A simple utility usually needs no stages at all; it does one deterministic thing and returns. Reach for named stages only when the work has distinct phases a reader needs to navigate.
|
||||
|
||||
## Hook naming
|
||||
|
||||
Hook points use the `on_<event>` form, where the event names the moment the hook fires. The hook value is a prompt string or a command the skill runs at that point, empty by default.
|
||||
|
||||
| Hook | Fires |
|
||||
| --- | --- |
|
||||
| `on_complete` | After the skill finishes its work |
|
||||
| `on_start` | Before the skill's first stage runs |
|
||||
| `on_error` | When the skill hits an unrecoverable error |
|
||||
|
||||
Keep hooks to real moments the skill reaches. Do not invent hook points for events the skill never produces.
|
||||
|
||||
## customize.toml fields
|
||||
|
||||
customize.toml is the only customizability mechanism, emitted only when the author accepts the offer (default no). `references/customize-toml-guide.md` owns the whole surface: the universal baked defaults, the `<purpose>_template` / `<purpose>_output_path` / `on_<event>` naming patterns, the standards-not-options arrays, the three-layer merge rules, the override files, and the rule that SKILL.md must read `{workflow.<name>}` rather than a hardcoded path. Author against that file.
|
||||
|
||||
## Overview section
|
||||
|
||||
The Overview is the first section after the title and primes the model for everything that follows. State what the skill does, how it works, and the outcome it delivers.
|
||||
|
||||
| Skill type | Shape |
|
||||
| --- | --- |
|
||||
| Complex workflow | This skill helps you {outcome} through {approach}. Act as {role}, guiding users through {key stages}. The output is {deliverable}. |
|
||||
| Simple workflow | This skill {what it does} by {approach}. Act as {role}. Use when {triggers}. Produces {output}. |
|
||||
| Simple utility | This skill {what it does}. Use when {when to use}. Returns {output format}. |
|
||||
|
||||
## Description format
|
||||
|
||||
The frontmatter `description` is the primary trigger mechanism. Its two-part format, the explicit-vs-organic distinction, and the good/bad examples live in `references/skill-quality-principles.md` under "Description format." Default to explicit invocation unless the author describes organic activation during discovery.
|
||||
|
||||
## Role guidance
|
||||
|
||||
Every generated SKILL.md carries a brief role statement in the Overview or as a standalone line:
|
||||
|
||||
```markdown
|
||||
Act as {role}. {brief expertise and approach}.
|
||||
```
|
||||
|
||||
A skill may use a fuller identity and principles section when personality serves the work, but a single role line is enough for most.
|
||||
|
||||
## Path rules
|
||||
|
||||
### Skill-internal references
|
||||
|
||||
Use bare paths from the skill root for any file inside the skill, including a reference between two files in the same folder:
|
||||
|
||||
- `references/build-process.md`
|
||||
- `references/standard-fields.md` referenced from another file in `references/`, still a bare path
|
||||
- `scripts/validate.py`
|
||||
- `assets/template.md`
|
||||
|
||||
The convention is universal: bare paths from the skill root. Never use a `./` prefix, which causes inconsistency and breaks under context compaction when the working directory shifts.
|
||||
|
||||
### Project-scope paths
|
||||
|
||||
Use `{project-root}/...` for any path relative to the project root:
|
||||
|
||||
- `{project-root}/_bmad/planning/prd.md`
|
||||
- `{project-root}/docs/report.md`
|
||||
|
||||
### Anti-patterns
|
||||
|
||||
These are wrong; the fences keep the path linter from firing on them:
|
||||
|
||||
```text
|
||||
{project-root}/{output_folder}/file.md # WRONG, double-prefix; a config var already has {project-root}
|
||||
_bmad/planning/prd.md # WRONG, bare _bmad needs a {project-root} prefix
|
||||
./references/foo.md # WRONG, never use ./ for a skill-internal path
|
||||
./scripts/foo.py # WRONG, bare paths from skill root only
|
||||
```
|
||||
@@ -0,0 +1,63 @@
|
||||
# Working-State Patterns
|
||||
|
||||
How a skill's work survives across turns and context compaction. This is a design axis of its own, separate from persona, intent modes, and degradation, and it has more than one answer. Load this file when building or revising a multi-turn skill that builds something, or when a skill already carries a `.memlog.md` or a structured working artifact.
|
||||
|
||||
## The choice
|
||||
|
||||
A multi-turn skill that builds something has to hold state somewhere. Pick by the shape of the work, not by default.
|
||||
|
||||
| Strategy | Holds | Choose when |
|
||||
|---|---|---|
|
||||
| memlog | the *why* — decisions, directions, rejected alternatives, conflicts | the deliverable is prose or a document and its value includes reasoning that must survive revisits and surface conflicts on update |
|
||||
| Structured working artifact | the *what* — work-in-progress in a custom schema that transforms into the output | the work decomposes into a natural intermediate the user iterates on directly, which later becomes the deliverable |
|
||||
| Both | the what and the why | long, revisable creative or engineering work where construction state and rationale both matter |
|
||||
| Neither | nothing across turns | a one-shot transform, a stateless utility, or a purely conversational skill where the input/output contract or the live conversation is the state |
|
||||
|
||||
memlog and the structured artifact are not rivals. memlog is *meta* about the work — a decision trail beside the deliverable. The structured artifact *is* the work — state lives inside it, so continuity comes from re-reading the artifact rather than a side log. A skill uses either, both, or neither.
|
||||
|
||||
## memlog: the decision trail
|
||||
|
||||
For a skill whose value includes the reasoning behind the deliverable. The memlog carries identity across sessions, keeps the agent from railroading the user, surfaces conflicts on update, and creates an audit trail when the user overrides a past call. A skill that needs it looks fine on the first pass and falls apart on revisit without it.
|
||||
|
||||
The memlog is typed, append-only, and written through `{project-root}/_bmad/scripts/memlog.py` to a `.memlog.md` file beside the primary artifact. The model never edits or re-reads it mid-session; it appends one typed entry at a time and trusts the one-line JSON ack. The cycle is capture (append as decisions and directions land), distill (at finalize, account for every entry), and project (read the whole log once on resume or when building a summary).
|
||||
|
||||
### Entry types and the CLI
|
||||
|
||||
The memlog CLI is runtime-installed at `{project-root}/_bmad/scripts/memlog.py`; a built skill calls it there and bundles no copy of its own. The `{project-root}` token resolves at runtime, so the same invocation works from any skill's root.
|
||||
|
||||
- `init --path <file>` creates the log.
|
||||
- `append --path <file> --type <type> --text <text>` adds one typed entry; `<type>` is one of `decision`, `direction`, `assumption`, `gap`, `note`, `event`.
|
||||
- `set-complete --path <file>` marks the workflow done.
|
||||
|
||||
Each command prints a one-line JSON ack (`{"ok": true, ...}`). The write is atomic (temp file, fsync, rename) so an interrupted run never half-writes an entry, and there is no edit or remove subcommand by design, because history is never rewritten.
|
||||
|
||||
### Workspace layout
|
||||
|
||||
Files live in a single folder rooted at the primary artifact. When the artifact is a single document, the workspace is the document's containing folder and the log sits as a peer. When the artifact is itself a folder (a built skill, a generated module), the workspace IS that folder and `.memlog.md` sits beside the primary file such as `SKILL.md`. Either way the workspace exists from the moment intent is confirmed, so the user knows the path immediately and state lives on disk rather than in the conversation.
|
||||
|
||||
### Resume, update, validate, finalize
|
||||
|
||||
- **Resume**: on activation, glob for `.memlog.md` (never `.decision-log.md`). If found, surface it, read it once to rebuild state, and offer to resume. The single read recovers full context regardless of compaction; after that the workflow resumes append-only.
|
||||
- **Update**: read the memlog first; the change request enters as a signal against the standing record. If it contradicts a prior decision, surface the conflict before applying. Every change gets a new `decision` entry, and an override also records the rejected reasoning.
|
||||
- **Validate**: read the memlog first; challenge the artifact against the standards the user themselves set, not a generic rubric.
|
||||
- **Finalize**: distill the memlog — every meaningful entry is either captured in the artifact or explicitly set aside as process noise — then call `set-complete`.
|
||||
|
||||
### Treatment style
|
||||
|
||||
State the principle once where it first applies, typically inside the Create intent as a single clause ("write the primary skeleton and init `.memlog.md` in the workspace; the memlog is canonical process memory"). Mention reads at the moments that matter: Update reads before changing decisions, Validate before critiquing, Finalize distills at handoff. That is the entire treatment. Do NOT open with a "memlog discipline" enumeration of what to log, write a separate `## Workspace` meta-section, include a tree diagram, or split workspace creation into "for new" and "for existing" sub-sections — "init if absent, append if present" is one sentence. `bmad-product-brief` is the canonical example: about five sentences total, threaded through Create, Update, Validate, Constraints, and Finalize.
|
||||
|
||||
## Structured working artifact: the work-in-progress itself
|
||||
|
||||
Some skills need no decision trail because the work has a natural intermediate form that carries its own state. The skill builds a custom file with its own schema — story beats, an outline, character sheets, a shot list, a spec kernel, a requirements matrix — that the user reads and edits directly, and that later transforms into the deliverable: beats into prose, an outline into an article, a spec into code, a storyboard into a video.
|
||||
|
||||
State lives in the artifact's structure, so cross-turn continuity is just re-reading the file; there is no separate log to keep. Choose this when the work is constructive and decomposes, when the user benefits from seeing and shaping the intermediate, and when the final output is a transformation of it. The artifact's schema is the skill's real contract, so design it deliberately and make each section earn its place the same way a SKILL.md does.
|
||||
|
||||
The transform is part of the pattern: name where the intermediate ends and the deliverable begins, and whether the transform is a separate intent ("draft from beats") or the tail of the same run.
|
||||
|
||||
## Both, and when
|
||||
|
||||
Long or high-stakes work uses both: the structured artifact carries the construction state, and a memlog records the decisions about it ("merged beats 3 and 4 for pacing", "cut the subplot — rejected reasoning here"). Reach for both only when the rationale genuinely needs to outlive the conversation and the artifact alone would not explain why it looks the way it does. For most skills, one or neither is enough.
|
||||
|
||||
## When none of this applies
|
||||
|
||||
A one-shot transform, a stateless utility, or a purely conversational skill keeps no cross-turn state: the input/output contract or the live conversation is all there is. Do not bolt a memlog or an intermediate artifact onto a skill that does one deterministic thing and returns.
|
||||
Reference in New Issue
Block a user