@mindrian_os/install 1.13.0-beta.11

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 (597) hide show
  1. package/.claude-plugin/plugin.json +21 -0
  2. package/.mcp.json +9 -0
  3. package/CHANGELOG.md +3333 -0
  4. package/LICENSE +123 -0
  5. package/README.md +673 -0
  6. package/agents/brain-query.md +80 -0
  7. package/agents/framework-runner.md +237 -0
  8. package/agents/grading.md +188 -0
  9. package/agents/investor.md +128 -0
  10. package/agents/larry-extended.md +135 -0
  11. package/agents/opportunity-scanner.md +91 -0
  12. package/agents/persona-analyst.md +132 -0
  13. package/agents/research.md +89 -0
  14. package/agents/reverse-salient-agent.md +27 -0
  15. package/bin/cli.js +142 -0
  16. package/bin/mindrian-mcp-server.cjs +182 -0
  17. package/bin/mindrian-tools.cjs +765 -0
  18. package/commands/act.md +439 -0
  19. package/commands/admin.md +404 -0
  20. package/commands/analyze-needs.md +42 -0
  21. package/commands/analyze-systems.md +39 -0
  22. package/commands/analyze-timing.md +42 -0
  23. package/commands/auto-explore.md +64 -0
  24. package/commands/beautiful-question.md +40 -0
  25. package/commands/brain-derive.md +78 -0
  26. package/commands/build-knowledge.md +42 -0
  27. package/commands/build-thesis.md +46 -0
  28. package/commands/causal.md +234 -0
  29. package/commands/challenge-assumptions.md +33 -0
  30. package/commands/compare-ventures.md +83 -0
  31. package/commands/dashboard.md +110 -0
  32. package/commands/deep-grade.md +82 -0
  33. package/commands/diagnose.md +58 -0
  34. package/commands/diagnostics.md +151 -0
  35. package/commands/doctor.md +151 -0
  36. package/commands/dominant-designs.md +40 -0
  37. package/commands/explain-decision.md +87 -0
  38. package/commands/explore-domains.md +42 -0
  39. package/commands/explore-futures.md +40 -0
  40. package/commands/explore-trends.md +42 -0
  41. package/commands/export.md +103 -0
  42. package/commands/file-meeting.md +724 -0
  43. package/commands/find-analogies.md +188 -0
  44. package/commands/find-bottlenecks.md +62 -0
  45. package/commands/find-connections.md +76 -0
  46. package/commands/funding.md +81 -0
  47. package/commands/grade.md +203 -0
  48. package/commands/graph.md +128 -0
  49. package/commands/hat-briefing.md +125 -0
  50. package/commands/heal.md +196 -0
  51. package/commands/help.md +399 -0
  52. package/commands/hmi-status.md +172 -0
  53. package/commands/jtbd.md +241 -0
  54. package/commands/leadership.md +73 -0
  55. package/commands/lean-canvas.md +40 -0
  56. package/commands/macro-trends.md +40 -0
  57. package/commands/map-unknowns.md +40 -0
  58. package/commands/memory.md +173 -0
  59. package/commands/models.md +175 -0
  60. package/commands/mos-reason.md +285 -0
  61. package/commands/mullins.md +120 -0
  62. package/commands/new-project.md +481 -0
  63. package/commands/onboard.md +434 -0
  64. package/commands/operator.md +149 -0
  65. package/commands/opportunities.md +144 -0
  66. package/commands/organize.md +497 -0
  67. package/commands/persona.md +198 -0
  68. package/commands/pipeline.md +112 -0
  69. package/commands/present.md +91 -0
  70. package/commands/publish.md +201 -0
  71. package/commands/query.md +124 -0
  72. package/commands/radar.md +72 -0
  73. package/commands/reanalyze.md +91 -0
  74. package/commands/research.md +196 -0
  75. package/commands/room.md +352 -0
  76. package/commands/rooms.md +598 -0
  77. package/commands/root-cause.md +40 -0
  78. package/commands/rs-experts.md +85 -0
  79. package/commands/rs-explain.md +100 -0
  80. package/commands/rs-fetch.md +94 -0
  81. package/commands/rs-thesis.md +85 -0
  82. package/commands/scenario-plan.md +40 -0
  83. package/commands/scheduled-tasks.md +285 -0
  84. package/commands/score-innovation.md +43 -0
  85. package/commands/scout.md +239 -0
  86. package/commands/setup.md +618 -0
  87. package/commands/snapshot.md +147 -0
  88. package/commands/speakers.md +84 -0
  89. package/commands/splash.md +28 -0
  90. package/commands/status.md +75 -0
  91. package/commands/structure-argument.md +42 -0
  92. package/commands/suggest-next.md +80 -0
  93. package/commands/systems-thinking.md +40 -0
  94. package/commands/think-hats.md +42 -0
  95. package/commands/update.md +181 -0
  96. package/commands/user-needs.md +40 -0
  97. package/commands/validate.md +40 -0
  98. package/commands/value-proposition.md +61 -0
  99. package/commands/vault.md +180 -0
  100. package/commands/visualize.md +52 -0
  101. package/commands/whitespace.md +507 -0
  102. package/commands/wiki.md +69 -0
  103. package/hooks/hooks.json +381 -0
  104. package/hooks/run-hook.cmd +64 -0
  105. package/lib/__init__.py +0 -0
  106. package/lib/__pycache__/__init__.cpython-312.pyc +0 -0
  107. package/lib/agents/auto-explore-agent.cjs +1043 -0
  108. package/lib/agents/reverse-salient-agent.cjs +679 -0
  109. package/lib/agents/tension-hook-agent.cjs +544 -0
  110. package/lib/brain/ROOM.md +44 -0
  111. package/lib/brain/chain-recommender.cjs +301 -0
  112. package/lib/chat/chat-context.js +185 -0
  113. package/lib/chat/chat-panel.js +721 -0
  114. package/lib/chat/fabric-chat.cjs +288 -0
  115. package/lib/chat/generative-tools.js +219 -0
  116. package/lib/conversation/ROOM.md +39 -0
  117. package/lib/conversation/classifier-rules.json +38 -0
  118. package/lib/conversation/classifier.cjs +264 -0
  119. package/lib/conversation/operator.cjs +287 -0
  120. package/lib/copy/115-spec-strings.cjs +55 -0
  121. package/lib/core/__init__.py +0 -0
  122. package/lib/core/__nav-stub.cjs +14 -0
  123. package/lib/core/__pycache__/__init__.cpython-312.pyc +0 -0
  124. package/lib/core/__pycache__/rs-math.cpython-312.pyc +0 -0
  125. package/lib/core/__pycache__/rs_cache.cpython-312.pyc +0 -0
  126. package/lib/core/__pycache__/rs_corpus.cpython-312.pyc +0 -0
  127. package/lib/core/__pycache__/rs_hybrid.cpython-312.pyc +0 -0
  128. package/lib/core/__pycache__/rs_math.cpython-312.pyc +0 -0
  129. package/lib/core/__pycache__/rs_rooms.cpython-312.pyc +0 -0
  130. package/lib/core/artifact-id.cjs +148 -0
  131. package/lib/core/asset-ops.cjs +151 -0
  132. package/lib/core/auto-commit-throttle.cjs +129 -0
  133. package/lib/core/bearer-token.cjs +199 -0
  134. package/lib/core/brain-client.cjs +865 -0
  135. package/lib/core/brain-derivation-prompts.cjs +326 -0
  136. package/lib/core/brain-derivation-queue.cjs +431 -0
  137. package/lib/core/brain-derivation.cjs +580 -0
  138. package/lib/core/brain-md-schema.cjs +528 -0
  139. package/lib/core/brain-md-staleness.cjs +357 -0
  140. package/lib/core/brain-response-sanitize.cjs +188 -0
  141. package/lib/core/bridge-writer.cjs +477 -0
  142. package/lib/core/chat-context-builder.cjs +253 -0
  143. package/lib/core/cross-room-aggregator.cjs +762 -0
  144. package/lib/core/daily-briefing.cjs +438 -0
  145. package/lib/core/decision-capture.cjs +618 -0
  146. package/lib/core/deep-links.cjs +82 -0
  147. package/lib/core/dispatch-optimizer.cjs +354 -0
  148. package/lib/core/dual-path-detector.cjs +84 -0
  149. package/lib/core/dual-path-detector.test.cjs +334 -0
  150. package/lib/core/exports-log.cjs +79 -0
  151. package/lib/core/feynman-minto-invariants.cjs +605 -0
  152. package/lib/core/folder-memory-async.cjs +338 -0
  153. package/lib/core/folder-memory-shared.cjs +890 -0
  154. package/lib/core/folder-memory.cjs +416 -0
  155. package/lib/core/framework-chain-composer.cjs +411 -0
  156. package/lib/core/frontmatter-schemas.cjs +330 -0
  157. package/lib/core/git-ops.cjs +141 -0
  158. package/lib/core/graph-ops.cjs +258 -0
  159. package/lib/core/hat-persistence.cjs +362 -0
  160. package/lib/core/index.cjs +60 -0
  161. package/lib/core/integration-registry.cjs +232 -0
  162. package/lib/core/intelligence-cascade.cjs +661 -0
  163. package/lib/core/lazygraph-ops.cjs +1057 -0
  164. package/lib/core/lru-cache.cjs +139 -0
  165. package/lib/core/mcp-profiles.cjs +182 -0
  166. package/lib/core/meeting-ops.cjs +54 -0
  167. package/lib/core/memory-ops.cjs +600 -0
  168. package/lib/core/migrations/ROOM.md +33 -0
  169. package/lib/core/migrations/phase-109-nodes-provenance.cjs +339 -0
  170. package/lib/core/migrations/phase-109-session-focus.cjs +99 -0
  171. package/lib/core/model-profiles.cjs +246 -0
  172. package/lib/core/mullins-scaffold.cjs +160 -0
  173. package/lib/core/nav-dial.cjs +316 -0
  174. package/lib/core/navigation/ROOM.md +15 -0
  175. package/lib/core/navigation/explanation.cjs +43 -0
  176. package/lib/core/navigation/focus.cjs +135 -0
  177. package/lib/core/navigation/ingestion.cjs +82 -0
  178. package/lib/core/navigation/insights.cjs +350 -0
  179. package/lib/core/navigation/memory-events.cjs +118 -0
  180. package/lib/core/navigation/neighborhood.cjs +78 -0
  181. package/lib/core/navigation/packet.cjs +182 -0
  182. package/lib/core/navigation/room-home.cjs +127 -0
  183. package/lib/core/navigation/transitions.cjs +82 -0
  184. package/lib/core/navigation-engine-shared.cjs +242 -0
  185. package/lib/core/navigation-engine.cjs +664 -0
  186. package/lib/core/navigation.cjs +60 -0
  187. package/lib/core/nl-graph-queries.cjs +164 -0
  188. package/lib/core/offer-presenter.cjs +406 -0
  189. package/lib/core/opportunity-extractor.cjs +183 -0
  190. package/lib/core/opportunity-ops.cjs +1371 -0
  191. package/lib/core/persona-ops.cjs +537 -0
  192. package/lib/core/persona-taxonomy.cjs +190 -0
  193. package/lib/core/platform-gates.cjs +120 -0
  194. package/lib/core/platform.cjs +257 -0
  195. package/lib/core/proactive-intelligence.cjs +528 -0
  196. package/lib/core/problem-type-router.cjs +315 -0
  197. package/lib/core/reasoning-ops.cjs +639 -0
  198. package/lib/core/reverse-salient-persona-suffix.cjs +115 -0
  199. package/lib/core/room-classifier-strict-mode.cjs +229 -0
  200. package/lib/core/room-db.cjs +127 -0
  201. package/lib/core/room-ops-async.cjs +92 -0
  202. package/lib/core/room-ops-shared.cjs +64 -0
  203. package/lib/core/room-ops-sync.cjs +70 -0
  204. package/lib/core/room-ops.cjs +32 -0
  205. package/lib/core/room-type-detector.cjs +386 -0
  206. package/lib/core/rs-brain-substrate-prompts.cjs +129 -0
  207. package/lib/core/rs-brain-substrate.cjs +570 -0
  208. package/lib/core/rs-breakthrough-scorer.cjs +255 -0
  209. package/lib/core/rs-canon-violations.cjs +82 -0
  210. package/lib/core/rs-chain-feeder.cjs +343 -0
  211. package/lib/core/rs-commercial-assessor.cjs +280 -0
  212. package/lib/core/rs-differential-scorer.cjs +376 -0
  213. package/lib/core/rs-domain-analyzer.cjs +385 -0
  214. package/lib/core/rs-egress-prompts.cjs +113 -0
  215. package/lib/core/rs-egress-telemetry.cjs +225 -0
  216. package/lib/core/rs-egress-violations.cjs +53 -0
  217. package/lib/core/rs-expert-mapper.cjs +467 -0
  218. package/lib/core/rs-fetcher-academic.cjs +697 -0
  219. package/lib/core/rs-fetcher-experts.cjs +314 -0
  220. package/lib/core/rs-fetcher-industry.cjs +731 -0
  221. package/lib/core/rs-fetcher-patents.cjs +564 -0
  222. package/lib/core/rs-innovation-classifier.cjs +194 -0
  223. package/lib/core/rs-mind-map.cjs +656 -0
  224. package/lib/core/rs-neo4j-writer.cjs +388 -0
  225. package/lib/core/rs-nl-to-query.cjs +425 -0
  226. package/lib/core/rs-pinecone-bridge.cjs +303 -0
  227. package/lib/core/rs-preprocessor.cjs +350 -0
  228. package/lib/core/rs-query-matrix.cjs +316 -0
  229. package/lib/core/rs-query-to-text.cjs +438 -0
  230. package/lib/core/rs-sqlite-mirror.cjs +443 -0
  231. package/lib/core/rs-thesis-generator.cjs +188 -0
  232. package/lib/core/rs_cache.py +479 -0
  233. package/lib/core/rs_corpus.py +468 -0
  234. package/lib/core/rs_hybrid.py +586 -0
  235. package/lib/core/rs_math.py +287 -0
  236. package/lib/core/rs_rooms.py +193 -0
  237. package/lib/core/scheduled-scanner.cjs +463 -0
  238. package/lib/core/scratchpad-ops.cjs +201 -0
  239. package/lib/core/section-8-trace-schema.cjs +138 -0
  240. package/lib/core/section-registry.cjs +111 -0
  241. package/lib/core/session-state.cjs +144 -0
  242. package/lib/core/shallow-doc-parser.cjs +174 -0
  243. package/lib/core/shallow-doc-parser.test.cjs +226 -0
  244. package/lib/core/skill-activation-router.cjs +284 -0
  245. package/lib/core/state-ops.cjs +46 -0
  246. package/lib/core/statusline-cache.cjs +266 -0
  247. package/lib/core/token-estimator.cjs +348 -0
  248. package/lib/core/user-archetype.cjs +239 -0
  249. package/lib/core/user-md-ops.cjs +524 -0
  250. package/lib/core/visual-ops.cjs +624 -0
  251. package/lib/core/write-lock.cjs +149 -0
  252. package/lib/graph/canvas-graph.js +467 -0
  253. package/lib/graph/constellation-config.cjs +299 -0
  254. package/lib/graph/graph-detail-panel.js +165 -0
  255. package/lib/hmi/ROOM.md +47 -0
  256. package/lib/hmi/across-session-memory.cjs +604 -0
  257. package/lib/hmi/cross-room-memory.cjs +575 -0
  258. package/lib/hmi/decoy-tier.cjs +395 -0
  259. package/lib/hmi/jtbd-classifier.cjs +219 -0
  260. package/lib/hmi/jtbd-state.cjs +199 -0
  261. package/lib/hmi/jtbd-taxonomy.json +392 -0
  262. package/lib/hmi/selector-dispatcher.cjs +546 -0
  263. package/lib/hmi/selector-telemetry.cjs +263 -0
  264. package/lib/hmi/shape-f0-renderer.cjs +139 -0
  265. package/lib/hmi/shape-f1-fallback.cjs +80 -0
  266. package/lib/hmi/shape-f1-renderer.cjs +138 -0
  267. package/lib/hmi/shape-f2-renderer.cjs +132 -0
  268. package/lib/hmi/shape-f3-renderer.cjs +66 -0
  269. package/lib/hmi/shape-f4-renderer.cjs +72 -0
  270. package/lib/hmi/shape-f5-renderer.cjs +155 -0
  271. package/lib/hmi/shape-f6-plan-review-renderer.cjs +312 -0
  272. package/lib/hmi/shape-f6-renderer.cjs +144 -0
  273. package/lib/hmi/shape-g-renderer.cjs +219 -0
  274. package/lib/hmi/shape-h-renderer.cjs +222 -0
  275. package/lib/hmi/tier-check.cjs +63 -0
  276. package/lib/import/PRECONDITIONS.md +41 -0
  277. package/lib/import/branding.cjs +210 -0
  278. package/lib/import/branding.test.cjs +235 -0
  279. package/lib/import/classifications-sync.cjs +104 -0
  280. package/lib/import/classifications-sync.test.cjs +129 -0
  281. package/lib/import/enricher.cjs +296 -0
  282. package/lib/import/enricher.test.cjs +273 -0
  283. package/lib/import/integration.test.cjs +376 -0
  284. package/lib/import/manifest.cjs +129 -0
  285. package/lib/import/manifest.schema.json +185 -0
  286. package/lib/import/manifest.test.cjs +123 -0
  287. package/lib/import/meeting-detector.cjs +92 -0
  288. package/lib/import/meeting-detector.test.cjs +100 -0
  289. package/lib/import/person-detector.cjs +229 -0
  290. package/lib/import/person-detector.test.cjs +149 -0
  291. package/lib/import/report.cjs +186 -0
  292. package/lib/import/report.test.cjs +186 -0
  293. package/lib/import/room-md-scaffolder.cjs +49 -0
  294. package/lib/import/router.cjs +224 -0
  295. package/lib/import/router.test.cjs +356 -0
  296. package/lib/import/run-all-tests.cjs +36 -0
  297. package/lib/import/smoke-test.cjs +213 -0
  298. package/lib/import/smoke-test.test.cjs +148 -0
  299. package/lib/import/test-fixtures/collision-vault/preexisting-room/STATE.md +8 -0
  300. package/lib/import/test-fixtures/collision-vault/preexisting-room/problem-definition/onboarding/onboarding.md +7 -0
  301. package/lib/import/test-fixtures/collision-vault/source/onboarding.md +5 -0
  302. package/lib/import/test-fixtures/obsidian-vault/.obsidian/workspace.json +1 -0
  303. package/lib/import/test-fixtures/obsidian-vault/notes/with-wikilinks.md +4 -0
  304. package/lib/import/test-fixtures/tiny-vault/notes/2026-01-15-team-sync.md +9 -0
  305. package/lib/import/test-fixtures/tiny-vault/notes/empty.md +3 -0
  306. package/lib/import/test-fixtures/tiny-vault/notes/onboarding.md +5 -0
  307. package/lib/import/test-fixtures/tiny-vault/notes/pricing.md +5 -0
  308. package/lib/import/test-fixtures/tiny-vault/notes/random.md +4 -0
  309. package/lib/import/undo.test.cjs +199 -0
  310. package/lib/import/vault-scanner.cjs +105 -0
  311. package/lib/import/vault-scanner.test.cjs +67 -0
  312. package/lib/mcp/app-html/dashboard.html +316 -0
  313. package/lib/mcp/app-html/graph.html +428 -0
  314. package/lib/mcp/app-html/mindrian-platform.html +1841 -0
  315. package/lib/mcp/app-html/wiki.html +383 -0
  316. package/lib/mcp/app-views.cjs +322 -0
  317. package/lib/mcp/brain-router.cjs +418 -0
  318. package/lib/mcp/capability-registry.cjs +62 -0
  319. package/lib/mcp/larry-context.cjs +46 -0
  320. package/lib/mcp/larry-server-instructions.md +114 -0
  321. package/lib/mcp/pipeline-state.cjs +275 -0
  322. package/lib/mcp/prompts.cjs +302 -0
  323. package/lib/mcp/resources.cjs +227 -0
  324. package/lib/mcp/session-catchup.cjs +327 -0
  325. package/lib/mcp/surface-detect.cjs +75 -0
  326. package/lib/mcp/tool-router.cjs +1034 -0
  327. package/lib/memory/aaak-compress.cjs +403 -0
  328. package/lib/memory/aaak-compress.test.cjs +288 -0
  329. package/lib/memory/async-artifact-auto-commit.test.cjs +223 -0
  330. package/lib/memory/bearer-token.test.cjs +315 -0
  331. package/lib/memory/brain-cache-lru.test.cjs +259 -0
  332. package/lib/memory/brain-client-query-shape.test.cjs +160 -0
  333. package/lib/memory/brain-derivation-graceful-degradation.test.cjs +1019 -0
  334. package/lib/memory/brain-derivation-queue.test.cjs +539 -0
  335. package/lib/memory/brain-derivation.test.cjs +634 -0
  336. package/lib/memory/brain-derive-command.test.cjs +534 -0
  337. package/lib/memory/brain-md-invariants-validator.test.cjs +704 -0
  338. package/lib/memory/brain-md-schema.test.cjs +467 -0
  339. package/lib/memory/brain-md-staleness.test.cjs +525 -0
  340. package/lib/memory/brain-server-resolution.test.cjs +314 -0
  341. package/lib/memory/chain-recommender.test.cjs +233 -0
  342. package/lib/memory/chat-context.test.cjs +128 -0
  343. package/lib/memory/command-registry.test.cjs +220 -0
  344. package/lib/memory/cross-room-aggregator.test.cjs +909 -0
  345. package/lib/memory/dashboard-server.test.cjs +256 -0
  346. package/lib/memory/debouncer-drain-at-prompt.test.cjs +389 -0
  347. package/lib/memory/decision-capture.test.cjs +632 -0
  348. package/lib/memory/decision-capture.worker.cjs +70 -0
  349. package/lib/memory/explain-decision-command.test.cjs +521 -0
  350. package/lib/memory/explain-decision-footer.test.cjs +316 -0
  351. package/lib/memory/explored-materials-store.cjs +392 -0
  352. package/lib/memory/feynman-minto-guardian.test.cjs +736 -0
  353. package/lib/memory/feynman-minto-invariants.test.cjs +511 -0
  354. package/lib/memory/feynman-prompts-drift.test.cjs +144 -0
  355. package/lib/memory/feynman-prompts.cjs +151 -0
  356. package/lib/memory/feynman-prompts.test.cjs +96 -0
  357. package/lib/memory/folder-memory-quadruple.test.cjs +548 -0
  358. package/lib/memory/folder-memory.test.cjs +503 -0
  359. package/lib/memory/framework-chain-composer.test.cjs +515 -0
  360. package/lib/memory/frontmatter-schema-validator.test.cjs +290 -0
  361. package/lib/memory/heal-command.test.cjs +604 -0
  362. package/lib/memory/index-artifact-transaction.test.cjs +333 -0
  363. package/lib/memory/lazygraph-rs-discoveries-view.test.cjs +122 -0
  364. package/lib/memory/mcp-input-validation.test.cjs +240 -0
  365. package/lib/memory/mcp-server-brain-deps.test.cjs +270 -0
  366. package/lib/memory/mcp-stack-fallback.test.cjs +433 -0
  367. package/lib/memory/minto-debouncer.test.cjs +407 -0
  368. package/lib/memory/minto-debouncer.worker.cjs +46 -0
  369. package/lib/memory/minto-migration-v88.test.cjs +265 -0
  370. package/lib/memory/minto-schema-v88.test.cjs +390 -0
  371. package/lib/memory/mos-status-renderer.test.cjs +631 -0
  372. package/lib/memory/narrative-schema.cjs +376 -0
  373. package/lib/memory/narrative-schema.test.cjs +209 -0
  374. package/lib/memory/nav-dial.test.cjs +414 -0
  375. package/lib/memory/navigation-engine-core.test.cjs +722 -0
  376. package/lib/memory/navigation-invariants.test.cjs +483 -0
  377. package/lib/memory/offer-presenter.test.cjs +554 -0
  378. package/lib/memory/on-stop-snapshot.test.cjs +404 -0
  379. package/lib/memory/pending-tension-store.cjs +373 -0
  380. package/lib/memory/post-compact-reinjection.test.cjs +854 -0
  381. package/lib/memory/post-write-triple.test.cjs +317 -0
  382. package/lib/memory/pre-compact-snapshot.test.cjs +495 -0
  383. package/lib/memory/problem-type-router.test.cjs +656 -0
  384. package/lib/memory/query-efficiency-telemetry.test.cjs +370 -0
  385. package/lib/memory/recompile-room-references.test.cjs +392 -0
  386. package/lib/memory/recompile-room-references.worker.cjs +42 -0
  387. package/lib/memory/record-decision-dual-write.test.cjs +454 -0
  388. package/lib/memory/room-classifier-strict-mode.test.cjs +417 -0
  389. package/lib/memory/room-minto-hook.test.cjs +398 -0
  390. package/lib/memory/rs-discovery-engine.test.cjs +323 -0
  391. package/lib/memory/run-feynman-tests.cjs +1247 -0
  392. package/lib/memory/security-trifecta.test.cjs +312 -0
  393. package/lib/memory/session-start-brain-staleness.test.cjs +363 -0
  394. package/lib/memory/session-start-triple-injection.test.cjs +514 -0
  395. package/lib/memory/sessionstart-banner-formatter.cjs +318 -0
  396. package/lib/memory/sessionstart-minto-banner.test.cjs +373 -0
  397. package/lib/memory/skill-activation-router.test.cjs +419 -0
  398. package/lib/memory/stamp-artifact-write.test.cjs +304 -0
  399. package/lib/memory/statusline-active-room.test.cjs +315 -0
  400. package/lib/memory/statusline-minto-segment.test.cjs +292 -0
  401. package/lib/memory/sync-async-entry-points.test.cjs +204 -0
  402. package/lib/memory/test-bridge-writer-enhanced.cjs +452 -0
  403. package/lib/memory/test-rs-brain-substrate-shape.cjs +529 -0
  404. package/lib/memory/test-rs-brain-substrate.cjs +636 -0
  405. package/lib/memory/test-rs-breakthrough-scorer.cjs +375 -0
  406. package/lib/memory/test-rs-canon-violations.cjs +218 -0
  407. package/lib/memory/test-rs-chain-feeder-core.cjs +344 -0
  408. package/lib/memory/test-rs-chain-feeder-skill-spawn.cjs +297 -0
  409. package/lib/memory/test-rs-commercial-assessor.cjs +385 -0
  410. package/lib/memory/test-rs-differential-scorer.cjs +480 -0
  411. package/lib/memory/test-rs-discovery-engine.cjs +603 -0
  412. package/lib/memory/test-rs-domain-analyzer.cjs +492 -0
  413. package/lib/memory/test-rs-egress-primitives.cjs +420 -0
  414. package/lib/memory/test-rs-expert-mapper.cjs +547 -0
  415. package/lib/memory/test-rs-explain-command.cjs +443 -0
  416. package/lib/memory/test-rs-fetcher-academic.cjs +848 -0
  417. package/lib/memory/test-rs-fetcher-experts.cjs +496 -0
  418. package/lib/memory/test-rs-fetcher-industry.cjs +702 -0
  419. package/lib/memory/test-rs-fetcher-patents.cjs +674 -0
  420. package/lib/memory/test-rs-innovation-classifier.cjs +301 -0
  421. package/lib/memory/test-rs-mind-map.cjs +646 -0
  422. package/lib/memory/test-rs-neo4j-writer.cjs +518 -0
  423. package/lib/memory/test-rs-nl-to-query.cjs +449 -0
  424. package/lib/memory/test-rs-pinecone-bridge.cjs +277 -0
  425. package/lib/memory/test-rs-preprocessor.cjs +433 -0
  426. package/lib/memory/test-rs-query-matrix.cjs +391 -0
  427. package/lib/memory/test-rs-query-to-text.cjs +551 -0
  428. package/lib/memory/test-rs-sqlite-mirror.cjs +649 -0
  429. package/lib/memory/test-rs-thesis-generator.cjs +360 -0
  430. package/lib/memory/triple-context-formatter.cjs +473 -0
  431. package/lib/memory/triple-context-formatter.test.cjs +442 -0
  432. package/lib/memory/user-md-persona.test.cjs +565 -0
  433. package/lib/memory/userpromptsubmit-integration.test.cjs +690 -0
  434. package/lib/memory/validators/README.md +157 -0
  435. package/lib/memory/validators/brain-md-invariants.cjs +475 -0
  436. package/lib/memory/validators/brain-substrate-invariants.cjs +285 -0
  437. package/lib/memory/validators/external-academic-invariants.cjs +249 -0
  438. package/lib/memory/validators/external-industry-invariants.cjs +271 -0
  439. package/lib/memory/validators/external-patents-invariants.cjs +266 -0
  440. package/lib/memory/validators/minto-invariants.cjs +62 -0
  441. package/lib/memory/validators/navigation-invariants.cjs +340 -0
  442. package/lib/memory/validators/queue-health.cjs +95 -0
  443. package/lib/memory/validators/snapshot-integrity.cjs +129 -0
  444. package/lib/memory/validators/stale-lifecycle.cjs +116 -0
  445. package/lib/memory/vault-section-minto-generator-atomic.test.cjs +556 -0
  446. package/lib/memory/vault-section-minto-generator-atomic.worker.cjs +73 -0
  447. package/lib/memory/write-lock-atomic.test.cjs +137 -0
  448. package/lib/memory/write-lock-atomic.worker.cjs +55 -0
  449. package/lib/parity/check-parity.cjs +83 -0
  450. package/lib/presentation/presentation-server.cjs +101 -0
  451. package/lib/presentation/presentation-watcher.cjs +123 -0
  452. package/lib/quickview/hub-server.cjs +719 -0
  453. package/lib/quickview/server.cjs +533 -0
  454. package/lib/render/JTBD-PALETTES.md +145 -0
  455. package/lib/render/ROOM.md +59 -0
  456. package/lib/render/render-v2.cjs +486 -0
  457. package/lib/render/render-v2.test.cjs +267 -0
  458. package/lib/render/render.cjs +65 -0
  459. package/lib/state/ROOM.md +46 -0
  460. package/lib/state/state-md-parser.cjs +215 -0
  461. package/lib/statusline/ROOM.md +38 -0
  462. package/lib/statusline/banner-suppression.cjs +50 -0
  463. package/lib/statusline/surface-detect.cjs +85 -0
  464. package/lib/update-bootstrap.sh.template +145 -0
  465. package/lib/vault/frontmatter-schema.cjs +297 -0
  466. package/lib/vault/room-scanner.cjs +352 -0
  467. package/lib/vault/wikilink-builder.cjs +231 -0
  468. package/lib/vault/wikilink-builder.test.cjs +182 -0
  469. package/lib/wiki/graph-links.cjs +281 -0
  470. package/lib/wiki/page-renderer.cjs +229 -0
  471. package/lib/wiki/wiki-chat.cjs +81 -0
  472. package/lib/wiki/wiki-layout.cjs +1459 -0
  473. package/lib/wiki/wiki-search.cjs +142 -0
  474. package/lib/wiki/wiki-server.cjs +678 -0
  475. package/lib/wiki/wiki-watcher.cjs +105 -0
  476. package/lib/workflow/ROOM.md +47 -0
  477. package/lib/workflow/command-resolver.cjs +155 -0
  478. package/lib/workflow/command-resolver.test.cjs +235 -0
  479. package/package.json +44 -0
  480. package/pipelines/analogy/01-decompose.md +80 -0
  481. package/pipelines/analogy/02-abstract.md +87 -0
  482. package/pipelines/analogy/03-search.md +135 -0
  483. package/pipelines/analogy/04-transfer.md +101 -0
  484. package/pipelines/analogy/05-validate.md +106 -0
  485. package/pipelines/analogy/CHAIN.md +56 -0
  486. package/pipelines/discovery/01-explore-domains.md +44 -0
  487. package/pipelines/discovery/02-think-hats.md +50 -0
  488. package/pipelines/discovery/03-analyze-needs.md +54 -0
  489. package/pipelines/discovery/CHAIN.md +37 -0
  490. package/pipelines/thesis/01-structure-argument.md +45 -0
  491. package/pipelines/thesis/02-challenge-assumptions.md +48 -0
  492. package/pipelines/thesis/03-build-thesis.md +54 -0
  493. package/pipelines/thesis/CHAIN.md +37 -0
  494. package/references/brain/causal-directives.md +91 -0
  495. package/references/brain/causal-enrichment.cypher +165 -0
  496. package/references/brain/command-triggers-schema.md +226 -0
  497. package/references/brain/graph-architecture.md +317 -0
  498. package/references/brain/query-patterns.md +460 -0
  499. package/references/brain/room-hierarchy-schema.md +218 -0
  500. package/references/brain/schema.md +76 -0
  501. package/references/capability-radar/capabilities-index.md +241 -0
  502. package/references/capability-radar/changelog-cache.md +81 -0
  503. package/references/causal/causal-schema.md +103 -0
  504. package/references/design/email-template-standard.md +155 -0
  505. package/references/design/graph-visualization-standard.md +178 -0
  506. package/references/document-generation.md +179 -0
  507. package/references/hsi/HSI-TOOLS-REFERENCE.md +222 -0
  508. package/references/import-config.md +141 -0
  509. package/references/integrations/detection-patterns.md +101 -0
  510. package/references/meeting/artifact-template.md +377 -0
  511. package/references/meeting/cross-meeting-intelligence.md +216 -0
  512. package/references/meeting/cross-relationship-patterns.md +202 -0
  513. package/references/meeting/live-join-interface.md +244 -0
  514. package/references/meeting/section-mapping.md +192 -0
  515. package/references/meeting/segment-classification.md +258 -0
  516. package/references/meeting/speaker-profile-template.md +219 -0
  517. package/references/meeting/summary-template.md +348 -0
  518. package/references/meeting/transcript-patterns.md +226 -0
  519. package/references/methodology/analyze-needs.md +135 -0
  520. package/references/methodology/analyze-systems.md +121 -0
  521. package/references/methodology/analyze-timing.md +149 -0
  522. package/references/methodology/beautiful-question.md +109 -0
  523. package/references/methodology/build-knowledge.md +161 -0
  524. package/references/methodology/build-thesis.md +237 -0
  525. package/references/methodology/challenge-assumptions.md +127 -0
  526. package/references/methodology/diagnose.md +169 -0
  527. package/references/methodology/dominant-designs.md +212 -0
  528. package/references/methodology/explore-domains.md +147 -0
  529. package/references/methodology/explore-futures.md +163 -0
  530. package/references/methodology/explore-trends.md +129 -0
  531. package/references/methodology/find-bottlenecks.md +131 -0
  532. package/references/methodology/grade.md +211 -0
  533. package/references/methodology/index.md +97 -0
  534. package/references/methodology/leadership.md +200 -0
  535. package/references/methodology/lean-canvas.md +116 -0
  536. package/references/methodology/macro-trends.md +192 -0
  537. package/references/methodology/map-unknowns.md +137 -0
  538. package/references/methodology/mullins-7-domains.md +104 -0
  539. package/references/methodology/problem-types.md +65 -0
  540. package/references/methodology/root-cause.md +178 -0
  541. package/references/methodology/sapphire-encoding.md +355 -0
  542. package/references/methodology/scenario-plan.md +178 -0
  543. package/references/methodology/score-innovation.md +154 -0
  544. package/references/methodology/structure-argument.md +158 -0
  545. package/references/methodology/systems-thinking.md +159 -0
  546. package/references/methodology/think-hats.md +147 -0
  547. package/references/methodology/triz-matrix.json +751 -0
  548. package/references/methodology/triz-principles.md +501 -0
  549. package/references/methodology/user-needs.md +199 -0
  550. package/references/methodology/validate.md +163 -0
  551. package/references/methodology/value-proposition.md +244 -0
  552. package/references/opportunities/funding-lifecycle.md +103 -0
  553. package/references/opportunities/grant-api-patterns.md +99 -0
  554. package/references/opportunities/opportunity-template.md +84 -0
  555. package/references/personality/assessment-philosophy.md +72 -0
  556. package/references/personality/lexicon.md +100 -0
  557. package/references/personality/persona-chains.md +56 -0
  558. package/references/personality/pws-lexicon-full.md +499 -0
  559. package/references/personality/voice-dna.md +156 -0
  560. package/references/personas/hat-perspectives.md +76 -0
  561. package/references/personas/persona-template.md +63 -0
  562. package/references/pipeline/act-output-contract.md +88 -0
  563. package/references/pipeline/chains-index.md +39 -0
  564. package/references/pws-profile-generation.md +79 -0
  565. package/references/reasoning/reasoning-schema.md +143 -0
  566. package/references/reasoning/reasoning-template.md +68 -0
  567. package/references/reasoning/run-template.md +38 -0
  568. package/references/research/RESEARCH_14_CLAUDE_CODE_SOURCE_ARCHITECTURE.md +209 -0
  569. package/references/research/RESEARCH_15_V1.8_OPTIMIZATION_JTBD.md +375 -0
  570. package/references/research/RESEARCH_16_NATIVE_FIRST_PLUGIN_ARCHITECTURE.md +575 -0
  571. package/references/research/RESEARCH_17_MCP_UI_FRAMEWORKS.md +272 -0
  572. package/references/taxonomy/TAXONOMY.md +192 -0
  573. package/references/templates/MINTO.md +36 -0
  574. package/references/user-research/2026-04-05-leah-lawrence-session.md +202 -0
  575. package/references/vault-kit/README.md +35 -0
  576. package/references/vault-kit/app.json +12 -0
  577. package/references/vault-kit/appearance.json +12 -0
  578. package/references/vault-kit/graph.json +35 -0
  579. package/references/vault-kit/snippets/mindrian-destijl.css +297 -0
  580. package/references/vault-kit/templates/new-artifact.md +37 -0
  581. package/references/vault-kit/templates/new-meeting-note.md +35 -0
  582. package/references/vault-kit/templates/new-team-profile.md +29 -0
  583. package/references/vault-kit/templates/new-xref.md +35 -0
  584. package/references/visual/symbol-system.md +151 -0
  585. package/skills/MOSDeckEngine/SKILL.md +325 -0
  586. package/skills/brain-connector/SKILL.md +114 -0
  587. package/skills/context-engine/SKILL.md +147 -0
  588. package/skills/conversation-mode/SKILL.md +102 -0
  589. package/skills/larry-personality/SKILL.md +219 -0
  590. package/skills/larry-personality/framework-chains.md +92 -0
  591. package/skills/larry-personality/mode-engine.md +185 -0
  592. package/skills/mullins-scaffold/SKILL.md +61 -0
  593. package/skills/mullins-scaffold/scaffold.json +146 -0
  594. package/skills/pws-methodology/SKILL.md +49 -0
  595. package/skills/room-passive/SKILL.md +165 -0
  596. package/skills/room-proactive/SKILL.md +250 -0
  597. package/skills/ui-system/SKILL.md +277 -0
@@ -0,0 +1,603 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /*
5
+ * Copyright (c) 2026 Mindrian. BSL 1.1.
6
+ * Phase 89.5 Plan 04 -- rs-discovery-engine fixture suite.
7
+ *
8
+ * Tests the top-level orchestrator at scripts/rs-discovery-engine.cjs.
9
+ * The orchestrator chains every RS phase end-to-end:
10
+ * Phase 1 (Domain Analysis 89.1) -> Phase 1.5 (Fetchers 89.2) ->
11
+ * Phase 2 (Preprocessor 89.2) -> Phase 3 (Differential Scorer +
12
+ * Classifier + Breakthrough Scorer 89.2) -> Phase 4 (Thesis 89.2 +
13
+ * Commercial Assessor 89.5-01 + Expert Mapper 89.3) -> Output Layer
14
+ * (89.3 Aura/SQLite writer + Mind Map) -> Chain Downstream (89.4
15
+ * Chain Feeder).
16
+ *
17
+ * 9 scenarios total (>=8 mandated by plan):
18
+ * T1 -- happy path: full pipeline with mocked 89.1-89.5 modules; bundle
19
+ * shape verified ({topic, domain_analysis, query_matrix,
20
+ * fetched_results, preprocessed, scored, classified, breakthroughs,
21
+ * theses, commercial, output: {written, mind_map, experts},
22
+ * chain_metadata}); chain_metadata array of >=1 entry per
23
+ * discovery; each entry has {recommended_verb, feeds_into,
24
+ * spawn_skill, confidence, reasoning}.
25
+ * T2 -- Tier 0 fallback: rs-neo4j-writer.writeDiscovery throws
26
+ * AuraUnreachableError -> orchestrator catches; bundle.output.written.tier
27
+ * === 'tier0' (dispatched to rs-sqlite-mirror).
28
+ * T3 -- Mode B graceful: chain-feeder.lookupUpstream returns
29
+ * {state: 'ready'} (Brain-unreachable graceful path); bundle still
30
+ * populates chain_metadata; emitChainMetadata still works locally.
31
+ * T4 -- chain composition: every chain_metadata.recommended_verb is in
32
+ * CANONICAL_VERBS; spawn_skill is null OR matches a SKILL_SPAWN_RULES
33
+ * rule; feeds_into is one of {'PWS VP', 'Causal Loop',
34
+ * 'Navigation Engine', 'JTBD'}.
35
+ * T5 -- Canon Part 8 input audit: opts contains forbidden bytes ->
36
+ * auditQueryObject throws ExternalEgressViolation BEFORE any module
37
+ * is invoked; err.meta.surface === 'rs-discovery-engine-input'.
38
+ * T6 -- Brain chokepoint exclusivity: read scripts/rs-discovery-engine.cjs
39
+ * source; assert grep 'fetch(' === 0; grep 'require.*brain-client'
40
+ * === 0 (orchestrator never directly imports brain-client; ALL
41
+ * Brain queries go through chain-feeder.lookupUpstream).
42
+ * T7 -- pause-state bubble: chain-feeder.lookupUpstream returns
43
+ * {state: 'pause', missing_upstream, suggested_action}; orchestrator
44
+ * returns the pause envelope verbatim; NO further phase modules
45
+ * invoked (mocks track invocation count; assert all === 0 after
46
+ * pause).
47
+ * T8 -- A1 sweep: every positive-path bundle JSON.stringify contains ZERO
48
+ * FORBIDDEN_PATTERNS hits.
49
+ * T9 -- runDiscovery is AsyncFunction (Module exports surface check).
50
+ *
51
+ * Pure CJS, zero npm deps, node built-ins only (assert + fs).
52
+ */
53
+
54
+ const assert = require('node:assert/strict');
55
+ const fs = require('node:fs');
56
+ const path = require('node:path');
57
+
58
+ // ---------- Suite bookkeeping ----------
59
+
60
+ let passed = 0;
61
+ let failed = 0;
62
+ const failures = [];
63
+ const tests = [];
64
+
65
+ function record(name, fn) {
66
+ tests.push({ name, fn });
67
+ }
68
+
69
+ async function runAll() {
70
+ for (const t of tests) {
71
+ try {
72
+ await t.fn();
73
+ passed++;
74
+ process.stdout.write('PASS ' + t.name + '\n');
75
+ } catch (err) {
76
+ failed++;
77
+ failures.push({ name: t.name, message: err && err.message ? err.message : String(err) });
78
+ process.stdout.write('FAIL ' + t.name + ': ' + (err && err.message ? err.message : String(err)) + '\n');
79
+ }
80
+ }
81
+ }
82
+
83
+ // ---------- Module under test ----------
84
+
85
+ const ENGINE_PATH = path.resolve(__dirname, '..', '..', 'scripts', 'rs-discovery-engine.cjs');
86
+ const orchestrator = require(ENGINE_PATH);
87
+ const { runDiscovery } = orchestrator;
88
+
89
+ // ---------- Reference imports for invariants ----------
90
+
91
+ const { CANONICAL_VERBS, SKILL_SPAWN_RULES } = require('../core/rs-chain-feeder.cjs');
92
+ const { FORBIDDEN_PATTERNS } = require('../core/rs-egress-prompts.cjs');
93
+
94
+ const FEEDS_INTO_CANONICAL = new Set(['PWS VP', 'Causal Loop', 'Navigation Engine', 'JTBD']);
95
+
96
+ // ---------- Helper: build deterministic mocks ----------
97
+ //
98
+ // Every mock returns a deterministic fixture so the orchestrator can be
99
+ // tested without external infrastructure (Brain, Aura, filesystem). The
100
+ // orchestrator's _test_mocks option substitutes these for the real
101
+ // require'd modules.
102
+
103
+ function makeInvocationCounters() {
104
+ return {
105
+ domainAnalyzer: 0,
106
+ queryMatrix: 0,
107
+ fetcherAcademic: 0,
108
+ fetcherPatents: 0,
109
+ fetcherIndustry: 0,
110
+ fetcherExperts: 0,
111
+ preprocessor: 0,
112
+ differentialScorer: 0,
113
+ innovationClassifier: 0,
114
+ breakthroughScorer: 0,
115
+ thesisGenerator: 0,
116
+ commercialAssessor: 0,
117
+ expertMapper: 0,
118
+ neo4jWriter: 0,
119
+ sqliteMirror: 0,
120
+ mindMap: 0,
121
+ chainFeederLookup: 0,
122
+ chainFeederEmit: 0,
123
+ };
124
+ }
125
+
126
+ function buildMockSet(opts) {
127
+ opts = opts || {};
128
+ const counts = opts.counts || makeInvocationCounters();
129
+
130
+ const mocks = {
131
+ domainAnalyzer: {
132
+ analyzeDomain: async function (topic) {
133
+ counts.domainAnalyzer += 1;
134
+ return {
135
+ primary_domain: 'biotech',
136
+ concepts: ['quantum', 'imaging', 'brain'],
137
+ terminology: ['MRI', 'qubit', 'fMRI'],
138
+ methods: ['superconducting', 'tomography'],
139
+ breakthroughs: ['NV-center diamond sensing'],
140
+ boundary_flag: false,
141
+ adjacent_domains: ['neurology', 'condensed matter physics'],
142
+ };
143
+ },
144
+ },
145
+ queryMatrix: {
146
+ generateQueryMatrix: function (analysis) {
147
+ counts.queryMatrix += 1;
148
+ return {
149
+ a_intersect_b: ['quantum AND imaging'],
150
+ a_leads_to_b: ['quantum -> imaging'],
151
+ b_leads_to_a: ['imaging -> quantum'],
152
+ adjacent: ['NV-center'],
153
+ };
154
+ },
155
+ },
156
+ fetcherAcademic: {
157
+ fetchAcademic: async function (queries) {
158
+ counts.fetcherAcademic += 1;
159
+ return {
160
+ papers: [
161
+ {
162
+ id: 'oa:123',
163
+ title: 'NV-center diamond magnetometry',
164
+ abstract: 'Superconducting qubit imaging.',
165
+ authors: [{ name: 'Dr. A', orcid: '0000-0001', institution: 'MIT' }],
166
+ source: 'openalex',
167
+ },
168
+ ],
169
+ telemetry: [{ source: 'openalex', status: 'ok' }],
170
+ };
171
+ },
172
+ },
173
+ fetcherPatents: {
174
+ fetchPatents: async function (queries) {
175
+ counts.fetcherPatents += 1;
176
+ return {
177
+ patents: [{ id: 'us:9876543', title: 'Method for NV-center imaging', abstract: 'patent abstract' }],
178
+ telemetry: [],
179
+ };
180
+ },
181
+ },
182
+ fetcherIndustry: {
183
+ fetchIndustry: async function (queries) {
184
+ counts.fetcherIndustry += 1;
185
+ return {
186
+ signals: [{ id: 'cb:co1', title: 'StartupCo NV imaging', signal: 'industry signal' }],
187
+ telemetry: [],
188
+ };
189
+ },
190
+ },
191
+ fetcherExperts: {
192
+ mapExperts: function (papers) {
193
+ counts.fetcherExperts += 1;
194
+ return [
195
+ {
196
+ name: 'Dr. A',
197
+ orcid: '0000-0001',
198
+ institution: 'MIT',
199
+ paper_count: 1,
200
+ h_index_estimate: 5,
201
+ },
202
+ ];
203
+ },
204
+ },
205
+ preprocessor: {
206
+ preprocess: function (documents) {
207
+ counts.preprocessor += 1;
208
+ return [
209
+ {
210
+ document_id: 'oa:123',
211
+ technical_terms: ['NV', 'magnetometry'],
212
+ concepts: ['quantum imaging'],
213
+ methods: ['superconducting'],
214
+ relevance_score: 0.8,
215
+ boundary_flag: false,
216
+ },
217
+ ];
218
+ },
219
+ },
220
+ differentialScorer: {
221
+ score: async function (queryConcept, docConcept, opts) {
222
+ counts.differentialScorer += 1;
223
+ return { diff: 0.3, lsa: 0.6, bert: 0.3, passes: true };
224
+ },
225
+ },
226
+ innovationClassifier: {
227
+ classify: function (scoredPair) {
228
+ counts.innovationClassifier += 1;
229
+ return Object.assign({}, scoredPair, {
230
+ query_concept: scoredPair.query_concept || 'quantum imaging',
231
+ doc_concept: scoredPair.doc_concept || 'transformer attention',
232
+ classification: 'structural_transfer',
233
+ bridge_concept: 'graph attention',
234
+ });
235
+ },
236
+ },
237
+ breakthroughScorer: {
238
+ scoreBreakthrough: function (classifiedPair) {
239
+ counts.breakthroughScorer += 1;
240
+ return Object.assign({}, classifiedPair, {
241
+ breakthrough: {
242
+ score: 8,
243
+ breakdown: { feasibility: 1.5, market: 1.6, magnitude: 1.7, advantage: 1.5, impact: 1.7 },
244
+ dominant_dimension: 'magnitude',
245
+ },
246
+ });
247
+ },
248
+ },
249
+ thesisGenerator: {
250
+ generateThesis: function (classifiedPair, breakthrough) {
251
+ counts.thesisGenerator += 1;
252
+ return 'By applying quantum imaging to transformer attention, achieve novelty because graph attention.';
253
+ },
254
+ },
255
+ commercialAssessor: {
256
+ assess: function (rsDiscovery) {
257
+ counts.commercialAssessor += 1;
258
+ return {
259
+ market_size_estimate: 'addressable market in the high single-digit billions',
260
+ value_proposition: 'translate quantum imaging into transformer attention',
261
+ partnership_targets: [{ name: 'MIT', type: 'academic', score: 0.9 }],
262
+ };
263
+ },
264
+ },
265
+ expertMapper: {
266
+ mapAuthorsToAura: async function (experts, opts) {
267
+ counts.expertMapper += 1;
268
+ return {
269
+ resolved_authors: [{
270
+ name: 'Dr. A', orcid: '0000-0001', institution: 'MIT',
271
+ h_index_estimate: 5, paper_count: 1, aura_node_id: null,
272
+ }],
273
+ resolved_institutions: [{ name: 'MIT', author_count: 1 }],
274
+ citation_edges: [],
275
+ missed_count: 0,
276
+ resolution_quality: 'degraded',
277
+ tier: 'sqlite',
278
+ schema_version: 1,
279
+ note: 'tier-0 degraded',
280
+ };
281
+ },
282
+ },
283
+ neo4jWriter: {
284
+ writeDiscovery: async function (pair, opts) {
285
+ counts.neo4jWriter += 1;
286
+ return {
287
+ wrote_node_count: 3,
288
+ wrote_edge_count: 2,
289
+ rollback_cypher: 'MATCH ... DETACH DELETE',
290
+ aura_op_id: 'op-aura-1',
291
+ schema_version: 1,
292
+ };
293
+ },
294
+ AuraUnreachableError: class AuraUnreachableError extends Error {
295
+ constructor(msg, meta) { super(msg); this.name = 'AuraUnreachableError'; this.meta = meta || {}; }
296
+ },
297
+ },
298
+ sqliteMirror: {
299
+ writeDiscovery: async function (pair, opts) {
300
+ counts.sqliteMirror += 1;
301
+ return {
302
+ wrote_node_count: 3,
303
+ wrote_edge_count: 2,
304
+ rollback_cypher: 'DELETE FROM ...',
305
+ aura_op_id: 'op-sqlite-1',
306
+ schema_version: 1,
307
+ };
308
+ },
309
+ },
310
+ mindMap: {
311
+ renderMindMap: async function (queryFilter, opts) {
312
+ counts.mindMap += 1;
313
+ return {
314
+ branches: {},
315
+ elements: [],
316
+ branch_colors: {},
317
+ metadata: { tier: 'sqlite', branch_counts: {}, total_nodes: 0, total_edges: 0, schema_version: 1 },
318
+ html_wrapper: '<html></html>',
319
+ };
320
+ },
321
+ },
322
+ chainFeeder: {
323
+ lookupUpstream: async function (problemType, stage, opts) {
324
+ counts.chainFeederLookup += 1;
325
+ return { state: 'ready' };
326
+ },
327
+ emitChainMetadata: function (rsType, score, activeContext) {
328
+ counts.chainFeederEmit += 1;
329
+ // Mirror the real chain-feeder logic for these scalars so T4
330
+ // chain composition checks (CANONICAL_VERBS membership +
331
+ // SKILL_SPAWN_RULES alignment + feeds_into canonical set) hold.
332
+ let feedsInto = 'JTBD';
333
+ if (rsType === 'structural_transfer') feedsInto = 'PWS VP';
334
+ else if (rsType === 'semantic_implementation') feedsInto = 'Causal Loop';
335
+ else if (rsType === 'hybrid') feedsInto = 'Navigation Engine';
336
+ const safeScore = Number.isFinite(score) ? score : 0;
337
+ let verb = 'Reformulate';
338
+ if (safeScore >= 7) verb = 'Bank Opportunity';
339
+ else if (safeScore >= 5) verb = 'Synthesize';
340
+ let spawnSkill = null;
341
+ let confidence = 0;
342
+ let reasoning = 'no rule matched';
343
+ // Mirror the first SKILL_SPAWN_RULES rule for happy-path mocks
344
+ // (score>=7 + structural_transfer -> /mos:find-analogies @ 0.85).
345
+ if (safeScore >= 7 && rsType === 'structural_transfer') {
346
+ spawnSkill = '/mos:find-analogies';
347
+ confidence = 0.85;
348
+ reasoning = 'high breakthrough + structural transfer -> SAPPhIRE/TRIZ deepening';
349
+ }
350
+ return {
351
+ recommended_verb: verb,
352
+ feeds_into: feedsInto,
353
+ spawn_skill: spawnSkill,
354
+ confidence: confidence,
355
+ reasoning: reasoning,
356
+ };
357
+ },
358
+ },
359
+ };
360
+
361
+ return { mocks, counts };
362
+ }
363
+
364
+ // Capture box for A1 sweep.
365
+ const positiveBundles = [];
366
+
367
+ // ---------- Tests ----------
368
+
369
+ record('T1 happy path: full pipeline with mocked 89.1-89.5 modules; bundle shape verified', async function () {
370
+ const { mocks, counts } = buildMockSet();
371
+ const bundle = await runDiscovery('quantum brain imaging', {
372
+ room_dir: '/tmp/test-room',
373
+ _test_mocks: mocks,
374
+ });
375
+
376
+ // Bundle shape.
377
+ assert.equal(typeof bundle, 'object', 'bundle must be object');
378
+ assert.equal(bundle.topic, 'quantum brain imaging', 'bundle.topic must match input');
379
+ assert.ok(bundle.domain_analysis && typeof bundle.domain_analysis === 'object', 'domain_analysis required');
380
+ assert.ok(bundle.query_matrix && typeof bundle.query_matrix === 'object', 'query_matrix required');
381
+ assert.ok(bundle.fetched_results && typeof bundle.fetched_results === 'object', 'fetched_results required');
382
+ assert.ok(Array.isArray(bundle.preprocessed), 'preprocessed must be array');
383
+ assert.ok(Array.isArray(bundle.scored), 'scored must be array');
384
+ assert.ok(Array.isArray(bundle.classified), 'classified must be array');
385
+ assert.ok(Array.isArray(bundle.breakthroughs), 'breakthroughs must be array');
386
+ assert.ok(Array.isArray(bundle.theses), 'theses must be array');
387
+ assert.ok(Array.isArray(bundle.commercial), 'commercial must be array');
388
+ assert.ok(bundle.output && typeof bundle.output === 'object', 'output required');
389
+ assert.ok(bundle.output.written && typeof bundle.output.written === 'object', 'output.written required');
390
+ assert.ok(bundle.output.mind_map && typeof bundle.output.mind_map === 'object', 'output.mind_map required');
391
+ assert.ok(bundle.output.experts && typeof bundle.output.experts === 'object', 'output.experts required');
392
+ assert.ok(Array.isArray(bundle.chain_metadata), 'chain_metadata must be array');
393
+
394
+ // Chain metadata contract: >=1 entry; each has the 5 canonical fields.
395
+ assert.ok(bundle.chain_metadata.length >= 1, 'chain_metadata must have >=1 entry');
396
+ for (const e of bundle.chain_metadata) {
397
+ assert.equal(typeof e.recommended_verb, 'string', 'recommended_verb must be string');
398
+ assert.equal(typeof e.feeds_into, 'string', 'feeds_into must be string');
399
+ assert.ok(e.spawn_skill === null || typeof e.spawn_skill === 'string',
400
+ 'spawn_skill must be null or string');
401
+ assert.equal(typeof e.confidence, 'number', 'confidence must be number');
402
+ assert.equal(typeof e.reasoning, 'string', 'reasoning must be string');
403
+ }
404
+
405
+ // Sanity: every mocked phase invoked at least once.
406
+ assert.ok(counts.domainAnalyzer >= 1, 'domainAnalyzer must be invoked');
407
+ assert.ok(counts.queryMatrix >= 1, 'queryMatrix must be invoked');
408
+ assert.ok(counts.fetcherAcademic >= 1, 'fetcherAcademic must be invoked');
409
+ assert.ok(counts.preprocessor >= 1, 'preprocessor must be invoked');
410
+ assert.ok(counts.chainFeederEmit >= 1, 'chainFeederEmit must be invoked');
411
+
412
+ positiveBundles.push(bundle);
413
+ });
414
+
415
+ record('T2 Tier 0 fallback: writeDiscovery throws AuraUnreachableError -> dispatched to sqlite', async function () {
416
+ const { mocks, counts } = buildMockSet();
417
+ // Force tier1 dispatch (simulate Aura url present) but make Aura write throw.
418
+ mocks.neo4jWriter.writeDiscovery = async function () {
419
+ counts.neo4jWriter += 1;
420
+ const E = mocks.neo4jWriter.AuraUnreachableError;
421
+ throw new E('Aura backend unreachable: simulated', { original: 'simulated' });
422
+ };
423
+
424
+ const bundle = await runDiscovery('quantum brain imaging', {
425
+ room_dir: '/tmp/test-room',
426
+ aura_url: 'neo4j+s://fake.aura.io', // forces tier1 detection
427
+ _test_mocks: mocks,
428
+ });
429
+
430
+ // Orchestrator must catch AuraUnreachableError and dispatch to sqlite.
431
+ assert.equal(bundle.output.written.tier, 'tier0',
432
+ 'output.written.tier must === tier0 after Aura-unreachable graceful fallback');
433
+ assert.ok(counts.sqliteMirror >= 1, 'sqliteMirror must be invoked on Tier 0 fallback');
434
+ assert.ok(counts.neo4jWriter >= 1, 'neo4jWriter must have been attempted before fallback');
435
+
436
+ positiveBundles.push(bundle);
437
+ });
438
+
439
+ record('T3 Mode B graceful: lookupUpstream ready (Brain unreachable) -> chain_metadata populated', async function () {
440
+ const { mocks, counts } = buildMockSet();
441
+ mocks.chainFeeder.lookupUpstream = async function () {
442
+ counts.chainFeederLookup += 1;
443
+ // Brain-unreachable graceful path per 89.4-02.
444
+ return { state: 'ready' };
445
+ };
446
+
447
+ const bundle = await runDiscovery('quantum brain imaging', {
448
+ room_dir: '/tmp/test-room',
449
+ _test_mocks: mocks,
450
+ });
451
+
452
+ // chain_metadata still populated locally (emitChainMetadata works without Brain).
453
+ assert.ok(Array.isArray(bundle.chain_metadata), 'chain_metadata must be array');
454
+ assert.ok(bundle.chain_metadata.length >= 1, 'chain_metadata must populate even in Mode B');
455
+ assert.ok(counts.chainFeederEmit >= 1, 'emitChainMetadata must run locally even when Brain is unreachable');
456
+
457
+ positiveBundles.push(bundle);
458
+ });
459
+
460
+ record('T4 chain composition: every recommended_verb in CANONICAL_VERBS; spawn_skill aligned; feeds_into canonical', async function () {
461
+ const { mocks } = buildMockSet();
462
+ const bundle = await runDiscovery('quantum brain imaging', {
463
+ room_dir: '/tmp/test-room',
464
+ _test_mocks: mocks,
465
+ });
466
+
467
+ const validSpawnSkills = new Set(SKILL_SPAWN_RULES.map(function (r) { return r.spawn; }));
468
+ for (const e of bundle.chain_metadata) {
469
+ assert.ok(CANONICAL_VERBS.includes(e.recommended_verb),
470
+ 'recommended_verb must be in CANONICAL_VERBS; got ' + JSON.stringify(e.recommended_verb));
471
+ if (e.spawn_skill !== null) {
472
+ assert.ok(validSpawnSkills.has(e.spawn_skill),
473
+ 'spawn_skill must match SKILL_SPAWN_RULES rule; got ' + JSON.stringify(e.spawn_skill));
474
+ }
475
+ assert.ok(FEEDS_INTO_CANONICAL.has(e.feeds_into),
476
+ 'feeds_into must be in canonical set; got ' + JSON.stringify(e.feeds_into));
477
+ }
478
+
479
+ positiveBundles.push(bundle);
480
+ });
481
+
482
+ record('T5 Canon Part 8 input audit: forbidden bytes in opts -> ExternalEgressViolation BEFORE any module invoked', async function () {
483
+ const counts = makeInvocationCounters();
484
+ const { mocks } = buildMockSet({ counts: counts });
485
+
486
+ let caught = null;
487
+ try {
488
+ await runDiscovery('topic', {
489
+ meeting_transcript: 'meeting with Lawrence said the deal is $5M',
490
+ _test_mocks: mocks,
491
+ });
492
+ } catch (err) {
493
+ caught = err;
494
+ }
495
+
496
+ assert.ok(caught !== null, 'expected ExternalEgressViolation throw, got none');
497
+ assert.equal(caught.name, 'ExternalEgressViolation',
498
+ 'expected err.name=ExternalEgressViolation; got ' + (caught && caught.name));
499
+ assert.ok(caught.meta && typeof caught.meta === 'object', 'err.meta must be object');
500
+ assert.equal(caught.meta.surface, 'rs-discovery-engine-input',
501
+ 'expected err.meta.surface=rs-discovery-engine-input; got ' + JSON.stringify(caught.meta.surface));
502
+
503
+ // Defense-in-depth: NO module invoked because audit ran at the gate.
504
+ assert.equal(counts.domainAnalyzer, 0, 'domainAnalyzer must NOT be invoked after audit throw');
505
+ assert.equal(counts.queryMatrix, 0, 'queryMatrix must NOT be invoked after audit throw');
506
+ assert.equal(counts.fetcherAcademic, 0, 'fetcherAcademic must NOT be invoked after audit throw');
507
+ assert.equal(counts.chainFeederLookup, 0, 'chainFeederLookup must NOT be invoked after audit throw');
508
+ });
509
+
510
+ record('T6 Brain chokepoint exclusivity: source has zero fetch( and zero direct brain-client require', function () {
511
+ const src = fs.readFileSync(ENGINE_PATH, 'utf8');
512
+ // No code path may invoke fetch( from the orchestrator. The 89.2 fetchers
513
+ // each have their OWN audit chokepoint; the orchestrator never reaches
514
+ // the network directly.
515
+ // Strip line comments and block comments before scanning.
516
+ const stripped = src
517
+ .replace(/\/\*[\s\S]*?\*\//g, '')
518
+ .replace(/\/\/[^\n]*/g, '');
519
+ assert.ok(stripped.indexOf('fetch(') === -1,
520
+ 'orchestrator source must NOT contain fetch( in code (defense-in-depth: zero new fetch surface)');
521
+
522
+ // The orchestrator never directly imports brain-client. ALL Brain queries
523
+ // go through chain-feeder.lookupUpstream which wraps brainClient.query
524
+ // per 89.4-02 chokepoint reuse.
525
+ const brainRequireRegex = /require\([^)]*brain-client[^)]*\)/;
526
+ assert.equal(brainRequireRegex.test(stripped), false,
527
+ 'orchestrator must NOT directly require brain-client.cjs; reuse 89.4-02 chain-feeder.lookupUpstream chokepoint');
528
+ });
529
+
530
+ record('T7 pause-state bubble: lookupUpstream pause -> pause envelope returned; NO further phase modules invoked', async function () {
531
+ const counts = makeInvocationCounters();
532
+ const { mocks } = buildMockSet({ counts: counts });
533
+ mocks.chainFeeder.lookupUpstream = async function () {
534
+ counts.chainFeederLookup += 1;
535
+ return {
536
+ state: 'pause',
537
+ missing_upstream: ['systems-thinking'],
538
+ suggested_action: 'Run Methodology',
539
+ };
540
+ };
541
+
542
+ const result = await runDiscovery('quantum brain imaging', {
543
+ room_dir: '/tmp/test-room',
544
+ _test_mocks: mocks,
545
+ });
546
+
547
+ // Pause envelope bubbles up verbatim.
548
+ assert.equal(result.state, 'pause', 'pause-state result.state must === pause');
549
+ assert.ok(Array.isArray(result.missing_upstream), 'pause result.missing_upstream must be array');
550
+ assert.equal(result.missing_upstream[0], 'systems-thinking', 'missing_upstream[0] preserved');
551
+ assert.equal(result.suggested_action, 'Run Methodology', 'suggested_action preserved');
552
+
553
+ // No phase modules beyond the chain-feeder gate were invoked.
554
+ assert.equal(counts.domainAnalyzer, 0, 'domainAnalyzer must NOT run after pause');
555
+ assert.equal(counts.queryMatrix, 0, 'queryMatrix must NOT run after pause');
556
+ assert.equal(counts.fetcherAcademic, 0, 'fetcherAcademic must NOT run after pause');
557
+ assert.equal(counts.preprocessor, 0, 'preprocessor must NOT run after pause');
558
+ assert.equal(counts.differentialScorer, 0, 'differentialScorer must NOT run after pause');
559
+ assert.equal(counts.chainFeederEmit, 0, 'chainFeederEmit must NOT run after pause');
560
+ assert.equal(counts.neo4jWriter, 0, 'neo4jWriter must NOT run after pause');
561
+ assert.equal(counts.sqliteMirror, 0, 'sqliteMirror must NOT run after pause');
562
+ });
563
+
564
+ record('T8 A1 sweep: every positive-path bundle JSON contains ZERO FORBIDDEN_PATTERNS hits', function () {
565
+ assert.ok(Array.isArray(FORBIDDEN_PATTERNS) && FORBIDDEN_PATTERNS.length >= 6,
566
+ 'FORBIDDEN_PATTERNS must be re-exported (>= 6 patterns)');
567
+ assert.ok(positiveBundles.length >= 4,
568
+ 'A1 sweep requires at least 4 captured positive bundles; got ' + positiveBundles.length);
569
+ for (let i = 0; i < positiveBundles.length; i += 1) {
570
+ const json = JSON.stringify(positiveBundles[i]);
571
+ for (const re of FORBIDDEN_PATTERNS) {
572
+ assert.equal(re.test(json), false,
573
+ 'positive bundle ' + i + ' contains FORBIDDEN_PATTERNS hit ' + re.source
574
+ + ' in JSON: ' + json.slice(0, 200));
575
+ }
576
+ }
577
+ });
578
+
579
+ record('T9 runDiscovery is AsyncFunction; Module exports surface verified', function () {
580
+ assert.equal(typeof runDiscovery, 'function', 'runDiscovery must be a function');
581
+ assert.equal(runDiscovery.constructor.name, 'AsyncFunction',
582
+ 'runDiscovery must be AsyncFunction; got ' + runDiscovery.constructor.name);
583
+ assert.ok(orchestrator._test && typeof orchestrator._test === 'object',
584
+ '_test export surface must be present for whitebox introspection');
585
+ });
586
+
587
+ // ---------- Suite report ----------
588
+
589
+ (async function () {
590
+ await runAll();
591
+ const total = passed + failed;
592
+ process.stdout.write('\n');
593
+ if (failed === 0) {
594
+ process.stdout.write('=== 89.5-04 rs-discovery-engine suite: ' + passed + '/' + total + ' passed ===\n');
595
+ process.exit(0);
596
+ } else {
597
+ process.stdout.write('=== 89.5-04 rs-discovery-engine suite: ' + passed + '/' + total + ' passed (' + failed + ' failed) ===\n');
598
+ for (const f of failures) {
599
+ process.stdout.write(' FAIL ' + f.name + ': ' + f.message + '\n');
600
+ }
601
+ process.exit(1);
602
+ }
603
+ })();