empirical-sdd 0.20.0
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/LICENSE +21 -0
- package/README.md +366 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +33711 -0
- package/dist/core.d.ts +54 -0
- package/dist/decisions.d.ts +7 -0
- package/dist/discovery.d.ts +47 -0
- package/dist/errors.d.ts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +3224 -0
- package/dist/integrations.d.ts +3 -0
- package/dist/mcp.d.ts +3 -0
- package/dist/specifications.d.ts +12 -0
- package/dist/storage.d.ts +74 -0
- package/dist/types.d.ts +283 -0
- package/dist/worktrees.d.ts +13 -0
- package/package.json +58 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Mateo Cerquetella and Empirical SDD contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
# Empirical SDD
|
|
2
|
+
|
|
3
|
+
Empirical is a small, agent-neutral spec-driven development engine for Codex,
|
|
4
|
+
Claude Code, Cursor, Gemini CLI, Windsurf, and any MCP client. It turns a coding
|
|
5
|
+
request into an exact, resumable workflow with committed contracts, evidence,
|
|
6
|
+
review, living capability specs, and safe Git worktree isolation.
|
|
7
|
+
|
|
8
|
+
Empirical `0.20.0` is an alpha release. It deliberately uses one active feature
|
|
9
|
+
per checkout and real Git worktrees for parallel work.
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install -g empirical-sdd
|
|
15
|
+
cd your-repository
|
|
16
|
+
empirical init
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
The first interactive init asks once for:
|
|
20
|
+
|
|
21
|
+
- whether Empirical should offer isolation when another feature is active;
|
|
22
|
+
- the detected or edited default Git base;
|
|
23
|
+
- the sibling path template, defaulting to `../{repo}-{feature}`;
|
|
24
|
+
- the branch pattern, defaulting to `{type}/{feature}`;
|
|
25
|
+
- whether Complex features require evidence-backed decision records.
|
|
26
|
+
|
|
27
|
+
Press Enter to accept each safe default. Edit the answers later with:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
empirical config
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Automation never waits for terminal input:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
empirical init --defaults
|
|
37
|
+
empirical init --isolation ask --base main \
|
|
38
|
+
--worktree-path '../{repo}-{feature}' \
|
|
39
|
+
--branch-pattern '{type}/{feature}' \
|
|
40
|
+
--decisions required
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## The normal UX
|
|
44
|
+
|
|
45
|
+
You can use Empirical directly in your agent after project or global skills are
|
|
46
|
+
installed. The agent chooses the lane, executes the returned action, completes
|
|
47
|
+
the exact revision, and consumes the next action until Done.
|
|
48
|
+
|
|
49
|
+
```text
|
|
50
|
+
vague idea ──> five Socratic passes ──> approved refined contract
|
|
51
|
+
│
|
|
52
|
+
concrete request ─────────────────────────────┤
|
|
53
|
+
▼
|
|
54
|
+
Fast or Complex exact workflow
|
|
55
|
+
│
|
|
56
|
+
another feature already active?
|
|
57
|
+
│ no │ yes
|
|
58
|
+
▼ ▼
|
|
59
|
+
work here preview Git worktree
|
|
60
|
+
│
|
|
61
|
+
explicit approval
|
|
62
|
+
│
|
|
63
|
+
▼
|
|
64
|
+
create, start, show resume
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Fast is only for explicit, tiny, localized, reversible, low-risk non-UI work.
|
|
68
|
+
Everything else—including UI, architecture, public APIs, security, migrations,
|
|
69
|
+
and cross-cutting changes—uses Complex.
|
|
70
|
+
|
|
71
|
+
## Socratic discovery is back
|
|
72
|
+
|
|
73
|
+
For a genuinely vague idea:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
empirical explore "Build a cooperative browser puzzle with time loops"
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Empirical asks one question at a time across five passes:
|
|
80
|
+
|
|
81
|
+
1. primary user and observed problem;
|
|
82
|
+
2. smallest observable outcome;
|
|
83
|
+
3. boundaries, constraints, and explicit non-goals;
|
|
84
|
+
4. failures and solution-changing risks;
|
|
85
|
+
5. concrete verification.
|
|
86
|
+
|
|
87
|
+
It saves every answer under `.empirical/discoveries/`, shows the full refined
|
|
88
|
+
contract, and waits for explicit approval before starting Fast or Complex.
|
|
89
|
+
|
|
90
|
+
Use packet mode for an already-running agent:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
empirical explore "<idea>" --no-interview
|
|
94
|
+
empirical explore "<idea>" --json
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
`--agent codex` is an optional human terminal entrypoint after approval. Agent
|
|
98
|
+
skills continue in their current runtime and never launch another AI.
|
|
99
|
+
|
|
100
|
+
## Simple feature demo
|
|
101
|
+
|
|
102
|
+
Request:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
empirical fast "Add a health command that prints ok"
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
The response is the implementation action and exact completion command:
|
|
109
|
+
|
|
110
|
+
```text
|
|
111
|
+
Empirical · step 1/1
|
|
112
|
+
|
|
113
|
+
add-a-health-command-that-prints-ok: implement (fast, waiting, revision 1)
|
|
114
|
+
|
|
115
|
+
Fast lane: implement the generated observable criterion, run one focused test,
|
|
116
|
+
review the diff, and complete revision 1.
|
|
117
|
+
|
|
118
|
+
Complete with: empirical complete --revision 1 --outcome passed \
|
|
119
|
+
--summary "Added the health command" \
|
|
120
|
+
--test "health command test passed" \
|
|
121
|
+
--review "focused diff reviewed"
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Fast writes everything below one feature directory:
|
|
125
|
+
|
|
126
|
+
```text
|
|
127
|
+
.empirical/specs/add-a-health-command-that-prints-ok/
|
|
128
|
+
├── spec.md
|
|
129
|
+
├── state.json
|
|
130
|
+
├── events/
|
|
131
|
+
└── evidence.json # after evidenced completion
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Complex feature demo
|
|
135
|
+
|
|
136
|
+
Request:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
empirical complex "Add team invitations with expiration and revocation"
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
The seven gates are:
|
|
143
|
+
|
|
144
|
+
1. Specify: observable criteria, scope, risks, verification, capability deltas.
|
|
145
|
+
2. Design: architecture plus accepted decisions.
|
|
146
|
+
3. Plan: executable implementation sequence.
|
|
147
|
+
4. Implement: code and focused checks.
|
|
148
|
+
5. Verify: criterion-by-criterion evidence; real browser and screenshot for UI.
|
|
149
|
+
6. Review: diff, criteria, and accepted-decision alignment.
|
|
150
|
+
7. Archive: apply reviewed deltas to living capability specifications.
|
|
151
|
+
|
|
152
|
+
Each completion response is already the next action:
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
empirical complete --revision 1 --outcome passed --summary "Specified invitations"
|
|
156
|
+
# edit design.md and decisions.md
|
|
157
|
+
empirical complete --revision 2 --outcome passed --summary "Designed invitation ownership"
|
|
158
|
+
# continue with the exact commands returned by Empirical
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
A material decision is concise and reviewable:
|
|
162
|
+
|
|
163
|
+
```markdown
|
|
164
|
+
## D-001: Own invitation expiry in the domain service
|
|
165
|
+
|
|
166
|
+
Status: Accepted
|
|
167
|
+
|
|
168
|
+
### Evidence
|
|
169
|
+
- Existing invitation writes already pass through the domain service.
|
|
170
|
+
|
|
171
|
+
### Options
|
|
172
|
+
1. Expire in the request handler.
|
|
173
|
+
2. Expire in the domain service.
|
|
174
|
+
|
|
175
|
+
### Chosen approach
|
|
176
|
+
Use the domain service so API and background jobs share one rule.
|
|
177
|
+
|
|
178
|
+
### Trade-offs and risks
|
|
179
|
+
The service gains time semantics; inject a clock for deterministic tests.
|
|
180
|
+
|
|
181
|
+
### Verification
|
|
182
|
+
Test API and background expiry against the same injected clock.
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
This is a visible decision trail, not persisted private chain-of-thought. Raw
|
|
186
|
+
prompts, scratchpads, tokens, credentials, and secrets do not belong there.
|
|
187
|
+
|
|
188
|
+
## Understand the next action
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
empirical explain
|
|
192
|
+
empirical explain --json
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Explain is read-only and reports:
|
|
196
|
+
|
|
197
|
+
- current feature, phase, status, and revision;
|
|
198
|
+
- why the state machine selected the next action;
|
|
199
|
+
- required and missing context;
|
|
200
|
+
- whether the gate says proceed or stop;
|
|
201
|
+
- accepted decision summaries.
|
|
202
|
+
|
|
203
|
+
MCP clients use `empirical_explain` and receive the same structured fields.
|
|
204
|
+
|
|
205
|
+
## Parallel work uses Git worktrees
|
|
206
|
+
|
|
207
|
+
If a different feature is active, Fast or Complex returns a proposal instead of
|
|
208
|
+
overwriting state:
|
|
209
|
+
|
|
210
|
+
```text
|
|
211
|
+
Empirical needs an isolated Git worktree (approval required)
|
|
212
|
+
Active feature: add-team-invitations
|
|
213
|
+
New request: Fix password reset expiry
|
|
214
|
+
Workflow/type: complex/fix
|
|
215
|
+
Base: main
|
|
216
|
+
Base commit: <approved-base-commit>
|
|
217
|
+
Branch: fix/fix-password-reset-expiry
|
|
218
|
+
Path: /projects/my-app-fix-password-reset-expiry
|
|
219
|
+
Command: git worktree add -b fix/fix-password-reset-expiry ... <approved-base-commit>
|
|
220
|
+
No mutation has occurred.
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
After approval Empirical:
|
|
224
|
+
|
|
225
|
+
1. requires the current checkout to be clean, including untracked files;
|
|
226
|
+
2. resolves the selected base;
|
|
227
|
+
3. rejects existing branches, paths, and registered checkout collisions;
|
|
228
|
+
4. runs `git worktree add -b <branch> <path> <approved-base-commit>` without
|
|
229
|
+
`--force`, so the approved base cannot move before creation;
|
|
230
|
+
5. initializes or migrates the new checkout;
|
|
231
|
+
6. starts the exact request there;
|
|
232
|
+
7. returns path, branch, base, feature, revision, and resume command.
|
|
233
|
+
|
|
234
|
+
Human terminal form:
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
empirical worktree create "Fix password reset expiry" \
|
|
238
|
+
--workflow complex --type fix
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Use `--yes` only after reviewing the rendered proposal in automation. Empirical
|
|
242
|
+
never stashes, commits, moves local changes, forces Git, deletes worktrees, or
|
|
243
|
+
deletes branches.
|
|
244
|
+
|
|
245
|
+
## Agent skills and commands
|
|
246
|
+
|
|
247
|
+
Project-local integrations are installed by `empirical init` and refreshed by:
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
empirical integrate
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
Install the five Empirical skills globally for every supported agent:
|
|
254
|
+
|
|
255
|
+
```bash
|
|
256
|
+
empirical integrate --global
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
The skills are `empirical`, `empirical-explore`, `empirical-fast`,
|
|
260
|
+
`empirical-complex`, and `empirical-loop`. Native invocation depends on the
|
|
261
|
+
agent: `$empirical` in Codex, `/empirical` in Claude Code, and the corresponding
|
|
262
|
+
skill/command discovery UX in Cursor, Gemini CLI, and Windsurf.
|
|
263
|
+
|
|
264
|
+
Generated guidance explicitly tells the current agent to conduct the Socratic
|
|
265
|
+
passes, show a worktree proposal, wait for approval, execute creation, maintain
|
|
266
|
+
Complex decisions, and consume exact revisions. It never starts another agent.
|
|
267
|
+
|
|
268
|
+
## CLI reference
|
|
269
|
+
|
|
270
|
+
```text
|
|
271
|
+
empirical init [--defaults|--interactive]
|
|
272
|
+
empirical config [--defaults|--interactive]
|
|
273
|
+
empirical adopt
|
|
274
|
+
empirical explore "<problem>" [--interactive] [--agent codex|none]
|
|
275
|
+
empirical fast "<request>"
|
|
276
|
+
empirical complex "<request>"
|
|
277
|
+
empirical worktree create "<request>" [--workflow fast|complex]
|
|
278
|
+
empirical loop
|
|
279
|
+
empirical explain
|
|
280
|
+
empirical status
|
|
281
|
+
empirical complete --revision N --outcome <outcome> --summary "..."
|
|
282
|
+
empirical verify
|
|
283
|
+
empirical retry --revision N
|
|
284
|
+
empirical archive --revision N
|
|
285
|
+
empirical capabilities [name]
|
|
286
|
+
empirical policy
|
|
287
|
+
empirical integrate [--global]
|
|
288
|
+
empirical doctor
|
|
289
|
+
empirical migrate
|
|
290
|
+
empirical mcp
|
|
291
|
+
empirical update [--check]
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
Global options are `--root <path>` and `--json`. Legacy Quick can only be
|
|
295
|
+
resumed from migrated state; it is never selected for new work.
|
|
296
|
+
|
|
297
|
+
## MCP tools
|
|
298
|
+
|
|
299
|
+
The server runs over stdio with `empirical mcp` and exposes:
|
|
300
|
+
|
|
301
|
+
- discovery/setup: `empirical_explore`, `empirical_init`, `empirical_adopt`,
|
|
302
|
+
`empirical_configure`;
|
|
303
|
+
- workflow: `empirical_fast`, `empirical_complex`, `empirical_loop`,
|
|
304
|
+
`empirical_next`, `empirical_complete`, `empirical_retry`,
|
|
305
|
+
`empirical_verify`, `empirical_archive`;
|
|
306
|
+
- isolation: `empirical_worktree_propose`, `empirical_worktree_create`;
|
|
307
|
+
- understanding: `empirical_explain`, `empirical_status`, `empirical_doctor`;
|
|
308
|
+
- project context: `empirical_capabilities`, `empirical_policy`,
|
|
309
|
+
`empirical_integrate`, `empirical_migrate`.
|
|
310
|
+
|
|
311
|
+
Only `empirical_worktree_create` performs the approved Git mutation. Proposal
|
|
312
|
+
and Explain tools are annotated read-only.
|
|
313
|
+
|
|
314
|
+
## Committed layout
|
|
315
|
+
|
|
316
|
+
```text
|
|
317
|
+
.empirical/
|
|
318
|
+
├── config.json
|
|
319
|
+
├── policy.json
|
|
320
|
+
├── capabilities/<capability>/spec.md
|
|
321
|
+
├── discoveries/<discovery>/
|
|
322
|
+
│ ├── interview.json
|
|
323
|
+
│ └── brief.md
|
|
324
|
+
└── specs/<feature>/
|
|
325
|
+
├── spec.md
|
|
326
|
+
├── design.md # Complex
|
|
327
|
+
├── decisions.md # Complex when required
|
|
328
|
+
├── plan.md # Complex
|
|
329
|
+
├── deltas/*.md # Complex behavior changes
|
|
330
|
+
├── state.json
|
|
331
|
+
├── state.lock # ephemeral
|
|
332
|
+
├── events/*.json
|
|
333
|
+
└── evidence.json
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
Feature state and journals are branch-local. Capability specs, configuration,
|
|
337
|
+
and policy are project-wide committed contracts.
|
|
338
|
+
|
|
339
|
+
## Migration and the 0.20 reset
|
|
340
|
+
|
|
341
|
+
Schema-1, schema-2, and schema-3 default root state migrates idempotently into
|
|
342
|
+
the matching feature directory. Terminal root state does not reserve the
|
|
343
|
+
checkout. Historical named parallel-state data is deliberately unsupported and
|
|
344
|
+
is not merged; inspect it with the older package before upgrading if needed.
|
|
345
|
+
|
|
346
|
+
The public alpha version is reset to `0.20.0`. The old `2.0.0`, `2.2.0`,
|
|
347
|
+
`2.3.0`, and `2.3.1` package versions are intentionally removed after 0.20.0 is
|
|
348
|
+
published and verified. Removed npm version numbers cannot be reused.
|
|
349
|
+
|
|
350
|
+
See [migration details](docs/migration-v1.md), the [protocol](docs/protocol.md),
|
|
351
|
+
the [MCP guide](docs/mcp.md), and the [OpenSpec comparison](docs/openspec-comparison.md).
|
|
352
|
+
|
|
353
|
+
## Development
|
|
354
|
+
|
|
355
|
+
```bash
|
|
356
|
+
bun install
|
|
357
|
+
bun run check
|
|
358
|
+
bun test
|
|
359
|
+
bun run test:dist
|
|
360
|
+
npm pack --dry-run
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
Empirical targets Node.js 20+ at runtime. Bun is used only for development,
|
|
364
|
+
tests, and building the published JavaScript package.
|
|
365
|
+
|
|
366
|
+
License: MIT.
|
package/dist/cli.d.ts
ADDED