mindforge-cc 10.0.3 → 11.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (333) hide show
  1. package/.mindforge/MINDFORGE-V2-SCHEMA.json +43 -10
  2. package/.mindforge/config.json +30 -2
  3. package/.mindforge/engine/cross-model-eval.md +74 -0
  4. package/.mindforge/engine/proactive/signal-detector.md +60 -0
  5. package/.mindforge/engine/proactive/suggestion-engine.md +100 -0
  6. package/.mindforge/personas/agent-architect.md +57 -0
  7. package/.mindforge/personas/agent-evaluator.md +162 -0
  8. package/.mindforge/personas/agent-memory-designer.md +157 -0
  9. package/.mindforge/personas/agent-ops-engineer.md +120 -0
  10. package/.mindforge/personas/agent-orchestrator.md +112 -0
  11. package/.mindforge/personas/ai-economist.md +57 -0
  12. package/.mindforge/personas/ai-safety-engineer.md +57 -0
  13. package/.mindforge/personas/analytics-engineer.md +57 -0
  14. package/.mindforge/personas/anti-pattern-hunter.md +61 -0
  15. package/.mindforge/personas/api-gateway-designer.md +132 -0
  16. package/.mindforge/personas/auth-engineer.md +112 -0
  17. package/.mindforge/personas/build-engineer.md +57 -0
  18. package/.mindforge/personas/business-analyst.md +56 -0
  19. package/.mindforge/personas/cache-architect.md +100 -0
  20. package/.mindforge/personas/causal-scientist.md +57 -0
  21. package/.mindforge/personas/cdn-architect.md +118 -0
  22. package/.mindforge/personas/change-agent.md +104 -0
  23. package/.mindforge/personas/code-narrator.md +52 -0
  24. package/.mindforge/personas/codegen-specialist.md +68 -0
  25. package/.mindforge/personas/communication-architect.md +102 -0
  26. package/.mindforge/personas/compliance-engineer.md +96 -0
  27. package/.mindforge/personas/consensus-engineer.md +116 -0
  28. package/.mindforge/personas/contract-tester.md +60 -192
  29. package/.mindforge/personas/data-architect.md +108 -0
  30. package/.mindforge/personas/data-mesh-architect.md +57 -0
  31. package/.mindforge/personas/data-pipeline-architect.md +120 -0
  32. package/.mindforge/personas/de-sloppifier.md +60 -0
  33. package/.mindforge/personas/debt-manager.md +66 -0
  34. package/.mindforge/personas/decision-architect.md +82 -51
  35. package/.mindforge/personas/deployment-captain.md +74 -0
  36. package/.mindforge/personas/design-system-lead.md +112 -0
  37. package/.mindforge/personas/dmux-orchestrator.md +75 -0
  38. package/.mindforge/personas/dx-engineer.md +96 -0
  39. package/.mindforge/personas/ecommerce-engineer.md +57 -0
  40. package/.mindforge/personas/edge-engineer.md +94 -0
  41. package/.mindforge/personas/edtech-architect.md +106 -0
  42. package/.mindforge/personas/embedding-architect.md +57 -0
  43. package/.mindforge/personas/environment-engineer.md +57 -0
  44. package/.mindforge/personas/eval-judge.md +55 -0
  45. package/.mindforge/personas/event-architect.md +102 -0
  46. package/.mindforge/personas/experiment-designer.md +138 -0
  47. package/.mindforge/personas/feature-store-engineer.md +57 -0
  48. package/.mindforge/personas/finops-analyst.md +66 -0
  49. package/.mindforge/personas/fintech-architect.md +57 -0
  50. package/.mindforge/personas/flutter-engineer.md +104 -0
  51. package/.mindforge/personas/gaming-engineer.md +57 -0
  52. package/.mindforge/personas/graphql-designer.md +73 -0
  53. package/.mindforge/personas/healthcare-engineer.md +57 -0
  54. package/.mindforge/personas/hiring-strategist.md +105 -0
  55. package/.mindforge/personas/hitl-architect.md +165 -0
  56. package/.mindforge/personas/i18n-architect.md +69 -0
  57. package/.mindforge/personas/iot-architect.md +105 -0
  58. package/.mindforge/personas/knowledge-curator.md +139 -0
  59. package/.mindforge/personas/knowledge-engineer.md +57 -0
  60. package/.mindforge/personas/lakehouse-architect.md +57 -0
  61. package/.mindforge/personas/llm-orchestrator.md +57 -0
  62. package/.mindforge/personas/logistics-architect.md +106 -0
  63. package/.mindforge/personas/market-analyst.md +53 -0
  64. package/.mindforge/personas/marketplace-engineer.md +105 -0
  65. package/.mindforge/personas/mcp-designer.md +54 -0
  66. package/.mindforge/personas/meeting-designer.md +104 -0
  67. package/.mindforge/personas/mentorship-lead.md +106 -0
  68. package/.mindforge/personas/migration-architect.md +57 -0
  69. package/.mindforge/personas/ml-ops-engineer.md +101 -0
  70. package/.mindforge/personas/mobile-architect.md +105 -0
  71. package/.mindforge/personas/mobile-security-engineer.md +106 -0
  72. package/.mindforge/personas/multi-tenancy-architect.md +71 -0
  73. package/.mindforge/personas/multimodal-engineer.md +57 -0
  74. package/.mindforge/personas/offline-specialist.md +105 -0
  75. package/.mindforge/personas/onboarding-navigator.md +63 -0
  76. package/.mindforge/personas/payments-engineer.md +135 -0
  77. package/.mindforge/personas/pipeline-engineer.md +115 -0
  78. package/.mindforge/personas/platform-engineer.md +97 -0
  79. package/.mindforge/personas/platform-lead.md +57 -0
  80. package/.mindforge/personas/privacy-engineer.md +57 -0
  81. package/.mindforge/personas/product-owner.md +56 -0
  82. package/.mindforge/personas/productivity-analyst.md +57 -0
  83. package/.mindforge/personas/prompt-architect.md +101 -0
  84. package/.mindforge/personas/proofreader.md +53 -0
  85. package/.mindforge/personas/pwa-architect.md +105 -0
  86. package/.mindforge/personas/quality-scorer.md +63 -0
  87. package/.mindforge/personas/react-native-engineer.md +106 -0
  88. package/.mindforge/personas/resilience-engineer.md +69 -0
  89. package/.mindforge/personas/rfc-architect.md +64 -0
  90. package/.mindforge/personas/saga-orchestrator.md +80 -0
  91. package/.mindforge/personas/secrets-engineer.md +57 -0
  92. package/.mindforge/personas/skill-smith.md +79 -0
  93. package/.mindforge/personas/sre-lead.md +107 -0
  94. package/.mindforge/personas/stream-engineer.md +57 -0
  95. package/.mindforge/personas/streaming-engineer.md +64 -0
  96. package/.mindforge/personas/swarm-templates.json +674 -44
  97. package/.mindforge/personas/system-designer.md +57 -0
  98. package/.mindforge/personas/team-coach.md +120 -0
  99. package/.mindforge/personas/tech-lead-coach.md +103 -0
  100. package/.mindforge/personas/technical-writer-lead.md +111 -0
  101. package/.mindforge/personas/vibe-checker.md +75 -0
  102. package/.mindforge/personas/worktree-manager.md +56 -0
  103. package/.mindforge/personas/zero-trust-engineer.md +113 -0
  104. package/.mindforge/skills/a11y-testing/SKILL.md +143 -0
  105. package/.mindforge/skills/agent-evaluation-framework/SKILL.md +227 -0
  106. package/.mindforge/skills/agent-memory-design/SKILL.md +199 -0
  107. package/.mindforge/skills/agent-orchestration-patterns/SKILL.md +129 -0
  108. package/.mindforge/skills/agent-tool-selection/SKILL.md +204 -0
  109. package/.mindforge/skills/ai-agent-deployment/SKILL.md +176 -0
  110. package/.mindforge/skills/ai-cost-management/SKILL.md +57 -0
  111. package/.mindforge/skills/ai-safety-alignment/SKILL.md +53 -0
  112. package/.mindforge/skills/analytics-instrumentation/SKILL.md +172 -0
  113. package/.mindforge/skills/api-gateway-patterns/SKILL.md +177 -0
  114. package/.mindforge/skills/api-marketplace/SKILL.md +56 -0
  115. package/.mindforge/skills/api-versioning/SKILL.md +100 -0
  116. package/.mindforge/skills/app-store-deployment/SKILL.md +44 -0
  117. package/.mindforge/skills/architecture-tradeoff-analysis/SKILL.md +97 -0
  118. package/.mindforge/skills/audit-logging/SKILL.md +140 -0
  119. package/.mindforge/skills/auth-patterns/SKILL.md +148 -0
  120. package/.mindforge/skills/autonomous-agent-harness/SKILL.md +218 -0
  121. package/.mindforge/skills/autonomous-agents/SKILL.md +59 -0
  122. package/.mindforge/skills/build-system-optimization/SKILL.md +54 -0
  123. package/.mindforge/skills/build-vs-buy/SKILL.md +80 -0
  124. package/.mindforge/skills/bundle-optimization/SKILL.md +174 -0
  125. package/.mindforge/skills/business-analyst/SKILL.md +82 -0
  126. package/.mindforge/skills/caching-strategies/SKILL.md +132 -0
  127. package/.mindforge/skills/capacity-planning/SKILL.md +96 -0
  128. package/.mindforge/skills/causal-inference/SKILL.md +42 -0
  129. package/.mindforge/skills/cdn-optimization/SKILL.md +212 -0
  130. package/.mindforge/skills/change-management/SKILL.md +106 -0
  131. package/.mindforge/skills/chaos-engineering/SKILL.md +99 -0
  132. package/.mindforge/skills/ci-cd-pipeline/SKILL.md +118 -0
  133. package/.mindforge/skills/cli-design/SKILL.md +118 -0
  134. package/.mindforge/skills/code-generation-patterns/SKILL.md +92 -0
  135. package/.mindforge/skills/code-review-methodology/SKILL.md +180 -0
  136. package/.mindforge/skills/code-tour/SKILL.md +145 -0
  137. package/.mindforge/skills/codebase-onboarding/SKILL.md +95 -0
  138. package/.mindforge/skills/compliance-as-code/SKILL.md +195 -0
  139. package/.mindforge/skills/conflict-resolution/SKILL.md +87 -0
  140. package/.mindforge/skills/connection-pooling/SKILL.md +151 -0
  141. package/.mindforge/skills/container-security/SKILL.md +151 -0
  142. package/.mindforge/skills/context-engineering/SKILL.md +114 -0
  143. package/.mindforge/skills/contract-testing/SKILL.md +85 -0
  144. package/.mindforge/skills/cost-estimation/SKILL.md +82 -0
  145. package/.mindforge/skills/cqrs-event-sourcing/SKILL.md +95 -0
  146. package/.mindforge/skills/cross-platform-testing/SKILL.md +43 -0
  147. package/.mindforge/skills/data-governance/SKILL.md +42 -0
  148. package/.mindforge/skills/data-lakehouse/SKILL.md +42 -0
  149. package/.mindforge/skills/data-mesh/SKILL.md +42 -0
  150. package/.mindforge/skills/data-modeling/SKILL.md +107 -0
  151. package/.mindforge/skills/data-pipeline-design/SKILL.md +171 -0
  152. package/.mindforge/skills/data-privacy-engineering/SKILL.md +42 -0
  153. package/.mindforge/skills/database-performance/SKILL.md +174 -0
  154. package/.mindforge/skills/database-sharding-advanced/SKILL.md +206 -0
  155. package/.mindforge/skills/de-sloppify/SKILL.md +120 -0
  156. package/.mindforge/skills/defense-in-depth/SKILL.md +84 -0
  157. package/.mindforge/skills/delegation-patterns/SKILL.md +123 -0
  158. package/.mindforge/skills/dependency-management/SKILL.md +94 -0
  159. package/.mindforge/skills/deployment-workflow/SKILL.md +135 -0
  160. package/.mindforge/skills/design-system/SKILL.md +113 -0
  161. package/.mindforge/skills/developer-onboarding/SKILL.md +99 -0
  162. package/.mindforge/skills/developer-productivity-metrics/SKILL.md +59 -0
  163. package/.mindforge/skills/distributed-consensus/SKILL.md +141 -0
  164. package/.mindforge/skills/dmux-workflows/SKILL.md +141 -0
  165. package/.mindforge/skills/dns-architecture/SKILL.md +167 -0
  166. package/.mindforge/skills/ecommerce-architecture/SKILL.md +41 -0
  167. package/.mindforge/skills/edge-computing/SKILL.md +91 -0
  168. package/.mindforge/skills/edtech-platform/SKILL.md +41 -0
  169. package/.mindforge/skills/email-deliverability/SKILL.md +177 -0
  170. package/.mindforge/skills/embedding-systems/SKILL.md +55 -0
  171. package/.mindforge/skills/environment-management/SKILL.md +54 -0
  172. package/.mindforge/skills/error-handling-architecture/SKILL.md +118 -0
  173. package/.mindforge/skills/estimation-techniques/SKILL.md +113 -0
  174. package/.mindforge/skills/eval-harness/SKILL.md +180 -0
  175. package/.mindforge/skills/event-driven-architecture/SKILL.md +162 -0
  176. package/.mindforge/skills/experiment-design/SKILL.md +139 -0
  177. package/.mindforge/skills/experiment-platform/SKILL.md +43 -0
  178. package/.mindforge/skills/feature-engineering/SKILL.md +42 -0
  179. package/.mindforge/skills/feature-flag-management/SKILL.md +183 -0
  180. package/.mindforge/skills/fine-tuning-workflow/SKILL.md +189 -0
  181. package/.mindforge/skills/fintech-patterns/SKILL.md +41 -0
  182. package/.mindforge/skills/flutter-architecture/SKILL.md +42 -0
  183. package/.mindforge/skills/gaming-backend/SKILL.md +41 -0
  184. package/.mindforge/skills/git-workflow-design/SKILL.md +129 -0
  185. package/.mindforge/skills/graceful-degradation/SKILL.md +95 -0
  186. package/.mindforge/skills/graphql-patterns/SKILL.md +243 -0
  187. package/.mindforge/skills/guardrails-and-safety/SKILL.md +137 -0
  188. package/.mindforge/skills/healthcare-systems/SKILL.md +40 -0
  189. package/.mindforge/skills/hiring-engineering/SKILL.md +119 -0
  190. package/.mindforge/skills/human-in-the-loop-design/SKILL.md +234 -0
  191. package/.mindforge/skills/i18n-architecture/SKILL.md +147 -0
  192. package/.mindforge/skills/idempotency-patterns/SKILL.md +84 -0
  193. package/.mindforge/skills/incident-communication/SKILL.md +96 -0
  194. package/.mindforge/skills/incident-management/SKILL.md +97 -0
  195. package/.mindforge/skills/infrastructure-as-code/SKILL.md +98 -0
  196. package/.mindforge/skills/instinct-clustering/SKILL.md +190 -0
  197. package/.mindforge/skills/internal-developer-platform/SKILL.md +51 -0
  198. package/.mindforge/skills/iot-platform/SKILL.md +41 -0
  199. package/.mindforge/skills/k8s-deployment/SKILL.md +358 -0
  200. package/.mindforge/skills/knowledge-graphs/SKILL.md +56 -0
  201. package/.mindforge/skills/knowledge-sharing-systems/SKILL.md +112 -0
  202. package/.mindforge/skills/llm-cost-optimization/SKILL.md +198 -0
  203. package/.mindforge/skills/llm-orchestration/SKILL.md +56 -0
  204. package/.mindforge/skills/load-testing/SKILL.md +84 -0
  205. package/.mindforge/skills/logistics-optimization/SKILL.md +40 -0
  206. package/.mindforge/skills/market-researcher/SKILL.md +99 -0
  207. package/.mindforge/skills/marketplace-trust/SKILL.md +40 -0
  208. package/.mindforge/skills/mcp-server-patterns/SKILL.md +264 -0
  209. package/.mindforge/skills/media-streaming/SKILL.md +41 -0
  210. package/.mindforge/skills/meeting-architecture/SKILL.md +146 -0
  211. package/.mindforge/skills/mentoring-patterns/SKILL.md +77 -0
  212. package/.mindforge/skills/microservices-patterns/SKILL.md +83 -0
  213. package/.mindforge/skills/migration-platform/SKILL.md +61 -0
  214. package/.mindforge/skills/migration-strategies/SKILL.md +129 -0
  215. package/.mindforge/skills/ml-feature-store/SKILL.md +56 -0
  216. package/.mindforge/skills/ml-monitoring/SKILL.md +42 -0
  217. package/.mindforge/skills/mobile-performance/SKILL.md +44 -0
  218. package/.mindforge/skills/mobile-security/SKILL.md +45 -0
  219. package/.mindforge/skills/model-evaluation/SKILL.md +53 -0
  220. package/.mindforge/skills/monorepo-management/SKILL.md +100 -0
  221. package/.mindforge/skills/multi-tenancy-patterns/SKILL.md +145 -0
  222. package/.mindforge/skills/multi-turn-conversation-design/SKILL.md +206 -0
  223. package/.mindforge/skills/multimodal-ai/SKILL.md +51 -0
  224. package/.mindforge/skills/mutation-testing/SKILL.md +97 -0
  225. package/.mindforge/skills/notification-system-design/SKILL.md +168 -0
  226. package/.mindforge/skills/observability-stack/SKILL.md +136 -0
  227. package/.mindforge/skills/offline-first-design/SKILL.md +43 -0
  228. package/.mindforge/skills/on-call-design/SKILL.md +111 -0
  229. package/.mindforge/skills/pagination-patterns/SKILL.md +230 -0
  230. package/.mindforge/skills/payment-integration/SKILL.md +176 -0
  231. package/.mindforge/skills/performance-reviews/SKILL.md +140 -0
  232. package/.mindforge/skills/platform-observability/SKILL.md +58 -0
  233. package/.mindforge/skills/platform-reliability/SKILL.md +52 -0
  234. package/.mindforge/skills/post-incident-learning/SKILL.md +96 -0
  235. package/.mindforge/skills/product-manager/SKILL.md +104 -0
  236. package/.mindforge/skills/progressive-web-app/SKILL.md +44 -0
  237. package/.mindforge/skills/prompt-engineering/SKILL.md +94 -0
  238. package/.mindforge/skills/proofreader/SKILL.md +158 -0
  239. package/.mindforge/skills/push-notification-architecture/SKILL.md +45 -0
  240. package/.mindforge/skills/python-performance/SKILL.md +183 -0
  241. package/.mindforge/skills/quality-audit/SKILL.md +171 -0
  242. package/.mindforge/skills/queue-design/SKILL.md +85 -0
  243. package/.mindforge/skills/rag-architecture/SKILL.md +176 -0
  244. package/.mindforge/skills/rate-limiting-design/SKILL.md +94 -0
  245. package/.mindforge/skills/react-native-patterns/SKILL.md +42 -0
  246. package/.mindforge/skills/react-performance/SKILL.md +229 -0
  247. package/.mindforge/skills/real-time-analytics/SKILL.md +42 -0
  248. package/.mindforge/skills/real-time-sync/SKILL.md +83 -0
  249. package/.mindforge/skills/responsive-native/SKILL.md +44 -0
  250. package/.mindforge/skills/responsive-patterns/SKILL.md +141 -0
  251. package/.mindforge/skills/rfc-pipeline/SKILL.md +114 -0
  252. package/.mindforge/skills/saas-multi-tenant/SKILL.md +41 -0
  253. package/.mindforge/skills/santa-method/SKILL.md +134 -0
  254. package/.mindforge/skills/search-implementation/SKILL.md +98 -0
  255. package/.mindforge/skills/secrets-platform/SKILL.md +56 -0
  256. package/.mindforge/skills/secrets-rotation/SKILL.md +173 -0
  257. package/.mindforge/skills/self-serve-infrastructure/SKILL.md +51 -0
  258. package/.mindforge/skills/serverless-patterns/SKILL.md +119 -0
  259. package/.mindforge/skills/skill-creator-meta/SKILL.md +146 -0
  260. package/.mindforge/skills/sprint-retrospective-facilitation/SKILL.md +112 -0
  261. package/.mindforge/skills/stakeholder-communication/SKILL.md +85 -0
  262. package/.mindforge/skills/state-management/SKILL.md +104 -0
  263. package/.mindforge/skills/stream-processing/SKILL.md +43 -0
  264. package/.mindforge/skills/streaming-architecture/SKILL.md +81 -0
  265. package/.mindforge/skills/supply-chain-security/SKILL.md +145 -0
  266. package/.mindforge/skills/synthetic-data-generation/SKILL.md +52 -0
  267. package/.mindforge/skills/system-design/SKILL.md +88 -0
  268. package/.mindforge/skills/team-topology-design/SKILL.md +107 -0
  269. package/.mindforge/skills/technical-debt-management/SKILL.md +86 -0
  270. package/.mindforge/skills/technical-interview-design/SKILL.md +98 -0
  271. package/.mindforge/skills/technical-leadership/SKILL.md +75 -0
  272. package/.mindforge/skills/technical-writing/SKILL.md +237 -0
  273. package/.mindforge/skills/technology-radar/SKILL.md +88 -0
  274. package/.mindforge/skills/testing-anti-patterns/SKILL.md +288 -0
  275. package/.mindforge/skills/tool-design/SKILL.md +138 -0
  276. package/.mindforge/skills/typescript-advanced/SKILL.md +198 -0
  277. package/.mindforge/skills/using-git-worktrees/SKILL.md +139 -0
  278. package/.mindforge/skills/verification-loop/SKILL.md +13 -1
  279. package/.mindforge/skills/vibe-security/SKILL.md +165 -0
  280. package/.mindforge/skills/visual-regression-testing/SKILL.md +97 -0
  281. package/.mindforge/skills/websocket-patterns/SKILL.md +203 -0
  282. package/.mindforge/skills/writing-plans/SKILL.md +170 -0
  283. package/.mindforge/skills/writing-skills/SKILL.md +216 -0
  284. package/.mindforge/skills/zero-trust-architecture/SKILL.md +166 -0
  285. package/CHANGELOG.md +240 -0
  286. package/MINDFORGE.md +4 -4
  287. package/README.md +49 -4
  288. package/RELEASENOTES.md +80 -0
  289. package/SECURITY.md +20 -8
  290. package/bin/autonomous/audit-writer.js +13 -0
  291. package/bin/autonomous/auto-runner.js +74 -16
  292. package/bin/autonomous/context-refactorer.js +26 -11
  293. package/bin/autonomous/state-manager.js +62 -6
  294. package/bin/autonomous/stuck-monitor.js +46 -7
  295. package/bin/autonomous/wave-executor.js +66 -25
  296. package/bin/dashboard/api-router.js +43 -0
  297. package/bin/dashboard/metrics-aggregator.js +28 -1
  298. package/bin/dashboard/server.js +67 -4
  299. package/bin/dashboard/sse-bridge.js +4 -4
  300. package/bin/engine/feedback-loop.js +8 -0
  301. package/bin/engine/intelligence-interlock.js +32 -15
  302. package/bin/engine/logic-drift-detector.js +2 -1
  303. package/bin/engine/nexus-tracer.js +3 -2
  304. package/bin/engine/remediation-engine.js +155 -32
  305. package/bin/engine/self-corrective-synthesizer.js +84 -10
  306. package/bin/engine/sre-manager.js +12 -4
  307. package/bin/engine/temporal-hub.js +131 -34
  308. package/bin/governance/approve.js +41 -5
  309. package/bin/governance/impact-analyzer.js +28 -0
  310. package/bin/governance/policy-engine.js +10 -3
  311. package/bin/governance/quantum-crypto.js +32 -19
  312. package/bin/governance/rbac-manager.js +74 -2
  313. package/bin/governance/ztai-manager.js +49 -7
  314. package/bin/hindsight-injector.js +3 -3
  315. package/bin/memory/eis-client.js +71 -34
  316. package/bin/memory/embedding-engine.js +61 -0
  317. package/bin/memory/knowledge-graph.js +58 -5
  318. package/bin/memory/knowledge-indexer.js +53 -6
  319. package/bin/memory/knowledge-store.js +22 -0
  320. package/bin/migrations/10.7.0-to-11.0.0.js +110 -0
  321. package/bin/migrations/schema-versions.js +13 -0
  322. package/bin/models/anthropic-provider.js +45 -0
  323. package/bin/models/cloud-broker.js +68 -20
  324. package/bin/models/gemini-provider.js +51 -0
  325. package/bin/models/model-client.js +20 -0
  326. package/bin/models/model-router.js +28 -8
  327. package/bin/models/openai-provider.js +44 -0
  328. package/bin/utils/file-io.js +63 -1
  329. package/bin/utils/index.js +58 -0
  330. package/docs/getting-started.md +1 -1
  331. package/docs/user-guide.md +2 -2
  332. package/package.json +2 -2
  333. package/.mindforge/personas/data-privacy-engineer.md +0 -187
@@ -122,9 +122,10 @@ class QuantumSafeKeyProvider extends KeyProvider {
122
122
  async sign(did, data) {
123
123
  const record = this.keyStore.get(did);
124
124
  if (!record) throw new Error(`PQ record not found for ${did}`);
125
-
125
+
126
126
  console.log(`[PQAS-DILITHIUM] Delegating signature to lattice enclave [DID: ${did}]`);
127
- return await this.quantumCrypto.signPQ(data, record.privateKey);
127
+ const result = await this.quantumCrypto.signPQ(data, record.privateKey);
128
+ return result;
128
129
  }
129
130
 
130
131
  async rotate(did) {
@@ -148,24 +149,34 @@ class ZTAIManager {
148
149
 
149
150
  /**
150
151
  * Registers a new agent and assigns a provider based on Trust Tier.
152
+ * @param {string} persona - Agent persona identifier
153
+ * @param {number} tier - Trust tier (1-4)
154
+ * @param {string|null} sessionId - Optional session scope for isolation
151
155
  */
152
- async registerAgent(persona, tier = 1) {
156
+ async registerAgent(persona, tier = 1, sessionId = null) {
153
157
  const uuid = crypto.randomUUID();
154
158
  const did = `did:mindforge:${uuid}`;
155
-
159
+
156
160
  // Tier 3 agents use the SecureEnclaveProvider
157
161
  const providerType = tier >= 3 ? 'enclave' : 'local';
158
162
  const provider = this.providers[providerType];
159
-
163
+
160
164
  const publicKeyPEM = await provider.generate(did);
161
165
 
162
- this.agentRegistry.set(did, {
166
+ const agentData = {
163
167
  publicKey: publicKeyPEM,
164
168
  persona,
165
169
  tier,
166
170
  providerType,
167
171
  createdAt: new Date().toISOString()
168
- });
172
+ };
173
+
174
+ // Store sessionId if provided for session-scoped isolation
175
+ if (sessionId) {
176
+ agentData.sessionId = sessionId;
177
+ }
178
+
179
+ this.agentRegistry.set(did, agentData);
169
180
 
170
181
  return did;
171
182
  }
@@ -219,6 +230,37 @@ class ZTAIManager {
219
230
  return this.agentRegistry.get(did);
220
231
  }
221
232
 
233
+ /**
234
+ * Returns all agents registered under a specific session.
235
+ * @param {string} sessionId - Session identifier to filter by
236
+ */
237
+ getSessionAgents(sessionId) {
238
+ const results = [];
239
+ for (const [did, agent] of this.agentRegistry.entries()) {
240
+ if (agent.sessionId === sessionId) {
241
+ results.push({ did, ...agent });
242
+ }
243
+ }
244
+ return results;
245
+ }
246
+
247
+ /**
248
+ * Revokes all agents belonging to a session. Used for session cleanup.
249
+ * @param {string} sessionId - Session identifier
250
+ */
251
+ revokeSessionAgents(sessionId) {
252
+ const dids = [];
253
+ for (const [did, agent] of this.agentRegistry.entries()) {
254
+ if (agent.sessionId === sessionId) {
255
+ dids.push(did);
256
+ }
257
+ }
258
+ for (const did of dids) {
259
+ this.revokeAgent(did);
260
+ }
261
+ return dids;
262
+ }
263
+
222
264
  /**
223
265
  * Specialized signing for FinOps budget decisions (Pillar V).
224
266
  */
@@ -43,9 +43,9 @@ class HindsightInjector {
43
43
  }
44
44
 
45
45
  // 4. Capture the new state immediately
46
- TemporalHub.captureState(hindsightEvent.id, {
47
- event: 'hindsight_injected',
48
- target_id: auditId
46
+ await TemporalHub.captureState(hindsightEvent.id, {
47
+ event: 'hindsight_injected',
48
+ target_id: auditId
49
49
  });
50
50
 
51
51
  return { success: true, event: hindsightEvent };
@@ -22,19 +22,42 @@ class EISClient {
22
22
  * @param {Array} entries - Local knowledge entries to sync.
23
23
  */
24
24
  async push(entries) {
25
- console.log(`[EIS-SYNC] Pushing ${entries.length} entries to Enterprise Intelligence Service...`);
26
-
27
- // Simulate network request
28
- return new Promise((resolve) => {
29
- setTimeout(() => {
30
- const results = entries.map(e => ({
31
- id: e.id,
32
- status: 'synced',
33
- version: crypto.createHash('sha256').update(JSON.stringify(e)).digest('hex').slice(0, 8)
34
- }));
35
- resolve(results);
36
- }, 500);
37
- });
25
+ if (!this.endpoint || this.endpoint === 'http://localhost:7340') {
26
+ return {
27
+ synced: entries.length,
28
+ hashes: entries.map(e => e.id || crypto.createHash('sha256').update(JSON.stringify(e)).digest('hex').slice(0, 8))
29
+ };
30
+ }
31
+
32
+ const url = `${this.endpoint}/api/v1/knowledge/push`;
33
+ const body = JSON.stringify({ entries, orgId: this.orgId });
34
+
35
+ let lastError;
36
+ for (let attempt = 0; attempt < 3; attempt++) {
37
+ try {
38
+ const headers = await this.getAuthHeader('push', 'knowledge');
39
+ headers['Content-Type'] = 'application/json';
40
+
41
+ const response = await fetch(url, {
42
+ method: 'POST',
43
+ headers,
44
+ body,
45
+ signal: AbortSignal.timeout(10000)
46
+ });
47
+
48
+ if (!response.ok) {
49
+ throw new Error(`EIS push failed: ${response.status}`);
50
+ }
51
+
52
+ return await response.json();
53
+ } catch (e) {
54
+ lastError = e;
55
+ await new Promise(r => setTimeout(r, 1000 * Math.pow(2, attempt)));
56
+ }
57
+ }
58
+
59
+ console.warn(`[EIS] Push failed after 3 retries: ${lastError.message}`);
60
+ return { synced: 0, error: lastError.message };
38
61
  }
39
62
 
40
63
  /**
@@ -42,35 +65,49 @@ class EISClient {
42
65
  * @param {Object} filter - Filter criteria (e.g. since timestamp).
43
66
  */
44
67
  async pull(filter = {}) {
45
- console.log(`[EIS-SYNC] Pulling new organizational knowledge from ${this.endpoint}...`);
46
-
47
- // Simulate network response
48
- return new Promise((resolve) => {
49
- setTimeout(() => {
50
- // Return empty array for now as this is a simulation
51
- resolve([]);
52
- }, 300);
53
- });
68
+ if (!this.endpoint || this.endpoint === 'http://localhost:7340') {
69
+ return [];
70
+ }
71
+
72
+ const url = `${this.endpoint}/api/v1/knowledge/pull`;
73
+ const body = JSON.stringify({ filter, orgId: this.orgId });
74
+
75
+ let lastError;
76
+ for (let attempt = 0; attempt < 3; attempt++) {
77
+ try {
78
+ const headers = await this.getAuthHeader('pull', 'knowledge');
79
+ headers['Content-Type'] = 'application/json';
80
+
81
+ const response = await fetch(url, {
82
+ method: 'POST',
83
+ headers,
84
+ body,
85
+ signal: AbortSignal.timeout(10000)
86
+ });
87
+
88
+ if (!response.ok) {
89
+ throw new Error(`EIS pull failed: ${response.status}`);
90
+ }
91
+
92
+ return await response.json();
93
+ } catch (e) {
94
+ lastError = e;
95
+ await new Promise(r => setTimeout(r, 1000 * Math.pow(2, attempt)));
96
+ }
97
+ }
98
+
99
+ console.warn(`[EIS] Pull failed after 3 retries: ${lastError.message}`);
100
+ return [];
54
101
  }
55
102
 
56
- /**
57
- * Verifies the authenticity of a remote knowledge entry.
58
- * @param {Object} entry - The remote entry.
59
- * @param {String} signature - The ZTAI signature from the remote agent.
60
- */
103
+ // TODO: implement when remote nodes are available
61
104
  verifyRemoteProvenance(entry, signature) {
62
105
  if (!signature) return false;
63
- // Real implementation would use ZTAIManager to verify the DID signature
64
106
  return true;
65
107
  }
66
108
 
67
- /**
68
- * Resolves a remote node reference.
69
- * @param {String} nodeId - The ID of the remote node.
70
- */
109
+ // TODO: implement when remote nodes are available
71
110
  async resolveRemoteNode(nodeId) {
72
- console.log(`[EIS-RESOLVE] Resolving remote node: ${nodeId}`);
73
- // Real implementation would fetch from the EIS API
74
111
  return null;
75
112
  }
76
113
 
@@ -130,6 +130,65 @@ function computeTfIdfVector(tokens, df, N) {
130
130
  return capped;
131
131
  }
132
132
 
133
+ // ── BM25 Scoring ─────────────────────────────────────────────────────────────
134
+
135
+ /**
136
+ * BM25 relevance scoring with document length normalization.
137
+ * @param {string[]} queryTokens - Tokenized query
138
+ * @param {string[]} docTokens - Tokenized document
139
+ * @param {Object<string, number>} docFrequency - term → number of docs containing term
140
+ * @param {number} totalDocs - Total documents in corpus
141
+ * @param {number} avgDocLength - Average document length across corpus
142
+ * @returns {number} BM25 score
143
+ */
144
+ function bm25Score(queryTokens, docTokens, docFrequency, totalDocs, avgDocLength) {
145
+ const k1 = 1.5;
146
+ const b = 0.75;
147
+ let score = 0;
148
+ const docLength = docTokens.length;
149
+
150
+ for (const term of queryTokens) {
151
+ const tf = docTokens.filter(t => t === term).length;
152
+ const df = docFrequency[term] || 0;
153
+ const idf = Math.log((totalDocs - df + 0.5) / (df + 0.5) + 1);
154
+ const tfNorm = (tf * (k1 + 1)) / (tf + k1 * (1 - b + b * (docLength / avgDocLength)));
155
+ score += idf * tfNorm;
156
+ }
157
+ return score;
158
+ }
159
+
160
+ /**
161
+ * Build a reusable BM25 index structure from knowledge entries.
162
+ * Applies 2x weighting to compound terms (camelCase/underscore bigrams).
163
+ * @param {object[]} entries - Knowledge entries with { id, topic, content, tags }
164
+ * @returns {{ docFrequency: Object<string, number>, avgDocLength: number, tokenizedDocs: Array<{id: string, tokens: string[]}> }}
165
+ */
166
+ function buildBM25Index(entries) {
167
+ const tokenizedDocs = entries
168
+ .filter(e => !e.deprecated)
169
+ .map(e => {
170
+ const text = `${e.topic || ''} ${e.content || ''} ${(e.tags || []).join(' ')}`;
171
+ const unigrams = tokenize(text);
172
+ const bi = bigrams(unigrams);
173
+ // Weight compound terms at 2x by duplicating bigrams
174
+ const tokens = [...unigrams, ...bi, ...bi];
175
+ return { id: e.id, tokens };
176
+ });
177
+
178
+ const docFrequency = {};
179
+ for (const doc of tokenizedDocs) {
180
+ const unique = new Set(doc.tokens);
181
+ for (const term of unique) {
182
+ docFrequency[term] = (docFrequency[term] || 0) + 1;
183
+ }
184
+ }
185
+
186
+ const totalTokens = tokenizedDocs.reduce((sum, doc) => sum + doc.tokens.length, 0);
187
+ const avgDocLength = tokenizedDocs.length > 0 ? totalTokens / tokenizedDocs.length : 0;
188
+
189
+ return { docFrequency, avgDocLength, tokenizedDocs };
190
+ }
191
+
133
192
  // ── Similarity ────────────────────────────────────────────────────────────────
134
193
 
135
194
  /**
@@ -321,6 +380,8 @@ module.exports = {
321
380
  inferEdges,
322
381
  saveCache,
323
382
  loadCache,
383
+ bm25Score,
384
+ buildBM25Index,
324
385
  SIMILARITY_THRESHOLD,
325
386
  SHADOW_THRESHOLD,
326
387
  };
@@ -109,6 +109,7 @@ function addEdge(edge) {
109
109
  record.checksum = crypto.createHash('sha256').update(payload).digest('hex');
110
110
 
111
111
  fs.appendFileSync(paths.EDGES_PATH, JSON.stringify(record) + '\n');
112
+ invalidateAdjacencyCache();
112
113
  return id;
113
114
  }
114
115
 
@@ -155,6 +156,7 @@ function deprecateEdge(edgeId, reason) {
155
156
  };
156
157
 
157
158
  fs.appendFileSync(paths.EDGES_PATH, JSON.stringify(deprecated) + '\n');
159
+ invalidateAdjacencyCache();
158
160
  }
159
161
 
160
162
  /**
@@ -181,18 +183,68 @@ function reinforceEdge(edgeId) {
181
183
  fs.appendFileSync(paths.EDGES_PATH, JSON.stringify(reinforced) + '\n');
182
184
  }
183
185
 
184
- // ── Adjacency Index ───────────────────────────────────────────────────────────
186
+ // ── Adjacency Index (with persistent cache) ─────────────────────────────────
187
+
188
+ function getAdjacencyCachePath() {
189
+ const paths = getPaths();
190
+ return path.join(paths.MEMORY_DIR, '.adjacency-cache.json');
191
+ }
192
+
193
+ function invalidateAdjacencyCache() {
194
+ const cachePath = getAdjacencyCachePath();
195
+ if (fs.existsSync(cachePath)) {
196
+ fs.unlinkSync(cachePath);
197
+ }
198
+ }
199
+
200
+ /**
201
+ * Load adjacency index from cache if edges file hasn't changed,
202
+ * otherwise rebuild and persist.
203
+ * @param {object[]} edges - All active edges (used for rebuild)
204
+ * @returns {Map<string, object[]>} nodeId → [{ edge, neighborId, direction }]
205
+ */
206
+ function loadOrBuildAdjacencyIndex(edges) {
207
+ const paths = getPaths();
208
+ const cachePath = getAdjacencyCachePath();
209
+ const edgesStat = fs.statSync(paths.EDGES_PATH, { throwIfNoEntry: false });
210
+
211
+ if (edgesStat && fs.existsSync(cachePath)) {
212
+ try {
213
+ const cache = JSON.parse(fs.readFileSync(cachePath, 'utf8'));
214
+ if (cache.mtime === edgesStat.mtimeMs) {
215
+ const index = new Map();
216
+ for (const [nodeId, neighbors] of Object.entries(cache.adjacency)) {
217
+ index.set(nodeId, neighbors);
218
+ }
219
+ return index;
220
+ }
221
+ } catch (e) { /* cache corrupt, rebuild */ }
222
+ }
223
+
224
+ const index = buildAdjacencyIndex(edges);
225
+
226
+ if (edgesStat) {
227
+ const serialized = {};
228
+ for (const [nodeId, neighbors] of index) {
229
+ serialized[nodeId] = neighbors;
230
+ }
231
+ const cacheData = { mtime: edgesStat.mtimeMs, adjacency: serialized };
232
+ ensureDir(paths.MEMORY_DIR);
233
+ fs.writeFileSync(cachePath, JSON.stringify(cacheData));
234
+ }
235
+
236
+ return index;
237
+ }
185
238
 
186
239
  /**
187
240
  * Build an in-memory adjacency index for O(1) neighbor lookups.
188
241
  * @param {object[]} edges - All active edges
189
- * @returns {Map<string, object[]>} nodeId → [{ edge, neighborId }]
242
+ * @returns {Map<string, object[]>} nodeId → [{ edge, neighborId, direction }]
190
243
  */
191
244
  function buildAdjacencyIndex(edges) {
192
245
  const index = new Map();
193
246
 
194
247
  for (const edge of edges) {
195
- // Forward direction
196
248
  if (!index.has(edge.sourceId)) index.set(edge.sourceId, []);
197
249
  index.get(edge.sourceId).push({
198
250
  edge,
@@ -200,7 +252,6 @@ function buildAdjacencyIndex(edges) {
200
252
  direction: 'outgoing',
201
253
  });
202
254
 
203
- // Reverse direction (for bidirectional traversal)
204
255
  if (!index.has(edge.targetId)) index.set(edge.targetId, []);
205
256
  index.get(edge.targetId).push({
206
257
  edge,
@@ -262,7 +313,7 @@ function addFederatedEdge(edge) {
262
313
  function traverse(startId, maxDepth = 2, opts = {}) {
263
314
  const { edgeTypes, minWeight = 0 } = opts;
264
315
  const edges = readAllEdges();
265
- const adjacency = buildAdjacencyIndex(edges);
316
+ const adjacency = loadOrBuildAdjacencyIndex(edges);
266
317
 
267
318
  const visited = new Set();
268
319
  const results = [];
@@ -598,6 +649,8 @@ module.exports = {
598
649
  deprecateEdge,
599
650
  reinforceEdge,
600
651
  buildAdjacencyIndex,
652
+ loadOrBuildAdjacencyIndex,
653
+ invalidateAdjacencyCache,
601
654
  traverse,
602
655
  findRelated,
603
656
  getNodeEdges,
@@ -9,7 +9,10 @@
9
9
  */
10
10
  'use strict';
11
11
 
12
+ const fs = require('fs');
13
+ const path = require('path');
12
14
  const Store = require('./knowledge-store');
15
+ const { buildBM25Index, bm25Score } = require('./embedding-engine');
13
16
 
14
17
  // ── Stopwords (excluded from TF-IDF scoring) ──────────────────────────────────
15
18
  const STOPWORDS = new Set([
@@ -79,6 +82,48 @@ function tfidfScore(queryTokens, entryId, index, docTokenCounts, N) {
79
82
  return score;
80
83
  }
81
84
 
85
+ // ── Persistent BM25 Index Cache ──────────────────────────────────────────────
86
+
87
+ function getKbPath() {
88
+ const memoryDir = path.join(process.cwd(), '.mindforge', 'memory');
89
+ return path.join(memoryDir, 'knowledge.jsonl');
90
+ }
91
+
92
+ function getCachePath() {
93
+ const memoryDir = path.join(process.cwd(), '.mindforge', 'memory');
94
+ return path.join(memoryDir, '.index-cache.json');
95
+ }
96
+
97
+ /**
98
+ * Load BM25 index from cache if source file hasn't changed,
99
+ * otherwise rebuild and persist.
100
+ */
101
+ function loadOrBuildIndex(entries) {
102
+ const kbPath = getKbPath();
103
+ const cachePath = getCachePath();
104
+ const stat = fs.statSync(kbPath, { throwIfNoEntry: false });
105
+
106
+ if (stat && fs.existsSync(cachePath)) {
107
+ try {
108
+ const cache = JSON.parse(fs.readFileSync(cachePath, 'utf8'));
109
+ if (cache.mtime === stat.mtimeMs && cache.entryCount === entries.length) {
110
+ return cache.index;
111
+ }
112
+ } catch (e) { /* cache corrupt, rebuild */ }
113
+ }
114
+
115
+ const index = buildBM25Index(entries);
116
+
117
+ if (stat) {
118
+ const dir = path.dirname(cachePath);
119
+ if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
120
+ const cacheData = { mtime: stat.mtimeMs, entryCount: entries.length, index };
121
+ fs.writeFileSync(cachePath, JSON.stringify(cacheData));
122
+ }
123
+
124
+ return index;
125
+ }
126
+
82
127
  // ── Main search function ──────────────────────────────────────────────────────
83
128
  /**
84
129
  * Search knowledge base with TF-IDF scoring.
@@ -106,18 +151,20 @@ function search(queryText, filters = {}, limit = 10) {
106
151
 
107
152
  const queryTokens = tokenize(queryText);
108
153
  if (queryTokens.length === 0) {
109
- // No meaningful query tokens — return by confidence
110
154
  return candidates
111
155
  .sort((a, b) => b.confidence - a.confidence)
112
156
  .slice(0, limit);
113
157
  }
114
158
 
115
- const { index, docTokenCounts, N } = buildIndex(candidates);
159
+ // Use cached BM25 index for scoring
160
+ const bm25Index = loadOrBuildIndex(candidates);
161
+ const { docFrequency, avgDocLength, tokenizedDocs } = bm25Index;
162
+ const totalDocs = tokenizedDocs.length;
163
+ const docMap = new Map(tokenizedDocs.map(d => [d.id, d.tokens]));
116
164
 
117
- // Score each candidate
118
165
  const scored = candidates.map(entry => {
119
- const textScore = tfidfScore(queryTokens, entry.id, index, docTokenCounts, N);
120
- // Combine TF-IDF score with confidence, but only if there's a text match
166
+ const docTokens = docMap.get(entry.id) || [];
167
+ const textScore = bm25Score(queryTokens, docTokens, docFrequency, totalDocs, avgDocLength);
121
168
  const finalScore = textScore > 0
122
169
  ? textScore * 0.7 + entry.confidence * 0.3
123
170
  : 0;
@@ -169,4 +216,4 @@ function loadSessionContext(context = {}) {
169
216
  return { preferences, decisions, bugPatterns, codePatterns, domain };
170
217
  }
171
218
 
172
- module.exports = { search, loadSessionContext, buildIndex, tfidfScore, tokenize };
219
+ module.exports = { search, loadSessionContext, buildIndex, tfidfScore, tokenize, loadOrBuildIndex };
@@ -126,6 +126,22 @@ function getFilePath(type) {
126
126
  }
127
127
  }
128
128
 
129
+ // ── File Integrity ────────────────────────────────────────────────────────────
130
+
131
+ /**
132
+ * Ensures a JSONL file doesn't end with a partial/truncated line.
133
+ * Appends a trailing newline if missing — prevents corruption from propagating.
134
+ */
135
+ function verifyFileIntegrity(filePath) {
136
+ if (!fs.existsSync(filePath)) return true;
137
+ const content = fs.readFileSync(filePath, 'utf8');
138
+ if (content.length === 0) return true;
139
+ if (!content.endsWith('\n')) {
140
+ fs.appendFileSync(filePath, '\n');
141
+ }
142
+ return true;
143
+ }
144
+
129
145
  // ── Write operations ──────────────────────────────────────────────────────────
130
146
 
131
147
  /**
@@ -184,10 +200,12 @@ function add(entry) {
184
200
  };
185
201
 
186
202
  const filePath = getFilePath(entry.type);
203
+ verifyFileIntegrity(filePath);
187
204
  fs.appendFileSync(filePath, JSON.stringify(full) + '\n');
188
205
 
189
206
  // Also append to unified knowledge-base.jsonl for cross-type queries
190
207
  if (filePath !== paths.KB_PATH) {
208
+ verifyFileIntegrity(paths.KB_PATH);
191
209
  fs.appendFileSync(paths.KB_PATH, JSON.stringify(full) + '\n');
192
210
  }
193
211
 
@@ -217,8 +235,10 @@ function deprecate(id, reason, supersededBy = null) {
217
235
  deprecated_at: new Date().toISOString(),
218
236
  };
219
237
 
238
+ verifyFileIntegrity(filePath);
220
239
  fs.appendFileSync(filePath, JSON.stringify(deprecated) + '\n');
221
240
  if (filePath !== paths.KB_PATH) {
241
+ verifyFileIntegrity(paths.KB_PATH);
222
242
  fs.appendFileSync(paths.KB_PATH, JSON.stringify(deprecated) + '\n');
223
243
  }
224
244
 
@@ -246,8 +266,10 @@ function reinforce(id) {
246
266
  };
247
267
 
248
268
  const filePath = getFilePath(entry.type);
269
+ verifyFileIntegrity(filePath);
249
270
  fs.appendFileSync(filePath, JSON.stringify(reinforced) + '\n');
250
271
  if (filePath !== paths.KB_PATH) {
272
+ verifyFileIntegrity(paths.KB_PATH);
251
273
  fs.appendFileSync(paths.KB_PATH, JSON.stringify(reinforced) + '\n');
252
274
  }
253
275
 
@@ -0,0 +1,110 @@
1
+ 'use strict';
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+
6
+ const MIGRATION_ID = '10.7.0-to-11.0.0';
7
+ const TARGET_VERSION = '11.0.0';
8
+
9
+ async function migrate(projectRoot) {
10
+ const results = { steps: [], success: true };
11
+
12
+ // Step 1: Backup config.json
13
+ const configPath = path.join(projectRoot, '.mindforge', 'config.json');
14
+ if (fs.existsSync(configPath)) {
15
+ const backupPath = configPath + '.v10-backup';
16
+ fs.copyFileSync(configPath, backupPath);
17
+ results.steps.push({ step: 'backup_config', status: 'done', path: backupPath });
18
+
19
+ // Step 2: Add new config sections
20
+ try {
21
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
22
+
23
+ if (!config.temporal) {
24
+ config.temporal = { max_snapshots: 50, max_age_days: 7 };
25
+ }
26
+ if (!config.rate_limiting) {
27
+ config.rate_limiting = { dashboard_rpm: 100, model_rpm: {} };
28
+ }
29
+ if (!config.session) {
30
+ config.session = { token_expiry_hours: 24 };
31
+ }
32
+ if (!config.wave_execution) {
33
+ config.wave_execution = { max_concurrency: 3 };
34
+ }
35
+
36
+ config.version = TARGET_VERSION;
37
+
38
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n');
39
+ results.steps.push({ step: 'update_config', status: 'done' });
40
+ } catch (e) {
41
+ results.steps.push({ step: 'update_config', status: 'warning', error: e.message });
42
+ }
43
+ }
44
+
45
+ // Step 3: Archive old AUDIT lines if > 5000
46
+ const auditPath = path.join(projectRoot, '.planning', 'AUDIT.jsonl');
47
+ if (fs.existsSync(auditPath)) {
48
+ try {
49
+ const content = fs.readFileSync(auditPath, 'utf8');
50
+ const lines = content.split('\n').filter(l => l.trim());
51
+ if (lines.length > 5000) {
52
+ const archiveDir = path.join(projectRoot, '.planning', 'audit-archive');
53
+ if (!fs.existsSync(archiveDir)) fs.mkdirSync(archiveDir, { recursive: true });
54
+
55
+ const zlib = require('zlib');
56
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
57
+ const archivePath = path.join(archiveDir, `AUDIT-pre-v11-${timestamp}.jsonl.gz`);
58
+ const toArchive = lines.slice(0, -500).join('\n') + '\n';
59
+ fs.writeFileSync(archivePath, zlib.gzipSync(toArchive));
60
+
61
+ const remaining = lines.slice(-500).join('\n') + '\n';
62
+ fs.writeFileSync(auditPath, remaining);
63
+ results.steps.push({ step: 'archive_audit', status: 'done', archived: lines.length - 500 });
64
+ } else {
65
+ results.steps.push({ step: 'archive_audit', status: 'skipped', reason: 'under_threshold' });
66
+ }
67
+ } catch (e) {
68
+ results.steps.push({ step: 'archive_audit', status: 'warning', error: e.message });
69
+ }
70
+ }
71
+
72
+ // Step 4: GC old snapshots
73
+ try {
74
+ const TemporalHub = require('../engine/temporal-hub');
75
+ const gcResult = await TemporalHub.gc({ maxSnapshots: 50, maxAgeDays: 30 });
76
+ results.steps.push({ step: 'snapshot_gc', status: 'done', deleted: gcResult.deleted });
77
+ } catch (e) {
78
+ results.steps.push({ step: 'snapshot_gc', status: 'warning', error: e.message });
79
+ }
80
+
81
+ // Step 5: Bump schema_version in HANDOFF.json
82
+ const handoffPath = path.join(projectRoot, '.planning', 'HANDOFF.json');
83
+ if (fs.existsSync(handoffPath)) {
84
+ try {
85
+ const handoff = JSON.parse(fs.readFileSync(handoffPath, 'utf8'));
86
+ handoff.schema_version = TARGET_VERSION;
87
+ fs.writeFileSync(handoffPath, JSON.stringify(handoff, null, 2) + '\n');
88
+ results.steps.push({ step: 'bump_handoff_version', status: 'done' });
89
+ } catch (e) {
90
+ results.steps.push({ step: 'bump_handoff_version', status: 'warning', error: e.message });
91
+ }
92
+ }
93
+
94
+ // Step 6: Update MINDFORGE.md VERSION
95
+ const mindforgeFile = path.join(projectRoot, 'MINDFORGE.md');
96
+ if (fs.existsSync(mindforgeFile)) {
97
+ try {
98
+ let content = fs.readFileSync(mindforgeFile, 'utf8');
99
+ content = content.replace(/VERSION\s*=\s*[\d.]+/, `VERSION = ${TARGET_VERSION}`);
100
+ fs.writeFileSync(mindforgeFile, content);
101
+ results.steps.push({ step: 'bump_mindforge_version', status: 'done' });
102
+ } catch (e) {
103
+ results.steps.push({ step: 'bump_mindforge_version', status: 'warning', error: e.message });
104
+ }
105
+ }
106
+
107
+ return results;
108
+ }
109
+
110
+ module.exports = { MIGRATION_ID, TARGET_VERSION, migrate };