mindforge-cc 11.9.4 → 11.9.5

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.
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "11.9.4",
2
+ "version": "11.9.5",
3
3
  "environment": "development",
4
4
  "governance": {
5
5
  "drift_threshold": 0.75,
package/CHANGELOG.md CHANGED
@@ -1,6 +1,109 @@
1
1
  # Changelog
2
2
 
3
- ## [11.9.4] — 2026-08-22 — Delivery: the gates register, the tarball matches its tag, three packages attested
3
+ ## [11.9.5] — 2026-08-22 — The release path can no longer strand itself, and the SDK ships
4
+
5
+ Patch release, and the shortest one in a while. It exists because 11.9.4 published two
6
+ packages and then failed on the third, and that failure took the release page and the
7
+ `stable` dist-tag with it. Both causes are fixed here, and one of them is the reason this
8
+ release is worth cutting rather than waiting: **`mindforge-sdk` publishes for the first
9
+ time in seven versions, with provenance.**
10
+
11
+ ### Fixed
12
+
13
+ **A publish that cannot finish the release it started**
14
+
15
+ - **`sdk/package.json` had no `repository` field.** npm's provenance verification compares
16
+ that field against the attestation **server-side, at PUT** — so the publish was rejected
17
+ with `422 Unprocessable Entity … "repository.url" is ""` *after* `mindforge-cc` and
18
+ `mindforge-mcp-server` had already published irreversibly. `npm publish --dry-run` does
19
+ not perform that comparison, and nothing in this repository read `repository` at all: all
20
+ six preflight gates passed on a manifest the registry was guaranteed to reject. The field
21
+ is added, matching the spelling the other two packages use.
22
+
23
+ - **`scripts/ci/verify-provenance-metadata.js` makes that failure reachable before the
24
+ point of no return.** It runs in the release **preflight** job, ahead of every publish,
25
+ and it does not carry a list of packages: it discovers them from the workflow — every
26
+ step whose `run` contains both `npm publish` and `--provenance`, resolved through its
27
+ `working-directory` — so a fourth package is covered without editing the gate.
28
+ Discovering zero targets is a hard failure rather than a pass, on the principle that a
29
+ check which examined nothing must not report success.
30
+
31
+ Verified the only way that means anything: run against a git worktree at tag `v11.9.4` —
32
+ the exact tree that the registry rejected — it exits 1 and names `sdk/package.json` and
33
+ the missing field. It would have stopped that release before anything reached npm.
34
+
35
+ - **The release steps were ordered so that an optional package could strand the release.**
36
+ The SDK publish sat *before* `Create GitHub Release` and the `stable` dist-tag move.
37
+ A failing step fails the job, so both were skipped — which is precisely the harm the
38
+ placement comment claimed to prevent. The same mode had already fired on **v11.5.1** and
39
+ **v11.8.3** from the MCP publish; v11.9.4 was its third occurrence.
40
+
41
+ Reordered to: `Publish to npm` → `Create GitHub Release` → `stable` dist-tag →
42
+ `mcp-server` → `sdk`. The rule now encoded in `tests/action-pinning.test.js`: **no step
43
+ whose failure leaves no residue may be able to skip a step that finishes an irreversible
44
+ one.** That test previously asserted the opposite and had to be inverted in the same
45
+ commit — because `Run Full Test Suite` is the release job's first step, a reorder shipped
46
+ alone would have failed the release at its own gate.
47
+
48
+ The two finishers carry guards on their own inputs rather than a bare `!cancelled()`,
49
+ which would publish a release with a 0-byte body and an unmatched `.tgz` glob when
50
+ `Build Package` fails — the `bodyBytes=0` defect already seen on v11.9.0, .1 and .2. And
51
+ deliberately not `continue-on-error`: a tolerated failure makes the run conclude
52
+ **green**, which is the blindness that let the SDK sit seven versions behind, unattested,
53
+ with nothing noticing.
54
+
55
+ **Prose surfaces that shipped stale twice running**
56
+
57
+ - `bin/utils/readiness-gate.js` scored `RELEASENOTES.md` on `fileExists` while its
58
+ changelog sibling three lines away checked that the version appeared *in* the file. That
59
+ asymmetry is why the immutable 11.9.3 tarball's README said "Latest release v11.9.2" and
60
+ the immutable 11.9.4 tarball shipped with no 11.9.4 entry at all — while `README.md`
61
+ offers that file as the human-readable route to the BREAKING notes. Both are now checked,
62
+ anchored rather than by substring (`includes('11.9.4')` is also satisfied by
63
+ `## v11.9.40`).
64
+
65
+ **Policy change, stated plainly:** every release from here needs a `RELEASENOTES.md`
66
+ entry. Six published 11.x versions do not have one, so that file has been curated rather
67
+ than exhaustive; the gate only ever looks for the version being released, so those gaps
68
+ are unaffected.
69
+
70
+ - README's `## Latest release` is deliberately gated by a **test** rather than written by
71
+ `sync-version.js`. Auto-bumping the version token onto the previous release's paragraph
72
+ produces the right number attached to the wrong description — a better-disguised
73
+ falsehood than a visibly stale one.
74
+
75
+ - `docs/sdk-reference.md` offered `npx mindforge-cc@stable` as a way to get the SDK
76
+ "as part of the framework". Measured false: the published package declares exactly
77
+ `express` and `sql.js` and ships no `sdk/` directory. Removed.
78
+
79
+ ### Added
80
+
81
+ - **`mindforge-sdk` is published, with provenance** — its first release since 11.8.0 and
82
+ its first ever attested one. This is not cosmetic. Everything fixed in the SDK across
83
+ 11.8.1–11.9.4 reached nobody, including the one that matters most:
84
+ `WebSocketEventStream` scheduled a reconnect with `setTimeout(() => this.connect(), …)`
85
+ and nothing handled the returned promise, so a failed reconnect was an unhandled
86
+ rejection — fatal under Node's default mode, **terminating the caller's process**. Every
87
+ consumer on 11.8.0 still has that. (#191)
88
+
89
+ - `npm run provenance:check` — the gate above, runnable offline.
90
+
91
+ ### Notes for operators
92
+
93
+ - 11.9.4 is complete but was finished by hand: its GitHub Release was created at the
94
+ existing tag from the registry's own tarball (verified against `dist.integrity` and both
95
+ attestation bundles' subject digests), and the `v11.9.4` tag was deliberately **not**
96
+ moved, because two published packages' provenance attests to the commit it names.
97
+ - The `stable` dist-tag lagged at 11.9.3 between the two releases. Because the dist-tag
98
+ step now runs *ahead* of both additive publishes, this release moves it forward even if a
99
+ package publish fails again.
100
+ - Still outstanding, and requiring repository settings rather than code: there is no `v*`
101
+ **tag ruleset** restricting who may create the ref that triggers publishing, and
102
+ `NPM_TOKEN` remains a long-lived repository secret with no GitHub environment in front of
103
+ it. Create the environment *first* — adding `environment:` while none exists publishes
104
+ exactly as before while looking like a gate.
105
+
106
+ ## [11.9.4] — 2026-08-22 — Delivery: the gates register, the tarball matches its tag
4
107
 
5
108
  Patch release. 11.9.3 argued that an instrument must not report success while doing
6
109
  nothing. 11.9.4 is what an adversarial audit of the **published** 11.9.3 artifact found
@@ -71,13 +174,36 @@ not from reading the repository. That distinction is the whole content of this r
71
174
  exactly this reason, and the manifest's entire content is the sync record *for that
72
175
  already-excluded file*. (#225)
73
176
 
74
- - **`mindforge-sdk` is published again, with provenance.** It sat at **11.8.0** on npm
75
- while `sync-version.js` kept `sdk/package.json` at canonical seven releases of
76
- disagreement (11.8.1 through 11.9.3, none published) that nothing detected, because
77
- `version:check` verifies the tracked file and not what the registry serves. It was also
78
- the only one of the three packages with **no attestation**. The release workflow now
79
- publishes it with `--provenance`, after the two proven publishes and before the GitHub
80
- Release, so the newest step cannot cost the others their artifacts.
177
+ - **`mindforge-sdk` was NOT published in this release. It remains at 11.8.0.** This entry
178
+ originally claimed it shipped with provenance; that claim was false and is corrected here
179
+ rather than quietly deleted, because a release arguing for measured claims does not get to
180
+ misstate a supply-chain property.
181
+
182
+ What happened: the SDK sat at **11.8.0** on npm while `sync-version.js` kept
183
+ `sdk/package.json` at canonical seven releases of disagreement (11.8.1 through 11.9.3,
184
+ none published) that nothing detected, because `version:check` verifies the tracked file
185
+ and not what the registry serves. It was also the only one of the three packages with **no
186
+ attestation**. A publish step was added for it, and the registry rejected it:
187
+
188
+ ```
189
+ npm error 422 Unprocessable Entity - PUT https://registry.npmjs.org/mindforge-sdk
190
+ Error verifying sigstore provenance bundle: Failed to validate repository information:
191
+ package.json: "repository.url" is "", expected to match
192
+ "https://github.com/sairam0424/MindForge" from provenance
193
+ ```
194
+
195
+ `sdk/package.json` carried no `repository` field. The other two packages both do, which is
196
+ exactly why they published and it did not. That field is validated **registry-side at PUT**,
197
+ after two irreversible publishes have already succeeded — `npm publish --dry-run` does not
198
+ check it and neither did any gate here. Both are fixed for 11.9.5: the field, and an offline
199
+ preflight gate that refuses to reach a publish without it.
200
+
201
+ The step was also badly placed. It ran **before** `Create GitHub Release` and the `stable`
202
+ dist-tag move, so its failure skipped both — which is the precise harm the placement comment
203
+ claimed to prevent. `mindforge-cc@11.9.4` and `mindforge-mcp-server@11.9.4` published
204
+ correctly with provenance attesting commit 353e8d41; the release page and the `stable` tag
205
+ were completed by hand afterwards. The finishing steps now run ahead of the additive
206
+ publishes, so no optional package can strand a release again.
81
207
 
82
208
  - **The Homebrew formula carries the real 11.9.3 digest.** Verified against an independent
83
209
  measurement rather than the tool's own output, and explicitly confirmed not to be the
package/MINDFORGE.md CHANGED
@@ -1,9 +1,9 @@
1
- # MINDFORGE.md — Parameter Registry (v11.9.4)
1
+ # MINDFORGE.md — Parameter Registry (v11.9.5)
2
2
 
3
3
  ## 1. IDENTITY & VERSIONING
4
4
 
5
5
  [NAME] = MindForge
6
- [VERSION] = 11.9.4
6
+ [VERSION] = 11.9.5
7
7
  [STABLE] = true
8
8
  [MODE] = "Platform Sovereign"
9
9
  [REQUIRED_CORE_VERSION] = 11.9.1
package/README.md CHANGED
@@ -6,14 +6,24 @@
6
6
 
7
7
  ## Latest release
8
8
 
9
- **v11.9.3** (2026-08-21) — Honesty: gates that can fail, commands that run, a release path that is
10
- checked. Twenty-one fixes sharing one defect an instrument reporting success while doing nothing:
11
- a self-install that printed "skipping" and overwrote 149 tracked files, 11 of 27 routed CLI verbs
12
- dying on `MODULE_NOT_FOUND` in a real install, `--fetch-sha` hashing npm's 404 body into the Homebrew
13
- formula, no version channel covering any document a user receives, and a publish path no check ever
14
- touched. **Contains behaviour changes under a patch bump** several fixed bugs whose correct
15
- behaviour differs from what shipped. See the BREAKING section in
16
- [CHANGELOG.md](./CHANGELOG.md), or [RELEASENOTES.md](./RELEASENOTES.md) for human-readable notes.
9
+ **v11.9.5** (2026-08-22) — The release path can no longer strand itself, and the SDK ships.
10
+ 11.9.4 published two packages and then failed on the third; because that step sat *before* the
11
+ release page and the `stable` dist-tag move, its failure skipped both. Fixed two ways: the steps
12
+ that finish a release now run ahead of any additive package publish, and a new offline preflight
13
+ gate refuses to reach a publish that the registry will reject. Verified against a worktree at tag
14
+ `v11.9.4` the exact tree npm rejectedthe gate exits 1 and names the file.
15
+
16
+ **`mindforge-sdk` publishes for the first time since 11.8.0, and for the first time with
17
+ provenance.** Everything fixed in it across 11.8.1–11.9.4 had reached nobody, including a
18
+ `WebSocketEventStream` reconnect whose unhandled rejection **terminates the caller's process**.
19
+
20
+ The previous release, **v11.9.4**, is where the hook gates started actually registering: 11.9.3
21
+ shipped the code and then declined to run it on essentially every project. Measured against the
22
+ published tarballs — 11.9.3: **11 hook scripts installed, 0 registered**; 11.9.4: **8 registered,
23
+ 3 deny-class verified blocking**. That **behaviour change under a patch bump** still applies — the
24
+ installer writes `.claude/settings.json` where it previously declined, merging append-only and
25
+ backing up first. See the BREAKING section in [CHANGELOG.md](./CHANGELOG.md), or
26
+ [RELEASENOTES.md](./RELEASENOTES.md) for human-readable notes.
17
27
 
18
28
  ---
19
29
 
@@ -22,8 +32,9 @@ behaviour differs from what shipped. See the BREAKING section in
22
32
  Read this before the install instructions. MindForge ships a large corpus of agent
23
33
  instructions — commands, skills, personas, protocols — and those are advisory: they work by
24
34
  being in the model's context, and a model can decline them. The parts that would *block* an
25
- action are hooks. Through 11.9.2 **no channel registered them**; as of 11.9.3 both channels
26
- register and execute them **on Claude Code**, and nowhere else.
35
+ action are hooks. Through 11.9.2 **no channel registered them.** 11.9.3 added the registration code
36
+ but it declined to run on almost every project, so in practice nothing was enforced there either.
37
+ **As of 11.9.4** both channels register and execute them **on Claude Code**, and nowhere else.
27
38
 
28
39
  | Capability | Plugin channel | `npx` channel |
29
40
  |---|---|---|
package/RELEASENOTES.md CHANGED
@@ -1,5 +1,129 @@
1
1
  # Release Notes
2
2
 
3
+ ## v11.9.5 — 2026-08-22 — The release path can no longer strand itself, and the SDK ships
4
+
5
+ ### Why this release exists
6
+
7
+ 11.9.4 published two packages and then failed on the third, and that failure took the release
8
+ page and the `stable` dist-tag with it:
9
+
10
+ ```
11
+ success Publish to npm <- mindforge-cc@11.9.4 (irreversible)
12
+ success Publish standalone MCP server to npm <- mindforge-mcp-server@11.9.4 (irreversible)
13
+ failure Publish the SDK to npm <- 422: "repository.url" is ""
14
+ skipped Create GitHub Release
15
+ skipped Point the stable dist-tag at this release
16
+ ```
17
+
18
+ Two causes, both fixed here.
19
+
20
+ **The metadata was only ever validated by the registry.** `sdk/package.json` had no
21
+ `repository` field, and npm compares that field against the attestation **server-side at PUT**.
22
+ `npm publish --dry-run` does not check it and nothing here read `repository` at all — so all six
23
+ preflight gates passed on a manifest guaranteed to be rejected. There is now an offline gate in
24
+ *preflight*, ahead of every publish, that discovers the provenance-publishing packages from the
25
+ workflow itself. Run against a worktree at tag `v11.9.4` — the tree the registry rejected — it
26
+ exits 1 and names the file. It would have stopped that release.
27
+
28
+ **The step order let an optional package strand the release.** The SDK publish sat before the
29
+ release page and the dist-tag move, so its failure skipped both. The same mode had already fired
30
+ on v11.5.1 and v11.8.3. Reordered so the steps that *finish* a release run ahead of any additive
31
+ package publish — which means this release moves `stable` forward even if a package fails again.
32
+
33
+ ### The user-visible part
34
+
35
+ **`mindforge-sdk` publishes for the first time since 11.8.0, and for the first time with
36
+ provenance.** Everything fixed in the SDK across 11.8.1–11.9.4 had reached nobody, including
37
+ this: `WebSocketEventStream` scheduled a reconnect and nothing handled the returned promise, so
38
+ a failed reconnect was an unhandled rejection — fatal under Node's default mode, **terminating
39
+ the caller's process**. Every consumer on 11.8.0 still has that.
40
+
41
+ ### Also fixed
42
+
43
+ - `bin/utils/readiness-gate.js` scored `RELEASENOTES.md` on existence while its changelog sibling
44
+ checked the version was *in* the file. That asymmetry is why both prose surfaces shipped stale
45
+ in 11.9.3 and again in 11.9.4. Both are now checked, anchored rather than by substring.
46
+ **Policy change:** every release from here needs an entry in this file.
47
+ - `docs/sdk-reference.md` claimed `npx mindforge-cc@stable` installs the SDK "as part of the
48
+ framework". Measured false — the published package declares exactly `express` and `sql.js` and
49
+ ships no `sdk/`. Removed.
50
+
51
+ ### Note on 11.9.4
52
+
53
+ It is complete, but was finished by hand: its GitHub Release was created at the existing tag from
54
+ the registry's own tarball, verified against `dist.integrity` and both attestation bundles'
55
+ subject digests. The `v11.9.4` tag was deliberately **not** moved, because two published
56
+ packages' provenance attests to the commit it names.
57
+
58
+ ## v11.9.4 — 2026-08-22 — Delivery: the gates register, the tarball matches its tag
59
+
60
+ ### The headline
61
+
62
+ **11.9.3 shipped the hook-registration code and then declined to run it.** The installer skipped
63
+ whenever any ancestor directory contained a `.claude`. On a machine that has ever run Claude Code
64
+ that means `~/.claude`, so essentially every install copied the enforcement in and wired none of it.
65
+
66
+ Measured against the published tarballs in a confined sandbox, with `~/.claude` as the only ancestor:
67
+
68
+ ```
69
+ 11.9.3: 11 hook scripts installed, 0 registered, no settings.json written
70
+ 11.9.4: 8 registered, preflight executed 7 of 8, 3 deny-class verified blocking
71
+ ```
72
+
73
+ The reason the installer printed was wrong three separate ways:
74
+
75
+ 1. `~/.claude/settings.json` is the **user tier**, applied in addition to the project tier. Its
76
+ existence says nothing about whether a project file is read — so the condition that suppressed
77
+ the gates was satisfied by an ordinary laptop.
78
+ 2. For a real project ancestor the claim is false too: that file is not read either. Proved with a
79
+ marker hook two levels up that never fired across a dozen tool calls. Skipping did not deliver
80
+ the gates elsewhere; it delivered them nowhere.
81
+ 3. The git-boundary guard was dead code, which is why the walk reached `$HOME` at all.
82
+
83
+ It now warns and registers anyway. A registration that turns out inert costs nothing; a skip is
84
+ guaranteed inert.
85
+
86
+ ### ⚠️ Behaviour change under a patch bump
87
+
88
+ The installer now writes `.claude/settings.json` on projects where it previously declined — for most
89
+ users, **0 registered hooks becomes 8**, three of which can block a tool call. It merges append-only
90
+ into any existing file, backs the previous one up under `.mindforge/backups/`, and records exactly
91
+ what it did in `.mindforge/hook-registration.json`.
92
+
93
+ A registered hook is only *live* if the harness has been **restarted** (hooks are snapshotted at
94
+ session start), the project is **trusted** in the harness, and `CLAUDE_PROJECT_DIR` is set with
95
+ `node` on the hook PATH. See *Hooks are installed but nothing is blocked* in
96
+ `docs/troubleshooting.md`.
97
+
98
+ ### Fixes
99
+
100
+ - The installer's only failure-path pointer led nowhere: it said "see `docs/troubleshooting.md`",
101
+ where the word *hook* appeared **0** times. That section now exists.
102
+ - The published tarball was not reproducible from its own tag. `.mindforge/memory/sync-manifest.json`
103
+ — gitignored, written at runtime — was **1 of 1979** shipped files not tracked at `v11.9.3`, so
104
+ provenance attested to a tree containing a file the repository does not contain.
105
+ - The README understated the product: it still said **no channel registers hooks** and that the
106
+ plugin dispatcher crashes on every fire. Measured: 14 of 14 plugin path tokens resolve and two
107
+ deny-class hooks return exit 2. A document that under-claims a security capability is the same
108
+ defect as one that over-claims it.
109
+ - Defects an 8-agent audit found in the *published* 11.9.3: an empty release page, a shipped CI
110
+ snippet telling users to `npx` a package we do not own, and a version-source gate that missed a
111
+ live defect twice.
112
+ - The Homebrew formula carries the real 11.9.3 digest, verified against an independent measurement.
113
+
114
+ ### Known issue in this release
115
+
116
+ **`mindforge-sdk` did not publish and remains at 11.8.0.** A publish step was added for it and the
117
+ registry rejected it with 422: `sdk/package.json` carried no `repository` field, which npm's
118
+ provenance verification validates **server-side at publish time** — `npm publish --dry-run` does not
119
+ check it, and no gate here did either.
120
+
121
+ Worse, the step was placed *before* the release-page and dist-tag steps, so its failure skipped
122
+ both. `mindforge-cc@11.9.4` and `mindforge-mcp-server@11.9.4` published correctly with provenance;
123
+ the release page and the `stable` tag were completed by hand afterwards. Both causes are fixed for
124
+ the next release: the missing field, an offline preflight gate that refuses to reach a publish
125
+ without it, and a reordering so the steps that finish a release run ahead of any optional package.
126
+
3
127
  ## v11.9.3 — 2026-08-21 — Honesty: gates that can fail, commands that run, a release path that is checked
4
128
 
5
129
  ### What's New
package/SECURITY.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Security Policy
2
2
 
3
- > **Current version:** 11.9.4 | **npm audit:** 0 vulnerabilities across root, sdk, mcp-server
3
+ > **Current version:** 11.9.5 | **npm audit:** 0 vulnerabilities across root, sdk, mcp-server
4
4
 
5
5
  ## Supported Versions
6
6
 
@@ -100,12 +100,28 @@ function releaseReadinessChecks(root) {
100
100
  pass: Boolean(pkgVersion) && pkgVersion === configVersion,
101
101
  fix: `Align versions: package.json=${pkgVersion || '?'} vs config.json=${configVersion || '?'}`,
102
102
  },
103
+ // CHECKS CONTENT, NOT MERE EXISTENCE, and that change has a cost worth naming: from now on every
104
+ // release needs a RELEASENOTES entry. Six published 11.x versions do not have one (11.0.0, 11.2.0,
105
+ // 11.2.1, 11.4.0, 11.7.1, 11.9.1) — the file has been curated rather than exhaustive. Those gaps are
106
+ // unaffected, because this only ever looks for the version being released.
107
+ //
108
+ // WHY IT CHANGED. This gate passed on `fileExists` while its changelog sibling three lines down
109
+ // checked that the version was IN the file. That asymmetry is why both prose surfaces shipped stale
110
+ // twice running: the immutable 11.9.3 tarball's README said "Latest release v11.9.2", and the
111
+ // immutable 11.9.4 tarball shipped with no 11.9.4 entry here at all — while README.md offers this
112
+ // file as the human-readable route to the BREAKING notes. 348a3a2c fixed the identical defect one
113
+ // release earlier by hand and added no gate, and it recurred immediately.
114
+ //
115
+ // Anchored, not `includes`. A substring test for "11.9.4" is also satisfied by "## v11.9.40" and by
116
+ // "## v11.9.4-notyet" — measured, when the equivalent test assertion was falsified.
103
117
  {
104
118
  id: 'releasenotes',
105
- label: 'RELEASENOTES.md present',
119
+ label: 'RELEASENOTES.md present and has an entry for the current version',
106
120
  points: 2,
107
- pass: fileExists(root, 'RELEASENOTES.md'),
108
- fix: 'Add RELEASENOTES.md for this release.',
121
+ pass: fileExists(root, 'RELEASENOTES.md') && Boolean(pkgVersion)
122
+ && new RegExp(`^## v${pkgVersion.replace(/\./g, '\\.')}(?![\\d.\\w-])`, 'm')
123
+ .test(safeRead(root, 'RELEASENOTES.md')),
124
+ fix: `Add a "## v${pkgVersion || '?'}" section to RELEASENOTES.md. README.md links here as the human-readable route to the BREAKING notes, so releasing without one points readers at a file whose newest entry describes a different version.`,
109
125
  },
110
126
  {
111
127
  id: 'changelog',
@@ -1,6 +1,6 @@
1
1
  # Changelog
2
2
 
3
- ## [11.9.4] — 2026-08-22 — Delivery: the gates register, the tarball matches its tag, three packages attested
3
+ ## [11.9.4] — 2026-08-22 — Delivery: the gates register, the tarball matches its tag
4
4
 
5
5
  Patch release. 11.9.3 argued that an instrument must not report success while doing
6
6
  nothing. 11.9.4 is what an adversarial audit of the **published** 11.9.3 artifact found
@@ -71,13 +71,36 @@ not from reading the repository. That distinction is the whole content of this r
71
71
  exactly this reason, and the manifest's entire content is the sync record *for that
72
72
  already-excluded file*. (#225)
73
73
 
74
- - **`mindforge-sdk` is published again, with provenance.** It sat at **11.8.0** on npm
75
- while `sync-version.js` kept `sdk/package.json` at canonical seven releases of
76
- disagreement (11.8.1 through 11.9.3, none published) that nothing detected, because
77
- `version:check` verifies the tracked file and not what the registry serves. It was also
78
- the only one of the three packages with **no attestation**. The release workflow now
79
- publishes it with `--provenance`, after the two proven publishes and before the GitHub
80
- Release, so the newest step cannot cost the others their artifacts.
74
+ - **`mindforge-sdk` was NOT published in this release. It remains at 11.8.0.** This entry
75
+ originally claimed it shipped with provenance; that claim was false and is corrected here
76
+ rather than quietly deleted, because a release arguing for measured claims does not get to
77
+ misstate a supply-chain property.
78
+
79
+ What happened: the SDK sat at **11.8.0** on npm while `sync-version.js` kept
80
+ `sdk/package.json` at canonical seven releases of disagreement (11.8.1 through 11.9.3,
81
+ none published) that nothing detected, because `version:check` verifies the tracked file
82
+ and not what the registry serves. It was also the only one of the three packages with **no
83
+ attestation**. A publish step was added for it, and the registry rejected it:
84
+
85
+ ```
86
+ npm error 422 Unprocessable Entity - PUT https://registry.npmjs.org/mindforge-sdk
87
+ Error verifying sigstore provenance bundle: Failed to validate repository information:
88
+ package.json: "repository.url" is "", expected to match
89
+ "https://github.com/sairam0424/MindForge" from provenance
90
+ ```
91
+
92
+ `sdk/package.json` carried no `repository` field. The other two packages both do, which is
93
+ exactly why they published and it did not. That field is validated **registry-side at PUT**,
94
+ after two irreversible publishes have already succeeded — `npm publish --dry-run` does not
95
+ check it and neither did any gate here. Both are fixed for 11.9.5: the field, and an offline
96
+ preflight gate that refuses to reach a publish without it.
97
+
98
+ The step was also badly placed. It ran **before** `Create GitHub Release` and the `stable`
99
+ dist-tag move, so its failure skipped both — which is the precise harm the placement comment
100
+ claimed to prevent. `mindforge-cc@11.9.4` and `mindforge-mcp-server@11.9.4` published
101
+ correctly with provenance attesting commit 353e8d41; the release page and the `stable` tag
102
+ were completed by hand afterwards. The finishing steps now run ahead of the additive
103
+ publishes, so no optional package can strand a release again.
81
104
 
82
105
  - **The Homebrew formula carries the real 11.9.3 digest.** Verified against an independent
83
106
  measurement rather than the tool's own output, and explicitly confirmed not to be the
@@ -0,0 +1,104 @@
1
+ # Changelog
2
+
3
+ ## [11.9.5] — 2026-08-22 — The release path can no longer strand itself, and the SDK ships
4
+
5
+ Patch release, and the shortest one in a while. It exists because 11.9.4 published two
6
+ packages and then failed on the third, and that failure took the release page and the
7
+ `stable` dist-tag with it. Both causes are fixed here, and one of them is the reason this
8
+ release is worth cutting rather than waiting: **`mindforge-sdk` publishes for the first
9
+ time in seven versions, with provenance.**
10
+
11
+ ### Fixed
12
+
13
+ **A publish that cannot finish the release it started**
14
+
15
+ - **`sdk/package.json` had no `repository` field.** npm's provenance verification compares
16
+ that field against the attestation **server-side, at PUT** — so the publish was rejected
17
+ with `422 Unprocessable Entity … "repository.url" is ""` *after* `mindforge-cc` and
18
+ `mindforge-mcp-server` had already published irreversibly. `npm publish --dry-run` does
19
+ not perform that comparison, and nothing in this repository read `repository` at all: all
20
+ six preflight gates passed on a manifest the registry was guaranteed to reject. The field
21
+ is added, matching the spelling the other two packages use.
22
+
23
+ - **`scripts/ci/verify-provenance-metadata.js` makes that failure reachable before the
24
+ point of no return.** It runs in the release **preflight** job, ahead of every publish,
25
+ and it does not carry a list of packages: it discovers them from the workflow — every
26
+ step whose `run` contains both `npm publish` and `--provenance`, resolved through its
27
+ `working-directory` — so a fourth package is covered without editing the gate.
28
+ Discovering zero targets is a hard failure rather than a pass, on the principle that a
29
+ check which examined nothing must not report success.
30
+
31
+ Verified the only way that means anything: run against a git worktree at tag `v11.9.4` —
32
+ the exact tree that the registry rejected — it exits 1 and names `sdk/package.json` and
33
+ the missing field. It would have stopped that release before anything reached npm.
34
+
35
+ - **The release steps were ordered so that an optional package could strand the release.**
36
+ The SDK publish sat *before* `Create GitHub Release` and the `stable` dist-tag move.
37
+ A failing step fails the job, so both were skipped — which is precisely the harm the
38
+ placement comment claimed to prevent. The same mode had already fired on **v11.5.1** and
39
+ **v11.8.3** from the MCP publish; v11.9.4 was its third occurrence.
40
+
41
+ Reordered to: `Publish to npm` → `Create GitHub Release` → `stable` dist-tag →
42
+ `mcp-server` → `sdk`. The rule now encoded in `tests/action-pinning.test.js`: **no step
43
+ whose failure leaves no residue may be able to skip a step that finishes an irreversible
44
+ one.** That test previously asserted the opposite and had to be inverted in the same
45
+ commit — because `Run Full Test Suite` is the release job's first step, a reorder shipped
46
+ alone would have failed the release at its own gate.
47
+
48
+ The two finishers carry guards on their own inputs rather than a bare `!cancelled()`,
49
+ which would publish a release with a 0-byte body and an unmatched `.tgz` glob when
50
+ `Build Package` fails — the `bodyBytes=0` defect already seen on v11.9.0, .1 and .2. And
51
+ deliberately not `continue-on-error`: a tolerated failure makes the run conclude
52
+ **green**, which is the blindness that let the SDK sit seven versions behind, unattested,
53
+ with nothing noticing.
54
+
55
+ **Prose surfaces that shipped stale twice running**
56
+
57
+ - `bin/utils/readiness-gate.js` scored `RELEASENOTES.md` on `fileExists` while its
58
+ changelog sibling three lines away checked that the version appeared *in* the file. That
59
+ asymmetry is why the immutable 11.9.3 tarball's README said "Latest release v11.9.2" and
60
+ the immutable 11.9.4 tarball shipped with no 11.9.4 entry at all — while `README.md`
61
+ offers that file as the human-readable route to the BREAKING notes. Both are now checked,
62
+ anchored rather than by substring (`includes('11.9.4')` is also satisfied by
63
+ `## v11.9.40`).
64
+
65
+ **Policy change, stated plainly:** every release from here needs a `RELEASENOTES.md`
66
+ entry. Six published 11.x versions do not have one, so that file has been curated rather
67
+ than exhaustive; the gate only ever looks for the version being released, so those gaps
68
+ are unaffected.
69
+
70
+ - README's `## Latest release` is deliberately gated by a **test** rather than written by
71
+ `sync-version.js`. Auto-bumping the version token onto the previous release's paragraph
72
+ produces the right number attached to the wrong description — a better-disguised
73
+ falsehood than a visibly stale one.
74
+
75
+ - `docs/sdk-reference.md` offered `npx mindforge-cc@stable` as a way to get the SDK
76
+ "as part of the framework". Measured false: the published package declares exactly
77
+ `express` and `sql.js` and ships no `sdk/` directory. Removed.
78
+
79
+ ### Added
80
+
81
+ - **`mindforge-sdk` is published, with provenance** — its first release since 11.8.0 and
82
+ its first ever attested one. This is not cosmetic. Everything fixed in the SDK across
83
+ 11.8.1–11.9.4 reached nobody, including the one that matters most:
84
+ `WebSocketEventStream` scheduled a reconnect with `setTimeout(() => this.connect(), …)`
85
+ and nothing handled the returned promise, so a failed reconnect was an unhandled
86
+ rejection — fatal under Node's default mode, **terminating the caller's process**. Every
87
+ consumer on 11.8.0 still has that. (#191)
88
+
89
+ - `npm run provenance:check` — the gate above, runnable offline.
90
+
91
+ ### Notes for operators
92
+
93
+ - 11.9.4 is complete but was finished by hand: its GitHub Release was created at the
94
+ existing tag from the registry's own tarball (verified against `dist.integrity` and both
95
+ attestation bundles' subject digests), and the `v11.9.4` tag was deliberately **not**
96
+ moved, because two published packages' provenance attests to the commit it names.
97
+ - The `stable` dist-tag lagged at 11.9.3 between the two releases. Because the dist-tag
98
+ step now runs *ahead* of both additive publishes, this release moves it forward even if a
99
+ package publish fails again.
100
+ - Still outstanding, and requiring repository settings rather than code: there is no `v*`
101
+ **tag ruleset** restricting who may create the ref that triggers publishing, and
102
+ `NPM_TOKEN` remains a long-lived repository secret with no GitHub environment in front of
103
+ it. Create the environment *first* — adding `environment:` while none exists publishes
104
+ exactly as before while looking like a gate.
package/docs/faq.md CHANGED
@@ -1,4 +1,4 @@
1
- # MindForge FAQ (v11.9.4)
1
+ # MindForge FAQ (v11.9.5)
2
2
 
3
3
  ## Is MindForge tied to Claude only?
4
4
  No. MindForge supports Claude Code and Antigravity. Install with `--claude`,
@@ -55,7 +55,7 @@ The `deep-research` workflow was removed before the v11.8.0 release (the superpo
55
55
  ## Version & Stability
56
56
 
57
57
  **Q: What version is current?**
58
- v11.9.4 — verify with `node bin/mindforge-cli.js --version`
58
+ v11.9.5 — verify with `node bin/mindforge-cli.js --version`
59
59
 
60
60
  **Q: Is v11.9.0 production-stable?**
61
61
  Yes. The IQ200 deep-audit (258 discrete checks across 14 dimensions) shows 258/258 passing. 0 CVEs, 0 test failures, 0 ESLint errors, 0 TypeScript errors.
@@ -80,7 +80,7 @@ Spawn dispatch is not yet implemented in v11.9.0. Use `/mindforge:auto` or `/min
80
80
  Tier-3 trust uses in-process key simulation in v11.9.0 — this is intentional and safe. `SECURITY_TIER_3_SIMULATED = true` is the documented v11.x behavior. Hardware TPM/HSM is planned for v12.x.
81
81
 
82
82
  **Q: What is the test coverage?**
83
- 134 test files: 132 pass, 0 failures, 2 env-dependent skips (`browser.test.js` needs a Chromium
83
+ 135 test files: 133 pass, 0 failures, 2 env-dependent skips (`browser.test.js` needs a Chromium
84
84
  daemon, `sre-integration.test.js` needs git worktree support and a clean tree).
85
85
 
86
86
  The enforced floor is **30% lines**, gated in CI by the `mindforge-quality` job
@@ -1,4 +1,4 @@
1
- # MindForge — Getting Started (v11.9.4)
1
+ # MindForge — Getting Started (v11.9.5)
2
2
 
3
3
  This guide gets you from zero to a working MindForge project in under five minutes.
4
4
 
@@ -114,7 +114,7 @@ Or use slash commands: `/mindforge:wf-code-audit`
114
114
  ## Your First 5 Minutes with MindForge
115
115
 
116
116
  1. **Verify install:** `node bin/mindforge-cli.js health`
117
- 2. **Check version:** `node bin/mindforge-cli.js --version` (should print `11.9.4`)
117
+ 2. **Check version:** `node bin/mindforge-cli.js --version` (should print `11.9.5`)
118
118
  3. **List workflows:** `node bin/mindforge-cli.js workflow list`
119
119
  4. **Run first slash command:** Open Claude Code → `/mindforge:status`
120
120
  5. **Onboard your codebase:** Open Claude Code → `/mindforge:wf-onboard-codebase`
@@ -14,11 +14,11 @@ import {
14
14
  } from 'mindforge-sdk';
15
15
  ```
16
16
 
17
- Current SDK version: `11.9.4`
17
+ Current SDK version: `11.9.5`
18
18
 
19
19
  ---
20
20
 
21
- ## SDK Exports (v11.9.4)
21
+ ## SDK Exports (v11.9.5)
22
22
 
23
23
  ```javascript
24
24
  const {
@@ -28,7 +28,7 @@ const {
28
28
  commands, // Command registry
29
29
  batch, // Batch execution
30
30
  MindForgeMemory, // Memory interface
31
- VERSION // '11.9.4'
31
+ VERSION // '11.9.5'
32
32
  } = require('mindforge-sdk');
33
33
  // or: import { MindForgeClient, VERSION } from 'mindforge-sdk';
34
34
  ```
@@ -418,13 +418,19 @@ cd sdk && npm install && npm run build
418
418
  ## Installation
419
419
  ```bash
420
420
  npm install mindforge-sdk
421
- # or: npx mindforge-cc@stable # installs SDK as part of the framework
422
421
  ```
423
422
 
424
- > **`mindforge-sdk` is versioned independently of the framework.** The release workflow
425
- > (`.github/workflows/mindforge-release.yml`) publishes `mindforge-cc` and
426
- > `mindforge-mcp-server` only it has no `sdk` steps so `sdk/package.json`'s version
427
- > tracks the monorepo while the published package does not. At the time of writing the
428
- > latest published SDK is **11.8.0** (`npm view mindforge-sdk versions`), even though the
429
- > in-repo `sdk/package.json` reads 11.9.2. Install it unpinned, as above; pinning it to a
430
- > framework version yields `E404 No match found for version …`.
423
+ > **`mindforge-sdk` lags the framework, and the framework does not contain it.** Installing
424
+ > `mindforge-cc` does **not** give you the SDK: the published package declares exactly two
425
+ > dependencies, `express` and `sql.js`, and ships no `sdk/` directory. A line here previously
426
+ > offered `npx mindforge-cc@stable` as a way to get the SDK "as part of the framework"; that was
427
+ > false and has been removed.
428
+ >
429
+ > The release workflow publishes the SDK as of 11.9.5, with provenance. Its first attempt
430
+ > (v11.9.4) was rejected by the registry — `sdk/package.json` carried no `repository` field, which
431
+ > npm's provenance check validates server-side at publish time — so **versions 11.8.1 through
432
+ > 11.9.4 do not exist on npm** and never will. Check what is actually published with
433
+ > `npm view mindforge-sdk version` rather than assuming it matches the framework: the version in
434
+ > `sdk/package.json` tracks the monorepo because `scripts/sync-version.js` rewrites it, whether or
435
+ > not that version reached the registry. Install it unpinned, as above; pinning it to a framework
436
+ > version that was never published yields `E404 No match found for version …`.
@@ -1,4 +1,4 @@
1
- # MindForge Troubleshooting (v11.9.4)
1
+ # MindForge Troubleshooting (v11.9.5)
2
2
 
3
3
  This page lists common issues and fast fixes. If you get stuck, start with
4
4
  `/mindforge:health`.
@@ -1,8 +1,8 @@
1
- # MindForge User Guide (v11.9.4)
1
+ # MindForge User Guide (v11.9.5)
2
2
 
3
3
  This guide gets you from install to productive, with the minimum needed to run MindForge in a real project.
4
4
 
5
- > **v11.9.4 Stats:** 35 workflows · 221 slash commands · 232 engine skills · 216 personas · 0 CVEs · 258/258 IQ200 checks passing
5
+ > **v11.9.5 Stats:** 35 workflows · 221 slash commands · 232 engine skills · 216 personas · 0 CVEs · 258/258 IQ200 checks passing
6
6
 
7
7
  ## Prerequisites
8
8
 
@@ -44,7 +44,7 @@ mindforge health # Verify project integrity
44
44
  mindforge security-scan # Run security checks
45
45
  mindforge headless # Run agent in non-interactive mode
46
46
  mindforge --verbose ... # Enable verbose output for debugging
47
- mindforge --version # Print installed version (e.g. 11.9.4) and exit 0
47
+ mindforge --version # Print installed version (e.g. 11.9.5) and exit 0
48
48
  ```
49
49
 
50
50
  Use `--verbose` (or `-v`) on any command for detailed diagnostic output. Use `--version` (or `-V`) to print the installed version and exit.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mindforge-cc",
3
- "version": "11.9.4",
3
+ "version": "11.9.5",
4
4
  "description": "MindForge — Sovereign Agentic Intelligence Framework. Sovereign Stability: Production-Hardened Agentic Intelligence (v11)",
5
5
  "bin": {
6
6
  "mindforge-cc": "bin/install.js",
@@ -68,6 +68,7 @@
68
68
  "harness:compliance": "node bin/installer/harness-adapter-compliance.js --check",
69
69
  "release:ready": "node bin/utils/readiness-gate.js release",
70
70
  "version:check": "node scripts/sync-version.js --check",
71
+ "provenance:check": "node scripts/ci/verify-provenance-metadata.js",
71
72
  "validate:assets": "node scripts/ci/validate-assets.js",
72
73
  "eval:retrieval": "node bin/eval/eval-harness.js --set golden-set-retrieval.json --min-recall 0.55",
73
74
  "commit": "cz",