mindforge-cc 11.9.1 → 11.9.3
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/.agent/CLAUDE.md +37 -13
- package/.agent/hooks/mindforge-block-no-verify.js +61 -13
- package/.agent/hooks/mindforge-config-protection.js +82 -3
- package/.agent/hooks/mindforge-context-monitor.js +1 -1
- package/.agent/hooks/mindforge-workflow-guard.js +2 -2
- package/.agent/hooks/run-with-flags.js +190 -20
- package/.agent/mindforge/browse.md +2 -2
- package/.agent/mindforge/checkpoint.md +1 -1
- package/.agent/mindforge/consult.md +1 -1
- package/.agent/mindforge/cost-report.md +1 -1
- package/.agent/mindforge/harness-audit.md +1 -1
- package/.agent/mindforge/orch-add-feature.md +1 -1
- package/.agent/mindforge/orch-build-mvp.md +1 -1
- package/.agent/mindforge/orch-change-feature.md +1 -1
- package/.agent/mindforge/orch-fix-defect.md +1 -1
- package/.agent/mindforge/orch-refine-code.md +1 -1
- package/.agent/mindforge/qa.md +2 -2
- package/.claude/CLAUDE.md +37 -13
- package/.claude/commands/mindforge/browse.md +2 -2
- package/.claude/commands/mindforge/checkpoint.md +1 -1
- package/.claude/commands/mindforge/consult.md +1 -1
- package/.claude/commands/mindforge/cost-report.md +1 -1
- package/.claude/commands/mindforge/harness-audit.md +1 -1
- package/.claude/commands/mindforge/orch-add-feature.md +1 -1
- package/.claude/commands/mindforge/orch-build-mvp.md +1 -1
- package/.claude/commands/mindforge/orch-change-feature.md +1 -1
- package/.claude/commands/mindforge/orch-fix-defect.md +1 -1
- package/.claude/commands/mindforge/orch-refine-code.md +1 -1
- package/.claude/commands/mindforge/qa.md +2 -2
- package/.mindforge/MINDFORGE-SCHEMA.json +126 -13
- package/.mindforge/config.json +4 -4
- package/.mindforge/engine/autonomous/headless-adapter.md +2 -2
- package/.mindforge/engine/cost-tracking/router.md +1 -1
- package/.mindforge/engine/cost-tracking/token-ledger.md +21 -24
- package/.mindforge/engine/temporal-protocol.md +2 -2
- package/.mindforge/governance/change-classifier.md +20 -4
- package/.mindforge/memory/sync-manifest.json +1 -1
- package/.mindforge/metrics/METRICS-SCHEMA.md +13 -4
- package/.mindforge/personas/cost-optimizer.md +2 -2
- package/.mindforge/personas/multi-model-bridge.md +1 -1
- package/.mindforge/skills/agent-architecture-audit/SKILL.md +2 -2
- package/.mindforge/skills/cost-aware-routing/SKILL.md +3 -3
- package/.mindforge/skills/multi-llm-consult/SKILL.md +2 -2
- package/.mindforge/skills/orch-pipeline/SKILL.md +4 -4
- package/CHANGELOG.md +402 -0
- package/MINDFORGE.md +13 -6
- package/README.md +51 -2
- package/RELEASENOTES.md +55 -2
- package/SECURITY.md +22 -3
- package/bin/autonomous/audit-writer.js +48 -33
- package/bin/autonomous/auto-runner.js +65 -2
- package/bin/change-classifier.js +151 -16
- package/bin/dashboard/api-router.js +28 -47
- package/bin/dashboard/error-response.js +44 -0
- package/bin/dashboard/frontend/app.js +429 -0
- package/bin/dashboard/frontend/index.html +14 -390
- package/bin/dashboard/metrics-aggregator.js +75 -30
- package/bin/dashboard/revops-api.js +12 -2
- package/bin/dashboard/server.js +245 -6
- package/bin/dashboard/sse-bridge.js +11 -8
- package/bin/dashboard/temporal-api.js +11 -5
- package/bin/engine/remediation-engine.js +12 -1
- package/bin/engine/sre-manager.js +1 -1
- package/bin/engine/temporal-cli.js +56 -6
- package/bin/engine/temporal-hub.js +41 -9
- package/bin/engine/verification-runner.js +134 -17
- package/bin/engine/verify-cli.js +25 -7
- package/bin/eval/eval-harness.js +212 -1
- package/bin/eval/golden-set-retrieval.json +9 -0
- package/bin/governance/approval-record.js +147 -0
- package/bin/governance/approve.js +12 -7
- package/bin/governance/policy-engine.js +41 -3
- package/bin/governance/policy-gate-hardened.js +36 -1
- package/bin/governance/verify-approvals.js +163 -0
- package/bin/harness-audit.js +224 -10
- package/bin/hindsight-injector.js +8 -2
- package/bin/hooks/instinct-capture-hook.js +19 -5
- package/bin/install.js +63 -3
- package/bin/installer/harness-adapter-compliance.js +339 -28
- package/bin/installer/hook-registration.js +504 -0
- package/bin/installer-core.js +451 -63
- package/bin/learning/instinct-cli.js +14 -24
- package/bin/memory/knowledge-capture.js +23 -3
- package/bin/memory/knowledge-graph.js +70 -31
- package/bin/memory/vector-hub.js +500 -44
- package/bin/migrations/0.6.0-to-1.0.0.js +30 -25
- package/bin/migrations/1.0.0-to-2.0.0.js +22 -23
- package/bin/mindforge-cli.js +110 -17
- package/bin/models/cost-tracker.js +126 -29
- package/bin/models/model-client.js +6 -1
- package/bin/models/model-router.js +28 -7
- package/bin/models/usage-record.js +71 -0
- package/bin/revops/debt-monitor.js +57 -13
- package/bin/security/trust-gate-hook.js +50 -6
- package/bin/skill-validator.js +6 -1
- package/bin/skills-builder/skill-scorer.js +46 -6
- package/bin/updater/self-update.js +6 -1
- package/bin/updater/version-comparator.js +21 -1
- package/bin/utils/file-lock.js +106 -0
- package/bin/utils/mindforge-params.js +124 -0
- package/bin/utils/mindforge-version.js +99 -0
- package/bin/utils/redact-secrets.js +106 -0
- package/bin/validate-config.js +75 -17
- package/bin/wizard/setup-wizard.js +4 -1
- package/bin/wizard/theme.js +9 -1
- package/changelogs/index.json +11 -9
- package/changelogs/v11.9.2.md +209 -0
- package/changelogs/v11.9.3.md +195 -0
- package/docs/References/config-reference.md +76 -14
- package/docs/References/sdk-api.md +1 -1
- package/docs/Templates/Codebase/architecture.md +1 -1
- package/docs/commands-reference.md +4 -5
- package/docs/faq.md +25 -5
- package/docs/getting-started.md +3 -3
- package/docs/sdk-reference.md +15 -7
- package/docs/troubleshooting.md +10 -6
- package/docs/user-guide.md +14 -14
- package/examples/sdk-integration/README.md +1 -1
- package/package.json +10 -4
- package/subagents/.claude-plugin/marketplace.json +1 -1
- package/bin/dashboard/approval-handler.js +0 -136
|
@@ -44,9 +44,25 @@ Scan the actual diff content, not only filenames, for patterns such as:
|
|
|
44
44
|
This protects against security-critical code being added to innocuous filenames
|
|
45
45
|
like `src/utils/helper.ts`.
|
|
46
46
|
|
|
47
|
-
### Signal C — AUDIT history patterns
|
|
48
|
-
|
|
49
|
-
change in that phase is elevated to Tier 3
|
|
47
|
+
### Signal C — AUDIT history patterns (SPECIFIED, NOT IMPLEMENTED)
|
|
48
|
+
Intended behaviour: if the current phase has a recent HIGH or CRITICAL
|
|
49
|
+
`security_finding`, the next change in that phase is elevated to Tier 3
|
|
50
|
+
automatically.
|
|
51
|
+
|
|
52
|
+
**This signal does not exist in `bin/change-classifier.js`.** It is recorded here
|
|
53
|
+
as a design intent, not as a live protection, because it would read from
|
|
54
|
+
`.planning/AUDIT.jsonl` — which is gitignored (`.gitignore:81`), untracked, and
|
|
55
|
+
absent from `package.json` `files[]`. That file therefore does not exist in the
|
|
56
|
+
fresh clone the classifier actually runs in
|
|
57
|
+
(`.github/workflows/control-plane.yml`). Implementing it against a source that is
|
|
58
|
+
structurally unavailable at the point of enforcement would produce a signal that
|
|
59
|
+
silently never fires — the same defect class as the Signal B gap above, where 13
|
|
60
|
+
of the 19 documented patterns were specified and absent.
|
|
61
|
+
|
|
62
|
+
The `security_finding` event itself is real and carries `severity`: see
|
|
63
|
+
`bin/dashboard/metrics-aggregator.js:160` and `bin/revops/debt-monitor.js:23`,
|
|
64
|
+
both of which read it from a local audit log. Enabling Signal C needs a decision
|
|
65
|
+
about how phase history reaches CI, not merely classifier code.
|
|
50
66
|
|
|
51
67
|
## Classification audit entry
|
|
52
68
|
Record why the tier was selected:
|
|
@@ -56,7 +72,7 @@ Record why the tier was selected:
|
|
|
56
72
|
"event": "change_classified",
|
|
57
73
|
"tier": 3,
|
|
58
74
|
"classification_reason": "code pattern: jwt.sign found in src/utils/helper.ts",
|
|
59
|
-
"signals_checked": ["file_path", "code_content"
|
|
75
|
+
"signals_checked": ["file_path", "code_content"],
|
|
60
76
|
"signal_triggered": "code_content",
|
|
61
77
|
"pattern_matched": "jwt.sign"
|
|
62
78
|
}
|
|
@@ -1,13 +1,22 @@
|
|
|
1
1
|
# MindForge Metrics — Schema Reference
|
|
2
2
|
|
|
3
3
|
## Files
|
|
4
|
-
- `session-quality.jsonl`
|
|
5
|
-
- `
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
- `session-quality.jsonl` — **no producer in this repo**; every reference to it
|
|
5
|
+
(`bin/dashboard/metrics-aggregator.js`, `sdk/src/client.ts`,
|
|
6
|
+
`mcp-server/src/vendor/client.ts`) is a READ. Expected to be supplied by the
|
|
7
|
+
agent/host; MindForge only consumes it.
|
|
8
|
+
- `phase-metrics.jsonl` — no producer in this repo
|
|
9
|
+
- `skill-usage.jsonl` — no producer in this repo
|
|
10
|
+
- `compaction-quality.jsonl` — no producer in this repo
|
|
11
|
+
- `token-usage.jsonl` — **code-written** by `bin/models/cost-tracker.js`; canonical
|
|
12
|
+
shape is `bin/models/usage-record.js`. Cost lives in `cost_usd` and nowhere else.
|
|
13
|
+
Gitignored and excluded from the npm tarball.
|
|
8
14
|
|
|
9
15
|
All files are append-only JSONL.
|
|
10
16
|
|
|
17
|
+
Per-session cost is NOT a `session-quality.jsonl` field: the dashboard joins it
|
|
18
|
+
from `token-usage.jsonl` on `session_id`.
|
|
19
|
+
|
|
11
20
|
## session-quality.jsonl fields
|
|
12
21
|
- session_id, date, phase, developer_id
|
|
13
22
|
- tasks_attempted, tasks_completed, tasks_failed
|
|
@@ -39,7 +39,7 @@ Map score to model tier via the routing decision matrix.
|
|
|
39
39
|
</step>
|
|
40
40
|
|
|
41
41
|
<step name="check_budget">
|
|
42
|
-
Read token-
|
|
42
|
+
Read token-usage.jsonl for current session/project spend.
|
|
43
43
|
Compare against budget limits in config.json.
|
|
44
44
|
If approaching warn threshold: flag to user.
|
|
45
45
|
</step>
|
|
@@ -66,6 +66,6 @@ Recommend routing adjustments for next session.
|
|
|
66
66
|
- NEVER skip security overrides to save money (auth/payment always >= standard tier)
|
|
67
67
|
- NEVER exceed hard budget limit without explicit user approval
|
|
68
68
|
- NEVER silently downgrade model quality — always inform
|
|
69
|
-
- Track every model interaction in token-
|
|
69
|
+
- Track every model interaction in token-usage.jsonl
|
|
70
70
|
- Report cost transparency in every session summary
|
|
71
71
|
</critical_rules>
|
|
@@ -82,5 +82,5 @@ Report to user with:
|
|
|
82
82
|
- ALWAYS attribute responses to their source model
|
|
83
83
|
- Maximum 2000 tokens per external prompt (cost control)
|
|
84
84
|
- Maximum 3 consultations per session (rate limiting)
|
|
85
|
-
- Log every external call in token-
|
|
85
|
+
- Log every external call in token-usage.jsonl
|
|
86
86
|
</critical_rules>
|
|
@@ -79,7 +79,7 @@ audit has a real target, not an abstraction.
|
|
|
79
79
|
| 9 | Answer shaping | SWARM-SUMMARY consolidation | Format corruption in the final response |
|
|
80
80
|
| 10 | Platform rendering | Dashboard (localhost:7339) / CLI / API transport | Transport-layer mutation of a valid answer |
|
|
81
81
|
| 11 | Hidden repair loops | soul-engine ADS rewrite + Temporal hindsight regeneration | Silent fallback/retry running a second LLM pass |
|
|
82
|
-
| 12 | Persistence | auto-state.json +
|
|
82
|
+
| 12 | Persistence | auto-state.json + hash-chained audit log | Expired state or cached artifacts reused as live evidence |
|
|
83
83
|
|
|
84
84
|
### Common Failure Patterns
|
|
85
85
|
|
|
@@ -148,7 +148,7 @@ Define what you're auditing:
|
|
|
148
148
|
Gather evidence from the codebase:
|
|
149
149
|
- **Source code** — swarm loop, hooks_route tool router, shard admission, prompt
|
|
150
150
|
assembly across the source-of-truth hierarchy
|
|
151
|
-
- **Logs** — NexusTracer session traces,
|
|
151
|
+
- **Logs** — NexusTracer session traces, hash-chained AUDIT entries, tool-call
|
|
152
152
|
records
|
|
153
153
|
- **Config** — MINDFORGE.md parameters, tool schemas, PersonaFactory patches,
|
|
154
154
|
provider settings
|
|
@@ -62,7 +62,7 @@ for cost-performance tradeoffs, or when budget limits are approaching.
|
|
|
62
62
|
### Budget Monitoring
|
|
63
63
|
|
|
64
64
|
Check budget status regularly:
|
|
65
|
-
- Session budget remaining: from token-
|
|
65
|
+
- Session budget remaining: from token-usage.jsonl
|
|
66
66
|
- Warning threshold: `[COST_WARN_USD]` from config
|
|
67
67
|
- Hard limit: `[COST_HARD_LIMIT_USD]` from config
|
|
68
68
|
|
|
@@ -72,12 +72,12 @@ Check budget status regularly:
|
|
|
72
72
|
- Never exceed hard limit without explicit user approval
|
|
73
73
|
|
|
74
74
|
### After any task
|
|
75
|
-
- Log actual model used + tokens consumed to token-
|
|
75
|
+
- Log actual model used + tokens consumed to token-usage.jsonl
|
|
76
76
|
- Compare actual vs optimal tier (for future routing accuracy)
|
|
77
77
|
- Report cost in session summary
|
|
78
78
|
|
|
79
79
|
## Self-check before task completion
|
|
80
80
|
- [ ] Did I log the model routing decision with rationale?
|
|
81
|
-
- [ ] Did I record actual token usage in token-
|
|
81
|
+
- [ ] Did I record actual token usage in token-usage.jsonl?
|
|
82
82
|
- [ ] Did I check remaining budget against session/project limits?
|
|
83
83
|
- [ ] Did I flag any tasks where a cheaper model could have been used?
|
|
@@ -57,7 +57,7 @@ multiple AI providers, or when the user explicitly requests cross-model consulta
|
|
|
57
57
|
```
|
|
58
58
|
|
|
59
59
|
### During consultation
|
|
60
|
-
- Log every external call in token-
|
|
60
|
+
- Log every external call in token-usage.jsonl (model, tokens, cost)
|
|
61
61
|
- Never send more than 2000 tokens to external models per consultation
|
|
62
62
|
- If a model is unavailable: skip it, note in output, continue with available models
|
|
63
63
|
- Respect rate limits — max 3 consultations per session
|
|
@@ -70,6 +70,6 @@ multiple AI providers, or when the user explicitly requests cross-model consulta
|
|
|
70
70
|
|
|
71
71
|
## Self-check before task completion
|
|
72
72
|
- [ ] Did I sanitize the prompt before sending to external models?
|
|
73
|
-
- [ ] Did I log every external call in token-
|
|
73
|
+
- [ ] Did I log every external call in token-usage.jsonl?
|
|
74
74
|
- [ ] Did I attribute responses to their source model (no unattributed blending)?
|
|
75
75
|
- [ ] Did I remind the user that external opinions are advisory?
|
|
@@ -128,7 +128,7 @@ Each phase delegates — it does not do the work inline.
|
|
|
128
128
|
and `security-auditor` / `penetration-tester` whenever the diff touches a
|
|
129
129
|
security trigger.
|
|
130
130
|
- **6. Commit** — conventional commits (`feat:` / `fix:` / `refactor:` / …), one
|
|
131
|
-
per logical chunk, **+ a
|
|
131
|
+
per logical chunk, **+ a hash-chained AUDIT.jsonl entry per commit**. → **GATE 2.**
|
|
132
132
|
|
|
133
133
|
---
|
|
134
134
|
|
|
@@ -166,7 +166,7 @@ This family is **gated, not autonomous**:
|
|
|
166
166
|
work, the manual security overhead is completed here before approval.
|
|
167
167
|
2. **GATE 2 — before Commit.** Present the diff summary and proposed conventional
|
|
168
168
|
commit messages; do not commit until the user confirms. Each confirmed commit
|
|
169
|
-
writes a
|
|
169
|
+
writes a hash-chained AUDIT.jsonl entry (below).
|
|
170
170
|
|
|
171
171
|
Everything between the gates flows without stopping.
|
|
172
172
|
|
|
@@ -227,7 +227,7 @@ On user confirmation at Gate 2, for **each** logical commit:
|
|
|
227
227
|
|
|
228
228
|
1. Commit with a **conventional** message scoped to one logical change:
|
|
229
229
|
`feat(<scope>): …` / `fix(<scope>): …` / `refactor(<scope>): …` / etc.
|
|
230
|
-
2. Append a **
|
|
230
|
+
2. Append a **hash-chained** AUDIT.jsonl entry to `.planning/AUDIT.jsonl`. Each
|
|
231
231
|
entry sets `previous_hash` to the prior entry's `_hash` and computes its own
|
|
232
232
|
`_hash` (per `.mindforge/audit/AUDIT-SCHEMA.md`):
|
|
233
233
|
|
|
@@ -263,7 +263,7 @@ On user confirmation at Gate 2, for **each** logical commit:
|
|
|
263
263
|
security trigger was touched; `/mindforge:security-scan` passed PRE-COMMIT
|
|
264
264
|
with no unaddressed Medium+ findings.
|
|
265
265
|
- [ ] Commits are conventional and scoped to one logical change.
|
|
266
|
-
- [ ] Each commit wrote a
|
|
266
|
+
- [ ] Each commit wrote a hash-chained AUDIT.jsonl entry (`previous_hash`/`_hash`).
|
|
267
267
|
- [ ] New / changed behavior has tests; coverage ≥ 80%.
|
|
268
268
|
|
|
269
269
|
---
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,407 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [11.9.3] — 2026-08-21 — Honesty: gates that can fail, commands that run, a release path that is checked
|
|
4
|
+
|
|
5
|
+
Patch release. No new features. Twenty-one fixes, and they all turned out to be the
|
|
6
|
+
same defect: **an instrument reported success while doing nothing.** Gates that could
|
|
7
|
+
not fail, tests satisfied by a comment, docs describing capabilities with no code
|
|
8
|
+
behind them, commands printing success while performing no action, and a publish path
|
|
9
|
+
that no check ever touched.
|
|
10
|
+
|
|
11
|
+
Contains behaviour changes under a patch bump — several of the things being fixed were
|
|
12
|
+
bugs that a consumer could have been relying on. Read BREAKING before upgrading if you
|
|
13
|
+
script against the CLI or the installer.
|
|
14
|
+
|
|
15
|
+
### BREAKING
|
|
16
|
+
|
|
17
|
+
Each of these is a bug fix whose correct behaviour differs from the shipped behaviour.
|
|
18
|
+
|
|
19
|
+
- **Routed CLI commands now act on YOUR project, not MindForge's own checkout.**
|
|
20
|
+
`bin/mindforge-cli.js` passed `cwd: ROOT` to every routed command, so `mindforge
|
|
21
|
+
classify` diffed MindForge's repository instead of yours, and `mindforge health`
|
|
22
|
+
inspected MindForge's `node_modules`. Measured across all 27 routed commands: 7
|
|
23
|
+
changed behaviour, all in the correct direction, none regressed. If you parsed output
|
|
24
|
+
that happened to describe MindForge itself, it now describes your project. (#201)
|
|
25
|
+
|
|
26
|
+
- **`npx mindforge-cc install` — and any other positional argument — now exits 1.**
|
|
27
|
+
The installer takes flags only and silently ignored stray words, so
|
|
28
|
+
`npx mindforge-cc install` appeared to work while installing nothing configured.
|
|
29
|
+
It now refuses with the correct form. `--runtime`'s value token is still accepted.
|
|
30
|
+
Use `npx mindforge-cc --claude --local`. (#202)
|
|
31
|
+
|
|
32
|
+
- **`mindforge verify` now SKIPS unavailable stages instead of failing them.** A project
|
|
33
|
+
with no ESLint config, no test script or no `bin/verify-audit.js` was reported as
|
|
34
|
+
FAILING those stages rather than as not having them. If your CI relied on a non-zero
|
|
35
|
+
exit in those cases, it will now pass. A run in which every stage skipped prints a
|
|
36
|
+
"NOTHING WAS VERIFIED" banner rather than a clean bill of health. (#204)
|
|
37
|
+
|
|
38
|
+
- **`scripts/sync-version.js` now exits non-zero when the plugin build artifacts are
|
|
39
|
+
stale.** A bump used to report `✅ every derivable channel is at <version>` and exit 0
|
|
40
|
+
while leaving `npm test` red. If you script this, handle the new exit code — it means
|
|
41
|
+
"run the build chain it just printed". (#211)
|
|
42
|
+
|
|
43
|
+
- **A self-install no longer writes over your tracked files.** Running the installer
|
|
44
|
+
inside a MindForge checkout printed that it was skipping and then overwrote 149
|
|
45
|
+
tracked files, including `CLAUDE.md`, `.claude/**`, `.agent/**` and `.mindforge/**`.
|
|
46
|
+
The skip is now honoured for local scope. (#200)
|
|
47
|
+
|
|
48
|
+
- **Releases must be tagged on a commit reachable from `main`.** The release workflow
|
|
49
|
+
now refuses a tag that is not an ancestor of `origin/main`. The documented flow is
|
|
50
|
+
develop → release → main; tagging elsewhere previously published, with provenance
|
|
51
|
+
attesting to that tree. (#216)
|
|
52
|
+
|
|
53
|
+
### Fixed
|
|
54
|
+
|
|
55
|
+
**Installer**
|
|
56
|
+
|
|
57
|
+
- A self-install claimed to skip and then overwrote 149 tracked files. The gate is now
|
|
58
|
+
scope-aware (`isSelfInstall() && scope === 'local'`). (#200)
|
|
59
|
+
- Every `--global` install reported failure on a correct run: `verifyInstall` demanded
|
|
60
|
+
six `bin/**` paths regardless of scope, so a global install ended
|
|
61
|
+
`❌ 6 of 12 required file(s) missing` and exit 1, with a `--force` retry that could
|
|
62
|
+
not help. A global install writes 389 files to `$HOME/.claude` and, deliberately,
|
|
63
|
+
zero to `bin/`. (#210)
|
|
64
|
+
- 11 of 27 routed CLI verbs died on `MODULE_NOT_FOUND` in a real install: the router
|
|
65
|
+
shipped but 6 of the scripts it dispatches to did not. `coreFiles` grew from 2 entries
|
|
66
|
+
to 8. (#210)
|
|
67
|
+
- Two leaks: `/tmp` staging files left behind on abandoned runs, and developer runtime
|
|
68
|
+
state (`celestial.db`, `.browser-daemon-token`) copied into consumer projects.
|
|
69
|
+
`SENSITIVE_EXCLUDE` now covers both. (#210)
|
|
70
|
+
- The forge commands overwrote three `mindforge` commands of the same name. (#197)
|
|
71
|
+
- The documented default install did not deliver the CLI it documents. (#196)
|
|
72
|
+
|
|
73
|
+
**Versioning and release**
|
|
74
|
+
|
|
75
|
+
- `sync-version.js --fetch-sha` hashed npm's 404 error body. For an unpublished version
|
|
76
|
+
the registry answers `{"error":"Not found"}` and `curl -sL` exits 0, so the digest
|
|
77
|
+
written into the Homebrew formula was the SHA-256 of that error text — the same
|
|
78
|
+
constant for every unpublished version — and `--check` then passed. Now `curl -fsSL`
|
|
79
|
+
plus a gzip magic-byte check, and it refuses rather than writing a digest no artifact
|
|
80
|
+
can match. (#203)
|
|
81
|
+
- The Homebrew formula may now LAG canonical but never LEAD it. Requiring equality
|
|
82
|
+
before publishing required something impossible: the digest is the hash of a tarball
|
|
83
|
+
that does not exist yet, and `npm test` blocked the publish that would have made it
|
|
84
|
+
satisfiable. (#208)
|
|
85
|
+
- Semver comparison is numeric per component. Lexicographically, `11.10.0` reads as
|
|
86
|
+
*behind* `11.9.2` — wrong on exactly the first release past a `.9` minor. (#208)
|
|
87
|
+
- Three version channels had no writer at all, so `npm test` failed on every bump and
|
|
88
|
+
the documented remedy could not fix it: `mcp-server/server.json` (both keys, matched
|
|
89
|
+
by identifier), `AGENTS.md`, and `sdk/README.md`'s second shape. (#207, #211)
|
|
90
|
+
- **No channel covered a document a user receives.** `SECURITY.md` — the security policy
|
|
91
|
+
at the root of the published package — said "Current version: 11.9.0", and
|
|
92
|
+
getting-started, faq, troubleshooting, user-guide and sdk-reference all titled
|
|
93
|
+
themselves v11.9.0: three releases stale, while every npm manifest was correct.
|
|
94
|
+
`--check` was green throughout, because a channel that does not exist cannot drift.
|
|
95
|
+
Structural markers now track canonical; narrative measurements deliberately do not.
|
|
96
|
+
(#211)
|
|
97
|
+
- A bump is not finished when `sync-version.js` exits. Two tracked artifacts are gated
|
|
98
|
+
against `package.json` and only a build can write them —
|
|
99
|
+
`plugins/mindforge/.claude-plugin/plugin.json` and
|
|
100
|
+
`plugins/mindforge/mcp/dist/index.js`. They are now reported under
|
|
101
|
+
`🔨 REQUIRE A BUILD` with the exact three-command chain, which nothing had documented.
|
|
102
|
+
(#211)
|
|
103
|
+
- `sync-version.js` reported "a channel is AHEAD of canonical" whenever its exit code
|
|
104
|
+
was non-zero for any reason, so the `--fetch-sha` refusal for an unpublished tarball
|
|
105
|
+
claimed the formula LEADS canonical in the same run that printed "DEFERRED until after
|
|
106
|
+
publish (behind, not ahead)". (#211)
|
|
107
|
+
- `changelogs/index.json`, which `bin/updater/changelog-fetcher.js` reads as the
|
|
108
|
+
authoritative version list, was missing 11.9.2. (#218)
|
|
109
|
+
|
|
110
|
+
**Publishing**
|
|
111
|
+
|
|
112
|
+
- **The tag push that publishes was exempt from every gate.** Publishing is triggered by
|
|
113
|
+
exactly one event — a `v*` tag push — and the repository's only ruleset targets
|
|
114
|
+
branches, so its six required checks applied to nothing on the path that ships. GitHub
|
|
115
|
+
cannot attach required status checks to a tag. A `preflight` job now gates it. (#216)
|
|
116
|
+
- The `stable` npm dist-tag was moved by hand, or not at all — it sat four releases
|
|
117
|
+
behind `latest` (11.8.3 against 11.9.2), so `npm i mindforge-cc@stable` delivered a
|
|
118
|
+
build with none of the 11.9.x fixes. The release workflow now moves it as its final
|
|
119
|
+
step: forward-only, prereleases skipped, and verified against npm's uncached dist-tags
|
|
120
|
+
endpoint rather than the CDN-cached packument. (#216)
|
|
121
|
+
|
|
122
|
+
**Dashboard**
|
|
123
|
+
|
|
124
|
+
- `--status` and `--stop` were documented in nine places and implemented in none; both
|
|
125
|
+
printed nothing and exited 0. Now implemented, before `express` is required, so they
|
|
126
|
+
work without the dependency installed. (#206)
|
|
127
|
+
- `--stop` identified the target by the SHAPE of its command line, which matched any
|
|
128
|
+
`node <anything>/dashboard/server.js` — verified against
|
|
129
|
+
`node /var/www/unrelated_app/dashboard/server.js`. It now resolves the script's
|
|
130
|
+
realpath and compares it to its own. (#206)
|
|
131
|
+
- `--status` printed a port it could not know: the PID file records only the pid, so it
|
|
132
|
+
reported whatever port that invocation happened to receive. Measured, `--status` on a
|
|
133
|
+
server started with `--port 7466` printed "port 7339". (#206)
|
|
134
|
+
|
|
135
|
+
**Memory**
|
|
136
|
+
|
|
137
|
+
- Every abandoned exit left a full copy of the database on disk — 1.8 GB of orphaned
|
|
138
|
+
`.tmp` files. (#199)
|
|
139
|
+
- The SDK's WebSocket client took the caller's process down on a failed reconnect. (#191)
|
|
140
|
+
|
|
141
|
+
**Verification**
|
|
142
|
+
|
|
143
|
+
- `mindforge verify`'s lint stage used `--max-warnings=0`, which made it impossible to
|
|
144
|
+
pass in the repository it ships from: `npx eslint .` reports 199 problems / 0 errors /
|
|
145
|
+
199 warnings, so `verify` reported a lint FAILURE on a tree that is green by the
|
|
146
|
+
project's own contract. Aligned with the project's definition; errors still fail. (#204)
|
|
147
|
+
- `temporal cleanup` printed "🧹 Cleaning up old temporal snapshots..." and
|
|
148
|
+
"✅ Cleanup complete." with no cleanup between them. Now wired to
|
|
149
|
+
`TemporalHub.gc({maxSnapshots: 50, maxAgeDays: 30})` with `--dry-run` and honest
|
|
150
|
+
counts, including zero. (#209)
|
|
151
|
+
|
|
152
|
+
**Documentation that named things that do not exist**
|
|
153
|
+
|
|
154
|
+
- The protocol files instructed the agent to run `soul-engine.js` and
|
|
155
|
+
`shard-controller.js`, neither of which exists anywhere in the package. Those steps
|
|
156
|
+
are reasoning protocols and now say so. (#205)
|
|
157
|
+
- Fifteen phantom `/mindforge:` slash commands in shipped docs. A reader following
|
|
158
|
+
`docs/user-guide.md` typed `/mindforge:personas --list` and got nothing. They were not
|
|
159
|
+
typos: `.agent/workflows/` holds 130 tracked files using those exact names — an old
|
|
160
|
+
target layout, committed and orphaned, shipping zero files. (#209)
|
|
161
|
+
- Four documented CLI invocations could not be run, each verified by running it:
|
|
162
|
+
`npx mindforge-cc@latest install` (exit 1), `mindforge-cli.js dashboard` (exit 1),
|
|
163
|
+
`npx mindforge auto` in a shipped engine doc (`auto` is a slash command, never a CLI
|
|
164
|
+
verb), and `@mindforge <verb>`, a syntax that exists nowhere. (#213)
|
|
165
|
+
- `workflow` is the most-documented CLI verb in the project and works, but appeared in
|
|
166
|
+
neither `--help` nor the "Available commands" list, so a user who mistyped it was told
|
|
167
|
+
it does not exist. (#213)
|
|
168
|
+
- Root `CLAUDE.md` named `bin/hooks/mindforge-context-monitor.js`; the file is under
|
|
169
|
+
`.agent/hooks/`. (#214)
|
|
170
|
+
|
|
171
|
+
### Added
|
|
172
|
+
|
|
173
|
+
- **`preflight` job on the release workflow.** Asserts the tagged commit is an ancestor
|
|
174
|
+
of `origin/main`, then runs the six gates a tag push never saw, with the publish job
|
|
175
|
+
behind `needs:`. (#216)
|
|
176
|
+
- **Automatic `stable` dist-tag movement**, forward-only and verified. (#216)
|
|
177
|
+
- **`node bin/dashboard/server.js --status` / `--stop`.** Not CLI verbs —
|
|
178
|
+
`mindforge-cli.js dashboard` does not route. (#206)
|
|
179
|
+
- **`mindforge temporal cleanup --dry-run`.** (#209)
|
|
180
|
+
- New regression gates, each falsified by mutation before being trusted:
|
|
181
|
+
`tests/protocol-claims.test.js` (no exemption list, deliberately — a name-keyed
|
|
182
|
+
allowlist was shown to excuse the exact defect it was written for), the shipped-doc
|
|
183
|
+
phantom-command gate, the CLI-verb gate, the authority-doc `.js` gate, the
|
|
184
|
+
version-channel round trips, and assertions that the release preflight itself cannot
|
|
185
|
+
be silently removed.
|
|
186
|
+
|
|
187
|
+
### Notes for operators
|
|
188
|
+
|
|
189
|
+
- `npm run version:check` is the offline drift check. A bump is finished only when
|
|
190
|
+
`sync-version.js` exits 0 — if it prints `🔨 REQUIRE A BUILD`, run the three commands
|
|
191
|
+
it names and commit both regenerated files.
|
|
192
|
+
- Releases are now gated on being tagged from `main`. One residual, inherent to
|
|
193
|
+
tag-triggered workflows: a tag push resolves the workflow from the TAGGED ref, so a
|
|
194
|
+
tag placed on a commit predating this release runs that commit's workflow and is
|
|
195
|
+
ungated.
|
|
196
|
+
|
|
197
|
+
## [11.9.2] — 2026-08-16 — Correctness: audit-chain integrity, dashboard crash policy, secret scanning
|
|
198
|
+
|
|
199
|
+
Patch release. No new features. Correctness work closing defects found by a
|
|
200
|
+
multi-agent audit of v11.9.1, plus the regression suites that keep them closed.
|
|
201
|
+
Contains a breaking change to the dashboard HTTP surface — see BREAKING below.
|
|
202
|
+
|
|
203
|
+
### BREAKING
|
|
204
|
+
|
|
205
|
+
Shipped under a PATCH bump. The break is confined to the dashboard's own HTTP
|
|
206
|
+
surface, which binds to 127.0.0.1 only — but if you script against it, read this.
|
|
207
|
+
|
|
208
|
+
- **Dashboard error responses changed shape.** `detail` is removed from 5 endpoints and
|
|
209
|
+
raw errno strings from 10 more; `correlation_id` is added to 15; a malformed request
|
|
210
|
+
body now returns `application/json` instead of express's `text/html` error page.
|
|
211
|
+
Anything parsing `detail` must correlate on the logged `correlation_id` instead. This
|
|
212
|
+
was deliberate — those fields leaked absolute filesystem paths, and therefore the
|
|
213
|
+
operator's username and home directory, into an unauthenticated response body
|
|
214
|
+
(`requireAuth` exempts GET).
|
|
215
|
+
- **The dashboard now EXITS on an unhandled rejection or uncaught exception** where
|
|
216
|
+
11.9.1 logged and continued. If you supervise the process, expect restarts where you
|
|
217
|
+
previously saw a logged error. Rationale in the Fixed section below: log-and-continue
|
|
218
|
+
held client sockets open until the client timed out, and had made `shutdown()` swallow
|
|
219
|
+
a throwing token unlink and keep serving the authenticated mutation API after SIGTERM.
|
|
220
|
+
- **`node bin/validate-config.js` and `mindforge security-scan` can now fail.** They
|
|
221
|
+
previously reported `MINDFORGE.md valid — 0 settings configured` and exited 0 on every
|
|
222
|
+
input. If you run either in CI, a genuinely invalid registry will now red-line where it
|
|
223
|
+
used to pass. Note this reaches **fresh installs and `--force` reinstalls only** — the
|
|
224
|
+
installer does not overwrite an existing `.mindforge/MINDFORGE-SCHEMA.json`, so a plain
|
|
225
|
+
upgrade keeps the old permissive schema.
|
|
226
|
+
|
|
227
|
+
### Fixed
|
|
228
|
+
|
|
229
|
+
- **`security-scan` could not fail.** `bin/validate-config.js` and
|
|
230
|
+
`bin/models/model-router.js` each parsed `MINDFORGE.md` with a plain `KEY=value` regex, but
|
|
231
|
+
the registry declares its 43 parameters as bracketed `[KEY] = value`. Every schema property
|
|
232
|
+
resolved to `undefined` and short-circuited, so the command reported
|
|
233
|
+
`MINDFORGE.md valid — 0 settings configured` and exited 0 on any input. The schema also had
|
|
234
|
+
no `required` key at all. Both parsers now share `bin/utils/mindforge-params.js`, which also
|
|
235
|
+
accepts the legacy plain form (`examples/starter-project/MINDFORGE.md` ships 28 such lines),
|
|
236
|
+
and the schema declares real `required`/`recommended` sets.
|
|
237
|
+
**Behaviour change for consumers:** three CI gates go from unfailable to failable —
|
|
238
|
+
`.github/workflows/mindforge-ci.yml:38`, `.gitlab-ci-mindforge.yml:12`, and
|
|
239
|
+
`.github/workflows/control-plane.yml:100`. If one red-lines on a valid value, the schema
|
|
240
|
+
bound is wrong; do not "fix" it by editing `MINDFORGE.md`. Model routing is unchanged —
|
|
241
|
+
30 persona x tier combinations resolve identically.
|
|
242
|
+
- **Trace retrieval returned nothing usable.** Queries were wrapped as a single FTS phrase, so
|
|
243
|
+
any query containing one absent term scored zero; and `traces_search` was keyed on `trace_id`
|
|
244
|
+
rather than the primary key, so each span's DELETE evicted the previous span and only the last
|
|
245
|
+
span per trace stayed searchable — 2,270 of 5,117 content-bearing traces, 44.4%, unsearchable.
|
|
246
|
+
Queries are now tokenised, OR-joined and ranked by tf-idf (`matchinfo('pcnx')`); the index is
|
|
247
|
+
re-keyed and rebuilt losslessly from the base table. `bin/eval/eval-harness.js` and its golden
|
|
248
|
+
set had zero callers and are now reachable as `npm run eval:retrieval`, with the baseline
|
|
249
|
+
committed: mean recall@10 0.6417, nDCG 0.5698 over 519 documents.
|
|
250
|
+
- **The cost ledger reported two totals for one concept.** `sum(cost_usd)` was $13.73 while
|
|
251
|
+
`sum(total_cost_usd)` was $0.00, and `tests/dashboard.test.js` wrote the reader's field name,
|
|
252
|
+
so the mismatch tested green. `bin/models/usage-record.js` is now the single definition of the
|
|
253
|
+
ledger path, record shape, per-entry cost and day bucket. The configured `ledger_path` pointed
|
|
254
|
+
at `token-ledger.jsonl`, a file that has never existed; that ghost filename had spread to 17
|
|
255
|
+
places across 13 files and is now absent. The dashboard cost tile no longer renders `$0.00`
|
|
256
|
+
on a 500 — it had no `res.ok` check, and because errors return well-formed JSON the catch
|
|
257
|
+
never fired, making an outage indistinguishable from zero spend.
|
|
258
|
+
A maintainer tool, `scripts/purge-synthetic-usage.js`, removes fixture rows: dry-run by
|
|
259
|
+
default, backs up first, idempotent, and aborts leaving the ledger untouched if the rewrite
|
|
260
|
+
fails. It is run from a repository checkout — `scripts/` is not in the published tarball, so
|
|
261
|
+
installed consumers do not have it.
|
|
262
|
+
- **Audit hash chain could fork under concurrent writers.** `bin/autonomous/audit-writer.js`
|
|
263
|
+
read the chain head and appended with no mutual exclusion, and cached the head in-process
|
|
264
|
+
indefinitely — so once a second process appended, the first kept chaining from a superseded
|
|
265
|
+
hash. Added `bin/utils/file-lock.js` (a fail-closed advisory lock promoted from
|
|
266
|
+
`bin/learning/instinct-cli.js`, deliberately NOT from `.agent/bin/lib/state.cjs`, which
|
|
267
|
+
writes anyway when the lock cannot be taken) held across read-head-through-fsync, and made
|
|
268
|
+
the cached head carry the file size that witnesses it is still the tail. 8 concurrent
|
|
269
|
+
appenders went from 199 broken links + 4 forks per 200 entries to 0. A lock alone was
|
|
270
|
+
measured insufficient — it still left 2 breaks and 1 fork, because the stale cache is a
|
|
271
|
+
second, independent defect.
|
|
272
|
+
- **Knowledge-graph edge updates were lost under concurrency.** `deprecateEdge`,
|
|
273
|
+
`reinforceEdge` and `applyDecay` in `bin/memory/knowledge-graph.js` each did
|
|
274
|
+
`readAllEdges()` -> mutate -> append with no lock, and `addEdge` appended unserialised
|
|
275
|
+
against them. Measured at HEAD over 4 runs of 8 processes x 20 `reinforceEdge` calls:
|
|
276
|
+
93-129 of 160 increments lost, final `traversal_count` 31-67 instead of 160. All four
|
|
277
|
+
write paths now hold the `graph-edges.jsonl` lock across read-through-append; the same
|
|
278
|
+
probe then loses 0 of 160 in every run, with no lock-acquisition failures.
|
|
279
|
+
- `bin/governance/policy-engine.js`: `logAudit`'s un-awaited audit write now has a
|
|
280
|
+
`.catch()` — a lock-contention failure is reported at the decision site instead of
|
|
281
|
+
escaping as an unhandled rejection.
|
|
282
|
+
- `bin/hooks/instinct-capture-hook.js` appended to the instinct store without the lock that
|
|
283
|
+
`instinct-cli`'s prune/import rewrite holds, so a hook append landing in that window was
|
|
284
|
+
clobbered by the rename. It now takes the same lock.
|
|
285
|
+
- `tests/v7-sovereign-security.test.js`: `new PolicyEngine()` no longer defaults
|
|
286
|
+
`planningDir` to `process.cwd()`, which appended test verdicts to the operator's real
|
|
287
|
+
`.planning/RISK-AUDIT.jsonl`.
|
|
288
|
+
- Packaging: `package.json` files[] now excludes `**/*.lock` so a lockfile orphaned by a
|
|
289
|
+
hard kill cannot leak into the npm tarball (verified: without the negation, a
|
|
290
|
+
`.mindforge/memory/graph-edges.jsonl.lock` does ship).
|
|
291
|
+
|
|
292
|
+
- **Audit-chain forgery via un-awaited rollback.** `HindsightInjector.inject` called
|
|
293
|
+
the async `TemporalHub.rollbackTo` without `await`, so its rejection escaped the
|
|
294
|
+
surrounding `try/catch` while execution continued: a failed rollback still fsync'd a
|
|
295
|
+
hash-chained `hindsight_injected` entry and flipped `auto-state.json` to
|
|
296
|
+
`awaiting_regeneration` for something that never happened. The log gained a
|
|
297
|
+
cryptographically valid record of a non-event, and `verify-audit` reported the chain
|
|
298
|
+
valid — valid and wrong.
|
|
299
|
+
- **CLI `defaultArgs` were replaced by user arguments, not prepended.** `mindforge
|
|
300
|
+
health <anything>` lost `--check` and fell through to `installer-core`'s real
|
|
301
|
+
`install()` with `force: true`. Now prepended.
|
|
302
|
+
- **`_verifyMetadata` compared UTF-16 code units, not bytes**, so a 64-unit / 65-byte
|
|
303
|
+
`integrity` still threw `RangeError` — and the caller degraded that throw into
|
|
304
|
+
"proceeding without integrity check" and restored the snapshot anyway. Read and
|
|
305
|
+
verify are now separate stages; only a genuinely absent `SNAPSHOT-META.json` reaches
|
|
306
|
+
the tolerant path.
|
|
307
|
+
- **Dashboard `RevOpsAPI` was required but never mounted**, so `/api/revops/overview`
|
|
308
|
+
404'd while the AgRevOps panels and docs described it as live. Even mounted it threw:
|
|
309
|
+
`getAuditEntries()` returns `{entries,total,limit,offset}` and three engines call
|
|
310
|
+
`.filter()` on it.
|
|
311
|
+
- **Dashboard leaked error internals to clients.** `err.message` reached response
|
|
312
|
+
bodies from 14 sites (`api-router.js` ×10, `temporal-api.js` ×3, `revops-api.js` ×1);
|
|
313
|
+
for fs-sourced errors that string carries absolute paths, disclosing the operator's
|
|
314
|
+
username and home directory. All sites now log server-side and return a generic
|
|
315
|
+
message plus a `correlation_id`, behind a 4-arg terminal handler that stops express
|
|
316
|
+
rendering `err.stack` when `NODE_ENV !== 'production'`.
|
|
317
|
+
- **Test runner discovery was a flat `readdirSync`**, so any suite in a subdirectory was
|
|
318
|
+
invisible. Now a recursive walk that prunes `tmp-*` / `node_modules` / dot
|
|
319
|
+
directories — directories only, never files.
|
|
320
|
+
- Three orphan files removed: one truncated `.planning/AUDIT.jsonl` to zero, one
|
|
321
|
+
overwrote `.planning/STATE.md`, one called a function absent from `bin/`. Recursion
|
|
322
|
+
made the `STATE.md` clobberer reachable by a single in-place rename; the other two
|
|
323
|
+
were unreachable by the runner at any depth. **The claim in `5177225`'s message that
|
|
324
|
+
all three were newly armed by recursion is correct for one of the three and
|
|
325
|
+
over-attributed for the other two.**
|
|
326
|
+
- Three relocated demos kept one-level-up requires after moving a directory deeper, so
|
|
327
|
+
all three exited 1; corrected to `../../bin/`.
|
|
328
|
+
|
|
329
|
+
### Changed
|
|
330
|
+
|
|
331
|
+
- **`mindforge audit-skill`, `register-skill`, `install-skill` and `record-learning` no
|
|
332
|
+
longer carry `defaultArgs`.** Prepending turned them from inert into live state
|
|
333
|
+
writers: `audit-skill <name> <ver> <tier>` appended a hash-chained
|
|
334
|
+
`{event:'skill_installed', validation_passed:true}` entry for a skill that does not
|
|
335
|
+
exist, and `register-skill` wrote a malformed row above the table header of
|
|
336
|
+
`.mindforge/org/skills/MANIFEST.md`, which ships in the tarball. Bare invocations now
|
|
337
|
+
print usage and exit 0 without reaching those writers, as at v11.9.1.
|
|
338
|
+
- **`subagent` is a first-class command.** Prepending `spawn` shadowed `spawn-agent`'s
|
|
339
|
+
`subagent` mode, whose documented route was `mindforge spawn subagent <name>`.
|
|
340
|
+
- **The dashboard now exits on an unhandled rejection instead of logging and
|
|
341
|
+
continuing.** An escaped rejection is the only reliable signal that an async call was
|
|
342
|
+
left un-awaited, and express 4.22.1 does not route async handler rejections to error
|
|
343
|
+
middleware — log-and-continue held the client socket open until the client gave up
|
|
344
|
+
(2.5s, 4s and 8s clients all timed out) versus a ~15ms reset on exit. Symmetric with
|
|
345
|
+
`uncaughtException`, whose log-and-continue form had made `shutdown()` swallow a
|
|
346
|
+
throwing token unlink and keep serving the token-authenticated mutation API **after
|
|
347
|
+
SIGTERM**, with the bearer token still on disk and valid in memory.
|
|
348
|
+
- **Dashboard error responses changed shape.** `detail` is removed from 5 endpoints,
|
|
349
|
+
raw errno strings from 10 more, `correlation_id` is added to 15, and a malformed
|
|
350
|
+
request body now returns `application/json` rather than express's `text/html` error
|
|
351
|
+
page. Anything parsing `detail` must correlate on the logged id instead.
|
|
352
|
+
|
|
353
|
+
### Added
|
|
354
|
+
|
|
355
|
+
- **Secret scanning enforced at three layers**: `.gitleaks.toml`, a `.husky/pre-commit`
|
|
356
|
+
gate that fails loudly when gitleaks is absent rather than skipping, and
|
|
357
|
+
`.github/workflows/secret-scan.yml` scanning full history. `scripts/ci/verify-secret-scan.sh`
|
|
358
|
+
self-tests the scanner — it distinguishes "scanned clean" from "scanned and found"
|
|
359
|
+
from "did not scan", because gitleaks exits 1 for both a finding and a failed config
|
|
360
|
+
load, and writes no report in the latter case.
|
|
361
|
+
|
|
362
|
+
### Tests
|
|
363
|
+
|
|
364
|
+
- Suite totals for this release: **105 files, 103 pass, 2 environment-dependent skips**
|
|
365
|
+
(`browser`, `sre-integration`). Eight new suites across the release:
|
|
366
|
+
`temporal-integrity`, `dashboard-error-leak`, `dashboard-crash-guards`,
|
|
367
|
+
`dashboard-wiring`, `cli-router`, `mindforge-params`, `file-lock`, `retrieval-fts`.
|
|
368
|
+
- **Four suites could not report failure and now can.** `v8-persistence`,
|
|
369
|
+
`v8-skill-evolution` and `v8-orbital-governance` ended `finally { process.exit(0) }`, and
|
|
370
|
+
`v7-pillar-integration` had zero assertions with a premium-model gate that named two models
|
|
371
|
+
absent from the registry for several releases. `npm test` is the only quality step before
|
|
372
|
+
`npm publish`, and the runner gates on child exit codes, so a blind suite blinded the publish
|
|
373
|
+
gate. Verified by injected failure rather than inspection.
|
|
374
|
+
`dashboard-wiring` derives the expected router set
|
|
375
|
+
from `server.js`'s own requires, so adding a router without mounting it fails.
|
|
376
|
+
`cli-router` runs against a mirror-root sandbox under `os.tmpdir()` — required, not
|
|
377
|
+
tidiness: the case that proves audit forgery is prevented would otherwise forge an
|
|
378
|
+
entry into the real chain on every run. `revops-roi.test.js` had 0 assertions and
|
|
379
|
+
could not fail; it now has 6.
|
|
380
|
+
|
|
381
|
+
### Not fixed — deferred to v12
|
|
382
|
+
|
|
383
|
+
- **No hook is registered in any consumer install.** The installer copies 9 hook
|
|
384
|
+
scripts into `<runtime>/hooks/`, but nothing writes `.claude/settings.json` and it is
|
|
385
|
+
absent from `package.json` `files[]`. Verified by installing the tarball into a
|
|
386
|
+
scratch project. Every gate this release hardens is inert until that lands.
|
|
387
|
+
- **`requireAuth` exempts GET and OPTIONS**, so every read route — including
|
|
388
|
+
`/api/audit`, which serves the hash-chained audit log — is credential-free to any
|
|
389
|
+
local process. Mutations are protected. This is a threat-model decision, not a patch.
|
|
390
|
+
- **`audit-skill audit <name> <ver> <tier>`** — the explicit form — still reaches a
|
|
391
|
+
writer that performs no existence check and hardcodes `validation_passed: true`. Only
|
|
392
|
+
the bare invocation is closed.
|
|
393
|
+
- **Snapshot integrity is not an authenticity control.** `HMAC_KEY` is a literal in
|
|
394
|
+
shipped source, the HMAC covers only the metadata object so file **contents** are
|
|
395
|
+
unsigned (editing a file inside a signed snapshot leaves the signature valid), and
|
|
396
|
+
deleting `SNAPSHOT-META.json` bypasses verification entirely.
|
|
397
|
+
- `cwd: ROOT` in the CLI, which resolves consumer state inside `node_modules`.
|
|
398
|
+
- `security-scan` cannot fail: its parser expects `KEY=value` while `MINDFORGE.md` uses
|
|
399
|
+
`[KEY] = value`, so it always reports 0 settings and exits 0.
|
|
400
|
+
- Version drift in six publishable manifests (`Formula/mindforge.rb`, `Dockerfile`,
|
|
401
|
+
`mcp-server/server.json`, `mcp-server/src/index.ts`, the plugin manifest and the
|
|
402
|
+
marketplace entry) is untouched here — none is gated, and the Formula pins a tarball
|
|
403
|
+
sha256 that cannot exist before publish.
|
|
404
|
+
|
|
3
405
|
## [11.9.1] — 2026-07-29 — Packaging Fix: Restore Missing Workflow Commands
|
|
4
406
|
|
|
5
407
|
### Fixed
|
package/MINDFORGE.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
# MINDFORGE.md — Parameter Registry (v11.9.
|
|
1
|
+
# MINDFORGE.md — Parameter Registry (v11.9.3)
|
|
2
2
|
|
|
3
3
|
## 1. IDENTITY & VERSIONING
|
|
4
4
|
|
|
5
5
|
[NAME] = MindForge
|
|
6
|
-
[VERSION] = 11.9.
|
|
6
|
+
[VERSION] = 11.9.3
|
|
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] —
|
|
102
|
-
|
|
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] —
|
|
105
|
-
|
|
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.
|