mindforge-cc 11.9.2 → 11.9.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/.agent/CLAUDE.md +37 -13
  2. package/.agent/hooks/mindforge-block-no-verify.js +61 -13
  3. package/.agent/hooks/mindforge-config-protection.js +82 -3
  4. package/.agent/hooks/mindforge-context-monitor.js +1 -1
  5. package/.agent/hooks/mindforge-workflow-guard.js +2 -2
  6. package/.agent/hooks/run-with-flags.js +190 -20
  7. package/.agent/mindforge/browse.md +2 -2
  8. package/.agent/mindforge/checkpoint.md +1 -1
  9. package/.agent/mindforge/harness-audit.md +1 -1
  10. package/.agent/mindforge/orch-add-feature.md +1 -1
  11. package/.agent/mindforge/orch-build-mvp.md +1 -1
  12. package/.agent/mindforge/orch-change-feature.md +1 -1
  13. package/.agent/mindforge/orch-fix-defect.md +1 -1
  14. package/.agent/mindforge/orch-refine-code.md +1 -1
  15. package/.agent/mindforge/qa.md +2 -2
  16. package/.claude/CLAUDE.md +37 -13
  17. package/.claude/commands/mindforge/browse.md +2 -2
  18. package/.claude/commands/mindforge/checkpoint.md +1 -1
  19. package/.claude/commands/mindforge/harness-audit.md +1 -1
  20. package/.claude/commands/mindforge/orch-add-feature.md +1 -1
  21. package/.claude/commands/mindforge/orch-build-mvp.md +1 -1
  22. package/.claude/commands/mindforge/orch-change-feature.md +1 -1
  23. package/.claude/commands/mindforge/orch-fix-defect.md +1 -1
  24. package/.claude/commands/mindforge/orch-refine-code.md +1 -1
  25. package/.claude/commands/mindforge/qa.md +2 -2
  26. package/.mindforge/MINDFORGE-SCHEMA.json +1 -1
  27. package/.mindforge/config.json +3 -3
  28. package/.mindforge/engine/autonomous/headless-adapter.md +9 -2
  29. package/.mindforge/engine/temporal-protocol.md +2 -2
  30. package/.mindforge/governance/change-classifier.md +20 -4
  31. package/.mindforge/skills/agent-architecture-audit/SKILL.md +2 -2
  32. package/.mindforge/skills/orch-pipeline/SKILL.md +4 -4
  33. package/CHANGELOG.md +357 -0
  34. package/MINDFORGE.md +13 -6
  35. package/README.md +49 -30
  36. package/RELEASENOTES.md +65 -2
  37. package/SECURITY.md +22 -3
  38. package/bin/autonomous/auto-runner.js +65 -2
  39. package/bin/change-classifier.js +151 -16
  40. package/bin/dashboard/api-router.js +18 -38
  41. package/bin/dashboard/frontend/app.js +429 -0
  42. package/bin/dashboard/frontend/index.html +13 -406
  43. package/bin/dashboard/metrics-aggregator.js +52 -23
  44. package/bin/dashboard/server.js +160 -1
  45. package/bin/dashboard/sse-bridge.js +11 -8
  46. package/bin/engine/sre-manager.js +1 -1
  47. package/bin/engine/temporal-cli.js +56 -6
  48. package/bin/engine/verification-runner.js +134 -17
  49. package/bin/engine/verify-cli.js +25 -7
  50. package/bin/governance/approval-record.js +147 -0
  51. package/bin/governance/approve.js +24 -8
  52. package/bin/governance/policy-engine.js +33 -3
  53. package/bin/governance/policy-gate-hardened.js +36 -1
  54. package/bin/governance/verify-approvals.js +175 -0
  55. package/bin/harness-audit.js +224 -10
  56. package/bin/hooks/instinct-capture-hook.js +12 -4
  57. package/bin/install.js +63 -3
  58. package/bin/installer/harness-adapter-compliance.js +339 -28
  59. package/bin/installer/hook-registration.js +547 -0
  60. package/bin/installer-core.js +481 -65
  61. package/bin/learning/instinct-cli.js +7 -0
  62. package/bin/memory/vector-hub.js +196 -13
  63. package/bin/migrations/0.6.0-to-1.0.0.js +30 -25
  64. package/bin/migrations/1.0.0-to-2.0.0.js +22 -23
  65. package/bin/mindforge-cli.js +67 -6
  66. package/bin/models/cost-tracker.js +104 -6
  67. package/bin/models/model-client.js +6 -1
  68. package/bin/revops/debt-monitor.js +57 -13
  69. package/bin/security/trust-gate-hook.js +50 -6
  70. package/bin/skill-validator.js +6 -1
  71. package/bin/skills-builder/skill-scorer.js +46 -6
  72. package/bin/updater/self-update.js +6 -1
  73. package/bin/updater/version-comparator.js +21 -1
  74. package/bin/utils/mindforge-version.js +99 -0
  75. package/bin/utils/redact-secrets.js +106 -0
  76. package/bin/validate-config.js +42 -2
  77. package/bin/wizard/setup-wizard.js +4 -1
  78. package/bin/wizard/theme.js +9 -1
  79. package/changelogs/index.json +11 -9
  80. package/changelogs/v11.9.3.md +204 -0
  81. package/changelogs/v11.9.4.md +155 -0
  82. package/docs/References/config-reference.md +5 -2
  83. package/docs/References/sdk-api.md +1 -1
  84. package/docs/Templates/Codebase/architecture.md +1 -1
  85. package/docs/commands-reference.md +4 -5
  86. package/docs/faq.md +25 -5
  87. package/docs/getting-started.md +10 -4
  88. package/docs/sdk-reference.md +15 -7
  89. package/docs/troubleshooting.md +65 -6
  90. package/docs/user-guide.md +14 -14
  91. package/examples/sdk-integration/README.md +1 -1
  92. package/package.json +8 -3
  93. package/subagents/.claude-plugin/marketplace.json +1 -1
  94. package/.mindforge/memory/sync-manifest.json +0 -6
  95. package/bin/dashboard/approval-handler.js +0 -136
package/CHANGELOG.md CHANGED
@@ -1,5 +1,362 @@
1
1
  # Changelog
2
2
 
3
+ ## [11.9.4] — 2026-08-22 — Delivery: the gates register, the tarball matches its tag, three packages attested
4
+
5
+ Patch release. 11.9.3 argued that an instrument must not report success while doing
6
+ nothing. 11.9.4 is what an adversarial audit of the **published** 11.9.3 artifact found
7
+ when that standard was applied to the delivery itself: **enforcement that installed and
8
+ then declined to register, a tarball that could not be reproduced from its own tag, and a
9
+ README that understated what shipped.**
10
+
11
+ Every finding here came from measuring the published package in a confined environment —
12
+ not from reading the repository. That distinction is the whole content of this release.
13
+
14
+ ### BREAKING
15
+
16
+ - **The installer now registers hooks on projects where it previously declined.** If you
17
+ install into a project that has an ancestor directory containing a `.claude`, MindForge
18
+ now writes `.claude/settings.json` (merging append-only into any existing file) instead
19
+ of skipping. On a machine that has ever run Claude Code, `~/.claude` makes that
20
+ essentially every project — so most installs go from **0 registered hooks to 8**. Three
21
+ of them can block a tool call. If you were relying on the installer being inert here,
22
+ it no longer is; `.mindforge/hook-registration.json` records exactly what was written,
23
+ and the previous settings file is backed up under `.mindforge/backups/`. (#224)
24
+
25
+ ### Fixed
26
+
27
+ **Hook registration — the gates shipped installed but inert**
28
+
29
+ - **`register()` skipped whenever any ancestor held a `.claude` directory.** Measured
30
+ against the published 11.9.3 tarball, confined HOME, `~/.claude` as the only ancestor:
31
+ **11 hook scripts installed, 0 registered, no settings file written.** The gates that
32
+ the shipped `CLAUDE.md` calls MANDATORY were copied in and left unreachable. Same
33
+ sandbox on 11.9.4: **8 registered, installer preflight executed 7 of 8 and verified all
34
+ 3 deny-class hooks returning exit 2** before keeping the file. (#224)
35
+
36
+ The reason it printed — *"the harness will read `<ancestor>/.claude/settings.json`, not
37
+ this directory"* — was wrong three separate ways:
38
+
39
+ 1. `~/.claude/settings.json` is the **user tier**, applied in addition to the project
40
+ tier. Its existence carries no information about whether a project file is read, so
41
+ the condition that suppressed the gates was satisfied by an ordinary laptop.
42
+ 2. For a genuine project ancestor the claim is false too — that file is not read
43
+ either. Verified with a natural experiment: an ancestor two levels up carried a
44
+ `PreToolUse` Bash hook appending a marker to a log; across a dozen tool calls with
45
+ the inner directory as the project root, the log was never created. Skipping did not
46
+ deliver the gates elsewhere. It delivered them nowhere.
47
+ 3. The git-boundary guard was **dead code**. `stop` was the git toplevel while the walk
48
+ began at `dirname(projectRoot)`, so when toplevel equalled projectRoot the stop
49
+ condition could never be true and the walk ran to the filesystem root every time.
50
+ The boundary meant to keep the check local is why it reached `$HOME`.
51
+
52
+ It now warns and registers anyway: a registration that turns out inert costs nothing and
53
+ becomes live when the harness is launched there, whereas a skip is guaranteed inert. The
54
+ check additionally requires a real `settings.json` **file** — the old one accepted any
55
+ directory named `.claude`, and the one it hit in practice held only markdown. (#224)
56
+
57
+ - **The installer's only failure-path pointer led nowhere.** It told anyone whose hooks
58
+ were not registered to "see `docs/troubleshooting.md`", where the word *hook* appeared
59
+ **0** times. That file now carries the section the message names, separating "not
60
+ registered" from "registered but not live", and including a copy-paste payload that
61
+ drives a hook directly so a broken hook can be told apart from an unwired one. (#224)
62
+
63
+ **Release artifacts**
64
+
65
+ - **The published tarball could not be reproduced from its tag.**
66
+ `.mindforge/memory/sync-manifest.json` — gitignored, written at runtime by
67
+ `bin/memory/semantic-hub.js` — was **1 of 1979** shipped files not tracked at
68
+ `v11.9.3`, so provenance attested to a tree containing a file the repository does not
69
+ contain. With a `files[]` allowlist, a **directory** entry ships its contents regardless
70
+ of `.gitignore`; `files[]` already carried a negation for `pattern-library.jsonl` for
71
+ exactly this reason, and the manifest's entire content is the sync record *for that
72
+ already-excluded file*. (#225)
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.
81
+
82
+ - **The Homebrew formula carries the real 11.9.3 digest.** Verified against an independent
83
+ measurement rather than the tool's own output, and explicitly confirmed not to be the
84
+ SHA-256 of npm's 21-byte `{"error":"Not found"}` body — the constant #203 used to write
85
+ for every unpublished version. (#223)
86
+
87
+ **Honesty about what is enforced**
88
+
89
+ - **The README understated the product.** "What is actually enforced" still declared that
90
+ **no install channel registers hooks**, with a `No / No` table, and stated that the
91
+ plugin channel's dispatcher crashes on every fire. Measured: the plugin's
92
+ `scripts/lib/` exists, all **14** path tokens in `plugins/mindforge/hooks/hooks.json`
93
+ resolve under the plugin root, and driving the dispatcher by hand returns **exit 2** for
94
+ `mindforge-block-no-verify` and `mindforge-config-protection`. A document that
95
+ under-claims a security capability is the same defect as one that over-claims it —
96
+ either way it describes a system that is not the one shipped. Now stated per channel,
97
+ with the four cases that remain deliberately unenforced and the three liveness
98
+ preconditions outside MindForge's control. (#225)
99
+
100
+ **Defects the published-artifact audit found (#222)**
101
+
102
+ - The **v11.9.3 release page shipped empty**: `changelog-fetcher.js --latest` exits 0
103
+ while writing zero bytes, so the `||` fallback never fired and a 195-line changelog
104
+ reached nobody. The step now prefers the in-tree changelog and fails on an empty body.
105
+ - A **shipped CI snippet told users to `npx` a package we do not own**.
106
+ `npx mindforge …` resolves to an unrelated third-party package; in a fresh runner it is
107
+ fetched and unpacked, install scripts and all, inside a job holding `MINDFORGE_TOKEN`.
108
+ Now pinned with `--package=mindforge-cc`.
109
+ - The **version-source gate missed a live defect twice**. `mindforge health` printed
110
+ `RELEASE v0.4.2` and `Current : v11.9.3` twenty-six lines apart in a project declaring
111
+ 0.4.2, and produced `Unexpected end of JSON input` with no manifest at all — the verb
112
+ whose job is verifying installation integrity misreporting the installation. Widening
113
+ the gate surfaced two more of the same shape, one of which bound the **wrong** version
114
+ silently into approval records, which is worse than no binding because the check still
115
+ returns a verdict.
116
+ - `mindforge approve` died with ENOENT on any non-Node project. Absent values are now
117
+ recorded as `null` rather than invented.
118
+
119
+ **Test infrastructure**
120
+
121
+ - `tests/production.test.js` carried the uncommitted diff into its clone with
122
+ `git diff HEAD` (which includes staged files) but committed it with `commit -a` (which
123
+ stages only modified and deleted **tracked** files). So any commit **adding** a file
124
+ under `bin/` or `tests/` left the clone dirty and failed the gate's own cleanliness
125
+ assertion — reintroducing precisely the `--no-verify` pressure that carry exists to
126
+ avoid, for the one case it did not cover.
127
+
128
+ ### Added
129
+
130
+ New regression gates, each falsified by reinstating the exact defect and confirming RED,
131
+ with every touched file restored byte-exact afterwards:
132
+
133
+ - `tests/hook-registration-ancestor.test.js` — six properties, the first of which asserts
134
+ the ancestor detector fires at all, so the other five cannot pass by never triggering.
135
+ - `every shipped file is tracked in git` — property-based, no name list. It cannot fail on
136
+ a clean clone, which is how the real leak survived CI, so it is paired with a second
137
+ test that plants the runtime state in a throwaway clone and then packs.
138
+ - `all three published packages publish with provenance` — counts the `npm publish`
139
+ invocations rather than matching one, because a single-match regex was satisfied by
140
+ either of the two packages that already had an attestation while the SDK had none. Also
141
+ asserts the SDK step is idempotent and ordered after the proven publishes.
142
+
143
+ ### Notes for operators
144
+
145
+ - **These fixes change installer behaviour on almost every project.** After upgrading,
146
+ check `.mindforge/hook-registration.json` to see what was registered, and restart the
147
+ harness — hooks are snapshotted at session start.
148
+ - A registered hook is only *live* if the harness has been restarted, the project is
149
+ trusted in the harness, and `CLAUDE_PROJECT_DIR` is set with `node` on the hook PATH.
150
+ None of those three are in MindForge's control; the last is a deliberate trade against a
151
+ fail-closed shell tail that was measured denying benign commands on a fresh clone.
152
+ - Two gaps remain that require repository settings rather than code, and are recorded
153
+ rather than claimed fixed: there is no `v*` **tag ruleset** restricting who may create
154
+ the ref that triggers publishing, and `NPM_TOKEN` is a long-lived repository secret with
155
+ no GitHub environment in front of it.
156
+
157
+ ## [11.9.3] — 2026-08-21 — Honesty: gates that can fail, commands that run, a release path that is checked
158
+
159
+ Patch release. No new features. Twenty-one fixes, and they all turned out to be the
160
+ same defect: **an instrument reported success while doing nothing.** Gates that could
161
+ not fail, tests satisfied by a comment, docs describing capabilities with no code
162
+ behind them, commands printing success while performing no action, and a publish path
163
+ that no check ever touched.
164
+
165
+ Contains behaviour changes under a patch bump — several of the things being fixed were
166
+ bugs that a consumer could have been relying on. Read BREAKING before upgrading if you
167
+ script against the CLI or the installer.
168
+
169
+ > **Corrected after release.** Three measured numbers in this entry were wrong and are fixed above:
170
+ > the count of places `--status`/`--stop` were documented (removed rather than re-guessed — it reads 4,
171
+ > 9 or 15 depending on how you count, which is the argument against stating it); the eslint total, which
172
+ > was 199 on the author's machine and **190** on a clean clone, because 9 problems came from an
173
+ > untracked local directory; and "four releases behind", which is **three** (11.8.3 → 11.9.0 → 11.9.1 →
174
+ > 11.9.2). Found by an adversarial audit of this changelog against the published artifact. A release
175
+ > arguing that measured numbers should be reproducible has to hold its own notes to that standard.
176
+
177
+ ### BREAKING
178
+
179
+ Each of these is a bug fix whose correct behaviour differs from the shipped behaviour.
180
+
181
+ - **Routed CLI commands now act on YOUR project, not MindForge's own checkout.**
182
+ `bin/mindforge-cli.js` passed `cwd: ROOT` to every routed command, so `mindforge
183
+ classify` diffed MindForge's repository instead of yours, and `mindforge health`
184
+ inspected MindForge's `node_modules`. Measured across all 27 routed commands: 7
185
+ changed behaviour, all in the correct direction, none regressed. If you parsed output
186
+ that happened to describe MindForge itself, it now describes your project. (#201)
187
+
188
+ - **`npx mindforge-cc install` — and any other positional argument — now exits 1.**
189
+ The installer takes flags only and silently ignored stray words, so
190
+ `npx mindforge-cc install` appeared to work while installing nothing configured.
191
+ It now refuses with the correct form. `--runtime`'s value token is still accepted.
192
+ Use `npx mindforge-cc --claude --local`. (#202)
193
+
194
+ - **`mindforge verify` now SKIPS unavailable stages instead of failing them.** A project
195
+ with no ESLint config, no test script or no `bin/verify-audit.js` was reported as
196
+ FAILING those stages rather than as not having them. If your CI relied on a non-zero
197
+ exit in those cases, it will now pass. A run in which every stage skipped prints a
198
+ "NOTHING WAS VERIFIED" banner rather than a clean bill of health. (#204)
199
+
200
+ - **`scripts/sync-version.js` now exits non-zero when the plugin build artifacts are
201
+ stale.** A bump used to report `✅ every derivable channel is at <version>` and exit 0
202
+ while leaving `npm test` red. If you script this, handle the new exit code — it means
203
+ "run the build chain it just printed". (#211)
204
+
205
+ - **A self-install no longer writes over your tracked files.** Running the installer
206
+ inside a MindForge checkout printed that it was skipping and then overwrote 149
207
+ tracked files, including `CLAUDE.md`, `.claude/**`, `.agent/**` and `.mindforge/**`.
208
+ The skip is now honoured for local scope. (#200)
209
+
210
+ - **Releases must be tagged on a commit reachable from `main`.** The release workflow
211
+ now refuses a tag that is not an ancestor of `origin/main`. The documented flow is
212
+ develop → release → main; tagging elsewhere previously published, with provenance
213
+ attesting to that tree. (#216)
214
+
215
+ ### Fixed
216
+
217
+ **Installer**
218
+
219
+ - A self-install claimed to skip and then overwrote 149 tracked files. The gate is now
220
+ scope-aware (`isSelfInstall() && scope === 'local'`). (#200)
221
+ - Every `--global` install reported failure on a correct run: `verifyInstall` demanded
222
+ six `bin/**` paths regardless of scope, so a global install ended
223
+ `❌ 6 of 12 required file(s) missing` and exit 1, with a `--force` retry that could
224
+ not help. A global install writes 389 files to `$HOME/.claude` and, deliberately,
225
+ zero to `bin/`. (#210)
226
+ - 11 of 27 routed CLI verbs died on `MODULE_NOT_FOUND` in a real install: the router
227
+ shipped but 6 of the scripts it dispatches to did not. `coreFiles` grew from 2 entries
228
+ to 8. (#210)
229
+ - Two leaks: `/tmp` staging files left behind on abandoned runs, and developer runtime
230
+ state (`celestial.db`, `.browser-daemon-token`) copied into consumer projects.
231
+ `SENSITIVE_EXCLUDE` now covers both. (#210)
232
+ - The forge commands overwrote three `mindforge` commands of the same name. (#197)
233
+ - The documented default install did not deliver the CLI it documents. (#196)
234
+
235
+ **Versioning and release**
236
+
237
+ - `sync-version.js --fetch-sha` hashed npm's 404 error body. For an unpublished version
238
+ the registry answers `{"error":"Not found"}` and `curl -sL` exits 0, so the digest
239
+ written into the Homebrew formula was the SHA-256 of that error text — the same
240
+ constant for every unpublished version — and `--check` then passed. Now `curl -fsSL`
241
+ plus a gzip magic-byte check, and it refuses rather than writing a digest no artifact
242
+ can match. (#203)
243
+ - The Homebrew formula may now LAG canonical but never LEAD it. Requiring equality
244
+ before publishing required something impossible: the digest is the hash of a tarball
245
+ that does not exist yet, and `npm test` blocked the publish that would have made it
246
+ satisfiable. (#208)
247
+ - Semver comparison is numeric per component. Lexicographically, `11.10.0` reads as
248
+ *behind* `11.9.2` — wrong on exactly the first release past a `.9` minor. (#208)
249
+ - Three version channels had no writer at all, so `npm test` failed on every bump and
250
+ the documented remedy could not fix it: `mcp-server/server.json` (both keys, matched
251
+ by identifier), `AGENTS.md`, and `sdk/README.md`'s second shape. (#207, #211)
252
+ - **No channel covered a document a user receives.** `SECURITY.md` — the security policy
253
+ at the root of the published package — said "Current version: 11.9.0", and
254
+ getting-started, faq, troubleshooting, user-guide and sdk-reference all titled
255
+ themselves v11.9.0: three releases stale, while every npm manifest was correct.
256
+ `--check` was green throughout, because a channel that does not exist cannot drift.
257
+ Structural markers now track canonical; narrative measurements deliberately do not.
258
+ (#211)
259
+ - A bump is not finished when `sync-version.js` exits. Two tracked artifacts are gated
260
+ against `package.json` and only a build can write them —
261
+ `plugins/mindforge/.claude-plugin/plugin.json` and
262
+ `plugins/mindforge/mcp/dist/index.js`. They are now reported under
263
+ `🔨 REQUIRE A BUILD` with the exact three-command chain, which nothing had documented.
264
+ (#211)
265
+ - `sync-version.js` reported "a channel is AHEAD of canonical" whenever its exit code
266
+ was non-zero for any reason, so the `--fetch-sha` refusal for an unpublished tarball
267
+ claimed the formula LEADS canonical in the same run that printed "DEFERRED until after
268
+ publish (behind, not ahead)". (#211)
269
+ - `changelogs/index.json`, which `bin/updater/changelog-fetcher.js` reads as the
270
+ authoritative version list, was missing 11.9.2. (#218)
271
+
272
+ **Publishing**
273
+
274
+ - **The tag push that publishes was exempt from every gate.** Publishing is triggered by
275
+ exactly one event — a `v*` tag push — and the repository's only ruleset targets
276
+ branches, so its six required checks applied to nothing on the path that ships. GitHub
277
+ cannot attach required status checks to a tag. A `preflight` job now gates it. (#216)
278
+ - The `stable` npm dist-tag was moved by hand, or not at all — it sat three releases
279
+ behind `latest` (11.8.3 against 11.9.2, via 11.9.0 and 11.9.1), so `npm i mindforge-cc@stable` delivered a
280
+ build with none of the 11.9.x fixes. The release workflow now moves it as its final
281
+ step: forward-only, prereleases skipped, and verified against npm's uncached dist-tags
282
+ endpoint rather than the CDN-cached packument. (#216)
283
+
284
+ **Dashboard**
285
+
286
+ - `--status` and `--stop` were documented across the harness roots and the docs and implemented
287
+ nowhere; both
288
+ printed nothing and exited 0. Now implemented, before `express` is required, so they
289
+ work without the dependency installed. (#206)
290
+ - `--stop` identified the target by the SHAPE of its command line, which matched any
291
+ `node <anything>/dashboard/server.js` — verified against
292
+ `node /var/www/unrelated_app/dashboard/server.js`. It now resolves the script's
293
+ realpath and compares it to its own. (#206)
294
+ - `--status` printed a port it could not know: the PID file records only the pid, so it
295
+ reported whatever port that invocation happened to receive. Measured, `--status` on a
296
+ server started with `--port 7466` printed "port 7339". (#206)
297
+
298
+ **Memory**
299
+
300
+ - Every abandoned exit left a full copy of the database on disk — 1.8 GB of orphaned
301
+ `.tmp` files. (#199)
302
+ - The SDK's WebSocket client took the caller's process down on a failed reconnect. (#191)
303
+
304
+ **Verification**
305
+
306
+ - `mindforge verify`'s lint stage used `--max-warnings=0`, which made it impossible to
307
+ pass in the repository it ships from: on a clean clone `npx eslint .` reports 190 problems /
308
+ 0 errors / 190 warnings, so `verify` reported a lint FAILURE on a tree that is green by the
309
+ project's own contract. Aligned with the project's definition; errors still fail. (#204)
310
+ - `temporal cleanup` printed "🧹 Cleaning up old temporal snapshots..." and
311
+ "✅ Cleanup complete." with no cleanup between them. Now wired to
312
+ `TemporalHub.gc({maxSnapshots: 50, maxAgeDays: 30})` with `--dry-run` and honest
313
+ counts, including zero. (#209)
314
+
315
+ **Documentation that named things that do not exist**
316
+
317
+ - The protocol files instructed the agent to run `soul-engine.js` and
318
+ `shard-controller.js`, neither of which exists anywhere in the package. Those steps
319
+ are reasoning protocols and now say so. (#205)
320
+ - Fifteen phantom `/mindforge:` slash commands in shipped docs. A reader following
321
+ `docs/user-guide.md` typed `/mindforge:personas --list` and got nothing. They were not
322
+ typos: `.agent/workflows/` holds 130 tracked files using those exact names — an old
323
+ target layout, committed and orphaned, shipping zero files. (#209)
324
+ - Four documented CLI invocations could not be run, each verified by running it:
325
+ `npx mindforge-cc@latest install` (exit 1), `mindforge-cli.js dashboard` (exit 1),
326
+ `npx mindforge auto` in a shipped engine doc (`auto` is a slash command, never a CLI
327
+ verb), and `@mindforge <verb>`, a syntax that exists nowhere. (#213)
328
+ - `workflow` is the most-documented CLI verb in the project and works, but appeared in
329
+ neither `--help` nor the "Available commands" list, so a user who mistyped it was told
330
+ it does not exist. (#213)
331
+ - Root `CLAUDE.md` named `bin/hooks/mindforge-context-monitor.js`; the file is under
332
+ `.agent/hooks/`. (#214)
333
+
334
+ ### Added
335
+
336
+ - **`preflight` job on the release workflow.** Asserts the tagged commit is an ancestor
337
+ of `origin/main`, then runs the six gates a tag push never saw, with the publish job
338
+ behind `needs:`. (#216)
339
+ - **Automatic `stable` dist-tag movement**, forward-only and verified. (#216)
340
+ - **`node bin/dashboard/server.js --status` / `--stop`.** Not CLI verbs —
341
+ `mindforge-cli.js dashboard` does not route. (#206)
342
+ - **`mindforge temporal cleanup --dry-run`.** (#209)
343
+ - New regression gates, each falsified by mutation before being trusted:
344
+ `tests/protocol-claims.test.js` (no exemption list, deliberately — a name-keyed
345
+ allowlist was shown to excuse the exact defect it was written for), the shipped-doc
346
+ phantom-command gate, the CLI-verb gate, the authority-doc `.js` gate, the
347
+ version-channel round trips, and assertions that the release preflight itself cannot
348
+ be silently removed.
349
+
350
+ ### Notes for operators
351
+
352
+ - `npm run version:check` is the offline drift check. A bump is finished only when
353
+ `sync-version.js` exits 0 — if it prints `🔨 REQUIRE A BUILD`, run the three commands
354
+ it names and commit both regenerated files.
355
+ - Releases are now gated on being tagged from `main`. One residual, inherent to
356
+ tag-triggered workflows: a tag push resolves the workflow from the TAGGED ref, so a
357
+ tag placed on a commit predating this release runs that commit's workflow and is
358
+ ungated.
359
+
3
360
  ## [11.9.2] — 2026-08-16 — Correctness: audit-chain integrity, dashboard crash policy, secret scanning
4
361
 
5
362
  Patch release. No new features. Correctness work closing defects found by a
package/MINDFORGE.md CHANGED
@@ -1,9 +1,9 @@
1
- # MINDFORGE.md — Parameter Registry (v11.9.2)
1
+ # MINDFORGE.md — Parameter Registry (v11.9.4)
2
2
 
3
3
  ## 1. IDENTITY & VERSIONING
4
4
 
5
5
  [NAME] = MindForge
6
- [VERSION] = 11.9.2
6
+ [VERSION] = 11.9.4
7
7
  [STABLE] = true
8
8
  [MODE] = "Platform Sovereign"
9
9
  [REQUIRED_CORE_VERSION] = 11.9.1
@@ -98,8 +98,15 @@
98
98
  The following parameters cannot be overridden by plugins, agents, or session-level configuration:
99
99
 
100
100
  - [MIN_SOUL_SCORE] — Minimum SOUL score required for architectural changes
101
- - [BLOCK_ON_SECURITY] — Security gate enforcement cannot be disabled
102
- - [COST_HARD_LIMIT_USD] — declared here, but **NOT enforced as of 11.9.2**; do not rely on it as a spend control. `bin/models/cost-tracker.js` reads `MODEL_COST_HARD_LIMIT_USD`, a key this registry does not declare, so `preflight()` returns early and no cap is ever applied. Wiring it is tracked as COST-02 for 11.9.3
101
+ - [BLOCK_ON_SECURITY] — DECLARED, UNREAD. `git grep -l BLOCK_ON_SECURITY -- bin/` returns nothing:
102
+ no code reads this key, so it changes no behaviour and deleting it fails no validation (the schema
103
+ lists it as `recommended`, not `required`). What actually blocks a config-weakening edit is the
104
+ `mindforge-config-protection` hook, which is deny-class and fails closed — see SECURITY.md.
105
+ - [COST_HARD_LIMIT_USD] — **enforced as of 11.9.3** (COST-02). `bin/models/cost-tracker.js` `preflight()` reads this key, adds the call estimate to today's ledger spend, and throws `COST_LIMIT_REACHED`; `bin/models/model-client.js` re-throws it, so the model call is refused. Non-overridable means a plugin or session cannot raise the number — it does not mean a cap always exists: `0`, or the key being absent, legally disables the cap, because an upgrade never rewrites an existing MINDFORGE.md (`bin/installer-core.js:706`) and the schema lists this key as `recommended`, not `required`. A present-but-unreadable value (e.g. `= none`) is a hard config fault — `preflight()` throws `COST_LIMIT_MISCONFIGURED` instead of running uncapped
103
106
  - [BLOCK_ON_SECURITY] is non-overridable; PQAS itself is simulated/experimental (inactive by default) and is NOT a non-overridable guarantee — do not rely on it as an enforced control
104
- - [SOVEREIGN_IDENTITY] — Identity verification is always required
105
- - [ENABLE_ZTAI] Zero-trust identity cannot be bypassed
107
+ - [SOVEREIGN_IDENTITY] — DECLARED, UNREAD. No reader in `bin/`. No identity is verified as a result
108
+ of this key being set.
109
+ - [ENABLE_ZTAI] — DECLARED, UNREAD, and the feature it gates is inactive. No reader in `bin/`;
110
+ measured on a live 3116-entry AUDIT.jsonl, 0 entries carry a `signature` or `did`. "Cannot be
111
+ bypassed" overstates a switch that is not wired to anything — see docs/security/ZTAI-OVERVIEW.md,
112
+ which now leads with a status banner.
package/README.md CHANGED
@@ -6,11 +6,14 @@
6
6
 
7
7
  ## Latest release
8
8
 
9
- **v11.9.2** (2026-08-16) — Correctness: the config gate can now fail, the audit chain no longer
10
- forks under concurrent writers, trace retrieval works, and the cost ledger has one record shape.
11
- **Contains a breaking change to the dashboard HTTP surface** (loopback-only) see the BREAKING
12
- section in [CHANGELOG.md](./CHANGELOG.md), or [RELEASENOTES.md](./RELEASENOTES.md) for
13
- human-readable notes.
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.
14
17
 
15
18
  ---
16
19
 
@@ -19,7 +22,8 @@ human-readable notes.
19
22
  Read this before the install instructions. MindForge ships a large corpus of agent
20
23
  instructions — commands, skills, personas, protocols — and those are advisory: they work by
21
24
  being in the model's context, and a model can decline them. The parts that would *block* an
22
- action are hooks, and **no install channel currently registers them.**
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.
23
27
 
24
28
  | Capability | Plugin channel | `npx` channel |
25
29
  |---|---|---|
@@ -27,34 +31,48 @@ action are hooks, and **no install channel currently registers them.**
27
31
  | Skills / personas / protocol docs | Yes | Yes |
28
32
  | Subagents | Yes | Yes |
29
33
  | Audit hash-chain (`bin/verify-audit.js`) | Yes | Yes |
30
- | **Hooks enforced (can block a tool call)** | **No** | **No** |
31
-
32
- Why, specifically:
33
-
34
- - **No hook configuration ships, and nothing generates one.** `package.json` `files[]` has 47
35
- entries and none contains `settings`, so neither `.claude/settings.json` nor
36
- `.agent/settings.json` is published. All references to those paths in `bin/` are reads or
37
- metadata strings there is no code that writes or merges one. `bin/harness-audit.js:335`
38
- even offers "wire trust-gate + block-no-verify into both …" as a *fix suggestion*, auditing a
39
- wiring nothing creates.
40
- - **The plugin channel's hooks additionally crash when fired.**
41
- `plugins/mindforge/scripts/run-with-flags.js:24` requires `./lib/hook-flags`, and
42
- `plugins/mindforge/scripts/lib/` does not exist in the published plugin. Running the
43
- dispatcher gives `Error: Cannot find module './lib/hook-flags'` and exit 1. The module it
44
- needs does exist at `.agent/hooks/lib/hook-flags.js`; it was never copied in.
45
-
46
- So treat MindForge as **governance-by-convention plus a tamper-evident audit log**, not as a
47
- policy enforcement point. Installing it also expands your repository's trust boundary by a large
48
- volume of agent instructions review what you install. Making hook registration real per
49
- harness is the headline goal of v12; the audit chain is genuinely verifiable today
34
+ | **Hooks enforced (can block a tool call)** | **Claude Code only** | **Claude Code + `--local` only** |
35
+
36
+ What that means, measured rather than asserted:
37
+
38
+ - **The `npx` channel generates the config it never used to ship.** `files[]` has 49 entries and
39
+ none of them contains `settings`, so no settings file is *published* — instead
40
+ `bin/installer/hook-registration.js` writes one at install time, merging append-only into any
41
+ file you already have. Measured on a confined install: **8 hooks registered** into
42
+ `.claude/settings.json`, of which the installer's own preflight **executed 7 and verified all 3
43
+ deny-class hooks returning exit 2** before keeping the file. A preflight failure rolls the
44
+ registration back rather than leaving a config whose commands do not run.
45
+ - **The plugin channel's dispatcher runs.** It previously crashed on every fire —
46
+ `run-with-flags.js` requires `./lib/hook-flags` and `plugins/mindforge/scripts/lib/` was not
47
+ copied in. That directory now exists, all **14 path tokens** in
48
+ `plugins/mindforge/hooks/hooks.json` resolve under the plugin root, and driving the dispatcher by
49
+ hand returns **exit 2** for `mindforge-block-no-verify` and `mindforge-config-protection`.
50
+
51
+ Still **not** enforced, deliberately and with a printed reason for each: any runtime other than
52
+ Claude Code (Cursor, Copilot, Gemini/Antigravity, OpenCode), `--global` scope, a self-install
53
+ inside a MindForge checkout, and Windows. Writing a Claude-schema config into `.cursor/` without an
54
+ execution-verified hook contract would be decorative. Every outcome, including "not registered", is
55
+ printed by the installer and written to `.mindforge/hook-registration.json`.
56
+
57
+ Three things gate whether a registered hook is *live*, none of them in MindForge's control: the
58
+ harness must be **restarted** (hooks are snapshotted at session start), the project must be
59
+ **trusted** in the harness, and `CLAUDE_PROJECT_DIR` must be set with `node` on the hook PATH —
60
+ if it is not, the commands exit 1 and the gate is simply absent, which is a deliberate trade
61
+ against a fail-closed tail that was measured denying benign commands on a fresh clone. See
62
+ *Hooks are installed but nothing is blocked* in `docs/troubleshooting.md`.
63
+
64
+ So: on Claude Code, treat MindForge as a policy enforcement point for the 8 registered hooks plus
65
+ a tamper-evident audit log; on every other harness, as **governance-by-convention** plus that same
66
+ audit log. Installing it also expands your repository's trust boundary by a large volume of agent
67
+ instructions — review what you install. The audit chain is verifiable today
50
68
  (`node bin/verify-audit.js`).
51
69
 
52
70
  ---
53
71
 
54
72
  ## Install
55
73
 
56
- Claude Code plugin marketplace (no project files written). **Note:** the plugin's hooks do not
57
- fire — see *What is actually enforced* above. Slash commands, skills and subagents do work.
74
+ Claude Code plugin marketplace (no project files written). The plugin's hooks now fire — see
75
+ *What is actually enforced* above for what that does and does not cover.
58
76
 
59
77
  ```bash
60
78
  /plugin marketplace add sairam0424/MindForge
@@ -72,8 +90,9 @@ All install channels (global, local, Antigravity, Cursor, Copilot, Gemini CLI, M
72
90
  **Upgrading from 11.9.x?** The installer does not overwrite an existing
73
91
  `.mindforge/MINDFORGE-SCHEMA.json`, so 11.9.2's armed config validator keeps the older
74
92
  permissive schema on a plain upgrade. Run with `--force` if you want the stricter gate. The
75
- daily cost cap declared as `[COST_HARD_LIMIT_USD]` in `MINDFORGE.md` is **not enforced** in
76
- 11.9.2 see the CHANGELOG.
93
+ daily cost cap declared as `[COST_HARD_LIMIT_USD]` in `MINDFORGE.md` was **not enforced** in
94
+ 11.9.2; 11.9.3 arms it. An upgrade never rewrites an existing `MINDFORGE.md`, so if yours
95
+ predates the key the cap stays off — add `[COST_HARD_LIMIT_USD] = 25.00` to turn it on.
77
96
 
78
97
  ---
79
98
 
package/RELEASENOTES.md CHANGED
@@ -1,5 +1,68 @@
1
1
  # Release Notes
2
2
 
3
+ ## v11.9.3 — 2026-08-21 — Honesty: gates that can fail, commands that run, a release path that is checked
4
+
5
+ ### What's New
6
+ Nothing. Twenty-one fixes sharing a single defect: **an instrument reported success while doing
7
+ nothing.** Gates that could not fail, tests a comment satisfied, docs naming scripts that do not
8
+ exist, commands printing success while performing no action, and a publish path no check ever
9
+ touched.
10
+
11
+ ### ⚠️ Breaking (under a patch bump)
12
+ Six behaviour changes, each a bug fix whose correct behaviour differs from what shipped. Read these
13
+ if you script against the CLI or the installer.
14
+
15
+ - **Routed CLI commands now act on YOUR project, not MindForge's checkout.** The router passed
16
+ `cwd: ROOT`, so `mindforge classify` diffed MindForge's repository instead of yours and
17
+ `mindforge health` inspected MindForge's `node_modules`. Of 27 routed commands, 7 changed
18
+ behaviour — all in the correct direction.
19
+ - **`npx mindforge-cc install`, and any other positional argument, now exits 1.** The installer
20
+ takes flags only and used to ignore stray words silently, so that command appeared to work while
21
+ configuring nothing. Use `npx mindforge-cc --claude --local`.
22
+ - **`mindforge verify` now SKIPS unavailable stages instead of failing them.** A project with no
23
+ ESLint config or no test script was reported as FAILING those stages rather than as not having
24
+ them. CI that relied on a non-zero exit there will now pass. A run where every stage skipped
25
+ prints a "NOTHING WAS VERIFIED" banner rather than a clean bill of health.
26
+ - **`scripts/sync-version.js` now exits non-zero when the plugin build artifacts are stale.** A bump
27
+ used to report success and exit 0 while leaving `npm test` red.
28
+ - **A self-install no longer writes over your tracked files.** Running the installer inside a
29
+ MindForge checkout printed that it was skipping and then overwrote 149 tracked files, including
30
+ `CLAUDE.md`, `.claude/**`, `.agent/**` and `.mindforge/**`.
31
+ - **Releases must be tagged on a commit reachable from `main`.**
32
+
33
+ ### Fixes
34
+ - **11 of 27 routed CLI verbs died on `MODULE_NOT_FOUND` in a real install.** The router shipped;
35
+ six of the scripts it dispatches to did not.
36
+ - **Every `--global` install reported failure on a correct run.** Verification demanded six `bin/**`
37
+ paths regardless of scope, so a global install — which writes 389 files to `$HOME/.claude` and,
38
+ deliberately, zero to `bin/` — ended `6 of 12 required file(s) missing` and exit 1, with a
39
+ `--force` retry that could not help.
40
+ - **`--fetch-sha` hashed npm's 404 error body into the Homebrew formula.** For an unpublished
41
+ version the registry answers `{"error":"Not found"}` and `curl -sL` exits 0, so the digest written
42
+ was the SHA-256 of that error text — the same constant for every unpublished version — and
43
+ `--check` then passed. It now fails closed on both status and gzip magic bytes.
44
+ - **No version channel covered a document a user receives.** `SECURITY.md` — the security policy at
45
+ the root of the published package — said "Current version: 11.9.0", and five docs titled
46
+ themselves v11.9.0: three releases stale while every npm manifest was correct. A channel that does
47
+ not exist cannot drift, so `--check` was green the whole time.
48
+ - **The tag push that publishes was exempt from every gate.** Publishing is triggered by exactly one
49
+ event — a `v*` tag push — and the repository's only ruleset targets branches, so its six required
50
+ checks applied to nothing on the path that ships. GitHub cannot attach required status checks to a
51
+ tag, so this had to be fixed in the workflow itself.
52
+ - **The `stable` dist-tag sat three releases behind `latest`** (11.8.3 against 11.9.2), so
53
+ `npm i mindforge-cc@stable` delivered a build with none of the 11.9.x fixes. The release workflow
54
+ now moves it as its final step — forward-only, prereleases skipped.
55
+ - **`mindforge dashboard --status` and `--stop` were documented and implemented nowhere.** Both
56
+ printed nothing useful. `--stop` also identified its target by the SHAPE of a command line, which
57
+ matched any `node <anything>/dashboard/server.js` — verified against an unrelated app's dashboard.
58
+ - **`temporal cleanup` printed "Cleaning up…" and "Cleanup complete." with no cleanup between them.**
59
+ - **The protocol files instructed the agent to run scripts that do not exist** (`soul-engine.js`,
60
+ `shard-controller.js`), and 15 phantom `/mindforge:` slash commands appeared in shipped docs. A
61
+ reader following the user guide typed `/mindforge:personas --list` and got nothing.
62
+ - **Every abandoned exit left a full copy of the database on disk** — 1.8 GB of orphaned `.tmp` files.
63
+
64
+ Full detail, including the measured evidence for each: [changelogs/v11.9.3.md](./changelogs/v11.9.3.md).
65
+
3
66
  ## v11.9.2 — 2026-08-16 — Correctness: config gate, audit chain, retrieval, cost ledger
4
67
 
5
68
  ### What's New
@@ -622,7 +685,7 @@ You must address these before upgrading from v9.x:
622
685
  |--------|--------|-----------|
623
686
  | `better-sqlite3` removed, replaced by `sql.js` | If you imported or extended VectorHub internals, the constructor API has changed | Use `createVectorHub()` factory function instead of `new VectorHub()` |
624
687
  | VectorHub uses FTS4 (not FTS5) | FTS5-specific syntax (e.g., `BM25`) no longer available | Use standard FTS4 `MATCH` queries; ranking is handled internally |
625
- | SDK `memory.ts` rewritten | If you imported memory utilities from `../../bin/` paths, those imports no longer resolve | Import from `@mindforge/sdk` directly — all public APIs are re-exported |
688
+ | SDK `memory.ts` rewritten | If you imported memory utilities from `../../bin/` paths, those imports no longer resolve | Import from `mindforge-sdk` directly — all public APIs are re-exported |
626
689
  | Dashboard endpoints require auth | Unauthenticated requests to `/api/steering`, `/api/approve`, and SSE mutators now return 401 | Set `MINDFORGE_DASHBOARD_TOKEN` env var; pass as `Authorization: Bearer <token>` |
627
690
  | `sync-jira` / `sync-confluence` CLI routes removed | These were stubs with no implementation | Remove any scripts that invoke these commands |
628
691
  | Prompt injection blocklist removed | The regex-based `BLOCKED_PATTERNS` array no longer exists | Use the structured action allowlist in `bin/governance/action-allowlist.js` |
@@ -714,7 +777,7 @@ The database file format is compatible. No data migration is required.
714
777
  import { MemoryStore } from '../../bin/memory/store';
715
778
 
716
779
  // After (v10) — public SDK exports
717
- import { MemoryStore } from '@mindforge/sdk';
780
+ import { MemoryStore } from 'mindforge-sdk';
718
781
  ```
719
782
 
720
783
  ### Step 5: Remove references to deleted commands