@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,340 @@
1
+ /*
2
+ * Copyright (c) 2026 Mindrian. BSL 1.1.
3
+ * Phase 91-09 -- navigation-invariants validator.
4
+ *
5
+ * Registry-compatible drop-in for the Phase 88-13 guardian. Auto-loaded
6
+ * by scripts/feynman-minto-guardian.cjs's loadValidators() walker; no
7
+ * guardian.cjs edits required (extensibility promise of Phase 88-13
8
+ * registry contract).
9
+ *
10
+ * Converts five silent Phase 91 navigation failure modes into first-class
11
+ * health signals visible at session-start, on-stop, and pre-commit:
12
+ *
13
+ * INV-1 trace_missing_field every persisted decision_trace
14
+ * entry must carry all 8 Section 8
15
+ * brain_md_* fields per
16
+ * navigation-engine-brain-interface
17
+ * v1. Missing field -> error.
18
+ * INV-2 recommended_in_wrong_mode RECOMMENDED marker may render only
19
+ * in mode_a (Canon Part 3 Section 6).
20
+ * Rendered in mode_b or tier_0 ->
21
+ * error.
22
+ * INV-3 weight_clamp_breach brain_md_weight_applied must lie
23
+ * in [0.0, 1.0] inclusive. Out-of-
24
+ * range -> error.
25
+ * INV-4 trace_file_malformed decision-traces/*.json that fails
26
+ * JSON.parse -> error. Sibling files
27
+ * continue to be scanned.
28
+ * INV-5 unknown_verb_passed trace.fire_skill (when present)
29
+ * must be in CANONICAL_VERBS (Canon
30
+ * Part 3 frozen 10-verb vocabulary).
31
+ * Unknown -> warning. Graceful when
32
+ * shared module unavailable.
33
+ *
34
+ * Canon Part 8 (Graph Boundary): pure LOCAL reader. Reads only files
35
+ * under <roomDir>/.mindrian/decision-traces/. Zero network surface; zero
36
+ * Brain MCP queries; zero shell-out. Test 13 source-scans this file for
37
+ * forbidden references.
38
+ *
39
+ * Canon Part 7 (Reuse Before Build): Phase 88-13 built the validator
40
+ * registry for exactly this scenario. This file plugs in; guardian.cjs
41
+ * stays untouched. Fail-open is inherited from the registry loader (a
42
+ * malformed sibling validator never prevents this validator from running).
43
+ *
44
+ * Three-surface compatibility: pure CJS + node built-ins (fs, path).
45
+ * Works identically on Claude Code CLI, Claude Desktop MCP, and Cowork
46
+ * shared-room scenarios.
47
+ *
48
+ * Mode dispatch (set by guardian invocation):
49
+ * session-start advisory; emitted to TRIPLE_CONTEXT footer.
50
+ * on-stop advisory; aggregated into invariant-report.json.
51
+ * pre-commit blocking at error/critical (guardian exits 2). This
52
+ * validator just emits; guardian owns exit codes.
53
+ */
54
+
55
+ 'use strict';
56
+
57
+ const fs = require('node:fs');
58
+ const path = require('node:path');
59
+
60
+ // ---------- Constants ----------
61
+
62
+ const SEVERITY_MAP = Object.freeze({
63
+ // 6 categories the validator emits, mapped to severities the guardian
64
+ // aggregates. Phase 88-13 expects the shape (object); the guardian's
65
+ // SEVERITY_ORDER alone owns numeric ordering.
66
+ trace_missing_field: 'error',
67
+ recommended_in_wrong_mode: 'error',
68
+ weight_clamp_breach: 'error',
69
+ unknown_verb_passed: 'warning',
70
+ trace_file_malformed: 'error',
71
+ session_file_absent: 'info',
72
+ });
73
+
74
+ // 8 Section 8 fields per .planning/research/navigation-engine-brain-
75
+ // interface.md v1. Order is documentation-stable; the validator does not
76
+ // rely on order, but the test suite reads this list defensively.
77
+ const REQUIRED_TRACE_FIELDS = Object.freeze([
78
+ 'brain_md_version',
79
+ 'brain_md_staleness',
80
+ 'brain_md_stale_reason',
81
+ 'brain_md_weight_applied',
82
+ 'brain_md_recommended_confidence',
83
+ 'brain_md_recommended_marker_rendered',
84
+ 'brain_md_tier_mode',
85
+ 'brain_md_sections_consumed',
86
+ ]);
87
+
88
+ const VALID_TIER_MODES = Object.freeze(['mode_a', 'mode_b', 'tier_0']);
89
+ const ROOM_SCOPE = '__room__';
90
+
91
+ // ---------- Lazy CANONICAL_VERBS load (graceful degradation) ----------
92
+
93
+ let _canonicalVerbs = undefined; // undefined: not yet loaded; null: unavailable.
94
+ function getCanonicalVerbs() {
95
+ if (_canonicalVerbs !== undefined) return _canonicalVerbs;
96
+ try {
97
+ const sharedPath = path.join(__dirname, '..', '..', 'core',
98
+ 'navigation-engine-shared.cjs');
99
+ // Best-effort require. If the shared module fails to load (missing,
100
+ // syntax error), fall back to null so INV-5 silently skips. Per the
101
+ // plan: graceful degradation, not noisy failure.
102
+ const mod = require(sharedPath);
103
+ if (mod && Array.isArray(mod.CANONICAL_VERBS) && mod.CANONICAL_VERBS.length > 0) {
104
+ _canonicalVerbs = mod.CANONICAL_VERBS;
105
+ } else {
106
+ _canonicalVerbs = null;
107
+ }
108
+ } catch (_) {
109
+ _canonicalVerbs = null;
110
+ }
111
+ return _canonicalVerbs;
112
+ }
113
+
114
+ // ---------- Helpers ----------
115
+
116
+ function isFiniteNumber(n) {
117
+ return typeof n === 'number' && isFinite(n);
118
+ }
119
+
120
+ function safeReadDir(dir) {
121
+ try {
122
+ return fs.readdirSync(dir, { withFileTypes: true })
123
+ .filter(function (d) { return d.isFile() && /\.json$/i.test(d.name); })
124
+ .map(function (d) { return d.name; })
125
+ .sort();
126
+ } catch (_) {
127
+ return null; // sentinel: directory absent or unreadable
128
+ }
129
+ }
130
+
131
+ function makeViolation(category, message, extras) {
132
+ const sev = SEVERITY_MAP[category] || 'warning';
133
+ const base = {
134
+ validator: 'navigation-invariants',
135
+ category: category,
136
+ severity: sev,
137
+ message: message,
138
+ scope: ROOM_SCOPE,
139
+ };
140
+ if (extras && typeof extras === 'object') {
141
+ return Object.assign(base, extras);
142
+ }
143
+ return base;
144
+ }
145
+
146
+ // ---------- Per-trace invariant checks ----------
147
+
148
+ /**
149
+ * Check a single persisted trace entry for INV-1, INV-2, INV-3, INV-5.
150
+ * Pushes violations into the supplied array. Each violation carries
151
+ * session_id (when known) + turn (when known) so /mos:explain-decision
152
+ * and the guardian footer can pinpoint the offending row.
153
+ */
154
+ function checkTraceEntry(trace, sessionId, fileName, violations) {
155
+ if (!trace || typeof trace !== 'object') return;
156
+ const turn = (typeof trace.turn === 'number') ? trace.turn : null;
157
+ const idCommon = {
158
+ session_id: sessionId,
159
+ file: fileName,
160
+ };
161
+ if (turn !== null) idCommon.turn = turn;
162
+
163
+ // INV-1 trace_missing_field. Use hasOwnProperty so explicit `null` /
164
+ // 0 / '' / false / [] do NOT trip the check (Section 8 sentinels are
165
+ // valid values).
166
+ for (const field of REQUIRED_TRACE_FIELDS) {
167
+ if (!Object.prototype.hasOwnProperty.call(trace, field)) {
168
+ violations.push(makeViolation(
169
+ 'trace_missing_field',
170
+ 'decision_trace missing required Section 8 field "' + field +
171
+ '" in session ' + sessionId +
172
+ (turn !== null ? ' turn ' + turn : ''),
173
+ Object.assign({ field: field, action_hint: 'review_decision_trace_emitter' },
174
+ idCommon)
175
+ ));
176
+ }
177
+ }
178
+
179
+ // INV-2 recommended_in_wrong_mode. RECOMMENDED marker may render only
180
+ // when tier_mode === 'mode_a' per Canon Part 3 Section 6.
181
+ const rendered = trace.brain_md_recommended_marker_rendered;
182
+ const tierMode = trace.brain_md_tier_mode;
183
+ if (rendered === true && tierMode !== 'mode_a' &&
184
+ VALID_TIER_MODES.indexOf(tierMode) !== -1) {
185
+ violations.push(makeViolation(
186
+ 'recommended_in_wrong_mode',
187
+ 'RECOMMENDED marker rendered while tier_mode="' + tierMode +
188
+ '" (Canon Part 3 Section 6 requires mode_a) in session ' +
189
+ sessionId + (turn !== null ? ' turn ' + turn : ''),
190
+ Object.assign({ tier_mode: tierMode, action_hint: 'audit_recommended_gate' },
191
+ idCommon)
192
+ ));
193
+ }
194
+
195
+ // INV-3 weight_clamp_breach. brain_md_weight_applied in [0.0, 1.0].
196
+ const weight = trace.brain_md_weight_applied;
197
+ if (isFiniteNumber(weight) && (weight < 0.0 || weight > 1.0)) {
198
+ violations.push(makeViolation(
199
+ 'weight_clamp_breach',
200
+ 'brain_md_weight_applied=' + weight + ' outside [0.0, 1.0] in session ' +
201
+ sessionId + (turn !== null ? ' turn ' + turn : ''),
202
+ Object.assign({ weight_applied: weight, action_hint: 'enforce_clamp_at_emitter' },
203
+ idCommon)
204
+ ));
205
+ }
206
+
207
+ // INV-5 unknown_verb_passed. Only check when CANONICAL_VERBS available
208
+ // AND fire_skill is a non-empty string (absent/null fire_skill is
209
+ // valid: the engine emits null when no skill is recommended).
210
+ const verbs = getCanonicalVerbs();
211
+ if (verbs !== null && typeof trace.fire_skill === 'string' &&
212
+ trace.fire_skill.length > 0 && verbs.indexOf(trace.fire_skill) === -1) {
213
+ violations.push(makeViolation(
214
+ 'unknown_verb_passed',
215
+ 'fire_skill="' + trace.fire_skill +
216
+ '" is not in Canon Part 3 vocabulary (10 frozen verbs) in session ' +
217
+ sessionId + (turn !== null ? ' turn ' + turn : ''),
218
+ Object.assign({ fire_skill: trace.fire_skill,
219
+ action_hint: 'route_through_canonicalizeVerb' }, idCommon)
220
+ ));
221
+ }
222
+ }
223
+
224
+ // ---------- Main validate() ----------
225
+
226
+ function validateRoom(roomDir) {
227
+ const violations = [];
228
+ const tracesDir = path.join(roomDir, '.mindrian', 'decision-traces');
229
+ const files = safeReadDir(tracesDir);
230
+
231
+ if (files === null) {
232
+ // INV: no decision-traces dir. This is the healthy fresh-room state;
233
+ // surface as info so /mos:explain-decision telemetry has something
234
+ // benign to report rather than a confusing silence.
235
+ violations.push(makeViolation(
236
+ 'session_file_absent',
237
+ 'No decision traces recorded yet (fresh room or pre-engine state).',
238
+ { action_hint: 'none' }
239
+ ));
240
+ return finalize(violations);
241
+ }
242
+
243
+ if (files.length === 0) {
244
+ // Directory exists but is empty. Treat the same as absent for
245
+ // signaling purposes.
246
+ violations.push(makeViolation(
247
+ 'session_file_absent',
248
+ 'decision-traces directory present but contains no session files.',
249
+ { action_hint: 'none' }
250
+ ));
251
+ return finalize(violations);
252
+ }
253
+
254
+ for (const fname of files) {
255
+ const fullPath = path.join(tracesDir, fname);
256
+ let raw;
257
+ try {
258
+ raw = fs.readFileSync(fullPath, 'utf8');
259
+ } catch (e) {
260
+ // Read failure is treated as malformed: the file exists but cannot
261
+ // be processed. Continue to the next sibling.
262
+ violations.push(makeViolation(
263
+ 'trace_file_malformed',
264
+ 'decision-traces file "' + fname + '" could not be read: ' +
265
+ (e && e.message ? e.message : String(e)),
266
+ { file: fname, action_hint: 'inspect_file_permissions' }
267
+ ));
268
+ continue;
269
+ }
270
+ let parsed;
271
+ try {
272
+ parsed = JSON.parse(raw);
273
+ } catch (e) {
274
+ violations.push(makeViolation(
275
+ 'trace_file_malformed',
276
+ 'decision-traces file "' + fname + '" is not valid JSON: ' +
277
+ (e && e.message ? e.message : String(e)),
278
+ { file: fname, action_hint: 'rotate_or_remove_corrupt_trace' }
279
+ ));
280
+ continue;
281
+ }
282
+ if (!parsed || typeof parsed !== 'object') {
283
+ violations.push(makeViolation(
284
+ 'trace_file_malformed',
285
+ 'decision-traces file "' + fname + '" did not parse to an object.',
286
+ { file: fname, action_hint: 'rotate_or_remove_corrupt_trace' }
287
+ ));
288
+ continue;
289
+ }
290
+ const sessionId = (typeof parsed.session_id === 'string' &&
291
+ parsed.session_id.length > 0) ? parsed.session_id : fname.replace(/\.json$/i, '');
292
+ const traces = Array.isArray(parsed.traces) ? parsed.traces : [];
293
+ for (const t of traces) {
294
+ checkTraceEntry(t, sessionId, fname, violations);
295
+ }
296
+ }
297
+
298
+ return finalize(violations);
299
+ }
300
+
301
+ function finalize(violations) {
302
+ // Aggregate severity for guardian's per-validator summary line.
303
+ const order = ['info', 'warning', 'error', 'critical'];
304
+ let max = -1;
305
+ for (const v of violations) {
306
+ const i = order.indexOf(v.severity);
307
+ if (i > max) max = i;
308
+ }
309
+ return {
310
+ severity: max === -1 ? null : order[max],
311
+ violations: violations,
312
+ };
313
+ }
314
+
315
+ // ---------- Exports ----------
316
+
317
+ module.exports = {
318
+ id: 'navigation-invariants',
319
+ severity_map: SEVERITY_MAP,
320
+ scope: 'room',
321
+ validate: function (sectionDirOrRoomDir, ctx) {
322
+ // Phase 88-13 contract: when scope === 'room' the guardian invokes
323
+ // validate(roomDir, ctx). For defensive symmetry with the other
324
+ // room-scoped validators (snapshot-integrity, queue-health,
325
+ // stale-lifecycle), prefer ctx.roomDir when available.
326
+ const roomDir = (ctx && typeof ctx.roomDir === 'string' && ctx.roomDir.length > 0)
327
+ ? ctx.roomDir
328
+ : sectionDirOrRoomDir;
329
+ if (typeof roomDir !== 'string' || roomDir.length === 0) {
330
+ return { severity: null, violations: [] };
331
+ }
332
+ return validateRoom(roomDir);
333
+ },
334
+ // Internal exports for tests (not part of the registry contract; the
335
+ // guardian ignores extra keys):
336
+ __internal: {
337
+ REQUIRED_TRACE_FIELDS: REQUIRED_TRACE_FIELDS,
338
+ VALID_TIER_MODES: VALID_TIER_MODES,
339
+ },
340
+ };
@@ -0,0 +1,95 @@
1
+ /*
2
+ * Copyright (c) 2026 Mindrian. BSL 1.1.
3
+ * Phase 88-13 MEM-GUARDIAN-QUEUE-01.
4
+ *
5
+ * Enforces size ceilings on the minto-debouncer queue
6
+ * (.mindrian/minto-queue.json shipped by 88-02). Without this validator,
7
+ * unbounded queue growth (drain never fires) accumulates silently for
8
+ * hundreds of sessions before anyone notices. This converts the silent
9
+ * growth into a visible session-start signal.
10
+ *
11
+ * Thresholds:
12
+ * entries < 500 healthy, no violation
13
+ * entries >= 500 && <= 999 warning queue_approaching_ceiling
14
+ * entries >= 1000 error queue_ceiling_exceeded +
15
+ * action_hint halt_enqueue_until_drained
16
+ *
17
+ * Emits at most ONE aggregate violation per invocation (not N per entry).
18
+ * Missing queue file -> no violation (healthy first-session state).
19
+ */
20
+
21
+ 'use strict';
22
+
23
+ const fs = require('node:fs');
24
+ const path = require('node:path');
25
+
26
+ const SEVERITY_MAP = { critical: 3, error: 2, warning: 1, info: 0 };
27
+ const WARN_THRESHOLD = 500;
28
+ const ERROR_THRESHOLD = 1000;
29
+ const ROOM_SCOPE = '__room__';
30
+
31
+ function validateRoom(roomDir) {
32
+ const qp = path.join(roomDir, '.mindrian', 'minto-queue.json');
33
+ if (!fs.existsSync(qp)) {
34
+ return { severity: null, violations: [] };
35
+ }
36
+ let parsed;
37
+ try {
38
+ parsed = JSON.parse(fs.readFileSync(qp, 'utf8'));
39
+ } catch (_) {
40
+ // Malformed queue file is a silent-failure signal in its own right.
41
+ return {
42
+ severity: 'warning',
43
+ violations: [{
44
+ validator: 'queue-health',
45
+ category: 'queue_unparseable',
46
+ severity: 'warning',
47
+ message: 'minto-queue.json is unparseable; debouncer self-healed or writer crashed',
48
+ scope: ROOM_SCOPE,
49
+ }],
50
+ };
51
+ }
52
+ const entries = (parsed && Array.isArray(parsed.entries)) ? parsed.entries : [];
53
+ const count = entries.length;
54
+ if (count < WARN_THRESHOLD) {
55
+ return { severity: null, violations: [] };
56
+ }
57
+ if (count >= ERROR_THRESHOLD) {
58
+ return {
59
+ severity: 'error',
60
+ violations: [{
61
+ validator: 'queue-health',
62
+ category: 'queue_ceiling_exceeded',
63
+ severity: 'error',
64
+ message: 'minto-debouncer queue at ' + count +
65
+ ' entries, ceiling ' + ERROR_THRESHOLD,
66
+ action_hint: 'halt_enqueue_until_drained',
67
+ count: count,
68
+ scope: ROOM_SCOPE,
69
+ }],
70
+ };
71
+ }
72
+ return {
73
+ severity: 'warning',
74
+ violations: [{
75
+ validator: 'queue-health',
76
+ category: 'queue_approaching_ceiling',
77
+ severity: 'warning',
78
+ message: 'minto-debouncer queue at ' + count +
79
+ ' entries, ceiling ' + ERROR_THRESHOLD,
80
+ action_hint: 'drain_soon',
81
+ count: count,
82
+ scope: ROOM_SCOPE,
83
+ }],
84
+ };
85
+ }
86
+
87
+ module.exports = {
88
+ id: 'queue-health',
89
+ severity_map: SEVERITY_MAP,
90
+ scope: 'room',
91
+ validate: function (sectionDirOrRoomDir, ctx) {
92
+ const roomDir = (ctx && ctx.roomDir) ? ctx.roomDir : sectionDirOrRoomDir;
93
+ return validateRoom(roomDir);
94
+ },
95
+ };
@@ -0,0 +1,129 @@
1
+ /*
2
+ * Copyright (c) 2026 Mindrian. BSL 1.1.
3
+ * Phase 88-13 MEM-GUARDIAN-SNAPSHOT-01.
4
+ *
5
+ * Detects partial session-snapshot.json produced by an on-stop walk that
6
+ * crashed mid-iteration before the atomic rename landed. Without this
7
+ * validator the drift stays silent for 20+ sessions (no visible
8
+ * TRIPLE_CONTEXT entry for the affected section, but user never sees why).
9
+ *
10
+ * Signals emitted:
11
+ * partial_snapshot warning per missing section, action_hint
12
+ * 'partial_snapshot_detected'
13
+ * snapshot_empty error when snapshot has zero sections but the
14
+ * room has at least one ROOM.md section on disk.
15
+ * Action hint 'rerun_on_stop'.
16
+ * (missing file) silent: no violation. Healthy first-session.
17
+ *
18
+ * Emits violations against a synthetic section key `__room__` so the
19
+ * guardian aggregator can surface them without tying them to a specific
20
+ * section (they are a room-wide health signal).
21
+ */
22
+
23
+ 'use strict';
24
+
25
+ const fs = require('node:fs');
26
+ const path = require('node:path');
27
+
28
+ const SEVERITY_MAP = { critical: 3, error: 2, warning: 1, info: 0 };
29
+ const ROOM_SCOPE = '__room__';
30
+
31
+ function safeReadSections(roomDir) {
32
+ // Returns an array of section dir names that hold a ROOM.md, per the
33
+ // ICM Layer 0 identity invariant (CLAUDE.md decision #15).
34
+ try {
35
+ return fs.readdirSync(roomDir, { withFileTypes: true })
36
+ .filter(function (d) { return d.isDirectory() && d.name[0] !== '.'; })
37
+ .filter(function (d) {
38
+ try {
39
+ return fs.existsSync(path.join(roomDir, d.name, 'ROOM.md'));
40
+ } catch (_) { return false; }
41
+ })
42
+ .map(function (d) { return d.name; });
43
+ } catch (_) {
44
+ return [];
45
+ }
46
+ }
47
+
48
+ function validateRoom(roomDir) {
49
+ const snapPath = path.join(roomDir, '.mindrian', 'session-snapshot.json');
50
+ if (!fs.existsSync(snapPath)) {
51
+ return { severity: null, violations: [] };
52
+ }
53
+ let parsed;
54
+ try {
55
+ const raw = fs.readFileSync(snapPath, 'utf8');
56
+ parsed = JSON.parse(raw);
57
+ } catch (_) {
58
+ // Malformed JSON surfaced as error (silent-to-loud conversion).
59
+ return {
60
+ severity: 'error',
61
+ violations: [{
62
+ validator: 'snapshot-integrity',
63
+ category: 'snapshot_unparseable',
64
+ severity: 'error',
65
+ message: 'session-snapshot.json is unparseable; on-stop likely crashed',
66
+ action_hint: 'rerun_on_stop',
67
+ scope: ROOM_SCOPE,
68
+ }],
69
+ };
70
+ }
71
+ const snapSections = (parsed && parsed.sections && typeof parsed.sections === 'object')
72
+ ? Object.keys(parsed.sections)
73
+ : [];
74
+ const diskSections = safeReadSections(roomDir);
75
+
76
+ const violations = [];
77
+ if (snapSections.length === 0 && diskSections.length > 0) {
78
+ violations.push({
79
+ validator: 'snapshot-integrity',
80
+ category: 'snapshot_empty',
81
+ severity: 'error',
82
+ message: 'on-stop walk crashed or never ran: snapshot empty while room has ' +
83
+ diskSections.length + ' section' + (diskSections.length === 1 ? '' : 's'),
84
+ action_hint: 'rerun_on_stop',
85
+ scope: ROOM_SCOPE,
86
+ });
87
+ } else {
88
+ const snapSet = new Set(snapSections);
89
+ for (const d of diskSections) {
90
+ if (!snapSet.has(d)) {
91
+ violations.push({
92
+ validator: 'snapshot-integrity',
93
+ category: 'partial_snapshot',
94
+ severity: 'warning',
95
+ message: 'section "' + d + '" exists on disk but missing from session-snapshot.json',
96
+ action_hint: 'partial_snapshot_detected',
97
+ scope: ROOM_SCOPE,
98
+ section: d,
99
+ });
100
+ }
101
+ }
102
+ }
103
+ // Aggregate severity
104
+ let max = -1;
105
+ const order = ['info', 'warning', 'error', 'critical'];
106
+ for (const v of violations) {
107
+ const i = order.indexOf(v.severity);
108
+ if (i > max) max = i;
109
+ }
110
+ return {
111
+ severity: max === -1 ? null : order[max],
112
+ violations: violations,
113
+ };
114
+ }
115
+
116
+ module.exports = {
117
+ id: 'snapshot-integrity',
118
+ severity_map: SEVERITY_MAP,
119
+ // Section-scoped validators get a sectionDir; this one is room-scoped so
120
+ // the guardian invokes it once per room (sectionDir parameter is ignored
121
+ // when context.scope === 'room'). The guardian honors a special
122
+ // `scope: 'room'` field so we do not duplicate work across N sections.
123
+ scope: 'room',
124
+ validate: function (sectionDirOrRoomDir, ctx) {
125
+ // The guardian always passes the room path when scope === 'room'.
126
+ const roomDir = (ctx && ctx.roomDir) ? ctx.roomDir : sectionDirOrRoomDir;
127
+ return validateRoom(roomDir);
128
+ },
129
+ };
@@ -0,0 +1,116 @@
1
+ /*
2
+ * Copyright (c) 2026 Mindrian. BSL 1.1.
3
+ * Phase 88-13 MEM-GUARDIAN-STALE-01.
4
+ *
5
+ * Re-validates every .mindrian/minto-stale.json entry (written by 88-06
6
+ * for sections whose MINTO couldn't regen) against the current MINTO
7
+ * state. A stale entry whose section now has a valid MINTO is a GHOST:
8
+ * the ledger lies. This validator emits a warning per ghost so the
9
+ * on-stop mode of the guardian can prune the ghost atomically. Without
10
+ * this, ghost entries linger forever and pollute session-start footers
11
+ * with false alarms.
12
+ *
13
+ * Signals:
14
+ * stale_ghost (warning) entry lists section X but invariants.validate(X)
15
+ * is now clean. Carries section name + action_hint
16
+ * 'prune_stale_entry'. Consumed by guardian on-stop
17
+ * mode to rewrite stale.json atomically.
18
+ * (MINTO still invalid) no new violation; real staleness is already
19
+ * surfaced by the stale.json consumer (88-07).
20
+ * (missing stale.json) no violation; healthy.
21
+ */
22
+
23
+ 'use strict';
24
+
25
+ const fs = require('node:fs');
26
+ const path = require('node:path');
27
+
28
+ const SEVERITY_MAP = { critical: 3, error: 2, warning: 1, info: 0 };
29
+ const ROOM_SCOPE = '__room__';
30
+
31
+ const { validate: invariantsValidate } = require('../../core/feynman-minto-invariants.cjs');
32
+
33
+ function validateRoom(roomDir) {
34
+ const stalePath = path.join(roomDir, '.mindrian', 'minto-stale.json');
35
+ if (!fs.existsSync(stalePath)) {
36
+ return { severity: null, violations: [] };
37
+ }
38
+ let parsed;
39
+ try {
40
+ parsed = JSON.parse(fs.readFileSync(stalePath, 'utf8'));
41
+ } catch (_) {
42
+ return {
43
+ severity: 'warning',
44
+ violations: [{
45
+ validator: 'stale-lifecycle',
46
+ category: 'stale_file_unparseable',
47
+ severity: 'warning',
48
+ message: 'minto-stale.json is unparseable',
49
+ scope: ROOM_SCOPE,
50
+ }],
51
+ };
52
+ }
53
+ const list = (parsed && Array.isArray(parsed.sections)) ? parsed.sections : [];
54
+ const violations = [];
55
+ // Reasons owned by the invariants module. Only these reasons are
56
+ // candidates for ghost detection via re-validation. Other reasons
57
+ // (never_generated, missing_timestamps, artifacts_newer_than_minto) are
58
+ // signaled by folder-memory.computeStale() independently of invariants
59
+ // state -- re-running invariants won't learn anything about them and
60
+ // pruning based on invariant cleanliness would erase real signals.
61
+ const INVARIANT_OWNED_REASONS = new Set(['invariant_violation', 'parse_failed']);
62
+ for (const entry of list) {
63
+ if (!entry || typeof entry !== 'object') continue;
64
+ const section = entry.section;
65
+ if (typeof section !== 'string' || section.length === 0) continue;
66
+ const reason = typeof entry.reason === 'string' ? entry.reason : '';
67
+ if (!INVARIANT_OWNED_REASONS.has(reason)) {
68
+ // Skip entries whose reason is not owned by the invariants module;
69
+ // folder-memory is the authoritative source for these, and pruning
70
+ // would erase valid staleness. These stay in stale.json until the
71
+ // originating producer (88-06 on-stop walk) removes them.
72
+ continue;
73
+ }
74
+ const mintoPath = path.join(roomDir, section, 'MINTO.md');
75
+ if (!fs.existsSync(mintoPath)) continue;
76
+ let result;
77
+ try { result = invariantsValidate(mintoPath); }
78
+ catch (_) { continue; }
79
+ // Ghost condition: MINTO is fully invariant-clean. If ANY violation
80
+ // survives (including freshness/coherence warnings), the section is
81
+ // still stale and must NOT be pruned.
82
+ const violationsList = (result && result.violations) || [];
83
+ if (violationsList.length === 0) {
84
+ violations.push({
85
+ validator: 'stale-lifecycle',
86
+ category: 'stale_ghost',
87
+ severity: 'warning',
88
+ message: 'stale.json lists "' + section + '" (reason=' + reason +
89
+ ') but MINTO is now invariant-clean',
90
+ action_hint: 'prune_stale_entry',
91
+ section: section,
92
+ scope: ROOM_SCOPE,
93
+ });
94
+ }
95
+ }
96
+ let max = -1;
97
+ const order = ['info', 'warning', 'error', 'critical'];
98
+ for (const v of violations) {
99
+ const i = order.indexOf(v.severity);
100
+ if (i > max) max = i;
101
+ }
102
+ return {
103
+ severity: max === -1 ? null : order[max],
104
+ violations: violations,
105
+ };
106
+ }
107
+
108
+ module.exports = {
109
+ id: 'stale-lifecycle',
110
+ severity_map: SEVERITY_MAP,
111
+ scope: 'room',
112
+ validate: function (sectionDirOrRoomDir, ctx) {
113
+ const roomDir = (ctx && ctx.roomDir) ? ctx.roomDir : sectionDirOrRoomDir;
114
+ return validateRoom(roomDir);
115
+ },
116
+ };