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
@@ -2,8 +2,8 @@
2
2
 
3
3
  ## Overview
4
4
 
5
- The `@mindforge/sdk` package provides a programmatic TypeScript API for integrating
6
- MindForge into tools, dashboards, and CI pipelines. Import from `@mindforge/sdk`.
5
+ The `mindforge-sdk` package provides a programmatic TypeScript API for integrating
6
+ MindForge into tools, dashboards, and CI pipelines. Import from `mindforge-sdk`.
7
7
 
8
8
  ```typescript
9
9
  import {
@@ -11,14 +11,14 @@ import {
11
11
  MindForgeEventStream,
12
12
  MindForgeMemory,
13
13
  commands,
14
- } from '@mindforge/sdk';
14
+ } from 'mindforge-sdk';
15
15
  ```
16
16
 
17
- Current SDK version: `11.9.0`
17
+ Current SDK version: `11.9.4`
18
18
 
19
19
  ---
20
20
 
21
- ## SDK Exports (v11.9.0)
21
+ ## SDK Exports (v11.9.4)
22
22
 
23
23
  ```javascript
24
24
  const {
@@ -28,7 +28,7 @@ const {
28
28
  commands, // Command registry
29
29
  batch, // Batch execution
30
30
  MindForgeMemory, // Memory interface
31
- VERSION // '11.9.0'
31
+ VERSION // '11.9.4'
32
32
  } = require('mindforge-sdk');
33
33
  // or: import { MindForgeClient, VERSION } from 'mindforge-sdk';
34
34
  ```
@@ -417,6 +417,14 @@ cd sdk && npm install && npm run build
417
417
 
418
418
  ## Installation
419
419
  ```bash
420
- npm install mindforge-sdk@11.9.1
420
+ npm install mindforge-sdk
421
421
  # or: npx mindforge-cc@stable # installs SDK as part of the framework
422
422
  ```
423
+
424
+ > **`mindforge-sdk` is versioned independently of the framework.** The release workflow
425
+ > (`.github/workflows/mindforge-release.yml`) publishes `mindforge-cc` and
426
+ > `mindforge-mcp-server` only — it has no `sdk` steps — so `sdk/package.json`'s version
427
+ > tracks the monorepo while the published package does not. At the time of writing the
428
+ > latest published SDK is **11.8.0** (`npm view mindforge-sdk versions`), even though the
429
+ > in-repo `sdk/package.json` reads 11.9.2. Install it unpinned, as above; pinning it to a
430
+ > framework version yields `E404 No match found for version …`.
@@ -1,4 +1,4 @@
1
- # MindForge Troubleshooting (v11.9.0)
1
+ # MindForge Troubleshooting (v11.9.4)
2
2
 
3
3
  This page lists common issues and fast fixes. If you get stuck, start with
4
4
  `/mindforge:health`.
@@ -117,15 +117,19 @@ rerun migration. See `.mindforge/audit/AUDIT-SCHEMA.md` for expected format.
117
117
 
118
118
  ### Protocol Step 0 fails to activate
119
119
  **Symptom:** Commands proceed without activating `_extended` skills.
120
- **Fix:** Run `/mindforge:neural-orchestrator --reset`. Ensure all `_extended` skills are present in `.agent/skills/`.
120
+ **Fix:** Ensure all `_extended` skills are present in `.agent/skills/`, then start a fresh session so the
121
+ skill loader re-reads them. There is no orchestrator reset command.
121
122
 
122
123
  ### Context drift in Parallel Mesh
123
124
  **Symptom:** Parallel agents making conflicting decisions.
124
- **Fix:** Run `/mindforge:parallel-mesh --sync`. This forces a global state re-synchronization across all active worker identities.
125
+ **Fix:** Re-synchronise by re-reading `.planning/HANDOFF.json` and `.planning/auto-state.json` before the
126
+ next wave — the mesh protocol is described in `.mindforge/engine/wave-executor.md`. It is a protocol you
127
+ follow, not a command.
125
128
 
126
129
  ### Workspace isolation failure
127
130
  **Symptom:** Conflicts between feature branches or dirty worktree.
128
- **Fix:** Run `/mindforge:workspace-isolated --cleanup`. Use `/mindforge:health --repair` if `.git/worktrees/` is corrupt.
131
+ **Fix:** Run `/mindforge:workspace` to inspect worktree state. Use `/mindforge:health --repair` if
132
+ `.git/worktrees/` is corrupt.
129
133
 
130
134
  ---
131
135
 
@@ -133,7 +137,7 @@ rerun migration. See `.mindforge/audit/AUDIT-SCHEMA.md` for expected format.
133
137
  If the above doesn’t resolve it:
134
138
  - Review `docs/user-guide.md`
135
139
  - Check `docs/security/SECURITY.md` for security issues
136
- - Open a GitHub issue or join the Discord: `/mindforge:join-discord`
140
+ - Open a GitHub issue: https://github.com/sairam0424/MindForge/issues
137
141
  - **Architecture**: `docs/architecture/V5-ENTERPRISE.md`
138
142
  - **Commands**: `docs/commands-reference.md`
139
143
  - **Personas**: `docs/PERSONAS.md`
@@ -203,4 +207,59 @@ All tests must be run from the MindForge project root: `cd /path/to/MindForge &&
203
207
 
204
208
  **Symptom:** `--version` flag reports "Unknown command" on installs older than v11.9.0.
205
209
 
206
- **Fix:** Upgrade to v11.9.0: `npx mindforge-cc@latest install`
210
+ **Fix:** Upgrade: `npx mindforge-cc@latest --claude --local`
211
+
212
+ ---
213
+
214
+ ## Hooks are installed but nothing is blocked
215
+
216
+ **Symptom:** The hook scripts are present under `.claude/hooks/`, but a command that should be denied
217
+ — say `git commit --no-verify` — runs normally.
218
+
219
+ Hooks have two separate failure modes: **not registered** (no config names them) and **registered but
220
+ not live** (the config exists, the harness has not applied it). Check them in that order.
221
+
222
+ **1. Was registration attempted, and what did it decide?** The installer prints one line for every
223
+ outcome, and writes a receipt:
224
+
225
+ ```
226
+ cat .mindforge/hook-registration.json
227
+ ```
228
+
229
+ `registered: false` there carries the reason. Registration is deliberately narrow: Claude Code only,
230
+ `--local` only, non-Windows. A self-install inside a MindForge checkout also declines, because that
231
+ repo maintains its own tracked config.
232
+
233
+ **2. Restart the harness.** Claude Code snapshots hooks at session start, so a registration performed
234
+ during an open session is not live in it. This is the single most common cause.
235
+
236
+ **3. Confirm the project is trusted.** User-tier and project-tier settings are applied independently:
237
+ `~/.claude/settings.json` is the user tier and applies to every session, while
238
+ `<project>/.claude/settings.json` is the project tier and needs the project itself to be trusted.
239
+ Measured on one machine: the user-tier hooks fired on every tool call while the project-tier hooks in
240
+ the same session did not, and that project's entry in `~/.claude.json` had
241
+ `hasTrustDialogAccepted: false`. Accept the trust prompt for the directory, then use `/hooks` to
242
+ confirm the entries are listed.
243
+
244
+ **4. Drive the hook directly** to separate "the hook is broken" from "the hook is not wired". This
245
+ takes the harness out of the loop entirely — a deny-class hook must exit **2**:
246
+
247
+ ```bash
248
+ echo '{"hook_event_name":"PreToolUse","tool_name":"Bash","cwd":"'"$PWD"'","tool_input":{"command":"git commit --no-verify -m x"}}' \
249
+ | node .claude/hooks/run-with-flags.js mindforge-block-no-verify .claude/hooks/mindforge-block-no-verify.js minimal,standard,strict
250
+ echo "exit=$?"
251
+ ```
252
+
253
+ Exit 2 with a `BLOCKED:` line on stderr means the hook works and the problem is registration or
254
+ trust. Exit 0 with the payload echoed back means the dispatcher could not load the script — check
255
+ that the second path exists under `.claude/hooks/`.
256
+
257
+ **5. If you launch the harness somewhere else, install there too.** Project settings are read from the
258
+ directory the harness starts in; they are **not** inherited from a parent directory. An ancestor
259
+ project having its own `.claude/settings.json` does not make its hooks apply here, and does not stop
260
+ these from applying — the installer warns when it sees one, and still registers.
261
+
262
+ **Known residual:** if `CLAUDE_PROJECT_DIR` is unset, or `node` is not on the hook PATH, the
263
+ registered commands exit 1 and the gate is simply absent — the same position as not installing. This
264
+ is a deliberate trade: a fail-closed shell tail was measured denying benign commands on a fresh
265
+ clone.
@@ -1,8 +1,8 @@
1
- # MindForge User Guide (v11.9.0)
1
+ # MindForge User Guide (v11.9.4)
2
2
 
3
3
  This guide gets you from install to productive, with the minimum needed to run MindForge in a real project.
4
4
 
5
- > **v11.9.0 Stats:** 35 workflows · 221 slash commands · 232 engine skills · 216 personas · 0 CVEs · 258/258 IQ200 checks passing
5
+ > **v11.9.4 Stats:** 35 workflows · 221 slash commands · 232 engine skills · 216 personas · 0 CVEs · 258/258 IQ200 checks passing
6
6
 
7
7
  ## Prerequisites
8
8
 
@@ -44,7 +44,7 @@ mindforge health # Verify project integrity
44
44
  mindforge security-scan # Run security checks
45
45
  mindforge headless # Run agent in non-interactive mode
46
46
  mindforge --verbose ... # Enable verbose output for debugging
47
- mindforge --version # Print installed version (e.g. 11.9.0) and exit 0
47
+ mindforge --version # Print installed version (e.g. 11.9.4) and exit 0
48
48
  ```
49
49
 
50
50
  Use `--verbose` (or `-v`) on any command for detailed diagnostic output. Use `--version` (or `-V`) to print the installed version and exit.
@@ -127,7 +127,7 @@ MindForge features 211 specialized personas. Each persona is optimized for a spe
127
127
  To switch personas or see the full list:
128
128
 
129
129
  ```bash
130
- /mindforge:personas --list
130
+ ls .mindforge/personas/ # 216 persona briefs; there is no personas command
131
131
  ```
132
132
 
133
133
  ---
@@ -137,7 +137,7 @@ To switch personas or see the full list:
137
137
  For complex tasks that require minimal intervention:
138
138
 
139
139
  ```bash
140
- /mindforge:autonomous --phase [N]
140
+ /mindforge:auto --phase [N]
141
141
  ```
142
142
 
143
143
  Use the **Steer** command to guide logic without stopping execution:
@@ -153,7 +153,7 @@ Use the **Steer** command to guide logic without stopping execution:
153
153
  Observe your agent waves, token spend, and milestone progress in real-time.
154
154
 
155
155
  ```bash
156
- /mindforge:dashboard --start --open
156
+ /mindforge:dashboard --open
157
157
  ```
158
158
 
159
159
  The dashboard provides a premium web interface at `http://localhost:7339`.
@@ -179,7 +179,7 @@ Extend MindForge by learning from documentation or authoring custom protocols.
179
179
 
180
180
  ```bash
181
181
  /mindforge:learn https://docs.nextjs.org "nextjs-mastery"
182
- /mindforge:skill-creation # Author a new high-fidelity protocol
182
+ /mindforge:skills-index # browse the catalogue; author new skills per the guide in CLAUDE.md
183
183
  ```
184
184
 
185
185
  ---
@@ -189,7 +189,7 @@ Extend MindForge by learning from documentation or authoring custom protocols.
189
189
  MindForge features automated PR creation and commit management.
190
190
 
191
191
  ```bash
192
- /mindforge:pr-branch "feature/auth-refactor"
192
+ git switch -c feature/auth-refactor # no pr-branch command; use git, then /mindforge:pr-review
193
193
  /mindforge:ship --auto-pr
194
194
  ```
195
195
 
@@ -202,7 +202,7 @@ MindForge provides mission-critical resilience and sovereign reasoning for enter
202
202
  ### Multi-Cloud Arbitrage
203
203
  MindForge automatically hedges against provider outages and optimizes for cost/latency.
204
204
  ```bash
205
- /mindforge:settings --cloud-arbitrage on
205
+ # settings live in MINDFORGE.md as [KEY] = value; edit it, then run `mindforge security-scan`
206
206
  ```
207
207
 
208
208
  ### Sovereign Reason Enclaves (SRE)
@@ -214,8 +214,8 @@ Tier 3 (Principal) agents execute reasoning in isolated enclaves to protect sens
214
214
  ### Dynamic Human-Agent Handover & Temporal Steering (Pillar VII)
215
215
  NEXUS enables sub-second state reconstruction and **Hindsight Injection**. When an agent drifts, roll back its logic via the Dashboard's **Temporal Slider** and inject a steering vector to re-orient the wave.
216
216
  ```bash
217
- /mindforge:temporal status # View active reasoning snapshots
218
- /mindforge:temporal inject [ID] # Manual CLI-based hindsight
217
+ mindforge temporal status # View active reasoning snapshots (a CLI command)
218
+ mindforge temporal inject [ID] # Manual CLI-based hindsight
219
219
  ```
220
220
 
221
221
  ### Agentic Revenue Operations (AgRevOps) (Pillar VIII)
@@ -239,7 +239,7 @@ The **Enterprise Expansion** introduces 14 hardened protocols from the Superpowe
239
239
 
240
240
  Activate the mesh for any session:
241
241
  ```bash
242
- /mindforge:neural-orchestrator
242
+ # the orchestrator layer is a protocol in .mindforge/engine/, not a command
243
243
  ```
244
244
 
245
245
  ---
@@ -260,7 +260,7 @@ Keep your framework current with the latest personas and library updates:
260
260
 
261
261
  MindForge allows you to "time-travel" through your agent's reasoning.
262
262
 
263
- 1. **Launch the Dashboard**: `/mindforge:dashboard --start --open`
263
+ 1. **Launch the Dashboard**: `/mindforge:dashboard --open`
264
264
  2. **Navigate to 'Temporal'**: Use the horizontal slider to scrub through reasoning snapshots.
265
265
  3. **Inspect State**: View the exact memory, file diffs, and thought chain at that point in space-time.
266
266
  4. **Inject Hindsight**: If you see a logic error, use the **Hindsight Injector** form to roll back and provide a corrective "Steering Vector."
@@ -283,4 +283,4 @@ Monitor your project's economic performance in real-time via the **RevOps Hub**.
283
283
  - **USP & Roadmap**: `docs/usp-features.md`
284
284
  - **Commands**: `docs/commands-reference.md`
285
285
  - **Troubleshooting**: `docs/troubleshooting.md`
286
- - **Discord**: `/mindforge:join-discord`
286
+ - **Issues**: https://github.com/sairam0424/MindForge/issues
@@ -1,6 +1,6 @@
1
1
  # SDK Integration Example
2
2
 
3
- Demonstrates basic usage of the `@mindforge/sdk` package.
3
+ Demonstrates basic usage of the `mindforge-sdk` package.
4
4
 
5
5
  ## Prerequisites
6
6
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mindforge-cc",
3
- "version": "11.9.2",
4
- "description": "MindForge \u2014 Sovereign Agentic Intelligence Framework. Sovereign Stability: Production-Hardened Agentic Intelligence (v11)",
3
+ "version": "11.9.4",
4
+ "description": "MindForge Sovereign Agentic Intelligence Framework. Sovereign Stability: Production-Hardened Agentic Intelligence (v11)",
5
5
  "bin": {
6
6
  "mindforge-cc": "bin/install.js",
7
7
  "mindforge": "bin/mindforge-cli.js"
@@ -29,6 +29,7 @@
29
29
  ".mindforge/intelligence/",
30
30
  ".mindforge/memory/",
31
31
  "!.mindforge/memory/pattern-library.jsonl",
32
+ "!.mindforge/memory/sync-manifest.json",
32
33
  ".mindforge/metrics/",
33
34
  "!.mindforge/metrics/token-usage.jsonl",
34
35
  ".mindforge/models/",
@@ -62,12 +63,16 @@
62
63
  "coverage": "npx c8 node tests/run-all.js",
63
64
  "lint": "eslint .",
64
65
  "harness:audit": "node bin/harness-audit.js",
66
+ "harness:gate": "node bin/harness-audit.js --min-score 76 --fail-on-findings",
67
+ "harness:gate:install": "node scripts/ci/harness-gate-install.js",
65
68
  "harness:compliance": "node bin/installer/harness-adapter-compliance.js --check",
66
69
  "release:ready": "node bin/utils/readiness-gate.js release",
70
+ "version:check": "node scripts/sync-version.js --check",
67
71
  "validate:assets": "node scripts/ci/validate-assets.js",
68
72
  "eval:retrieval": "node bin/eval/eval-harness.js --set golden-set-retrieval.json --min-recall 0.55",
69
73
  "commit": "cz",
70
- "prepare": "husky"
74
+ "prepare": "husky",
75
+ "verify:pinning": "node scripts/ci/verify-action-pinning.js"
71
76
  },
72
77
  "keywords": [
73
78
  "claude-code",
@@ -6,7 +6,7 @@
6
6
  },
7
7
  "metadata": {
8
8
  "version": "1.0.3",
9
- "description": "Curated collection of 154 specialized Claude Code subagents organized into 10 focused categories"
9
+ "description": "Curated collection of 164 specialized Claude Code subagents organized into 10 focused categories"
10
10
  },
11
11
  "plugins": [
12
12
  {
@@ -1,6 +0,0 @@
1
- {
2
- "pattern-library.jsonl": {
3
- "lastSync": "2026-08-16T19:50:41.118Z",
4
- "localCount": 1
5
- }
6
- }
@@ -1,136 +0,0 @@
1
- /**
2
- * MindForge v2 — Approval Handler
3
- * Handles POST /api/approve/:id — approve or reject governance requests.
4
- * Reads/writes APPROVAL-*.json files in .planning/approvals/
5
- */
6
- 'use strict';
7
-
8
- const fs = require('fs');
9
- const path = require('path');
10
-
11
- // Paths resolved lazily for testing
12
- const getPaths = () => ({
13
- approvals: path.join(process.cwd(), '.planning', 'approvals'),
14
- audit: path.join(process.cwd(), '.planning', 'AUDIT.jsonl'),
15
- });
16
-
17
- /**
18
- * Process an approval decision from the dashboard.
19
- * @param {string} approvalId - The APPROVAL UUID
20
- * @param {string} decision - 'approve' or 'reject'
21
- * @param {string} comment - Optional comment
22
- * @param {string} approver - Approver identifier (email or name)
23
- * @returns {{ success, decision, message }}
24
- */
25
- function processDecision(approvalId, decision, comment, approver, confirmationId = null) {
26
- // Input validation
27
- if (!approvalId || typeof approvalId !== 'string') {
28
- return { success: false, error: 'Invalid approval ID' };
29
- }
30
-
31
- // Sanitize approvalId — only allow UUID characters
32
- if (!/^[a-f0-9-]{36}$/.test(approvalId)) {
33
- return { success: false, error: 'Malformed approval ID format' };
34
- }
35
-
36
- if (!['approve', 'reject'].includes(decision)) {
37
- return { success: false, error: 'Decision must be "approve" or "reject"' };
38
- }
39
-
40
- // Find the approval file
41
- const paths = getPaths();
42
- const filePath = path.join(paths.approvals, `APPROVAL-${approvalId}.json`);
43
- if (!fs.existsSync(filePath)) {
44
- return { success: false, error: `Approval not found: ${approvalId}` };
45
- }
46
-
47
- let approval;
48
- try {
49
- approval = JSON.parse(fs.readFileSync(filePath, 'utf8'));
50
- } catch {
51
- return { success: false, error: 'Cannot parse approval file' };
52
- }
53
-
54
- // Validate approval is still pending
55
- if (approval.status !== 'pending') {
56
- return { success: false, error: `Approval already ${approval.status}` };
57
- }
58
-
59
- // Check expiry
60
- if (approval.expires_at && new Date(approval.expires_at) < new Date()) {
61
- return { success: false, error: 'Approval has expired' };
62
- }
63
-
64
- // TIER 3 CONFIRMATION — require typing the plan ID
65
- if (approval.tier === 3 && decision === 'approve') {
66
- const expectedConfirmation = `${approval.phase}-${approval.plan}`;
67
- if (!confirmationId || confirmationId.trim() !== expectedConfirmation) {
68
- return {
69
- success: false,
70
- error: `Tier 3 approval requires typing the plan ID "${expectedConfirmation}" to confirm.`,
71
- confirmation_required: true,
72
- expected: expectedConfirmation,
73
- tier3_warning: 'This is a Tier 3 change (auth/payment/PII). Review the code diff before approving.',
74
- };
75
- }
76
- }
77
-
78
- // Write AUDIT entry FIRST (before updating file)
79
- writeAuditEntry({
80
- id: require('crypto').randomBytes(8).toString('hex'),
81
- timestamp: new Date().toISOString(),
82
- event: decision === 'approve' ? 'approval_granted' : 'approval_rejected',
83
- approval_id: approvalId,
84
- tier: approval.tier,
85
- phase: approval.phase,
86
- plan: approval.plan,
87
- resolved_by: approver || 'dashboard',
88
- comment: comment || null,
89
- agent: 'mindforge-dashboard',
90
- session_id: 'dashboard',
91
- });
92
-
93
- // Update approval file
94
- const updated = {
95
- ...approval,
96
- status: decision === 'approve' ? 'approved' : 'rejected',
97
- resolved_at: new Date().toISOString(),
98
- resolved_by: approver || 'dashboard',
99
- comment: comment || null,
100
- resolution_channel: 'mindforge-dashboard',
101
- };
102
-
103
- fs.writeFileSync(filePath, JSON.stringify(updated, null, 2));
104
-
105
- return {
106
- success: true,
107
- decision,
108
- approval_id: approvalId,
109
- tier: approval.tier,
110
- message: `${approval.tier === 3 ? 'Tier 3' : 'Tier 2'} approval ${decision}d for Plan ${approval.phase}-${approval.plan}`,
111
- };
112
- }
113
-
114
- function writeAuditEntry(entry) {
115
- try {
116
- const paths = getPaths();
117
- if (!fs.existsSync(path.dirname(paths.audit))) return;
118
- // UC-04b: unified, hash-chained, durable append into the single verifiable chain.
119
- const { appendAuditEntrySync } = require('../autonomous/audit-writer');
120
- appendAuditEntrySync(paths.audit, entry);
121
- } catch { /* ignore AUDIT write failures */ }
122
- }
123
-
124
- function listApprovals() {
125
- const paths = getPaths();
126
- if (!fs.existsSync(paths.approvals)) return [];
127
- return fs.readdirSync(paths.approvals)
128
- .filter(f => f.startsWith('APPROVAL-') && f.endsWith('.json'))
129
- .map(f => {
130
- try { return JSON.parse(fs.readFileSync(path.join(paths.approvals, f), 'utf8')); }
131
- catch { return null; }
132
- })
133
- .filter(Boolean);
134
- }
135
-
136
- module.exports = { processDecision, listApprovals };