Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions .claude/agents/monitor.md
Original file line number Diff line number Diff line change
Expand Up @@ -880,6 +880,50 @@ Include in JSON output when validation_criteria provided:
- If `security_critical == true`: set `valid: false` (missing executable enforcement is a release blocker).
- Otherwise: add a **testability** issue and require Actor to add tests.

### TDD Violation Detection (when tdd.enforce=true)

When the project config has `tdd.enforce: true`, apply this check to EVERY Actor submission before the 11-dimension model. A violation sets `valid: false` immediately.

**TDD violation criteria** — any of the following is a `tdd_violation`:
1. Tests were written AFTER implementation (tests reference implementation details unavailable from the spec alone, or the implementation was clearly written first)
2. Tests pass WITHOUT the implementation (trivial pass, over-mocked, testing structure not behavior)
3. No new test exists for the new behavior introduced by this subtask
4. Actor output claims "TDD" but shows tests written simultaneously with or after code

**How to check** (examine the diff):
- Test files should introduce assertions on behavior described in the spec, not on internal implementation structure
- Implementation files should be adding code that satisfies pre-existing test contracts
- If tests and implementation appear to be written together (same commit, same session), check whether tests assert behavior or structure
- A test that only checks `isinstance(result, SomeClass)` or a single attribute is structural, not behavioral

**Rationalization detection** — flag any of these patterns in Actor output as a violation signal:
- "Tests written simultaneously with code" → likely violation; verify manually
- "Tests verify implementation structure" → violation (must verify behavior)
- "I added tests after to ensure coverage" → violation
- "This is too simple to need a test first" → violation
- "The test is obvious so I wrote code first" → violation

**TDD verdict output** (include in JSON when tdd.enforce is true):

```json
{
"tdd_check": {
"enforced": true,
"violation": false,
"test_written_first": true,
"test_fails_without_impl": true,
"test_behavior_not_structure": true,
"verdict": "tdd_compliant"
}
}
```

If `violation: true`:
- Set `valid: false`
- Use verdict `tdd_violation`
- Include message: `"TDD violation: [specific reason]. Implementation must be deleted and restarted with failing tests first."`
- Do NOT suggest "just add tests" — the implementation must be deleted and rewritten test-first per the Iron Law.

</Monitor_Contract_Validation>

<Monitor_11D_Validation_v3_0>
Expand Down
151 changes: 150 additions & 1 deletion .claude/skills/map-tdd/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,58 @@ argument-hint: "[task description]"

**Key insight:** If implementation is in context when writing tests, AI writes tests that confirm the implementation — including its bugs. By writing tests FIRST from the spec only, tests become an independent correctness oracle.

## The Iron Law

```
NO PRODUCTION CODE WITHOUT A FAILING TEST FIRST
```

When `tdd.enforce: true` is set in `.map/config.yaml`, this law is mandatory — not advisory. Code written before a failing test is **deleted**. Not refactored. Not adapted. Deleted. Start over.

### RED-GREEN-REFACTOR (mandatory cycle)

| Phase | Action | Verification |
|-------|--------|--------------|
| **RED** | Write a failing test | VERIFY it fails for the right reason — not import error, not typo |
| **GREEN** | Write minimal code to pass | VERIFY all tests pass |
| **REFACTOR** | Clean up | VERIFY tests still pass after each change |

Never skip the RED phase. A test that is "obviously going to fail" still needs a run to confirm it fails for the right reason.

### Red Flags (self-detection)

Stop immediately and restart if you notice any of these:
1. Writing implementation before running any test
2. "Just this once" — there are no exceptions
3. "This is different because..." — it is not different
4. "The test is obvious" — then it takes 30 seconds
5. "I'll add tests after" — you will not, or they will confirm bugs
6. "The spec is clear enough" — tests make it executable
7. "TDD slows me down" — you are paying for it later
8. "This is configuration, not code" — configuration breaks too
9. "I already know it works" — the test proves it
10. "I'll refactor into testability later" — now is later
11. Writing tests AFTER implementation and calling it TDD
12. Fixing tests to match buggy implementation
13. "There's no way to test this" — extract the testable core
14. Checking "tests pass" without checking they fail first

### Rationalization Table

| Rationalization | Counter |
|-----------------|---------|
| "Too simple to test" | Simple code breaks. Test takes 30 seconds. |
| "I'll add tests after, I promise" | You won't. Or they'll confirm your bugs. |
| "Deleting N hours of work is wasteful" | Sunk cost fallacy. The waste was writing untested code. |
| "TDD is dogmatic" | TDD IS pragmatic — it forces a debuggable interface. |
| "I don't know how to test this yet" | That's a spec clarity problem. Clarify the spec first. |
| "The test would just mock everything" | Mock the boundary, not the behavior. Restructure. |
| "Tests slow down the deadline" | Debugging untested code slows it down more. |
| "The framework handles this" | Prove it with a test. |
| "I need to spike first" | Spikes are throwaway. Write the test on the real implementation. |
| "This is an integration concern" | Extract the unit. Integration tests come after unit tests. |
| "The existing codebase doesn't have tests" | You're adding tests now. One change at a time. |

**What this command does NOT do:**
- Does NOT replace /map-efficient — it augments the Actor/Monitor loop with test-first phases
- Does NOT work without a spec or plan — requires spec_<branch>.md or clear acceptance criteria
Expand Down Expand Up @@ -103,6 +155,27 @@ python3 .map/scripts/map_orchestrator.py set_tdd_mode true

This inserts TEST_WRITER (2.25) and TEST_FAIL_GATE (2.26) phases before ACTOR (2.3) in the step sequence.

### Check tdd.enforce Configuration

```bash
TDD_ENFORCE=$(python3 -c "
import sys; sys.path.insert(0,'src')
try:
from mapify_cli.config.project_config import load_map_config
from pathlib import Path
cfg = load_map_config(Path('.map/config.yaml'))
print('true' if cfg.tdd_enforce else 'false')
except Exception:
print('false')
" 2>/dev/null || echo 'false')
```

When `TDD_ENFORCE=true`:
- The Iron Law applies: any code written before a failing test is **deleted**
- Spec compliance reviewer and code quality reviewer run after each ACTOR phase (mandatory)
- Monitor enforces the TDD violation check
- The rationalization table above is your reference — no excuse survives it

---

## Step 1: State Machine Loop
Expand Down Expand Up @@ -303,7 +376,83 @@ Output: standard Actor output (approach + code + trade-offs)
)
```

After Actor returns, run the TDD Refactor step below, then call Monitor (2.4). Monitor validation is required before marking the subtask complete, including in TDD workflows.
After Actor returns, run the spec compliance reviewer and code quality reviewer (if `tdd.enforce: true`), then run the TDD Refactor step, then call Monitor (2.4).

### Spec Compliance Reviewer (adversarial, MANDATORY when tdd.enforce=true)

Spawn this BEFORE code quality review. The two reviews cannot be swapped.

**Adversarial framing:** The implementer finished suspiciously quickly. Do NOT trust the Actor summary. Read the actual code.

```python
Task(
subagent_type="actor",
description="Spec compliance review: subtask [ID]",
prompt=f"""You are an adversarial spec compliance reviewer.

You have been told the implementer finished subtask [ID]. Do NOT trust their summary.
Read the actual code diff. Compare every requirement in the spec to the actual diff.

<subtask_spec>
[paste AAG contract + validation_criteria from decomposition]
</subtask_spec>

<actual_diff>
[paste git diff for this subtask]
</actual_diff>

Check EVERY requirement:
1. Is each requirement implemented? Show file:line evidence.
2. Is there extra work not in the spec? (Scope creep, gold-plating)
3. Are there misunderstandings? (Implemented the wrong thing)
4. Are all edge cases from the spec covered?

Output:
- SPEC-COMPLIANT: YES or NO
- If NO: list each gap with exact file:line reference and the spec line it violates
"""
)
```

**Gate**: If the reviewer returns `SPEC-COMPLIANT: NO`, route back to ACTOR with the specific gaps listed. Do NOT proceed to code quality review until spec passes.

### Code Quality Reviewer (runs ONLY after spec reviewer passes)

```python
Task(
subagent_type="actor",
description="Code quality review: subtask [ID]",
prompt=f"""You are a code quality reviewer. Spec compliance is already verified.

Review the implementation quality only.

<actual_diff>
[paste git diff for this subtask]
</actual_diff>

Check:
1. **File responsibility**: Does each file do one thing?
2. **Unit decomposition**: Are functions small and independently testable?
3. **Plan conformance**: Does structure match the architectural plan?
4. **Size discipline**: No functions > 40 lines without documented justification
5. **Error handling**: All error paths handled explicitly
6. **Type safety**: No untyped `Any` without justification
7. **Naming**: Names describe behavior, not structure

Output:
**Strengths**: (what is done well — be specific)
**Issues**:
- CRITICAL: [blocks proceeding — must fix before Monitor]
- IMPORTANT: [should fix in this subtask]
- MINOR: [acceptable to defer]
**Assessment**: PASS | PASS_WITH_MINOR | FAIL
"""
)
```

**Sequential gate**: Spec compliance review MUST complete with `SPEC-COMPLIANT: YES` before code quality review starts. Running them in parallel bypasses the gate.

If code quality review returns `FAIL` (CRITICAL issues), route back to ACTOR. Once it returns `PASS` or `PASS_WITH_MINOR`, proceed to TDD Refactor and then Monitor.

### TDD Refactor: Clean Stale Red-Phase Comments

Expand Down
10 changes: 10 additions & 0 deletions src/mapify_cli/config/project_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,15 @@ class MapConfig:
# it yet.
max_wave_retries: int = 3

# Enforce TDD discipline project-wide (#285). When true, /map-efficient routes
# Actor-phase dispatches through the TEST_WRITER → TEST_FAIL_GATE → ACTOR
# sequence automatically, equivalent to always running /map-tdd. Code written
# before a failing test is treated as a violation: Monitor emits a TDD_VIOLATION
# finding. spec-compliance and code-quality reviewer subagents run after each
# subtask. Default OFF so existing workflows are unaffected.
# Dotted YAML key: `tdd.enforce` (aliased in load_map_config).
tdd_enforce: bool = False


def clamp_max_actors(n: object) -> int:
"""Clamp max_actors to the valid range [1, 8], or return the default 4.
Expand Down Expand Up @@ -331,6 +340,7 @@ def load_map_config(project_path: Path) -> MapConfig:
("execution.retry_degraded_once", "retry_degraded_once"),
("execution.concurrent_dispatch", "concurrent_dispatch"),
("execution.max_wave_retries", "max_wave_retries"),
("tdd.enforce", "tdd_enforce"),
):
if dotted in data and field_name not in data:
data[field_name] = data.pop(dotted)
Expand Down
44 changes: 44 additions & 0 deletions src/mapify_cli/templates/agents/monitor.md
Original file line number Diff line number Diff line change
Expand Up @@ -880,6 +880,50 @@ Include in JSON output when validation_criteria provided:
- If `security_critical == true`: set `valid: false` (missing executable enforcement is a release blocker).
- Otherwise: add a **testability** issue and require Actor to add tests.

### TDD Violation Detection (when tdd.enforce=true)

When the project config has `tdd.enforce: true`, apply this check to EVERY Actor submission before the 11-dimension model. A violation sets `valid: false` immediately.

**TDD violation criteria** — any of the following is a `tdd_violation`:
1. Tests were written AFTER implementation (tests reference implementation details unavailable from the spec alone, or the implementation was clearly written first)
2. Tests pass WITHOUT the implementation (trivial pass, over-mocked, testing structure not behavior)
3. No new test exists for the new behavior introduced by this subtask
4. Actor output claims "TDD" but shows tests written simultaneously with or after code

**How to check** (examine the diff):
- Test files should introduce assertions on behavior described in the spec, not on internal implementation structure
- Implementation files should be adding code that satisfies pre-existing test contracts
- If tests and implementation appear to be written together (same commit, same session), check whether tests assert behavior or structure
- A test that only checks `isinstance(result, SomeClass)` or a single attribute is structural, not behavioral

**Rationalization detection** — flag any of these patterns in Actor output as a violation signal:
- "Tests written simultaneously with code" → likely violation; verify manually
- "Tests verify implementation structure" → violation (must verify behavior)
- "I added tests after to ensure coverage" → violation
- "This is too simple to need a test first" → violation
- "The test is obvious so I wrote code first" → violation

**TDD verdict output** (include in JSON when tdd.enforce is true):

```json
{
"tdd_check": {
"enforced": true,
"violation": false,
"test_written_first": true,
"test_fails_without_impl": true,
"test_behavior_not_structure": true,
"verdict": "tdd_compliant"
}
}
```

If `violation: true`:
- Set `valid: false`
- Use verdict `tdd_violation`
- Include message: `"TDD violation: [specific reason]. Implementation must be deleted and restarted with failing tests first."`
- Do NOT suggest "just add tests" — the implementation must be deleted and rewritten test-first per the Iron Law.

</Monitor_Contract_Validation>

<Monitor_11D_Validation_v3_0>
Expand Down
Loading
Loading