@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,391 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /*
5
+ * Copyright (c) 2026 Mindrian. BSL 1.1.
6
+ * Phase 89.1 Plan 03 -- rs-query-matrix adversarial fixture suite.
7
+ *
8
+ * 11 scenarios covering:
9
+ * Happy path (T1): 1 scenario producing 60 queries
10
+ * Edge cases (T2-T5): 4 scenarios (null primary, empty
11
+ * adjacent, empty concepts, malformed)
12
+ * Determinism (T6, T7): 2 scenarios (deep-equal, 5-run identity)
13
+ * Adversarial (T8-T11): 4 scenarios (currency in primary,
14
+ * email in adjacent, person in concepts,
15
+ * SSN in terminology)
16
+ *
17
+ * End-of-suite A1 sweep:
18
+ * Walk every successful output's queries, JSON.stringify, scan against
19
+ * FORBIDDEN_PATTERNS + DANGEROUS_SUBSTRINGS. Any hit hard-fails the suite.
20
+ *
21
+ * Pure CJS, zero npm deps, node built-ins only (assert, path).
22
+ */
23
+
24
+ const assert = require('node:assert/strict');
25
+ const path = require('node:path');
26
+
27
+ const REPO_ROOT = path.resolve(__dirname, '..', '..');
28
+
29
+ // ---------- Frozen invariants ----------
30
+
31
+ const QUERIES_PER_CATEGORY = 15;
32
+ const CATEGORY_NAMES = Object.freeze([
33
+ 'a_intersect_b',
34
+ 'a_leads_to_b',
35
+ 'b_leads_to_a',
36
+ 'adjacent',
37
+ ]);
38
+
39
+ // Hard substrings that must never appear in any successful output's queries.
40
+ // Mirrors Phase 89.1a-03 / Phase 90-08 DANGEROUS_SUBSTRINGS so the A1 sweep
41
+ // matches the reference suite byte-for-byte.
42
+ const DANGEROUS_SUBSTRINGS = Object.freeze([
43
+ 'Lawrence',
44
+ '5.2M',
45
+ 'meeting with',
46
+ 'jonathan@mindrian.com',
47
+ '123-45-6789',
48
+ ]);
49
+
50
+ // Source of truth for the parity gate. Importing from the authoritative
51
+ // module (cross-room-aggregator) means any canon amendment there is felt
52
+ // here with zero code change.
53
+ const crossRoomAggregator = require('../core/cross-room-aggregator.cjs');
54
+
55
+ // Every successful output's full categories object is captured here so the
56
+ // A1 sweep at suite end can scan every produced query string against
57
+ // FORBIDDEN_PATTERNS + DANGEROUS_SUBSTRINGS.
58
+ const successfulOutputs = [];
59
+
60
+ // ---------- Scenario bookkeeping ----------
61
+
62
+ let passed = 0;
63
+ let failed = 0;
64
+ const failures = [];
65
+
66
+ async function runScenario(name, fn) {
67
+ const start = Date.now();
68
+ try {
69
+ await fn();
70
+ passed += 1;
71
+ process.stdout.write(' ok ' + name + ' (' + (Date.now() - start) + 'ms)\n');
72
+ } catch (err) {
73
+ failed += 1;
74
+ failures.push({ name: name, err: err });
75
+ process.stderr.write(' FAIL ' + name + '\n');
76
+ process.stderr.write(' ' + (err && err.stack ? err.stack : err) + '\n');
77
+ }
78
+ }
79
+
80
+ // ---------- Fixture helpers ----------
81
+
82
+ function makeHappyAnalysis(overrides) {
83
+ const base = {
84
+ primary_domain: 'reverse-salient-framework',
85
+ concepts: ['lag', 'expansion', 'bottleneck', 'disruption'],
86
+ terminology: ['reverse salient', 'momentum'],
87
+ methods: ['lsa', 'bert'],
88
+ breakthroughs: ['differential analysis'],
89
+ boundary_flag: false,
90
+ adjacent_domains: ['systems-thinking', 'jtbd'],
91
+ };
92
+ return Object.assign({}, base, overrides || {});
93
+ }
94
+
95
+ function assertCategoryShape(out, label) {
96
+ assert.ok(out && typeof out === 'object', label + ': output is not an object');
97
+ assert.ok(out.categories && typeof out.categories === 'object',
98
+ label + ': output.categories is missing');
99
+ for (const cat of CATEGORY_NAMES) {
100
+ assert.ok(Array.isArray(out.categories[cat]),
101
+ label + ': categories.' + cat + ' is not an array');
102
+ assert.equal(out.categories[cat].length, QUERIES_PER_CATEGORY,
103
+ label + ': categories.' + cat + ' length mismatch (got ' +
104
+ (out.categories[cat] && out.categories[cat].length) + ')');
105
+ for (let i = 0; i < out.categories[cat].length; i += 1) {
106
+ const q = out.categories[cat][i];
107
+ assert.equal(typeof q, 'string',
108
+ label + ': categories.' + cat + '[' + i + '] is not a string');
109
+ assert.ok(q.length > 0,
110
+ label + ': categories.' + cat + '[' + i + '] is empty');
111
+ }
112
+ }
113
+ }
114
+
115
+ function totalQueries(out) {
116
+ let n = 0;
117
+ for (const cat of CATEGORY_NAMES) n += out.categories[cat].length;
118
+ return n;
119
+ }
120
+
121
+ // ---------- Main ----------
122
+
123
+ async function main() {
124
+ process.stdout.write('\n=== Phase 89.1 Plan 03: rs-query-matrix fixture suite ===\n\n');
125
+
126
+ // ----- Parity gate -----
127
+ // The matrix module consumes FORBIDDEN_PATTERNS via rs-brain-substrate-
128
+ // prompts.cjs which re-exports byte-for-byte from cross-room-aggregator.
129
+ // Asserting parity here catches drift at every index.
130
+ const prompts = require('../core/rs-brain-substrate-prompts.cjs');
131
+ assert.equal(
132
+ prompts.FORBIDDEN_PATTERNS.length,
133
+ crossRoomAggregator.FORBIDDEN_PATTERNS.length,
134
+ 'FORBIDDEN_PATTERNS parity: length mismatch with cross-room-aggregator'
135
+ );
136
+ for (let i = 0; i < prompts.FORBIDDEN_PATTERNS.length; i += 1) {
137
+ assert.equal(
138
+ prompts.FORBIDDEN_PATTERNS[i].source,
139
+ crossRoomAggregator.FORBIDDEN_PATTERNS[i].source,
140
+ 'FORBIDDEN_PATTERNS parity: regex[' + i + '].source mismatch'
141
+ );
142
+ }
143
+ process.stdout.write(' ok Parity gate: FORBIDDEN_PATTERNS[' +
144
+ prompts.FORBIDDEN_PATTERNS.length + '] byte-for-byte with cross-room-aggregator\n');
145
+
146
+ // Load module-under-test ONCE. The matrix module is pure (no Brain client,
147
+ // no fs side effects) so no require.cache reset is needed between
148
+ // scenarios; mirrors test-rs-domain-analyzer.cjs pattern.
149
+ const matrixMod = require('../core/rs-query-matrix.cjs');
150
+ const generateQueryMatrix = matrixMod.generateQueryMatrix;
151
+ const ExternalEgressViolation = matrixMod.ExternalEgressViolation;
152
+
153
+ // ========== Test 1: Happy path ==========
154
+
155
+ await runScenario("T1: Happy path -- 60 queries from 7-field analysis", async () => {
156
+ const da = makeHappyAnalysis();
157
+ const out = generateQueryMatrix(da);
158
+ assertCategoryShape(out, 'T1');
159
+ assert.equal(totalQueries(out), 60, 'T1: total query count must equal 60');
160
+ // Canonical guarantee: every query must mention A OR B (most mention
161
+ // both). Templates that use pick(c|t|m|br, idx, a) substitute one of
162
+ // the analysis arrays which themselves anchor to the domain, but the
163
+ // load-bearing invariant is that NO query is generic prose with
164
+ // neither A nor B present.
165
+ const A = 'reverse-salient-framework';
166
+ const B = 'systems-thinking';
167
+ let aOrBCount = 0;
168
+ for (const cat of CATEGORY_NAMES) {
169
+ for (const q of out.categories[cat]) {
170
+ if (q.indexOf(A) !== -1 || q.indexOf(B) !== -1) aOrBCount += 1;
171
+ }
172
+ }
173
+ assert.equal(aOrBCount, 60,
174
+ 'T1: every query must mention A or B; got ' + aOrBCount + '/60');
175
+ successfulOutputs.push({ label: 'T1', out: out });
176
+ });
177
+
178
+ // ========== Tests 2-5: Edge cases ==========
179
+
180
+ await runScenario("T2: Edge -- null primary_domain returns invalid_analysis", async () => {
181
+ const da = makeHappyAnalysis({ primary_domain: null });
182
+ const out = generateQueryMatrix(da);
183
+ assert.equal(out.error, 'invalid_analysis',
184
+ 'T2: expected error envelope, got: ' + JSON.stringify(out));
185
+ assert.equal(out.reason, 'no_primary_domain',
186
+ 'T2: expected reason no_primary_domain, got: ' + out.reason);
187
+ });
188
+
189
+ await runScenario("T3: Edge -- empty adjacent_domains returns invalid_analysis", async () => {
190
+ const da = makeHappyAnalysis({ adjacent_domains: [] });
191
+ const out = generateQueryMatrix(da);
192
+ assert.equal(out.error, 'invalid_analysis',
193
+ 'T3: expected error envelope, got: ' + JSON.stringify(out));
194
+ assert.equal(out.reason, 'no_adjacent_domain',
195
+ 'T3: expected reason no_adjacent_domain, got: ' + out.reason);
196
+ });
197
+
198
+ await runScenario("T4: Edge -- empty concepts returns invalid_analysis", async () => {
199
+ const da = makeHappyAnalysis({ concepts: [] });
200
+ const out = generateQueryMatrix(da);
201
+ assert.equal(out.error, 'invalid_analysis',
202
+ 'T4: expected error envelope, got: ' + JSON.stringify(out));
203
+ assert.equal(out.reason, 'no_concepts',
204
+ 'T4: expected reason no_concepts, got: ' + out.reason);
205
+ });
206
+
207
+ await runScenario("T5: Edge -- malformed input ({}) returns invalid_analysis", async () => {
208
+ const out = generateQueryMatrix({});
209
+ assert.equal(out.error, 'invalid_analysis',
210
+ 'T5: expected error envelope, got: ' + JSON.stringify(out));
211
+ // {} fails primary_domain check first per validateAnalysis order.
212
+ assert.ok(typeof out.reason === 'string' && out.reason.length > 0,
213
+ 'T5: expected reason string, got: ' + out.reason);
214
+ });
215
+
216
+ // ========== Tests 6-7: Determinism ==========
217
+
218
+ await runScenario("T6: Determinism -- two invocations yield deep-equal output", async () => {
219
+ const da = makeHappyAnalysis();
220
+ const out1 = generateQueryMatrix(da);
221
+ const out2 = generateQueryMatrix(da);
222
+ assertCategoryShape(out1, 'T6/out1');
223
+ assertCategoryShape(out2, 'T6/out2');
224
+ assert.equal(JSON.stringify(out1), JSON.stringify(out2),
225
+ 'T6: deep-equal failed; outputs differ across calls');
226
+ successfulOutputs.push({ label: 'T6', out: out1 });
227
+ });
228
+
229
+ await runScenario("T7: Determinism -- 5 invocations yield identical JSON", async () => {
230
+ const da = makeHappyAnalysis();
231
+ const baseline = JSON.stringify(generateQueryMatrix(da));
232
+ for (let i = 0; i < 4; i += 1) {
233
+ const next = JSON.stringify(generateQueryMatrix(da));
234
+ assert.equal(next, baseline,
235
+ 'T7: run ' + (i + 2) + ' differs from baseline; non-deterministic');
236
+ }
237
+ successfulOutputs.push({ label: 'T7', out: JSON.parse(baseline) });
238
+ });
239
+
240
+ // ========== Tests 8-11: Adversarial ==========
241
+ //
242
+ // Each adversarial scenario asserts that the matrix EITHER throws
243
+ // ExternalEgressViolation OR returns the {error:'invalid_analysis',
244
+ // reason:'forbidden_input'} envelope. Both satisfy Canon Part 8: no
245
+ // forbidden bytes are inserted into the output array. The crucial
246
+ // load-bearing fact is that NO out.categories is returned with leaked
247
+ // strings.
248
+
249
+ await runScenario("T8: Adversarial -- leaked currency in primary_domain", async () => {
250
+ const da = makeHappyAnalysis({ primary_domain: '$5.2M-strategy' });
251
+ let threw = null;
252
+ let out = null;
253
+ try {
254
+ out = generateQueryMatrix(da);
255
+ } catch (err) {
256
+ threw = err;
257
+ }
258
+ if (threw !== null) {
259
+ assert.equal(threw.name, 'ExternalEgressViolation',
260
+ 'T8: expected ExternalEgressViolation, got: ' + (threw && threw.name));
261
+ // Throw path: nothing returned at all.
262
+ } else {
263
+ assert.equal(out.error, 'invalid_analysis',
264
+ 'T8: expected error envelope or throw, got: ' + JSON.stringify(out));
265
+ assert.equal(out.reason, 'forbidden_input',
266
+ 'T8: expected reason forbidden_input, got: ' + out.reason);
267
+ // Ensure no categories were leaked.
268
+ assert.ok(!out.categories,
269
+ 'T8: forbidden input must not produce categories');
270
+ }
271
+ });
272
+
273
+ await runScenario("T9: Adversarial -- leaked email in adjacent_domains[0]", async () => {
274
+ const da = makeHappyAnalysis({ adjacent_domains: ['jonathan@mindrian.com'] });
275
+ let threw = null;
276
+ let out = null;
277
+ try {
278
+ out = generateQueryMatrix(da);
279
+ } catch (err) {
280
+ threw = err;
281
+ }
282
+ if (threw !== null) {
283
+ assert.equal(threw.name, 'ExternalEgressViolation',
284
+ 'T9: expected ExternalEgressViolation, got: ' + (threw && threw.name));
285
+ } else {
286
+ assert.equal(out.error, 'invalid_analysis',
287
+ 'T9: expected error envelope or throw, got: ' + JSON.stringify(out));
288
+ assert.equal(out.reason, 'forbidden_input',
289
+ 'T9: expected reason forbidden_input, got: ' + out.reason);
290
+ assert.ok(!out.categories,
291
+ 'T9: forbidden input must not produce categories');
292
+ }
293
+ });
294
+
295
+ await runScenario("T10: Adversarial -- leaked person in concepts[0]", async () => {
296
+ const da = makeHappyAnalysis({ concepts: ['Lawrence said it', 'jtbd'] });
297
+ let threw = null;
298
+ let out = null;
299
+ try {
300
+ out = generateQueryMatrix(da);
301
+ } catch (err) {
302
+ threw = err;
303
+ }
304
+ if (threw !== null) {
305
+ assert.equal(threw.name, 'ExternalEgressViolation',
306
+ 'T10: expected ExternalEgressViolation, got: ' + (threw && threw.name));
307
+ } else {
308
+ assert.equal(out.error, 'invalid_analysis',
309
+ 'T10: expected error envelope or throw, got: ' + JSON.stringify(out));
310
+ assert.equal(out.reason, 'forbidden_input',
311
+ 'T10: expected reason forbidden_input, got: ' + out.reason);
312
+ assert.ok(!out.categories,
313
+ 'T10: forbidden input must not produce categories');
314
+ }
315
+ });
316
+
317
+ await runScenario("T11: Adversarial -- SSN-like in terminology", async () => {
318
+ const da = makeHappyAnalysis({ terminology: ['key concept 123-45-6789'] });
319
+ let threw = null;
320
+ let out = null;
321
+ try {
322
+ out = generateQueryMatrix(da);
323
+ } catch (err) {
324
+ threw = err;
325
+ }
326
+ if (threw !== null) {
327
+ assert.equal(threw.name, 'ExternalEgressViolation',
328
+ 'T11: expected ExternalEgressViolation, got: ' + (threw && threw.name));
329
+ } else {
330
+ assert.equal(out.error, 'invalid_analysis',
331
+ 'T11: expected error envelope or throw, got: ' + JSON.stringify(out));
332
+ assert.equal(out.reason, 'forbidden_input',
333
+ 'T11: expected reason forbidden_input, got: ' + out.reason);
334
+ assert.ok(!out.categories,
335
+ 'T11: forbidden input must not produce categories');
336
+ }
337
+ });
338
+
339
+ // ========== A1 sweep: cross-scenario forbidden-pattern audit ==========
340
+ //
341
+ // Walk every captured successful output's queries, JSON.stringify, scan
342
+ // against FORBIDDEN_PATTERNS + DANGEROUS_SUBSTRINGS. This is the same
343
+ // load-bearing invariant the rs-domain-analyzer suite enforces (A1
344
+ // sweep): forbidden bytes must NEVER appear in a successful output, no
345
+ // matter which template path produced them.
346
+
347
+ process.stdout.write('\n --- A1 sweep: cross-scenario forbidden-pattern audit ---\n');
348
+ let sweepHits = 0;
349
+ for (const entry of successfulOutputs) {
350
+ const blob = JSON.stringify(entry.out);
351
+ for (const re of prompts.FORBIDDEN_PATTERNS) {
352
+ if (re.test(blob)) {
353
+ process.stderr.write(' A1 FAIL: ' + entry.label + ' matched FORBIDDEN_PATTERN ' + re.source + '\n');
354
+ sweepHits += 1;
355
+ }
356
+ }
357
+ for (const dang of DANGEROUS_SUBSTRINGS) {
358
+ if (blob.indexOf(dang) !== -1) {
359
+ process.stderr.write(' A1 FAIL: ' + entry.label + ' contains DANGEROUS_SUBSTRING "' + dang + '"\n');
360
+ sweepHits += 1;
361
+ }
362
+ }
363
+ }
364
+ if (sweepHits === 0) {
365
+ process.stdout.write(' ok A1 sweep: ' + successfulOutputs.length +
366
+ ' outputs scanned, 0 forbidden hits\n');
367
+ } else {
368
+ failed += 1;
369
+ failures.push({ name: 'A1 sweep', err: new Error('A1 sweep had ' + sweepHits + ' forbidden hits') });
370
+ }
371
+
372
+ // ========== Final report ==========
373
+
374
+ process.stdout.write('\n=== 89.1-03 query-matrix suite: ' + passed + '/11 passed ===\n');
375
+ if (failed > 0) {
376
+ process.stderr.write('\n=== ' + failed + ' FAILURES ===\n');
377
+ for (const f of failures) {
378
+ process.stderr.write(' ' + f.name + ': ' + (f.err && f.err.message) + '\n');
379
+ }
380
+ process.exit(1);
381
+ }
382
+
383
+ // Defensive: silence unused-locals if future refactor drops them.
384
+ void REPO_ROOT;
385
+ void ExternalEgressViolation;
386
+ }
387
+
388
+ main().catch(function (err) {
389
+ process.stderr.write('FATAL: ' + (err && err.stack ? err.stack : err) + '\n');
390
+ process.exit(1);
391
+ });