tdd-enforcer 0.3.2 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/adapters/pi/hooks.ts +1 -2
- package/adapters/pi/index.ts +7 -3
- package/adapters/pi/tools.test.ts +9 -4
- package/adapters/pi/tools.ts +42 -106
- package/engine/config.test.ts +69 -0
- package/engine/config.ts +9 -0
- package/engine/index.ts +6 -1
- package/engine/log.test.ts +171 -0
- package/engine/orchestrate.test.ts +445 -0
- package/engine/orchestrate.ts +159 -0
- package/engine/prompts.test.ts +90 -0
- package/{adapters/pi → engine}/prompts.ts +1 -1
- package/engine/state.test.ts +274 -2
- package/engine/state.ts +135 -1
- package/package.json +1 -2
- package/skills/tdd-enforcer/SKILL.md +4 -2
- package/DESIGN.md +0 -183
- package/adapters/pi/helpers.test.ts +0 -275
- package/adapters/pi/helpers.ts +0 -146
- package/adapters/pi/log.test.ts +0 -95
- package/adapters/pi/prompts.test.ts +0 -35
- package/behaviour.md +0 -175
- /package/{adapters/pi → engine}/log.ts +0 -0
package/behaviour.md
DELETED
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
# TDD Enforcer — Behaviour Spec
|
|
2
|
-
|
|
3
|
-
## Entry Gate — `loadTddState(root)` (all surfaces)
|
|
4
|
-
|
|
5
|
-
Every surface (commands, hooks, tools) hits this first:
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
loadTddState(root):
|
|
9
|
-
│
|
|
10
|
-
├── .pi/tdd/ exists? NO → "Missing .pi/tdd/. See the tdd-enforcer skill."
|
|
11
|
-
│
|
|
12
|
-
├── rules.json exists? NO → "Missing .pi/tdd/rules.json. See the tdd-enforcer skill."
|
|
13
|
-
│
|
|
14
|
-
├── rules.json valid? NO → "Invalid .pi/tdd/rules.json. See the tdd-enforcer skill."
|
|
15
|
-
│
|
|
16
|
-
├── .pi/tdd/.git/ exists? NO → initGit(root)
|
|
17
|
-
│ FAIL → "Failed to initialise private git repo."
|
|
18
|
-
│
|
|
19
|
-
├── state.json exists? NO → recoverState()
|
|
20
|
-
│ │
|
|
21
|
-
│ └── recoverState():
|
|
22
|
-
│ ├── .git exists? + headMessage readable?
|
|
23
|
-
│ │ ├── "tdd: init" → { enabled: false, current: "red" }
|
|
24
|
-
│ │ ├── "tdd: red" → { enabled: true, current: "green" }
|
|
25
|
-
│ │ ├── "tdd: green" → { enabled: true, current: "refactor" }
|
|
26
|
-
│ │ ├── "tdd: refactor" → { enabled: true, current: "red" }
|
|
27
|
-
│ │ └── no match / error → { enabled: false, current: "red" }
|
|
28
|
-
│ └── no .git / no commits → { enabled: false, current: "red" }
|
|
29
|
-
│
|
|
30
|
-
├── state.json valid? NO → recoverState() (same as above)
|
|
31
|
-
│
|
|
32
|
-
└── return { ok: true, state, config }
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
After this gate, every surface has `state` + `config`. Then branches on `state.enabled`.
|
|
36
|
-
|
|
37
|
-
---
|
|
38
|
-
|
|
39
|
-
## Commands (user only)
|
|
40
|
-
|
|
41
|
-
| Command | Gate check | After gate |
|
|
42
|
-
|---------|-----------|------------|
|
|
43
|
-
| `tdd:on` | Setup valid? | If `enabled` → error "already on". Init git (if missing), snapshot, set `enabled: true`. |
|
|
44
|
-
| `tdd:off` | Setup valid? | If `disabled` → error "already off". Set `enabled: false`. |
|
|
45
|
-
| `tdd:status` | Setup valid? | Show state + config regardless of `enabled`. |
|
|
46
|
-
| `tdd:reset` | Setup valid? | Nuke private git, re-init, snapshot, set `enabled: false`. |
|
|
47
|
-
| `tdd:red` | Setup valid? | If already in RED → no-op. Snapshot working tree, auto-enable if disabled, set `current: "red"`. Notify "Skipped to RED phase". |
|
|
48
|
-
| `tdd:green` | Setup valid? | If already in GREEN → no-op. Snapshot working tree, auto-enable if disabled, set `current: "green"`. Notify "Skipped to GREEN phase". |
|
|
49
|
-
| `tdd:refactor` | Setup valid? | If already in REFACTOR → no-op. Snapshot working tree, auto-enable if disabled, set `current: "refactor"`. Notify "Skipped to REFACTOR phase". |
|
|
50
|
-
|
|
51
|
-
All errors reference the tdd-enforcer skill.
|
|
52
|
-
|
|
53
|
-
### Phase Jump Commands — Usage
|
|
54
|
-
|
|
55
|
-
These let the user skip phases they don't need for small changes:
|
|
56
|
-
|
|
57
|
-
| Scenario | Command | Why |
|
|
58
|
-
|----------|---------|-----|
|
|
59
|
-
| "This is just an implementation change, no test needed" | `/tdd:green` | Skip RED, go straight to GREEN. Test files stay locked, implementation files unlocked. |
|
|
60
|
-
| "This is just cleanup, not new behaviour" | `/tdd:refactor` | Skip RED + GREEN. All files unlocked. |
|
|
61
|
-
| "Done refactoring, start next cycle" | `/tdd:red` | Same as `next_tdd_phase` from REFACTOR but direct — no gate check needed. |
|
|
62
|
-
|
|
63
|
-
Unlike `next_tdd_phase`, these commands do NOT run transition gate checks. The user is explicitly choosing to skip a phase — they own the consequences.
|
|
64
|
-
|
|
65
|
-
---
|
|
66
|
-
|
|
67
|
-
## Hooks (agent — automatic)
|
|
68
|
-
|
|
69
|
-
| Hook | Gate + enabled | Behaviour |
|
|
70
|
-
|------|---------------|-----------|
|
|
71
|
-
| `tool_call` (write/edit) | Setup broken → pass through. Disabled → pass through. **Enabled** → block if `relPath` starts with `.pi/tdd/` OR phase-locked. | |
|
|
72
|
-
| `tool_result` (bash) | Setup broken → pass through. Disabled → pass through. **Enabled** → revert if path starts with `.pi/tdd/` OR phase-locked. RETOOL revert paths to `.pi/tdd/` prefix check. | |
|
|
73
|
-
|
|
74
|
-
---
|
|
75
|
-
|
|
76
|
-
## Tools (agent — callable)
|
|
77
|
-
|
|
78
|
-
| Tool | Gate + enabled | Behaviour |
|
|
79
|
-
|------|---------------|-----------|
|
|
80
|
-
| `next_tdd_phase` | Disabled → error. Enabled → run gate + snapshot + transition. | |
|
|
81
|
-
| `previous_tdd_phase` | Disabled → error. Enabled → revert to previous snapshot. | |
|
|
82
|
-
| `tdd_status` | Disabled → error. Enabled → show state + config. | |
|
|
83
|
-
|
|
84
|
-
---
|
|
85
|
-
|
|
86
|
-
## Flow Diagrams
|
|
87
|
-
|
|
88
|
-
### Initial Setup Flow
|
|
89
|
-
|
|
90
|
-
```
|
|
91
|
-
User creates .pi/tdd/rules.json
|
|
92
|
-
│
|
|
93
|
-
▼
|
|
94
|
-
User runs /tdd:on
|
|
95
|
-
│
|
|
96
|
-
▼
|
|
97
|
-
Gate: .pi/tdd/ exists? ──NO──► error (agent creates it)
|
|
98
|
-
│
|
|
99
|
-
YES
|
|
100
|
-
│
|
|
101
|
-
▼
|
|
102
|
-
Gate: rules.json exists? ──NO──► error (agent creates it)
|
|
103
|
-
│
|
|
104
|
-
YES
|
|
105
|
-
│
|
|
106
|
-
▼
|
|
107
|
-
Gate: rules.json valid? ──NO──► error (agent fixes it)
|
|
108
|
-
│
|
|
109
|
-
YES
|
|
110
|
-
│
|
|
111
|
-
▼
|
|
112
|
-
Gate: state.json exists? ──NO──► auto-create
|
|
113
|
-
│
|
|
114
|
-
YES/auto-created
|
|
115
|
-
│
|
|
116
|
-
▼
|
|
117
|
-
Init git (if missing) ──► snapshot ──► enabled: true
|
|
118
|
-
│
|
|
119
|
-
▼
|
|
120
|
-
TDD active — RED phase, enforcement on
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
### Phase Cycle Flow
|
|
124
|
-
|
|
125
|
-
```
|
|
126
|
-
RED: write tests
|
|
127
|
-
│ tests fail? ──NO──► "Tests passed. Add a failing test before transitioning."
|
|
128
|
-
│ YES
|
|
129
|
-
├─► next_tdd_phase ──► GREEN
|
|
130
|
-
│
|
|
131
|
-
GREEN: implement features
|
|
132
|
-
│ tests pass? ──NO──► "Tests failed. Fix them before transitioning."
|
|
133
|
-
│ YES
|
|
134
|
-
├─► next_tdd_phase ──► REFACTOR
|
|
135
|
-
│
|
|
136
|
-
REFACTOR: refactor freely
|
|
137
|
-
│ tests pass? ──NO──► "Tests failed. Fix them before transitioning."
|
|
138
|
-
│ YES
|
|
139
|
-
├─► next_tdd_phase ──► RED (new cycle)
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
### Bash Enforcement Flow
|
|
143
|
-
|
|
144
|
-
```
|
|
145
|
-
Agent runs bash command
|
|
146
|
-
│
|
|
147
|
-
▼
|
|
148
|
-
tool_call hook: stash pre-command state
|
|
149
|
-
│
|
|
150
|
-
▼
|
|
151
|
-
Bash executes (modifies files)
|
|
152
|
-
│
|
|
153
|
-
▼
|
|
154
|
-
tool_result hook: diff against stash
|
|
155
|
-
│
|
|
156
|
-
▼
|
|
157
|
-
For each changed file:
|
|
158
|
-
├── path starts with ".pi/tdd/"? ──YES──► revert, flag as violation
|
|
159
|
-
├── locked in current phase? ──YES──► revert, flag as violation
|
|
160
|
-
└── no violations ──► keep changes
|
|
161
|
-
│
|
|
162
|
-
▼
|
|
163
|
-
Return warning listing reverted vs retained files
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
---
|
|
167
|
-
|
|
168
|
-
## Protection Summary
|
|
169
|
-
|
|
170
|
-
| Surface | `.pi/tdd/` locked? | Phase-locked files? |
|
|
171
|
-
|---------|-------------------|-------------------|
|
|
172
|
-
| write/edit (TDD enabled) | ✅ Block | ✅ Block |
|
|
173
|
-
| write/edit (TDD disabled) | ❌ Free | ❌ Free |
|
|
174
|
-
| bash (TDD enabled) | ✅ Reverted | ✅ Reverted |
|
|
175
|
-
| bash (TDD disabled) | ❌ Free | ❌ Free |
|
|
File without changes
|