Audience: users implementing features or enforcing test discipline. Version: 2.6.10. See also:
command-reference.md(the/bdd-pipelinecommand),orchestration.md(how plans execute),hooks.md§2.1 (oracle-md-only,quality-gate).
Two complementary workflows produce tested code. BDD starts from a .feature file and generates the implementation through a contract; TDD governs how any implementation is written (test first, then code, then refactor).
| Workflow | Starts from | Produces | Use when |
|---|---|---|---|
| BDD pipeline (Part A) | A .feature file |
Contract → tests → frontend → backend | A new feature with describable behavior |
| TDD discipline (Part B) | Any task | Oracle plan → failing test → code → pass → refactor | Any code change where regression matters |
Both run under the same execution discipline: Oracle plans, workers implement, quality-gate lints, evidence is required.
Status: Shipped and verified Package:
opencode-matrixx(v2.6.10) Context: Native matrixx feature — no Python, no external bundling
- What It Is
- Architecture Overview
- Pipeline Flow
- Available Slash Commands
- Example Walkthrough
- Agent Reference
- Technical Details
- Getting Started
| The BDD Pipeline is a first-class feature in matrixx that transforms Gherkin .feature files into production-ready artifacts through AI agents. Given a feature file, the pipeline produces:
- 📋 Contract JSON — Structured, schema-validated representation of the feature
- 🧪 Tests — Cucumber step definitions + page objects (E2E test suite)
- 🎨 Frontend — React components derived from UI annotations
- ⚙️ Backend — Typed API services with Zod validation
| All of this is driven by matrixx's built-in agents and skills — no human-in-loop required. The bdd-contract agent enriches the parsed Contract, and Morpheus (with bdd-frontend, bdd-backend, bdd-tests skills) generates the test, frontend, and backend artifacts. |
┌─────────────────────────────────────────────────────────────┐
│ Gherkin .feature file │
│ (login.feature, checkout.feature, api-pagination.feature) │
└──────────────────────┬──────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────┐
│ Deterministic Tools │
│ │
│ bdd_parse_gherkin → AST from @cucumber/gherkin │
│ bdd_create_contract → AST → Contract JSON (Zod v4) │
│ bdd_validate_contract → Contract JSON → schema check │
│ bdd_pipeline_run → full pipeline + ANALYSIS.md │
│ │
│ These are TDD-tested, deterministic, no LLM involved. │
└──────────────────────┬───────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────┐
│ AI Agents (EXPENSIVE) │
│ │
| │ bdd-contract → Enriches Contract with semantic insights |
| │ Morpheus → Runs bdd-frontend / bdd-tests / bdd-backend │
| │ skills to generate components, step defs, │
| │ and typed API services |
└──────────────────────┬───────────────────────────────────────┘
│
▼
┌────────────┬──────────┬──────────┬───────────────────────────┐
│ Contract │ Tests │ Frontend │ Backend │
│ JSON │ .steps │ .tsx │ .ts (Zod services) │
│ │ .pageobj │ │ │
└────────────┴──────────┴──────────┴───────────────────────────┘
| Decision | Rationale |
|---|---|
| No Python | Pure TypeScript/Node.js — consistent with matrixx stack |
No stories_2_tdd bundling |
Agents do the work natively; no legacy code import |
| 5 separate slash commands | No subcommand routing infrastructure needed |
| Deterministic tools first, agents second | Tools (bdd_parse_gherkin, bdd_create_contract) do the parsing work; agents enrich on top |
| 1 new EXPENSIVE agent |
┌─────────────────────┐
│ .feature file │
│ (Gherkin syntax) │
└──────────┬──────────┘
│
▼
┌─────────────────────┐
│ bdd_parse_gherkin │ ← Deterministic tool
│ │
│ Uses @cucumber/ │
│ gherkin v34 │
│ generateMessages() │
└──────────┬──────────┘
│ GherkinDocument AST (JSON)
▼
┌─────────────────────┐
│ bdd_create_contract │ ← Deterministic tool
│ │
│ Parses annotations │
│ Validates schema │
│ Writes JSON file │
└──────────┬──────────┘
│ Contract JSON v1
│ (schemaVersion: 1)
▼
┌───────────────┴───────────────┐
│ │
▼ ▼
┌──────────────────┐ ┌─────────────────────┐
│ bdd-contract │ │ Contract JSON file │
│ (agent enrich) │ │ (used downstream) │
└──────────────────┘ └──────────┬──────────┘
│
┌───────────────────────┼───────────────────────┐
│ │ │
▼ ▼ ▼
┌──────────────────┐ ┌──────────────────┐ ┌────────────────────┐
│ Morpheus │ │ Morpheus │ │ Morpheus │
│ + bdd-tests │ │ + bdd-frontend │ │ + bdd-backend │
│ │ │ │ │ │
│ Step defs │ │ React │ │ Typed API │
│ Page objects │ │ components │ │ services (Zod) │
│ npx cucumber-js │ │ (@ui:* annot.) │ │ (@api:* annot.) │
└──────────────────┘ └──────────────────┘ └────────────────────┘
There are 5 slash commands, each accessible from the matrixx chat prompt:
Purpose: Parse a .feature file and produce a Contract JSON.
/bdd-contract demos/bdd/login/1001_username_password.feature
What happens:
- Reads the
.featurefile - Parses it with
@cucumber/gherkin(deterministic AST) - Extracts Gherkin comments as structured annotations (
@api:*,@ui:*,@state:*,@assumption:) - Produces
.contract.jsonnext to the source file - The
bdd-contractagent enriches the contract with semantic insights
Output: <feature-path>.contract.json
// login.contract.json (simplified)
{
"schemaVersion": 1,
"generatedAt": "2026-07-06T...",
"sourceFile": "demos/bdd/login/1001_username_password.feature",
"feature": {
"name": "User Login",
"description": "As a registered user...",
"tags": [],
"annotations": {}
},
"scenarios": [
{
"name": "Successful login with valid credentials",
"tags": [],
"steps": [
{ "keyword": "Given", "text": "the user is on the login page" },
{ "keyword": "When", "text": "the user enters \"alice@example.com\" as the email" },
...
]
}
],
"annotations": {
"ui": [{ "key": "form", "value": "login-form-component" }, ...],
"api": [{ "endpoint": "POST /api/v1/auth/login" }],
"state": [{ "name": "session", "value": "new-session-init" }]
}
}
Purpose: Generate Cucumber step definitions + page objects from a Contract JSON.
/bdd-tests demos/bdd/login/1001_username_password.contract.json
What happens:
- Reads the Contract JSON
- The
bdd-testsskill (loaded into Morpheus) generates*.steps.tsfiles (Given/When/Then implementations) - Generates page object files (encapsulating UI interactions)
- You run tests with
npx cucumber-js
Output: Step definition files + page object files
Purpose: Generate React components from a Contract JSON (using @ui:* annotations).
/bdd-frontend demos/bdd/login/1001_username_password.contract.json
What happens:
- Reads the Contract JSON
- The
bdd-frontendskill (loaded into Morpheus) generates React components - Uses
@ui:route,@ui:testid,@ui:stringannotations to drive component design - Generates functional React components
Output: .tsx component files
Purpose: Generate typed API services from a Contract JSON (using @api:* annotations).
/bdd-backend demos/bdd/login/1001_username_password.contract.json
What happens:
- Reads the Contract JSON
- The
bdd-backendskill (loaded into Morpheus) generates typed service files - Uses
@api:endpointand@api:responseannotations for request/response types - Uses Zod schemas for runtime validation
Output: .ts service files with Zod schemas
Purpose: Run the full pipeline end-to-end — all 4 steps in sequence.
/bdd-pipeline demos/bdd/login/1001_username_password.feature
Pipeline Steps:
/bdd-contract— Parse feature → generate Contract JSON/bdd-tests— Generate Cucumber step definitions + page objects/bdd-frontend— Generate React components/bdd-backend— Generate typed API services
Output: All 4 artifacts produced in a single orchestrated run, plus ANALYSIS.md in the per-feature output dir (the /bdd-pipeline command delegates to the bdd_pipeline_run tool — it does not just chain the four commands)
Validate a contract on its own at any point with /bdd-pipeline's sibling tool bdd_validate_contract, or regenerate with --force.
Feature: User Login
As a registered user
I want to log in with my credentials
So that I can access my account dashboard
Scenario: Successful login with valid credentials
Given the user is on the login page
When the user enters "alice@example.com" as the email
And the user enters "securePass123" as the password
Then the user should be redirected to the dashboard
And a welcome message should be displayedProduces login.contract.json — a structured representation containing:
- Feature metadata (name, description)
- All scenarios with their steps
- Extracted annotations grouped by type (
api,ui,state,assumptions) schemaVersion: 1for future compatibility
Produces Cucumber step definition files:
// login.steps.ts
import { Given, When, Then } from "@cucumber/cucumber";
import { LoginPage } from "./login.page";
const page = new LoginPage();
Given("the user is on the login page", async () => {
await page.navigate();
});
When("the user enters {string} as the email", async (email: string) => {
await page.enterEmail(email);
});
// ...Produces a React component:
// Login.tsx
export function Login({ onLogin }: LoginProps) {
return (
<div data-testid="login-form-component">
<form onSubmit={...}>
<input data-testid="email-input" type="email" />
<button data-testid="login-submit-button" type="submit">
Log In
</button>
</form>
</div>
);
}Produces a typed API service:
// auth.ts
import { z } from "zod";
export const LoginRequestSchema = z.object({
email: z.string().email(),
password: z.string().min(8),
});
export const LoginResponseSchema = z.object({
token: z.string(),
redirectTo: z.string(),
});
export async function login(data: z.infer<typeof LoginRequestSchema>) {
const response = await fetch("/api/v1/auth/login", {
method: "POST",
body: JSON.stringify(LoginRequestSchema.parse(data)),
});
return LoginResponseSchema.parse(await response.json());
}| Agent | Cost | Mode | Skill | Purpose |
|---|---|---|---|---|
| bdd-contract | EXPENSIVE | all |
bdd-contract |
Enrich parsed Contract JSON with business semantics, naming, and intent |
| Agent | Skills Loaded | Purpose |
|---|---|---|
| Morpheus (existing) | bdd-frontend, bdd-backend, bdd-tests |
Generates React components, Cucumber step defs, and typed API services from Contract JSON |
| Agent | Skill Loaded | Purpose |
|---|---|---|
| Sati (existing) | bdd-frontend (alt path) |
Same bdd-frontend skill — Sati remains a valid invocation target for React-specific work |
| Agent | Skill Loaded | Purpose |
|---|---|---|
| Sati (existing) | bdd-frontend |
Generate React components from Contract @ui:* annotations |
| The bdd-contract agent follows the Cipher template (see src/agents/cipher.ts): |
┌──────────────────────────────────────────────────────────┐
│ Agent Factory │
│ │
│ createXxxAgent(model: string): AgentConfig │
│ │
│ Claude branch: │
│ - thinking: { type: "enabled", budgetTokens: 10000 } │
│ - temperature: 0.1 │
│ - maxTokens: 16000 │
│ │
│ GPT branch: │
│ - reasoningEffort: "medium" │
│ - textVerbosity: "high" │
│ - maxTokens: 16000 │
└──────────────────────────────────────────────────────────┘
| bdd-contract is registered in agentSources and agentMetadata in src/agents/builtin-agents.ts, discoverable via the agent menu (mode: "all"). The bdd-frontend / bdd-backend / bdd-tests skills are auto-loaded into Morpheus via buildAvailableSkills() and surfaced through the dynamic prompt builder — no specialist wrapper agents are needed. |
| Field | Type | Required | Description |
|---|---|---|---|
schemaVersion |
1 (literal) |
✅ | Version identifier for forward compatibility |
generatedAt |
ISO 8601 datetime | ✅ | When the contract was generated |
sourceFile |
string (path) | ✅ | Path to the original .feature file |
feature |
FeatureObject | ✅ | Feature name, description, tags, feature-level annotations |
scenarios |
Scenario[] | ✅ | List of scenarios with steps, tags, optional examples |
background |
Background? | ❌ | Shared background steps (Gherkin Background:) |
rules |
Rule[]? | ❌ | Gherkin 6+ Rule: blocks |
annotations |
Annotations | ✅ | Structured annotations: api, ui, state, assumptions |
Annotations are NOT placed in .feature files. The .feature file must be 100% pure Gherkin. The bdd-contract agent infers all annotations from the feature content via LLM reasoning and writes them into the Contract JSON.
| Annotation Field | Inferred From |
|---|---|
annotations.api[].method + path |
HTTP verbs (GET/POST/PUT/DELETE), URL paths in step text |
annotations.api[].description |
API context from feature/scenario descriptions |
annotations.ui[].component |
Page/screen names, form/button patterns in step text |
annotations.ui[].description |
UI element context |
annotations.state[].key |
Form field names, session/auth/cart state references |
annotations.state[].description |
State variable purpose and lifecycle |
annotations.assumptions[] |
Implicit preconditions, business rules in feature description |
bdd_parse_gherkin
- Input:
.featurefile path - Output: JSON-serialized GherkinDocument AST
- Uses:
@cucumber/gherkingenerateMessages()withSourceMediaType.TEXT_X_CUCUMBER_GHERKIN_PLAIN - TDD: 6 tests (valid file, missing file, malformed, sourceMap toggle, empty file)
bdd_create_contract
- Input: parsed AST JSON + source file path + options
- Output:
<feature-path>.contract.jsonwritten alongside the source file (with empty annotations) - Steps: walks GherkinDocument AST, validates against
ContractSchema. Annotations are LEFT EMPTY — the bdd-contract agent fills them via LLM inference from feature content - Annotation parsing lives in
src/tools/bdd-create-contract/tools.ts; contract types insrc/features/bdd/schema.ts+src/features/bdd/types.ts - TDD: 9 tests (valid contract, schema validation, force flag, malformed input, data tables, outlines, rules, empty annotations)
bdd_validate_contract
- Input: path to a Contract JSON file
- Output: schema validation result against
ContractSchema - Use it to check a contract before running
/bdd-tests,/bdd-frontend, or/bdd-backend
bdd_pipeline_run
- Input: one or more
.featurefile paths (or directories/globs) + output dir - Output: full pipeline run (contract → tests → frontend → backend) plus
ANALYSIS.mdin the per-feature output dir - This is what
/bdd-pipelineinvokes; seesrc/tools/bdd-pipeline/(pipeline-runner.ts,subagent-runner.ts,feature-resolver.ts,analysis-report.ts)
| Guardrail | Enforced |
|---|---|
| ❌ No Python files | ✓ 0 Python files added |
| ❌ No stories_2_tdd imports | ✓ None |
| ❌ No new MCP servers | ✓ None |
| ❌ No new hooks | ✓ None |
| ❌ No auto-installation of test runners | ✓ User runs bun install themselves for cucumber |
| ❌ No new specialist agents for tests/frontend/backend | ✓ These run via Morpheus + bdd-* skills (single-source-of-truth consolidation) |
| ❌ No subcommand routing | ✓ 5 separate commands |
Real demo features live under demos/bdd/ (numbered, e.g. demos/bdd/login/1001_username_password.feature). Each demo dir can contain a bdd.config.json, cucumber.cjs, generated *.contract.json files alongside the features, and pipeline outputs (ANALYSIS.md, backend/, components/, tests/, reports/):
| Demo dir | Content |
|---|---|
demos/bdd/login/ |
Username/password, PIN, biometric, migrated-user scenarios |
demos/bdd/recovery/ |
OTP verification, password reset scenarios |
demos/bdd/session/ |
Session timeout scenarios |
demos/bdd/registration/, demos/bdd/welcome/ |
Registration and welcome flows |
Run per-demo tests with the run-tests.sh inside each demo dir.
- matrixx (opencode-matrixx v2.6.10+)
@cucumber/gherkinv34 (bundled dependency — auto-installed with matrixx)@cucumber/cucumberand@playwright/test(user-installed per project)
# 1. Full pipeline (recommended for new features)
/bdd-pipeline src/features/my-feature.feature
# 2. Individual steps
/bdd-contract src/features/my-feature.feature
/bdd-tests src/features/my-feature.contract.json
/bdd-frontend src/features/my-feature.contract.json
/bdd-backend src/features/my-feature.contract.json
# 3. Overwrite existing artifacts
/bdd-contract src/features/my-feature.feature --force
/bdd-pipeline src/features/my-feature.feature --forceThe better your annotations, the better the generated code:
# @api:endpoint GET /api/users
# @api:response 200 { users: User[] }
# @ui:route /users -> UserListPage
# @ui:testid container=user-list-container
# @state:variable users User[] empty
# @assumption: Users are sorted by creation date descending
Feature: User Management
...After running the pipeline:
# Run generated tests
npx cucumber-js
# Typecheck generated code
bun run typecheck
# Lint generated code
bun run lint| Metric | Value |
|---|---|
| New test files | 49+ (12 agent + 23 schema/annotation + 14 tool) |
| New source files | ~28 across features/, agents/, tools/ |
| Commits | 16 on feat/bdd branch (after consolidation) |
| Branch target | dev (merge to dev, not master) |
| Production deps added | 1 (@cucumber/gherkin) |
| Dev deps added | 3 (@cucumber/cucumber, @playwright/test, tsx — for generated E2E test runs) |
| Lines of implementation | ~800 (non-test, non-prompt) |
| Lines of tests | ~1,300 |
src/
├── features/bdd/
│ ├── schema.ts ← Contract JSON v1 Zod schema (ContractSchema, ContractAnnotationsSchema)
│ ├── types.ts ← Re-exported TypeScript types
├── tools/
│ ├── bdd-parse-gherkin/ ← bdd_parse_gherkin tool (createBddParseGherkinTool)
│ ├── bdd-create-contract/ ← bdd_create_contract tool (createBddCreateContractTool, annotation parsing)
│ ├── bdd-validate-contract/ ← bdd_validate_contract tool (createBddValidateContractTool)
│ └── bdd-pipeline/ ← bdd_pipeline_run tool (pipeline-runner, subagent-runner, feature-resolver, analysis-report)
├── agents/
│ ├── bdd-contract.ts ← BDD contract specialist agent (only new agent)
│ ├── bdd-contract.test.ts ← 12 agent tests
│ ├── morpheus.ts ← Matrixx orchestrator (runs bdd-tests, bdd-frontend, bdd-backend)
├── features/builtin-skills/skills/
│ ├── bdd-contract.ts ← BDD contract skill (template prompt)
│ ├── bdd-tests.ts ← BDD tests skill
│ ├── bdd-frontend.ts ← BDD frontend skill
│ └── bdd-backend.ts ← BDD backend skill
└── features/builtin-commands/templates/
├── bdd-contract.ts ← /bdd-contract command template
├── bdd-tests.ts ← /bdd-tests command template
├── bdd-frontend.ts ← /bdd-frontend command template
├── bdd-backend.ts ← /bdd-backend command template
└── bdd-pipeline.ts ← /bdd-pipeline command template
TDD in Matrixx operates at two layers:
| Layer | Agent/Skill | Responsibility |
|---|---|---|
| Planning | Oracle | Decides what to test, when, and why — bakes TDD instructions into every work plan task |
| Enforcement | tdd-enforcer skill |
Ensures the executing agent actually follows RED-GREEN-REFACTOR at runtime |
Oracle (plans) → includes TDD instructions in every task
↓
Developer (executes) → loads tdd-enforcer skill to follow those instructions
┌─────────────────────────────────────────────────────────────────────┐
│ USER REQUEST │
│ "Implement feature X" │
└───────────────────────────┬─────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ ORACLE (PLANNER) │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ PLAN TEMPLATE (plan-template.ts) │ │
│ │ │ │
│ │ • Test Decision section: YES/NO for TDD │ │
│ │ • If TDD → each task includes RED-GREEN-REFACTOR steps │ │
│ │ • Acceptance criteria: bun test commands + expected output │ │
│ │ • QA scenarios: agent-executed verification steps │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ Output: .matrixx/plans/{name}.md │
│ (TDD instructions baked into every task) │
└───────────────────────────┬─────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ SOFTWARE-DEV PIPELINE │
│ (software-dev.ts) │
│ │
│ Phase 1: PLAN ─→ Phase 2: BUILD (TDD) ─→ Phase 3: VERIFY ─→ ... │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ DEVELOPER AGENT (category="source") │ │
│ │ │ │
│ │ load_skills=["git-master", "tdd-enforcer"] │ │
│ │ │ │
│ │ For each file: │ │
│ │ 1. RED: Write failing test first │ │
│ │ 2. GREEN: Minimum code to pass │ │
│ │ 3. REFACTOR: Clean up while green │ │
│ │ 4. Run bun test after each change │ │
│ └─────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
Oracle enforces TDD through the plan template (src/agents/oracle/plan-template.ts). When generating a work plan, Oracle includes TDD instructions in every task.
Every plan includes a test decision section:
### Test Decision
- **Infrastructure exists**: [YES/NO]
- **Automated tests**: [TDD / Tests-after / None]
- **Framework**: [bun test / vitest / jest / pytest / none]Each task in the plan follows RED-GREEN-REFACTOR:
### If TDD Enabled
Each TODO follows RED-GREEN-REFACTOR:
**Task Structure:**
1. **RED**: Write failing test first
- Test file: `[path].test.ts`
- Test command: `bun test [file]`
- Expected: FAIL (test exists, implementation doesn't)
2. **GREEN**: Implement minimum code to pass
- Command: `bun test [file]`
- Expected: PASS
3. **REFACTOR**: Clean up while keeping green
- Command: `bun test [file]`
- Expected: PASS (still)Each task's acceptance criteria includes TDD-specific verification:
**If TDD (tests enabled):**
- [ ] Test file created: src/auth/login.test.ts
- [ ] Test covers: successful login returns JWT token
- [ ] bun test src/auth/login.test.ts → PASS (3 tests, 0 failures)Beyond unit tests, Oracle mandates agent-executed QA scenarios for integration/E2E verification:
Scenario: Successful login redirects to dashboard
Tool: Playwright (playwright skill)
Preconditions: Dev server running on localhost:3000
Steps:
1. Navigate to: http://localhost:3000/login
2. Fill: input[name="email"] → "test@example.com"
3. Click: button[type="submit"]
4. Wait for: navigation to /dashboard
5. Assert: h1 text contains "Welcome back"
Expected Result: Dashboard loads with welcome messageThe tdd-enforcer skill (src/features/builtin-skills/skills/tdd-enforcer.ts) is loaded by the Developer agent at execution time. It enforces the RED-GREEN-REFACTOR cycle defined in the plan.
NO IMPLEMENTATION WITHOUT A FAILING TEST FIRST.
| Situation | Required First Action |
|---------------------|------------------------------------------|
| Bug fix | Write a test that REPRODUCES the bug |
| New feature | Write failing tests for each criterion |
| New function/class | Write test file BEFORE source file |
| Refactor | Verify coverage; write tests if missing |
| Any code change | "Do I have a failing test?" — if NO, STOP|
RED → Write a test. Run it. It MUST fail (for the right reason).
GREEN → Write minimum code to make that test pass. No more.
REFACTOR → Clean up code. Tests MUST stay green throughout.
Before GREEN:
"Does my test fail with the expected error? (not a compile error)"
IF NO → Fix the test. Do not proceed.
Before REFACTOR:
"Does bun test pass with 0 failures?"
IF NO → Fix the implementation. Do not proceed.
Before marking task DONE:
"Does bun test pass with 0 failures?"
"Have I written tests for EVERY change I made?"
IF EITHER IS NO → STOP. Fix it. Do not report done.| Convention | Rule |
|---|---|
| File placement | src/foo/bar.ts → src/foo/bar.test.ts (alongside source) |
| BDD markers | //#given / //#when / //#then in every test case |
| Imports | import { describe, test, expect } from "bun:test" |
| Evidence | bun test + bun run typecheck must pass before marking done |
TDD enforcement is integrated into the software-dev pipeline (src/features/builtin-skills/skills/software-dev.ts):
┌─────────────────────────────────────────────────────────────────┐
│ SOFTWARE-DEV PIPELINE │
├─────────┬─────────────┬─────────────────────────────────────────┤
│ Phase │ Role │ TDD Integration │
├─────────┼─────────────┼─────────────────────────────────────────┤
│ PLAN │ Oracle │ Generates TDD instructions in plan │
│ BUILD │ Developer │ Loads tdd-enforcer, follows RED-GREEN-REFACTOR │
│ VERIFY │ Quality │ Runs bun test + typecheck + lint + build│
│ REVIEW │ 5-agent │ Checks test coverage and quality │
│ SECURE │ Sentinel │ Reviews test isolation and mocking │
│ SHIP │ Git-master │ Ensures tests included in commits │
└─────────┴─────────────┴─────────────────────────────────────────┘
task(
category="source",
load_skills=["git-master", "tdd-enforcer"],
run_in_background=true,
description="Implement {FEATURE}",
prompt=`Implement from plan:
{PLAN}
File: {PATH}
Follow tdd-enforcer: write test FIRST (RED), then minimum code (GREEN),
then refactor. Run bun test after each change.`
)task(
category="source",
load_skills=["tdd-enforcer", "quality-gate"],
description="Write tests for {FEATURE}",
prompt="..."
)The tdd-enforcer skill is enabled by default (fail-closed). It stays active unless you explicitly opt out in the matrixx config. Schema: src/config/schema/tdd-enforcer.ts (TddEnforcerConfigSchema, enabled defaults to true; set enabled: false to opt out); wired as optional tdd_enforcer key in src/config/schema/matrixx-config.ts:
See matrixx.example.jsonc (tdd_enforcer block, active enabled: true) for the canonical example.
| File | Check |
|---|---|
src/plugin/skill-context.ts |
Adds tdd-enforcer to disabledSkills only on explicit enabled: false |
src/plugin-handlers/agent-config-handler.ts |
Same gate for agent config: strips only on explicit opt-out |
src/tools/delegate-task/tools.ts |
Hard requirement: category="source" fails without tdd-enforcer in load_skills, even when globally opted out |
src/tools/delegate-task/constants.ts (TDD_TEST_FIRST_APPEND) |
Test-first banner (NO IMPLEMENTATION WITHOUT A FAILING TEST FIRST) injected into source prompts, visible even if the skill is omitted |
- Oracle still includes TDD instructions in plans (template is static)
- Developer agent does NOT load the
tdd-enforcerskill for non-code categories category="source"still errors withouttdd-enforcerinload_skills: opt-out does not exempt code-writing delegations- RED-GREEN-REFACTOR enforcement stays active via the prompt banner and the Morpheus completion gate
- Tests-after is never acceptable for software-scope tasks
Task is NOT complete without (software-scope: any task writing or editing *.ts|*.tsx|*.js|*.jsx, or category="source"; docs-only and exploration exempt):
bun test # Must show: X tests passed, 0 failed
bun run typecheck # Must show: exit code 0, no errorsRED-first proof (both excerpts pasted, no "tests later"):
RED: bun test <file> FAIL excerpt (test ran before implementation, failed for the right reason)
GREEN: same command PASS excerpt (N passed, 0 failed)
Reporting format:
✅ bun test — 42 tests passed, 0 failed (3.2s)
✅ bun run typecheck — no errors
✅ RED: <file> failing test before fix, passing after (excerpts pasted)
If ANY verification fails:
- STOP. Do not report done.
- Fix the failure (code, never the test).
- Re-run ALL verification commands.
- Report done only when ALL pass.
| Anti-Pattern | Why It's Wrong | Correct Action |
|---|---|---|
| Write implementation THEN tests | Tests become documentation, not verification | Write failing test FIRST |
| Delete a failing test | You're hiding a problem | Fix the code to make it pass |
Skip a failing test (test.skip) |
Same as deleting | Fix the code |
| Write empty test body | Provides false confidence | Write real assertions |
| Only mock everything | Tests prove the mock works, not the code | Use real deps where feasible |
| Only happy-path tests | Errors happen in production | Add error/edge case tests |
Run bun test once at the very end |
Bugs compound | Run after each GREEN step |
| "Tests are for later" | Later never comes | Test-first, always |
| Separate test commit from impl commit | Breaks bisect, breaks CI | Same commit always |
User: "Implement feature X"
│
▼
Oracle: Creates plan with TDD instructions
│ • Test Decision: TDD enabled
│ • Each task: RED → GREEN → REFACTOR steps
│ • Acceptance criteria: bun test commands
│ • QA scenarios: agent-executed verification
│
▼
/start-work → Architect executes plan
│
▼
Developer agent loads tdd-enforcer skill
│ • For each file in plan:
│ 1. RED: Write failing test (bun test → FAIL)
│ 2. GREEN: Minimum code (bun test → PASS)
│ 3. REFACTOR: Clean up (bun test → PASS)
│ 4. Report evidence
│
▼
Quality gate verifies
│ • bun test — 0 failures
│ • bun run typecheck — no errors
│ • bun run lint — 0 issues
│ • bun run build — success
│
▼
Done ✓