empirical-sdd 0.35.0 → 0.36.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/CHANGELOG.md CHANGED
@@ -8,6 +8,139 @@ under the alpha rules in [docs/versioning.md](docs/versioning.md).
8
8
 
9
9
  ## [Unreleased]
10
10
 
11
+ ## [0.36.0] - 2026-09-16
12
+
13
+ ### Added
14
+
15
+ - Added the empirical-init **Track every change** ticket preset. It expands the
16
+ complete feature/fix/chore by Fast/Quick/Complex matrix to `required`, shows
17
+ that matrix before setup is saved, and applies the existing strict tracker
18
+ mutation gate to every kind of work until its ticket is synchronized. Active
19
+ Empirical tasks now also require a destination action and tracker-gate check
20
+ before the first write after changing repository root, checkout, worktree, or
21
+ host environment.
22
+ - Automatic Policy v2 post-commit synchronization, prepared Linear MCP intents,
23
+ and recovery of this checkout's pending completed tickets.
24
+ - Explicit Init confirmations for all workflow/delivery mappings and the Done
25
+ milestone, plus receipt-backed release and deployment observations.
26
+ - Action packets, `empirical_status` and `empirical_explain` return a
27
+ deterministic `roadmap`: `progress` and `phases[]` from the engine's single
28
+ phase order per profile (Complex 8, Quick 5, Fast 2 non-terminal phases),
29
+ one `checks[]` entry per verification-matrix check with its state, receipt id
30
+ and last duration (a `passed` state binds the same proof the completion gate
31
+ requires, including the current repository tree digest), an `estimateMs` for unrun and failed checks from prior
32
+ attempt durations, classified `waitingOn[]` items, a concrete `nextAction`
33
+ and `verificationLeft`. Idle checkouts return `roadmap: null`. Roadmaps and
34
+ estimates are recomputed on every read and never change a gate or transition.
35
+ - Human CLI output for `status`, `explain`, `next` and `loop` renders the
36
+ Empirical status card (Done, Not done, Next, Waiting on you, Verification)
37
+ from that roadmap, and `--json` exposes the same `roadmap` field.
38
+ - Generated agent skills require the status card at start or resume, at every
39
+ phase change, at every stop, and before any run whose summed estimate is over
40
+ 60 seconds or unknown, where they state the estimate and offer to defer.
41
+ - `empirical_overview` adds a read-only roadmap summary (progress, phase, next
42
+ action, waiting count, remaining checks) for the first 128 readable spec
43
+ copies; unreadable, failing and beyond-limit copies keep their bounded
44
+ diagnostic and report `roadmap: null`.
45
+ - `empirical_qa_execute` and `empirical_integrate` send MCP
46
+ `notifications/progress` for each existing heartbeat when the request carries
47
+ a `progressToken`; requests without one are unchanged.
48
+ - Added direct mode: the generated local `empirical` skill and the automatic
49
+ instruction block now start with a self-contained Direct mode section. A
50
+ request that says "direct", "without Empirical" or "quick change" is handled
51
+ as a plain agent turn that makes no Empirical call, reads no specification,
52
+ decision, capability or context page, runs a test, lint, typecheck or build
53
+ only when asked, and ends with
54
+ `Changed <X> in <N> files · not tested (not requested) · say "track this" to formalize`.
55
+ - Added `empirical_direct` (library `direct`, private CLI `direct`) with exactly
56
+ three actions: `pause` ("go direct") records `pause: { since, baseCommit }` on
57
+ the selected feature with one `Pause: direct mode` journal event and no spec,
58
+ delta, decision, receipt or tracker gate; `resume` ("back to Empirical")
59
+ clears the pause and folds the paths changed since the base commit in as one
60
+ `iterate` for Fast work in Implement or implemented Done and for iterative
61
+ Complex work in an iterate-eligible phase, and otherwise as one journal event
62
+ that also names any iterate guard a paused feature could not have cleared;
63
+ `track` ("track this") rebuilds direct commits and uncommitted paths from Git
64
+ and starts a Fast (default) or Complex feature whose request lists them.
65
+ - While a feature is paused, `loop` and `next` return only a paused action naming
66
+ `resume`, `status` and `overview` report the pause, and `complete`, `iterate`,
67
+ `consolidate`, `promote`, `retry`, QA execution and recording, evidence
68
+ execution and collection, `integrate`, `deliver` and `publish` fail with
69
+ `FEATURE_PAUSED` without state change.
70
+ - Added an optional team `defaultMode` (`empirical` or `direct`) to
71
+ `.empirical/config.json` and a personal override in the checkout's
72
+ `<git-dir>/empirical-sdd/preferences.json` through `empirical_configure` with
73
+ `scope: "personal"`. Absence keeps existing configuration bytes identical, any
74
+ other value fails `INVALID_CONFIG`, and `status` reports team, personal and
75
+ effective values with a warning for an unreadable or invalid personal file.
76
+ - Complex Implement actions carry `contractSummary`, a deterministic extract of
77
+ the feature's goal, acceptance criteria, accepted decisions and open risks
78
+ bounded to 6,000 characters, with the full spec, design, decisions and plan
79
+ listed as optional `references`. Their `capabilityContext` lists only the
80
+ capabilities the feature's own deltas declare. Iteration actions add
81
+ `adjustmentRequest`, the newest request verbatim, which overrides conflicting
82
+ earlier criteria and decisions; the superseding decision is recorded after the
83
+ change and never blocks Implement completion.
84
+ - During an iteration of a Complex feature started with `iterative: true` (recorded
85
+ durably as `lifecycle.iterative`), contract edits to acceptance criteria, declared
86
+ requirement contents and decisions are an amendment by default:
87
+ `empirical_iterate` and the Implement completion accept them and re-approve the
88
+ amended specification and delta digests in one journal event, without returning
89
+ to Specify and without a human confirmation gate. `amendContract: true`
90
+ (`--amend-contract`) is the explicit equivalent, cannot be combined with
91
+ `reviseContract` (`INVALID_ARGUMENT`), and Fast rejects it with
92
+ `PROFILE_CONFLICT`. The approved contract is retained in
93
+ `contract-revisions/<revision>.baseline.json` and each change in
94
+ `<revision>.amendment.json` with previous and current criterion text and
95
+ superseded decision ids. Consolidation and Review actions, the Review packet and
96
+ `empirical_explain` list every amendment since the last full approval. Raising
97
+ the risk floor, adding or removing a delta capability, adding, removing or
98
+ renaming a requirement block, changing its operation, or changing `impact.json`
99
+ fails with `CONTRACT_REVISION_REQUIRED` and re-approves nothing, while a
100
+ `failed`, `blocked` or `awaiting_human` outcome can still be recorded. The risk
101
+ limit compares the resulting risk level over criteria and declared requirement
102
+ text, so rewording, reordering or lowering the floor is not an escalation.
103
+ Outside the iteration stage, and for Complex features without the iterative
104
+ opt-in, contract edits keep failing with `SPEC_CHANGED`, `DELTA_CHANGED` or
105
+ `IMPACT_CHANGED`, and `reviseContract` is unchanged. Retained history is
106
+ authenticated: a baseline is trusted only while it reproduces the approved
107
+ specification and delta digests, and a missing or malformed amendment record
108
+ fails with `CONTRACT_HISTORY_MISSING` or `CONTRACT_HISTORY_INVALID`.
109
+
110
+ ### Fixed
111
+
112
+ - Any verification command can declare `full-ci`, not only `bun run ci`, so
113
+ repositories built with pnpm, npm, Make, Python or other tools can satisfy the
114
+ promotion gate, use integration replay coverage and opt into `remote-checks`
115
+ (SDD-72). Changed-file commands still cannot declare it. For a non-`bun run ci`
116
+ full-CI command, changes to task-runner manifests in its `cwd` or to files named
117
+ in its argv replay every command during integration and require local proof
118
+ under `remote-checks`. Bun-only policies keep their configuration digest.
119
+ - `rationale.missingContext` now lists only unmet requirements: existing
120
+ artifacts, evidence kinds proven by accepted receipts at the current revision
121
+ and QA checks with passing current receipts are excluded, while
122
+ `requiredContext` is unchanged.
123
+ - CLI step counts came from a hardcoded 10-phase Complex list that included
124
+ Deliver and Publish; they now equal the engine's `roadmap.progress`.
125
+
126
+ ### Migration
127
+
128
+ - Schema 5 is unchanged. Update the installed package, refresh the managed
129
+ Empirical skills and repository instructions, and restart connected agent/MCP
130
+ sessions to load the new direct-mode and status-card guidance.
131
+ - Existing configurations retain their defaults. To adopt direct mode, request
132
+ it explicitly or configure the optional team/personal `defaultMode`. To adopt
133
+ automatic ticket completion on release or deployment, configure and confirm
134
+ the tracker lifecycle status mappings and production environment in Init.
135
+ - Complex iterative features created before 0.36.0 do not have the durable
136
+ `lifecycle.iterative` opt-in and continue using strict contract revision.
137
+ Finish them with the existing revision path, or start new iterative work
138
+ through the normal workflow to use in-place amendments. Do not edit journal
139
+ state or baseline files to add the marker manually.
140
+ - Non-Bun repositories may explicitly mark their full-CI command with `full-ci`;
141
+ changed-file commands remain ineligible. Existing Bun-only policies need no
142
+ change.
143
+
11
144
  ## [0.35.0] - 2026-09-15
12
145
 
13
146
  ### Added
@@ -675,7 +808,8 @@ Published through GitHub Actions trusted publishing with npm provenance.
675
808
 
676
809
  - Prepared and released package version `0.20.2`.
677
810
 
678
- [Unreleased]: https://github.com/goempirical/empirical-sdd/compare/v0.35.0...HEAD
811
+ [Unreleased]: https://github.com/goempirical/empirical-sdd/compare/v0.36.0...HEAD
812
+ [0.36.0]: https://github.com/goempirical/empirical-sdd/compare/v0.35.0...v0.36.0
679
813
  [0.35.0]: https://github.com/goempirical/empirical-sdd/compare/v0.34.0...v0.35.0
680
814
  [0.34.0]: https://github.com/goempirical/empirical-sdd/compare/v0.33.0...v0.34.0
681
815
  [0.33.0]: https://github.com/goempirical/empirical-sdd/compare/v0.32.0...v0.33.0
package/README.md CHANGED
@@ -112,6 +112,11 @@ Choose Fast for small, self-contained changes. Work that builds on an existing
112
112
  foundation and will be integrated belongs in Complex iterative
113
113
  (`empirical_complex` with `iterative: true`): adjust with `empirical_iterate`
114
114
  without test runs, then say "ready to close" to run final verification once.
115
+ Each Complex implementation packet carries a bounded contract summary instead of
116
+ the full documents, and the newest adjustment wins: a behavior change at the same
117
+ risk floor amends the criteria and decisions in place, with the approved contract
118
+ snapshotted for review. Raising the risk floor or changing the declared capability
119
+ scope still requires an explicit contract revision through Specify/Design/Plan.
115
120
 
116
121
  Fast trades verification confidence for less waiting and process. A follow-up
117
122
  adjustment to the same Fast feature uses `empirical_iterate`, from Implement or
@@ -125,6 +130,42 @@ evidence and completion level they originally earned.
125
130
  Delivery is never implied. Empirical does not infer permission to merge a pull
126
131
  request, bypass protection, create a release, or publish a package.
127
132
 
133
+ Every read returns one deterministic roadmap, and every stop shows the same
134
+ status card built from it, so you always see where the work is and what it
135
+ needs from you:
136
+
137
+ ```text
138
+ Empirical · add-team-invitations · Complex · verify (6/8) · rev 5
139
+ Done: specify, design, plan, implement, context
140
+ Not done: verify: qa-unit unrun, qa-browser missing-environment
141
+ Next: Run qa-unit at revision 5 (~2m 10s) when you request tests
142
+ Waiting on you: [test-request] Ask to run 1 check (~2m 10s), or keep iterating
143
+ [environment] qa-browser needs isolated-consumer
144
+ Verification: 2 of 4 checks left (~2m 10s known; 1 unknown)
145
+ ```
146
+
147
+ `empirical status`, `explain`, `next` and `loop` print it, `--json` carries the
148
+ same `roadmap`, and the agent skill shows it at every start, phase change and
149
+ stop, and before a long run it estimates and offers to defer. The card reports
150
+ facts; it authorizes nothing.
151
+ ## Work directly when you want to
152
+
153
+ Say "direct", "without Empirical" or "quick change" and the agent just edits:
154
+ no specification, state, phase, receipt, gate, tracker update or worktree
155
+ proposal, and no reading of specs, decisions or context pages. Nothing runs
156
+ unless you ask for it, and the turn ends with one line such as
157
+ `Changed the button label in 1 files · not tested (not requested) · say "track this" to formalize`.
158
+
159
+ Inside a repository or feature that uses Empirical, "go direct" pauses the
160
+ selected feature, "back to Empirical" folds the direct diff back in as one
161
+ iteration, and "track this" rebuilds recent direct commits and uncommitted files
162
+ from Git into a Fast (or Complex) feature. Push, merge, pull request, tag,
163
+ publish, credential use and destructive Git still need an explicit request.
164
+
165
+ A team can set `defaultMode` to `direct` in `.empirical/config.json`, and each
166
+ developer can override it for their own checkout; explicit Fast, Complex or
167
+ "use Empirical" requests always start those lanes.
168
+
128
169
  ## Run tests when you need them
129
170
 
130
171
  Fast and Complex iteration do not automatically run tests after edits. Ask for a
@@ -198,6 +239,14 @@ executes them through the authenticated Linear MCP tools, and validated results
198
239
  converge the same binding, milestone, and strict-gate records without sharing
199
240
  the OAuth token.
200
241
 
242
+ ### Automatic lifecycle tracking
243
+
244
+ Policy v2 workflow actions now synchronize automatically. Linear MCP hosts
245
+ receive a prepared tracker intent, and trusted host dispatchers can execute it
246
+ automatically. Init confirms every discovered mapping and whether Done means
247
+ local completion, a confirmed release, or production deployment. See
248
+ [Lifecycle tracking](docs/tracking.md) for setup, recovery, and the observation hook.
249
+
201
250
  ## Documentation
202
251
 
203
252
  - [Practical guide](https://goempirical.github.io/empirical-sdd/) — visual onboarding and diagrams
@@ -3,6 +3,8 @@ export declare function withCheckoutLock<T>(root: string, operation: () => Promi
3
3
  /** A shared feature lock prevents a writer from racing ownership transfer. */
4
4
  export declare function withFeatureLock<T>(root: string, feature: string, operation: () => Promise<T>, options?: {
5
5
  allowPendingTransfer?: boolean;
6
+ /** Completed tracking may use its recorded owner or a validated delivery event. */
7
+ completedTransfer?: "tracker-owner" | "lifecycle-record";
6
8
  }): Promise<T>;
7
9
  export interface CheckoutSelection {
8
10
  feature: string | null;
@@ -14,6 +16,11 @@ export declare function readCheckoutSelection(rootInput: string): Promise<Checko
14
16
  export declare function writeCheckoutSelection(rootInput: string, feature: string | null, expectedFeature?: string): Promise<void>;
15
17
  /** Transfer releases an unfinished owner without creating terminal obligations. */
16
18
  export declare function moveCheckoutSelection(sourceRoot: string, targetRoot: string, feature: string): Promise<void>;
19
+ /** Call under the shared feature lock before automatic external side effects. */
20
+ export declare function assertCheckoutFeatureOwner(root: string, feature: string): Promise<void>;
21
+ /** A receipt-backed delivery event may adopt completed work in another checkout.
22
+ * Call as the guarded journal effect, and roll back if that commit fails. */
23
+ export declare function adoptCompletedTrackerFeature(root: string, feature: string): Promise<() => Promise<void>>;
17
24
  /** Read only this checkout's recovery anchor, never sibling selections. */
18
25
  export declare function readCheckoutLastFeature(rootInput: string): Promise<{
19
26
  git: boolean;
@@ -27,3 +34,5 @@ export declare function readCheckoutRecoveryFeatures(rootInput: string): Promise
27
34
  * commit, so a process exit before selector cleanup cannot orphan the effect. */
28
35
  export declare function recordCheckoutRecoveryFeature(rootInput: string, feature: string): Promise<void>;
29
36
  export declare function forgetCheckoutRecoveryFeatures(rootInput: string, resolvedFeatures: string[]): Promise<void>;
37
+ /** A checkout-local runtime file under `<git-dir>/empirical-sdd/`, guarded like the selector; null outside Git. */
38
+ export declare function checkoutRuntimePath(rootInput: string, name: string): Promise<string | null>;