empirical-sdd 0.20.0 → 0.20.1

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/README.md CHANGED
@@ -1,82 +1,124 @@
1
1
  # Empirical SDD
2
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.
3
+ Empirical is an agent-neutral spec-driven development engine for Codex, Claude
4
+ Code, Cursor, Gemini CLI, Windsurf, and MCP clients. It turns a coding request
5
+ into an exact, resumable workflow with observable contracts, evidence, review,
6
+ living capability specifications, and safe Git worktree isolation.
7
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.
8
+ Empirical `0.20.1` is an alpha release. It uses one active feature per checkout
9
+ and real Git worktrees for parallel work.
10
10
 
11
11
  ## Install
12
12
 
13
13
  ```bash
14
14
  npm install -g empirical-sdd
15
- cd your-repository
16
- empirical init
15
+ empirical install
17
16
  ```
18
17
 
19
- The first interactive init asks once for:
18
+ `empirical install` opens a multi-select list of every supported coding agent.
19
+ Detected agents and existing Empirical installations are labeled and selected
20
+ by default. Use the arrow keys to move, Space to select, `a` to toggle all, and
21
+ Enter to install.
20
22
 
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.
23
+ The selection is exact: Empirical installs one global entrypoint in every
24
+ selected agent and removes only Empirical-managed entrypoints from agents you
25
+ deselect. Unmanaged files are never overwritten or deleted. The installer works
26
+ from any directory and neither creates repository state nor launches an agent.
26
27
 
27
- Press Enter to accept each safe default. Edit the answers later with:
28
+ For scripts and unattended setup, choose agents explicitly:
28
29
 
29
30
  ```bash
30
- empirical config
31
+ # Exact selection; repeat -a/--agent
32
+ empirical install --agent codex --agent cursor
33
+
34
+ # Every supported agent
35
+ empirical install --all
36
+
37
+ # Detected agents plus existing managed installations
38
+ empirical install --yes
31
39
  ```
32
40
 
33
- Automation never waits for terminal input:
41
+ Then open your repository in a coding agent and use its one Empirical entrypoint:
42
+
43
+ | Agent | Invocation |
44
+ | --- | --- |
45
+ | Codex | `$empirical` |
46
+ | Claude Code | `/empirical` |
47
+ | Cursor Agent chat | `empirical` |
48
+ | Gemini CLI | `empirical` |
49
+ | Windsurf Cascade | `@empirical` |
50
+
51
+ To upgrade both the package and installed entrypoints:
34
52
 
35
53
  ```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
54
+ empirical update
41
55
  ```
42
56
 
43
- ## The normal UX
57
+ `empirical install` and `empirical update` are the entire public terminal CLI.
58
+ Repository setup and feature work happen inside the current coding agent; old
59
+ terminal verbs such as `init`, `config`, `explore`, `fast`, `complex`, and
60
+ `loop` are rejected.
61
+
62
+ ## One entrypoint owns the workflow
44
63
 
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.
64
+ Ask the installed Empirical entrypoint for repository work in ordinary language.
65
+ It deterministically:
66
+
67
+ 1. initializes an uninitialized repository in the current runtime;
68
+ 2. builds or refreshes compact repository knowledge;
69
+ 3. resumes non-terminal work already owned by this checkout;
70
+ 4. uses the original five-pass Socratic interview only when the request is
71
+ genuinely vague;
72
+ 5. routes an approved, concrete request internally to Fast or Complex;
73
+ 6. executes exact revisions through evidence, review, and living-spec archive;
74
+ 7. offers an explicit agent handoff only after a Complex specification exists.
48
75
 
49
76
  ```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
77
+ one Empirical invocation
78
+
79
+ ├─ repository uninitialized ──> first-run setup + compact context
80
+ ├─ active feature found ──────> resume exact revision
81
+ └─ new request
82
+ ├─ genuinely vague ────> five Socratic passes ──> approval
83
+ └─ concrete ───────────> internal Fast / Complex routing
84
+
85
+ approved Complex spec exists?
86
+
87
+ Continue here | Save | Continue in agent
65
88
  ```
66
89
 
67
- Fast is only for explicit, tiny, localized, reversible, low-risk non-UI work.
90
+ Fast is only for explicit, tiny, localized, reversible, low-risk, non-UI work.
68
91
  Everything else—including UI, architecture, public APIs, security, migrations,
69
92
  and cross-cutting changes—uses Complex.
70
93
 
71
- ## Socratic discovery is back
94
+ ## First use and repository knowledge
72
95
 
73
- For a genuinely vague idea:
96
+ On first use, the agent initializes `.empirical/`. It applies safe defaults or
97
+ asks only questions that materially change Git isolation or Complex decision
98
+ policy. It does not install project-local workflow skills.
74
99
 
75
- ```bash
76
- empirical explore "Build a cooperative browser puzzle with time loops"
100
+ Initialization also creates a compact, committed context set:
101
+
102
+ ```text
103
+ .empirical/context/
104
+ ├── manifest.json
105
+ ├── index.md
106
+ ├── overview.md
107
+ ├── architecture.md
108
+ ├── commands.md
109
+ └── conventions.md
77
110
  ```
78
111
 
79
- Empirical asks one question at a time across five passes:
112
+ The deterministic manifest contains bounded path, size, and content-digest
113
+ metadata—not source contents. Dependency trees, build output, ignored files,
114
+ secret-like paths, credentials, binary files, and large files are excluded.
115
+ Topic pages are maintained from repository evidence and are not overwritten by
116
+ a routine refresh. There are no embeddings, hosted services, or vector database.
117
+
118
+ ## Socratic discovery
119
+
120
+ For a vague idea such as “make onboarding better,” Empirical asks one question
121
+ at a time across five passes:
80
122
 
81
123
  1. primary user and observed problem;
82
124
  2. smallest observable outcome;
@@ -84,232 +126,102 @@ Empirical asks one question at a time across five passes:
84
126
  4. failures and solution-changing risks;
85
127
  5. concrete verification.
86
128
 
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:
129
+ It adds only material follow-ups, saves the answers, presents the complete
130
+ refined contract, and waits for explicit approval before creating workflow
131
+ state. A concrete request does not pay this discovery cost.
91
132
 
92
- ```bash
93
- empirical explore "<idea>" --no-interview
94
- empirical explore "<idea>" --json
95
- ```
133
+ ## Small feature demo
96
134
 
97
- `--agent codex` is an optional human terminal entrypoint after approval. Agent
98
- skills continue in their current runtime and never launch another AI.
135
+ In your coding agent:
99
136
 
100
- ## Simple feature demo
101
-
102
- Request:
103
-
104
- ```bash
105
- empirical fast "Add a health command that prints ok"
106
- ```
137
+ > `$empirical` Add a health command that prints `ok`.
107
138
 
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:
139
+ Empirical recognizes an explicit, localized, low-risk non-UI change and routes
140
+ it internally to Fast. The agent inspects only relevant files, implements the
141
+ generated observable criterion, runs one focused test, reviews the diff, and
142
+ completes the exact revision. The durable result is:
125
143
 
126
144
  ```text
127
145
  .empirical/specs/add-a-health-command-that-prints-ok/
128
146
  ├── spec.md
129
147
  ├── state.json
130
148
  ├── 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
149
+ └── evidence.json
159
150
  ```
160
151
 
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.
152
+ You do not choose or invoke a separate Fast command.
170
153
 
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.
154
+ ## Complex feature demo
177
155
 
178
- ### Trade-offs and risks
179
- The service gains time semantics; inject a clock for deterministic tests.
156
+ In your coding agent:
180
157
 
181
- ### Verification
182
- Test API and background expiry against the same injected clock.
183
- ```
158
+ > `$empirical` Add team invitations with expiration, revocation, and audit
159
+ > history. Existing members must keep access during rollout.
184
160
 
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.
161
+ Empirical routes the request to Complex and drives seven gates:
187
162
 
188
- ## Understand the next action
163
+ 1. Specify observable criteria, scope, risks, verification, and capability
164
+ deltas.
165
+ 2. Design the architecture and record accepted evidence-backed decisions.
166
+ 3. Plan an executable implementation sequence.
167
+ 4. Implement the approved contract.
168
+ 5. Verify every criterion; UI work requires real-browser evidence.
169
+ 6. Review the diff against criteria and accepted decisions.
170
+ 7. Archive reviewed deltas into living capability specifications.
189
171
 
190
- ```bash
191
- empirical explain
192
- empirical explain --json
193
- ```
172
+ After Specify passes, the agent offers:
194
173
 
195
- Explain is read-only and reports:
174
+ - Continue here.
175
+ - Save for later.
176
+ - Continue in a detected agent.
196
177
 
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.
178
+ For an external handoff, Empirical displays the target, whether it accepts a
179
+ prompt or only a workspace, the exact working directory, and exact argument
180
+ array. Detection and Save launch nothing. The command is revalidated and
181
+ authorized only after you explicitly approve that exact option.
202
182
 
203
- MCP clients use `empirical_explain` and receive the same structured fields.
183
+ Decision records store reviewable evidence, options, the selected approach,
184
+ trade-offs, risks, and verification—not private chain-of-thought, prompts,
185
+ scratchpads, tokens, or credentials.
204
186
 
205
187
  ## Parallel work uses Git worktrees
206
188
 
207
- If a different feature is active, Fast or Complex returns a proposal instead of
208
- overwriting state:
189
+ If a different feature is active, the single entrypoint returns a read-only
190
+ worktree proposal instead of overwriting state. It shows the base and immutable
191
+ base commit, branch, sibling path, exact Git argument array, and approval token.
209
192
 
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
- ```
193
+ After explicit approval Empirical requires a clean source checkout, revalidates
194
+ every field, rejects collisions, creates the linked checkout without force, and
195
+ starts the exact request there. It never stashes, commits, moves local changes,
196
+ deletes worktrees, or deletes branches.
222
197
 
223
- After approval Empirical:
198
+ Active selection lives in checkout-local Git metadata while portable feature
199
+ contracts remain committed under `.empirical/specs/`. A linked checkout therefore
200
+ does not accidentally inherit a blocked feature owned by another checkout.
224
201
 
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.
202
+ ## Internal automation API
233
203
 
234
- Human terminal form:
204
+ The TypeScript API and MCP tools remain available for agent runtimes and
205
+ programmatic integrations. They include setup, context refresh, discovery,
206
+ Fast/Complex routing, resume, exact completion, verification, review, archive,
207
+ status/explain, handoff, capability projection, and worktree proposal/creation.
208
+ They are automation primitives, not additional user-facing terminal commands.
235
209
 
236
- ```bash
237
- empirical worktree create "Fix password reset expiry" \
238
- --workflow complex --type fix
239
- ```
210
+ The stdio MCP server exposes these groups:
240
211
 
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.
212
+ - setup/context: `empirical_init`, `empirical_adopt`, `empirical_configure`,
213
+ `empirical_context`;
214
+ - routing/workflow: `empirical_explore`, `empirical_fast`,
215
+ `empirical_complex`, `empirical_loop`, `empirical_next`,
216
+ `empirical_complete`, `empirical_retry`, `empirical_verify`,
217
+ `empirical_archive`;
218
+ - handoff/isolation: `empirical_handoff`, `empirical_worktree_propose`,
219
+ `empirical_worktree_create`;
220
+ - understanding: `empirical_explain`, `empirical_status`,
221
+ `empirical_capabilities`, `empirical_policy`, `empirical_doctor`.
244
222
 
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.
223
+ Only explicitly approved worktree creation mutates Git. Agent handoff returns an
224
+ approval-bound command but never launches it itself.
313
225
 
314
226
  ## Committed layout
315
227
 
@@ -317,6 +229,7 @@ and Explain tools are annotated read-only.
317
229
  .empirical/
318
230
  ├── config.json
319
231
  ├── policy.json
232
+ ├── context/
320
233
  ├── capabilities/<capability>/spec.md
321
234
  ├── discoveries/<discovery>/
322
235
  │ ├── interview.json
@@ -333,34 +246,34 @@ and Explain tools are annotated read-only.
333
246
  └── evidence.json
334
247
  ```
335
248
 
336
- Feature state and journals are branch-local. Capability specs, configuration,
337
- and policy are project-wide committed contracts.
249
+ Feature contracts, journals, context, capability specs, configuration, and
250
+ policy are committed. The checkout's selected feature is stored in its own Git
251
+ metadata and is not shared across linked worktrees.
338
252
 
339
- ## Migration and the 0.20 reset
253
+ ## Migration and the 0.20 alpha
340
254
 
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.
255
+ Running the installer again is the migration: it removes only marker-owned old
256
+ global and project-local Empirical workflow artifacts, preserves unmanaged
257
+ content and existing runtime configuration, and converges without unnecessary
258
+ second-run changes. Existing schema-4 projects and discovery records remain
259
+ readable.
345
260
 
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.
261
+ Schema-1, schema-2, and schema-3 default root state migrates idempotently into
262
+ the matching feature directory. Historical alternate parallel-state data is
263
+ left untouched and unsupported.
349
264
 
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).
265
+ See [migration details](docs/migration-v1.md), the [architecture](docs/architecture.md),
266
+ the [MCP guide](docs/mcp.md), the [security model](docs/security.md), and the
267
+ [OpenSpec comparison](docs/openspec-comparison.md).
352
268
 
353
269
  ## Development
354
270
 
355
271
  ```bash
356
272
  bun install
357
- bun run check
358
- bun test
359
- bun run test:dist
360
- npm pack --dry-run
273
+ bun run ci
361
274
  ```
362
275
 
363
- Empirical targets Node.js 20+ at runtime. Bun is used only for development,
364
- tests, and building the published JavaScript package.
276
+ Empirical targets Node.js 20+ at runtime. Bun is used for development, tests,
277
+ and building the published JavaScript package.
365
278
 
366
279
  License: MIT.
@@ -0,0 +1,27 @@
1
+ import type { AgentHandoffOption, AgentIntegrationId, AgentLaunchCapability, DetectedAgent } from "./types.js";
2
+ export interface SupportedAgentDefinition {
3
+ id: AgentIntegrationId;
4
+ agent: string;
5
+ executables: string[];
6
+ skillSegments: string[];
7
+ invocation: string;
8
+ reload: string;
9
+ capability: AgentLaunchCapability;
10
+ }
11
+ export declare const SUPPORTED_AGENTS: SupportedAgentDefinition[];
12
+ export interface AgentDetectionOptions {
13
+ homeRoot?: string;
14
+ pathValue?: string;
15
+ includeAll?: boolean;
16
+ includeConfigured?: boolean;
17
+ }
18
+ export declare function detectSupportedAgents(options?: AgentDetectionOptions): Promise<DetectedAgent[]>;
19
+ export declare function agentDefinition(id: AgentIntegrationId): SupportedAgentDefinition;
20
+ export declare function buildHandoffOption(input: {
21
+ root: string;
22
+ feature: string;
23
+ specification: string;
24
+ specDigest: string;
25
+ agent: DetectedAgent;
26
+ }): AgentHandoffOption;
27
+ export declare function handoffToken(value: unknown): string;
@@ -0,0 +1,8 @@
1
+ export interface CheckoutSelection {
2
+ feature: string | null;
3
+ linked: boolean;
4
+ selectionPath: string | null;
5
+ claimedElsewhere: Set<string>;
6
+ }
7
+ export declare function readCheckoutSelection(rootInput: string): Promise<CheckoutSelection>;
8
+ export declare function writeCheckoutSelection(rootInput: string, feature: string | null): Promise<void>;