@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,639 @@
1
+ /**
2
+ * MindrianOS Plugin -- Reasoning Engine Operations
3
+ * Core operations for .reasoning/ artifacts: REASONING.md generation,
4
+ * frontmatter CRUD (get/set/merge), methodology run artifacts, status listing.
5
+ * Pure Node.js built-ins only (zero npm deps per Phase 10 decision).
6
+ *
7
+ * Follows persona-ops.cjs module pattern exactly.
8
+ * Enhanced parseFrontmatter handles 2-3 levels of nesting (confidence.high,
9
+ * requires as array of objects, verification.must_be_true as nested list).
10
+ */
11
+
12
+ 'use strict';
13
+
14
+ const fs = require('fs');
15
+ const path = require('path');
16
+ const crypto = require('crypto');
17
+ const { discoverSections } = require('./section-registry.cjs');
18
+ const { safeReadFile } = require('./index.cjs');
19
+
20
+ // ---------------------------------------------------------------------------
21
+ // Plugin root (for template loading)
22
+ // ---------------------------------------------------------------------------
23
+
24
+ const PLUGIN_ROOT = path.resolve(__dirname, '../..');
25
+
26
+ // ---------------------------------------------------------------------------
27
+ // Enhanced frontmatter parser (handles 2-3 levels of nesting)
28
+ // ---------------------------------------------------------------------------
29
+
30
+ /**
31
+ * Parse YAML frontmatter from a markdown string.
32
+ * Enhanced version: handles nested objects, arrays of objects, and inline arrays.
33
+ * Supports the locked reasoning schema (confidence.high is list, requires is
34
+ * list of objects, verification.must_be_true is nested list).
35
+ *
36
+ * @param {string} content
37
+ * @returns {Object}
38
+ */
39
+ function parseFrontmatter(content) {
40
+ if (!content || typeof content !== 'string') return {};
41
+
42
+ const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
43
+ if (!match) return {};
44
+
45
+ const yaml = match[1];
46
+ const lines = yaml.split('\n');
47
+ const result = {};
48
+
49
+ // Stack-based approach for nested structures
50
+ let currentTopKey = null;
51
+ let currentSubKey = null;
52
+ let currentList = null;
53
+ let currentObj = null; // For sub-object within a parent key (e.g., confidence)
54
+ let currentObjList = null; // For list of objects (e.g., requires)
55
+ let pendingListItem = null; // For multi-line list items (objects in list)
56
+
57
+ function flushState() {
58
+ if (currentObjList !== null && currentTopKey) {
59
+ if (pendingListItem) {
60
+ currentObjList.push(pendingListItem);
61
+ pendingListItem = null;
62
+ }
63
+ result[currentTopKey] = currentObjList;
64
+ currentObjList = null;
65
+ } else if (currentObj !== null && currentTopKey) {
66
+ result[currentTopKey] = currentObj;
67
+ currentObj = null;
68
+ } else if (currentList !== null && currentTopKey) {
69
+ result[currentTopKey] = currentList;
70
+ currentList = null;
71
+ }
72
+ currentSubKey = null;
73
+ }
74
+
75
+ for (let i = 0; i < lines.length; i++) {
76
+ const line = lines[i];
77
+ const trimmed = line.trimEnd();
78
+
79
+ // Calculate indentation
80
+ const indent = line.length - line.trimStart().length;
81
+
82
+ // Top-level key: value (no indentation)
83
+ if (indent === 0 && /^[a-z_]/.test(trimmed)) {
84
+ flushState();
85
+
86
+ const colonIdx = trimmed.indexOf(':');
87
+ if (colonIdx === -1) continue;
88
+
89
+ currentTopKey = trimmed.slice(0, colonIdx).trim();
90
+ const val = trimmed.slice(colonIdx + 1).trim();
91
+
92
+ if (val === '' || val === 'null') {
93
+ // Could be followed by nested content — don't assign yet
94
+ result[currentTopKey] = null;
95
+ } else if (val.startsWith('[') && val.endsWith(']')) {
96
+ // Inline array: ["a", "b"]
97
+ try {
98
+ result[currentTopKey] = JSON.parse(val);
99
+ } catch (e) {
100
+ // Try manual parse for unquoted items
101
+ const inner = val.slice(1, -1);
102
+ result[currentTopKey] = inner.split(',').map(s => s.trim().replace(/^["']|["']$/g, ''));
103
+ }
104
+ currentTopKey = null;
105
+ } else if (val === 'true') {
106
+ result[currentTopKey] = true;
107
+ } else if (val === 'false') {
108
+ result[currentTopKey] = false;
109
+ } else if (/^-?\d+(\.\d+)?$/.test(val)) {
110
+ result[currentTopKey] = parseFloat(val);
111
+ } else {
112
+ result[currentTopKey] = val.replace(/^["']|["']$/g, '');
113
+ }
114
+ continue;
115
+ }
116
+
117
+ if (!currentTopKey) continue;
118
+
119
+ // Indent level 2 (2 spaces): sub-key or list item
120
+ if (indent === 2) {
121
+ const stripped = trimmed.trimStart();
122
+
123
+ // List item: "- something"
124
+ const listItemMatch = stripped.match(/^-\s+(.*)$/);
125
+ if (listItemMatch) {
126
+ const itemVal = listItemMatch[1].trim();
127
+
128
+ // Check if this is a key-value list item: "- section: value"
129
+ const kvMatch = itemVal.match(/^([a-z_]+):\s*(.+)$/);
130
+ if (kvMatch) {
131
+ // This is part of a list of objects (e.g., requires)
132
+ if (currentObjList === null) {
133
+ currentObjList = [];
134
+ }
135
+ if (pendingListItem) {
136
+ currentObjList.push(pendingListItem);
137
+ }
138
+ pendingListItem = {};
139
+ pendingListItem[kvMatch[1]] = parseValue(kvMatch[2]);
140
+ } else {
141
+ // Simple list item (string)
142
+ if (currentList === null) currentList = [];
143
+ currentList.push(parseValue(itemVal));
144
+ }
145
+ continue;
146
+ }
147
+
148
+ // Sub-key: "key: value" (nested object like confidence or verification)
149
+ const subKeyMatch = stripped.match(/^([a-z_]+):\s*(.*)$/);
150
+ if (subKeyMatch) {
151
+ // Flush any pending list of objects
152
+ if (currentObjList !== null) {
153
+ if (pendingListItem) {
154
+ currentObjList.push(pendingListItem);
155
+ pendingListItem = null;
156
+ }
157
+ // This shouldn't happen in our schema, but handle gracefully
158
+ }
159
+
160
+ if (currentObj === null) currentObj = {};
161
+ currentSubKey = subKeyMatch[1];
162
+ const subVal = subKeyMatch[2].trim();
163
+
164
+ if (subVal === '' || subVal === 'null') {
165
+ currentObj[currentSubKey] = null;
166
+ } else if (subVal.startsWith('[') && subVal.endsWith(']')) {
167
+ // Inline array
168
+ try {
169
+ currentObj[currentSubKey] = JSON.parse(subVal);
170
+ } catch (e) {
171
+ const inner = subVal.slice(1, -1);
172
+ currentObj[currentSubKey] = inner.split(',').map(s => s.trim().replace(/^["']|["']$/g, ''));
173
+ }
174
+ currentSubKey = null;
175
+ } else if (subVal === 'true') {
176
+ currentObj[currentSubKey] = true;
177
+ } else if (subVal === 'false') {
178
+ currentObj[currentSubKey] = false;
179
+ } else {
180
+ currentObj[currentSubKey] = parseValue(subVal);
181
+ }
182
+ continue;
183
+ }
184
+ }
185
+
186
+ // Indent level 4 (4 spaces): sub-sub content
187
+ if (indent === 4) {
188
+ const trimmedItem = trimmed.trim();
189
+
190
+ // Key-value continuation of a list item object: " provides: value"
191
+ if (pendingListItem) {
192
+ const kvMatch = trimmedItem.match(/^([a-z_]+):\s*(.+)$/);
193
+ if (kvMatch) {
194
+ pendingListItem[kvMatch[1]] = parseValue(kvMatch[2]);
195
+ continue;
196
+ }
197
+ }
198
+
199
+ // Sub-list item: " - value" (under a sub-key like verification.must_be_true)
200
+ const subListMatch = trimmedItem.match(/^-\s+(.+)$/);
201
+ if (subListMatch && currentObj && currentSubKey) {
202
+ if (!Array.isArray(currentObj[currentSubKey])) {
203
+ currentObj[currentSubKey] = [];
204
+ }
205
+ currentObj[currentSubKey].push(parseValue(subListMatch[1]));
206
+ continue;
207
+ }
208
+ }
209
+ }
210
+
211
+ // Final flush
212
+ flushState();
213
+
214
+ return result;
215
+ }
216
+
217
+ /**
218
+ * Parse a YAML scalar value (string, number, boolean).
219
+ * @param {string} val
220
+ * @returns {*}
221
+ */
222
+ function parseValue(val) {
223
+ if (val === 'true') return true;
224
+ if (val === 'false') return false;
225
+ if (val === 'null' || val === '') return null;
226
+ if (/^-?\d+(\.\d+)?$/.test(val)) return parseFloat(val);
227
+ return val.replace(/^["']|["']$/g, '');
228
+ }
229
+
230
+ // ---------------------------------------------------------------------------
231
+ // Frontmatter reconstruction (serialize object back to YAML)
232
+ // ---------------------------------------------------------------------------
233
+
234
+ /**
235
+ * Reconstruct a frontmatter object back to a YAML string.
236
+ * Handles nested objects, arrays of objects, arrays of strings, inline arrays.
237
+ *
238
+ * @param {Object} obj
239
+ * @returns {string}
240
+ */
241
+ function reconstructFrontmatter(obj) {
242
+ const lines = [];
243
+
244
+ for (const [key, value] of Object.entries(obj)) {
245
+ if (value === null || value === undefined) {
246
+ lines.push(`${key}:`);
247
+ } else if (typeof value === 'boolean') {
248
+ lines.push(`${key}: ${value}`);
249
+ } else if (typeof value === 'number') {
250
+ lines.push(`${key}: ${value}`);
251
+ } else if (typeof value === 'string') {
252
+ // Quote strings that contain special YAML chars
253
+ if (value.includes(':') || value.includes('#') || value.includes('"')) {
254
+ lines.push(`${key}: "${value.replace(/"/g, '\\"')}"`);
255
+ } else {
256
+ lines.push(`${key}: ${value}`);
257
+ }
258
+ } else if (Array.isArray(value)) {
259
+ // Check if all items are simple strings/numbers (use inline for short arrays)
260
+ const allSimple = value.every(v => typeof v === 'string' || typeof v === 'number');
261
+ const isShortInline = allSimple && JSON.stringify(value).length < 80;
262
+
263
+ if (allSimple && isShortInline && value.length <= 4) {
264
+ // Inline array: affects: ["a", "b"]
265
+ lines.push(`${key}: ${JSON.stringify(value)}`);
266
+ } else if (allSimple) {
267
+ // Block list
268
+ lines.push(`${key}:`);
269
+ for (const item of value) {
270
+ lines.push(` - "${item}"`);
271
+ }
272
+ } else {
273
+ // Array of objects
274
+ lines.push(`${key}:`);
275
+ for (const item of value) {
276
+ if (typeof item === 'object' && item !== null) {
277
+ const entries = Object.entries(item);
278
+ if (entries.length > 0) {
279
+ lines.push(` - ${entries[0][0]}: ${serializeScalar(entries[0][1])}`);
280
+ for (let j = 1; j < entries.length; j++) {
281
+ lines.push(` ${entries[j][0]}: ${serializeScalar(entries[j][1])}`);
282
+ }
283
+ }
284
+ } else {
285
+ lines.push(` - ${serializeScalar(item)}`);
286
+ }
287
+ }
288
+ }
289
+ } else if (typeof value === 'object') {
290
+ // Nested object (like confidence, verification)
291
+ lines.push(`${key}:`);
292
+ for (const [subKey, subVal] of Object.entries(value)) {
293
+ if (Array.isArray(subVal)) {
294
+ const allStr = subVal.every(v => typeof v === 'string' || typeof v === 'number');
295
+ if (allStr && JSON.stringify(subVal).length < 80) {
296
+ lines.push(` ${subKey}: ${JSON.stringify(subVal)}`);
297
+ } else {
298
+ lines.push(` ${subKey}:`);
299
+ for (const item of subVal) {
300
+ lines.push(` - "${item}"`);
301
+ }
302
+ }
303
+ } else {
304
+ lines.push(` ${subKey}: ${serializeScalar(subVal)}`);
305
+ }
306
+ }
307
+ }
308
+ }
309
+
310
+ return lines.join('\n');
311
+ }
312
+
313
+ /**
314
+ * Serialize a scalar value for YAML output.
315
+ * @param {*} val
316
+ * @returns {string}
317
+ */
318
+ function serializeScalar(val) {
319
+ if (val === null || val === undefined) return '';
320
+ if (typeof val === 'boolean') return String(val);
321
+ if (typeof val === 'number') return String(val);
322
+ if (typeof val === 'string') {
323
+ if (val.includes(':') || val.includes('#') || val.includes('"')) {
324
+ return `"${val.replace(/"/g, '\\"')}"`;
325
+ }
326
+ return `"${val}"`;
327
+ }
328
+ return String(val);
329
+ }
330
+
331
+ // ---------------------------------------------------------------------------
332
+ // Frontmatter splicing (replace frontmatter in content)
333
+ // ---------------------------------------------------------------------------
334
+
335
+ /**
336
+ * Replace frontmatter in a markdown content string.
337
+ * @param {string} content - Full markdown content
338
+ * @param {Object} newObj - New frontmatter object
339
+ * @returns {string} - Content with updated frontmatter
340
+ */
341
+ function spliceFrontmatter(content, newObj) {
342
+ const yamlStr = reconstructFrontmatter(newObj);
343
+ const body = content.replace(/^---\r?\n[\s\S]*?\r?\n---/, '').trimStart();
344
+ return `---\n${yamlStr}\n---\n\n${body}`;
345
+ }
346
+
347
+ // ---------------------------------------------------------------------------
348
+ // Template loading
349
+ // ---------------------------------------------------------------------------
350
+
351
+ /**
352
+ * Load the REASONING.md template from references.
353
+ * @returns {string}
354
+ */
355
+ function loadReasoningTemplate() {
356
+ const templatePath = path.join(PLUGIN_ROOT, 'references', 'reasoning', 'reasoning-template.md');
357
+ const content = safeReadFile(templatePath);
358
+ if (!content) throw new Error('Reasoning template not found at ' + templatePath);
359
+ return content;
360
+ }
361
+
362
+ /**
363
+ * Load the methodology run template from references.
364
+ * @returns {string}
365
+ */
366
+ function loadRunTemplate() {
367
+ const templatePath = path.join(PLUGIN_ROOT, 'references', 'reasoning', 'run-template.md');
368
+ const content = safeReadFile(templatePath);
369
+ if (!content) throw new Error('Run template not found at ' + templatePath);
370
+ return content;
371
+ }
372
+
373
+ // ---------------------------------------------------------------------------
374
+ // Core operations
375
+ // ---------------------------------------------------------------------------
376
+
377
+ /**
378
+ * Generate REASONING.md for one or all discovered sections.
379
+ * Creates .reasoning/{section}/REASONING.md from template with populated frontmatter.
380
+ *
381
+ * @param {string} roomDir - Path to room directory
382
+ * @param {string|null} sectionName - Specific section, or null for all
383
+ * @returns {{ generated: string[], room_hash: string, reasoning_dir: string } | { error: string }}
384
+ */
385
+ function generateReasoning(roomDir, sectionName) {
386
+ const resolved = path.resolve(roomDir);
387
+ const stateContent = safeReadFile(path.join(resolved, 'STATE.md'));
388
+ if (!stateContent) return { error: 'No room STATE.md found' };
389
+
390
+ const sections = discoverSections(resolved);
391
+ if (sectionName && !sections.all.includes(sectionName)) {
392
+ return { error: `Section not found: ${sectionName}` };
393
+ }
394
+
395
+ const targetSections = sectionName ? [sectionName] : sections.all;
396
+ const reasoningDir = path.join(resolved, '.reasoning');
397
+ fs.mkdirSync(reasoningDir, { recursive: true });
398
+
399
+ const roomHash = crypto.createHash('md5').update(stateContent).digest('hex').slice(0, 7);
400
+ const date = new Date().toISOString().split('T')[0];
401
+ const generated = [];
402
+
403
+ for (const section of targetSections) {
404
+ const sectionReasoningDir = path.join(reasoningDir, section);
405
+ fs.mkdirSync(sectionReasoningDir, { recursive: true });
406
+
407
+ const template = loadReasoningTemplate();
408
+ const sectionLabel = section.replace(/-/g, ' ').replace(/\b\w/g, c => c.toUpperCase());
409
+ const content = template
410
+ .replace(/\{section\}/g, section)
411
+ .replace(/\{date\}/g, date)
412
+ .replace(/\{hash\}/g, roomHash)
413
+ .replace(/\{run_id\}/g, '')
414
+ .replace(/\{Section Label\}/g, sectionLabel);
415
+
416
+ fs.writeFileSync(path.join(sectionReasoningDir, 'REASONING.md'), content, 'utf-8');
417
+ generated.push(section);
418
+ }
419
+
420
+ return { generated, room_hash: roomHash, reasoning_dir: '.reasoning/' };
421
+ }
422
+
423
+ /**
424
+ * Get reasoning content and parsed frontmatter for a section.
425
+ *
426
+ * @param {string} roomDir
427
+ * @param {string} section
428
+ * @returns {{ section: string, content: string, frontmatter: Object } | { error: string }}
429
+ */
430
+ function getReasoning(roomDir, section) {
431
+ const resolved = path.resolve(roomDir);
432
+ const reasoningPath = path.join(resolved, '.reasoning', section, 'REASONING.md');
433
+ const content = safeReadFile(reasoningPath);
434
+
435
+ if (!content) return { error: `No reasoning found for section: ${section}` };
436
+
437
+ const frontmatter = parseFrontmatter(content);
438
+ return { section, content, frontmatter };
439
+ }
440
+
441
+ /**
442
+ * List all discovered sections with reasoning status.
443
+ *
444
+ * @param {string} roomDir
445
+ * @returns {Array<{ section: string, has_reasoning: boolean, generated?: string, verification_status?: string, confidence_summary?: Object, brain_enriched?: boolean, room_hash?: string }>}
446
+ */
447
+ function listReasoning(roomDir) {
448
+ const resolved = path.resolve(roomDir);
449
+ const reasoningDir = path.join(resolved, '.reasoning');
450
+ const sections = discoverSections(resolved);
451
+
452
+ return sections.all.map(section => {
453
+ const reasoningPath = path.join(reasoningDir, section, 'REASONING.md');
454
+ const content = safeReadFile(reasoningPath);
455
+ if (!content) return { section, has_reasoning: false };
456
+
457
+ const fm = parseFrontmatter(content);
458
+ return {
459
+ section,
460
+ has_reasoning: true,
461
+ generated: fm.generated || null,
462
+ verification_status: (fm.verification && fm.verification.status) || 'unknown',
463
+ confidence_summary: {
464
+ high: Array.isArray(fm.confidence && fm.confidence.high) ? fm.confidence.high.length : 0,
465
+ medium: Array.isArray(fm.confidence && fm.confidence.medium) ? fm.confidence.medium.length : 0,
466
+ low: Array.isArray(fm.confidence && fm.confidence.low) ? fm.confidence.low.length : 0,
467
+ },
468
+ brain_enriched: fm.brain_enriched === true || fm.brain_enriched === 'true',
469
+ room_hash: fm.room_hash || null,
470
+ };
471
+ });
472
+ }
473
+
474
+ /**
475
+ * Verify reasoning for a section: returns verification criteria and dependency info.
476
+ *
477
+ * @param {string} roomDir
478
+ * @param {string} sectionName
479
+ * @returns {{ section: string, criteria: string[], status: string, provides: string[], requires: Array, affects: string[] } | { error: string }}
480
+ */
481
+ function verifyReasoning(roomDir, sectionName) {
482
+ const resolved = path.resolve(roomDir);
483
+ const reasoningPath = path.join(resolved, '.reasoning', sectionName, 'REASONING.md');
484
+ const content = safeReadFile(reasoningPath);
485
+
486
+ if (!content) return { error: `No reasoning found for section: ${sectionName}` };
487
+
488
+ const fm = parseFrontmatter(content);
489
+ const criteria = (fm.verification && fm.verification.must_be_true) || [];
490
+
491
+ return {
492
+ section: sectionName,
493
+ criteria,
494
+ status: (fm.verification && fm.verification.status) || 'pending',
495
+ provides: fm.provides || [],
496
+ requires: fm.requires || [],
497
+ affects: fm.affects || [],
498
+ };
499
+ }
500
+
501
+ /**
502
+ * Create a methodology run artifact in .reasoning/runs/.
503
+ * Generates a sequential run ID: run-{date}-{seq}.
504
+ *
505
+ * @param {string} roomDir
506
+ * @param {string} section
507
+ * @returns {{ run_id: string, path: string } | { error: string }}
508
+ */
509
+ function createRun(roomDir, section) {
510
+ const resolved = path.resolve(roomDir);
511
+ const stateContent = safeReadFile(path.join(resolved, 'STATE.md'));
512
+ if (!stateContent) return { error: 'No room STATE.md found' };
513
+
514
+ const runsDir = path.join(resolved, '.reasoning', 'runs');
515
+ fs.mkdirSync(runsDir, { recursive: true });
516
+
517
+ const date = new Date().toISOString().split('T')[0];
518
+ const roomHash = crypto.createHash('md5').update(stateContent).digest('hex').slice(0, 7);
519
+
520
+ // Find next sequential ID for today
521
+ let seq = 1;
522
+ try {
523
+ const existing = fs.readdirSync(runsDir).filter(f => f.startsWith(`run-${date}-`));
524
+ if (existing.length > 0) {
525
+ const nums = existing.map(f => {
526
+ const m = f.match(/run-\d{4}-\d{2}-\d{2}-(\d+)/);
527
+ return m ? parseInt(m[1], 10) : 0;
528
+ });
529
+ seq = Math.max(...nums) + 1;
530
+ }
531
+ } catch (e) {
532
+ // directory might not exist yet
533
+ }
534
+
535
+ const runId = `run-${date}-${String(seq).padStart(3, '0')}`;
536
+ const started = new Date().toISOString();
537
+ const sectionLabel = section.replace(/-/g, ' ').replace(/\b\w/g, c => c.toUpperCase());
538
+
539
+ const template = loadRunTemplate();
540
+ const content = template
541
+ .replace(/\{run_id\}/g, runId)
542
+ .replace(/\{section\}/g, section)
543
+ .replace(/\{started\}/g, started)
544
+ .replace(/\{completed\}/g, '')
545
+ .replace(/\{hash\}/g, roomHash)
546
+ .replace(/\{Section Label\}/g, sectionLabel);
547
+
548
+ const runPath = path.join(runsDir, `${runId}.md`);
549
+ fs.writeFileSync(runPath, content, 'utf-8');
550
+
551
+ return { run_id: runId, path: `.reasoning/runs/${runId}.md` };
552
+ }
553
+
554
+ // ---------------------------------------------------------------------------
555
+ // Frontmatter CRUD (REASON-05)
556
+ // ---------------------------------------------------------------------------
557
+
558
+ /**
559
+ * Get frontmatter from a section's REASONING.md, optionally a specific field.
560
+ *
561
+ * @param {string} roomDir
562
+ * @param {string} section
563
+ * @param {string} [field] - Optional specific field
564
+ * @returns {Object}
565
+ */
566
+ function getReasoningFrontmatter(roomDir, section, field) {
567
+ const resolved = path.resolve(roomDir);
568
+ const filePath = path.join(resolved, '.reasoning', section, 'REASONING.md');
569
+ const content = safeReadFile(filePath);
570
+ if (!content) return { error: `No reasoning for section: ${section}` };
571
+
572
+ const fm = parseFrontmatter(content);
573
+ if (field) {
574
+ return field in fm ? { [field]: fm[field] } : { error: `Field not found: ${field}` };
575
+ }
576
+ return fm;
577
+ }
578
+
579
+ /**
580
+ * Set a specific frontmatter field in a section's REASONING.md.
581
+ *
582
+ * @param {string} roomDir
583
+ * @param {string} section
584
+ * @param {string} field
585
+ * @param {*} value
586
+ * @returns {{ updated: boolean, section: string, field: string, value: * } | { error: string }}
587
+ */
588
+ function setReasoningFrontmatter(roomDir, section, field, value) {
589
+ const resolved = path.resolve(roomDir);
590
+ const filePath = path.join(resolved, '.reasoning', section, 'REASONING.md');
591
+ const content = safeReadFile(filePath);
592
+ if (!content) return { error: `No reasoning for section: ${section}` };
593
+
594
+ const fm = parseFrontmatter(content);
595
+ fm[field] = value;
596
+ const newContent = spliceFrontmatter(content, fm);
597
+ fs.writeFileSync(filePath, newContent, 'utf-8');
598
+ return { updated: true, section, field, value };
599
+ }
600
+
601
+ /**
602
+ * Merge an object into a section's REASONING.md frontmatter.
603
+ *
604
+ * @param {string} roomDir
605
+ * @param {string} section
606
+ * @param {Object} data - Object to merge
607
+ * @returns {{ merged: boolean, section: string, fields: string[] } | { error: string }}
608
+ */
609
+ function mergeReasoningFrontmatter(roomDir, section, data) {
610
+ const resolved = path.resolve(roomDir);
611
+ const filePath = path.join(resolved, '.reasoning', section, 'REASONING.md');
612
+ const content = safeReadFile(filePath);
613
+ if (!content) return { error: `No reasoning for section: ${section}` };
614
+
615
+ const fm = parseFrontmatter(content);
616
+ const fields = [];
617
+ for (const [key, value] of Object.entries(data)) {
618
+ fm[key] = value;
619
+ fields.push(key);
620
+ }
621
+ const newContent = spliceFrontmatter(content, fm);
622
+ fs.writeFileSync(filePath, newContent, 'utf-8');
623
+ return { merged: true, section, fields };
624
+ }
625
+
626
+ // ---------------------------------------------------------------------------
627
+ // Exports
628
+ // ---------------------------------------------------------------------------
629
+
630
+ module.exports = {
631
+ generateReasoning,
632
+ getReasoning,
633
+ listReasoning,
634
+ verifyReasoning,
635
+ createRun,
636
+ getReasoningFrontmatter,
637
+ setReasoningFrontmatter,
638
+ mergeReasoningFrontmatter,
639
+ };