@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,473 @@
1
+ /*
2
+ * Copyright (c) 2026 Mindrian. BSL 1.1.
3
+ *
4
+ * Phase 88-07 Task 1 -- TRIPLE_CONTEXT formatter
5
+ * ================================================
6
+ * Pure formatter for the TRIPLE_CONTEXT block that scripts/session-start
7
+ * injects into Claude's additionalContext. Consumed by scripts/session-start
8
+ * to render per-section triple memory (ROOM identity + STATE summary +
9
+ * MINTO reasoning) that survives session boundaries.
10
+ *
11
+ * Budget policy (grounded in measurement, not heuristic):
12
+ * - DEFAULT_BUDGET_TOKENS = 5000 (baseline session-start emission measured
13
+ * at ~3825 tokens on a 2-section fixture; 5000-token cap leaves room
14
+ * inside practical 40-50k aggregate session-start ceiling). See
15
+ * 88-07-SUMMARY.md for the measurement trace.
16
+ * - Env override: SESSION_START_BUDGET_TOKENS=N overrides the default
17
+ * at runtime. Must parse to a positive integer; falls back to default
18
+ * on garbage (non-numeric, zero, negative).
19
+ * - Truncation: sort sections by reasoning_health_score ASCENDING (weakest
20
+ * first = most-informative-first). Null scores sort BEFORE any numeric
21
+ * score (treated as weakest). Emit until budget consumed; append
22
+ * "[+N strongest sections elided for budget]" footer.
23
+ *
24
+ * Decision log policy:
25
+ * - Render latest 3 entries per section. If more, append "[+N older]".
26
+ * - Empty decision_log -> "Decision log:" header omitted entirely.
27
+ *
28
+ * References policy:
29
+ * - <= 5 refs -> render all as space-separated wikilinks.
30
+ * - > 5 refs -> first 5 + "[+N more]".
31
+ *
32
+ * Staleness:
33
+ * - is_stale:true -> State line carries "(stale: <stale_reason>)" suffix.
34
+ *
35
+ * Pending-tier-1 footer:
36
+ * - pendingTier1 array with entries -> soft footer with count + /mos:reason
37
+ * hint.
38
+ *
39
+ * Stale-report footer:
40
+ * - staleReport array with entries -> soft footer listing sections + reasons.
41
+ *
42
+ * Zero sections -> returns empty string so session-start falls through to
43
+ * existing behavior without emitting an empty block.
44
+ *
45
+ * Pure logic: zero fs imports, zero child_process, zero node:url. Surface-
46
+ * agnostic by construction (CLI + Desktop MCP + Cowork).
47
+ *
48
+ * Exports:
49
+ * module.exports = {
50
+ * formatTripleContext({ sections, pendingTier1?, staleReport? }) -> string,
51
+ * estimateTokens(str) -> number,
52
+ * getBudgetTokens() -> number,
53
+ * DEFAULT_BUDGET_TOKENS: 5000
54
+ * };
55
+ *
56
+ * License: BSL 1.1.
57
+ */
58
+
59
+ 'use strict';
60
+
61
+ // ---------- Constants ----------
62
+
63
+ // Default budget (grounded in measurement; see 88-07-SUMMARY.md).
64
+ // Baseline session-start emission measured at ~3825 tokens on a
65
+ // 2-section fixture; 5000-token cap for TRIPLE_CONTEXT leaves room inside
66
+ // the practical 40-50k aggregate session-start ceiling.
67
+ const DEFAULT_BUDGET_TOKENS = 5000;
68
+
69
+ // Decision-log rendering cap per section.
70
+ const DECISION_LOG_RECENT = 3;
71
+
72
+ // Reference-rendering cap per section.
73
+ const REFS_RENDER_CAP = 5;
74
+
75
+ // Reserve ~200 tokens for header + elision footer + safety slack so the
76
+ // per-section accumulation cannot nudge the total over the cap when the
77
+ // footer is appended last.
78
+ const FOOTER_RESERVE_TOKENS = 200;
79
+
80
+ // ---------- classifyHealth helper (88.1-03: systemMessage retrofit) ----------
81
+ //
82
+ // Canon Part 2 glyph vocabulary: check / warn / low / --. Extracted so both
83
+ // the TRIPLE_CONTEXT formatter (existing inline consumer) and the 88.1-03
84
+ // hook systemMessage emission (new consumer) and the 88.1-04 statusline
85
+ // (future consumer) share a single classifier. Byte-identity with the prior
86
+ // inline implementation is preserved: same thresholds (>=0.7 -> check,
87
+ // >=0.4 -> warn, else low), same missing-data fallback (--).
88
+ //
89
+ // Signature: classifyHealth(score: number | null | undefined)
90
+ // -> 'check' | 'warn' | 'low' | '--'
91
+ //
92
+ // - Finite number >= 0.7 -> 'check'
93
+ // - Finite number >= 0.4 -> 'warn'
94
+ // - Finite number < 0.4 -> 'low'
95
+ // - null | undefined | NaN | non-number -> '--'
96
+ function classifyHealth(score) {
97
+ if (typeof score !== 'number' || !Number.isFinite(score)) return '--';
98
+ if (score >= 0.7) return 'check';
99
+ if (score >= 0.4) return 'warn';
100
+ return 'low';
101
+ }
102
+
103
+ // ---------- Token estimation ----------
104
+
105
+ function estimateTokens(str) {
106
+ if (!str) return 0;
107
+ const s = typeof str === 'string' ? str : String(str);
108
+ return Math.ceil(s.length / 4);
109
+ }
110
+
111
+ // ---------- Budget resolution (env override) ----------
112
+
113
+ function getBudgetTokens() {
114
+ const raw = process.env.SESSION_START_BUDGET_TOKENS;
115
+ if (raw !== undefined && raw !== null && raw !== '') {
116
+ const n = parseInt(raw, 10);
117
+ // Must parse cleanly AND be positive. parseInt("abc")=NaN, parseInt("0")=0.
118
+ // We reject NaN, zero, negatives, and strings that don't represent the
119
+ // full value (e.g. "3abc" parses as 3 but the caller likely typo'd).
120
+ if (Number.isFinite(n) && n > 0 && String(n) === String(raw).trim()) {
121
+ return n;
122
+ }
123
+ }
124
+ return DEFAULT_BUDGET_TOKENS;
125
+ }
126
+
127
+ // ---------- Helpers ----------
128
+
129
+ /**
130
+ * Sort keys weakest-first. Null reasoning_health_score sorts FIRST
131
+ * (treated as highest-priority-to-surface). Ties broken by section name
132
+ * for deterministic output.
133
+ */
134
+ function sortKeysWeakestFirst(sections) {
135
+ const keys = Object.keys(sections || {});
136
+ return keys.sort((a, b) => {
137
+ const sa = sections[a] && sections[a].reasoning
138
+ ? sections[a].reasoning.reasoning_health_score
139
+ : undefined;
140
+ const sb = sections[b] && sections[b].reasoning
141
+ ? sections[b].reasoning.reasoning_health_score
142
+ : undefined;
143
+ // null / undefined -> -1 (weakest-most, sorted first)
144
+ const ka = (sa === null || sa === undefined) ? -1 : Number(sa);
145
+ const kb = (sb === null || sb === undefined) ? -1 : Number(sb);
146
+ if (ka !== kb) return ka - kb;
147
+ return a < b ? -1 : a > b ? 1 : 0;
148
+ });
149
+ }
150
+
151
+ function fmtRefs(refs) {
152
+ if (!Array.isArray(refs) || refs.length === 0) return '(none)';
153
+ const rendered = [];
154
+ const cap = REFS_RENDER_CAP;
155
+ const sliced = refs.slice(0, cap);
156
+ for (const r of sliced) {
157
+ if (!r || !r.target) continue;
158
+ const label = r.label && r.label !== r.target ? '|' + r.label : '';
159
+ rendered.push('[[' + r.target + label + ']]');
160
+ }
161
+ let s = rendered.join(' ');
162
+ const overflow = refs.length - cap;
163
+ if (overflow > 0) s += ' [+' + overflow + ' more]';
164
+ return s || '(none)';
165
+ }
166
+
167
+ function fmtDecision(d) {
168
+ if (!d || typeof d !== 'object') return '';
169
+ const ts = d.timestamp ? String(d.timestamp).slice(0, 10) : 'unknown';
170
+ const action = d.action || 'unknown';
171
+ const resp = d.user_response || 'unknown';
172
+ const reason = d.reason ? ' (reason: ' + String(d.reason) + ')' : '';
173
+ return '- ' + ts + ': ' + action + ' -> user ' + resp + reason;
174
+ }
175
+
176
+ function fmtStateLine(state, reasoning) {
177
+ const parts = [];
178
+ if (state && state.exists) {
179
+ const ac = Number(state.artifact_count) || 0;
180
+ parts.push(ac + ' artifact' + (ac === 1 ? '' : 's'));
181
+ if (typeof state.completeness_score === 'number') {
182
+ const pct = Math.round(state.completeness_score * 100);
183
+ parts.push(pct + '% complete');
184
+ }
185
+ if (state.last_activity_at) {
186
+ parts.push('last updated ' + String(state.last_activity_at).slice(0, 10));
187
+ }
188
+ } else {
189
+ parts.push('no STATE.md');
190
+ }
191
+
192
+ // Derive MINTO health glyph from reasoning_health_score via the shared
193
+ // classifyHealth helper (exported for Plan 88.1-04 statusline + Plan 88.1-03
194
+ // hook systemMessage retrofit; 88.1-03: systemMessage retrofit).
195
+ const health = classifyHealth(
196
+ reasoning && typeof reasoning.reasoning_health_score === 'number'
197
+ ? reasoning.reasoning_health_score
198
+ : null
199
+ );
200
+ let line = parts.join(', ') + ', MINTO health ' + health;
201
+
202
+ // Stale annotation
203
+ if (reasoning && reasoning.is_stale) {
204
+ const reason = reasoning.stale_reason || 'unknown';
205
+ line += ' (stale: ' + reason + ')';
206
+ }
207
+ return line;
208
+ }
209
+
210
+ function fmtReasoningBlock(reasoning) {
211
+ const lines = [];
212
+ if (!reasoning || !reasoning.exists) {
213
+ lines.push(' governing thought: (not yet generated)');
214
+ return lines.join('\n');
215
+ }
216
+ const gt = reasoning.governing_thought;
217
+ if (gt === null || gt === undefined || gt === '') {
218
+ lines.push(' governing thought: (not yet generated)');
219
+ } else {
220
+ lines.push(' governing thought: "' + String(gt) + '"');
221
+ }
222
+ const argc = Number(reasoning.arguments_count) || 0;
223
+ const mece = reasoning.mece_status || 'fail';
224
+ const score = typeof reasoning.reasoning_health_score === 'number'
225
+ ? reasoning.reasoning_health_score.toFixed(2)
226
+ : 'n/a';
227
+ lines.push(' arguments ' + argc + ', MECE ' + mece + ', reasoning health ' + score);
228
+ return lines.join('\n');
229
+ }
230
+
231
+ function fmtDecisionLog(decisionLog) {
232
+ if (!Array.isArray(decisionLog) || decisionLog.length === 0) return '';
233
+ const total = decisionLog.length;
234
+ // Latest N are the END of the array (write order, oldest-first per 88-01).
235
+ const recent = decisionLog.slice(Math.max(0, total - DECISION_LOG_RECENT));
236
+ const overflow = total - recent.length;
237
+ const lines = ['Decision log:'];
238
+ for (const d of recent) {
239
+ const line = fmtDecision(d);
240
+ if (line) lines.push(' ' + line);
241
+ }
242
+ if (overflow > 0) lines.push(' [+' + overflow + ' older]');
243
+ return lines.join('\n');
244
+ }
245
+
246
+ // ---------- Phase 90-03: Brain derivation annotation ----------
247
+ //
248
+ // Per-section staleness result emitted by lib/core/brain-md-staleness.cjs.
249
+ // Rendered as a single optional line after the Reasoning block. Shape:
250
+ // { exists, staleness, stale_reason, brain_generated_at, brain_graph_version,
251
+ // age_days, recommended_action }
252
+ //
253
+ // Render policy (per plan interfaces):
254
+ // fresh present -> "Brain derivation: fresh (2d ago, v1)"
255
+ // stale present + hash mismatch -> "Brain derivation: stale (governing_thought changed, regenerating)"
256
+ // stale present + age_exceeded -> "Brain derivation: stale (9d ago, pending regen)"
257
+ // stale present + version mismatch -> "Brain derivation: stale (graph version updated, regenerating)"
258
+ // stale present + parse_failed -> "Brain derivation: stale (parse failed, regenerating)"
259
+ // stale + recommended_action=enqueue_when_brain_online -> " ... pending Brain connection"
260
+ // absent + brain online -> "Brain derivation: absent"
261
+ // absent + brain offline -> "Brain derivation: absent (Brain offline)"
262
+ //
263
+ // Backward-compat: if the entire room has zero BRAIN.md files AND
264
+ // brain_offline_everywhere=true, Plan 90-03 caller should suppress the
265
+ // per-section line (scripts/session-start decides this at the payload
266
+ // level; formatter renders whatever brain field is attached).
267
+ function fmtBrainLine(brain) {
268
+ if (!brain || typeof brain !== 'object') return '';
269
+ const s = brain.staleness;
270
+ if (s === 'absent') {
271
+ const offline = brain.stale_reason === 'brain_offline';
272
+ return 'Brain derivation: absent' + (offline ? ' (Brain offline)' : '');
273
+ }
274
+ if (s === 'fresh') {
275
+ const parts = [];
276
+ if (typeof brain.age_days === 'number') {
277
+ const d = Math.max(0, Math.round(brain.age_days));
278
+ parts.push(d === 0 ? 'today' : d + 'd ago');
279
+ }
280
+ if (typeof brain.brain_graph_version === 'number') {
281
+ parts.push('v' + brain.brain_graph_version);
282
+ }
283
+ const detail = parts.length > 0 ? ' (' + parts.join(', ') + ')' : '';
284
+ return 'Brain derivation: fresh' + detail;
285
+ }
286
+ if (s === 'stale') {
287
+ const reason = brain.stale_reason || 'unknown';
288
+ let label;
289
+ if (reason === 'governing_thought_changed') label = 'governing_thought changed';
290
+ else if (reason === 'age_exceeded') {
291
+ const d = typeof brain.age_days === 'number' ? Math.round(brain.age_days) + 'd ago' : 'age exceeded';
292
+ label = d;
293
+ } else if (reason === 'brain_graph_version_mismatch') label = 'graph version updated';
294
+ else if (reason === 'parse_failed') label = 'parse failed';
295
+ else if (reason === 'brain_offline') label = 'Brain offline';
296
+ else label = String(reason);
297
+ const action = brain.recommended_action === 'enqueue_when_brain_online'
298
+ ? ' pending Brain connection'
299
+ : ' regenerating';
300
+ return 'Brain derivation: stale (' + label + ',' + action + ')';
301
+ }
302
+ return '';
303
+ }
304
+
305
+ /**
306
+ * Build per-section block. Returns string (possibly multi-line). Never
307
+ * throws on malformed inputs; degrades gracefully.
308
+ *
309
+ * Phase 90-03: accepts optional `triple.brain` field (result of
310
+ * lib/core/brain-md-staleness.cjs computeBrainStaleness). Rendered as a
311
+ * single 'Brain derivation: ...' line after the Reasoning block when
312
+ * present. Absent field -> line suppressed (backward-compat for rooms
313
+ * with zero BRAIN.md files / Brain offline forever).
314
+ */
315
+ function buildSectionBlock(name, triple) {
316
+ const t = triple || {};
317
+ const room = t.room || {};
318
+ const state = t.state || {};
319
+ const reasoning = t.reasoning || {};
320
+ const brain = t.brain || null;
321
+
322
+ const lines = [];
323
+ lines.push('### ' + name + '/');
324
+
325
+ // Identity line
326
+ const identity = room.exists && room.identity_text
327
+ ? String(room.identity_text).split('\n')[0].replace(/^#+\s*/, '').slice(0, 160)
328
+ : '(no ROOM.md)';
329
+ lines.push('Identity: ' + identity);
330
+
331
+ // References line
332
+ lines.push('References: ' + fmtRefs(room.references));
333
+
334
+ // State line
335
+ lines.push('State: ' + fmtStateLine(state, reasoning));
336
+
337
+ // Reasoning block (2 lines)
338
+ lines.push('Reasoning:');
339
+ lines.push(fmtReasoningBlock(reasoning));
340
+
341
+ // Phase 90-03: Brain derivation annotation (optional, per-section).
342
+ const brainLine = fmtBrainLine(brain);
343
+ if (brainLine) lines.push(brainLine);
344
+
345
+ // Decision log (conditional)
346
+ const dl = fmtDecisionLog(reasoning.decision_log);
347
+ if (dl) lines.push(dl);
348
+
349
+ return lines.join('\n');
350
+ }
351
+
352
+ // ---------- Footers ----------
353
+
354
+ function fmtPendingTier1Footer(pendingTier1) {
355
+ if (!Array.isArray(pendingTier1) || pendingTier1.length === 0) return '';
356
+ const n = pendingTier1.length;
357
+ return '> NOTE: ' + n + ' section' + (n === 1 ? '' : 's') +
358
+ ' have tier-0 MINTO pending tier-1 regen. Run /mos:reason --regenerate to upgrade reasoning narratives.';
359
+ }
360
+
361
+ function fmtStaleFooter(staleReport) {
362
+ if (!Array.isArray(staleReport) || staleReport.length === 0) return '';
363
+ const parts = staleReport.map(s => {
364
+ const sec = (s && s.section) ? s.section : 'unknown';
365
+ const reason = (s && s.reason) ? s.reason : 'unknown';
366
+ return sec + ' (' + reason + ')';
367
+ });
368
+ return '> NOTE: ' + parts.length + ' section' + (parts.length === 1 ? '' : 's') +
369
+ ' flagged stale: ' + parts.join(', ') + '.';
370
+ }
371
+
372
+ // ---------- Main formatter ----------
373
+
374
+ /**
375
+ * formatTripleContext({ sections, pendingTier1?, staleReport? }) -> string
376
+ *
377
+ * Sections map: { <sectionName>: <tripleObject> } (shape from folder-memory.readTriple).
378
+ * pendingTier1: optional array of { section }-shaped entries from
379
+ * .mindrian/pending-tier1-regen.json.
380
+ * staleReport: optional array of { section, reason }-shaped entries from
381
+ * .mindrian/minto-stale.json.
382
+ *
383
+ * Returns complete block string OR empty string if no sections to render.
384
+ * Guaranteed: estimateTokens(output) <= getBudgetTokens().
385
+ */
386
+ function formatTripleContext(opts) {
387
+ const o = opts || {};
388
+ const sections = (o.sections && typeof o.sections === 'object') ? o.sections : {};
389
+ const keys = sortKeysWeakestFirst(sections);
390
+
391
+ if (keys.length === 0) return '';
392
+
393
+ const budget = getBudgetTokens();
394
+ const header = '## ACTIVE ROOM MEMORY (per-section triple)';
395
+
396
+ // Build all section blocks up front so we can pack into budget.
397
+ const built = [];
398
+ for (const k of keys) {
399
+ const block = buildSectionBlock(k, sections[k]);
400
+ built.push({ name: k, block: block, tokens: estimateTokens(block) });
401
+ }
402
+
403
+ // Pack weakest-first into budget. Reserve room for header + potential
404
+ // elision footer so we can append them without overshooting the cap.
405
+ const headerTokens = estimateTokens(header);
406
+ const available = Math.max(0, budget - headerTokens - FOOTER_RESERVE_TOKENS);
407
+
408
+ const emitted = [];
409
+ let used = 0;
410
+ for (const entry of built) {
411
+ // +1 token for the blank-line separator between blocks
412
+ const withSep = entry.tokens + 1;
413
+ if (used + withSep > available) break;
414
+ emitted.push(entry);
415
+ used += withSep;
416
+ }
417
+
418
+ const elidedCount = built.length - emitted.length;
419
+
420
+ // If nothing fits, still emit at least the header + weakest section
421
+ // truncated to a single line so the output is non-empty and useful.
422
+ if (emitted.length === 0 && built.length > 0) {
423
+ // Degenerate: cap too tight. Emit header + "N sections elided" footer only.
424
+ const pieces = [header, '', '> NOTE: ' + built.length +
425
+ ' strongest sections elided for budget (budget too tight to render any section)'];
426
+ return pieces.join('\n');
427
+ }
428
+
429
+ // Compose final output
430
+ const pieces = [header, ''];
431
+ for (const e of emitted) {
432
+ pieces.push(e.block);
433
+ pieces.push('');
434
+ }
435
+
436
+ if (elidedCount > 0) {
437
+ pieces.push(
438
+ '> NOTE: ' + elidedCount +
439
+ ' strongest sections elided for budget (sorted weakest-first; weakest preserved)'
440
+ );
441
+ }
442
+
443
+ // Footers (pending-tier1, stale)
444
+ const pFooter = fmtPendingTier1Footer(o.pendingTier1);
445
+ if (pFooter) pieces.push(pFooter);
446
+ const sFooter = fmtStaleFooter(o.staleReport);
447
+ if (sFooter) pieces.push(sFooter);
448
+
449
+ let out = pieces.join('\n');
450
+
451
+ // Final budget safety: if we somehow exceed the cap (e.g. pending/stale
452
+ // footers blew the reserve), trim elided footer first, then emitted
453
+ // sections from the end (strongest-first, preserving weakest-first order).
454
+ // We CAP to budget * 4 chars as a hard backstop.
455
+ const capChars = budget * 4;
456
+ if (out.length > capChars) {
457
+ // Hard truncate with clear marker. This path is defensive only;
458
+ // should never fire with sensible budgets.
459
+ out = out.slice(0, capChars - 80) +
460
+ '\n> NOTE: output truncated to respect SESSION_START_BUDGET_TOKENS';
461
+ }
462
+
463
+ return out;
464
+ }
465
+
466
+ module.exports = {
467
+ formatTripleContext: formatTripleContext,
468
+ estimateTokens: estimateTokens,
469
+ getBudgetTokens: getBudgetTokens,
470
+ classifyHealth: classifyHealth,
471
+ fmtBrainLine: fmtBrainLine,
472
+ DEFAULT_BUDGET_TOKENS: DEFAULT_BUDGET_TOKENS,
473
+ };