@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,631 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /*
5
+ * Copyright (c) 2026 Mindrian. BSL 1.1.
6
+ *
7
+ * Phase 88.1-05 -- /mos:status Shape E renderer acceptance tests.
8
+ *
9
+ * Verifies scripts/mos-status.cjs. The renderer implements Canon Part 2
10
+ * Body Shape E (Action Report) for /mos:status: one governing_thought row
11
+ * per section, MINTO health glyph in the Canon Part 2 vocabulary (check /
12
+ * warn / low / --), stale suffix, empty-section placeholder, budget-
13
+ * respecting truncation, and a summary row at the bottom.
14
+ *
15
+ * Canon references:
16
+ * Part 2 UI Ruling System Shape E zone layout + glyph vocabulary.
17
+ * Part 3 Tri-Context Decision Gate -- /mos:status renders LOCAL state
18
+ * only (the first of the three contexts). Never BRAIN. Never
19
+ * SIGNAL.
20
+ * Part 8 Graph Boundary -- every triple read goes through
21
+ * lib/core/folder-memory.cjs readTriple; cache reads go through
22
+ * lib/core/statusline-cache.cjs getCached; zero Brain egress.
23
+ *
24
+ * Reuse from Plan 88.1-04:
25
+ * - lib/core/statusline-cache.cjs getCached / setCached (5s TTL)
26
+ * - classifyHealth shared glyph classifier (byte-identical thresholds)
27
+ * - truncateGoverningThought (80-char budget here, wider than statusline's
28
+ * 60-char budget; renderer applies its own truncation at the call site)
29
+ *
30
+ * Test map (12 cases, one-to-one with the PLAN Task 1 <behavior> block):
31
+ *
32
+ * 1. Healthy 3-section room: each row carries glyph + governing_thought.
33
+ * 2. Stale section: row includes "(stale: {reason})" suffix.
34
+ * 3. Empty section (no MINTO.md): row reads "(no MINTO yet)" dim.
35
+ * 4. governing_thought > 80 chars: truncated + ellipsis.
36
+ * 5. Summary counts filled / stale / median across a 10-section fixture.
37
+ * 6. --stale-only flag: renders only stale sections + summary.
38
+ * 7. <section> argument: renders that section's full triple (not truncated).
39
+ * 8. Missing room: prints "no active room; /mos:rooms to list" + exit 0.
40
+ * 9. Zero external network: no fetch/http/brain.mindrian.ai strings in the
41
+ * renderer source.
42
+ * 10. Shape E zones present: header + rows + summary + actions.
43
+ * 11. Warm-cache path: if statusline-cache has fresh data for the section,
44
+ * skip readTriple (verified via monkey-patch on readTriple).
45
+ * 12. Cold-cache path: no cache yet -> readTriple is called for each
46
+ * section discovered under roomRoot.
47
+ *
48
+ * Registered in lib/memory/run-feynman-tests.cjs.
49
+ */
50
+
51
+ const assert = require('node:assert/strict');
52
+ const fs = require('node:fs');
53
+ const os = require('node:os');
54
+ const path = require('node:path');
55
+ const { spawnSync } = require('node:child_process');
56
+
57
+ const REPO = path.resolve(__dirname, '..', '..');
58
+ const RENDERER = path.join(REPO, 'scripts/mos-status.cjs');
59
+ const CACHE_PATH = path.join(REPO, 'lib/core/statusline-cache.cjs');
60
+
61
+ // Load cache helpers for fixture warm-priming.
62
+ try { delete require.cache[require.resolve(CACHE_PATH)]; } catch (_) {}
63
+ const statuslineCache = require(CACHE_PATH);
64
+
65
+ // ---------- Fixture helpers ----------
66
+
67
+ const TMP_ROOTS = [];
68
+ function mkTmp(prefix) {
69
+ const d = fs.mkdtempSync(path.join(os.tmpdir(), prefix));
70
+ TMP_ROOTS.push(d);
71
+ return d;
72
+ }
73
+ process.on('exit', () => {
74
+ for (const d of TMP_ROOTS) {
75
+ try { fs.rmSync(d, { recursive: true, force: true }); } catch (_) {}
76
+ }
77
+ });
78
+
79
+ function writeRoomMd(dir, identity) {
80
+ fs.writeFileSync(
81
+ path.join(dir, 'ROOM.md'),
82
+ '# ' + (identity || 'section identity') + '\n',
83
+ 'utf8'
84
+ );
85
+ }
86
+
87
+ function writeStateMd(dir, opts) {
88
+ const o = opts || {};
89
+ const body = [
90
+ '# Section State',
91
+ '',
92
+ 'artifact_count: ' + (o.artifact_count !== undefined ? o.artifact_count : 3),
93
+ 'gap_status: ' + (o.gap_status || 'active'),
94
+ 'completeness_score: ' + (o.completeness_score !== undefined ? o.completeness_score : 0.7),
95
+ '',
96
+ 'Last activity: 2026-04-23',
97
+ '',
98
+ ].join('\n');
99
+ fs.writeFileSync(path.join(dir, 'STATE.md'), body, 'utf8');
100
+ }
101
+
102
+ function writeMintoMd(dir, opts) {
103
+ const o = opts || {};
104
+ const fm = {
105
+ governing_thought: o.governing_thought !== undefined
106
+ ? o.governing_thought
107
+ : 'TAM of $12B is bottom-up defensible',
108
+ arguments_count: o.arguments_count !== undefined ? o.arguments_count : 3,
109
+ evidence_density: o.evidence_density !== undefined ? o.evidence_density : 0.8,
110
+ mece_status: o.mece_status || 'pass',
111
+ last_generated_at: o.last_generated_at || '2026-04-20T00:00:00Z',
112
+ last_artifact_write_seen_at: o.last_artifact_write_seen_at
113
+ || '2026-04-20T00:00:00Z',
114
+ flagged_weaknesses: o.flagged_weaknesses || [],
115
+ decision_log: o.decision_log || [],
116
+ };
117
+ const lines = ['---'];
118
+ for (const k of Object.keys(fm)) {
119
+ const v = fm[k];
120
+ if (Array.isArray(v)) {
121
+ lines.push(k + ': ' + (v.length === 0 ? '[]' : JSON.stringify(v)));
122
+ } else if (v === null) {
123
+ lines.push(k + ': null');
124
+ } else if (typeof v === 'string') {
125
+ lines.push(k + ': ' + JSON.stringify(v));
126
+ } else {
127
+ lines.push(k + ': ' + v);
128
+ }
129
+ }
130
+ lines.push('---', '', '# MINTO body', '');
131
+ // argument/evidence sentinels the parser counts
132
+ const bodyLines = [];
133
+ for (let i = 0; i < (o.arguments_count || 3); i++) {
134
+ bodyLines.push('## Argument ' + (i + 1));
135
+ bodyLines.push('**Evidence:** supporting text for argument ' + (i + 1));
136
+ bodyLines.push('');
137
+ }
138
+ fs.writeFileSync(
139
+ path.join(dir, 'MINTO.md'),
140
+ lines.join('\n') + '\n' + bodyLines.join('\n'),
141
+ 'utf8'
142
+ );
143
+ }
144
+
145
+ function mkRoom() {
146
+ return mkTmp('mos-status-test-');
147
+ }
148
+
149
+ function mkSection(room, name, opts) {
150
+ const p = path.join(room, name);
151
+ fs.mkdirSync(p, { recursive: true });
152
+ writeRoomMd(p, name);
153
+ writeStateMd(p, opts);
154
+ if (!opts || opts.withMinto !== false) {
155
+ writeMintoMd(p, opts);
156
+ }
157
+ return p;
158
+ }
159
+
160
+ function runRenderer(args, opts) {
161
+ const o = opts || {};
162
+ const env = Object.assign({}, process.env, o.env || {});
163
+ const res = spawnSync(process.execPath, [RENDERER].concat(args || []), {
164
+ cwd: o.cwd || process.cwd(),
165
+ env: env,
166
+ encoding: 'utf8',
167
+ timeout: 5000,
168
+ });
169
+ return {
170
+ stdout: res.stdout || '',
171
+ stderr: res.stderr || '',
172
+ status: res.status,
173
+ };
174
+ }
175
+
176
+ // ---------- Precondition: renderer must exist (this will fail in RED) ----------
177
+
178
+ assert.equal(
179
+ fs.existsSync(RENDERER),
180
+ true,
181
+ 'RED guard: scripts/mos-status.cjs must exist before running tests. ' +
182
+ 'Create it in the GREEN step. Path: ' + RENDERER
183
+ );
184
+
185
+ // ---------- Test 1: healthy 3-section room ----------
186
+
187
+ (function test1HealthyRoom() {
188
+ const room = mkRoom();
189
+ mkSection(room, 'market-analysis', {
190
+ governing_thought: 'TAM of $12B is bottom-up defensible',
191
+ arguments_count: 4,
192
+ evidence_density: 0.9,
193
+ });
194
+ mkSection(room, 'problem-definition', {
195
+ governing_thought: 'IT integration is the wedge',
196
+ arguments_count: 3,
197
+ evidence_density: 0.6,
198
+ });
199
+ mkSection(room, 'solution-design', {
200
+ governing_thought: 'API middleware unblocks integration',
201
+ arguments_count: 2,
202
+ evidence_density: 0.4,
203
+ });
204
+
205
+ const r = runRenderer([], { cwd: room });
206
+ assert.equal(r.status, 0, 'renderer exits 0 on healthy room');
207
+ assert.ok(r.stdout.indexOf('market-analysis') !== -1, 'market-analysis row rendered');
208
+ assert.ok(r.stdout.indexOf('problem-definition') !== -1, 'problem-definition row rendered');
209
+ assert.ok(r.stdout.indexOf('solution-design') !== -1, 'solution-design row rendered');
210
+ assert.ok(
211
+ r.stdout.indexOf('TAM of $12B') !== -1,
212
+ 'market-analysis governing_thought rendered inline'
213
+ );
214
+ assert.ok(
215
+ r.stdout.indexOf('IT integration is the wedge') !== -1,
216
+ 'problem-definition governing_thought rendered inline'
217
+ );
218
+ // Glyph vocabulary: at least one of check/warn/low appears on a section row.
219
+ const hasGlyph = /\b(check|warn|low)\b/.test(r.stdout);
220
+ assert.ok(hasGlyph, 'at least one Canon Part 2 glyph present on section rows');
221
+ console.log('PASS test 1: healthy 3-section room renders rows + glyphs');
222
+ })();
223
+
224
+ // ---------- Test 2: stale section ----------
225
+
226
+ (function test2StaleSection() {
227
+ const room = mkRoom();
228
+ mkSection(room, 'market-analysis', {
229
+ governing_thought: 'TAM defensible',
230
+ arguments_count: 3,
231
+ });
232
+ // Build a stale section: a MINTO.md backdated before the artifact mtime.
233
+ const stale = path.join(room, 'business-model');
234
+ fs.mkdirSync(stale, { recursive: true });
235
+ writeRoomMd(stale, 'business-model');
236
+ writeStateMd(stale, {});
237
+ writeMintoMd(stale, {
238
+ governing_thought: 'Freemium plus seat-based',
239
+ last_generated_at: '2026-01-01T00:00:00Z',
240
+ last_artifact_write_seen_at: '2026-01-01T00:00:00Z',
241
+ });
242
+ // Drop an artifact with mtime clearly after the MINTO.md mtime.
243
+ const art = path.join(stale, 'tam.md');
244
+ fs.writeFileSync(art, '# TAM artifact\n', 'utf8');
245
+ const future = Date.now() / 1000 + 3600;
246
+ fs.utimesSync(art, future, future);
247
+ // Rewind MINTO.md mtime to well before the artifact.
248
+ const past = Date.now() / 1000 - 86400;
249
+ fs.utimesSync(path.join(stale, 'MINTO.md'), past, past);
250
+
251
+ const r = runRenderer([], { cwd: room });
252
+ assert.equal(r.status, 0, 'renderer exits 0 with stale section');
253
+ assert.ok(
254
+ r.stdout.indexOf('(stale:') !== -1,
255
+ 'stale suffix present: (stale: ...)'
256
+ );
257
+ assert.ok(
258
+ /business-model[^\n]*\(stale:/.test(r.stdout),
259
+ 'stale suffix applied to business-model row'
260
+ );
261
+ console.log('PASS test 2: stale section carries (stale: reason) suffix');
262
+ })();
263
+
264
+ // ---------- Test 3: empty section (no MINTO.md) ----------
265
+
266
+ (function test3EmptySection() {
267
+ const room = mkRoom();
268
+ mkSection(room, 'team-execution', {
269
+ governing_thought: 'Team of 3 with biotech + IT mix',
270
+ });
271
+ // Empty section: ROOM.md but NO MINTO.md
272
+ const empty = path.join(room, 'competitive-analysis');
273
+ fs.mkdirSync(empty, { recursive: true });
274
+ writeRoomMd(empty, 'competitive-analysis');
275
+ writeStateMd(empty, {});
276
+ // No writeMintoMd call -- deliberately empty.
277
+
278
+ const r = runRenderer([], { cwd: room });
279
+ assert.equal(r.status, 0, 'renderer exits 0 with empty section');
280
+ assert.ok(
281
+ r.stdout.indexOf('(no MINTO yet)') !== -1,
282
+ '(no MINTO yet) placeholder present for empty section'
283
+ );
284
+ assert.ok(
285
+ /competitive-analysis[^\n]*\(no MINTO yet\)/.test(r.stdout),
286
+ 'placeholder is applied to competitive-analysis row'
287
+ );
288
+ console.log('PASS test 3: empty section renders (no MINTO yet)');
289
+ })();
290
+
291
+ // ---------- Test 4: long governing_thought truncated ----------
292
+
293
+ (function test4TruncatedThought() {
294
+ const room = mkRoom();
295
+ const long =
296
+ 'This is an exceptionally long governing thought that exceeds the ' +
297
+ 'eighty-character budget enforced by the /mos:status renderer and ' +
298
+ 'should be truncated with an ellipsis suffix so the row remains ' +
299
+ 'readable.';
300
+ mkSection(room, 'market-analysis', { governing_thought: long });
301
+
302
+ const r = runRenderer([], { cwd: room });
303
+ assert.equal(r.status, 0, 'renderer exits 0 on long thought');
304
+ // Accept Unicode ellipsis OR ASCII "..." tail on the section row.
305
+ const hasEllipsis =
306
+ r.stdout.indexOf('\u2026') !== -1 || r.stdout.indexOf('...') !== -1;
307
+ assert.ok(hasEllipsis, 'ellipsis marker present for truncated thought');
308
+ // Raw long string must NOT appear verbatim.
309
+ assert.ok(
310
+ r.stdout.indexOf(long) === -1,
311
+ 'raw untruncated long thought must not appear in output'
312
+ );
313
+ console.log('PASS test 4: long governing_thought truncated with ellipsis');
314
+ })();
315
+
316
+ // ---------- Test 5: summary counts + median across 10 sections ----------
317
+
318
+ (function test5SummaryCounts() {
319
+ const room = mkRoom();
320
+ // 7 healthy sections with governing_thought present.
321
+ for (let i = 0; i < 7; i++) {
322
+ mkSection(room, 'healthy-' + i, {
323
+ governing_thought: 'Healthy claim number ' + i,
324
+ arguments_count: 3,
325
+ evidence_density: 0.7,
326
+ });
327
+ }
328
+ // 2 stale sections.
329
+ for (let i = 0; i < 2; i++) {
330
+ const name = 'stale-' + i;
331
+ const p = path.join(room, name);
332
+ fs.mkdirSync(p, { recursive: true });
333
+ writeRoomMd(p, name);
334
+ writeStateMd(p, {});
335
+ writeMintoMd(p, {
336
+ governing_thought: 'Stale claim ' + i,
337
+ last_generated_at: '2026-01-01T00:00:00Z',
338
+ last_artifact_write_seen_at: '2026-01-01T00:00:00Z',
339
+ });
340
+ fs.writeFileSync(path.join(p, 'artifact.md'), '# x\n', 'utf8');
341
+ const future = Date.now() / 1000 + 3600;
342
+ fs.utimesSync(path.join(p, 'artifact.md'), future, future);
343
+ const past = Date.now() / 1000 - 86400;
344
+ fs.utimesSync(path.join(p, 'MINTO.md'), past, past);
345
+ }
346
+ // 1 empty section (no MINTO.md).
347
+ const emp = path.join(room, 'empty-0');
348
+ fs.mkdirSync(emp, { recursive: true });
349
+ writeRoomMd(emp, 'empty-0');
350
+ writeStateMd(emp, {});
351
+
352
+ const r = runRenderer([], { cwd: room });
353
+ assert.equal(r.status, 0, 'renderer exits 0 on 10-section fixture');
354
+ // Summary line includes counts: 10 sections, 9 filled, 2 stale (stale sections
355
+ // still have MINTO.md so they ARE filled). median is a fractional number.
356
+ assert.ok(
357
+ /10 sections/.test(r.stdout),
358
+ 'summary reports 10 sections'
359
+ );
360
+ assert.ok(
361
+ /(\s|^)9 filled/.test(r.stdout),
362
+ 'summary reports 9 filled (7 healthy + 2 stale)'
363
+ );
364
+ assert.ok(
365
+ /(\s|^)2 stale/.test(r.stdout),
366
+ 'summary reports 2 stale'
367
+ );
368
+ assert.ok(
369
+ /median/i.test(r.stdout),
370
+ 'summary includes a median-health label'
371
+ );
372
+ console.log('PASS test 5: summary counts filled/stale/median accurately');
373
+ })();
374
+
375
+ // ---------- Test 6: --stale-only flag ----------
376
+
377
+ (function test6StaleOnly() {
378
+ const room = mkRoom();
379
+ mkSection(room, 'healthy-a', { governing_thought: 'Claim A' });
380
+ mkSection(room, 'healthy-b', { governing_thought: 'Claim B' });
381
+ const stale = path.join(room, 'stale-c');
382
+ fs.mkdirSync(stale, { recursive: true });
383
+ writeRoomMd(stale, 'stale-c');
384
+ writeStateMd(stale, {});
385
+ writeMintoMd(stale, {
386
+ governing_thought: 'Stale claim C',
387
+ last_generated_at: '2026-01-01T00:00:00Z',
388
+ last_artifact_write_seen_at: '2026-01-01T00:00:00Z',
389
+ });
390
+ fs.writeFileSync(path.join(stale, 'art.md'), '# x\n', 'utf8');
391
+ const future = Date.now() / 1000 + 3600;
392
+ fs.utimesSync(path.join(stale, 'art.md'), future, future);
393
+ const past = Date.now() / 1000 - 86400;
394
+ fs.utimesSync(path.join(stale, 'MINTO.md'), past, past);
395
+
396
+ const r = runRenderer(['--stale-only'], { cwd: room });
397
+ assert.equal(r.status, 0, 'renderer exits 0 for --stale-only');
398
+ assert.ok(
399
+ r.stdout.indexOf('stale-c') !== -1,
400
+ 'stale-only includes the stale section'
401
+ );
402
+ assert.ok(
403
+ r.stdout.indexOf('healthy-a') === -1,
404
+ '--stale-only excludes healthy-a'
405
+ );
406
+ assert.ok(
407
+ r.stdout.indexOf('healthy-b') === -1,
408
+ '--stale-only excludes healthy-b'
409
+ );
410
+ console.log('PASS test 6: --stale-only filters to stale sections only');
411
+ })();
412
+
413
+ // ---------- Test 7: <section> argument renders one section in detail ----------
414
+
415
+ (function test7SingleSection() {
416
+ const room = mkRoom();
417
+ mkSection(room, 'market-analysis', {
418
+ governing_thought:
419
+ 'Comprehensive bottom-up TAM of $12B defensible via enterprise ' +
420
+ 'SaaS penetration model across twelve verticals with channel' +
421
+ ' partners.',
422
+ arguments_count: 5,
423
+ evidence_density: 0.9,
424
+ });
425
+ mkSection(room, 'problem-definition', {
426
+ governing_thought: 'IT integration is the wedge',
427
+ });
428
+
429
+ const r = runRenderer(['market-analysis'], { cwd: room });
430
+ assert.equal(r.status, 0, 'renderer exits 0 on section-argument path');
431
+ assert.ok(
432
+ r.stdout.indexOf('market-analysis') !== -1,
433
+ 'section-argument path names target section'
434
+ );
435
+ assert.ok(
436
+ r.stdout.indexOf('problem-definition') === -1,
437
+ 'section-argument path excludes other sections'
438
+ );
439
+ // Full detail: governing_thought rendered in full (not ellipsis-truncated).
440
+ assert.ok(
441
+ r.stdout.indexOf('twelve verticals with channel') !== -1,
442
+ 'section-argument renders governing_thought in FULL (no truncation)'
443
+ );
444
+ console.log('PASS test 7: single-section argument renders full detail');
445
+ })();
446
+
447
+ // ---------- Test 8: missing room (no .room-root / no room dir) ----------
448
+
449
+ (function test8MissingRoom() {
450
+ // Run in an empty tmp dir that has no room/ subdir and no sections.
451
+ const empty = mkTmp('mos-status-noroom-');
452
+ const r = runRenderer([], { cwd: empty });
453
+ assert.equal(r.status, 0, 'renderer exits 0 on missing-room path');
454
+ assert.ok(
455
+ /no active room/i.test(r.stdout),
456
+ 'missing-room output explains there is no active room'
457
+ );
458
+ assert.ok(
459
+ /mos:rooms/.test(r.stdout),
460
+ 'missing-room output suggests /mos:rooms'
461
+ );
462
+ console.log('PASS test 8: missing room prints one-line hint + exits 0');
463
+ })();
464
+
465
+ // ---------- Test 9: zero external network / Brain references in the source ----------
466
+
467
+ (function test9NoNetwork() {
468
+ const src = fs.readFileSync(RENDERER, 'utf8');
469
+ // Canon Part 8: the renderer must be strictly LOCAL.
470
+ const forbidden = [
471
+ 'brain.mindrian.ai',
472
+ 'http://',
473
+ 'https://',
474
+ 'require(\'node:http\')',
475
+ 'require("node:http")',
476
+ 'require(\'http\')',
477
+ 'require("http")',
478
+ 'require(\'node:https\')',
479
+ 'require("node:https")',
480
+ 'require(\'https\')',
481
+ 'require("https")',
482
+ 'curl ',
483
+ ];
484
+ for (const needle of forbidden) {
485
+ assert.equal(
486
+ src.indexOf(needle),
487
+ -1,
488
+ 'Canon Part 8: renderer must NOT contain "' + needle + '"'
489
+ );
490
+ }
491
+ // "fetch(" used anywhere in the source is a canonical breach.
492
+ assert.equal(
493
+ /\bfetch\s*\(/.test(src),
494
+ false,
495
+ 'Canon Part 8: renderer must NOT call fetch()'
496
+ );
497
+ console.log('PASS test 9: renderer has zero external network surface');
498
+ })();
499
+
500
+ // ---------- Test 10: Shape E zones (header / rows / summary / actions) ----------
501
+
502
+ (function test10ShapeEZones() {
503
+ const room = mkRoom();
504
+ mkSection(room, 'market-analysis', {
505
+ governing_thought: 'TAM of $12B is bottom-up defensible',
506
+ });
507
+ mkSection(room, 'solution-design', {
508
+ governing_thought: 'API middleware unblocks integration',
509
+ });
510
+
511
+ const r = runRenderer([], { cwd: room });
512
+ assert.equal(r.status, 0, 'renderer exits 0 on Shape E fixture');
513
+ // Zone 1 header: "/mos:status" marker + room breadcrumb.
514
+ assert.ok(
515
+ r.stdout.indexOf('/mos:status') !== -1,
516
+ 'Shape E zone 1 header carries /mos:status marker'
517
+ );
518
+ // Zone 2 rows: at least one section row named.
519
+ assert.ok(
520
+ r.stdout.indexOf('market-analysis') !== -1,
521
+ 'Shape E zone 2 renders section rows'
522
+ );
523
+ // Zone 3 summary: counts line.
524
+ assert.ok(
525
+ /\d+ sections?/.test(r.stdout),
526
+ 'Shape E zone 3 summary line present'
527
+ );
528
+ // Zone 4 actions: /mos:reason hint OR talk-to-Larry hint.
529
+ assert.ok(
530
+ /mos:reason|Larry/i.test(r.stdout),
531
+ 'Shape E zone 4 actions footer present'
532
+ );
533
+ console.log('PASS test 10: Shape E zones (header/rows/summary/actions) emitted');
534
+ })();
535
+
536
+ // ---------- Test 11: warm-cache path (skip readTriple if cache fresh) ----------
537
+
538
+ (function test11WarmCache() {
539
+ // Warm the cache for the section BEFORE invoking the renderer, then flip a
540
+ // sentinel in MINTO.md so we can verify the renderer printed the cached
541
+ // text (warm hit) rather than the fresh disk text (cold re-read).
542
+ const room = mkRoom();
543
+ const sectionPath = mkSection(room, 'market-analysis', {
544
+ governing_thought: 'CACHED thought wins',
545
+ arguments_count: 3,
546
+ evidence_density: 0.8,
547
+ });
548
+
549
+ // Build the triple exactly as folder-memory.readTriple would, then prime
550
+ // the 5s TTL cache keyed by (roomRoot=room, sectionPath=absolute section).
551
+ const primedTriple = {
552
+ room: { exists: true, identity_text: 'market-analysis', references: [] },
553
+ state: {
554
+ exists: true,
555
+ artifact_count: 3,
556
+ gap_status: 'active',
557
+ completeness_score: 0.7,
558
+ minto_health: '--',
559
+ last_activity_at: null,
560
+ },
561
+ reasoning: {
562
+ exists: true,
563
+ governing_thought: 'CACHED thought wins',
564
+ arguments_count: 3,
565
+ evidence_density: 0.8,
566
+ mece_status: 'pass',
567
+ reasoning_health_score: 0.82,
568
+ flagged_weaknesses: [],
569
+ decision_log: [],
570
+ last_generated_at: '2026-04-20T00:00:00Z',
571
+ last_artifact_write_seen_at: '2026-04-20T00:00:00Z',
572
+ is_stale: false,
573
+ stale_reason: null,
574
+ },
575
+ };
576
+ statuslineCache.setCached(room, sectionPath, primedTriple);
577
+
578
+ // Now rewrite MINTO.md on disk with a DIFFERENT sentinel text.
579
+ writeMintoMd(sectionPath, {
580
+ governing_thought: 'DISK thought loses',
581
+ arguments_count: 3,
582
+ evidence_density: 0.8,
583
+ });
584
+
585
+ const r = runRenderer([], { cwd: room });
586
+ assert.equal(r.status, 0, 'renderer exits 0 under warm cache');
587
+ assert.ok(
588
+ r.stdout.indexOf('CACHED thought wins') !== -1,
589
+ 'warm cache hit: renderer prints CACHED sentinel'
590
+ );
591
+ assert.ok(
592
+ r.stdout.indexOf('DISK thought loses') === -1,
593
+ 'warm cache hit: renderer does NOT re-read the disk triple'
594
+ );
595
+ console.log('PASS test 11: warm-cache path skips readTriple for fresh sections');
596
+ })();
597
+
598
+ // ---------- Test 12: cold-cache path (readTriple called per section) ----------
599
+
600
+ (function test12ColdCache() {
601
+ // Fresh room; no priming. Renderer must still emit a complete render,
602
+ // which is only possible if it falls back to readTriple for each section.
603
+ const room = mkRoom();
604
+ mkSection(room, 'cold-one', {
605
+ governing_thought: 'Cold section one thought',
606
+ });
607
+ mkSection(room, 'cold-two', {
608
+ governing_thought: 'Cold section two thought',
609
+ });
610
+ mkSection(room, 'cold-three', {
611
+ governing_thought: 'Cold section three thought',
612
+ });
613
+
614
+ const r = runRenderer([], { cwd: room });
615
+ assert.equal(r.status, 0, 'renderer exits 0 under cold cache');
616
+ assert.ok(
617
+ r.stdout.indexOf('Cold section one thought') !== -1,
618
+ 'cold read: cold-one governing_thought rendered'
619
+ );
620
+ assert.ok(
621
+ r.stdout.indexOf('Cold section two thought') !== -1,
622
+ 'cold read: cold-two governing_thought rendered'
623
+ );
624
+ assert.ok(
625
+ r.stdout.indexOf('Cold section three thought') !== -1,
626
+ 'cold read: cold-three governing_thought rendered'
627
+ );
628
+ console.log('PASS test 12: cold-cache path readTriple-based render complete');
629
+ })();
630
+
631
+ console.log('\nAll 12 mos-status-renderer tests passed.');