@mindrian_os/install 1.13.0-beta.16 → 1.13.0-beta.19

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 (219) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/CHANGELOG.md +36 -0
  3. package/commands/act.md +1 -0
  4. package/commands/admin.md +1 -0
  5. package/commands/analyze-needs.md +2 -0
  6. package/commands/analyze-systems.md +2 -0
  7. package/commands/analyze-timing.md +2 -0
  8. package/commands/auto-explore.md +2 -0
  9. package/commands/beautiful-question.md +2 -0
  10. package/commands/brain-derive.md +2 -0
  11. package/commands/build-knowledge.md +2 -0
  12. package/commands/build-thesis.md +2 -0
  13. package/commands/causal.md +2 -0
  14. package/commands/challenge-assumptions.md +2 -0
  15. package/commands/compare-ventures.md +2 -0
  16. package/commands/dashboard.md +2 -1
  17. package/commands/deep-grade.md +2 -0
  18. package/commands/diagnose.md +21 -1
  19. package/commands/diagnostics.md +14 -3
  20. package/commands/doctor.md +4 -1
  21. package/commands/dogfood-flush.md +92 -0
  22. package/commands/dominant-designs.md +2 -0
  23. package/commands/explain-decision.md +2 -0
  24. package/commands/explore-domains.md +2 -0
  25. package/commands/explore-futures.md +2 -0
  26. package/commands/explore-trends.md +2 -0
  27. package/commands/export.md +1 -0
  28. package/commands/feynman-timeline-refresh.md +2 -0
  29. package/commands/file-meeting.md +4 -0
  30. package/commands/find-analogies.md +1 -0
  31. package/commands/find-bottlenecks.md +2 -0
  32. package/commands/find-connections.md +2 -0
  33. package/commands/funding.md +1 -0
  34. package/commands/grade.md +4 -0
  35. package/commands/graph.md +1 -0
  36. package/commands/hat-briefing.md +1 -0
  37. package/commands/heal.md +22 -170
  38. package/commands/help.md +54 -334
  39. package/commands/hmi-status.md +23 -144
  40. package/commands/jtbd.md +1 -0
  41. package/commands/leadership.md +2 -0
  42. package/commands/lean-canvas.md +2 -0
  43. package/commands/macro-trends.md +2 -0
  44. package/commands/map-unknowns.md +2 -0
  45. package/commands/memory.md +1 -0
  46. package/commands/models.md +1 -0
  47. package/commands/mos-reason.md +2 -0
  48. package/commands/mos.md +139 -0
  49. package/commands/mullins.md +2 -0
  50. package/commands/mva-brief.md +58 -0
  51. package/commands/mva-option.md +91 -0
  52. package/commands/new-project.md +4 -0
  53. package/commands/onboard.md +22 -7
  54. package/commands/operator.md +1 -0
  55. package/commands/opportunities.md +1 -0
  56. package/commands/organize.md +22 -469
  57. package/commands/persona.md +1 -0
  58. package/commands/pipeline.md +2 -0
  59. package/commands/present.md +1 -0
  60. package/commands/publish.md +2 -0
  61. package/commands/query.md +24 -102
  62. package/commands/radar.md +2 -0
  63. package/commands/reanalyze.md +1 -0
  64. package/commands/research.md +2 -0
  65. package/commands/room.md +2 -0
  66. package/commands/rooms.md +1 -0
  67. package/commands/root-cause.md +2 -0
  68. package/commands/rs-experts.md +1 -0
  69. package/commands/rs-explain.md +1 -0
  70. package/commands/rs-fetch.md +1 -0
  71. package/commands/rs-thesis.md +1 -0
  72. package/commands/scenario-plan.md +2 -0
  73. package/commands/scheduled-tasks.md +1 -0
  74. package/commands/score-innovation.md +2 -0
  75. package/commands/scout.md +1 -0
  76. package/commands/setup.md +2 -0
  77. package/commands/snapshot.md +2 -0
  78. package/commands/speakers.md +1 -0
  79. package/commands/splash.md +5 -2
  80. package/commands/status.md +1 -0
  81. package/commands/structure-argument.md +2 -0
  82. package/commands/suggest-next.md +2 -0
  83. package/commands/systems-thinking.md +2 -0
  84. package/commands/think-hats.md +2 -0
  85. package/commands/update.md +2 -0
  86. package/commands/user-needs.md +2 -0
  87. package/commands/validate.md +2 -0
  88. package/commands/value-proposition.md +2 -0
  89. package/commands/vault.md +2 -0
  90. package/commands/visualize.md +24 -29
  91. package/commands/whitespace.md +2 -1
  92. package/commands/wiki.md +1 -0
  93. package/hooks/hooks.json +31 -88
  94. package/lib/agents/auto-explore-agent.cjs +82 -0
  95. package/lib/agents/mva/brain-classic-traps.cjs +77 -0
  96. package/lib/agents/mva/brain-cross-domain.cjs +79 -0
  97. package/lib/agents/mva/brain-similar-ventures.cjs +93 -0
  98. package/lib/agents/mva/dashboard-graph-neighborhood.cjs +72 -0
  99. package/lib/agents/mva/index.cjs +42 -0
  100. package/lib/agents/mva/six-hats-red-black.cjs +137 -0
  101. package/lib/agents/mva/tavily-funding-scan.cjs +147 -0
  102. package/lib/agents/mva/test-all-six-agents.cjs +467 -0
  103. package/lib/conversation/operator.cjs +64 -0
  104. package/lib/conversation/operator.test.cjs +160 -0
  105. package/lib/core/breakthrough/canary.cjs +134 -0
  106. package/lib/core/breakthrough/canary.test.cjs +136 -0
  107. package/lib/core/breakthrough/detectors.cjs +359 -0
  108. package/lib/core/breakthrough/detectors.test.cjs +333 -0
  109. package/lib/core/breakthrough/ethics-fence.cjs +127 -0
  110. package/lib/core/breakthrough/ethics-fence.test.cjs +178 -0
  111. package/lib/core/breakthrough/resurfacing.cjs +150 -0
  112. package/lib/core/breakthrough/resurfacing.test.cjs +233 -0
  113. package/lib/core/breakthrough/review-queue.cjs +154 -0
  114. package/lib/core/breakthrough/review-queue.test.cjs +160 -0
  115. package/lib/core/breakthrough/scanner-d17-d18.test.cjs +229 -0
  116. package/lib/core/breakthrough/scanner.cjs +426 -0
  117. package/lib/core/breakthrough/scanner.test.cjs +267 -0
  118. package/lib/core/breakthrough/schema.cjs +164 -0
  119. package/lib/core/breakthrough/schema.test.cjs +256 -0
  120. package/lib/core/breakthrough/scoring.cjs +293 -0
  121. package/lib/core/breakthrough/scoring.test.cjs +423 -0
  122. package/lib/core/breakthrough/verb-dispatch.cjs +221 -0
  123. package/lib/core/breakthrough/verb-dispatch.test.cjs +185 -0
  124. package/lib/core/breakthrough/voice-scaffold.cjs +247 -0
  125. package/lib/core/breakthrough/voice-scaffold.test.cjs +251 -0
  126. package/lib/core/first-touch-version-stamper.cjs +113 -0
  127. package/lib/core/larry-thinness-acknowledgment.cjs +64 -0
  128. package/lib/core/larry-thinness-acknowledgment.test.cjs +97 -0
  129. package/lib/core/llm-name-suggester.cjs +194 -0
  130. package/lib/core/llm-name-suggester.test.cjs +132 -0
  131. package/lib/core/mva-agent-contract.cjs +170 -0
  132. package/lib/core/mva-agent-contract.test.cjs +169 -0
  133. package/lib/core/mva-budget.cjs +75 -0
  134. package/lib/core/mva-budget.test.cjs +68 -0
  135. package/lib/core/mva-classifier.cjs +370 -0
  136. package/lib/core/mva-classifier.test.cjs +248 -0
  137. package/lib/core/mva-deck-builder.cjs +452 -0
  138. package/lib/core/mva-deck-builder.test.cjs +287 -0
  139. package/lib/core/mva-detect.smoke.test.cjs +197 -0
  140. package/lib/core/mva-dispatcher.cjs +110 -0
  141. package/lib/core/mva-dispatcher.test.cjs +216 -0
  142. package/lib/core/mva-option-router.cjs +292 -0
  143. package/lib/core/mva-option-router.test.cjs +483 -0
  144. package/lib/core/mva-orchestrator.cjs +365 -0
  145. package/lib/core/mva-orchestrator.test.cjs +908 -0
  146. package/lib/core/mva-progressive-renderer.cjs +194 -0
  147. package/lib/core/mva-progressive-renderer.test.cjs +157 -0
  148. package/lib/core/mva-rule-linter.cjs +213 -0
  149. package/lib/core/mva-rule-linter.test.cjs +336 -0
  150. package/lib/core/mva-state.cjs +159 -0
  151. package/lib/core/mva-telemetry.cjs +58 -0
  152. package/lib/core/mva-telemetry.test.cjs +196 -0
  153. package/lib/core/mva-vercel-deploy.cjs +168 -0
  154. package/lib/core/mva-vercel-deploy.test.cjs +239 -0
  155. package/lib/core/navigation/dashboard-helpers.cjs +145 -0
  156. package/lib/core/navigation/edges.cjs +35 -0
  157. package/lib/core/navigation/memory-events.cjs +126 -0
  158. package/lib/core/navigation.cjs +11 -0
  159. package/lib/core/resolve-vercel-key.cjs +107 -0
  160. package/lib/core/resolve-vercel-key.test.cjs +137 -0
  161. package/lib/core/room-auto-create.cjs +318 -0
  162. package/lib/core/room-auto-create.test.cjs +198 -0
  163. package/lib/core/room-discard-cascade.cjs +225 -0
  164. package/lib/core/room-discard-cascade.test.cjs +135 -0
  165. package/lib/core/room-name-validator.cjs +132 -0
  166. package/lib/core/room-name-validator.test.cjs +156 -0
  167. package/lib/core/room-naming-selector.cjs +357 -0
  168. package/lib/core/room-naming-selector.test.cjs +277 -0
  169. package/lib/core/room-receipt-emit.cjs +63 -0
  170. package/lib/core/room-skeleton-scaffold.cjs +315 -0
  171. package/lib/core/room-skeleton-scaffold.test.cjs +291 -0
  172. package/lib/core/stale-copy-scanner.cjs +190 -0
  173. package/lib/core/state-aware-router.cjs +78 -0
  174. package/lib/core/telemetry/schema.cjs +168 -0
  175. package/lib/core/telemetry/schema.test.cjs +124 -0
  176. package/lib/core/telemetry/validator.cjs +197 -0
  177. package/lib/core/telemetry/validator.test.cjs +188 -0
  178. package/lib/core/telemetry/writer.cjs +141 -0
  179. package/lib/core/telemetry/writer.test.cjs +331 -0
  180. package/lib/core/terminal-capability.cjs +88 -0
  181. package/lib/core/venture-shape-nudge.cjs +163 -0
  182. package/lib/core/venture-shape-nudge.test.cjs +161 -0
  183. package/lib/core/visual-ops.cjs +70 -2
  184. package/lib/hmi/selector-dispatcher.cjs +90 -1
  185. package/lib/hmi/shape-f7-breakthrough-renderer.cjs +222 -0
  186. package/lib/hmi/shape-f7-breakthrough-renderer.test.cjs +233 -0
  187. package/lib/memory/body-shape-coverage.test.cjs +268 -0
  188. package/lib/memory/doctor-deprecation-surface.test.cjs +185 -0
  189. package/lib/memory/first-touch-version.test.cjs +198 -0
  190. package/lib/memory/help-coverage.test.cjs +108 -0
  191. package/lib/memory/help-renderer.test.cjs +145 -0
  192. package/lib/memory/palette-consistency.test.cjs +127 -0
  193. package/lib/memory/pending-tension-store.cjs +80 -0
  194. package/lib/memory/render-v2-disposition.test.cjs +199 -0
  195. package/lib/memory/run-feynman-tests.cjs +240 -0
  196. package/lib/memory/sessionstart-coordinator.test.cjs +446 -0
  197. package/lib/memory/skill-vs-code-drift.test.cjs +257 -0
  198. package/lib/memory/soft-alias.test.cjs +144 -0
  199. package/lib/memory/stale-copy-scanner.test.cjs +291 -0
  200. package/lib/memory/state-aware-router.test.cjs +90 -0
  201. package/lib/memory/statusline-two-row.test.cjs +338 -0
  202. package/lib/memory/terminal-capability.test.cjs +155 -0
  203. package/lib/render/ROOM.md +74 -22
  204. package/lib/sessionstart/budget-compressor.cjs +130 -0
  205. package/lib/sessionstart/contributor-interface.cjs +134 -0
  206. package/lib/sessionstart/contributor-isolator.cjs +128 -0
  207. package/lib/sessionstart/precedence-ladder.cjs +47 -0
  208. package/lib/statusline/governing-thought-truncator.cjs +45 -0
  209. package/lib/statusline/two-row-renderer.cjs +186 -0
  210. package/lib/statusline/version-resolver.cjs +81 -0
  211. package/package.json +1 -1
  212. package/references/visual/ROOM.md +55 -0
  213. package/references/visual/palette.json +54 -0
  214. package/skills/larry-personality/SKILL.md +34 -0
  215. package/skills/mva-pipeline/SKILL.md +129 -0
  216. package/skills/ui-system/SKILL.md +109 -1
  217. package/skills/ui-system/rules/dual-palette.md +156 -0
  218. package/skills/ui-system/rules/glyph-disambiguation.md +171 -0
  219. package/skills/ui-system/rules/shape-f-zero-and-six.md +169 -0
package/hooks/hooks.json CHANGED
@@ -18,88 +18,10 @@
18
18
  "hooks": [
19
19
  {
20
20
  "type": "command",
21
- "command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/operator-update.cjs\"",
22
- "timeout": 3000
23
- }
24
- ]
25
- },
26
- {
27
- "matcher": "startup|clear|compact",
28
- "hooks": [
29
- {
30
- "type": "command",
31
- "command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/memory-resume-nudge.cjs\"",
32
- "timeout": 3000
33
- }
34
- ]
35
- },
36
- {
37
- "matcher": "startup|clear|compact",
38
- "hooks": [
39
- {
40
- "type": "command",
41
- "command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/migrate-stale-user-settings.cjs\" --auto --quiet",
42
- "timeout": 2000
43
- }
44
- ]
45
- },
46
- {
47
- "matcher": "startup|clear|compact",
48
- "hooks": [
49
- {
50
- "type": "command",
51
- "command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/statusline-fallback-echo.cjs\"",
52
- "timeout": 2000
53
- }
54
- ]
55
- },
56
- {
57
- "matcher": "startup|clear|compact",
58
- "hooks": [
59
- {
60
- "type": "command",
61
- "command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/check-onboard-statusline.cjs\"",
62
- "timeout": 2000
63
- }
64
- ]
65
- },
66
- {
67
- "matcher": "startup|clear|compact",
68
- "hooks": [
69
- {
70
- "type": "command",
71
- "command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/preflight-tension-surface.cjs\"",
72
- "timeout": 3000
73
- }
74
- ]
75
- },
76
- {
77
- "matcher": "startup|clear|compact",
78
- "hooks": [
79
- {
80
- "type": "command",
81
- "command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/preflight-doctor.cjs\"",
82
- "timeout": 2000
83
- }
84
- ]
85
- },
86
- {
87
- "matcher": "startup|clear|compact",
88
- "hooks": [
89
- {
90
- "type": "command",
91
- "command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/preflight-release-drift.cjs\"",
92
- "timeout": 2000
93
- }
94
- ]
95
- },
96
- {
97
- "matcher": "startup|clear|compact",
98
- "hooks": [
99
- {
100
- "type": "command",
101
- "command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/preflight-auto-explore.cjs\"",
102
- "timeout": 3000
21
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/sessionstart-coordinator.cjs\"",
22
+ "timeout": 10000,
23
+ "async": false,
24
+ "statusMessage": "Loading room context..."
103
25
  }
104
26
  ]
105
27
  },
@@ -108,8 +30,10 @@
108
30
  "hooks": [
109
31
  {
110
32
  "type": "command",
111
- "command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/restore-post-compact-context.cjs\"",
112
- "timeout": 3000
33
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/sessionstart-npm-reconcile.cjs\"",
34
+ "timeout": 60000,
35
+ "async": true,
36
+ "statusMessage": "Reconciling dependencies..."
113
37
  }
114
38
  ]
115
39
  },
@@ -118,10 +42,10 @@
118
42
  "hooks": [
119
43
  {
120
44
  "type": "command",
121
- "command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/sessionstart-npm-reconcile.cjs\"",
122
- "timeout": 60000,
123
- "async": true,
124
- "statusMessage": "Reconciling dependencies..."
45
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/check-pending-breakthrough.cjs\"",
46
+ "timeout": 2000,
47
+ "async": false,
48
+ "statusMessage": "Scanning for breakthroughs..."
125
49
  }
126
50
  ]
127
51
  }
@@ -280,6 +204,16 @@
280
204
  "timeout": 3000
281
205
  }
282
206
  ]
207
+ },
208
+ {
209
+ "matcher": "SlashCommand",
210
+ "hooks": [
211
+ {
212
+ "type": "command",
213
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/telemetry-command-invocation.cjs\"",
214
+ "timeout": 5000
215
+ }
216
+ ]
283
217
  }
284
218
  ],
285
219
  "UserPromptSubmit": [
@@ -292,6 +226,15 @@
292
226
  }
293
227
  ]
294
228
  },
229
+ {
230
+ "hooks": [
231
+ {
232
+ "type": "command",
233
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/mva-detect.cjs\"",
234
+ "timeout": 1500
235
+ }
236
+ ]
237
+ },
295
238
  {
296
239
  "hooks": [
297
240
  {
@@ -46,6 +46,26 @@ const path = require('node:path');
46
46
  const crypto = require('node:crypto');
47
47
  const store = require('../memory/explored-materials-store.cjs');
48
48
 
49
+ // Phase 121-02 D-06: vocabulary maps for unified auto_explore_decision emit.
50
+ // Phase 117 source_pipeline {domain, reverse-salients, cross-domain}
51
+ // -> unified finding_type {whitespace, reverse_salient, cross_domain}.
52
+ // Phase 117 F.1 verbs {EXPLORE, LATER, SKIP}
53
+ // -> unified user_response {kept, redid, ignored}.
54
+ // FREE_TEXT is intentionally EXCLUDED -- it is a system fallback when the
55
+ // navigator types prose; it is not a clean engagement signal.
56
+ // auto_explore_skipped (system-driven suppress paths) is also EXCLUDED --
57
+ // those fire from emitSkipped, never from handleUserResponse.
58
+ const D06_FINDING_TYPE_MAP = Object.freeze({
59
+ 'domain': 'whitespace',
60
+ 'reverse-salients': 'reverse_salient',
61
+ 'cross-domain': 'cross_domain',
62
+ });
63
+ const D06_USER_RESPONSE_MAP = Object.freeze({
64
+ EXPLORE: 'kept',
65
+ LATER: 'redid',
66
+ SKIP: 'ignored',
67
+ });
68
+
49
69
  // ---------- Constants ----------
50
70
 
51
71
  const MATERIAL_ID_LEN = 32;
@@ -773,6 +793,36 @@ function handleUserResponse(args) {
773
793
  });
774
794
  } catch (_e) { /* never throw on telemetry */ }
775
795
 
796
+ // Phase 121-02 D-06: capture user F.1 decision into the unified
797
+ // ~/.mindrian/telemetry/v1.13/events-YYYY-WNN.jsonl stream (Plan 121-00
798
+ // writer chokepoint). Emit ONLY for the 3 engagement verbs
799
+ // (EXPLORE -> kept, LATER -> redid, SKIP -> ignored). FREE_TEXT is a
800
+ // system fallback and is intentionally excluded. auto_explore_skipped
801
+ // (fingerprint/fire suppress paths) is NEVER routed through this
802
+ // function and therefore cannot emit auto_explore_decision either.
803
+ // Non-blocking: try/catch swallows any writer breach so the handler
804
+ // still returns ok:true to its caller (the F.1 surface).
805
+ try {
806
+ if (D06_USER_RESPONSE_MAP[userResponse]) {
807
+ let writer = null;
808
+ try { writer = require('../core/telemetry/writer.cjs'); } catch (_e) { writer = null; }
809
+ if (writer && typeof writer.emit === 'function') {
810
+ const findingType = D06_FINDING_TYPE_MAP[String(finding.source_pipeline || '')] || 'whitespace';
811
+ const score = (typeof finding.score === 'number' && Number.isFinite(finding.score))
812
+ ? finding.score
813
+ : 0;
814
+ const slugSrc = String(roomSlug || (roomDir ? path.basename(roomDir) : '')).slice(0, 256);
815
+ const slugHash = crypto.createHash('sha256').update(slugSrc).digest('hex');
816
+ writer.emit('auto_explore_decision', {
817
+ finding_type: String(findingType).slice(0, 64),
818
+ user_response: D06_USER_RESPONSE_MAP[userResponse],
819
+ domain_match_score: score,
820
+ room_slug_sha256: slugHash,
821
+ });
822
+ }
823
+ }
824
+ } catch (_e) { /* never throw on telemetry */ }
825
+
776
826
  return {
777
827
  ok: true,
778
828
  response: userResponse,
@@ -1014,6 +1064,36 @@ function _resetDriftCacheForTests() {
1014
1064
  _driftEmittedThisSession = false;
1015
1065
  }
1016
1066
 
1067
+ /**
1068
+ * Phase 119-00 helper: read $ROOMS_HOME/.rooms/registry.json and return true
1069
+ * iff there is no active room (registry missing OR registry.active is empty
1070
+ * string).
1071
+ *
1072
+ * Used by scripts/auto-explore-fingerprint.cjs to decide whether to call
1073
+ * lib/core/room-auto-create.cjs::autoCreatePlaceholderRoom as a sibling action.
1074
+ *
1075
+ * Per CONTEXT.md D-01: only the "first material lands AND no active room"
1076
+ * configuration triggers auto-create. An active room means the user already
1077
+ * chose a room; never overwrite.
1078
+ *
1079
+ * Pure file-read; no network, no Brain MCP. Canon Part 8 boundary preserved.
1080
+ *
1081
+ * @param {string} roomsHome absolute path to $ROOMS_HOME (or $MINDRIAN_ROOMS_HOME)
1082
+ * @returns {boolean}
1083
+ */
1084
+ function detectNoActiveRoom(roomsHome) {
1085
+ if (!roomsHome || typeof roomsHome !== 'string') return true;
1086
+ const registryPath = path.join(roomsHome, '.rooms', 'registry.json');
1087
+ try {
1088
+ if (!fs.existsSync(registryPath)) return true;
1089
+ const raw = fs.readFileSync(registryPath, 'utf8');
1090
+ const reg = JSON.parse(raw);
1091
+ return !(reg && typeof reg.active === 'string' && reg.active.length > 0);
1092
+ } catch (_e) {
1093
+ return true; // unreadable registry -> treat as no-active-room (fail-open to auto-create)
1094
+ }
1095
+ }
1096
+
1017
1097
  // ---------- Module exports ----------
1018
1098
 
1019
1099
  module.exports = {
@@ -1033,6 +1113,8 @@ module.exports = {
1033
1113
  emitSkipped,
1034
1114
  emitSanitizerHit,
1035
1115
  emitBrainCanonDrift,
1116
+ // Phase 119-00 sibling helper (D-01 invariant check for the auto-create hook):
1117
+ detectNoActiveRoom,
1036
1118
  // Constants:
1037
1119
  BQ_TEMPLATE_REGISTRY,
1038
1120
  CANONICAL_CHAIN_ORDER,
@@ -0,0 +1,77 @@
1
+ /*
2
+ * Copyright (c) 2026 Mindrian. BSL 1.1.
3
+ *
4
+ * Phase 118-02 Plan 02 Task 1 -- brain-classic-traps agent (Agent 3 of 6 in
5
+ * B1; agent_id 'brain_classic_traps' in lib/agents/mva/index.cjs).
6
+ *
7
+ * Calls Brain via lib/core/brain-client.cjs::query() with a GENERIC Cypher
8
+ * template from data/mva-agent-prompts.json. Returns top-1 FailureMode pattern
9
+ * with a "Classic trap:" summary line.
10
+ *
11
+ * Graph-native HARD RULES (memory feedback_reverse_salient_agent_graph_native.md):
12
+ * 1. NEVER require room-db.cjs directly (Phase 109 D-06 chokepoint).
13
+ * 2. NEVER require any Brain-MCP client module DIRECTLY for raw queries;
14
+ * use lib/core/brain-client.cjs which enforces the wire-schema sanitization
15
+ * AND only with framework-name/phase-id/enum args, never user content.
16
+ * 3. NEVER write to stdout / stderr (telemetry side-channel rule).
17
+ *
18
+ * Canon Part 8 hard invariant (MVA-118-10):
19
+ * The Cypher carries ONLY $-bound parameters with hardcoded stage labels.
20
+ * NEVER the user's raw sentence. NEVER the sentence_sha256 as a Cypher
21
+ * string interpolation. NEVER any user-content env var (token name elided
22
+ * per the Test 6 grep regression).
23
+ *
24
+ * Pure CJS, node built-ins only, zero new runtime dependencies.
25
+ */
26
+ 'use strict';
27
+
28
+ const path = require('node:path');
29
+ const brainClient = require('../../core/brain-client.cjs');
30
+
31
+ const PROMPTS_PATH = path.resolve(__dirname, '..', '..', '..', 'data', 'mva-agent-prompts.json');
32
+
33
+ /**
34
+ * @param {{ sentence_sha256: string, remaining_budget_ms: number }} _context
35
+ * @param {AbortSignal} signal
36
+ * @returns {Promise<{ status:'ok'|'empty', payload:any } | null>}
37
+ */
38
+ async function run(_context, signal) {
39
+ if (!brainClient.isAvailable()) {
40
+ return { status: 'empty', payload: { reason: 'brain_unavailable' } };
41
+ }
42
+ if (signal && signal.aborted) return null;
43
+
44
+ let prompts;
45
+ try {
46
+ prompts = require(PROMPTS_PATH).brain_classic_traps;
47
+ } catch (_e) {
48
+ return { status: 'empty', payload: { reason: 'prompts_unavailable' } };
49
+ }
50
+
51
+ let result;
52
+ try {
53
+ result = await brainClient.query(prompts.cypher, prompts.params);
54
+ } catch (_e) {
55
+ return { status: 'empty', payload: { reason: 'brain_error' } };
56
+ }
57
+
58
+ if (signal && signal.aborted) return null;
59
+
60
+ const records = (result && Array.isArray(result.records)) ? result.records : [];
61
+ if (records.length === 0) {
62
+ return { status: 'empty', payload: { reason: 'no_trap' } };
63
+ }
64
+ const trap = records[0];
65
+ const tail = trap.signature || 'classic failure pattern';
66
+ const summary = 'Classic trap: ' + (trap.name || 'unnamed') + ' -- ' + tail;
67
+
68
+ return {
69
+ status: 'ok',
70
+ payload: {
71
+ summary_line: summary,
72
+ deck_data: { trap: trap },
73
+ },
74
+ };
75
+ }
76
+
77
+ module.exports = { run };
@@ -0,0 +1,79 @@
1
+ /*
2
+ * Copyright (c) 2026 Mindrian. BSL 1.1.
3
+ *
4
+ * Phase 118-02 Plan 02 Task 1 -- brain-cross-domain agent (Agent 2 of 6 in
5
+ * B1; agent_id 'brain_cross_domain' in lib/agents/mva/index.cjs).
6
+ *
7
+ * Calls Brain via lib/core/brain-client.cjs::search() in cross-domain mode
8
+ * (GENERIC handle from data/mva-agent-prompts.json) and returns top-1
9
+ * analogous framework with a one-line "Cross-domain analogy:" summary.
10
+ *
11
+ * Graph-native HARD RULES (memory feedback_reverse_salient_agent_graph_native.md):
12
+ * 1. NEVER require room-db.cjs directly (Phase 109 D-06 chokepoint).
13
+ * 2. NEVER require any Brain-MCP client module DIRECTLY for raw queries;
14
+ * use lib/core/brain-client.cjs which enforces the wire-schema sanitization
15
+ * AND only with framework-name/phase-id/enum args, never user content.
16
+ * 3. NEVER write to stdout / stderr (telemetry side-channel rule).
17
+ *
18
+ * Canon Part 8 hard invariant (MVA-118-09):
19
+ * The Brain query carries ONLY a hardcoded generic handle. NEVER the user's
20
+ * raw sentence. NEVER the sentence_sha256 as a free-text query body. NEVER
21
+ * any user-content env var (token name elided per the Test 6 grep regression).
22
+ *
23
+ * Pure CJS, node built-ins only, zero new runtime dependencies.
24
+ */
25
+ 'use strict';
26
+
27
+ const path = require('node:path');
28
+ const brainClient = require('../../core/brain-client.cjs');
29
+
30
+ const PROMPTS_PATH = path.resolve(__dirname, '..', '..', '..', 'data', 'mva-agent-prompts.json');
31
+
32
+ /**
33
+ * @param {{ sentence_sha256: string, remaining_budget_ms: number }} _context
34
+ * @param {AbortSignal} signal
35
+ * @returns {Promise<{ status:'ok'|'empty', payload:any } | null>}
36
+ */
37
+ async function run(_context, signal) {
38
+ if (!brainClient.isAvailable()) {
39
+ return { status: 'empty', payload: { reason: 'brain_unavailable' } };
40
+ }
41
+ if (signal && signal.aborted) return null;
42
+
43
+ let prompts;
44
+ try {
45
+ prompts = require(PROMPTS_PATH).brain_cross_domain;
46
+ } catch (_e) {
47
+ return { status: 'empty', payload: { reason: 'prompts_unavailable' } };
48
+ }
49
+
50
+ let result;
51
+ try {
52
+ result = await brainClient.search(prompts.query, {
53
+ filters: prompts.filters,
54
+ limit: prompts.limit,
55
+ });
56
+ } catch (_e) {
57
+ return { status: 'empty', payload: { reason: 'brain_error' } };
58
+ }
59
+
60
+ if (signal && signal.aborted) return null;
61
+
62
+ const analogies = (result && Array.isArray(result.results)) ? result.results : [];
63
+ if (analogies.length === 0) {
64
+ return { status: 'empty', payload: { reason: 'no_analogy' } };
65
+ }
66
+ const analogy = analogies[0];
67
+ const tail = analogy.signature || 'pattern transfer applicable';
68
+ const summary = 'Cross-domain analogy: ' + (analogy.name || 'unnamed') + ' -- ' + tail;
69
+
70
+ return {
71
+ status: 'ok',
72
+ payload: {
73
+ summary_line: summary,
74
+ deck_data: { analogy: analogy },
75
+ },
76
+ };
77
+ }
78
+
79
+ module.exports = { run };
@@ -0,0 +1,93 @@
1
+ /*
2
+ * Copyright (c) 2026 Mindrian. BSL 1.1.
3
+ *
4
+ * Phase 118-02 Plan 02 Task 1 -- brain-similar-ventures agent (Agent 1 of 6
5
+ * in B1; agent_id 'brain_similar' in lib/agents/mva/index.cjs).
6
+ *
7
+ * Calls Brain via lib/core/brain-client.cjs::search() with a GENERIC handle
8
+ * from data/mva-agent-prompts.json. Returns the top-3 venture matches with a
9
+ * one-line human-readable summary + structured deck_data.
10
+ *
11
+ * Mirrors lib/agents/auto-explore-agent.cjs structure verbatim per the plan.
12
+ *
13
+ * Graph-native HARD RULES (memory feedback_reverse_salient_agent_graph_native.md):
14
+ * 1. NEVER require room-db.cjs directly (Phase 109 D-06 chokepoint).
15
+ * 2. NEVER require any Brain-MCP client module DIRECTLY for raw queries;
16
+ * use lib/core/brain-client.cjs which enforces the wire-schema sanitization
17
+ * AND only with framework-name/phase-id/enum args, never user content.
18
+ * 3. NEVER write to stdout / stderr (telemetry side-channel rule).
19
+ *
20
+ * Canon Part 8 hard invariant (MVA-118-08):
21
+ * The Brain query carries ONLY generic handles loaded from
22
+ * data/mva-agent-prompts.json. NEVER the user's raw sentence. NEVER the
23
+ * sentence_sha256 as a free-text query body. NEVER any user-content env
24
+ * var (which is never set; see Plan 118-01's AgentContext invariant -- the
25
+ * sentence-bearing env var name is elided here so the grep regression in
26
+ * test-all-six-agents.cjs Test 6 returns zero matches on this file).
27
+ *
28
+ * Pure CJS, node built-ins only, zero new runtime dependencies.
29
+ */
30
+ 'use strict';
31
+
32
+ const path = require('node:path');
33
+ const brainClient = require('../../core/brain-client.cjs');
34
+
35
+ const PROMPTS_PATH = path.resolve(__dirname, '..', '..', '..', 'data', 'mva-agent-prompts.json');
36
+
37
+ /**
38
+ * Agent run function. Conforms to the Plan 118-01 Agent contract:
39
+ * async function agent(context, signal) -> { status:'ok'|'empty', payload } | null
40
+ *
41
+ * @param {{ sentence_sha256: string, remaining_budget_ms: number }} _context
42
+ * @param {AbortSignal} signal
43
+ * @returns {Promise<{ status:'ok'|'empty', payload:any } | null>}
44
+ */
45
+ async function run(_context, signal) {
46
+ // Fast-fail when Brain is unreachable (no key configured). Per the plan's
47
+ // done-criteria: this must return status='empty' in <100ms.
48
+ if (!brainClient.isAvailable()) {
49
+ return { status: 'empty', payload: { reason: 'brain_unavailable' } };
50
+ }
51
+ if (signal && signal.aborted) return null;
52
+
53
+ // Load the generic prompt template. Per Canon Part 8 this file is the SOLE
54
+ // source of Brain query bodies for this agent -- audited in one place.
55
+ let prompts;
56
+ try {
57
+ // require() caches; that is desirable here (the JSON is static config).
58
+ prompts = require(PROMPTS_PATH).brain_similar_ventures;
59
+ } catch (_e) {
60
+ return { status: 'empty', payload: { reason: 'prompts_unavailable' } };
61
+ }
62
+
63
+ let result;
64
+ try {
65
+ result = await brainClient.search(prompts.query, {
66
+ filters: prompts.filters,
67
+ limit: prompts.limit,
68
+ });
69
+ } catch (_e) {
70
+ return { status: 'empty', payload: { reason: 'brain_error' } };
71
+ }
72
+
73
+ if (signal && signal.aborted) return null;
74
+
75
+ // brain-client may return { results: [...] } or null on quota-exhaustion + fallback.
76
+ const ventures = (result && Array.isArray(result.results)) ? result.results.slice(0, 3) : [];
77
+ if (ventures.length === 0) {
78
+ return { status: 'empty', payload: { reason: 'no_matches' } };
79
+ }
80
+
81
+ const summary = 'Found ' + ventures.length + ' ventures in this space: ' +
82
+ ventures.map((v) => (v.name || 'unnamed') + ' (' + (v.status || 'active') + ')').join(', ');
83
+
84
+ return {
85
+ status: 'ok',
86
+ payload: {
87
+ summary_line: summary,
88
+ deck_data: { ventures: ventures },
89
+ },
90
+ };
91
+ }
92
+
93
+ module.exports = { run };
@@ -0,0 +1,72 @@
1
+ /*
2
+ * Copyright (c) 2026 Mindrian. BSL 1.1.
3
+ *
4
+ * Phase 118-02 Plan 02 Task 3 -- dashboard-graph-neighborhood agent (Agent 6
5
+ * of 6 in B1; agent_id 'dashboard_graph' in lib/agents/mva/index.cjs).
6
+ *
7
+ * Reads the active room's graph via lib/core/navigation.cjs (the Phase 109
8
+ * single chokepoint; Canon Part 9 D-06 invariant) and returns a 1-2 hop
9
+ * neighborhood snapshot of recent decision nodes.
10
+ *
11
+ * Graph-native HARD RULES (memory feedback_reverse_salient_agent_graph_native.md):
12
+ * 1. NEVER require lib/core/room-db.cjs directly (the Phase 109 D-06
13
+ * chokepoint allow-list does NOT include MVA agents).
14
+ * 2. NEVER require better-sqlite3 / node:sqlite directly.
15
+ * 3. NEVER write to stdout / stderr (telemetry side-channel rule).
16
+ * 4. NEVER call out over the network (the dashboard is purely LOCAL graph).
17
+ *
18
+ * Canon Part 8 hard invariant (MVA-118-12):
19
+ * The room graph read is LOCAL only. Zero outbound. The summary line + deck
20
+ * data carry only structural identifiers + counts, never raw artifact text.
21
+ *
22
+ * Pure CJS, node built-ins only, zero new runtime dependencies.
23
+ */
24
+ 'use strict';
25
+
26
+ const nav = require('../../core/navigation.cjs');
27
+
28
+ /**
29
+ * @param {{ sentence_sha256: string, remaining_budget_ms: number }} _context
30
+ * @param {AbortSignal} signal
31
+ * @returns {Promise<{ status:'ok'|'empty', payload:any } | null>}
32
+ */
33
+ async function run(_context, signal) {
34
+ if (signal && signal.aborted) return null;
35
+
36
+ let active;
37
+ try {
38
+ active = nav.detectActiveRoom();
39
+ } catch (_e) {
40
+ return { status: 'empty', payload: { reason: 'no_active_room' } };
41
+ }
42
+ if (!active || !active.hasRoomDb) {
43
+ return { status: 'empty', payload: { reason: 'no_active_room' } };
44
+ }
45
+ if (signal && signal.aborted) return null;
46
+
47
+ let neighborhood;
48
+ try {
49
+ neighborhood = nav.getRecentDecisionNeighborhood(active.roomDir, { hops: 1, limit: 5 });
50
+ } catch (_e) {
51
+ return { status: 'empty', payload: { reason: 'graph_error' } };
52
+ }
53
+ if (signal && signal.aborted) return null;
54
+
55
+ const nodes = (neighborhood && Array.isArray(neighborhood.nodes)) ? neighborhood.nodes : [];
56
+ const edges = (neighborhood && Array.isArray(neighborhood.edges)) ? neighborhood.edges : [];
57
+ if (nodes.length === 0) {
58
+ return { status: 'empty', payload: { reason: 'empty_room' } };
59
+ }
60
+ const count = nodes.length;
61
+ const suffix = count === 1 ? '' : 's';
62
+ const summary = 'Your room already has ' + count + ' related decision node' + suffix + '. Quick preview:';
63
+ return {
64
+ status: 'ok',
65
+ payload: {
66
+ summary_line: summary,
67
+ deck_data: { nodes: nodes, edges: edges },
68
+ },
69
+ };
70
+ }
71
+
72
+ module.exports = { run };
@@ -0,0 +1,42 @@
1
+ /*
2
+ * Copyright (c) 2026 Mindrian. BSL 1.1.
3
+ *
4
+ * Phase 118-02 Plan 02 -- ALL_AGENTS aggregator for the 6 MVA agents (Binding
5
+ * Decision B1). Consumed by lib/core/mva-dispatcher.cjs which knows nothing
6
+ * about which agents are which -- it accepts any { id, fn } tuple conforming
7
+ * to the Agent contract in lib/core/mva-agent-contract.cjs.
8
+ *
9
+ * Agent ID -> source-file mapping (short forms per B1; long forms here):
10
+ *
11
+ * brain_similar <- brain-similar-ventures.cjs (Agent 1)
12
+ * brain_cross_domain <- brain-cross-domain.cjs (Agent 2)
13
+ * brain_classic_traps <- brain-classic-traps.cjs (Agent 3)
14
+ * tavily_funding <- tavily-funding-scan.cjs (Agent 4)
15
+ * six_hats_red_black <- six-hats-red-black.cjs (Agent 5)
16
+ * dashboard_graph <- dashboard-graph-neighborhood.cjs (Agent 6)
17
+ *
18
+ * NOTE on filename drift (NIT-2 invariant from plan-checker iteration 2):
19
+ * The canonical filenames in this plan's files_modified (e.g.
20
+ * brain-cross-domain.cjs, dashboard-graph-neighborhood.cjs) are the
21
+ * implementation-time source files. The JSDoc above documents the agent-id
22
+ * -> source-file mapping using the B1 short forms so Plan 118-03's renderer
23
+ * prefixes ([brain] / [analogy] / [traps] / [funding] / [worth chewing on]
24
+ * / [your room]) deterministically resolve from agent_id alone. If an
25
+ * executor renames a source file, update both this comment block AND the
26
+ * require() path immediately below in the same commit.
27
+ *
28
+ * Canon Part 8: this module is a pure aggregator. Zero I/O. Each agent owns
29
+ * its own boundary; the array shape preserves the dispatcher contract.
30
+ */
31
+ 'use strict';
32
+
33
+ const ALL_AGENTS = Object.freeze([
34
+ { id: 'brain_similar', fn: require('./brain-similar-ventures.cjs').run },
35
+ { id: 'brain_cross_domain', fn: require('./brain-cross-domain.cjs').run },
36
+ { id: 'brain_classic_traps', fn: require('./brain-classic-traps.cjs').run },
37
+ { id: 'tavily_funding', fn: require('./tavily-funding-scan.cjs').run },
38
+ { id: 'six_hats_red_black', fn: require('./six-hats-red-black.cjs').run },
39
+ { id: 'dashboard_graph', fn: require('./dashboard-graph-neighborhood.cjs').run },
40
+ ]);
41
+
42
+ module.exports = { ALL_AGENTS };