@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,425 @@
1
+ /*
2
+ * Copyright (c) 2026 Mindrian. BSL 1.1.
3
+ * Phase 89.5 Plan 02 -- NL-to-Query triangulation (HARDEST Canon Part 8 surface in v1.11.0).
4
+ *
5
+ * Translates user-supplied natural-language queries into a triangulated
6
+ * three-graph query bundle: {cypher, sql, brain_query}. Read by the
7
+ * Phase 89.5 orchestrator (Plan 89.5-04) and the /mos:rs-explain command
8
+ * (Plan 89.5-05); never executes queries itself (Canon Part 7 reuse:
9
+ * lazygraph-ops + the Brain HTTP client are the executors).
10
+ *
11
+ * Why this module is the hardest Canon Part 8 surface in v1.11.0:
12
+ *
13
+ * The Brain (brain.mindrian.ai) is a generic methodology repository
14
+ * that MUST never receive user content. Every other 89.x callsite
15
+ * builds Brain queries from STRUCTURED inputs (problem_type, framework
16
+ * id, phase id) where the audit surface is a finite enum. This module
17
+ * builds Brain queries from FREE-FORM user NL, which means the only
18
+ * thing standing between an arbitrary user phrase and a Brain RPC is
19
+ * the chokepoint pattern in this file.
20
+ *
21
+ * The chokepoint is buildBrainQueryFromNL. It is the SINGLE function
22
+ * in the codebase that constructs Brain query payloads from NL input.
23
+ * It runs auditQueryString on the raw NL (SEAM 1) and auditQueryObject
24
+ * on the constructed payload (SEAM 2). Recognized intents map to
25
+ * allow-listed Brain templates that carry only generic scalars
26
+ * (framework name, methodology id, source id). Unrecognized intents
27
+ * OR intents that would require user-content -> brain_query is null
28
+ * (Brain query OMITTED; room.db + Aura still work).
29
+ *
30
+ * The translate() entry point also runs auditQueryObject on the
31
+ * {nl_query, opts} input (SEAM A) and on the constructed bundle before
32
+ * return (SEAM C). Three audit seams + one chokepoint = four
33
+ * independent tripwires defending the Brain boundary against arbitrary
34
+ * user NL.
35
+ *
36
+ * Reuses (Canon Part 7):
37
+ * rs-egress-violations.cjs::ExternalEgressViolation (89.2-01)
38
+ * rs-egress-prompts.cjs::auditQueryString (89.2-01)
39
+ * rs-egress-prompts.cjs::auditQueryObject (89.2-01)
40
+ * rs-egress-prompts.cjs::FORBIDDEN_PATTERNS (89.2-01)
41
+ *
42
+ * NEVER imports (this module CONSTRUCTS, the orchestrator EXECUTES):
43
+ * the Brain HTTP client module (orchestrator only)
44
+ * lazygraph-ops.cjs::queryGraph (orchestrator only)
45
+ *
46
+ * NEVER invokes any network primitive. Pure CJS, zero npm deps,
47
+ * no Node built-ins beyond core require.
48
+ */
49
+ 'use strict';
50
+
51
+ const { ExternalEgressViolation } = require('./rs-egress-violations.cjs');
52
+ const {
53
+ auditQueryString,
54
+ auditQueryObject,
55
+ FORBIDDEN_PATTERNS,
56
+ } = require('./rs-egress-prompts.cjs');
57
+
58
+ // ---------- Constants ----------
59
+
60
+ // Maximum bound-parameter scalar length. Bounded so a runaway NL fragment
61
+ // cannot smuggle a multi-kilobyte payload through the entity extractor.
62
+ const PARAM_MAX_LENGTH = 100;
63
+
64
+ // ---------- Entity extractors (pure functions over NL strings) ----------
65
+ //
66
+ // Each extractor pulls a structured scalar from the NL string and runs the
67
+ // scalar through auditQueryString before returning. ExternalEgressViolation
68
+ // bubbles to the caller if the extracted scalar matches any FORBIDDEN_PATTERN.
69
+ // Length cap applied after extraction, before audit.
70
+
71
+ function _truncateAndAudit(scalar, surfaceTag) {
72
+ if (typeof scalar !== 'string') return null;
73
+ let s = scalar.trim();
74
+ if (s.length === 0) return null;
75
+ if (s.length > PARAM_MAX_LENGTH) s = s.slice(0, PARAM_MAX_LENGTH);
76
+ // Strip surrounding quotes (single or double).
77
+ s = s.replace(/^["']|["']$/g, '').trim();
78
+ if (s.length === 0) return null;
79
+ // Audit BEFORE return. Any forbidden pattern raises immediately.
80
+ auditQueryString(s, surfaceTag);
81
+ return s;
82
+ }
83
+
84
+ // extractRoomSlugParam: pulls "in my <slug> room" or "for my <slug> venture"
85
+ // or fallback to known section keywords.
86
+ function extractRoomSlugParam(nl_query) {
87
+ const surface = 'rs-nl-to-query-extract-room-slug';
88
+ // "in my fintech room" / "for my biotech venture" / "in my X room"
89
+ const m1 = /(?:in|for)\s+my\s+([a-z0-9 _-]{1,50}?)\s+(?:room|venture|project)/i.exec(nl_query);
90
+ if (m1 && m1[1]) {
91
+ const slug = _truncateAndAudit(m1[1].trim().toLowerCase().replace(/\s+/g, '-'), surface);
92
+ if (slug) return { room_slug: slug };
93
+ }
94
+ // Fallback: look for "<word> room" anywhere.
95
+ const m2 = /\b([a-z][a-z0-9_-]{2,30})\s+room\b/i.exec(nl_query);
96
+ if (m2 && m2[1]) {
97
+ const slug = _truncateAndAudit(m2[1].trim().toLowerCase(), surface);
98
+ if (slug) return { room_slug: slug };
99
+ }
100
+ // Last resort: empty bound param so the parameterized binding still works.
101
+ return { room_slug: '' };
102
+ }
103
+
104
+ // extractTopicParam: pulls "experts on <topic>" or "leading researchers in <topic>".
105
+ function extractTopicParam(nl_query) {
106
+ const surface = 'rs-nl-to-query-extract-topic';
107
+ const m1 = /experts?\s+on\s+(.+?)(?:\?|$|\.|;)/i.exec(nl_query);
108
+ if (m1 && m1[1]) {
109
+ const topic = _truncateAndAudit(m1[1].trim(), surface);
110
+ if (topic) return { topic: topic.toLowerCase() };
111
+ }
112
+ const m2 = /(?:researchers|authors|leaders)\s+(?:in|on)\s+(.+?)(?:\?|$|\.|;)/i.exec(nl_query);
113
+ if (m2 && m2[1]) {
114
+ const topic = _truncateAndAudit(m2[1].trim(), surface);
115
+ if (topic) return { topic: topic.toLowerCase() };
116
+ }
117
+ return { topic: '' };
118
+ }
119
+
120
+ // extractFrameworkParam: maps NL framework references to canonical scalars.
121
+ // Allow-list approach: only recognized framework names produce a bound scalar.
122
+ const FRAMEWORK_ALIASES = Object.freeze({
123
+ 'rs discovery': 'reverse_salient_engine',
124
+ 'reverse salient': 'reverse_salient_engine',
125
+ 'reverse salients': 'reverse_salient_engine',
126
+ 'reverse-salient': 'reverse_salient_engine',
127
+ 'jtbd': 'jtbd',
128
+ 'jobs-to-be-done': 'jtbd',
129
+ 'jobs to be done': 'jtbd',
130
+ 'persona': 'persona',
131
+ 'navigation engine': 'navigation_engine',
132
+ 'pws vp': 'pws_vp',
133
+ 'mind map': 'mind_map',
134
+ });
135
+
136
+ function extractFrameworkParam(nl_query) {
137
+ // Walk aliases longest-first so multi-word matches win.
138
+ const lc = nl_query.toLowerCase();
139
+ const sortedAliases = Object.keys(FRAMEWORK_ALIASES).sort(function (a, b) {
140
+ return b.length - a.length;
141
+ });
142
+ for (const alias of sortedAliases) {
143
+ if (lc.indexOf(alias) !== -1) {
144
+ // Already an enum scalar; no audit needed (allow-list source).
145
+ return { target_framework: FRAMEWORK_ALIASES[alias] };
146
+ }
147
+ }
148
+ return { target_framework: '' };
149
+ }
150
+
151
+ // extractMethodologyParam: maps NL methodology refs to source_id scalar.
152
+ function extractMethodologyParam(nl_query) {
153
+ const lc = nl_query.toLowerCase();
154
+ const sortedAliases = Object.keys(FRAMEWORK_ALIASES).sort(function (a, b) {
155
+ return b.length - a.length;
156
+ });
157
+ for (const alias of sortedAliases) {
158
+ if (lc.indexOf(alias) !== -1) {
159
+ return { source_id: FRAMEWORK_ALIASES[alias] };
160
+ }
161
+ }
162
+ return { source_id: '' };
163
+ }
164
+
165
+ // ---------- Frozen ALLOW_LIST_INTENTS ----------
166
+ //
167
+ // Five intent records covering the v1.11.0-beta.1 NL-to-Query surface.
168
+ // Each record is independently Object.freeze'd so the table cannot mutate
169
+ // at runtime even if a caller obtains a reference. params_extractor is the
170
+ // pure-function entity puller that audits the scalar before binding.
171
+ //
172
+ // Brain templates use parameterized Cypher placeholders ($source_id,
173
+ // $target_framework). Local SQL uses $1/$2 PostgreSQL-style placeholders.
174
+ // Local Cypher uses $room_slug / $topic placeholders. Templates NEVER
175
+ // inline user NL.
176
+
177
+ const ALLOW_LIST_INTENTS = Object.freeze([
178
+ Object.freeze({
179
+ intent_id: 'feeds_into_query',
180
+ keyword_patterns: [
181
+ /what\s+(frameworks?|methodologies?)\s+(chain|feed)\s+(into|to)/i,
182
+ /downstream\s+of/i,
183
+ /what\s+chains?\s+into/i,
184
+ ],
185
+ brain_template:
186
+ 'MATCH (m:Methodology {id: $target_framework})-[:FEEDS_INTO*0..1]-(t:Methodology) '
187
+ + 'RETURN t.name AS name, t.id AS id LIMIT 10',
188
+ sql_template: null,
189
+ cypher_template: null,
190
+ params_extractor: extractFrameworkParam,
191
+ }),
192
+ Object.freeze({
193
+ intent_id: 'reverse_salients_in_room',
194
+ keyword_patterns: [
195
+ /(show|find|list)\s+(me\s+)?reverse\s+salients?/i,
196
+ ],
197
+ brain_template: null,
198
+ sql_template:
199
+ 'SELECT * FROM rs_discoveries WHERE room_slug = ? ORDER BY created_at DESC',
200
+ cypher_template:
201
+ 'MATCH (rs:RSDiscovery {room_slug: $room_slug}) RETURN rs ORDER BY rs.created_at DESC',
202
+ params_extractor: extractRoomSlugParam,
203
+ }),
204
+ Object.freeze({
205
+ intent_id: 'experts_on_topic',
206
+ keyword_patterns: [
207
+ /(?:who\s+(?:are\s+)?|find\s+)experts?\s+on/i,
208
+ /(?:who.*authored|leading\s+researchers)\s+(?:in|on)/i,
209
+ ],
210
+ brain_template: null,
211
+ sql_template: null,
212
+ cypher_template:
213
+ 'MATCH (a:Author)-[:AUTHORED_BY]->(p:Paper) '
214
+ + 'WHERE p.topic = $topic RETURN a.name AS name, a.affiliation AS affiliation LIMIT 20',
215
+ params_extractor: extractTopicParam,
216
+ }),
217
+ Object.freeze({
218
+ intent_id: 'methodology_chain',
219
+ keyword_patterns: [
220
+ /methodology\s+chains?\s+from/i,
221
+ /what\s+comes\s+after/i,
222
+ /chains?\s+from\s+(?:jtbd|persona|swot|porter)/i,
223
+ ],
224
+ brain_template:
225
+ 'MATCH (m:Methodology {id: $source_id})-[:FEEDS_INTO*1..3]->(t:Methodology) '
226
+ + 'RETURN t.name AS name, t.id AS id LIMIT 10',
227
+ sql_template: null,
228
+ cypher_template: null,
229
+ params_extractor: extractMethodologyParam,
230
+ }),
231
+ Object.freeze({
232
+ intent_id: 'discovery_history',
233
+ keyword_patterns: [
234
+ /(?:what\s+)?(?:rs\s+|reverse\s+salient\s+)?discoveries\s+(?:have\s+i|did\s+i)\s+(?:made|created|found)/i,
235
+ /my\s+discoveries/i,
236
+ /discoveries.*(?:have\s+i|in\s+my\s+\w+\s+room)/i,
237
+ ],
238
+ brain_template: null,
239
+ sql_template:
240
+ 'SELECT * FROM rs_discoveries WHERE room_slug = ? ORDER BY created_at DESC',
241
+ cypher_template:
242
+ 'MATCH (rs:RSDiscovery {room_slug: $room_slug}) RETURN rs ORDER BY rs.created_at DESC',
243
+ params_extractor: extractRoomSlugParam,
244
+ }),
245
+ ]);
246
+
247
+ // ---------- Internal helpers ----------
248
+
249
+ // classifyIntent: deterministic keyword match over ALLOW_LIST_INTENTS.
250
+ // First-match-wins across the entries; within an entry, ANY keyword match
251
+ // triggers the intent. Returns the entry OR null if no match.
252
+ function classifyIntent(nl_query) {
253
+ if (typeof nl_query !== 'string' || nl_query.length === 0) return null;
254
+ for (const entry of ALLOW_LIST_INTENTS) {
255
+ for (const re of entry.keyword_patterns) {
256
+ if (re.test(nl_query)) return entry;
257
+ }
258
+ }
259
+ return null;
260
+ }
261
+
262
+ // ---------- THE CHOKEPOINT: buildBrainQueryFromNL ----------
263
+ //
264
+ // THE SINGLE function in the codebase that constructs Brain query payloads
265
+ // from NL input. Two-seam defense:
266
+ // SEAM 1: auditQueryString on the raw NL (catches direct forbidden bytes)
267
+ // SEAM 2: auditQueryObject on the constructed payload (catches indirect
268
+ // leakage through entity extraction or template substitution)
269
+ //
270
+ // If intent === null OR intent.brain_template === null OR the entity
271
+ // extractor returns an empty scalar -> return null (Brain query OMITTED).
272
+ //
273
+ // Never throws on the "Brain query OMITTED" path; only throws when the
274
+ // audit explicitly identifies a FORBIDDEN_PATTERN in the input or output.
275
+
276
+ function buildBrainQueryFromNL(nl_query, intent) {
277
+ // SEAM 1: raw NL audit (the input chokepoint for Brain construction).
278
+ // ExternalEgressViolation bubbles to the caller (translate()).
279
+ auditQueryString(nl_query, 'rs-nl-to-query-brain-input');
280
+
281
+ // No intent OR intent has no Brain template -> Brain query OMITTED.
282
+ if (intent === null || intent.brain_template === null) return null;
283
+
284
+ // Extract entity params (extractor audits the scalar already).
285
+ const params = intent.params_extractor(nl_query);
286
+
287
+ // If extractor returned an empty scalar across all bound keys, we can't
288
+ // form a meaningful Brain query without inlining user NL. OMIT.
289
+ let hasNonEmpty = false;
290
+ for (const k of Object.keys(params)) {
291
+ if (typeof params[k] === 'string' && params[k].length > 0) {
292
+ hasNonEmpty = true;
293
+ break;
294
+ }
295
+ }
296
+ if (!hasNonEmpty) return null;
297
+
298
+ // Build the structured payload. NEVER inline user NL.
299
+ const brainQuery = {
300
+ cypher: intent.brain_template,
301
+ params: params,
302
+ intent_id: intent.intent_id,
303
+ };
304
+
305
+ // SEAM 2: constructed-payload audit. JSON.stringify scan catches any
306
+ // residual user-content that snuck through the extractor (e.g., if a
307
+ // future extractor regression bound a multi-word phrase containing a
308
+ // forbidden pattern).
309
+ auditQueryObject(brainQuery, 'rs-nl-to-query-brain-output');
310
+
311
+ return brainQuery;
312
+ }
313
+
314
+ // ---------- Local query builder (room.db SQL + Aura Cypher) ----------
315
+ //
316
+ // Builds parameterized SQL/Cypher. NEVER concatenates user NL into the
317
+ // template string. ALL bound scalars come from the intent's
318
+ // params_extractor (which already ran auditQueryString on the scalar).
319
+
320
+ function buildLocalQueries(nl_query, intent) {
321
+ if (intent === null) {
322
+ return { sql: null, sql_params: null, cypher: null, cypher_params: null };
323
+ }
324
+ const params = intent.params_extractor(nl_query);
325
+
326
+ // SQL: use $1 placeholder, bind room_slug as the first positional param.
327
+ let sql = null;
328
+ let sql_params = null;
329
+ if (typeof intent.sql_template === 'string') {
330
+ sql = intent.sql_template;
331
+ // Bind the FIRST scalar key as $1. Parameterized binding only.
332
+ const keys = Object.keys(params);
333
+ if (keys.length > 0) {
334
+ sql_params = [params[keys[0]]];
335
+ } else {
336
+ sql_params = [];
337
+ }
338
+ }
339
+
340
+ // Cypher: use named placeholders ($room_slug / $topic). Pass the params
341
+ // map directly; never concatenated.
342
+ let cypher = null;
343
+ let cypher_params = null;
344
+ if (typeof intent.cypher_template === 'string') {
345
+ cypher = intent.cypher_template;
346
+ cypher_params = params;
347
+ }
348
+
349
+ return { sql: sql, sql_params: sql_params, cypher: cypher, cypher_params: cypher_params };
350
+ }
351
+
352
+ // ---------- Public entry: translate ----------
353
+ //
354
+ // Top-level NL-to-Query translator. Three audit seams + one chokepoint:
355
+ //
356
+ // SEAM A: auditQueryObject({nl_query, opts}) before ANY work
357
+ // -> catches forbidden patterns nested in opts (e.g., a leaked
358
+ // meeting_transcript field)
359
+ // SEAM 1: inside buildBrainQueryFromNL -- raw NL audit
360
+ // SEAM 2: inside buildBrainQueryFromNL -- constructed-payload audit
361
+ // SEAM C: auditQueryObject on the returned bundle -- last line of defense
362
+ //
363
+ // Returns: {cypher, sql, brain_query, sql_params, cypher_params}
364
+ // - brain_query is null when intent unrecognized OR Brain template absent
365
+ // - sql / cypher are null when the intent is the other backend's exclusive
366
+ // - sql_params / cypher_params follow their respective query string
367
+
368
+ function translate(nl_query, opts) {
369
+ opts = opts || {};
370
+
371
+ // SEAM A: input audit. JSON.stringify scan catches forbidden patterns in
372
+ // either the NL itself OR any field of opts. Throws ExternalEgressViolation
373
+ // BEFORE buildBrainQueryFromNL runs, so adversarial opts.meeting_transcript
374
+ // never reaches the chokepoint.
375
+ auditQueryObject({ nl_query: nl_query, opts: opts }, 'rs-nl-to-query-input');
376
+
377
+ // Defensive: also require nl_query to be a string. Null/non-string is a
378
+ // caller bug, not a Canon violation.
379
+ if (typeof nl_query !== 'string') {
380
+ throw new TypeError('translate: nl_query must be a string; got ' + typeof nl_query);
381
+ }
382
+
383
+ // Classify and build.
384
+ const intent = classifyIntent(nl_query);
385
+ const brainQuery = buildBrainQueryFromNL(nl_query, intent);
386
+ const local = buildLocalQueries(nl_query, intent);
387
+
388
+ const bundle = {
389
+ cypher: local.cypher,
390
+ sql: local.sql,
391
+ brain_query: brainQuery,
392
+ sql_params: local.sql_params,
393
+ cypher_params: local.cypher_params,
394
+ };
395
+
396
+ // SEAM C: post-build audit on the returned bundle. Catches any leakage
397
+ // that snuck past SEAM A + the chokepoint (e.g., a bound scalar that
398
+ // matched a FORBIDDEN_PATTERN only after extractor normalization).
399
+ auditQueryObject(bundle, 'rs-nl-to-query-output');
400
+
401
+ return bundle;
402
+ }
403
+
404
+ // ---------- Exports ----------
405
+
406
+ module.exports = {
407
+ translate,
408
+ ALLOW_LIST_INTENTS,
409
+ // Re-export so callers can catch by err.name without re-requiring the
410
+ // upstream egress-violations module.
411
+ ExternalEgressViolation,
412
+ // Test surface (Canon Part 7: never used by production callers; only the
413
+ // RED/GREEN suite imports these for chokepoint introspection).
414
+ _test: {
415
+ classifyIntent: classifyIntent,
416
+ buildBrainQueryFromNL: buildBrainQueryFromNL,
417
+ buildLocalQueries: buildLocalQueries,
418
+ extractRoomSlugParam: extractRoomSlugParam,
419
+ extractTopicParam: extractTopicParam,
420
+ extractFrameworkParam: extractFrameworkParam,
421
+ extractMethodologyParam: extractMethodologyParam,
422
+ FRAMEWORK_ALIASES: FRAMEWORK_ALIASES,
423
+ PARAM_MAX_LENGTH: PARAM_MAX_LENGTH,
424
+ },
425
+ };