@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,551 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /*
5
+ * Copyright (c) 2026 Mindrian. BSL 1.1.
6
+ * Phase 89.5 Plan 03 -- rs-query-to-text Larry-voiced explainer suite.
7
+ *
8
+ * 11 scenarios covering raw graph results -> Larry-voiced NL explanation:
9
+ *
10
+ * Positive-path (4 result types each get >=1 test):
11
+ * T1 rs_discovery kind: explain renders evidence + insight + warning structure
12
+ * T2 expert_network kind: explain mentions experts + institutions
13
+ * T3 methodology_chain kind: explain mentions JTBD chaining
14
+ * T4 discovery_history kind: explain mentions count + reflection prompt
15
+ *
16
+ * Venture context enrichment (Mode A; quadruple complete):
17
+ * T5 opts._test_quadruple_override carries room+state+minto+brain;
18
+ * rendered string surfaces brain.sections.pattern_matches signal
19
+ * (Mode A enrichment proof)
20
+ *
21
+ * Mode B fallback (BRAIN.md absent):
22
+ * T6 opts._test_quadruple_override with brain:null still renders coherent
23
+ * string and does NOT contain Mode A "Brain says" enrichment marker
24
+ *
25
+ * No-LLM invariant:
26
+ * T7 fetch shim never called; brain-client require throws if attempted;
27
+ * explain() returns normally
28
+ *
29
+ * Canon Part 8 adversarial (post-render audit):
30
+ * T8 forbidden pattern in input query_results -> input audit OR output
31
+ * audit throws ExternalEgressViolation
32
+ * T9 forbidden meeting fragment in row text -> output redacts OR throws
33
+ *
34
+ * Voice pattern adherence:
35
+ * T10 rs_discovery output matches Evidence -> Insight -> Warning pedagogy
36
+ *
37
+ * A1 sweep (defense-in-depth across positive outputs):
38
+ * T11 every positive-path rendered string scanned against
39
+ * FORBIDDEN_PATTERNS -> zero matches
40
+ *
41
+ * Pure CJS, zero npm deps, node built-ins only (assert + fs + path).
42
+ */
43
+
44
+ const assert = require('node:assert/strict');
45
+ const fs = require('node:fs');
46
+ const path = require('node:path');
47
+
48
+ // ---------- Suite bookkeeping ----------
49
+
50
+ let passed = 0;
51
+ let failed = 0;
52
+ const failures = [];
53
+
54
+ function record(name, fn) {
55
+ try {
56
+ fn();
57
+ passed++;
58
+ process.stdout.write('PASS ' + name + '\n');
59
+ } catch (err) {
60
+ failed++;
61
+ failures.push({ name, message: err && err.message ? err.message : String(err) });
62
+ process.stdout.write('FAIL ' + name + ': ' + (err && err.message ? err.message : String(err)) + '\n');
63
+ }
64
+ }
65
+
66
+ // ---------- Module under test ----------
67
+
68
+ const mod = require('../core/rs-query-to-text.cjs');
69
+ const { explain, VOICE_TEMPLATES, _test } = mod;
70
+
71
+ const egressPrompts = require('../core/rs-egress-prompts.cjs');
72
+ const { FORBIDDEN_PATTERNS } = egressPrompts;
73
+
74
+ // Collect positive-test outputs for the A1 sweep (T11).
75
+ const positiveOutputs = [];
76
+
77
+ // ---------- T1: rs_discovery positive path ----------
78
+
79
+ record('T1 rs_discovery: explain renders Larry-voiced evidence + insight', function () {
80
+ const query_results = {
81
+ kind: 'rs_discovery',
82
+ rows: [
83
+ {
84
+ id: 'rs-1',
85
+ thesis: 'Apply quantum sensing to adjacent imaging modalities',
86
+ breakthrough_score: 8,
87
+ classification: 'structural_transfer',
88
+ domains: ['physics', 'medicine'],
89
+ },
90
+ {
91
+ id: 'rs-2',
92
+ thesis: 'Photonic compute',
93
+ breakthrough_score: 5,
94
+ },
95
+ ],
96
+ };
97
+ const out = explain(query_results, {});
98
+ positiveOutputs.push(out);
99
+
100
+ assert.equal(typeof out, 'string', 'explain must return a string');
101
+ assert.ok(out.length > 0, 'rendered string must be non-empty');
102
+ // Evidence: numeric "Found N" or "discoveries" leading.
103
+ assert.ok(/\b2\b/.test(out),
104
+ 'rendered string must reference the row count (2) somewhere');
105
+ assert.ok(/(Found|discoveries|surfaced|candidates|pairs)/i.test(out),
106
+ 'rendered string must lead with an evidence verb (Found / discoveries / surfaced / candidates / pairs)');
107
+ // Insight: top thesis surfaces in narrative.
108
+ assert.ok(out.indexOf('Apply quantum sensing') !== -1,
109
+ 'top thesis text must surface in rendered string');
110
+ // Warning / forward-looking: a Canon Part 3 verb OR a /mos: command OR
111
+ // pedagogical "next" prompt appears in the rendering.
112
+ const hasNextPrompt =
113
+ /(Bank Opportunity|Run Methodology|Devils Advocate|Synthesize|Reformulate|Defer|Reflect|Reading the Room)/i.test(out)
114
+ || /\/mos:/.test(out)
115
+ || /(file|next|worth|merits)/i.test(out);
116
+ assert.ok(hasNextPrompt,
117
+ 'rendered string must include a forward-looking next-step (Canon Part 3 verb or /mos: command or pedagogical prompt)');
118
+ });
119
+
120
+ // ---------- T2: expert_network positive path ----------
121
+
122
+ record('T2 expert_network: explain mentions experts + institutions', function () {
123
+ const query_results = {
124
+ kind: 'expert_network',
125
+ rows: [
126
+ { name: 'Dr. X', institution: 'MIT' },
127
+ { name: 'Dr. Y', institution: 'Stanford' },
128
+ ],
129
+ };
130
+ const out = explain(query_results, {});
131
+ positiveOutputs.push(out);
132
+
133
+ assert.equal(typeof out, 'string', 'explain must return a string');
134
+ assert.ok(/\b2\b/.test(out), 'rendered string must reference row count 2');
135
+ // At least one of "Mapped" or "experts" or "authors" leads.
136
+ assert.ok(/(Mapped|experts|authors|domain experts|Found)/i.test(out),
137
+ 'rendered string must lead with an expert-network evidence verb');
138
+ // Both institutions surface.
139
+ assert.ok(out.indexOf('MIT') !== -1, 'rendered string must include MIT');
140
+ assert.ok(out.indexOf('Stanford') !== -1, 'rendered string must include Stanford');
141
+ });
142
+
143
+ // ---------- T3: methodology_chain positive path ----------
144
+
145
+ record('T3 methodology_chain: explain mentions JTBD chain pattern', function () {
146
+ const query_results = {
147
+ kind: 'methodology_chain',
148
+ rows: [
149
+ { from: 'jtbd', to: 'persona' },
150
+ { from: 'jtbd', to: 'lean-canvas' },
151
+ ],
152
+ };
153
+ const out = explain(query_results, {});
154
+ positiveOutputs.push(out);
155
+
156
+ assert.equal(typeof out, 'string', 'explain must return a string');
157
+ // Source framework name surfaces.
158
+ assert.ok(/jtbd/i.test(out), 'rendered string must reference jtbd source');
159
+ // Downstream targets surface.
160
+ const hasPersona = out.indexOf('persona') !== -1;
161
+ const hasLean = out.indexOf('lean-canvas') !== -1;
162
+ assert.ok(hasPersona || hasLean,
163
+ 'rendered string must mention at least one downstream target (persona OR lean-canvas)');
164
+ // Numeric chain count surfaces.
165
+ assert.ok(/\b2\b/.test(out),
166
+ 'rendered string must reference downstream count 2');
167
+ });
168
+
169
+ // ---------- T4: discovery_history positive path ----------
170
+
171
+ record('T4 discovery_history: explain renders count + reflection prompt', function () {
172
+ const query_results = {
173
+ kind: 'discovery_history',
174
+ rows: [
175
+ { thesis: 'Old discovery', created_at: '2026-04-20' },
176
+ { thesis: 'Newer discovery insight', created_at: '2026-04-26' },
177
+ ],
178
+ };
179
+ const out = explain(query_results, {});
180
+ positiveOutputs.push(out);
181
+
182
+ assert.equal(typeof out, 'string', 'explain must return a string');
183
+ assert.ok(/\b2\b/.test(out),
184
+ 'rendered string must reference history count 2');
185
+ assert.ok(/(discoveries|logged|looking back|recent)/i.test(out),
186
+ 'rendered string must lead with a discovery-history evidence verb');
187
+ // Most-recent thesis surfaces.
188
+ assert.ok(out.indexOf('Newer discovery insight') !== -1
189
+ || out.indexOf('Old discovery') !== -1,
190
+ 'rendered string must mention at least one historical thesis');
191
+ // Reflection prompt: Synthesize OR /mos:reflect OR convergence cue.
192
+ assert.ok(/(Synthesize|Reflect|reflecting|convergence|pattern)/i.test(out),
193
+ 'rendered string must include a reflection prompt (Synthesize / Reflect / convergence / pattern)');
194
+ });
195
+
196
+ // ---------- T5: venture context enrichment (Mode A; quadruple complete) ----------
197
+
198
+ record('T5 Mode A: quadruple override surfaces brain enrichment in render', function () {
199
+ const query_results = {
200
+ kind: 'rs_discovery',
201
+ rows: [
202
+ {
203
+ id: 'rs-1',
204
+ thesis: 'Adjacent domain transfer hypothesis',
205
+ breakthrough_score: 7,
206
+ classification: 'structural_transfer',
207
+ },
208
+ ],
209
+ };
210
+ const opts = {
211
+ room_dir: '/tmp/test-room-with-quadruple',
212
+ _test_quadruple_override: {
213
+ room: {
214
+ exists: true,
215
+ identity_text: 'fintech-venture',
216
+ references: [],
217
+ last_updated_at: null,
218
+ },
219
+ state: {
220
+ exists: true,
221
+ artifact_count: 5,
222
+ gap_status: 'active',
223
+ completeness_score: 0.6,
224
+ minto_health: 'fresh',
225
+ last_activity_at: null,
226
+ },
227
+ reasoning: {
228
+ exists: true,
229
+ governing_thought: 'expand to APAC',
230
+ arguments_count: 3,
231
+ evidence_density: 0.5,
232
+ mece_status: 'pass',
233
+ reasoning_health_score: 0.7,
234
+ flagged_weaknesses: [],
235
+ decision_log: [],
236
+ last_generated_at: null,
237
+ last_artifact_write_seen_at: null,
238
+ is_stale: false,
239
+ stale_reason: null,
240
+ },
241
+ brain: {
242
+ exists: true,
243
+ section: 'opportunity-bank',
244
+ brain_generated_at: '2026-04-26T12:00:00Z',
245
+ brain_graph_version: 1,
246
+ governing_thought_hash: 'abc123',
247
+ staleness: 'fresh',
248
+ stale_reason: null,
249
+ author: 'derive',
250
+ confidence_baseline: 0.8,
251
+ parse_failed: false,
252
+ sections: {
253
+ pattern_matches: { body: 'adjacent-domain-X structural pattern hit', tokens_estimate: 9 },
254
+ cross_domain_analogies: null,
255
+ wicked_indicators: null,
256
+ unfilled_opportunity_matches: null,
257
+ framework_chain_predictions: null,
258
+ assessment_thinking_chain_position: null,
259
+ problemtype_classification: null,
260
+ flagged_contradictions_xroom: null,
261
+ hsi_signals: null,
262
+ },
263
+ flagged_weaknesses: [],
264
+ },
265
+ },
266
+ };
267
+ const out = explain(query_results, opts);
268
+ positiveOutputs.push(out);
269
+
270
+ assert.equal(typeof out, 'string', 'explain must return a string');
271
+ assert.ok(out.length > 0, 'rendered string must be non-empty');
272
+ // Mode A enrichment marker surfaces somewhere.
273
+ const hasBrainMarker = /Brain says|Brain:|brain enrichment|Brain context/i.test(out);
274
+ const hasPatternMatch = out.indexOf('adjacent-domain-X') !== -1
275
+ || out.indexOf('structural pattern') !== -1;
276
+ assert.ok(hasBrainMarker || hasPatternMatch,
277
+ 'Mode A render must surface brain pattern_matches signal (either explicit Brain marker OR pattern_matches body text)');
278
+ });
279
+
280
+ // ---------- T6: Mode B fallback (BRAIN.md absent) ----------
281
+
282
+ record('T6 Mode B: brain:null does NOT surface Brain enrichment marker', function () {
283
+ const query_results = {
284
+ kind: 'rs_discovery',
285
+ rows: [
286
+ {
287
+ id: 'rs-1',
288
+ thesis: 'Local-only Mode B test thesis',
289
+ breakthrough_score: 6,
290
+ },
291
+ ],
292
+ };
293
+ const opts = {
294
+ room_dir: '/tmp/test-room-without-brain',
295
+ _test_quadruple_override: {
296
+ room: {
297
+ exists: true,
298
+ identity_text: 'mode-b-room',
299
+ references: [],
300
+ last_updated_at: null,
301
+ },
302
+ state: {
303
+ exists: true,
304
+ artifact_count: 2,
305
+ gap_status: 'seeded',
306
+ completeness_score: 0.3,
307
+ minto_health: '--',
308
+ last_activity_at: null,
309
+ },
310
+ reasoning: {
311
+ exists: false,
312
+ governing_thought: null,
313
+ arguments_count: 0,
314
+ evidence_density: 0,
315
+ mece_status: 'fail',
316
+ reasoning_health_score: 0,
317
+ flagged_weaknesses: [],
318
+ decision_log: [],
319
+ last_generated_at: null,
320
+ last_artifact_write_seen_at: null,
321
+ is_stale: true,
322
+ stale_reason: 'never_generated',
323
+ },
324
+ brain: null,
325
+ },
326
+ };
327
+ const out = explain(query_results, opts);
328
+ positiveOutputs.push(out);
329
+
330
+ assert.equal(typeof out, 'string', 'explain must return a string');
331
+ assert.ok(out.length > 0, 'rendered string must be non-empty');
332
+ // Crucial Mode B invariant: NO Brain enrichment marker.
333
+ assert.ok(!/Brain says/i.test(out),
334
+ 'Mode B render must NOT contain "Brain says" enrichment marker');
335
+ });
336
+
337
+ // ---------- T7: no-LLM invariant proof ----------
338
+
339
+ record('T7 no-LLM: fetch shim never called; brain-client require not allowed', function () {
340
+ // Install fetch shim that throws if called.
341
+ const originalFetch = global.fetch;
342
+ let fetchCalled = false;
343
+ global.fetch = function () {
344
+ fetchCalled = true;
345
+ throw new Error('fetch must NEVER be called from rs-query-to-text');
346
+ };
347
+ try {
348
+ // Also probe Module._cache: brain-client.cjs MUST NOT be in the require
349
+ // graph of rs-query-to-text.cjs.
350
+ const Module = require('node:module');
351
+ const cacheKeys = Object.keys(Module._cache || {});
352
+ const brainClientLoaded = cacheKeys.some(function (k) {
353
+ return /\/brain-client\.cjs$/.test(k);
354
+ });
355
+ // It's allowed for OTHER suites or test-time imports to have loaded
356
+ // brain-client; the proof we want is that THIS module did not require
357
+ // it. So we check the source of rs-query-to-text.cjs directly.
358
+ const srcPath = path.resolve(__dirname, '../core/rs-query-to-text.cjs');
359
+ const src = fs.readFileSync(srcPath, 'utf8');
360
+ const brainClientHits = (src.match(/require\(['"][^'"]*brain-client[^'"]*['"]\)/g) || []).length;
361
+ assert.equal(brainClientHits, 0,
362
+ 'rs-query-to-text.cjs must NOT require brain-client.cjs; got ' + brainClientHits + ' hits');
363
+
364
+ // Run explain through full positive path.
365
+ const query_results = {
366
+ kind: 'rs_discovery',
367
+ rows: [{ id: 'rs-1', thesis: 'no-LLM proof', breakthrough_score: 4 }],
368
+ };
369
+ const out = explain(query_results, {});
370
+ assert.equal(typeof out, 'string', 'explain must return string even with fetch shim active');
371
+ assert.equal(fetchCalled, false,
372
+ 'fetch must NOT be called during explain()');
373
+ // Suppress unused-var lint by referencing brainClientLoaded.
374
+ void brainClientLoaded;
375
+ } finally {
376
+ global.fetch = originalFetch;
377
+ }
378
+ });
379
+
380
+ // ---------- T8: Canon Part 8 input adversarial ----------
381
+
382
+ record('T8 adversarial: forbidden pattern in input throws OR is redacted', function () {
383
+ // Email-like forbidden pattern in row text.
384
+ const query_results = {
385
+ kind: 'rs_discovery',
386
+ rows: [
387
+ {
388
+ id: 'rs-evil',
389
+ thesis: 'Reach out to lawrence@example.com about the discovery',
390
+ breakthrough_score: 9,
391
+ },
392
+ ],
393
+ };
394
+ let threw = null;
395
+ let out = null;
396
+ try {
397
+ out = explain(query_results, {});
398
+ } catch (e) {
399
+ threw = e;
400
+ }
401
+ if (threw !== null) {
402
+ assert.equal(threw.name, 'ExternalEgressViolation',
403
+ 'thrown error must be ExternalEgressViolation');
404
+ assert.ok(threw.meta && typeof threw.meta === 'object',
405
+ 'ExternalEgressViolation must carry meta');
406
+ } else {
407
+ // Acceptable alternative: rendered output strips the email.
408
+ assert.equal(typeof out, 'string', 'if not thrown, must return string');
409
+ assert.ok(out.indexOf('lawrence@example.com') === -1,
410
+ 'rendered output must NOT contain raw forbidden email pattern');
411
+ }
412
+ });
413
+
414
+ // ---------- T9: meeting-transcript fragment leak ----------
415
+
416
+ record('T9 adversarial: "meeting with" fragment redacted OR throws', function () {
417
+ const query_results = {
418
+ kind: 'rs_discovery',
419
+ rows: [
420
+ {
421
+ id: 'rs-evil-2',
422
+ thesis: 'Insight surfaced during meeting with the team last week',
423
+ breakthrough_score: 7,
424
+ },
425
+ ],
426
+ };
427
+ let threw = null;
428
+ let out = null;
429
+ try {
430
+ out = explain(query_results, {});
431
+ } catch (e) {
432
+ threw = e;
433
+ }
434
+ if (threw !== null) {
435
+ assert.equal(threw.name, 'ExternalEgressViolation',
436
+ 'thrown error must be ExternalEgressViolation');
437
+ } else {
438
+ assert.equal(typeof out, 'string', 'if not thrown, must return string');
439
+ assert.ok(!/meeting with/i.test(out),
440
+ 'rendered output must NOT contain "meeting with" forbidden fragment');
441
+ }
442
+ });
443
+
444
+ // ---------- T10: voice pattern adherence ----------
445
+
446
+ record('T10 voice pattern: rs_discovery output follows Evidence -> Insight -> Warning', function () {
447
+ const query_results = {
448
+ kind: 'rs_discovery',
449
+ rows: [
450
+ {
451
+ id: 'rs-pedagogy',
452
+ thesis: 'Cross-domain transfer thesis for pedagogy test',
453
+ breakthrough_score: 8,
454
+ classification: 'structural_transfer',
455
+ },
456
+ {
457
+ id: 'rs-pedagogy-2',
458
+ thesis: 'Secondary discovery',
459
+ breakthrough_score: 5,
460
+ },
461
+ {
462
+ id: 'rs-pedagogy-3',
463
+ thesis: 'Tertiary discovery',
464
+ breakthrough_score: 4,
465
+ },
466
+ ],
467
+ };
468
+ const out = explain(query_results, {});
469
+ positiveOutputs.push(out);
470
+
471
+ assert.equal(typeof out, 'string', 'explain must return a string');
472
+ // Evidence: leading numeric statement (Found / surfaced / candidates / pairs / discoveries).
473
+ const hasEvidence = /(Found\s+\d+|^\d+\s+discoveries|surfaced|candidates|pairs|discoveries)/i.test(out);
474
+ assert.ok(hasEvidence,
475
+ 'voice template must lead with quantitative Evidence statement');
476
+ // Insight: synthesis (top thesis or "strongest" or "Top:" or "Pattern" surfaces).
477
+ const hasInsight = /(strongest|Top:|Pattern|merits|stands\s+out)/i.test(out)
478
+ || out.indexOf('Cross-domain transfer thesis') !== -1;
479
+ assert.ok(hasInsight,
480
+ 'voice template must contain Insight synthesis (strongest/Top/Pattern OR top thesis text)');
481
+ // Warning / forward-looking: Canon Part 3 verb OR /mos: command OR
482
+ // "next" / "worth" prompt.
483
+ const hasWarning =
484
+ /(Bank Opportunity|Run Methodology|Devils Advocate|Synthesize|Reformulate|Defer|Reflect)/i.test(out)
485
+ || /\/mos:/.test(out)
486
+ || /(worth|next|merits|file|filed)/i.test(out);
487
+ assert.ok(hasWarning,
488
+ 'voice template must end with forward-looking Warning / next-step prompt');
489
+ });
490
+
491
+ // ---------- T11: A1 sweep across positive outputs ----------
492
+
493
+ record('T11 A1 sweep: zero FORBIDDEN_PATTERNS in positive outputs', function () {
494
+ assert.ok(positiveOutputs.length >= 5,
495
+ 'must have collected >= 5 positive outputs for A1 sweep; got '
496
+ + positiveOutputs.length);
497
+ for (let i = 0; i < positiveOutputs.length; i++) {
498
+ const out = positiveOutputs[i];
499
+ assert.equal(typeof out, 'string',
500
+ 'positive output ' + i + ' must be a string');
501
+ for (const re of FORBIDDEN_PATTERNS) {
502
+ assert.equal(re.test(out), false,
503
+ 'A1 sweep failed: positive output ' + i + ' matched FORBIDDEN_PATTERN '
504
+ + re.source + '; sample: ' + out.slice(0, 120));
505
+ }
506
+ }
507
+ });
508
+
509
+ // ---------- Extra structural assertions on the module surface ----------
510
+
511
+ record('T_extra VOICE_TEMPLATES surface conformance (frozen + 5 kinds + >=3 each)', function () {
512
+ assert.ok(VOICE_TEMPLATES && typeof VOICE_TEMPLATES === 'object',
513
+ 'VOICE_TEMPLATES must be an object');
514
+ assert.ok(Object.isFrozen(VOICE_TEMPLATES),
515
+ 'VOICE_TEMPLATES must be Object.freeze\'d');
516
+ const expectedKinds = ['rs_discovery', 'expert_network', 'methodology_chain', 'discovery_history', 'fallback'];
517
+ for (const kind of expectedKinds) {
518
+ assert.ok(Array.isArray(VOICE_TEMPLATES[kind]),
519
+ 'VOICE_TEMPLATES.' + kind + ' must be an array');
520
+ assert.ok(Object.isFrozen(VOICE_TEMPLATES[kind]),
521
+ 'VOICE_TEMPLATES.' + kind + ' array must be frozen');
522
+ assert.ok(VOICE_TEMPLATES[kind].length >= 3,
523
+ 'VOICE_TEMPLATES.' + kind + ' must have >= 3 templates; got '
524
+ + VOICE_TEMPLATES[kind].length);
525
+ }
526
+ // _test export shape.
527
+ assert.ok(_test && typeof _test === 'object', '_test must be an object');
528
+ assert.equal(typeof _test.detectKind, 'function',
529
+ '_test.detectKind must be a function');
530
+ assert.equal(typeof _test.loadVentureContext, 'function',
531
+ '_test.loadVentureContext must be a function');
532
+ assert.equal(typeof _test.pickTemplate, 'function',
533
+ '_test.pickTemplate must be a function');
534
+ assert.equal(typeof _test.fillTemplate, 'function',
535
+ '_test.fillTemplate must be a function');
536
+ });
537
+
538
+ // ---------- Suite report ----------
539
+
540
+ const total = passed + failed;
541
+ process.stdout.write('\n');
542
+ if (failed === 0) {
543
+ process.stdout.write('=== 89.5-03 rs-query-to-text suite: ' + passed + '/' + total + ' passed ===\n');
544
+ process.exit(0);
545
+ } else {
546
+ process.stdout.write('=== 89.5-03 rs-query-to-text suite: ' + passed + '/' + total + ' passed (' + failed + ' failed) ===\n');
547
+ for (const f of failures) {
548
+ process.stdout.write(' FAIL ' + f.name + ': ' + f.message + '\n');
549
+ }
550
+ process.exit(1);
551
+ }