@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,255 @@
1
+ /*
2
+ * Copyright (c) 2026 Mindrian. BSL 1.1.
3
+ * Phase 89.2 Plan 07 Task 2 -- Phase 3 deterministic breakthrough scorer.
4
+ *
5
+ * 5-dimension 0-10 rubric per kickoff §5 Phase 3 enumeration. Deterministic
6
+ * weighted sum from substrate metadata + classifier output. Each dimension
7
+ * is scored 0-2; total is the simple sum.
8
+ *
9
+ * feasibility 0-2 from substrate.tier
10
+ * core -> 2.0
11
+ * applied -> 1.5
12
+ * theoretical -> 1.0
13
+ * <other> -> 1.0 (defensive default)
14
+ *
15
+ * market 0-2 from industry signal count (Tavily-orchestrated
16
+ * industry-fetcher signal count for the target domain):
17
+ * 0 -> 0.0
18
+ * 1-3 -> 0.5
19
+ * 4-9 -> 1.0
20
+ * 10-19 -> 1.5
21
+ * >=20 -> 2.0
22
+ *
23
+ * magnitude 0-2 from differential score (`diff` value mapped):
24
+ * 0.0 - 0.3 -> 0.0
25
+ * 0.3 - 0.5 -> 1.0
26
+ * 0.5 - 0.7 -> 1.5
27
+ * >=0.7 -> 2.0
28
+ *
29
+ * advantage 0-2 from cross-domain pair rarity. Computed from
30
+ * opts.pair_density (density of similar pairs in the
31
+ * substrate, [0, 1]; 1 = fully dense, 0 = perfectly rare).
32
+ * advantage = 2 * (1 - density), clamped to [0, 2].
33
+ * Default density = 1.0 (fully dense -> zero advantage)
34
+ * when pair_density is omitted -- pessimistic default.
35
+ *
36
+ * impact 0-2 from BERT cosine score (semantic depth):
37
+ * 0.0 - 0.2 -> 0.0
38
+ * 0.2 - 0.4 -> 0.5
39
+ * 0.4 - 0.6 -> 1.0
40
+ * 0.6 - 0.8 -> 1.5
41
+ * >=0.8 -> 2.0
42
+ *
43
+ * dominant_dimension is the breakdown key with the highest score. Ties
44
+ * are broken by frozen DIMENSIONS order ['feasibility', 'market',
45
+ * 'magnitude', 'advantage', 'impact'] -- the FIRST matching key wins.
46
+ * The frozen-order tie-break is the determinism contract; without it,
47
+ * Object.keys insertion order would be the implicit tie-breaker, which
48
+ * is fragile under refactor.
49
+ *
50
+ * Determinism contract: byte-identical JSON.stringify(out1) === JSON.stringify(out2)
51
+ * for identical inputs. No Math.random, no Date.now, no LLM call.
52
+ *
53
+ * Canon Part 8 (Graph Boundary): two defense-in-depth layers.
54
+ *
55
+ * Layer 1 -- pre-input scan: classified_pair.query_concept and
56
+ * classified_pair.doc_concept passed through auditQueryString BEFORE
57
+ * any rubric application. Throws ExternalEgressViolation on hit.
58
+ *
59
+ * Layer 2 -- pre-return audit: composite output passed through
60
+ * auditQueryObject before return. Defense-in-depth so any forbidden
61
+ * pattern smuggled via opts.substrate_metadata.title (or any field
62
+ * that propagates into the return envelope) is caught at the gate.
63
+ *
64
+ * Pure CJS, zero npm deps, node built-ins only beyond rs-egress-* primitives.
65
+ */
66
+ 'use strict';
67
+
68
+ const { auditQueryString, auditQueryObject } = require('./rs-egress-prompts.cjs');
69
+ require('./rs-egress-violations.cjs');
70
+
71
+ // ---------- Frozen invariants ----------
72
+
73
+ // 5-dimension space, frozen. Order is the tie-break contract for
74
+ // dominant_dimension: first matching key wins.
75
+ const DIMENSIONS = Object.freeze([
76
+ 'feasibility',
77
+ 'market',
78
+ 'magnitude',
79
+ 'advantage',
80
+ 'impact',
81
+ ]);
82
+
83
+ // substrate.tier -> feasibility lookup (frozen).
84
+ const TIER_TO_FEASIBILITY = Object.freeze({
85
+ core: 2.0,
86
+ applied: 1.5,
87
+ theoretical: 1.0,
88
+ });
89
+
90
+ // ---------- Dimension functions ----------
91
+
92
+ // Industry signal count -> market score. Pure step function.
93
+ function SIGNAL_COUNT_TO_MARKET(n) {
94
+ const x = (typeof n === 'number' && isFinite(n)) ? n : 0;
95
+ if (x >= 20) return 2.0;
96
+ if (x >= 10) return 1.5;
97
+ if (x >= 4) return 1.0;
98
+ if (x >= 1) return 0.5;
99
+ return 0.0;
100
+ }
101
+
102
+ // Differential score -> magnitude score. Pure step function.
103
+ function DIFF_TO_MAGNITUDE(d) {
104
+ const x = (typeof d === 'number' && isFinite(d)) ? d : 0;
105
+ if (x >= 0.7) return 2.0;
106
+ if (x >= 0.5) return 1.5;
107
+ if (x >= 0.3) return 1.0;
108
+ return 0.0;
109
+ }
110
+
111
+ // Cross-domain pair density -> advantage score. Density in [0, 1] inverts
112
+ // to advantage = 2 * (1 - density), clamped to [0, 2] for defense against
113
+ // out-of-range inputs (e.g., NaN, density > 1, density < 0).
114
+ function PAIR_DENSITY_TO_ADVANTAGE(rho) {
115
+ const x = (typeof rho === 'number' && isFinite(rho)) ? rho : 1.0;
116
+ const raw = 2.0 * (1.0 - x);
117
+ if (raw < 0) return 0.0;
118
+ if (raw > 2.0) return 2.0;
119
+ return raw;
120
+ }
121
+
122
+ // BERT score -> impact score. Pure step function.
123
+ function BERT_TO_IMPACT(b) {
124
+ const x = (typeof b === 'number' && isFinite(b)) ? b : 0;
125
+ if (x >= 0.8) return 2.0;
126
+ if (x >= 0.6) return 1.5;
127
+ if (x >= 0.4) return 1.0;
128
+ if (x >= 0.2) return 0.5;
129
+ return 0.0;
130
+ }
131
+
132
+ // ---------- computeDominant ----------
133
+ //
134
+ // Returns the first DIMENSIONS key whose breakdown value equals the max.
135
+ // Frozen-order tie-break is the determinism contract.
136
+
137
+ function computeDominant(breakdown) {
138
+ if (!breakdown || typeof breakdown !== 'object') return DIMENSIONS[0];
139
+ let max = -Infinity;
140
+ for (let i = 0; i < DIMENSIONS.length; i += 1) {
141
+ const v = breakdown[DIMENSIONS[i]];
142
+ if (typeof v === 'number' && v > max) max = v;
143
+ }
144
+ for (let i = 0; i < DIMENSIONS.length; i += 1) {
145
+ if (breakdown[DIMENSIONS[i]] === max) return DIMENSIONS[i];
146
+ }
147
+ return DIMENSIONS[0];
148
+ }
149
+
150
+ // ---------- scoreBreakthrough ----------
151
+ //
152
+ // Public entry point. Synchronous (no I/O, no spawn). Throws only on
153
+ // Canon Part 8 violations.
154
+ //
155
+ // Inputs:
156
+ // classified_pair object the post-classifier shape (pass-through fields)
157
+ // opts optional:
158
+ // substrate_metadata {tier: 'core'|'applied'|'theoretical', ...}
159
+ // industry_signal_count number count of industry-fetcher signals
160
+ // pair_density number [0, 1]; 1 = fully dense, 0 = rare
161
+ //
162
+ // Output (happy path):
163
+ // {<pass-through classified_pair fields>,
164
+ // breakthrough: {
165
+ // score: 0-10,
166
+ // breakdown: {feasibility, market, magnitude, advantage, impact},
167
+ // dominant_dimension: <one of DIMENSIONS>,
168
+ // }}
169
+ //
170
+ // Output (invalid input):
171
+ // {error: 'invalid_input', reason: <string>}
172
+
173
+ function scoreBreakthrough(classified_pair, opts) {
174
+ if (!classified_pair || typeof classified_pair !== 'object') {
175
+ return { error: 'invalid_input', reason: 'not_object' };
176
+ }
177
+
178
+ // Canon Part 8 Layer 1: pre-input scan on user-controlled concepts
179
+ // BEFORE any rubric application. Throws ExternalEgressViolation on hit.
180
+ if (typeof classified_pair.query_concept === 'string') {
181
+ auditQueryString(classified_pair.query_concept, 'breakthrough-scorer');
182
+ }
183
+ if (typeof classified_pair.doc_concept === 'string') {
184
+ auditQueryString(classified_pair.doc_concept, 'breakthrough-scorer');
185
+ }
186
+
187
+ opts = opts || {};
188
+ const substrateMeta = (opts.substrate_metadata && typeof opts.substrate_metadata === 'object')
189
+ ? opts.substrate_metadata
190
+ : {};
191
+ const tier = (typeof substrateMeta.tier === 'string') ? substrateMeta.tier : 'theoretical';
192
+
193
+ // 5-dimension rubric application.
194
+ const feasibility = (tier in TIER_TO_FEASIBILITY) ? TIER_TO_FEASIBILITY[tier] : 1.0;
195
+ const market = SIGNAL_COUNT_TO_MARKET(opts.industry_signal_count);
196
+ const magnitude = DIFF_TO_MAGNITUDE(classified_pair.diff);
197
+ const advantage = PAIR_DENSITY_TO_ADVANTAGE(
198
+ (typeof opts.pair_density === 'number') ? opts.pair_density : 1.0
199
+ );
200
+ const impact = BERT_TO_IMPACT(classified_pair.bert);
201
+
202
+ const breakdown = {
203
+ feasibility: feasibility,
204
+ market: market,
205
+ magnitude: magnitude,
206
+ advantage: advantage,
207
+ impact: impact,
208
+ };
209
+ // Score = simple sum, bounded in [0, 10] by construction (each
210
+ // dimension is in [0, 2]).
211
+ const score = feasibility + market + magnitude + advantage + impact;
212
+ const dominant_dimension = computeDominant(breakdown);
213
+
214
+ // Pass-through preserves the classifier shape so downstream
215
+ // thesis-generator can read all 3 layers (pair + classification +
216
+ // breakthrough) from a single object.
217
+ const out = {
218
+ query_concept: classified_pair.query_concept,
219
+ doc_concept: classified_pair.doc_concept,
220
+ diff: classified_pair.diff,
221
+ lsa: classified_pair.lsa,
222
+ bert: classified_pair.bert,
223
+ passes: classified_pair.passes,
224
+ classification: classified_pair.classification,
225
+ bridge_concept: classified_pair.bridge_concept,
226
+ breakthrough: {
227
+ score: score,
228
+ breakdown: breakdown,
229
+ dominant_dimension: dominant_dimension,
230
+ },
231
+ };
232
+
233
+ // Canon Part 8 Layer 2: pre-return audit on composite output. Defense
234
+ // in depth. If a future refactor propagates substrate_metadata.title or
235
+ // similar fields into the envelope, the audit catches forbidden bytes
236
+ // at the gate.
237
+ auditQueryObject(out, 'breakthrough-scorer');
238
+
239
+ return out;
240
+ }
241
+
242
+ // ---------- Exports ----------
243
+
244
+ module.exports = {
245
+ scoreBreakthrough: scoreBreakthrough,
246
+ _test: {
247
+ DIMENSIONS: DIMENSIONS,
248
+ TIER_TO_FEASIBILITY: TIER_TO_FEASIBILITY,
249
+ SIGNAL_COUNT_TO_MARKET: SIGNAL_COUNT_TO_MARKET,
250
+ DIFF_TO_MAGNITUDE: DIFF_TO_MAGNITUDE,
251
+ PAIR_DENSITY_TO_ADVANTAGE: PAIR_DENSITY_TO_ADVANTAGE,
252
+ BERT_TO_IMPACT: BERT_TO_IMPACT,
253
+ computeDominant: computeDominant,
254
+ },
255
+ };
@@ -0,0 +1,82 @@
1
+ /*
2
+ * Copyright (c) 2026 Mindrian. BSL 1.1.
3
+ * Phase 89.4 Plan 01 -- Canon Part 3 closed-vocabulary enforcement.
4
+ *
5
+ * Sibling of rs-egress-violations.cjs (89.2-01) by ANATOMY but
6
+ * SEPARATE module by SEMANTICS. ExternalEgressViolation guards
7
+ * outbound flow to public external fetchers; CanonVerbViolation
8
+ * guards the 10-verb closed vocabulary at the Decision Gate
9
+ * boundary. Sharing the class would conflate two distinct
10
+ * chokepoints. Both classes follow identical anatomy (.name + .meta)
11
+ * so Canon-aware caller wrappers catch them uniformly via err.name.
12
+ *
13
+ * The 10-verb canonical vocabulary is authoritative per
14
+ * docs/MINDRIAN-CANON.md Part 3 lines 153-162. New verbs require
15
+ * canon amendment, not a code-level invention.
16
+ *
17
+ * meta convention (informal, not enforced): callers SHOULD populate
18
+ * meta.attempted_verb (string) the verb_string that failed validation
19
+ * meta.surface (string) the call-site tag, e.g. 'navigation-engine'
20
+ * The class itself does not enforce shape so adversarial fixtures can
21
+ * probe edge cases (default meta = {}, omitted meta) without
22
+ * instantiation fighting them.
23
+ *
24
+ * validateVerb contract:
25
+ * typeof verb_string !== 'string' -> TypeError ('must be a string')
26
+ * empty or out-of-set string -> CanonVerbViolation
27
+ * in-set string -> returns the input verbatim
28
+ *
29
+ * surface argument is optional. When supplied as a non-empty string it
30
+ * propagates to err.meta.surface. When omitted or empty, defaults to
31
+ * the literal 'unknown' so downstream audit log lines always carry a
32
+ * non-empty surface tag (mirrors Phase 89.2 audit-triple convention).
33
+ *
34
+ * CANONICAL_VERBS is Object.freeze'd so accidental mutation throws in
35
+ * strict mode and Object.isFrozen returns true. Downstream consumers
36
+ * (89.5 NL-Graph Surface UI, future Decision Gate renderers) can
37
+ * enumerate the set without defensive copying.
38
+ *
39
+ * Pure CJS, zero npm deps, no Node built-ins beyond core require.
40
+ */
41
+ 'use strict';
42
+
43
+ class CanonVerbViolation extends Error {
44
+ constructor(message, meta) {
45
+ super(message);
46
+ this.name = 'CanonVerbViolation';
47
+ this.meta = meta || {};
48
+ }
49
+ }
50
+
51
+ const CANONICAL_VERBS = Object.freeze([
52
+ 'Run Methodology',
53
+ 'Reformulate',
54
+ 'Spawn Sub-Agent',
55
+ 'Navigate Graph',
56
+ "Devil's Advocate",
57
+ 'Scenario Plan',
58
+ 'Synthesize',
59
+ 'Bank Opportunity',
60
+ 'Defer',
61
+ 'Free-Text',
62
+ ]);
63
+
64
+ function validateVerb(verb_string, surface) {
65
+ if (typeof verb_string !== 'string') {
66
+ throw new TypeError(
67
+ 'validateVerb: input must be a string; got ' + typeof verb_string
68
+ );
69
+ }
70
+ const surfaceTag = (typeof surface === 'string' && surface.length > 0)
71
+ ? surface
72
+ : 'unknown';
73
+ if (!CANONICAL_VERBS.includes(verb_string)) {
74
+ throw new CanonVerbViolation(
75
+ 'verb not in Canon Part 3 closed vocabulary: ' + JSON.stringify(verb_string),
76
+ { attempted_verb: verb_string, surface: surfaceTag }
77
+ );
78
+ }
79
+ return verb_string;
80
+ }
81
+
82
+ module.exports = { CanonVerbViolation, CANONICAL_VERBS, validateVerb };
@@ -0,0 +1,343 @@
1
+ /*
2
+ * Copyright (c) 2026 Mindrian. BSL 1.1.
3
+ * Phase 89.4 Plan 02 -- engine-choreography codification (core).
4
+ * Phase 89.4 Plan 03 -- skill-spawn rule table wired in place.
5
+ *
6
+ * Codifies upstream + downstream chain wiring for the RS Discovery
7
+ * Engine per kickoff section 6 (USER LOAD-BEARING INTENT 7).
8
+ *
9
+ * lookupUpstream(problem_type, stage, opts?)
10
+ * -- queries Brain FEEDS_INTO topology via the EXISTING brain-client
11
+ * chokepoint (Canon Part 7); returns {state: 'ready'} OR
12
+ * {state: 'pause', missing_upstream, suggested_action}.
13
+ *
14
+ * emitChainMetadata(rs_type, breakthrough_score, active_context)
15
+ * -- returns the chain metadata block consumed by RS output
16
+ * layer; recommended_verb validated via Canon Part 3 closed-
17
+ * vocabulary checker (89.4-01) BEFORE the block is returned.
18
+ * Plan 89.4-03 wires the internal recommendSkillSpawn call so the
19
+ * chain metadata block carries spawn_skill + confidence + reasoning
20
+ * derived from the SKILL_SPAWN_RULES table.
21
+ *
22
+ * recommendSkillSpawn(rs_type, breakthrough_score, opts)
23
+ * -- Plan 89.4-03 swap: first-match-wins iteration over the locked
24
+ * SKILL_SPAWN_RULES table per kickoff section 6.4. Returns the
25
+ * recommendation; NEVER auto-invokes a skill (the user picks via
26
+ * the Canon Part 3 verb at the Decision Gate; 89.5 / 91 concern).
27
+ *
28
+ * SKILL_SPAWN_RULES (frozen)
29
+ * -- 5 rules per kickoff section 6.4 in declared order. Object.freeze'd
30
+ * at module scope AND each rule entry is independently frozen so
31
+ * the table cannot mutate at runtime.
32
+ *
33
+ * Reuses (Canon Part 7):
34
+ * brain-client.cjs::query / isAvailable (89.1a chokepoint)
35
+ * rs-egress-prompts.cjs::auditQueryObject (89.2-01 chokepoint)
36
+ * rs-canon-violations.cjs::validateVerb (89.4-01)
37
+ * rs-canon-violations.cjs::CanonVerbViolation (89.4-01)
38
+ * rs-egress-violations.cjs::ExternalEgressViolation (89.2-01)
39
+ *
40
+ * Brain query graceful-degradation order (mirrors Phase 90 Mode B/C/Tier-0):
41
+ * 1. brainClient.isAvailable() === false -> {state: 'ready'} + warn
42
+ * 2. brainClient.query() throws or returns null -> {state: 'ready'} + warn
43
+ * 3. response.records absent or wrong shape -> {state: 'ready'} + warn
44
+ * 4. Cross-reference returned framework names against
45
+ * opts.upstreamFreshness Map<name, boolean>; absent key = fresh.
46
+ *
47
+ * Canon Part 8 defense-in-depth:
48
+ * - lookupUpstream input ({problem_type, stage}) is audited via
49
+ * auditQueryObject BEFORE any Brain query is dispatched. If the
50
+ * audit trips, no Brain RPC is made and ExternalEgressViolation
51
+ * bubbles to the caller.
52
+ * - emitChainMetadata input (active_context) is audited via
53
+ * auditQueryObject so adversarial bytes nested in active_context.meta
54
+ * cannot smuggle into the returned metadata block.
55
+ * - recommendSkillSpawn opts (when non-empty) is audited as well.
56
+ * - The module never reaches the network directly; the only outbound
57
+ * surface is brainClient.query, which inherits 89.1a's allow-list.
58
+ *
59
+ * Pure CJS, zero npm deps, no Node built-ins beyond core require.
60
+ */
61
+ 'use strict';
62
+
63
+ const brainClientDefault = require('./brain-client.cjs');
64
+ const { auditQueryObject } = require('./rs-egress-prompts.cjs');
65
+ const { ExternalEgressViolation } = require('./rs-egress-violations.cjs');
66
+ const {
67
+ validateVerb,
68
+ CanonVerbViolation,
69
+ CANONICAL_VERBS,
70
+ } = require('./rs-canon-violations.cjs');
71
+
72
+ // ---------- Skill-spawn rule table (Plan 89.4-03; LOCKED per kickoff section 6.4) ----------
73
+
74
+ // Rules are evaluated in declared order via first-match-wins semantics.
75
+ // Confidence values match the kickoff section 6.4 specification verbatim;
76
+ // the 0.7 RECOMMENDED threshold is enforced by the CALLER (Plan 89.5
77
+ // Decision Gate UI) per Phase 88.2 Navigation Engine Brain interface
78
+ // contract. recommendSkillSpawn returns the raw confidence so callers can
79
+ // choose whether to surface a RECOMMENDED chip.
80
+ //
81
+ // Each rule entry is independently Object.freeze'd so the table cannot be
82
+ // mutated at runtime even if a caller obtains a reference to a rule. The
83
+ // match() functions are pure (no side effects, no I/O) and tolerate
84
+ // missing opts keys via `(opts.X || 0)` / `(opts.X || []).length` guards.
85
+ const SKILL_SPAWN_RULES = Object.freeze([
86
+ Object.freeze({
87
+ match: function (rs, score, opts) {
88
+ return score >= 7 && rs === 'structural_transfer';
89
+ },
90
+ spawn: '/mos:find-analogies',
91
+ confidence: 0.85,
92
+ reasoning: 'high breakthrough + structural transfer -> SAPPhIRE/TRIZ deepening',
93
+ }),
94
+ Object.freeze({
95
+ match: function (rs, score, opts) {
96
+ return score >= 7 && (opts.industry_signals_count || 0) > 0;
97
+ },
98
+ spawn: '/mos:lean-canvas',
99
+ confidence: 0.80,
100
+ reasoning: 'high breakthrough + market signal -> business model exploration',
101
+ }),
102
+ Object.freeze({
103
+ match: function (rs, score, opts) {
104
+ return (opts.cross_methodology_substrates || []).length > 1;
105
+ },
106
+ spawn: '/mos:pipeline',
107
+ confidence: 0.75,
108
+ reasoning: 'cross-methodology discovery -> chained pipeline (RS -> JTBD -> Persona)',
109
+ }),
110
+ Object.freeze({
111
+ match: function (rs, score, opts) {
112
+ return (opts.resolved_experts_count || 0) > 5
113
+ && (opts.resolved_institutions_count || 0) > 1;
114
+ },
115
+ spawn: '/mos:persona',
116
+ confidence: 0.70,
117
+ reasoning: 'expert network dense -> team composition',
118
+ }),
119
+ Object.freeze({
120
+ match: function (rs, score, opts) {
121
+ return score < 5 && opts.cynefin === 'complex';
122
+ },
123
+ spawn: '/mos:think-hats',
124
+ confidence: 0.65,
125
+ reasoning: 'low breakthrough + Cynefin complex -> perspective diversity',
126
+ }),
127
+ ]);
128
+
129
+ // ---------- Internal helpers ----------
130
+
131
+ // Sanitize a string for embedding in a Cypher query. Mirrors the byte-
132
+ // for-byte whitelist from brain-client.cjs::sanitizeCypherInput
133
+ // ([a-zA-Z0-9 ._-]). We do NOT call brainClient._test.sanitizeCypherInput
134
+ // directly so this module remains testable with a stub brainClient.
135
+ function _sanitizeCypher(value) {
136
+ if (value === null || value === undefined) return '';
137
+ const s = typeof value === 'string' ? value : String(value);
138
+ return s.replace(/[^a-zA-Z0-9 ._-]/g, '');
139
+ }
140
+
141
+ // Build the Brain Cypher query asking for upstream FEEDS_INTO frameworks
142
+ // for the reverse-salient engine, parameterized (defensively sanitized)
143
+ // by problem_type + stage for forward-compat (89.5 may bind these via
144
+ // Brain's parameterized query path).
145
+ function _buildUpstreamCypher(problem_type, stage) {
146
+ const safeProblem = _sanitizeCypher(problem_type);
147
+ const safeStage = _sanitizeCypher(stage);
148
+ // Note: safeProblem / safeStage are intentionally embedded in a
149
+ // comment line so they participate in the query text without
150
+ // affecting the MATCH semantics. The authoritative Brain edge query
151
+ // is for upstream frameworks pointing at the reverse-salient node.
152
+ return (
153
+ '// chain-feeder upstream lookup (problem_type=' + safeProblem +
154
+ ' stage=' + safeStage + ')\n' +
155
+ 'MATCH (rs:Framework {id: "reverse-salient-framework"}) ' +
156
+ '<-[:FEEDS_INTO]-(upstream:Framework) ' +
157
+ 'WHERE rs.id IS NOT NULL ' +
158
+ 'RETURN upstream.name AS name LIMIT 10'
159
+ );
160
+ }
161
+
162
+ // Defensively pull the framework name from a Brain record. Brain
163
+ // returns either {name: '...'} (driver-mode) or [n0, n1, ...] (raw
164
+ // columns). We support both.
165
+ function _recordName(rec) {
166
+ if (!rec || typeof rec !== 'object') return null;
167
+ if (typeof rec.name === 'string') return rec.name;
168
+ if (Array.isArray(rec) && typeof rec[0] === 'string') return rec[0];
169
+ return null;
170
+ }
171
+
172
+ // ---------- Public surface: lookupUpstream ----------
173
+
174
+ async function lookupUpstream(problem_type, stage, opts) {
175
+ opts = opts || {};
176
+ const brainClient = opts.brainClient || brainClientDefault;
177
+
178
+ // Canon Part 8: pre-flight audit on the input strings before they
179
+ // can reach Brain. ExternalEgressViolation bubbles to the caller.
180
+ auditQueryObject(
181
+ { problem_type: problem_type, stage: stage },
182
+ 'rs-chain-feeder-lookup-upstream'
183
+ );
184
+
185
+ if (!brainClient.isAvailable()) {
186
+ process.stderr.write('chain-feeder: Brain unreachable; assuming upstream ready\n');
187
+ return { state: 'ready' };
188
+ }
189
+
190
+ let result;
191
+ try {
192
+ const cypher = _buildUpstreamCypher(problem_type, stage);
193
+ result = await brainClient.query(cypher);
194
+ } catch (_err) {
195
+ process.stderr.write('chain-feeder: Brain query threw; assuming upstream ready\n');
196
+ return { state: 'ready' };
197
+ }
198
+
199
+ if (!result || !Array.isArray(result.records)) {
200
+ process.stderr.write(
201
+ 'chain-feeder: Brain query returned unexpected shape; assuming upstream ready\n'
202
+ );
203
+ return { state: 'ready' };
204
+ }
205
+
206
+ // Cross-reference upstream framework names against active room state
207
+ // freshness. Plan 89.4-02 ships a minimal in-memory check: if
208
+ // opts.upstreamFreshness is provided (Map<framework_name, boolean>),
209
+ // use it. Absent key = fresh by default (Phase 89.5 will integrate
210
+ // folder-memory.cjs for real freshness reads against BRAIN.md
211
+ // quadruples per Phase 90).
212
+ const freshness = opts.upstreamFreshness instanceof Map
213
+ ? opts.upstreamFreshness
214
+ : new Map();
215
+
216
+ const missing = [];
217
+ for (const rec of result.records) {
218
+ const name = _recordName(rec);
219
+ if (typeof name !== 'string' || name.length === 0) continue;
220
+ if (freshness.has(name) && freshness.get(name) === false) {
221
+ missing.push(name);
222
+ }
223
+ }
224
+
225
+ if (missing.length === 0) return { state: 'ready' };
226
+ return {
227
+ state: 'pause',
228
+ missing_upstream: missing,
229
+ suggested_action: 'Run Methodology',
230
+ };
231
+ }
232
+
233
+ // ---------- Public surface: emitChainMetadata ----------
234
+
235
+ function emitChainMetadata(rs_type, breakthrough_score, active_context) {
236
+ active_context = active_context || {};
237
+
238
+ // Canon Part 8: scan active_context for FORBIDDEN_PATTERNS via the
239
+ // existing chokepoint. Adversarial bytes nested in any field
240
+ // (e.g., active_context.meta.contact) get caught here.
241
+ auditQueryObject(active_context, 'rs-chain-feeder-emit-metadata');
242
+
243
+ // feeds_into mapping (deterministic per rs_type).
244
+ let feeds_into;
245
+ if (rs_type === 'structural_transfer') feeds_into = 'PWS VP';
246
+ else if (rs_type === 'semantic_implementation') feeds_into = 'Causal Loop';
247
+ else if (rs_type === 'hybrid') feeds_into = 'Navigation Engine';
248
+ else feeds_into = 'JTBD'; // fallback for unknown rs_type
249
+
250
+ // recommended_verb selection (deterministic per breakthrough_score).
251
+ // Plan 89.4-03 may refine via skill rules; this module ships the
252
+ // baseline heuristic.
253
+ const score = Number(breakthrough_score);
254
+ const safeScore = Number.isFinite(score) ? score : 0;
255
+ let recommended_verb;
256
+ if (safeScore >= 7) recommended_verb = 'Bank Opportunity';
257
+ else if (safeScore >= 5) recommended_verb = 'Synthesize';
258
+ else recommended_verb = 'Reformulate';
259
+
260
+ // Canon Part 3: validate before returning. Defensive against future
261
+ // edits to the heuristic introducing out-of-set verbs.
262
+ validateVerb(recommended_verb, 'rs-chain-feeder-emit-metadata');
263
+
264
+ // Plan 89.4-03 wiring: the chain metadata block now carries the rule
265
+ // recommendation. active_context is reused as opts for the rule-table
266
+ // evaluation. recommendSkillSpawn re-runs auditQueryObject under its
267
+ // own surface tag; this is intentional double-defense and matches the
268
+ // sibling pattern in lookupUpstream (audit before any consequential
269
+ // computation, even if the caller already audited).
270
+ const skill = recommendSkillSpawn(rs_type, safeScore, active_context);
271
+
272
+ return {
273
+ recommended_verb: recommended_verb,
274
+ feeds_into: feeds_into,
275
+ spawn_skill: skill.spawn_skill,
276
+ confidence: skill.confidence,
277
+ reasoning: skill.reasoning,
278
+ };
279
+ }
280
+
281
+ // ---------- Public surface: recommendSkillSpawn (Plan 89.4-03 rule-table wired) ----------
282
+
283
+ function recommendSkillSpawn(rs_type, breakthrough_score, opts) {
284
+ opts = opts || {};
285
+ // Canon Part 8 defense-in-depth (TIGHTENED in Plan 89.4-03): always run
286
+ // auditQueryObject when opts is a non-null object. The Plan 89.4-02 stub
287
+ // had a `Object.keys().length > 0` guard which, while sufficient for the
288
+ // stub, allowed adversarial single-key payloads to slip through if a
289
+ // caller post-mutated opts after the gate. The unconditional audit
290
+ // closes that window. Empty `{}` opts pass JSON.stringify('{}') trivially
291
+ // (zero forbidden-pattern hits).
292
+ auditQueryObject(opts, 'rs-chain-feeder-recommend-skill-spawn');
293
+
294
+ const score = Number(breakthrough_score);
295
+ const safeScore = Number.isFinite(score) ? score : 0;
296
+
297
+ // First-match-wins: iterate SKILL_SPAWN_RULES in declared order; the
298
+ // first rule whose match() returns true wins; subsequent rules are NOT
299
+ // evaluated. If no rule matches, return the no-rule fallback shape.
300
+ for (let i = 0; i < SKILL_SPAWN_RULES.length; i++) {
301
+ const rule = SKILL_SPAWN_RULES[i];
302
+ let matched = false;
303
+ try {
304
+ matched = !!rule.match(rs_type, safeScore, opts);
305
+ } catch (_e) {
306
+ // Defensive: a rule predicate that throws on unexpected opts shape
307
+ // never crashes the loop. Treated as a non-match so the iteration
308
+ // continues. This preserves first-match-wins semantics even under
309
+ // malformed input.
310
+ matched = false;
311
+ }
312
+ if (matched) {
313
+ return {
314
+ spawn_skill: rule.spawn,
315
+ confidence: rule.confidence,
316
+ reasoning: rule.reasoning,
317
+ };
318
+ }
319
+ }
320
+
321
+ return {
322
+ spawn_skill: null,
323
+ confidence: 0,
324
+ reasoning: 'no rule matched',
325
+ };
326
+ }
327
+
328
+ // ---------- Module exports ----------
329
+
330
+ module.exports = {
331
+ lookupUpstream,
332
+ emitChainMetadata,
333
+ recommendSkillSpawn,
334
+ // Plan 89.4-03 export (additive). Frozen array; callers may iterate
335
+ // for introspection (e.g., 89.5 NL-Graph Surface UI listing
336
+ // recommended skills) but cannot mutate.
337
+ SKILL_SPAWN_RULES,
338
+ // Re-export so Canon-aware caller wrappers can catch by err.name
339
+ // without re-requiring the upstream modules themselves.
340
+ ExternalEgressViolation,
341
+ CanonVerbViolation,
342
+ CANONICAL_VERBS,
343
+ };