Make each behavioral promise answerable by a test result.
SDD workflows produce requirements and plans; projects run tests. A green suite alone does not say which test checks a particular outcome, or whether a newly written scenario has any executable check at all. focused-spec keeps that link explicit: a small scenario names exact test targets, and run executes them before reporting the scenario as passed.
Keep your existing specification workflow and tests. The agent skill asks for scenarios while authoring a spec, allows planned: targets until implementation, and requires real evidence before completion. The CLI finds those scenarios in configured Markdown; project-local runners execute the selected tests. It does not replace OpenSpec, Spec Kit, BMad, or their native validation.
A scenario names one behavior and the exact tests that prove it. This one lives in the runnable OpenSpec example (Go + pytest):
#### Scenario: Blocked account submits valid credentials
- **ID**: `auth.login.blocked-account`
- **EVIDENCE**: `go-unit::./go/auth::TestBlockedAccount`
- **EVIDENCE**: `pytest-functional::tests/functional/test_auth.py::test_blocked_account`
- **WHEN** a blocked account submits otherwise valid credentials
- **THEN** authentication is rejectedFrom a checkout of this repository, npm run smoke executes both targets rather than treating the scenario text as proof. Its CLI output:
validation scope: all discovered scopes
execution selection: all discovered scopes
PASS auth.login.blocked-account
PASS go-unit::./go/auth::TestBlockedAccount
PASS pytest-functional::tests/functional/test_auth.py::test_blocked_account
summary: 1 PASS, 0 FAIL, 0 SKIP, 0 ERROR; 2 unique targets
Your SDD framework or Markdown files
↓
Focused scenario (ID · WHEN · THEN · EVIDENCE)
↓
Project-local runner → exact test → observed result
Your SDD tool owns proposals, requirements, and native document rules. focused-spec owns the checkable link from one outcome to one or more independent tests, even across languages. Its core is language- and framework-neutral; project-local runners select and execute the tests. If a Gherkin scenario already runs through Cucumber/Godog, that scenario is itself an executable specification—you do not need a second focused scenario merely to run it again.
Requires Node.js 22.16.0+. In the project you want to verify:
npm install --save-dev focused-spec@latestIf an agent will author or update behavioral scenarios, also install the agent skill for that agent. The CLI works without the skill when you maintain scenarios and runners yourself; the skill supplies the agent workflow, not the executable:
npx --yes skills add bamanoz/focused-spec --skill focused-spec-
Configure your scenario-bearing Markdown files in
.focused-spec/config.yamland implement a project-local runner for each evidence type you use. Installing the CLI alone does not provide runners or tests. -
Write a scenario with a stable
ID, oneWHEN, oneTHEN, and one or more exactEVIDENCEselectors. Multiple evidence rows must all pass. -
Validate and run the completed project. Validation resolves evidence but never executes tests;
runperforms strict validation and then executes the same selected scopes:npx focused-spec validate --strict npx focused-spec run
For any in-progress scope, use validate --scope <name> without --strict while evidence is planned:, then validate --scope <name> --strict and run --scope <name> once it is executable. Without --scope, both commands select every discovered scope. Scope and CLI details.
You do not need to rewrite your codebase or backfill every historical spec. Keep your current SDD workflow and tests; start with the next behavior you change. Enroll just its scenario with an ID and exact EVIDENCE, configure the existing Markdown location and a project-local runner, then run that evidence. Native scenarios without focused metadata stay untouched and are reported as unenrolled, not passed. Add coverage outcome by outcome as you work. See incremental adoption and OpenSpec's brownfield guide.
Document discovery is explicit, not tied to a framework or inferred from its folders:
Every layout assigns exactly one ordinary, path-safe scope, either explicitly with scope: <name> or by capturing one {scope} fragment. There is no default or privileged scope; even the name baseline is ordinary. Reusing a scenario ID across scopes requires REVISES: <source-scope>.
| Workflow | Runnable example | Focused scenario location |
|---|---|---|
| OpenSpec | Go + pytest | openspec/specs/**/spec.md |
| Spec Kit | Spec Kit-style feature | specs/{scope}/spec.md |
| BMad | BMad-style spec | _bmad-output/specs/spec-{scope}/scenarios.md companion |
Each example includes its own configuration, real tests, and project-local runner. Run the examples from this repository's checkout; plain Markdown works with the same configured document patterns.
A document pattern selects a location; it does not translate a framework's prose into focused scenarios. Framework-native validation remains the framework's job. Configuration guide.
- Each evidence selector must resolve to exactly one target or an actionable error.
PASSmeans the selected test ran and passed. A scenario passes only when all its evidence passes.planned:is temporary evidence allowed in any scope during non-strict validation, not a passing test.SKIPandERRORare not success by default;runvalidates strictly before execution.
- Concepts and evidence semantics
- Installation and agent skill · Configuration and scenario authoring
- Project-local runners · CLI reference
- Documentation map · Development workflow
MIT licensed — see LICENSE.