@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,449 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /*
5
+ * Copyright (c) 2026 Mindrian. BSL 1.1.
6
+ * Phase 89.5 Plan 02 -- rs-nl-to-query NL-to-Query triangulation suite.
7
+ *
8
+ * 16 scenarios covering THE HARDEST Canon Part 8 surface in v1.11.0:
9
+ *
10
+ * Positive-path (intent recognition + frozen ALLOW_LIST_INTENTS):
11
+ * T1 feeds_into_query intent -> brain_query payload with allow-list scalar
12
+ * T2 reverse_salients_in_room intent -> SQL-only (brain_query null)
13
+ * T3 experts_on_topic intent -> Cypher-only (brain_query null)
14
+ * T4 methodology_chain intent -> brain_query only (sql + cypher null)
15
+ * T5 discovery_history intent -> SQL + Cypher mirror (brain_query null)
16
+ * T6 ALLOW_LIST_INTENTS frozen + length >= 5 + entry shape conformance
17
+ * T7 unrecognized intent -> brain_query null + safe fallback
18
+ *
19
+ * Adversarial Canon Part 8 (>= 6 leak-attempt scenarios):
20
+ * T8 artifact body leak attempt -> brain_query null OR audit throws
21
+ * T9 venture name leak attempt -> JSON.stringify(brain_query) excludes name
22
+ * T10 meeting transcript leak via opts -> input audit throws ExternalEgressViolation
23
+ * T11 financial figure leak attempt ($500M) -> output excludes the figure
24
+ * T12 decision_log leak attempt -> brain_query null AND output safe
25
+ * T13 governing_thought leak attempt -> brain_query null AND output safe
26
+ *
27
+ * Injection prevention:
28
+ * T14 SQL injection NL -> parameterized binding (zero string concatenation)
29
+ *
30
+ * Chokepoint exclusivity (Canon Part 7 + Part 8 invariant):
31
+ * T15 source-level grep: zero fetch(; zero brain-client require;
32
+ * >= 1 buildBrainQueryFromNL definition; >= 3 auditQueryObject sites
33
+ *
34
+ * A1 sweep (defense-in-depth across positive paths):
35
+ * T16 every positive-path output JSON.stringify scanned against
36
+ * FORBIDDEN_PATTERNS -> zero matches
37
+ *
38
+ * Pure CJS, zero npm deps, node built-ins only (assert + fs + path).
39
+ */
40
+
41
+ const assert = require('node:assert/strict');
42
+ const fs = require('node:fs');
43
+ const path = require('node:path');
44
+
45
+ // ---------- Suite bookkeeping ----------
46
+
47
+ let passed = 0;
48
+ let failed = 0;
49
+ const failures = [];
50
+
51
+ function record(name, fn) {
52
+ try {
53
+ fn();
54
+ passed++;
55
+ process.stdout.write('PASS ' + name + '\n');
56
+ } catch (err) {
57
+ failed++;
58
+ failures.push({ name, message: err && err.message ? err.message : String(err) });
59
+ process.stdout.write('FAIL ' + name + ': ' + (err && err.message ? err.message : String(err)) + '\n');
60
+ }
61
+ }
62
+
63
+ // ---------- Module under test ----------
64
+
65
+ const mod = require('../core/rs-nl-to-query.cjs');
66
+ const { translate, ALLOW_LIST_INTENTS, _test } = mod;
67
+
68
+ const egressPrompts = require('../core/rs-egress-prompts.cjs');
69
+ const { FORBIDDEN_PATTERNS } = egressPrompts;
70
+
71
+ // Collect positive-test outputs for the A1 sweep (T16).
72
+ const positiveOutputs = [];
73
+
74
+ // ---------- T1: feeds_into_query intent ----------
75
+
76
+ record('T1 feeds_into_query intent emits brain_query with allow-list scalar', function () {
77
+ const nl = 'What frameworks chain into RS Discovery?';
78
+ const out = translate(nl, {});
79
+ positiveOutputs.push(out);
80
+
81
+ assert.ok(out && typeof out === 'object', 'translate must return object');
82
+ assert.ok('cypher' in out, 'output must have cypher key');
83
+ assert.ok('sql' in out, 'output must have sql key');
84
+ assert.ok('brain_query' in out, 'output must have brain_query key');
85
+
86
+ assert.ok(out.brain_query !== null && typeof out.brain_query === 'object',
87
+ 'feeds_into_query intent must produce non-null brain_query');
88
+ assert.ok(typeof out.brain_query.cypher === 'string',
89
+ 'brain_query.cypher must be a string template');
90
+ assert.ok(out.brain_query.params && typeof out.brain_query.params === 'object',
91
+ 'brain_query.params must be an object');
92
+
93
+ // No raw user NL substring inside the brain_query payload.
94
+ const payloadJson = JSON.stringify(out.brain_query);
95
+ assert.ok(payloadJson.indexOf('RS Discovery') === -1,
96
+ 'brain_query payload must not contain raw user NL substring "RS Discovery"');
97
+ });
98
+
99
+ // ---------- T2: reverse_salients_in_room (LOCAL only) ----------
100
+
101
+ record('T2 reverse_salients_in_room intent: SQL parameterized + brain_query null', function () {
102
+ const nl = 'Show me reverse salients in my fintech room';
103
+ const out = translate(nl, {});
104
+ positiveOutputs.push(out);
105
+
106
+ assert.equal(out.brain_query, null,
107
+ 'reverse_salients_in_room is LOCAL-only; brain_query must be null');
108
+ assert.ok(typeof out.sql === 'string', 'sql must be a string template');
109
+ assert.ok(out.sql.indexOf('$1') !== -1 || out.sql.indexOf('?') !== -1,
110
+ 'sql must use parameterized placeholder ($1 or ?)');
111
+ assert.ok(Array.isArray(out.sql_params),
112
+ 'sql_params must be an array');
113
+ assert.ok(out.sql_params.length >= 1, 'sql_params must contain bound entity');
114
+ // Bound entity should reference fintech room slug.
115
+ const paramJoined = out.sql_params.join('|').toLowerCase();
116
+ assert.ok(paramJoined.indexOf('fintech') !== -1,
117
+ 'sql_params must include bound "fintech" room slug');
118
+ // No string concatenation: SQL template must not contain user NL substring.
119
+ assert.ok(out.sql.toLowerCase().indexOf('fintech') === -1,
120
+ 'sql template must NOT contain "fintech" (parameterized binding required)');
121
+ });
122
+
123
+ // ---------- T3: experts_on_topic (Aura-only) ----------
124
+
125
+ record('T3 experts_on_topic intent: Cypher parameterized + brain_query null', function () {
126
+ const nl = 'Who are experts on quantum computing?';
127
+ const out = translate(nl, {});
128
+ positiveOutputs.push(out);
129
+
130
+ assert.equal(out.brain_query, null,
131
+ 'experts_on_topic is LOCAL Aura; brain_query must be null');
132
+ assert.ok(typeof out.cypher === 'string', 'cypher must be a string');
133
+ assert.ok(out.cypher.indexOf('$topic') !== -1,
134
+ 'cypher must reference $topic parameter placeholder');
135
+ assert.ok(out.cypher_params && typeof out.cypher_params === 'object',
136
+ 'cypher_params must be an object');
137
+ assert.ok(out.cypher_params.topic && typeof out.cypher_params.topic === 'string',
138
+ 'cypher_params.topic must be a bound string');
139
+ assert.ok(out.cypher_params.topic.toLowerCase().indexOf('quantum') !== -1,
140
+ 'cypher_params.topic must include "quantum" entity');
141
+ // No raw concatenation.
142
+ assert.ok(out.cypher.toLowerCase().indexOf('quantum computing') === -1,
143
+ 'cypher template must NOT inline "quantum computing" (parameterized only)');
144
+ });
145
+
146
+ // ---------- T4: methodology_chain (Brain-only) ----------
147
+
148
+ record('T4 methodology_chain intent: Brain template + sql/cypher null', function () {
149
+ const nl = 'What methodology chains from JTBD?';
150
+ const out = translate(nl, {});
151
+ positiveOutputs.push(out);
152
+
153
+ assert.ok(out.brain_query !== null && typeof out.brain_query === 'object',
154
+ 'methodology_chain must emit Brain template');
155
+ assert.ok(typeof out.brain_query.cypher === 'string',
156
+ 'brain_query.cypher must be a string');
157
+ assert.ok(out.brain_query.params && typeof out.brain_query.params === 'object',
158
+ 'brain_query.params must be an object');
159
+ assert.ok(typeof out.brain_query.params.source_id === 'string',
160
+ 'brain_query.params.source_id must be a bound scalar');
161
+ assert.ok(out.brain_query.params.source_id.toLowerCase().indexOf('jtbd') !== -1,
162
+ 'source_id must reference jtbd');
163
+ // No user NL substring inside the Brain payload.
164
+ const json = JSON.stringify(out.brain_query);
165
+ assert.ok(json.indexOf('What methodology') === -1,
166
+ 'brain_query must not contain raw NL prefix');
167
+ });
168
+
169
+ // ---------- T5: discovery_history (SQL + Cypher mirror) ----------
170
+
171
+ record('T5 discovery_history intent: SQL + Cypher mirror, brain_query null', function () {
172
+ const nl = 'What RS discoveries have I made in my biotech room?';
173
+ const out = translate(nl, {});
174
+ positiveOutputs.push(out);
175
+
176
+ assert.equal(out.brain_query, null,
177
+ 'discovery_history is LOCAL only; brain_query must be null');
178
+ assert.ok(typeof out.sql === 'string', 'sql must be a string');
179
+ assert.ok(Array.isArray(out.sql_params), 'sql_params must be array');
180
+ assert.ok(out.sql_params.length >= 1, 'sql_params must contain room slug');
181
+ // Verify it's the room slug ('biotech') -- not raw NL.
182
+ const paramJoined = out.sql_params.join('|').toLowerCase();
183
+ assert.ok(paramJoined.indexOf('biotech') !== -1, 'bound param must include biotech');
184
+ });
185
+
186
+ // ---------- T6: ALLOW_LIST_INTENTS shape + freeze ----------
187
+
188
+ record('T6 ALLOW_LIST_INTENTS frozen + length >= 5 + entry shape', function () {
189
+ assert.ok(Array.isArray(ALLOW_LIST_INTENTS), 'ALLOW_LIST_INTENTS must be array');
190
+ assert.equal(Object.isFrozen(ALLOW_LIST_INTENTS), true, 'ALLOW_LIST_INTENTS must be frozen');
191
+ assert.ok(ALLOW_LIST_INTENTS.length >= 5,
192
+ 'ALLOW_LIST_INTENTS.length must be >= 5; got ' + ALLOW_LIST_INTENTS.length);
193
+ for (const entry of ALLOW_LIST_INTENTS) {
194
+ assert.ok(entry && typeof entry === 'object', 'every entry must be object');
195
+ assert.equal(typeof entry.intent_id, 'string', 'entry.intent_id must be string');
196
+ assert.ok(Array.isArray(entry.keyword_patterns),
197
+ 'entry.keyword_patterns must be array');
198
+ assert.ok(entry.keyword_patterns.length >= 1,
199
+ 'entry.keyword_patterns must have >= 1 regex');
200
+ // brain_template, sql_template, cypher_template each string|null
201
+ assert.ok(entry.brain_template === null || typeof entry.brain_template === 'string',
202
+ 'entry.brain_template must be string or null');
203
+ assert.ok(entry.sql_template === null || typeof entry.sql_template === 'string',
204
+ 'entry.sql_template must be string or null');
205
+ assert.ok(entry.cypher_template === null || typeof entry.cypher_template === 'string',
206
+ 'entry.cypher_template must be string or null');
207
+ assert.equal(typeof entry.params_extractor, 'function',
208
+ 'entry.params_extractor must be function');
209
+ // Frozen entry guard.
210
+ assert.equal(Object.isFrozen(entry), true,
211
+ 'every ALLOW_LIST_INTENTS entry must be Object.freeze\'d');
212
+ }
213
+ });
214
+
215
+ // ---------- T7: unrecognized intent ----------
216
+
217
+ record('T7 unrecognized intent: brain_query null, no leak', function () {
218
+ const nl = 'Tell me a joke about quantum computing';
219
+ const out = translate(nl, {});
220
+ // Don't push to positiveOutputs because brain_query is null by design.
221
+ assert.equal(out.brain_query, null,
222
+ 'unrecognized NL must produce brain_query === null');
223
+ // SQL + Cypher should be null OR a safe generic fallback (no raw NL).
224
+ if (typeof out.sql === 'string') {
225
+ assert.ok(out.sql.indexOf('joke') === -1, 'safe fallback SQL must not echo NL');
226
+ }
227
+ if (typeof out.cypher === 'string') {
228
+ assert.ok(out.cypher.indexOf('joke') === -1, 'safe fallback Cypher must not echo NL');
229
+ }
230
+ });
231
+
232
+ // ---------- T8: artifact body leak attempt ----------
233
+
234
+ record('T8 artifact body leak attempt: brain_query null AND output audit safe', function () {
235
+ // The NL contains content that LOOKS like an artifact body excerpt.
236
+ const nl = 'What does my artifact body say about RS chains?';
237
+ let out = null;
238
+ let threw = null;
239
+ try {
240
+ out = translate(nl, {});
241
+ } catch (e) {
242
+ threw = e;
243
+ }
244
+ // Two acceptable outcomes:
245
+ // (a) Audit throws ExternalEgressViolation on output (preferred)
246
+ // (b) Output returned with brain_query null
247
+ if (threw !== null) {
248
+ assert.equal(threw.name, 'ExternalEgressViolation',
249
+ 'if throw, must be ExternalEgressViolation');
250
+ } else {
251
+ assert.equal(out.brain_query, null,
252
+ 'artifact-body NL must NOT produce brain_query (LOCAL-only fallback or null)');
253
+ }
254
+ });
255
+
256
+ // ---------- T9: venture name leak attempt ----------
257
+
258
+ record('T9 venture name leak attempt: name never reaches brain_query payload', function () {
259
+ const nl = 'Show me reverse salients for my Acme Quantum Brain Imaging venture';
260
+ const out = translate(nl, {});
261
+ // brain_query may be either null (LOCAL-only intent) OR a generic template.
262
+ if (out.brain_query !== null) {
263
+ const json = JSON.stringify(out.brain_query);
264
+ assert.ok(json.indexOf('Acme Quantum Brain Imaging') === -1,
265
+ 'brain_query payload must NOT contain venture name');
266
+ assert.ok(json.indexOf('Acme') === -1,
267
+ 'brain_query payload must NOT contain venture name fragment');
268
+ }
269
+ });
270
+
271
+ // ---------- T10: meeting transcript leak via opts ----------
272
+
273
+ record('T10 meeting transcript via opts: input audit throws ExternalEgressViolation', function () {
274
+ const nl = 'What frameworks chain from JTBD?';
275
+ // Use a phrase that hits FORBIDDEN_PATTERNS: "meeting with" pattern.
276
+ const opts = { meeting_transcript: 'meeting with private board minutes about regulatory blocker' };
277
+ let threw = null;
278
+ try {
279
+ translate(nl, opts);
280
+ } catch (e) {
281
+ threw = e;
282
+ }
283
+ assert.ok(threw !== null,
284
+ 'meeting_transcript in opts must trip input audit and throw');
285
+ assert.equal(threw.name, 'ExternalEgressViolation',
286
+ 'thrown error must be ExternalEgressViolation');
287
+ assert.ok(threw.meta && typeof threw.meta === 'object',
288
+ 'err.meta must be object');
289
+ assert.ok(typeof threw.meta.surface === 'string' && threw.meta.surface.length > 0,
290
+ 'err.meta.surface must be a non-empty string tag');
291
+ // Surface tag MUST identify the input chokepoint.
292
+ assert.ok(threw.meta.surface.indexOf('input') !== -1
293
+ || threw.meta.surface.indexOf('rs-nl-to-query') !== -1,
294
+ 'err.meta.surface must identify the rs-nl-to-query input chokepoint; got '
295
+ + JSON.stringify(threw.meta.surface));
296
+ });
297
+
298
+ // ---------- T11: financial figure leak attempt ----------
299
+
300
+ record('T11 financial figure leak attempt: $500M never in output', function () {
301
+ // The financial figure $500M matches FORBIDDEN_PATTERNS and MUST trip the audit.
302
+ const nl = 'Find experts on $500M Series A failure modes';
303
+ let out = null;
304
+ let threw = null;
305
+ try {
306
+ out = translate(nl, {});
307
+ } catch (e) {
308
+ threw = e;
309
+ }
310
+ // Two acceptable outcomes:
311
+ // (a) Audit throws ExternalEgressViolation -- preferred since $500M is a forbidden pattern
312
+ // (b) Output returned but $500M does NOT appear anywhere
313
+ if (threw !== null) {
314
+ assert.equal(threw.name, 'ExternalEgressViolation');
315
+ } else {
316
+ const fullJson = JSON.stringify(out);
317
+ assert.ok(fullJson.indexOf('$500M') === -1,
318
+ 'financial figure $500M must not appear anywhere in output');
319
+ assert.ok(fullJson.indexOf('500M') === -1,
320
+ 'financial figure 500M must not appear in output');
321
+ }
322
+ });
323
+
324
+ // ---------- T12: decision_log leak attempt ----------
325
+
326
+ record('T12 decision_log leak attempt: brain_query null + safe', function () {
327
+ const nl = 'Why did I reject opportunity X in my decision log?';
328
+ let out = null;
329
+ let threw = null;
330
+ try {
331
+ out = translate(nl, {});
332
+ } catch (e) {
333
+ threw = e;
334
+ }
335
+ if (threw !== null) {
336
+ assert.equal(threw.name, 'ExternalEgressViolation');
337
+ } else {
338
+ assert.equal(out.brain_query, null,
339
+ 'decision_log NL must yield brain_query === null');
340
+ }
341
+ });
342
+
343
+ // ---------- T13: governing_thought leak attempt ----------
344
+
345
+ record('T13 governing_thought leak attempt: brain_query null + safe', function () {
346
+ const nl = "What's my governing thought on Mindrian moat?";
347
+ let out = null;
348
+ let threw = null;
349
+ try {
350
+ out = translate(nl, {});
351
+ } catch (e) {
352
+ threw = e;
353
+ }
354
+ if (threw !== null) {
355
+ assert.equal(threw.name, 'ExternalEgressViolation');
356
+ } else {
357
+ assert.equal(out.brain_query, null,
358
+ 'governing_thought NL must yield brain_query === null');
359
+ }
360
+ });
361
+
362
+ // ---------- T14: SQL/Cypher injection prevention ----------
363
+
364
+ record('T14 SQL injection NL: parameterized binding (no concatenation)', function () {
365
+ const nl = "Show me reverse salients in '; DROP TABLE rs_discoveries;--";
366
+ const out = translate(nl, {});
367
+ assert.equal(out.brain_query, null, 'reverse_salients_in_room is LOCAL-only');
368
+ assert.ok(typeof out.sql === 'string', 'sql must be a string');
369
+ // Crucial: the injection string must NOT appear in the SQL TEMPLATE.
370
+ assert.ok(out.sql.indexOf("DROP TABLE") === -1,
371
+ 'sql template must NEVER contain "DROP TABLE" (parameterized only)');
372
+ assert.ok(out.sql.indexOf("';") === -1,
373
+ 'sql template must NEVER contain quote-semicolon injection sequence');
374
+ // Bound parameter is allowed to contain the raw input -- DB driver escapes it.
375
+ assert.ok(Array.isArray(out.sql_params),
376
+ 'sql_params must be array (raw input bound, not concatenated)');
377
+ });
378
+
379
+ // ---------- T15: chokepoint exclusivity ----------
380
+
381
+ record('T15 chokepoint exclusivity: source-level grep invariants', function () {
382
+ const srcPath = path.resolve(__dirname, '../core/rs-nl-to-query.cjs');
383
+ const src = fs.readFileSync(srcPath, 'utf8');
384
+
385
+ // Count occurrences of forbidden surfaces.
386
+ const fetchHits = (src.match(/\bfetch\s*\(/g) || []).length;
387
+ assert.equal(fetchHits, 0,
388
+ 'rs-nl-to-query.cjs must NEVER call fetch(); got ' + fetchHits + ' hits');
389
+
390
+ // brain-client require must not appear (this module CONSTRUCTS, does NOT execute).
391
+ const brainClientHits = (src.match(/require\(['"][^'"]*brain-client[^'"]*['"]\)/g) || []).length;
392
+ assert.equal(brainClientHits, 0,
393
+ 'rs-nl-to-query.cjs must NOT require brain-client.cjs; got ' + brainClientHits + ' hits');
394
+
395
+ // queryGraph must not be called directly (orchestrator executes).
396
+ const queryGraphHits = (src.match(/\.queryGraph\s*\(/g) || []).length;
397
+ assert.equal(queryGraphHits, 0,
398
+ 'rs-nl-to-query.cjs must NOT call queryGraph(); got ' + queryGraphHits + ' hits');
399
+
400
+ // The chokepoint function must exist (definition + at least one call).
401
+ const buildBrainQueryHits = (src.match(/buildBrainQueryFromNL/g) || []).length;
402
+ assert.ok(buildBrainQueryHits >= 2,
403
+ 'buildBrainQueryFromNL must appear >= 2 times (definition + call); got '
404
+ + buildBrainQueryHits);
405
+
406
+ // auditQueryObject must be called at >= 3 sites.
407
+ const auditObjHits = (src.match(/auditQueryObject\s*\(/g) || []).length;
408
+ assert.ok(auditObjHits >= 3,
409
+ 'auditQueryObject must be called at >= 3 sites; got ' + auditObjHits);
410
+
411
+ // _test export exists.
412
+ assert.ok(_test && typeof _test === 'object', '_test export must be an object');
413
+ assert.equal(typeof _test.classifyIntent, 'function',
414
+ '_test.classifyIntent must be exported');
415
+ assert.equal(typeof _test.buildBrainQueryFromNL, 'function',
416
+ '_test.buildBrainQueryFromNL must be exported');
417
+ });
418
+
419
+ // ---------- T16: A1 sweep across positive outputs ----------
420
+
421
+ record('T16 A1 sweep: zero FORBIDDEN_PATTERNS matches in positive outputs', function () {
422
+ assert.ok(positiveOutputs.length >= 5,
423
+ 'must have collected >= 5 positive outputs for A1 sweep; got '
424
+ + positiveOutputs.length);
425
+ for (let i = 0; i < positiveOutputs.length; i++) {
426
+ const out = positiveOutputs[i];
427
+ const json = JSON.stringify(out);
428
+ for (const re of FORBIDDEN_PATTERNS) {
429
+ assert.equal(re.test(json), false,
430
+ 'A1 sweep failed: positive output ' + i + ' matched FORBIDDEN_PATTERN '
431
+ + re.source);
432
+ }
433
+ }
434
+ });
435
+
436
+ // ---------- Suite report ----------
437
+
438
+ const total = passed + failed;
439
+ process.stdout.write('\n');
440
+ if (failed === 0) {
441
+ process.stdout.write('=== 89.5-02 rs-nl-to-query suite: ' + passed + '/' + total + ' passed ===\n');
442
+ process.exit(0);
443
+ } else {
444
+ process.stdout.write('=== 89.5-02 rs-nl-to-query suite: ' + passed + '/' + total + ' passed (' + failed + ' failed) ===\n');
445
+ for (const f of failures) {
446
+ process.stdout.write(' FAIL ' + f.name + ': ' + f.message + '\n');
447
+ }
448
+ process.exit(1);
449
+ }