@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,105 @@
1
+ 'use strict';
2
+ /**
3
+ * wiki-watcher.cjs — File watcher + SSE broadcast for wiki auto-refresh
4
+ *
5
+ * Watches room/ directory via chokidar. On file changes,
6
+ * calls the onChange callback and broadcasts SSE events
7
+ * to all connected browser clients.
8
+ */
9
+
10
+ const chokidar = require('chokidar');
11
+ const path = require('path');
12
+
13
+ const sseClients = new Set();
14
+
15
+ /**
16
+ * Start watching a room directory for changes.
17
+ * @param {string} roomDir - Path to room/ directory
18
+ * @param {function} onChangeCallback - Called with { event, path } on changes
19
+ * @returns {object} chokidar watcher instance
20
+ */
21
+ function startWatcher(roomDir, onChangeCallback) {
22
+ const absRoom = path.resolve(roomDir);
23
+
24
+ const watcher = chokidar.watch(absRoom, {
25
+ ignoreInitial: true,
26
+ ignored: [
27
+ /\.mindrian/,
28
+ /\.reasoning/,
29
+ /node_modules/,
30
+ /\.git/
31
+ ],
32
+ persistent: true,
33
+ awaitWriteFinish: {
34
+ stabilityThreshold: 300,
35
+ pollInterval: 100
36
+ }
37
+ });
38
+
39
+ watcher.on('all', (event, filePath) => {
40
+ // Only care about .md file changes
41
+ if (!filePath.endsWith('.md')) return;
42
+
43
+ const relPath = path.relative(absRoom, filePath);
44
+
45
+ // Call the application callback (rebuild index, etc.)
46
+ if (typeof onChangeCallback === 'function') {
47
+ onChangeCallback({ event, path: relPath });
48
+ }
49
+
50
+ // Broadcast SSE event to all connected clients
51
+ broadcast({ event: 'change', path: relPath, type: event });
52
+ });
53
+
54
+ return watcher;
55
+ }
56
+
57
+ /**
58
+ * Add an SSE client (Express response object).
59
+ * Sets appropriate headers and sends initial keepalive.
60
+ * @param {object} res - Express response object
61
+ */
62
+ function addSSEClient(res) {
63
+ res.writeHead(200, {
64
+ 'Content-Type': 'text/event-stream',
65
+ 'Cache-Control': 'no-cache',
66
+ 'Connection': 'keep-alive'
67
+ });
68
+
69
+ // Initial keepalive comment
70
+ res.write(':keepalive\n\n');
71
+
72
+ sseClients.add(res);
73
+
74
+ // Clean up on disconnect
75
+ res.on('close', () => {
76
+ removeSSEClient(res);
77
+ });
78
+ }
79
+
80
+ /**
81
+ * Remove an SSE client from the set.
82
+ * @param {object} res - Express response object
83
+ */
84
+ function removeSSEClient(res) {
85
+ sseClients.delete(res);
86
+ }
87
+
88
+ /**
89
+ * Broadcast an SSE event to all connected clients.
90
+ * @param {object} data - Event data to serialize as JSON
91
+ */
92
+ function broadcast(data) {
93
+ const message = `data: ${JSON.stringify(data)}\n\n`;
94
+
95
+ for (const client of sseClients) {
96
+ try {
97
+ client.write(message);
98
+ } catch (e) {
99
+ // Client disconnected — remove
100
+ sseClients.delete(client);
101
+ }
102
+ }
103
+ }
104
+
105
+ module.exports = { startWatcher, addSSEClient, removeSSEClient };
@@ -0,0 +1,47 @@
1
+ ---
2
+ type: directory-identity
3
+ name: lib/workflow
4
+ section: lib/workflow
5
+ purpose: Workflow layer -- the framework <-> command registry resolver. The sole door from "framework" to "/mos: command".
6
+ founding_phase: 122
7
+ phase: 122
8
+ milestone: v1.13.0-beta.11
9
+ canon_parts: [7, 8]
10
+ created: 2026-05-12
11
+ ---
12
+
13
+ # lib/workflow/
14
+
15
+ `lib/workflow/` is the home for the Workflow Layer -- the deterministic join between the Brain's methodology graph (`Framework -[:FEEDS_INTO]-> Framework`) and the plugin's `/mos:` command surface. Phase 122 is the founding phase; the resolver is the contained surface.
16
+
17
+ The reliability rules this directory enforces (per `.planning/WORKFLOW-LAYER-SPEC.md`):
18
+
19
+ 1. **Single source of truth.** `frameworks:` in each `commands/*.md` frontmatter is the only place the framework-to-command mapping is declared. Nothing here re-asserts it.
20
+ 2. **Generated, drift-impossible.** `data/command-registry.json` is built from frontmatter; a CI tripwire fails on stale registry or an unresolvable Brain framework name.
21
+ 3. **The resolver is the only door.** `command-resolver.cjs` is the sole path from framework to command. Larry never names a `/mos:` command from memory.
22
+ 4. **The trigger is the hook, not the model.** The navigation engine computes the command sequence; Larry is the voice, not the decision-maker.
23
+ 5. **Degrade, do not fabricate.** A framework with no command yields "run [framework] manually" -- never a made-up command.
24
+
25
+ ## Files in this section
26
+
27
+ | File | Plan | Purpose |
28
+ |------|------|---------|
29
+ | `command-resolver.test.cjs` | 122-01 (stub), 122-03 (fill) | Wave-0 stub for the resolver test suite. Covers `commandsForFramework`, `frameworksForCommand`, `composeWorkflow` (incl. null/optional markers), `validateChainAutonomy`, the empty-registry degrade path, and the no-Brain assertion once 122-03 fills it. |
30
+ | `command-resolver.cjs` | 122-03 | The resolver. `commandsForFramework`, `frameworksForCommand`, `composeWorkflow(frameworkChain) -> [{step, framework, command\|null, optional}]`, `validateChainAutonomy(workflow) -> {runnable, blockers}`. Reads only `data/command-registry.json` at runtime. Never queries the Brain. |
31
+
32
+ ## Canon Part 8 boundary (LOCAL + plugin-local, never Brain)
33
+
34
+ The resolver reads `data/command-registry.json` (plugin-local, generated, committed) and nothing else. It makes zero network calls. Commands NEVER enter the Brain (Canon Part 8) -- the registry is validated AGAINST the Brain's framework names at build time (`scripts/build-command-registry.cjs --refresh-names`), never written back. The chain recommender that seeds workflows from `FEEDS_INTO` lives in `lib/brain/` and carries only generic framework handles + problem-type enums in its Cypher -- never user content.
35
+
36
+ ## Decision #15 compliance
37
+
38
+ Per `CLAUDE.md` Decision #15, every directory in the data room (and the lib tree by extension under this milestone's policy) carries a ROOM.md identity file. `lib/workflow/` is bound to Phase 122; subsequent additions update this file's "Files in this section" table. No MINTO.md required at this level -- the `.room-root` cascade scope is `room/`, not `lib/`.
39
+
40
+ ## Cross-references
41
+
42
+ - Spec: `.planning/WORKFLOW-LAYER-SPEC.md`
43
+ - Phase 122 PLAN: `.planning/phases/122-workflow-layer/122-01-PLAN.md`
44
+ - Phase 122 RESEARCH: `.planning/phases/122-workflow-layer/122-RESEARCH.md`
45
+ - Frontmatter contract: `docs/COMMAND-FRONTMATTER.md`
46
+ - Canon: `docs/MINDRIAN-CANON.md` Parts 7, 8
47
+ - Sibling identity reference: `lib/hmi/ROOM.md` (Phase 100), `lib/conversation/ROOM.md` (Phase 99)
@@ -0,0 +1,155 @@
1
+ 'use strict';
2
+
3
+ /*
4
+ * Copyright (c) 2026 Mindrian. BSL 1.1.
5
+ *
6
+ * Phase 122-03 -- command-resolver.cjs (the only door)
7
+ * ====================================================
8
+ * The SOLE deterministic read-only path from "framework" to "command".
9
+ * Reads only data/command-registry.json at runtime. NEVER touches the Brain.
10
+ *
11
+ * Reliability rules (per .planning/WORKFLOW-LAYER-SPEC.md):
12
+ * 3. The resolver is the only door. The suggest-next / pipeline / act
13
+ * orchestrators, the navigation hook, the pws-methodology skill, and
14
+ * the brain-connector skill all go through this module. Larry never
15
+ * names a command from memory; every command he emits came back from
16
+ * the resolver.
17
+ * 5. Degrade, do not fabricate. A framework with no command yields
18
+ * { command: null, optional: true } -- never a made-up command. A
19
+ * missing / empty registry degrades every function to empty results.
20
+ *
21
+ * Canon Part 8 (Graph Boundary): this file does NOT require the Brain HTTP
22
+ * client and makes ZERO network calls. The registry is a plugin-local,
23
+ * generated, committed artifact (built by scripts/build-command-registry.cjs,
24
+ * validated AGAINST the Brain's framework names at build time, never written
25
+ * back). The pre-commit / test grep guard from 122-02 enforces the no-Brain
26
+ * rule.
27
+ *
28
+ * The four functions:
29
+ * commandsForFramework(name) -> string[] (registry framework_index[name] or [])
30
+ * frameworksForCommand(cmd) -> string[] (the command entry's frameworks, or [])
31
+ * composeWorkflow(chain) -> [{ step, framework, command|null, optional }]
32
+ * validateChainAutonomy(wf) -> { runnable, blockers }
33
+ *
34
+ * Test-only surface (small, clearly test-only):
35
+ * __reset() clears the per-process cache
36
+ * MINDRIAN_COMMAND_REGISTRY env overrides REGISTRY_PATH (for fixtures)
37
+ *
38
+ * License: BSL 1.1.
39
+ */
40
+
41
+ const fs = require('node:fs');
42
+ const path = require('node:path');
43
+
44
+ const DEFAULT_REGISTRY_PATH = path.join(__dirname, '..', '..', 'data', 'command-registry.json');
45
+
46
+ // Test-only override: lets the test point at a fixture or a nonexistent file
47
+ // to exercise the degrade path. Resolved fresh on every _load() cache miss so
48
+ // a test can flip it between __reset() calls.
49
+ function _registryPath() {
50
+ const override = process.env.MINDRIAN_COMMAND_REGISTRY;
51
+ return (typeof override === 'string' && override.length > 0) ? override : DEFAULT_REGISTRY_PATH;
52
+ }
53
+
54
+ // Per-process cache. The registry is a generated artifact that does not change
55
+ // during a run; reading it once is the integration-registry.cjs precedent.
56
+ let _cache = null;
57
+
58
+ // Degrade shape: an empty registry. Every function returns empty results
59
+ // against it -- no throw, no fabricated command.
60
+ const EMPTY_REGISTRY = Object.freeze({ commands: [], framework_index: {}, curated_chains: [] });
61
+
62
+ function _load() {
63
+ if (_cache) return _cache;
64
+ try {
65
+ const raw = fs.readFileSync(_registryPath(), 'utf8');
66
+ const parsed = JSON.parse(raw);
67
+ // Be tolerant of a partially-shaped file: fill missing keys.
68
+ _cache = {
69
+ commands: Array.isArray(parsed && parsed.commands) ? parsed.commands : [],
70
+ framework_index: (parsed && parsed.framework_index && typeof parsed.framework_index === 'object')
71
+ ? parsed.framework_index : {},
72
+ curated_chains: Array.isArray(parsed && parsed.curated_chains) ? parsed.curated_chains : [],
73
+ };
74
+ } catch (_e) {
75
+ _cache = EMPTY_REGISTRY; // degrade: missing / unreadable / malformed registry
76
+ }
77
+ return _cache;
78
+ }
79
+
80
+ /**
81
+ * commandsForFramework(name) -> string[]
82
+ * The /mos: command(s) declared (via frontmatter) to run framework `name`.
83
+ * Unknown framework / empty registry -> []. Never throws.
84
+ */
85
+ function commandsForFramework(name) {
86
+ if (typeof name !== 'string' || name.length === 0) return [];
87
+ const idx = _load().framework_index || {};
88
+ const cmds = idx[name];
89
+ return Array.isArray(cmds) ? cmds.slice() : [];
90
+ }
91
+
92
+ /**
93
+ * frameworksForCommand(cmd) -> string[]
94
+ * The framework(s) the given /mos: command declares it runs.
95
+ * Unknown command / empty registry -> []. Never throws.
96
+ */
97
+ function frameworksForCommand(cmd) {
98
+ if (typeof cmd !== 'string' || cmd.length === 0) return [];
99
+ const c = _load().commands.find(function (x) { return x && x.command === cmd; });
100
+ return (c && Array.isArray(c.frameworks)) ? c.frameworks.slice() : [];
101
+ }
102
+
103
+ /**
104
+ * composeWorkflow(frameworkChain) -> [{ step, framework, command|null, optional }]
105
+ * Maps an ordered framework-name list to a step list. The first command for
106
+ * each framework is taken; a framework with no command degrades to
107
+ * { command: null, optional: true } (the consumer prints "run X manually").
108
+ * Non-array / [] -> []. Never throws.
109
+ */
110
+ function composeWorkflow(frameworkChain) {
111
+ if (!Array.isArray(frameworkChain)) return [];
112
+ return frameworkChain.map(function (fw, i) {
113
+ const cmds = commandsForFramework(fw);
114
+ return {
115
+ step: i + 1,
116
+ framework: fw,
117
+ command: cmds.length > 0 ? cmds[0] : null,
118
+ optional: cmds.length === 0,
119
+ };
120
+ });
121
+ }
122
+
123
+ /**
124
+ * validateChainAutonomy(workflow) -> { runnable, blockers }
125
+ * `blockers` names every step whose command exists in the registry but is not
126
+ * `autonomous_safe: true` (or is unknown to the registry). Steps with
127
+ * command === null are skipped (not blockers -- they are manual-only by
128
+ * design, the consumer surfaces a "run manually" line, /mos:act --chain stops
129
+ * there with a "needs you here" gate per the spec). Never throws.
130
+ */
131
+ function validateChainAutonomy(workflow) {
132
+ const reg = _load();
133
+ const byCmd = new Map(reg.commands.map(function (c) { return [c && c.command, c]; }));
134
+ const blockers = [];
135
+ for (const s of (Array.isArray(workflow) ? workflow : [])) {
136
+ if (!s || !s.command) continue; // null command -> not a blocker (manual step)
137
+ const c = byCmd.get(s.command);
138
+ if (!c || c.autonomous_safe !== true) {
139
+ blockers.push({ step: s.step, command: s.command, reason: 'not autonomous_safe' });
140
+ }
141
+ }
142
+ return { runnable: blockers.length === 0, blockers: blockers };
143
+ }
144
+
145
+ // Test-only: clear the per-process cache so a test can re-point the registry.
146
+ function __reset() { _cache = null; }
147
+
148
+ module.exports = {
149
+ commandsForFramework: commandsForFramework,
150
+ frameworksForCommand: frameworksForCommand,
151
+ composeWorkflow: composeWorkflow,
152
+ validateChainAutonomy: validateChainAutonomy,
153
+ // Test-only surface (see header).
154
+ __reset: __reset,
155
+ };
@@ -0,0 +1,235 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /**
5
+ * Phase 122-03 -- command-resolver tests (real suite; fills the 122-01 Wave-0 stub).
6
+ *
7
+ * Registered in lib/memory/run-feynman-tests.cjs TEST_FILES[] (since 122-01,
8
+ * unchanged path). Run: node lib/workflow/command-resolver.test.cjs
9
+ * Exit 0 on pass; throws (node:assert) on any fail.
10
+ *
11
+ * Seven assertion groups (per 122-03-PLAN.md Task 1 <behavior>):
12
+ * 1. commandsForFramework -- known framework returns its array; unknown -> [].
13
+ * 2. frameworksForCommand -- known command returns its frameworks; unknown -> [].
14
+ * 3. composeWorkflow -- step/framework/command/optional shape, 1-indexed, in
15
+ * order; []/non-array -> [].
16
+ * 4. composeWorkflow on a deliberately command-less framework ("Red Teaming")
17
+ * -> { step:1, framework:"Red Teaming", command:null, optional:true }.
18
+ * 5. validateChainAutonomy -- /mos:hat-briefing (autonomous_safe: false) is a
19
+ * blocker; an all-autonomous_safe chain -> { runnable:true, blockers:[] };
20
+ * command:null steps are skipped.
21
+ * 6. Degrade -- MINDRIAN_COMMAND_REGISTRY pointed at a nonexistent file +
22
+ * __reset() -> empty registry, every function empty, no throw.
23
+ * 7. No-Brain -- the resolver source contains no require() of brain-client,
24
+ * no fetch(, no require('node:http'/'node:https').
25
+ */
26
+
27
+ const assert = require('node:assert/strict');
28
+ const fs = require('node:fs');
29
+ const path = require('node:path');
30
+
31
+ const REPO_ROOT = path.resolve(__dirname, '..', '..');
32
+ const RESOLVER_PATH = path.join(__dirname, 'command-resolver.cjs');
33
+ const REGISTRY_PATH = path.join(REPO_ROOT, 'data', 'command-registry.json');
34
+
35
+ // The real registry (read directly so the test asserts the COMPOSITION SHAPE
36
+ // against the committed artifact rather than hardcoding command strings that
37
+ // the 122-01 retrofit could legitimately tweak).
38
+ const registry = JSON.parse(fs.readFileSync(REGISTRY_PATH, 'utf8'));
39
+ const frameworkIndex = registry.framework_index || {};
40
+ const commandsByName = new Map(registry.commands.map(function (c) { return [c.command, c]; }));
41
+
42
+ const resolver = require('./command-resolver.cjs');
43
+
44
+ let passed = 0;
45
+ function test(name, fn) {
46
+ fn();
47
+ process.stdout.write(' ok ' + name + '\n');
48
+ passed += 1;
49
+ }
50
+
51
+ // Pick a real framework that has at least one command, deterministically (first
52
+ // key in the index whose value is a non-empty array). Keeps the test
53
+ // retrofit-proof.
54
+ const mappedFramework = Object.keys(frameworkIndex).find(function (k) {
55
+ return Array.isArray(frameworkIndex[k]) && frameworkIndex[k].length > 0;
56
+ });
57
+ assert.ok(mappedFramework, 'registry framework_index must contain at least one mapped framework');
58
+
59
+ // ---------------------------------------------------------------------------
60
+ // 1. commandsForFramework
61
+ // ---------------------------------------------------------------------------
62
+ test('commandsForFramework returns the registry framework_index array for a known framework', function () {
63
+ const got = resolver.commandsForFramework(mappedFramework);
64
+ assert.deepStrictEqual(got, frameworkIndex[mappedFramework]);
65
+ assert.ok(Array.isArray(got) && got.length > 0);
66
+ });
67
+
68
+ test('commandsForFramework returns [] for an unknown framework / empty / non-string', function () {
69
+ assert.deepStrictEqual(resolver.commandsForFramework('No Such Framework XYZ'), []);
70
+ assert.deepStrictEqual(resolver.commandsForFramework(''), []);
71
+ assert.deepStrictEqual(resolver.commandsForFramework(undefined), []);
72
+ assert.deepStrictEqual(resolver.commandsForFramework(null), []);
73
+ });
74
+
75
+ // ---------------------------------------------------------------------------
76
+ // 2. frameworksForCommand
77
+ // ---------------------------------------------------------------------------
78
+ test('frameworksForCommand returns the frameworks array from that command entry', function () {
79
+ const methCmd = registry.commands.find(function (c) {
80
+ return Array.isArray(c.frameworks) && c.frameworks.length > 0;
81
+ });
82
+ assert.ok(methCmd, 'registry must contain a command with a non-empty frameworks list');
83
+ assert.deepStrictEqual(resolver.frameworksForCommand(methCmd.command), methCmd.frameworks);
84
+ });
85
+
86
+ test('frameworksForCommand returns [] for an unknown command / empty / non-string', function () {
87
+ assert.deepStrictEqual(resolver.frameworksForCommand('/mos:no-such-command-xyz'), []);
88
+ assert.deepStrictEqual(resolver.frameworksForCommand(''), []);
89
+ assert.deepStrictEqual(resolver.frameworksForCommand(undefined), []);
90
+ });
91
+
92
+ // ---------------------------------------------------------------------------
93
+ // 3. composeWorkflow -- shape, 1-indexed, in order
94
+ // ---------------------------------------------------------------------------
95
+ test('composeWorkflow returns 1-indexed in-order { step, framework, command|null, optional } steps', function () {
96
+ // The spec acceptance example -- all three frameworks ARE mapped post-retrofit.
97
+ const chain = ['Beautiful Question Framework', 'Domain Selection', 'Jobs to Be Done (JTBD)'];
98
+ const wf = resolver.composeWorkflow(chain);
99
+ assert.strictEqual(wf.length, 3);
100
+ wf.forEach(function (s, i) {
101
+ assert.strictEqual(s.step, i + 1);
102
+ assert.strictEqual(s.framework, chain[i]);
103
+ assert.ok('command' in s);
104
+ assert.ok('optional' in s);
105
+ const cmds = frameworkIndex[chain[i]] || [];
106
+ if (cmds.length > 0) {
107
+ assert.strictEqual(s.command, cmds[0]);
108
+ assert.strictEqual(s.optional, false);
109
+ } else {
110
+ assert.strictEqual(s.command, null);
111
+ assert.strictEqual(s.optional, true);
112
+ }
113
+ });
114
+ // The spec example expects all three filled.
115
+ assert.ok(wf.every(function (s) { return s.command !== null && s.optional === false; }),
116
+ 'the spec acceptance example expects all three frameworks to resolve to a command');
117
+ });
118
+
119
+ test('composeWorkflow inverse-of-framework_index consistency for every mapped framework', function () {
120
+ const allMapped = Object.keys(frameworkIndex).filter(function (k) {
121
+ return Array.isArray(frameworkIndex[k]) && frameworkIndex[k].length > 0;
122
+ });
123
+ const wf = resolver.composeWorkflow(allMapped);
124
+ assert.strictEqual(wf.length, allMapped.length);
125
+ wf.forEach(function (s, i) {
126
+ assert.strictEqual(s.command, frameworkIndex[allMapped[i]][0]);
127
+ assert.strictEqual(s.optional, false);
128
+ });
129
+ });
130
+
131
+ test('composeWorkflow on [] returns []; on a non-array returns []', function () {
132
+ assert.deepStrictEqual(resolver.composeWorkflow([]), []);
133
+ assert.deepStrictEqual(resolver.composeWorkflow(null), []);
134
+ assert.deepStrictEqual(resolver.composeWorkflow(undefined), []);
135
+ assert.deepStrictEqual(resolver.composeWorkflow('not an array'), []);
136
+ assert.deepStrictEqual(resolver.composeWorkflow(42), []);
137
+ });
138
+
139
+ // ---------------------------------------------------------------------------
140
+ // 4. command-less framework degrades, does not fabricate
141
+ // ---------------------------------------------------------------------------
142
+ test('composeWorkflow(["Red Teaming"]) degrades to { command:null, optional:true } (no fabricated command)', function () {
143
+ // "Red Teaming" is intentionally command-less per the spec.
144
+ assert.ok(!(frameworkIndex['Red Teaming'] && frameworkIndex['Red Teaming'].length > 0),
145
+ 'Red Teaming must remain command-less for this assertion to be meaningful');
146
+ const wf = resolver.composeWorkflow(['Red Teaming']);
147
+ assert.deepStrictEqual(wf, [{ step: 1, framework: 'Red Teaming', command: null, optional: true }]);
148
+ });
149
+
150
+ // ---------------------------------------------------------------------------
151
+ // 5. validateChainAutonomy
152
+ // ---------------------------------------------------------------------------
153
+ test('validateChainAutonomy flags a non-autonomous_safe command (/mos:hat-briefing) as a blocker', function () {
154
+ const hb = commandsByName.get('/mos:hat-briefing');
155
+ assert.ok(hb, 'registry must contain /mos:hat-briefing');
156
+ assert.strictEqual(hb.autonomous_safe, false, '/mos:hat-briefing must be autonomous_safe: false');
157
+ const v = resolver.validateChainAutonomy([
158
+ { step: 1, command: '/mos:hat-briefing' },
159
+ { step: 2, command: '/mos:analyze-needs' },
160
+ ]);
161
+ assert.strictEqual(v.runnable, false);
162
+ assert.ok(v.blockers.some(function (b) {
163
+ return b.step === 1 && b.command === '/mos:hat-briefing' && b.reason === 'not autonomous_safe';
164
+ }));
165
+ });
166
+
167
+ test('validateChainAutonomy on an all-autonomous_safe chain returns { runnable:true, blockers:[] }', function () {
168
+ const safeCmds = registry.commands.filter(function (c) { return c.autonomous_safe === true; }).slice(0, 3);
169
+ assert.ok(safeCmds.length >= 2, 'registry must contain at least 2 autonomous_safe commands');
170
+ const wf = safeCmds.map(function (c, i) { return { step: i + 1, command: c.command }; });
171
+ const v = resolver.validateChainAutonomy(wf);
172
+ assert.deepStrictEqual(v, { runnable: true, blockers: [] });
173
+ });
174
+
175
+ test('validateChainAutonomy skips command:null steps (they are not blockers)', function () {
176
+ const v = resolver.validateChainAutonomy([
177
+ { step: 1, command: null },
178
+ { step: 2, command: '/mos:analyze-needs' }, // autonomous_safe: true
179
+ ]);
180
+ assert.strictEqual(v.runnable, true);
181
+ assert.deepStrictEqual(v.blockers, []);
182
+ const v2 = resolver.validateChainAutonomy([
183
+ { step: 1, command: null },
184
+ { step: 2, command: '/mos:hat-briefing' },
185
+ ]);
186
+ assert.strictEqual(v2.runnable, false);
187
+ assert.strictEqual(v2.blockers.length, 1);
188
+ assert.strictEqual(v2.blockers[0].step, 2);
189
+ });
190
+
191
+ test('validateChainAutonomy on []/non-array/undefined returns { runnable:true, blockers:[] }', function () {
192
+ assert.deepStrictEqual(resolver.validateChainAutonomy([]), { runnable: true, blockers: [] });
193
+ assert.deepStrictEqual(resolver.validateChainAutonomy(undefined), { runnable: true, blockers: [] });
194
+ assert.deepStrictEqual(resolver.validateChainAutonomy(null), { runnable: true, blockers: [] });
195
+ });
196
+
197
+ // ---------------------------------------------------------------------------
198
+ // 6. Degrade -- missing registry -> empty results, no throw
199
+ // ---------------------------------------------------------------------------
200
+ test('a missing / unreadable registry degrades every function to empty results (no throw)', function () {
201
+ const prev = process.env.MINDRIAN_COMMAND_REGISTRY;
202
+ try {
203
+ process.env.MINDRIAN_COMMAND_REGISTRY = path.join(REPO_ROOT, 'data', '__nonexistent_registry__.json');
204
+ resolver.__reset();
205
+ assert.deepStrictEqual(resolver.commandsForFramework('Beautiful Question Framework'), []);
206
+ assert.deepStrictEqual(resolver.frameworksForCommand('/mos:analyze-needs'), []);
207
+ assert.deepStrictEqual(resolver.composeWorkflow(['Beautiful Question Framework', 'Red Teaming']),
208
+ [
209
+ { step: 1, framework: 'Beautiful Question Framework', command: null, optional: true },
210
+ { step: 2, framework: 'Red Teaming', command: null, optional: true },
211
+ ]);
212
+ assert.deepStrictEqual(resolver.validateChainAutonomy([{ step: 1, command: '/mos:analyze-needs' }]),
213
+ { runnable: false, blockers: [{ step: 1, command: '/mos:analyze-needs', reason: 'not autonomous_safe' }] });
214
+ } finally {
215
+ if (prev === undefined) { delete process.env.MINDRIAN_COMMAND_REGISTRY; }
216
+ else { process.env.MINDRIAN_COMMAND_REGISTRY = prev; }
217
+ resolver.__reset();
218
+ }
219
+ // Sanity: back to the real registry after reset.
220
+ assert.ok(resolver.commandsForFramework(mappedFramework).length > 0);
221
+ });
222
+
223
+ // ---------------------------------------------------------------------------
224
+ // 7. No-Brain -- the resolver source is a pure local reader
225
+ // ---------------------------------------------------------------------------
226
+ test('command-resolver.cjs source contains no brain-client require, no fetch(, no node:http(s) require', function () {
227
+ const src = fs.readFileSync(RESOLVER_PATH, 'utf8');
228
+ assert.ok(!/brain-client/.test(src), 'resolver must not reference brain-client');
229
+ assert.ok(!/\bfetch\s*\(/.test(src), 'resolver must not call fetch()');
230
+ assert.ok(!/require\(\s*['"]node:https?['"]\s*\)/.test(src), 'resolver must not require node:http / node:https');
231
+ assert.ok(!/require\(\s*['"]https?['"]\s*\)/.test(src), 'resolver must not require http / https');
232
+ });
233
+
234
+ process.stdout.write('\ncommand-resolver.test.cjs: ' + passed + ' assertion groups PASSED\n');
235
+ process.exit(0);
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@mindrian_os/install",
3
+ "version": "1.13.0-beta.11",
4
+ "description": "Install MindrianOS into Claude Code with one command -- `npx @mindrian_os/install`. Ships the MindrianOS plugin (Larry + PWS methodology + Data Room) plus a setup/diagnostics CLI (install/doctor/update).",
5
+ "scripts": {
6
+ "mcp": "node bin/mindrian-mcp-server.cjs",
7
+ "parity": "node lib/parity/check-parity.cjs",
8
+ "migrate-minto-v88": "node scripts/migrate-minto-schema-v88.cjs"
9
+ },
10
+ "bin": {
11
+ "mindrian-os": "bin/cli.js"
12
+ },
13
+ "files": [
14
+ "bin/",
15
+ "lib/",
16
+ "pipelines/",
17
+ "references/",
18
+ "skills/",
19
+ "commands/",
20
+ "agents/",
21
+ "hooks/",
22
+ ".claude-plugin/",
23
+ ".mcp.json",
24
+ "README.md",
25
+ "LICENSE",
26
+ "CHANGELOG.md"
27
+ ],
28
+ "dependencies": {
29
+ "@ig3/markdown-it-wikilinks": "^1.0.2",
30
+ "@modelcontextprotocol/ext-apps": "^1.5.0",
31
+ "@modelcontextprotocol/sdk": "^1.29.0",
32
+ "asciichart": "^1.5.25",
33
+ "chokidar": "^4.0.3",
34
+ "express": "^5.1.0",
35
+ "flexsearch": "^0.7.43",
36
+ "gray-matter": "^4.0.3",
37
+ "markdown-it": "^14.1.0",
38
+ "zod": "^3.25.76"
39
+ },
40
+ "engines": {
41
+ "node": ">=22.5.0"
42
+ },
43
+ "license": "BSL-1.1"
44
+ }
@@ -0,0 +1,80 @@
1
+ ---
2
+ stage: 1
3
+ methodology: reason
4
+ chain: analogy
5
+ input_from: null
6
+ output_to: abstract
7
+ room_section: problem-definition
8
+ ---
9
+
10
+ # Stage 1: Decompose (SAPPhIRE Extraction)
11
+
12
+ ## Input Extraction
13
+
14
+ First stage -- uses room artifacts across all sections. No prior pipeline artifact needed.
15
+
16
+ Scan `room/STATE.md` for venture context: problem type, venture stage, filled sections. Then read key artifacts from the most populated sections (problem-definition, solution-design, market-analysis) to understand the venture's core challenge.
17
+
18
+ If the user provided a specific problem or contradiction when starting the pipeline, use that as the focal point. Otherwise, identify the venture's primary challenge from room state.
19
+
20
+ ## Stage Instructions
21
+
22
+ Run `/mos:reason` with the venture's core problem, framing the decomposition around SAPPhIRE layers.
23
+
24
+ Read `references/methodology/sapphire-encoding.md` for the SAPPhIRE ontology reference.
25
+
26
+ For each major room artifact, extract:
27
+
28
+ ### SAPPhIRE Triples
29
+
30
+ | Layer | Question | Extract From |
31
+ |-------|----------|-------------|
32
+ | **State** | What is the current situation/condition? | problem-definition/ |
33
+ | **Action** | What action does the system perform? | solution-design/ |
34
+ | **Part** | What structural components exist? | team-execution/ |
35
+ | **Phenomenon** | What observable behaviors/trends drive this? | market-analysis/ |
36
+ | **Input** | What resources/inputs does the system consume? | business-model/ |
37
+ | **Real effect** | What underlying principle/mechanism operates? | competitive-analysis/ |
38
+ | **Effect** | What measurable outcome results? | financial-model/ |
39
+
40
+ ### Core Contradiction Identification
41
+
42
+ Identify the venture's CORE CONTRADICTION -- the tension where improving one dimension worsens another:
43
+ - "Increasing [X] degrades [Y]"
44
+ - "We need [A] but [A] prevents [B]"
45
+ - "Our strength in [domain] becomes a weakness when [condition]"
46
+
47
+ Check existing KuzuDB `CONTRADICTS` edges if available:
48
+ ```
49
+ Scan room/.lazygraph/ for existing contradiction edges
50
+ ```
51
+
52
+ ### Function-Behavior-Structure Encoding
53
+
54
+ For the core problem, produce:
55
+ - **Function:** What the system DOES (verb + object, domain-independent)
56
+ - **Behavior:** HOW it achieves the function (mechanism)
57
+ - **Structure:** WHAT components enable the behavior (parts and relationships)
58
+
59
+ Larry should push the user past domain-specific language: "You say 'customer acquisition' -- but functionally, what are you doing? You're FILTERING a population by fit criteria and CONVERTING interest to commitment. Those are functions that exist everywhere."
60
+
61
+ When the methodology produces its artifact, ensure pipeline provenance is added to frontmatter:
62
+
63
+ ```yaml
64
+ pipeline: analogy
65
+ pipeline_stage: 1
66
+ sapphire_function: "[extracted function]"
67
+ sapphire_behavior: "[extracted behavior]"
68
+ sapphire_structure: "[extracted structure]"
69
+ core_contradiction: "[improving X] vs [worsening Y]"
70
+ ```
71
+
72
+ ## Output Contract
73
+
74
+ The following sections from the artifact feed into Stage 2 (abstract):
75
+
76
+ - **SAPPhIRE triples** -- become the input for domain-independent encoding
77
+ - **Core contradiction** -- becomes the target for TRIZ parameter mapping
78
+ - **Function-behavior-structure** -- becomes the basis for cross-domain search queries
79
+
80
+ Stage 2 will extract these by scanning `room/problem-definition/` for the most recent artifact with `pipeline: analogy` and `pipeline_stage: 1` in frontmatter.