@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,433 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /*
5
+ * Copyright (c) 2026 Mindrian. BSL 1.1.
6
+ * Phase 89.2 Plan 06 Task 2 -- preprocessor fixture suite.
7
+ *
8
+ * 10 scenarios for the deterministic per-document preprocessor that
9
+ * produces the 5-field shape:
10
+ * {document_id, technical_terms[], concepts[], methods[],
11
+ * relevance_score, boundary_flag}
12
+ *
13
+ * Test 1 happy path (5 papers + 3 patents + 2 signals; 5-field shape verified)
14
+ * Test 2 determinism (5 invocations identical bytes)
15
+ * Test 3 empty documents (returns [])
16
+ * Test 4 malformed document (no abstract/signal/title) -> warning + empty fields
17
+ * Test 5 industry signal (uses signal field instead of abstract)
18
+ * Test 6 boundary_flag triggered (low relevance / no concept overlap)
19
+ * Test 7 boundary_flag NOT triggered (high relevance + concept overlap)
20
+ * Test 8 CANON PART 8 adversarial: forbidden in document.abstract
21
+ * Test 9 CANON PART 8 adversarial: forbidden in document.title (email)
22
+ * Test 10 CANON PART 8 adversarial: forbidden in domain_analysis input
23
+ *
24
+ * Suite-end audit:
25
+ * A1 walk every captured preprocessed[]; JSON.stringify scan against
26
+ * FORBIDDEN_PATTERNS + DANGEROUS_SUBSTRINGS; ZERO hits.
27
+ *
28
+ * Pure CJS, zero npm deps, node built-ins only.
29
+ */
30
+
31
+ const assert = require('node:assert/strict');
32
+ const path = require('node:path');
33
+
34
+ const REPO_ROOT = path.resolve(__dirname, '..', '..');
35
+
36
+ const crossRoomAggregator = require('../core/cross-room-aggregator.cjs');
37
+ const FORBIDDEN_PATTERNS = crossRoomAggregator.FORBIDDEN_PATTERNS;
38
+
39
+ const DANGEROUS_SUBSTRINGS = Object.freeze([
40
+ 'Lawrence',
41
+ '5.2M',
42
+ 'meeting with',
43
+ 'jonathan@mindrian.com',
44
+ '123-45-6789',
45
+ ]);
46
+
47
+ // ---------- Suite bookkeeping ----------
48
+
49
+ let passed = 0;
50
+ let failed = 0;
51
+ const failures = [];
52
+ const SCENARIO_RESULTS = [];
53
+
54
+ function resetRequireCache() {
55
+ const targets = [
56
+ '../core/rs-egress-violations.cjs',
57
+ '../core/rs-egress-prompts.cjs',
58
+ '../core/cross-room-aggregator.cjs',
59
+ '../core/rs-preprocessor.cjs',
60
+ ];
61
+ for (const t of targets) {
62
+ try {
63
+ const p = require.resolve(t);
64
+ delete require.cache[p];
65
+ } catch (_e) { /* best effort */ }
66
+ }
67
+ }
68
+
69
+ async function runScenario(name, fn) {
70
+ const start = Date.now();
71
+ try {
72
+ await fn();
73
+ passed += 1;
74
+ process.stdout.write(' ok ' + name + ' (' + (Date.now() - start) + 'ms)\n');
75
+ } catch (err) {
76
+ failed += 1;
77
+ failures.push({ name: name, err: err });
78
+ process.stderr.write(' FAIL ' + name + '\n');
79
+ process.stderr.write(' ' + (err && err.stack ? err.stack : err) + '\n');
80
+ } finally {
81
+ resetRequireCache();
82
+ }
83
+ }
84
+
85
+ function captureResult(name, result) {
86
+ SCENARIO_RESULTS.push({ scenario: name, result: result });
87
+ }
88
+
89
+ // ---------- Fixtures ----------
90
+
91
+ function makePapers(n) {
92
+ // 5 papers with cancer-immunotherapy-style abstracts.
93
+ const out = [];
94
+ for (let i = 0; i < n; i += 1) {
95
+ out.push({
96
+ id: 'paper-' + i,
97
+ title: 'Cancer immunotherapy biomarker analysis ' + i,
98
+ abstract: 'We applied deep learning models to cancer immunotherapy biomarker discovery. ' +
99
+ 'The biomarker analysis revealed checkpoint inhibitor responsiveness in patient cohorts. ' +
100
+ 'We measured response rates and computed survival statistics across the cohort.',
101
+ authors: ['Dr Adams', 'Dr Brown'],
102
+ source: 'arxiv',
103
+ doi: '10.1000/paper' + i,
104
+ fetched_at: '2026-04-26T00:00:00Z',
105
+ });
106
+ }
107
+ return out;
108
+ }
109
+
110
+ function makePatents(n) {
111
+ const out = [];
112
+ for (let i = 0; i < n; i += 1) {
113
+ out.push({
114
+ id: 'pat-' + i,
115
+ patent_id: 'US' + (10000 + i),
116
+ title: 'Method for biomarker checkpoint analysis ' + i,
117
+ abstract: 'A method for analyzing biomarker expression in checkpoint inhibitor therapy. ' +
118
+ 'The system implemented machine learning over patient samples to predict response.',
119
+ inventors: ['Adams J', 'Brown K'],
120
+ source: 'google_patents',
121
+ fetched_at: '2026-04-26T00:00:00Z',
122
+ });
123
+ }
124
+ return out;
125
+ }
126
+
127
+ function makeSignals(n) {
128
+ const out = [];
129
+ for (let i = 0; i < n; i += 1) {
130
+ out.push({
131
+ id: 'sig-' + i,
132
+ signal: 'Biotech startup ' + i + ' raised funding for cancer immunotherapy biomarker platform development.',
133
+ source: 'tavily',
134
+ url: 'https://example.com/signal' + i,
135
+ fetched_at: '2026-04-26T00:00:00Z',
136
+ });
137
+ }
138
+ return out;
139
+ }
140
+
141
+ function makeDomainAnalysis() {
142
+ return {
143
+ primary_domain: 'cancer-immunotherapy',
144
+ concepts: ['cancer', 'immunotherapy', 'biomarker', 'checkpoint', 'inhibitor', 'response'],
145
+ terminology: ['oncology', 'immune', 'targeted'],
146
+ methods: ['deep-learning', 'machine-learning'],
147
+ };
148
+ }
149
+
150
+ // ---------- Scenarios ----------
151
+
152
+ async function scenario1HappyPath() {
153
+ const m = require('../core/rs-preprocessor.cjs');
154
+ const docs = [].concat(makePapers(5), makePatents(3), makeSignals(2));
155
+ const out = m.preprocess(docs, { domain_analysis: makeDomainAnalysis() });
156
+ captureResult('1-happy-path', out);
157
+ assert.ok(Array.isArray(out), 'output is array');
158
+ assert.equal(out.length, 10, 'all 10 documents processed; got ' + out.length);
159
+ for (const rec of out) {
160
+ assert.ok(typeof rec.document_id === 'string', 'document_id is string');
161
+ assert.ok(Array.isArray(rec.technical_terms), 'technical_terms is array');
162
+ assert.ok(Array.isArray(rec.concepts), 'concepts is array');
163
+ assert.ok(Array.isArray(rec.methods), 'methods is array');
164
+ assert.equal(typeof rec.relevance_score, 'number', 'relevance_score is number');
165
+ assert.ok(rec.relevance_score >= 0 && rec.relevance_score <= 1, 'relevance_score in [0,1]');
166
+ assert.equal(typeof rec.boundary_flag, 'boolean', 'boundary_flag is boolean');
167
+ assert.ok(rec.technical_terms.length <= 20, 'technical_terms <= 20');
168
+ assert.ok(rec.concepts.length <= 10, 'concepts <= 10');
169
+ assert.ok(rec.methods.length <= 5, 'methods <= 5');
170
+ }
171
+ // Spot-check at least one paper carries some technical_terms + concepts.
172
+ const firstPaper = out[0];
173
+ assert.ok(firstPaper.technical_terms.length >= 1, 'first paper has >=1 technical_terms');
174
+ assert.ok(firstPaper.concepts.length >= 1, 'first paper has >=1 concept overlap with domain_analysis');
175
+ }
176
+
177
+ async function scenario2Determinism() {
178
+ const m = require('../core/rs-preprocessor.cjs');
179
+ const docs = makePapers(3);
180
+ const da = makeDomainAnalysis();
181
+ const out1 = m.preprocess(docs, { domain_analysis: da });
182
+ const out2 = m.preprocess(docs, { domain_analysis: da });
183
+ const out3 = m.preprocess(docs, { domain_analysis: da });
184
+ const out4 = m.preprocess(docs, { domain_analysis: da });
185
+ const out5 = m.preprocess(docs, { domain_analysis: da });
186
+ captureResult('2-determinism-1', out1);
187
+ const j1 = JSON.stringify(out1);
188
+ assert.equal(j1, JSON.stringify(out2), 'invocation 2 byte-identical to 1');
189
+ assert.equal(j1, JSON.stringify(out3), 'invocation 3 byte-identical to 1');
190
+ assert.equal(j1, JSON.stringify(out4), 'invocation 4 byte-identical to 1');
191
+ assert.equal(j1, JSON.stringify(out5), 'invocation 5 byte-identical to 1');
192
+ }
193
+
194
+ async function scenario3EmptyDocuments() {
195
+ const m = require('../core/rs-preprocessor.cjs');
196
+ const out = m.preprocess([], { domain_analysis: makeDomainAnalysis() });
197
+ captureResult('3-empty-docs', out);
198
+ assert.ok(Array.isArray(out), 'output is array');
199
+ assert.equal(out.length, 0, 'empty input -> empty output');
200
+ }
201
+
202
+ async function scenario4MalformedDocument() {
203
+ const m = require('../core/rs-preprocessor.cjs');
204
+ const docs = [{ id: 'malformed-1', source: 'unknown' }];
205
+ const out = m.preprocess(docs, { domain_analysis: makeDomainAnalysis() });
206
+ captureResult('4-malformed', out);
207
+ assert.equal(out.length, 1, 'one record processed');
208
+ const rec = out[0];
209
+ assert.equal(rec.document_id, 'malformed-1', 'document_id preserved');
210
+ assert.deepEqual(rec.technical_terms, [], 'technical_terms empty');
211
+ assert.deepEqual(rec.concepts, [], 'concepts empty');
212
+ assert.deepEqual(rec.methods, [], 'methods empty');
213
+ assert.equal(rec.relevance_score, 0, 'relevance_score == 0');
214
+ assert.equal(rec.boundary_flag, true, 'boundary_flag true');
215
+ assert.equal(rec.warning, 'document_text_missing', 'warning emitted');
216
+ }
217
+
218
+ async function scenario5IndustrySignal() {
219
+ const m = require('../core/rs-preprocessor.cjs');
220
+ // Signal field carries rich domain-overlapping content so the boundary_flag
221
+ // resolves to false; the test verifies that the signal field is mapped onto
222
+ // the same preprocessing path as abstract (papers/patents both use abstract
223
+ // while industry signals use signal -- per CONTEXT.md fetcher output shapes).
224
+ const docs = [{
225
+ id: 'sig-only-1',
226
+ signal: 'CRISPR startup raised funding for cancer immunotherapy biomarker checkpoint inhibitor response platform development',
227
+ source: 'tavily',
228
+ fetched_at: '2026-04-26T00:00:00Z',
229
+ }];
230
+ const out = m.preprocess(docs, { domain_analysis: makeDomainAnalysis() });
231
+ captureResult('5-industry-signal', out);
232
+ assert.equal(out.length, 1, 'one record processed');
233
+ const rec = out[0];
234
+ // technical_terms should pick up tokens from signal field.
235
+ const json = JSON.stringify(rec.technical_terms);
236
+ assert.ok(/crispr|startup|biomarker|cancer/i.test(json),
237
+ 'technical_terms should reflect signal text; got ' + json);
238
+ assert.equal(typeof rec.relevance_score, 'number', 'relevance_score number');
239
+ // All 6 da concepts (cancer, immunotherapy, biomarker, checkpoint, inhibitor,
240
+ // response) are overlapping with the signal text -> overlap == 6/6 == 1.0.
241
+ assert.ok(rec.concepts.length >= 5,
242
+ 'concept overlap >= 5 for full-domain signal; got ' + rec.concepts.length);
243
+ assert.equal(rec.boundary_flag, false,
244
+ 'boundary_flag false (industry signal mapped onto same preprocessing path)');
245
+ }
246
+
247
+ async function scenario6BoundaryFlagTriggered() {
248
+ const m = require('../core/rs-preprocessor.cjs');
249
+ const docs = [{
250
+ id: 'unrelated-1',
251
+ abstract: 'Completely unrelated content about astronomy and stars and galaxies',
252
+ source: 'arxiv',
253
+ fetched_at: '2026-04-26T00:00:00Z',
254
+ }];
255
+ const out = m.preprocess(docs, { domain_analysis: makeDomainAnalysis() });
256
+ captureResult('6-boundary-triggered', out);
257
+ const rec = out[0];
258
+ // No overlap with cancer/immunotherapy/biomarker concepts.
259
+ assert.equal(rec.boundary_flag, true, 'boundary_flag true on unrelated content; got ' + rec.boundary_flag);
260
+ }
261
+
262
+ async function scenario7BoundaryFlagNotTriggered() {
263
+ const m = require('../core/rs-preprocessor.cjs');
264
+ const docs = [{
265
+ id: 'overlap-1',
266
+ abstract: 'cancer immunotherapy biomarker checkpoint inhibitor response analysis cancer cancer biomarker biomarker checkpoint inhibitor response',
267
+ source: 'arxiv',
268
+ fetched_at: '2026-04-26T00:00:00Z',
269
+ }];
270
+ const out = m.preprocess(docs, { domain_analysis: makeDomainAnalysis() });
271
+ captureResult('7-boundary-not-triggered', out);
272
+ const rec = out[0];
273
+ assert.ok(rec.relevance_score >= 0.5, 'relevance_score >= 0.5; got ' + rec.relevance_score);
274
+ assert.ok(rec.concepts.length >= 4, 'concepts >= 4; got ' + rec.concepts.length);
275
+ assert.equal(rec.boundary_flag, false, 'boundary_flag false on high overlap');
276
+ }
277
+
278
+ async function scenario8AdversarialAbstract() {
279
+ const m = require('../core/rs-preprocessor.cjs');
280
+ const docs = [{
281
+ id: 'adv-1',
282
+ abstract: 'meeting with Dr Smith about $5.2M Q4 financial results was held last week',
283
+ source: 'arxiv',
284
+ fetched_at: '2026-04-26T00:00:00Z',
285
+ }];
286
+ let out = null;
287
+ let threw = null;
288
+ try {
289
+ out = m.preprocess(docs, { domain_analysis: makeDomainAnalysis() });
290
+ } catch (err) {
291
+ threw = err;
292
+ }
293
+ if (threw) {
294
+ assert.equal(threw.name, 'ExternalEgressViolation',
295
+ 'must throw ExternalEgressViolation on adversarial abstract; got ' + (threw && threw.name));
296
+ captureResult('8-adv-abstract-throw', { thrown: threw.name });
297
+ } else {
298
+ captureResult('8-adv-abstract-scrubbed', out);
299
+ const json = JSON.stringify(out);
300
+ assert.ok(!/meeting with/i.test(json), 'output must not contain "meeting with"');
301
+ assert.ok(!/5\.2M/i.test(json), 'output must not contain "5.2M"');
302
+ }
303
+ }
304
+
305
+ async function scenario9AdversarialTitleEmail() {
306
+ const m = require('../core/rs-preprocessor.cjs');
307
+ const docs = [{
308
+ id: 'adv-2',
309
+ title: 'jonathan@mindrian.com cancer paper',
310
+ abstract: 'Standard cancer biomarker analysis content with no leakage at all',
311
+ source: 'arxiv',
312
+ fetched_at: '2026-04-26T00:00:00Z',
313
+ }];
314
+ let out = null;
315
+ let threw = null;
316
+ try {
317
+ out = m.preprocess(docs, { domain_analysis: makeDomainAnalysis() });
318
+ } catch (err) {
319
+ threw = err;
320
+ }
321
+ if (threw) {
322
+ assert.equal(threw.name, 'ExternalEgressViolation',
323
+ 'must throw ExternalEgressViolation on email-in-title; got ' + (threw && threw.name));
324
+ captureResult('9-adv-email-throw', { thrown: threw.name });
325
+ } else {
326
+ captureResult('9-adv-email-scrubbed', out);
327
+ const json = JSON.stringify(out);
328
+ assert.ok(!/jonathan@mindrian\.com/i.test(json), 'output must not contain leaked email');
329
+ }
330
+ }
331
+
332
+ async function scenario10AdversarialDomainAnalysis() {
333
+ const m = require('../core/rs-preprocessor.cjs');
334
+ const docs = makePapers(2);
335
+ // Domain analysis carries forbidden pattern in concepts.
336
+ const dirty_da = {
337
+ primary_domain: 'cancer',
338
+ concepts: ['Lawrence said breakthrough', 'biomarker'],
339
+ terminology: ['oncology'],
340
+ methods: ['ml'],
341
+ };
342
+ let out = null;
343
+ let threw = null;
344
+ try {
345
+ out = m.preprocess(docs, { domain_analysis: dirty_da });
346
+ } catch (err) {
347
+ threw = err;
348
+ }
349
+ // Either rejected at pre-input scan with envelope OR scrubbed and proceeds.
350
+ if (threw) {
351
+ assert.equal(threw.name, 'ExternalEgressViolation',
352
+ 'either throws ExternalEgressViolation or returns rejection envelope; got throw=' + (threw && threw.name));
353
+ captureResult('10-adv-da-throw', { thrown: threw.name });
354
+ } else if (out && out.error === 'invalid_input') {
355
+ captureResult('10-adv-da-rejected', out);
356
+ assert.equal(out.reason, 'forbidden_input', 'rejection reason matches');
357
+ } else {
358
+ captureResult('10-adv-da-scrubbed', out);
359
+ const json = JSON.stringify(out);
360
+ assert.ok(!/Lawrence said/.test(json), 'output must not contain "Lawrence said"');
361
+ }
362
+ }
363
+
364
+ // ---------- A1 sweep ----------
365
+
366
+ function a1Sweep() {
367
+ let hits = 0;
368
+ for (const rec of SCENARIO_RESULTS) {
369
+ const json = JSON.stringify(rec.result);
370
+ for (const re of FORBIDDEN_PATTERNS) {
371
+ if (re.test(json)) {
372
+ hits += 1;
373
+ process.stderr.write(
374
+ ' A1 HIT scenario=' + rec.scenario +
375
+ ' pattern=' + re.source + '\n'
376
+ );
377
+ }
378
+ }
379
+ for (const sub of DANGEROUS_SUBSTRINGS) {
380
+ if (json.indexOf(sub) !== -1) {
381
+ hits += 1;
382
+ process.stderr.write(
383
+ ' A1 HIT scenario=' + rec.scenario +
384
+ ' substring=' + sub + '\n'
385
+ );
386
+ }
387
+ }
388
+ }
389
+ return hits;
390
+ }
391
+
392
+ // ---------- Main ----------
393
+
394
+ (async function main() {
395
+ process.stdout.write('=== 89.2-06-preprocessor suite (REPO_ROOT=' + REPO_ROOT + ') ===\n');
396
+
397
+ await runScenario('1-happy-path', scenario1HappyPath);
398
+ await runScenario('2-determinism', scenario2Determinism);
399
+ await runScenario('3-empty-documents', scenario3EmptyDocuments);
400
+ await runScenario('4-malformed-document', scenario4MalformedDocument);
401
+ await runScenario('5-industry-signal', scenario5IndustrySignal);
402
+ await runScenario('6-boundary-flag-triggered', scenario6BoundaryFlagTriggered);
403
+ await runScenario('7-boundary-flag-not-triggered', scenario7BoundaryFlagNotTriggered);
404
+ await runScenario('8-adversarial-abstract', scenario8AdversarialAbstract);
405
+ await runScenario('9-adversarial-title-email', scenario9AdversarialTitleEmail);
406
+ await runScenario('10-adversarial-domain-analysis', scenario10AdversarialDomainAnalysis);
407
+
408
+ const sweepHits = a1Sweep();
409
+ if (sweepHits > 0) {
410
+ failed += 1;
411
+ failures.push({
412
+ name: 'A1-sweep',
413
+ err: new Error('A1 sweep found ' + sweepHits + ' forbidden-pattern hits'),
414
+ });
415
+ process.stderr.write(' FAIL A1-sweep (' + sweepHits + ' hits)\n');
416
+ } else {
417
+ process.stdout.write(' ok A1-sweep (zero forbidden-pattern hits)\n');
418
+ }
419
+
420
+ if (failed > 0) {
421
+ for (const f of failures) {
422
+ process.stderr.write(' FAILURE: ' + f.name + ': ' +
423
+ (f.err && f.err.message ? f.err.message : String(f.err)) + '\n');
424
+ }
425
+ process.stdout.write('=== 89.2-06-preprocessor suite: ' + passed + '/10 passed (' + failed + ' failed) ===\n');
426
+ process.exit(1);
427
+ }
428
+ process.stdout.write('=== 89.2-06-preprocessor suite: 10/10 passed ===\n');
429
+ process.exit(0);
430
+ })().catch(function (err) {
431
+ process.stderr.write('FATAL: ' + (err && err.stack ? err.stack : err) + '\n');
432
+ process.exit(2);
433
+ });