@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,226 @@
1
+ 'use strict';
2
+
3
+ /*
4
+ * Phase 115-02 -- shallow-doc-parser unit tests (8 fixtures + ancillary)
5
+ *
6
+ * Test map (mirrors PLAN <behavior>):
7
+ * PR-01..PR-03 parseRoleHints 3 fixtures
8
+ * PV-01..PV-03 parseVentureHint 3 fixtures
9
+ * PC-01 parseClaims 1 fixture
10
+ * ES-01 extractShallow happy-path 1 integration fixture
11
+ * ES-02 extractShallow graceful-degradation 1 fixture
12
+ *
13
+ * Navigation API is STUBBED via Module._resolveFilename redirect to a
14
+ * generated __nav-stub.cjs that records calls into navStub.__calls. This
15
+ * keeps the unit test free of room.db side effects; live integration is
16
+ * covered by tests/test-115-dual-path-integration.sh (Task 4).
17
+ *
18
+ * Canon Part 7 alignment: stub mirrors the (sessionId, nodeId, setBy)
19
+ * surface the parser writes through. The parser MUST NOT require
20
+ * room-db.cjs directly; that contract is enforced by a grep in <verify>.
21
+ */
22
+
23
+ const assert = require('node:assert/strict');
24
+ const path = require('node:path');
25
+ const fs = require('node:fs');
26
+ const Module = require('node:module');
27
+
28
+ // ---------- Generate the navigation stub ----------
29
+
30
+ const stubPath = path.resolve(__dirname, '__nav-stub.cjs');
31
+ const navStubSource = `'use strict';
32
+ // Auto-generated by shallow-doc-parser.test.cjs. DO NOT edit by hand; the
33
+ // surface is defined to mirror lib/core/navigation.cjs as Phase 115-02
34
+ // expects to consume it (sessionId/nodeId/setBy form for setFocus,
35
+ // sessionId/eventType/payload form for recordMemoryEvent).
36
+ const calls = { setFocus: [], memoryEvents: [], getActiveFocus: [] };
37
+ function reset() { calls.setFocus.length = 0; calls.memoryEvents.length = 0; calls.getActiveFocus.length = 0; }
38
+ module.exports = {
39
+ setFocus: function (sid, nid, sb) { calls.setFocus.push({ sid: sid, nid: nid, sb: sb }); return { ok: true, eventId: 'stub-evt-' + calls.setFocus.length }; },
40
+ recordMemoryEvent: function (sid, type, payload) { calls.memoryEvents.push({ sid: sid, type: type, payload: payload }); return { ok: true, eventId: 'stub-mem-' + calls.memoryEvents.length }; },
41
+ getActiveFocus: function (sid) { calls.getActiveFocus.push({ sid: sid }); return null; },
42
+ __calls: calls,
43
+ __reset: reset,
44
+ };
45
+ `;
46
+ fs.writeFileSync(stubPath, navStubSource);
47
+
48
+ // ---------- Redirect ./navigation.cjs requires from inside lib/core/ ----------
49
+
50
+ const targetParserPath = path.resolve(__dirname, 'shallow-doc-parser.cjs');
51
+ const originalResolve = Module._resolveFilename;
52
+ Module._resolveFilename = function (request, parent, ...rest) {
53
+ if (request === './navigation.cjs' && parent && parent.filename === targetParserPath) {
54
+ return stubPath;
55
+ }
56
+ return originalResolve.call(this, request, parent, ...rest);
57
+ };
58
+
59
+ // ---------- Test scaffolding ----------
60
+
61
+ let passed = 0;
62
+ let failed = 0;
63
+ function run(name, fn) {
64
+ try {
65
+ fn();
66
+ process.stdout.write('ok ' + name + '\n');
67
+ passed += 1;
68
+ } catch (err) {
69
+ process.stderr.write('FAIL ' + name + '\n' + (err && err.stack ? err.stack : String(err)) + '\n');
70
+ failed += 1;
71
+ }
72
+ }
73
+
74
+ const { extractShallow, parseRoleHints, parseVentureHint, parseClaims } = require(targetParserPath);
75
+ const navStub = require(stubPath);
76
+
77
+ // ---------- parseRoleHints (3 fixtures) ----------
78
+
79
+ run('PR-01 Founder of Acme Robotics -> Founder', () => {
80
+ const r = parseRoleHints('Founder of Acme Robotics');
81
+ assert.ok(r, 'parseRoleHints returned null');
82
+ assert.equal(r.canonical_role, 'Founder');
83
+ assert.equal(typeof r.confidence, 'number');
84
+ assert.ok(r.confidence > 0 && r.confidence <= 1);
85
+ });
86
+
87
+ run('PR-02 PhD Researcher in cancer biology, NIH-funded -> Researcher', () => {
88
+ const r = parseRoleHints('PhD Researcher in cancer biology, NIH-funded');
89
+ assert.ok(r);
90
+ assert.equal(r.canonical_role, 'Researcher');
91
+ });
92
+
93
+ run('PR-03 GP at Acme Ventures, $50M fund -> Investor', () => {
94
+ const r = parseRoleHints('GP at Acme Ventures, $50M fund');
95
+ assert.ok(r);
96
+ assert.equal(r.canonical_role, 'Investor');
97
+ });
98
+
99
+ run('PR-04 plain prose with no role hints -> null', () => {
100
+ const r = parseRoleHints('I have been thinking about market fit lately and the next quarter feels uncertain.');
101
+ assert.equal(r, null);
102
+ });
103
+
104
+ run('PR-null null input -> null', () => {
105
+ const r = parseRoleHints(null);
106
+ assert.equal(r, null);
107
+ });
108
+
109
+ // ---------- parseVentureHint (3 fixtures) ----------
110
+
111
+ run('PV-01 Founder of Acme Robotics -> Acme Robotics', () => {
112
+ const r = parseVentureHint('Founder of Acme Robotics');
113
+ assert.equal(r.name, 'Acme Robotics');
114
+ assert.equal(r.stage, 'unknown');
115
+ });
116
+
117
+ run('PV-02 PI on NCT12345678 -> clinical-trial', () => {
118
+ const r = parseVentureHint('PI on NCT12345678 clinical trial');
119
+ assert.equal(r.name, 'NCT12345678');
120
+ assert.equal(r.stage, 'clinical-trial');
121
+ });
122
+
123
+ run('PV-03 plain prose graceful degradation -> null name', () => {
124
+ const r = parseVentureHint("I'm working on something");
125
+ assert.equal(r.name, null);
126
+ assert.equal(r.stage, 'unknown');
127
+ });
128
+
129
+ run('PV-null null input -> null name', () => {
130
+ const r = parseVentureHint(null);
131
+ assert.equal(r.name, null);
132
+ assert.equal(r.stage, 'unknown');
133
+ });
134
+
135
+ // ---------- parseClaims (1 fixture) ----------
136
+
137
+ run('PC-01 CV with 3 bullets -> 3 claim objects', () => {
138
+ const text = '- Founded Acme in 2024\n- Raised $5M Series A\n- Team of 8 engineers and operators';
139
+ const claims = parseClaims(text);
140
+ assert.equal(claims.length, 3);
141
+ assert.ok(claims[0].text.length > 0);
142
+ assert.ok(claims[1].text.length > 0);
143
+ assert.ok(claims[2].text.length > 0);
144
+ assert.match(claims[0].text, /Founded Acme in 2024/);
145
+ });
146
+
147
+ run('PC-null null input -> empty array', () => {
148
+ const r = parseClaims(null);
149
+ assert.deepEqual(r, []);
150
+ });
151
+
152
+ // ---------- extractShallow integration (ES-01 happy-path) ----------
153
+
154
+ run('ES-01 full CV paste -> 1 user + 1 venture + 3 claims, navigation calls', () => {
155
+ navStub.__reset();
156
+ const text = [
157
+ 'Founder of Acme Robotics',
158
+ 'PhD MIT 2018',
159
+ 'NIH SBIR $2M 2023',
160
+ '',
161
+ '- Founded Acme in 2024',
162
+ '- Raised Seed round 2024',
163
+ '- Team of 6 engineers',
164
+ ].join('\n');
165
+ const t0 = Date.now();
166
+ const r = extractShallow(text, 'session-test-1');
167
+ const elapsed = Date.now() - t0;
168
+
169
+ // Result shape
170
+ assert.ok(r.user, 'expected user node, got ' + JSON.stringify(r.user));
171
+ assert.equal(r.user.canonical_role, 'Founder');
172
+ assert.ok(r.venture, 'expected venture node');
173
+ assert.equal(r.venture.name, 'Acme Robotics');
174
+ assert.ok(Array.isArray(r.claims));
175
+ assert.equal(r.claims.length, 3);
176
+
177
+ // Navigation calls: setFocus called exactly once for venture
178
+ assert.equal(navStub.__calls.setFocus.length, 1);
179
+ assert.equal(navStub.__calls.setFocus[0].sid, 'session-test-1');
180
+ assert.equal(navStub.__calls.setFocus[0].sb, 'auto-from-upload');
181
+
182
+ // Navigation calls: 5 node_created memory events (1 user + 1 venture + 3 claims)
183
+ assert.equal(navStub.__calls.memoryEvents.length, 5,
184
+ 'expected 5 memory events, got ' + navStub.__calls.memoryEvents.length);
185
+ for (const ev of navStub.__calls.memoryEvents) {
186
+ assert.equal(ev.type, 'node_created');
187
+ assert.equal(ev.sid, 'session-test-1');
188
+ }
189
+
190
+ // Performance budget (sanity)
191
+ assert.ok(elapsed < 100, 'extractShallow took ' + elapsed + 'ms, expected < 100');
192
+ });
193
+
194
+ // ---------- extractShallow graceful degradation (ES-02) ----------
195
+
196
+ run('ES-02 garbage input -> 0 nodes, 0 memory events, no throw', () => {
197
+ navStub.__reset();
198
+ const r = extractShallow('asdfqwerty 123 !@#$%^&*()_+', 'session-test-garbage');
199
+ assert.equal(r.user, null);
200
+ assert.equal(r.venture, null);
201
+ assert.deepEqual(r.claims, []);
202
+ assert.equal(navStub.__calls.setFocus.length, 0);
203
+ assert.equal(navStub.__calls.memoryEvents.length, 0);
204
+ });
205
+
206
+ run('ES-null missing sessionId -> empty result, no navigation calls', () => {
207
+ navStub.__reset();
208
+ const r = extractShallow('Founder of Acme Robotics', '');
209
+ assert.equal(r.user, null);
210
+ assert.equal(r.venture, null);
211
+ assert.deepEqual(r.claims, []);
212
+ assert.equal(navStub.__calls.setFocus.length, 0);
213
+ });
214
+
215
+ run('ES-null2 null text -> empty result', () => {
216
+ navStub.__reset();
217
+ const r = extractShallow(null, 'session-x');
218
+ assert.equal(r.user, null);
219
+ assert.equal(r.venture, null);
220
+ assert.deepEqual(r.claims, []);
221
+ });
222
+
223
+ // ---------- Summary ----------
224
+
225
+ process.stdout.write('\nshallow-doc-parser: ' + passed + '/' + (passed + failed) + ' passed, ' + failed + ' failed\n');
226
+ process.exit(failed === 0 ? 0 : 1);
@@ -0,0 +1,284 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /*
5
+ * Copyright (c) 2026 Mindrian. BSL 1.1.
6
+ *
7
+ * Phase 91-03 -- Skill Activation Router (precedence layer over legacy
8
+ * file-state + env activation)
9
+ * =====================================================================
10
+ * Composes navigation-engine.decide() output with the pre-91 (legacy)
11
+ * skill activation set into a single declarative activation decision
12
+ * that the UserPromptSubmit hook embeds into additionalContext.
13
+ *
14
+ * Routing precedence (Canon Part 3 + Canon Part 7):
15
+ *
16
+ * 1. engine.fire_skill is set AND validates as canonical verb
17
+ * -> source = 'engine'
18
+ * -> activated_skills = [canonical-cased verb]
19
+ * -> suppressed_skills = engine.suppress_skills minus the fired verb
20
+ * -> reason = 'engine_fire_skill_set'
21
+ *
22
+ * 2. engine.fire_skill is null/invalid AND engine.suppress_skills
23
+ * is non-empty
24
+ * -> source = 'mixed'
25
+ * -> activated_skills = legacyActivation minus suppress_skills
26
+ * -> suppressed_skills = intersection(legacyActivation, suppress_skills)
27
+ * -> reason = 'engine_suppress_with_legacy'
28
+ *
29
+ * 3. engine is null OR engine.fire_skill is null AND
30
+ * engine.suppress_skills is empty
31
+ * -> source = 'legacy'
32
+ * -> activated_skills = legacyActivation (unchanged)
33
+ * -> suppressed_skills = []
34
+ * -> reason = 'engine_silent_or_absent'
35
+ *
36
+ * Canon Part 3 (closed 10-verb vocabulary):
37
+ * The CANONICAL_VERBS array in lib/core/navigation-engine-shared.cjs is
38
+ * the single source of truth. Engine outputs MUST map to one of the 10
39
+ * verbs. Unknown verbs are rejected with a 'canon_part_3_unknown_verb_
40
+ * rejected' trace note and the router falls through to legacy or mixed
41
+ * depending on whether suppress_skills is also populated. New verbs
42
+ * require a canon amendment, NOT a runtime addition.
43
+ *
44
+ * Canon Part 7 (Reuse Before Build):
45
+ * Legacy file-state + env activation is preserved. This module is a
46
+ * precedence layer on top, NOT a replacement. When engine returns
47
+ * { fire_skill: null, suppress_skills: [] } (the silent path), output
48
+ * is byte-equivalent to pre-91 behavior.
49
+ *
50
+ * Canon Part 8 (Graph Boundary):
51
+ * Pure local. Zero I/O. Zero network. Zero Brain reads. The router
52
+ * never queries Brain, never embeds user content in any payload. It
53
+ * composes two pre-computed inputs into a declarative output.
54
+ *
55
+ * Purity:
56
+ * - No fs require (verified by Test 28-style audit; this module is
57
+ * pure-function except the require of navigation-engine-shared for
58
+ * CANONICAL_VERBS).
59
+ * - No I/O.
60
+ * - Never throws on null/non-array inputs (defensive coercion).
61
+ *
62
+ * License: BSL 1.1.
63
+ */
64
+
65
+ const shared = require('./navigation-engine-shared.cjs');
66
+
67
+ const CANONICAL_VERBS = shared.CANONICAL_VERBS;
68
+
69
+ // ---------- Pure helpers ----------
70
+
71
+ /**
72
+ * validateVerb(verb) -> boolean
73
+ *
74
+ * Returns true if verb maps (case-insensitive) to a CANONICAL_VERBS
75
+ * entry per Canon Part 3. Returns false on null, non-string, empty
76
+ * string, or unknown verb. The router uses this gate to enforce the
77
+ * closed-vocabulary boundary on engine outputs.
78
+ */
79
+ function validateVerb(verb) {
80
+ if (verb === null || verb === undefined) return false;
81
+ if (typeof verb !== 'string') return false;
82
+ if (verb.length === 0) return false;
83
+ const lc = verb.toLowerCase();
84
+ for (let i = 0; i < CANONICAL_VERBS.length; i += 1) {
85
+ if (CANONICAL_VERBS[i].toLowerCase() === lc) return true;
86
+ }
87
+ return false;
88
+ }
89
+
90
+ /**
91
+ * canonicalizeVerb(verb) -> string|null
92
+ *
93
+ * Returns the canonical-cased entry from CANONICAL_VERBS that matches
94
+ * verb case-insensitively. Returns null when verb is not a canonical
95
+ * verb. The router calls this to normalize user/engine-supplied casing
96
+ * to the canonical form before emission (Test 12).
97
+ */
98
+ function canonicalizeVerb(verb) {
99
+ if (verb === null || verb === undefined) return null;
100
+ if (typeof verb !== 'string') return null;
101
+ const lc = verb.toLowerCase();
102
+ for (let i = 0; i < CANONICAL_VERBS.length; i += 1) {
103
+ if (CANONICAL_VERBS[i].toLowerCase() === lc) return CANONICAL_VERBS[i];
104
+ }
105
+ return null;
106
+ }
107
+
108
+ /**
109
+ * coerceArray(maybeArray) -> Array
110
+ *
111
+ * Defensive coercion. Returns the input when it is an array; returns
112
+ * [] for any other shape (null, undefined, string, object, number).
113
+ * Used for both engine.suppress_skills and legacyActivation inputs.
114
+ */
115
+ function coerceArray(maybeArray) {
116
+ if (Array.isArray(maybeArray)) return maybeArray;
117
+ return [];
118
+ }
119
+
120
+ /**
121
+ * intersection(a, b) -> Array
122
+ *
123
+ * Returns elements appearing in both a and b. Preserves a's order.
124
+ * Used to compute suppressed_skills (legacy ∩ engine.suppress_skills)
125
+ * in mixed mode.
126
+ */
127
+ function intersection(a, b) {
128
+ const aArr = coerceArray(a);
129
+ const bArr = coerceArray(b);
130
+ if (aArr.length === 0 || bArr.length === 0) return [];
131
+ const bSet = new Set(bArr);
132
+ const out = [];
133
+ for (let i = 0; i < aArr.length; i += 1) {
134
+ if (bSet.has(aArr[i])) out.push(aArr[i]);
135
+ }
136
+ return out;
137
+ }
138
+
139
+ /**
140
+ * difference(a, b) -> Array
141
+ *
142
+ * Returns elements of a not present in b. Preserves a's order. Used to
143
+ * compute activated_skills (legacy minus engine.suppress_skills) in
144
+ * mixed mode and to drop a fired-verb from suppress_skills in the
145
+ * contradictory-decision case.
146
+ */
147
+ function difference(a, b) {
148
+ const aArr = coerceArray(a);
149
+ const bArr = coerceArray(b);
150
+ if (bArr.length === 0) return aArr.slice();
151
+ const bSet = new Set(bArr);
152
+ const out = [];
153
+ for (let i = 0; i < aArr.length; i += 1) {
154
+ if (!bSet.has(aArr[i])) out.push(aArr[i]);
155
+ }
156
+ return out;
157
+ }
158
+
159
+ // ---------- Main entry ----------
160
+
161
+ /**
162
+ * routeActivation(engineDecision, legacyActivation) -> {
163
+ * activated_skills: string[],
164
+ * suppressed_skills: string[],
165
+ * source: 'engine' | 'legacy' | 'mixed',
166
+ * reason: string,
167
+ * trace_notes: string[]
168
+ * }
169
+ *
170
+ * Composes engine decision with legacy activation set. See the
171
+ * routing-precedence comment block at the top of this file for the
172
+ * three precedence rules.
173
+ *
174
+ * Pure function. Defensive on inputs (null, non-array, missing fields
175
+ * all coerce to safe defaults; never throws).
176
+ *
177
+ * Inputs:
178
+ * engineDecision: typed decision from navigation-engine.decide(), OR
179
+ * null when the engine timed out / errored / was not
180
+ * invoked. May be a partial object; missing fields
181
+ * coerce to safe defaults.
182
+ * legacyActivation: string[] of skill names that the pre-91
183
+ * (file-state + env) activation logic determined
184
+ * would fire this turn. May be null, non-array,
185
+ * or empty.
186
+ *
187
+ * Outputs (always a fresh object; never returns input references):
188
+ * activated_skills: ordered list of skill names that should fire.
189
+ * suppressed_skills: ordered list of skill names that should NOT fire
190
+ * this turn (informational; consumer Larry uses
191
+ * this to know which legacy activations were
192
+ * vetoed).
193
+ * source: 'engine' | 'legacy' | 'mixed' (which path won).
194
+ * reason: short symbolic reason code.
195
+ * trace_notes: optional symbolic notes (Canon Part 3 verb rejections,
196
+ * contradictory decisions resolved, etc) consumed by
197
+ * /mos:explain-decision.
198
+ */
199
+ function routeActivation(engineDecision, legacyActivation) {
200
+ const traceNotes = [];
201
+
202
+ // ---- Defensive input coercion ----
203
+ // Capture whether both inputs were nullish so we can flag null_inputs.
204
+ const bothNull =
205
+ (engineDecision === null || engineDecision === undefined) &&
206
+ (legacyActivation === null || legacyActivation === undefined);
207
+
208
+ // legacy is always an array internally; non-array shapes coerce to [].
209
+ const legacy = coerceArray(legacyActivation);
210
+
211
+ // engine fields read defensively. Missing engine -> treated as silent.
212
+ let fireSkillRaw = null;
213
+ let suppress = [];
214
+ if (engineDecision !== null && typeof engineDecision === 'object') {
215
+ if (engineDecision.fire_skill !== undefined) {
216
+ fireSkillRaw = engineDecision.fire_skill;
217
+ }
218
+ if (Array.isArray(engineDecision.suppress_skills)) {
219
+ suppress = engineDecision.suppress_skills.slice();
220
+ }
221
+ }
222
+
223
+ // ---- Precedence Rule 1: engine.fire_skill set + canonical verb ----
224
+ if (fireSkillRaw !== null && fireSkillRaw !== undefined && fireSkillRaw !== '') {
225
+ if (validateVerb(fireSkillRaw)) {
226
+ const canonical = canonicalizeVerb(fireSkillRaw);
227
+ // Resolve contradictory fire-vs-suppress: drop the fired verb
228
+ // from the suppress list so the output is internally consistent.
229
+ let resolvedSuppress = suppress;
230
+ const lcCanonical = canonical.toLowerCase();
231
+ const hadOverlap = suppress.some(function (s) {
232
+ return typeof s === 'string' && s.toLowerCase() === lcCanonical;
233
+ });
234
+ if (hadOverlap) {
235
+ resolvedSuppress = suppress.filter(function (s) {
236
+ return !(typeof s === 'string' && s.toLowerCase() === lcCanonical);
237
+ });
238
+ traceNotes.push('engine_contradictory_fire_vs_suppress_resolved');
239
+ }
240
+ return {
241
+ activated_skills: [canonical],
242
+ suppressed_skills: resolvedSuppress,
243
+ source: 'engine',
244
+ reason: 'engine_fire_skill_set',
245
+ trace_notes: traceNotes,
246
+ };
247
+ }
248
+ // Unknown / non-canonical verb. Reject with trace note and fall
249
+ // through to suppress-only (mixed) or legacy.
250
+ traceNotes.push('canon_part_3_unknown_verb_rejected');
251
+ }
252
+
253
+ // ---- Precedence Rule 2: engine silent on fire, but suppresses ----
254
+ if (suppress.length > 0) {
255
+ const activated = difference(legacy, suppress);
256
+ const suppressed = intersection(legacy, suppress);
257
+ return {
258
+ activated_skills: activated,
259
+ suppressed_skills: suppressed,
260
+ source: 'mixed',
261
+ reason: 'engine_suppress_with_legacy',
262
+ trace_notes: traceNotes,
263
+ };
264
+ }
265
+
266
+ // ---- Precedence Rule 3: full legacy fallback ----
267
+ return {
268
+ activated_skills: legacy.slice(),
269
+ suppressed_skills: [],
270
+ source: 'legacy',
271
+ reason: bothNull ? 'null_inputs' : 'engine_silent_or_absent',
272
+ trace_notes: traceNotes,
273
+ };
274
+ }
275
+
276
+ module.exports = {
277
+ routeActivation: routeActivation,
278
+ validateVerb: validateVerb,
279
+ canonicalizeVerb: canonicalizeVerb,
280
+ // Internal helpers exposed for test introspection only.
281
+ _intersection: intersection,
282
+ _difference: difference,
283
+ _coerceArray: coerceArray,
284
+ };
@@ -0,0 +1,46 @@
1
+ /**
2
+ * MindrianOS Plugin — State Operations
3
+ * Wraps existing Bash scripts via execSync. Does NOT rewrite Bash logic.
4
+ * Pure Node.js built-ins only.
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const { execSync } = require('child_process');
10
+ const path = require('path');
11
+ const { safeReadFile } = require('./index.cjs');
12
+
13
+ const SCRIPTS_DIR = path.resolve(__dirname, '../../scripts');
14
+
15
+ /**
16
+ * Run compute-state script against a room directory.
17
+ * Returns raw stdout as string.
18
+ * @param {string} roomDir - Path to room directory
19
+ * @returns {string} Raw script output
20
+ */
21
+ function computeState(roomDir) {
22
+ const resolved = path.resolve(roomDir);
23
+ const scriptPath = path.join(SCRIPTS_DIR, 'compute-state');
24
+ try {
25
+ const result = execSync(`bash "${scriptPath}" "${resolved}"`, {
26
+ timeout: 10000,
27
+ encoding: 'utf-8',
28
+ stdio: ['pipe', 'pipe', 'pipe'],
29
+ });
30
+ return result;
31
+ } catch (e) {
32
+ throw new Error(`compute-state failed: ${e.message}`);
33
+ }
34
+ }
35
+
36
+ /**
37
+ * Read the room's STATE.md file directly.
38
+ * @param {string} roomDir - Path to room directory
39
+ * @returns {string|null} STATE.md contents or null if not found
40
+ */
41
+ function getState(roomDir) {
42
+ const resolved = path.resolve(roomDir);
43
+ return safeReadFile(path.join(resolved, 'STATE.md'));
44
+ }
45
+
46
+ module.exports = { computeState, getState };