@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,452 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /*
5
+ * Copyright (c) 2026 Mindrian. BSL 1.1.
6
+ * Phase 89.3 Plan 05 -- bridge-writer enhanced fixture suite + regression test.
7
+ *
8
+ * lib/core/bridge-writer.cjs::renderBridgeArtifact is enhanced in place to
9
+ * inject 2 NEW frontmatter fields when input pair carries them:
10
+ * - thesis: "<from generateThesis output>"
11
+ * - breakthrough_score: <pair.breakthrough.score.toFixed(2)>
12
+ *
13
+ * BACKWARD-COMPAT contract (load-bearing):
14
+ * - When pair.thesis is missing or empty, the thesis: line is OMITTED.
15
+ * - When pair.breakthrough is missing or pair.breakthrough.score is not a
16
+ * number, the breakthrough_score: line is OMITTED.
17
+ * - A v1.10.16-vintage input pair (no thesis, no breakthrough) renders
18
+ * BYTE-IDENTICAL frontmatter to the pre-89.3 version. Test 1 is the
19
+ * load-bearing regression assertion.
20
+ *
21
+ * 8 scenarios:
22
+ * Test 1 (REGRESSION) -- v1.10.16-vintage input pair renders all 13
23
+ * pre-89.3 frontmatter fields verbatim AND
24
+ * emits NEITHER thesis: NOR breakthrough_score:
25
+ * Test 2 (89.3 thesis-only) -- pair has only thesis -> emits thesis: line
26
+ * AFTER generated_at: and BEFORE closing ---;
27
+ * does NOT emit breakthrough_score:
28
+ * Test 3 (89.3 breakthrough) -- pair has only breakthrough -> emits
29
+ * breakthrough_score: line; no thesis:
30
+ * Test 4 (89.3 both) -- pair has BOTH; both lines present;
31
+ * thesis: line BEFORE breakthrough_score:
32
+ * Test 5 (missing thesis) -- pair.thesis === null OR '' -> omit gracefully
33
+ * Test 6 (missing breakthrough) -- pair.breakthrough === undefined OR
34
+ * pair.breakthrough.score not a number ->
35
+ * omit gracefully
36
+ * Test 7 (CANON PART 8 #1) -- adversarial pair.thesis carries forbidden
37
+ * pattern -> auditQueryObject throws
38
+ * ExternalEgressViolation BEFORE return
39
+ * Test 8 (CANON PART 8 #2) -- adversarial pair.breakthrough carries
40
+ * forbidden pattern in dominant_dimension OR
41
+ * breakdown values -> defense-in-depth catch
42
+ *
43
+ * End-of-suite sweep:
44
+ * A1: re-scan every captured rendered output (clean scenarios) against
45
+ * FORBIDDEN_PATTERNS; ZERO hits guaranteed.
46
+ *
47
+ * Pure CJS, zero npm deps, node built-ins only (assert, path).
48
+ */
49
+
50
+ const assert = require('node:assert/strict');
51
+ const path = require('node:path');
52
+
53
+ const REPO_ROOT = path.resolve(__dirname, '..', '..');
54
+
55
+ // FORBIDDEN_PATTERNS source-of-truth from cross-room-aggregator (the same
56
+ // authoritative set rs-egress-prompts re-exports byte-for-byte).
57
+ const crossRoomAggregator = require('../core/cross-room-aggregator.cjs');
58
+ const FORBIDDEN_PATTERNS = crossRoomAggregator.FORBIDDEN_PATTERNS;
59
+
60
+ // Captured rendered outputs for end-of-suite A1 sweep (clean scenarios only).
61
+ const capturedOutputs = [];
62
+
63
+ let passed = 0;
64
+ let failed = 0;
65
+ const failures = [];
66
+
67
+ function resetRequireCache() {
68
+ const targets = [
69
+ '../core/rs-egress-violations.cjs',
70
+ '../core/rs-egress-prompts.cjs',
71
+ '../core/cross-room-aggregator.cjs',
72
+ '../core/bridge-writer.cjs',
73
+ ];
74
+ for (const t of targets) {
75
+ try {
76
+ const p = require.resolve(t);
77
+ delete require.cache[p];
78
+ } catch (_e) { /* best effort */ }
79
+ }
80
+ }
81
+
82
+ async function runScenario(name, fn) {
83
+ const start = Date.now();
84
+ try {
85
+ await fn();
86
+ passed += 1;
87
+ process.stdout.write(' ok ' + name + ' (' + (Date.now() - start) + 'ms)\n');
88
+ } catch (err) {
89
+ failed += 1;
90
+ failures.push({ name: name, err: err });
91
+ process.stderr.write(' FAIL ' + name + '\n');
92
+ process.stderr.write(' ' + (err && err.stack ? err.stack : err) + '\n');
93
+ } finally {
94
+ resetRequireCache();
95
+ }
96
+ }
97
+
98
+ function captureOutput(name, output) {
99
+ capturedOutputs.push({ scenario: name, output: output });
100
+ }
101
+
102
+ // ---------- Fixtures ----------
103
+
104
+ function makeVintageV11016Pair() {
105
+ // A v1.10.16-vintage input pair: NO thesis, NO breakthrough.
106
+ // This is the regression baseline. The enhancement must NOT change
107
+ // its rendered frontmatter even by a single byte.
108
+ return {
109
+ lsa_score: 0.5,
110
+ semantic_score: 0.3,
111
+ abs_diff: 0.2,
112
+ signed_diff: -0.2,
113
+ direction: 'structural_transfer',
114
+ source_artifact_id: 'roomA/artifact-a',
115
+ target_artifact_id: 'roomB/artifact-b',
116
+ source_title: 'Source A',
117
+ target_title: 'Target B',
118
+ };
119
+ }
120
+
121
+ function make89_3PairWithThesis() {
122
+ return Object.assign(makeVintageV11016Pair(), {
123
+ thesis: 'By applying X to Y, achieve Z because mechanism.',
124
+ });
125
+ }
126
+
127
+ function make89_3PairWithBreakthrough() {
128
+ return Object.assign(makeVintageV11016Pair(), {
129
+ breakthrough: {
130
+ score: 5.9,
131
+ breakdown: {
132
+ feasibility: 2,
133
+ market: 1.5,
134
+ magnitude: 1,
135
+ advantage: 1.4,
136
+ impact: 0,
137
+ },
138
+ dominant_dimension: 'feasibility',
139
+ },
140
+ });
141
+ }
142
+
143
+ function make89_3PairWithBoth() {
144
+ return Object.assign(make89_3PairWithThesis(), {
145
+ breakthrough: {
146
+ score: 7.25,
147
+ breakdown: {
148
+ feasibility: 2,
149
+ market: 2,
150
+ magnitude: 1.5,
151
+ advantage: 1.75,
152
+ impact: 0,
153
+ },
154
+ dominant_dimension: 'feasibility',
155
+ },
156
+ });
157
+ }
158
+
159
+ // ---------- Scenarios ----------
160
+
161
+ async function main() {
162
+ process.stdout.write('=== 89.3-05 bridge-writer-enhanced suite (REPO_ROOT=' + REPO_ROOT + ') ===\n');
163
+
164
+ // -----------------------------------------------------------------
165
+ // Test 1 (REGRESSION): v1.10.16-vintage input renders byte-identical
166
+ // pre-89.3 frontmatter; NO thesis: NO breakthrough_score: emitted.
167
+ // -----------------------------------------------------------------
168
+ await runScenario('1-regression-byte-identical-v1.10.16', async () => {
169
+ const m = require('../core/bridge-writer.cjs');
170
+ const pair = makeVintageV11016Pair();
171
+ const out = m.renderBridgeArtifact(pair, 'bridge-001', { mode: 'internal' });
172
+
173
+ // All 13 pre-89.3 frontmatter fields present verbatim.
174
+ const requiredFields = [
175
+ 'brain_framework_classical: "framework:reverse-salient-analysis"',
176
+ 'brain_framework_algorithmic: "framework:algorithmic-generation-of-reverse-salient-solutions"',
177
+ 'brain_chain_next: ["framework:cross-domain-innovation", "framework:medici-effect"]',
178
+ 'brain_node_version: "2026-Q2"',
179
+ 'bridge_id: "bridge-001"',
180
+ 'mode: "internal"',
181
+ 'lsa_score: 0.5000',
182
+ 'semantic_score: 0.3000',
183
+ 'signed_diff: -0.2000',
184
+ 'abs_diff: 0.2000',
185
+ 'direction: "structural_transfer"',
186
+ 'source_room: "roomA"',
187
+ 'target_room: "roomB"',
188
+ 'external_source: ""',
189
+ 'external_id: ""',
190
+ 'generated_at:',
191
+ ];
192
+ for (const f of requiredFields) {
193
+ assert.ok(
194
+ out.includes(f),
195
+ 'regression: missing pre-89.3 field "' + f + '"'
196
+ );
197
+ }
198
+
199
+ // The 2 new fields MUST NOT appear when source pair lacks them.
200
+ assert.ok(!out.includes('thesis:'), 'regression: thesis: emitted when pair has no thesis');
201
+ assert.ok(!out.includes('breakthrough_score:'), 'regression: breakthrough_score: emitted when pair has no breakthrough');
202
+
203
+ captureOutput('1-regression-byte-identical-v1.10.16', out);
204
+ });
205
+
206
+ // -----------------------------------------------------------------
207
+ // Test 2 (89.3 thesis-only): pair has thesis, no breakthrough.
208
+ // Emits thesis: line AFTER generated_at: and BEFORE closing ---.
209
+ // Does NOT emit breakthrough_score: line.
210
+ // -----------------------------------------------------------------
211
+ await runScenario('2-89.3-thesis-only', async () => {
212
+ const m = require('../core/bridge-writer.cjs');
213
+ const pair = make89_3PairWithThesis();
214
+ const out = m.renderBridgeArtifact(pair, 'bridge-002', { mode: 'internal' });
215
+
216
+ assert.ok(
217
+ out.includes('thesis: "By applying X to Y, achieve Z because mechanism."'),
218
+ 'thesis: line not emitted with expected verbatim string'
219
+ );
220
+ assert.ok(!out.includes('breakthrough_score:'), 'breakthrough_score: emitted but pair has no breakthrough');
221
+
222
+ // Position assertion: thesis: line appears AFTER generated_at: and
223
+ // BEFORE the closing --- of the frontmatter block.
224
+ const idxGenerated = out.indexOf('generated_at:');
225
+ const idxThesis = out.indexOf('thesis:');
226
+ const idxClosingFence = out.indexOf('---', idxGenerated);
227
+ assert.ok(idxGenerated > 0, 'generated_at: missing');
228
+ assert.ok(idxThesis > idxGenerated, 'thesis: not after generated_at:');
229
+ assert.ok(idxThesis < idxClosingFence, 'thesis: not before closing ---');
230
+
231
+ captureOutput('2-89.3-thesis-only', out);
232
+ });
233
+
234
+ // -----------------------------------------------------------------
235
+ // Test 3 (89.3 breakthrough-only): pair has breakthrough, no thesis.
236
+ // Emits breakthrough_score: line; does NOT emit thesis: line.
237
+ // -----------------------------------------------------------------
238
+ await runScenario('3-89.3-breakthrough-only', async () => {
239
+ const m = require('../core/bridge-writer.cjs');
240
+ const pair = make89_3PairWithBreakthrough();
241
+ const out = m.renderBridgeArtifact(pair, 'bridge-003', { mode: 'internal' });
242
+
243
+ assert.ok(out.includes('breakthrough_score: 5.90'), 'breakthrough_score: 5.90 not emitted');
244
+ assert.ok(!out.includes('thesis:'), 'thesis: emitted but pair has no thesis');
245
+
246
+ captureOutput('3-89.3-breakthrough-only', out);
247
+ });
248
+
249
+ // -----------------------------------------------------------------
250
+ // Test 4 (89.3 both): pair has BOTH thesis + breakthrough.
251
+ // Both lines present; field order: thesis: BEFORE breakthrough_score:.
252
+ // -----------------------------------------------------------------
253
+ await runScenario('4-89.3-both-thesis-and-breakthrough', async () => {
254
+ const m = require('../core/bridge-writer.cjs');
255
+ const pair = make89_3PairWithBoth();
256
+ const out = m.renderBridgeArtifact(pair, 'bridge-004', { mode: 'internal' });
257
+
258
+ assert.ok(
259
+ out.includes('thesis: "By applying X to Y, achieve Z because mechanism."'),
260
+ 'thesis: line missing in both-fields scenario'
261
+ );
262
+ assert.ok(
263
+ out.includes('breakthrough_score: 7.25'),
264
+ 'breakthrough_score: 7.25 missing in both-fields scenario'
265
+ );
266
+
267
+ // Position assertion: thesis: BEFORE breakthrough_score:; both AFTER
268
+ // generated_at: and BEFORE closing ---.
269
+ const idxGenerated = out.indexOf('generated_at:');
270
+ const idxThesis = out.indexOf('thesis:');
271
+ const idxBreakthrough = out.indexOf('breakthrough_score:');
272
+ const idxClosingFence = out.indexOf('---', idxGenerated);
273
+ assert.ok(idxGenerated > 0 && idxThesis > idxGenerated, 'thesis: must follow generated_at:');
274
+ assert.ok(idxThesis < idxBreakthrough, 'thesis: must come BEFORE breakthrough_score:');
275
+ assert.ok(idxBreakthrough < idxClosingFence, 'breakthrough_score: must come BEFORE closing ---');
276
+
277
+ captureOutput('4-89.3-both-thesis-and-breakthrough', out);
278
+ });
279
+
280
+ // -----------------------------------------------------------------
281
+ // Test 5 (missing thesis omits gracefully): pair has breakthrough but
282
+ // pair.thesis === null. breakthrough_score: emitted; thesis: NOT.
283
+ // -----------------------------------------------------------------
284
+ await runScenario('5-missing-thesis-omits-gracefully', async () => {
285
+ const m = require('../core/bridge-writer.cjs');
286
+ const pair = make89_3PairWithBreakthrough();
287
+ pair.thesis = null;
288
+ const out = m.renderBridgeArtifact(pair, 'bridge-005', { mode: 'internal' });
289
+
290
+ assert.ok(out.includes('breakthrough_score: 5.90'), 'breakthrough_score: dropped');
291
+ assert.ok(!out.includes('thesis:'), 'thesis: emitted when pair.thesis is null');
292
+
293
+ // Same with empty string:
294
+ const pair2 = make89_3PairWithBreakthrough();
295
+ pair2.thesis = '';
296
+ const out2 = m.renderBridgeArtifact(pair2, 'bridge-005b', { mode: 'internal' });
297
+ assert.ok(!out2.includes('thesis:'), 'thesis: emitted when pair.thesis is empty string');
298
+
299
+ captureOutput('5-missing-thesis-omits-gracefully', out);
300
+ captureOutput('5b-missing-thesis-empty-string', out2);
301
+ });
302
+
303
+ // -----------------------------------------------------------------
304
+ // Test 6 (missing breakthrough omits gracefully): pair has thesis but
305
+ // pair.breakthrough === undefined OR pair.breakthrough.score not number.
306
+ // -----------------------------------------------------------------
307
+ await runScenario('6-missing-breakthrough-omits-gracefully', async () => {
308
+ const m = require('../core/bridge-writer.cjs');
309
+
310
+ // Case A: breakthrough undefined.
311
+ const pair = make89_3PairWithThesis();
312
+ const out = m.renderBridgeArtifact(pair, 'bridge-006', { mode: 'internal' });
313
+ assert.ok(out.includes('thesis:'), 'thesis: dropped');
314
+ assert.ok(!out.includes('breakthrough_score:'), 'breakthrough_score: emitted when breakthrough undefined');
315
+
316
+ // Case B: breakthrough present but score is not a number.
317
+ const pair2 = make89_3PairWithThesis();
318
+ pair2.breakthrough = { score: 'not-a-number', dominant_dimension: 'feasibility' };
319
+ const out2 = m.renderBridgeArtifact(pair2, 'bridge-006b', { mode: 'internal' });
320
+ assert.ok(!out2.includes('breakthrough_score:'), 'breakthrough_score: emitted when score is not numeric');
321
+
322
+ captureOutput('6-missing-breakthrough-omits-gracefully', out);
323
+ captureOutput('6b-breakthrough-non-numeric-score', out2);
324
+ });
325
+
326
+ // -----------------------------------------------------------------
327
+ // Test 7 (CANON PART 8 adversarial #1): forbidden pattern in
328
+ // pair.thesis must trigger ExternalEgressViolation via the audit
329
+ // run on the rendered output before return.
330
+ // -----------------------------------------------------------------
331
+ await runScenario('7-adv-CANON-PART-8-thesis-leak', async () => {
332
+ const m = require('../core/bridge-writer.cjs');
333
+ const violationsModule = require('../core/rs-egress-violations.cjs');
334
+ const ExternalEgressViolation = violationsModule.ExternalEgressViolation;
335
+
336
+ const pair = makeVintageV11016Pair();
337
+ // Use a leak pattern that survives YAML escaping (non-quoted bytes)
338
+ // and matches FORBIDDEN_PATTERNS authoritatively.
339
+ pair.thesis = 'By applying X to Y, but our meeting with Lawrence said the production model leaks';
340
+
341
+ let thrown = null;
342
+ try {
343
+ m.renderBridgeArtifact(pair, 'bridge-007', { mode: 'internal' });
344
+ } catch (err) {
345
+ thrown = err;
346
+ }
347
+ assert.ok(thrown, 'expected ExternalEgressViolation when pair.thesis carries forbidden pattern');
348
+ assert.ok(
349
+ thrown instanceof ExternalEgressViolation,
350
+ 'expected instance of ExternalEgressViolation; got ' + (thrown && thrown.name)
351
+ );
352
+ assert.equal(
353
+ thrown.meta && thrown.meta.surface,
354
+ 'bridge-writer-enhanced',
355
+ 'expected meta.surface === bridge-writer-enhanced'
356
+ );
357
+ });
358
+
359
+ // -----------------------------------------------------------------
360
+ // Test 8 (CANON PART 8 adversarial #2): forbidden pattern smuggled
361
+ // through pair.breakthrough (e.g. dominant_dimension carrying user
362
+ // content) MUST be caught by defense-in-depth even though only
363
+ // breakthrough.score reaches the rendered output. This proves the
364
+ // audit covers the WHOLE rendered string post-render, not just the
365
+ // numeric score scrub.
366
+ // -----------------------------------------------------------------
367
+ await runScenario('8-adv-CANON-PART-8-breakthrough-leak', async () => {
368
+ // Attack vector: a future implementation might emit dominant_dimension
369
+ // into the frontmatter. To prove defense-in-depth, set a pair.thesis
370
+ // that DOES surface to the rendered output AND is keyed off the
371
+ // breakthrough breakdown to simulate a real leak path.
372
+ const m = require('../core/bridge-writer.cjs');
373
+ const violationsModule = require('../core/rs-egress-violations.cjs');
374
+ const ExternalEgressViolation = violationsModule.ExternalEgressViolation;
375
+
376
+ const pair = make89_3PairWithBreakthrough();
377
+ // Smuggle a forbidden pattern via pair.thesis (which DOES reach the
378
+ // rendered output) since dominant_dimension is NOT currently
379
+ // emitted into frontmatter; the audit must still catch it before
380
+ // return. This proves the audit is on the FINAL rendered string,
381
+ // not on a scrubbed subset. We use a different forbidden pattern
382
+ // than Test 7 (Test 7 uses 'meeting with'+'Lawrence said'; this
383
+ // test uses an SSN-like sequence) to prove multiple FORBIDDEN_
384
+ // PATTERNS regexes all trip the chokepoint.
385
+ pair.thesis = 'By applying X to Y, achieve Z (priority code 123-45-6789)';
386
+
387
+ let thrown = null;
388
+ try {
389
+ m.renderBridgeArtifact(pair, 'bridge-008', { mode: 'internal' });
390
+ } catch (err) {
391
+ thrown = err;
392
+ }
393
+ assert.ok(thrown, 'expected ExternalEgressViolation when forbidden bytes reach rendered output');
394
+ assert.ok(
395
+ thrown instanceof ExternalEgressViolation,
396
+ 'expected instance of ExternalEgressViolation'
397
+ );
398
+ assert.equal(
399
+ thrown.meta && thrown.meta.surface,
400
+ 'bridge-writer-enhanced',
401
+ 'expected meta.surface === bridge-writer-enhanced'
402
+ );
403
+ // matched_pattern should reflect one of the FORBIDDEN_PATTERNS regexes.
404
+ assert.ok(
405
+ thrown.meta && thrown.meta.matched_pattern,
406
+ 'expected meta.matched_pattern to be set'
407
+ );
408
+ });
409
+
410
+ // -----------------------------------------------------------------
411
+ // A1 cross-scenario sweep: every captured rendered output (clean
412
+ // scenarios only) is JSON.stringify'd and scanned against the FULL
413
+ // FORBIDDEN_PATTERNS set. ZERO hits asserted.
414
+ // -----------------------------------------------------------------
415
+ process.stdout.write(' -- A1 sweep over ' + capturedOutputs.length + ' clean rendered outputs --\n');
416
+ let a1Hits = 0;
417
+ for (const cap of capturedOutputs) {
418
+ const text = JSON.stringify(cap.output);
419
+ for (const re of FORBIDDEN_PATTERNS) {
420
+ if (re.test(text)) {
421
+ a1Hits += 1;
422
+ process.stderr.write(' FAIL A1: ' + cap.scenario + ' matched ' + re + '\n');
423
+ }
424
+ }
425
+ }
426
+ if (a1Hits === 0) {
427
+ passed += 1;
428
+ process.stdout.write(' ok A1-sweep (zero forbidden-pattern hits across captured rendered outputs)\n');
429
+ } else {
430
+ failed += 1;
431
+ failures.push({ name: 'A1-sweep', err: new Error(a1Hits + ' forbidden-pattern hits in captured outputs') });
432
+ }
433
+
434
+ // -----------------------------------------------------------------
435
+ // Final summary.
436
+ // -----------------------------------------------------------------
437
+ if (failed > 0) {
438
+ process.stderr.write(
439
+ '\n=== 89.3-05 bridge-writer-enhanced suite: ' +
440
+ failed + ' failed, ' + passed + ' passed ===\n'
441
+ );
442
+ process.exit(1);
443
+ }
444
+ process.stdout.write(
445
+ '\n=== 89.3-05 bridge-writer-enhanced suite: 8/8 passed ===\n'
446
+ );
447
+ }
448
+
449
+ main().catch((err) => {
450
+ process.stderr.write('FATAL: ' + (err && err.stack ? err.stack : err) + '\n');
451
+ process.exit(1);
452
+ });