@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,416 @@
1
+ /*
2
+ * Copyright (c) 2026 Mindrian. BSL 1.1.
3
+ *
4
+ * Phase 88-01 -- folder-memory SYNC entry point
5
+ * ==============================================
6
+ * The ONE and ONLY read contract for the per-folder memory triple
7
+ * (ROOM.md + STATE.md + MINTO.md). Every skill, hook, statusline
8
+ * segment, session-start injection, guardian, and the Navigation Engine
9
+ * (Phase 91) consume the triple through `readTriple(sectionPath)`.
10
+ *
11
+ * The contract and field shape are documented in
12
+ * .planning/phases/88-feynman-minto-memory-layer/88-CONTEXT.md
13
+ * lines 99-132
14
+ * and in the PLAN <interfaces> block for plan 88-01. Any change to the
15
+ * returned shape is a cross-plan breaking change (88-06, 88-07, 88-08,
16
+ * 88-09, 88-10, 88-13 all consume it).
17
+ *
18
+ * Sync entry point: used by CLI hook scripts (session-start, on-stop,
19
+ * post-write, pre/post-compact), statusline segments, guardian, and the
20
+ * pre-commit gate. Mirror async twin at lib/core/folder-memory-async.cjs
21
+ * keeps key-set parity for MCP/Desktop callers.
22
+ *
23
+ * Pure CJS, node built-ins only, zero npm deps. Three-surface compatible
24
+ * by construction (CLI + Desktop MCP + Cowork).
25
+ *
26
+ * API:
27
+ * readTriple(sectionPath) -> {room, state, reasoning}
28
+ * readDecisionLog(sectionPath) -> decision_log array
29
+ * readQuadruple(sectionPath) -> {room, state, reasoning, brain}
30
+ * isQuadrupleFresh(quadruple) -> boolean
31
+ * computeHealthScore(reasoning) -> number in [0,1] (re-export)
32
+ * getCurrentRoom([workDir]) -> {slug, path, source} | null (Phase 94-01)
33
+ *
34
+ * License: BSL 1.1.
35
+ */
36
+
37
+ 'use strict';
38
+
39
+ const fs = require('node:fs');
40
+ const path = require('node:path');
41
+ const shared = require('./folder-memory-shared.cjs');
42
+ const invariants = require('./feynman-minto-invariants.cjs');
43
+
44
+ const RESERVED = new Set(['ROOM.md', 'STATE.md', 'MINTO.md', 'TEAM-STATE.md']);
45
+
46
+ function safeStatSync(p) {
47
+ try {
48
+ return fs.statSync(p);
49
+ } catch (_e) {
50
+ return null;
51
+ }
52
+ }
53
+
54
+ function safeReadSync(p) {
55
+ try {
56
+ return fs.readFileSync(p, 'utf8');
57
+ } catch (_e) {
58
+ return null;
59
+ }
60
+ }
61
+
62
+ function collectArtifactMtimes(sectionPath) {
63
+ const mtimes = [];
64
+ let entries = [];
65
+ try {
66
+ entries = fs.readdirSync(sectionPath);
67
+ } catch (_e) {
68
+ return mtimes;
69
+ }
70
+ for (const name of entries) {
71
+ if (name[0] === '.') continue;
72
+ if (RESERVED.has(name)) continue;
73
+ const abs = path.join(sectionPath, name);
74
+ const st = safeStatSync(abs);
75
+ if (!st) continue;
76
+ if (st.isFile() && name.endsWith('.md')) {
77
+ mtimes.push(st.mtimeMs);
78
+ }
79
+ }
80
+ return mtimes;
81
+ }
82
+
83
+ /**
84
+ * readTriple(sectionPath) -> {room, state, reasoning}
85
+ *
86
+ * Never throws. Missing files degrade gracefully (exists:false).
87
+ * Invariant violations (critical) downgrade reasoning to stale but do
88
+ * not zero its fields -- best-effort parse continues so consumers see
89
+ * as much context as possible.
90
+ */
91
+ function readTriple(sectionPath) {
92
+ const room = { ...shared.emptyRoom() };
93
+ const state = { ...shared.emptyState() };
94
+ const reasoning = { ...shared.emptyReasoning() };
95
+
96
+ // Sentinel: if the section path itself doesn't exist, return the
97
+ // all-empty shell. This is the graceful-degradation contract (Test 9).
98
+ const sectionStat = safeStatSync(sectionPath);
99
+ if (!sectionStat || !sectionStat.isDirectory()) {
100
+ reasoning.reasoning_health_score = shared.computeHealthScore(reasoning);
101
+ return { room: room, state: state, reasoning: reasoning };
102
+ }
103
+
104
+ // ---- ROOM.md ----
105
+ const roomPath = path.join(sectionPath, 'ROOM.md');
106
+ const roomStat = safeStatSync(roomPath);
107
+ if (roomStat && roomStat.isFile()) {
108
+ const roomBuf = safeReadSync(roomPath);
109
+ if (roomBuf !== null) {
110
+ Object.assign(room, shared.parseRoomMd(roomBuf, roomStat.mtimeMs));
111
+ }
112
+ }
113
+
114
+ // ---- STATE.md ----
115
+ const statePath = path.join(sectionPath, 'STATE.md');
116
+ const stateStat = safeStatSync(statePath);
117
+ if (stateStat && stateStat.isFile()) {
118
+ const stateBuf = safeReadSync(statePath);
119
+ if (stateBuf !== null) {
120
+ Object.assign(state, shared.parseStateMd(stateBuf));
121
+ }
122
+ }
123
+
124
+ // ---- MINTO.md ----
125
+ const mintoPath = path.join(sectionPath, 'MINTO.md');
126
+ const mintoStat = safeStatSync(mintoPath);
127
+ if (mintoStat && mintoStat.isFile()) {
128
+ const mintoBuf = safeReadSync(mintoPath);
129
+ if (mintoBuf !== null) {
130
+ const parsed = shared.parseMintoMd(mintoBuf);
131
+ Object.assign(reasoning, parsed);
132
+ reasoning.exists = true;
133
+
134
+ // Ask the invariants validator for its verdict. Critical violations
135
+ // downgrade stale_reason to 'invariant_violation' so every downstream
136
+ // consumer agrees. Best-effort parse is preserved; we do NOT zero
137
+ // governing_thought or decision_log on invariant failure.
138
+ let invariantSeverity = null;
139
+ try {
140
+ const v = invariants.validate(mintoPath);
141
+ invariantSeverity = v.severity;
142
+ } catch (_e) {
143
+ // Validator is defensive; treat unexpected failure as warning-level
144
+ invariantSeverity = null;
145
+ }
146
+
147
+ const artifactMtimes = collectArtifactMtimes(sectionPath);
148
+ const stale = shared.computeStale(
149
+ reasoning,
150
+ artifactMtimes,
151
+ mintoStat.mtimeMs,
152
+ invariantSeverity
153
+ );
154
+ reasoning.is_stale = stale.is_stale;
155
+ reasoning.stale_reason = stale.stale_reason;
156
+ }
157
+ }
158
+ // If reasoning.exists is still false (no MINTO.md), the default
159
+ // emptyReasoning() shell already carries is_stale:true,
160
+ // stale_reason:'never_generated' which matches the contract.
161
+
162
+ // Compute reasoning_health_score deterministically from the parsed
163
+ // reasoning fields + freshness outcome.
164
+ reasoning.reasoning_health_score = shared.computeHealthScore(reasoning);
165
+
166
+ return { room: room, state: state, reasoning: reasoning };
167
+ }
168
+
169
+ /**
170
+ * readDecisionLog(sectionPath) -> Array of decision_log entries.
171
+ *
172
+ * Read-optimized for 88-09 consumer (post-compact re-injection). Same
173
+ * permissive shape as readTriple().reasoning.decision_log: returns ALL
174
+ * entries in write order (oldest first), no cap enforcement on the
175
+ * read side (guardian is strict; read is permissive).
176
+ */
177
+ function readDecisionLog(sectionPath) {
178
+ const mintoPath = path.join(sectionPath, 'MINTO.md');
179
+ const buf = safeReadSync(mintoPath);
180
+ if (buf === null) return [];
181
+ const parsed = shared.parseMintoMd(buf);
182
+ return Array.isArray(parsed.decision_log) ? parsed.decision_log : [];
183
+ }
184
+
185
+ // ---------- Phase 90-04 readQuadruple (additive extension) ----------
186
+ //
187
+ // readQuadruple composes on top of readTriple. readTriple semantics are
188
+ // preserved byte-for-byte; readQuadruple simply adds a fourth field
189
+ // named "brain" that is either null (BRAIN.md absent) or a structured
190
+ // object parsed from BRAIN.md.
191
+ //
192
+ // Canon Part 8 (Graph Boundary): readQuadruple is a LOCAL read. No
193
+ // Brain MCP call is made here. The BRAIN.md file was written locally
194
+ // by Plan 90-01 deriveSection (which is the module that DOES call
195
+ // Brain, under chokepoint buildBrainQueryContext). Consumers
196
+ // downstream of readQuadruple are responsible for not sending brain
197
+ // content back into Brain query payloads.
198
+
199
+ /**
200
+ * readQuadruple(sectionPath) -> {room, state, reasoning, brain}
201
+ *
202
+ * Additive extension of readTriple. Brain field:
203
+ * - null when BRAIN.md is absent
204
+ * - struct with parse_failed:true when BRAIN.md is present but
205
+ * unparseable (malformed frontmatter, empty file, I/O error)
206
+ * - full struct when BRAIN.md parses cleanly
207
+ *
208
+ * Never throws. Phase 88-01 readTriple signature/return unchanged.
209
+ */
210
+ function readQuadruple(sectionPath) {
211
+ const triple = readTriple(sectionPath);
212
+ const brainPath = path.join(sectionPath, 'BRAIN.md');
213
+ const brain = shared.parseBrainMd(brainPath);
214
+ return shared.attachBrainToTriple(triple, brain);
215
+ }
216
+
217
+ /**
218
+ * isQuadrupleFresh(quadruple) -> boolean
219
+ *
220
+ * Returns true iff:
221
+ * (a) reasoning.is_stale === false, AND
222
+ * (b) brain is null OR brain.staleness === 'fresh' OR
223
+ * brain.stale_reason === 'brain_offline'
224
+ *
225
+ * Rationale: brain-offline is a transient network condition, not a
226
+ * derivation-staleness signal. A quadruple whose BRAIN.md is stale
227
+ * because Brain is temporarily unreachable is still "fresh enough" for
228
+ * consumers that don't require the brain signal. A brain that is stale
229
+ * for ANY other reason (governing_thought_changed, age_exceeded,
230
+ * brain_graph_version_mismatch, derivation_timeout) marks the
231
+ * quadruple as not-fresh.
232
+ *
233
+ * Pure function -- no I/O, no exceptions.
234
+ */
235
+ function isQuadrupleFresh(quadruple) {
236
+ if (!quadruple || typeof quadruple !== 'object') return false;
237
+ const reasoning = quadruple.reasoning;
238
+ if (!reasoning || reasoning.is_stale !== false) return false;
239
+ const brain = quadruple.brain;
240
+ if (brain === null || brain === undefined) return true;
241
+ if (brain.staleness === 'fresh') return true;
242
+ if (brain.stale_reason === 'brain_offline') return true;
243
+ return false;
244
+ }
245
+
246
+ // ---------- Phase 94-01 getCurrentRoom (statusline canonical read) ----------
247
+ //
248
+ // Lawrence Aronhime hit the v1.11.0 bug "look at the bottom. It still says
249
+ // core power" four times in 38 minutes because scripts/context-monitor was
250
+ // deriving the room name from a stale source. This function anchors the
251
+ // canonical contract: STATE.md frontmatter current_room is the source of
252
+ // truth; statusline is a derived read-only view.
253
+ //
254
+ // Canon Part 7 (Reuse Before Build): composes resolveRoom() from room-ops-
255
+ // shared and reuses the same minimal frontmatter sniff readTriple already
256
+ // uses (no new YAML lib). Canon Part 4: read-only function, never writes.
257
+ // Canon Part 8: pure local; never queries Brain.
258
+
259
+ /**
260
+ * Resolve the canonical STATE.md path for the active room.
261
+ *
262
+ * Resolution order (first match wins):
263
+ * 1. <workDir>/.rooms/registry.json -> active room's STATE.md
264
+ * 2. <workDir>/room/STATE.md (legacy default room)
265
+ * 3. <workDir>/STATE.md (workDir IS the room)
266
+ *
267
+ * Returns absolute path string or null. Pure I/O probes; never throws.
268
+ *
269
+ * @param {string} workDir
270
+ * @returns {string|null}
271
+ */
272
+ function resolveCanonicalStateMd(workDir) {
273
+ let resolved;
274
+ try {
275
+ resolved = path.resolve(workDir);
276
+ } catch (_e) {
277
+ return null;
278
+ }
279
+
280
+ // Strategy 1: registry-driven active room.
281
+ const registryPath = path.join(resolved, '.rooms', 'registry.json');
282
+ const regStat = safeStatSync(registryPath);
283
+ if (regStat && regStat.isFile()) {
284
+ const regBuf = safeReadSync(registryPath);
285
+ if (regBuf !== null) {
286
+ try {
287
+ const reg = JSON.parse(regBuf);
288
+ if (reg && reg.active && reg.rooms && reg.rooms[reg.active]) {
289
+ const roomDir = path.resolve(resolved, reg.rooms[reg.active].path);
290
+ const candidate = path.join(roomDir, 'STATE.md');
291
+ const st = safeStatSync(candidate);
292
+ if (st && st.isFile()) return candidate;
293
+ }
294
+ } catch (_e) { /* fall through */ }
295
+ }
296
+ }
297
+
298
+ // Strategy 2: legacy room/ dir.
299
+ const legacy = path.join(resolved, 'room', 'STATE.md');
300
+ const legacyStat = safeStatSync(legacy);
301
+ if (legacyStat && legacyStat.isFile()) return legacy;
302
+
303
+ // Strategy 3: workDir IS a room.
304
+ const direct = path.join(resolved, 'STATE.md');
305
+ const directStat = safeStatSync(direct);
306
+ if (directStat && directStat.isFile()) return direct;
307
+
308
+ return null;
309
+ }
310
+
311
+ /**
312
+ * Extract the YAML frontmatter block from a markdown buffer, then walk
313
+ * its lines for the `current_room` key. Returns the parsed slug string
314
+ * or null on every failure mode (no frontmatter, malformed, key absent).
315
+ *
316
+ * Strips surrounding single/double quotes and whitespace from the value.
317
+ * Treats explicit `null` / empty string as absent.
318
+ *
319
+ * @param {string} buf
320
+ * @returns {string|null}
321
+ */
322
+ function parseCurrentRoomField(buf) {
323
+ if (typeof buf !== 'string' || buf.length === 0) return null;
324
+
325
+ // Frontmatter MUST open with --- on the very first line. This is a
326
+ // tighter sniff than parseStateMd does, but the canonical write surface
327
+ // (the /mos:rooms skill) emits clean frontmatter every time.
328
+ if (buf.indexOf('---') !== 0) return null;
329
+ if (buf.length < 4) return null;
330
+ if (buf[3] !== '\n' && buf[3] !== '\r') return null;
331
+
332
+ // Locate the closing ---.
333
+ const rest = buf.slice(buf.indexOf('\n') + 1);
334
+ const closeMatch = rest.match(/^---\s*$/m);
335
+ if (!closeMatch) return null;
336
+ const fmText = rest.slice(0, closeMatch.index);
337
+
338
+ // Walk frontmatter lines for current_room.
339
+ const lines = fmText.split(/\r?\n/);
340
+ for (const raw of lines) {
341
+ if (raw.length === 0) continue;
342
+ if (/^\s*#/.test(raw)) continue;
343
+ const m = raw.match(/^current_room\s*:\s*(.+?)\s*$/);
344
+ if (!m) continue;
345
+ let value = m[1].trim();
346
+ if (value.length === 0) return null;
347
+ if (value === 'null' || value === '~') return null;
348
+
349
+ // Strip surrounding quotes (single, double, or matched pairs).
350
+ if (
351
+ (value[0] === '"' && value[value.length - 1] === '"') ||
352
+ (value[0] === "'" && value[value.length - 1] === "'")
353
+ ) {
354
+ if (value.length >= 2) value = value.slice(1, -1).trim();
355
+ }
356
+ if (value.length === 0) return null;
357
+
358
+ // Reject obvious garbage that the YAML-malformed test produces. A
359
+ // valid slug is non-empty, non-whitespace, and does not contain
360
+ // unescaped colons (which would imply a nested structure we cannot
361
+ // honor without a real YAML parser).
362
+ if (value.indexOf(':') !== -1) return null;
363
+
364
+ return value;
365
+ }
366
+ return null;
367
+ }
368
+
369
+ /**
370
+ * getCurrentRoom([workDir]) -> {slug, path, source: 'state_md'} | null
371
+ *
372
+ * Reads the canonical active-room slug from STATE.md frontmatter
373
+ * `current_room` field. Resolution order matches resolveCanonicalStateMd.
374
+ * Pure read; never writes; never throws.
375
+ *
376
+ * Returns null when STATE.md is missing, lacks frontmatter, lacks the
377
+ * current_room field, or has malformed YAML. Consumers (scripts/context-
378
+ * monitor, /mos:status, etc) treat null as "fall back to git rev-parse"
379
+ * per Canon Part 3 Tier 0 graceful degradation.
380
+ *
381
+ * Phase 94-01 -- statusline canonical source. Lawrence reproducer fence.
382
+ *
383
+ * @param {string} [workDir] - workspace root (default process.cwd())
384
+ * @returns {{slug: string, path: string, source: 'state_md'} | null}
385
+ */
386
+ function getCurrentRoom(workDir) {
387
+ const root = workDir || process.cwd();
388
+ const statePath = resolveCanonicalStateMd(root);
389
+ if (!statePath) return null;
390
+
391
+ const buf = safeReadSync(statePath);
392
+ if (buf === null) return null;
393
+
394
+ let slug;
395
+ try {
396
+ slug = parseCurrentRoomField(buf);
397
+ } catch (_e) {
398
+ return null;
399
+ }
400
+ if (slug === null) return null;
401
+
402
+ return {
403
+ slug: slug,
404
+ path: statePath,
405
+ source: 'state_md',
406
+ };
407
+ }
408
+
409
+ module.exports = {
410
+ readTriple: readTriple,
411
+ readDecisionLog: readDecisionLog,
412
+ readQuadruple: readQuadruple,
413
+ isQuadrupleFresh: isQuadrupleFresh,
414
+ computeHealthScore: shared.computeHealthScore,
415
+ getCurrentRoom: getCurrentRoom,
416
+ };