@mindrian_os/install 1.13.0-beta.17 → 1.13.0-beta.21

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 (199) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/.mcp.json +6 -1
  3. package/CHANGELOG.md +31 -0
  4. package/README.md +51 -56
  5. package/bin/mindrian-brain-mcp-client.cjs +152 -0
  6. package/commands/act.md +1 -0
  7. package/commands/admin.md +1 -0
  8. package/commands/analyze-needs.md +2 -0
  9. package/commands/analyze-systems.md +2 -0
  10. package/commands/analyze-timing.md +2 -0
  11. package/commands/auto-explore.md +2 -0
  12. package/commands/beautiful-question.md +2 -0
  13. package/commands/brain-derive.md +2 -0
  14. package/commands/build-knowledge.md +2 -0
  15. package/commands/build-thesis.md +2 -0
  16. package/commands/causal.md +2 -0
  17. package/commands/challenge-assumptions.md +2 -0
  18. package/commands/compare-ventures.md +2 -0
  19. package/commands/dashboard.md +2 -1
  20. package/commands/deep-grade.md +2 -0
  21. package/commands/diagnose.md +21 -1
  22. package/commands/diagnostics.md +14 -3
  23. package/commands/doctor.md +6 -2
  24. package/commands/dogfood-flush.md +92 -0
  25. package/commands/dominant-designs.md +2 -0
  26. package/commands/explain-decision.md +2 -0
  27. package/commands/explore-domains.md +2 -0
  28. package/commands/explore-futures.md +2 -0
  29. package/commands/explore-trends.md +2 -0
  30. package/commands/export.md +1 -0
  31. package/commands/feynman-timeline-refresh.md +2 -0
  32. package/commands/file-meeting.md +2 -0
  33. package/commands/find-analogies.md +1 -0
  34. package/commands/find-bottlenecks.md +2 -0
  35. package/commands/find-connections.md +2 -0
  36. package/commands/funding.md +1 -0
  37. package/commands/grade.md +2 -0
  38. package/commands/graph.md +1 -0
  39. package/commands/hat-briefing.md +1 -0
  40. package/commands/heal.md +22 -170
  41. package/commands/help.md +54 -334
  42. package/commands/hmi-status.md +23 -144
  43. package/commands/jtbd.md +1 -0
  44. package/commands/leadership.md +2 -0
  45. package/commands/lean-canvas.md +2 -0
  46. package/commands/macro-trends.md +2 -0
  47. package/commands/map-unknowns.md +2 -0
  48. package/commands/memory.md +1 -0
  49. package/commands/models.md +1 -0
  50. package/commands/mos-reason.md +2 -0
  51. package/commands/mos.md +139 -0
  52. package/commands/mullins.md +2 -0
  53. package/commands/mva-brief.md +2 -0
  54. package/commands/mva-option.md +2 -0
  55. package/commands/new-project.md +2 -0
  56. package/commands/onboard.md +20 -7
  57. package/commands/operator.md +1 -0
  58. package/commands/opportunities.md +1 -0
  59. package/commands/organize.md +22 -469
  60. package/commands/persona.md +1 -0
  61. package/commands/pipeline.md +2 -0
  62. package/commands/present.md +1 -0
  63. package/commands/publish.md +2 -0
  64. package/commands/query.md +24 -102
  65. package/commands/radar.md +2 -0
  66. package/commands/reanalyze.md +1 -0
  67. package/commands/research.md +2 -0
  68. package/commands/room.md +2 -0
  69. package/commands/rooms.md +1 -0
  70. package/commands/root-cause.md +2 -0
  71. package/commands/rs-experts.md +1 -0
  72. package/commands/rs-explain.md +1 -0
  73. package/commands/rs-fetch.md +1 -0
  74. package/commands/rs-thesis.md +1 -0
  75. package/commands/scenario-plan.md +2 -0
  76. package/commands/scheduled-tasks.md +1 -0
  77. package/commands/score-innovation.md +2 -0
  78. package/commands/scout.md +1 -0
  79. package/commands/setup.md +2 -0
  80. package/commands/snapshot.md +2 -0
  81. package/commands/speakers.md +1 -0
  82. package/commands/splash.md +5 -2
  83. package/commands/status.md +1 -0
  84. package/commands/structure-argument.md +2 -0
  85. package/commands/suggest-next.md +2 -0
  86. package/commands/systems-thinking.md +2 -0
  87. package/commands/think-hats.md +2 -0
  88. package/commands/update.md +2 -0
  89. package/commands/user-needs.md +2 -0
  90. package/commands/validate.md +2 -0
  91. package/commands/value-proposition.md +2 -0
  92. package/commands/vault.md +2 -0
  93. package/commands/visualize.md +24 -29
  94. package/commands/whitespace.md +2 -1
  95. package/commands/wiki.md +1 -0
  96. package/hooks/hooks.json +22 -88
  97. package/lib/agents/auto-explore-agent.cjs +82 -0
  98. package/lib/core/breakthrough/canary.cjs +134 -0
  99. package/lib/core/breakthrough/canary.test.cjs +136 -0
  100. package/lib/core/breakthrough/detectors.cjs +359 -0
  101. package/lib/core/breakthrough/detectors.test.cjs +333 -0
  102. package/lib/core/breakthrough/ethics-fence.cjs +127 -0
  103. package/lib/core/breakthrough/ethics-fence.test.cjs +178 -0
  104. package/lib/core/breakthrough/resurfacing.cjs +150 -0
  105. package/lib/core/breakthrough/resurfacing.test.cjs +233 -0
  106. package/lib/core/breakthrough/review-queue.cjs +154 -0
  107. package/lib/core/breakthrough/review-queue.test.cjs +160 -0
  108. package/lib/core/breakthrough/scanner-d17-d18.test.cjs +229 -0
  109. package/lib/core/breakthrough/scanner.cjs +426 -0
  110. package/lib/core/breakthrough/scanner.test.cjs +267 -0
  111. package/lib/core/breakthrough/schema.cjs +164 -0
  112. package/lib/core/breakthrough/schema.test.cjs +256 -0
  113. package/lib/core/breakthrough/scoring.cjs +293 -0
  114. package/lib/core/breakthrough/scoring.test.cjs +423 -0
  115. package/lib/core/breakthrough/verb-dispatch.cjs +221 -0
  116. package/lib/core/breakthrough/verb-dispatch.test.cjs +185 -0
  117. package/lib/core/breakthrough/voice-scaffold.cjs +247 -0
  118. package/lib/core/breakthrough/voice-scaffold.test.cjs +251 -0
  119. package/lib/core/directive-envelope.cjs +175 -0
  120. package/lib/core/directive-envelope.test.cjs +225 -0
  121. package/lib/core/doctor/class-m-brain-smoke.cjs +278 -0
  122. package/lib/core/doctor/class-m-brain-smoke.test.cjs +310 -0
  123. package/lib/core/first-touch-version-stamper.cjs +113 -0
  124. package/lib/core/larry-thinness-acknowledgment.cjs +64 -0
  125. package/lib/core/larry-thinness-acknowledgment.test.cjs +97 -0
  126. package/lib/core/llm-name-suggester.cjs +194 -0
  127. package/lib/core/llm-name-suggester.test.cjs +132 -0
  128. package/lib/core/mcp-profiles.cjs +1 -1
  129. package/lib/core/migration-snapshot.cjs +172 -0
  130. package/lib/core/migration-snapshot.test.cjs +174 -0
  131. package/lib/core/mindrian-brain-shim.test.cjs +214 -0
  132. package/lib/core/mva-orchestrator.cjs +41 -0
  133. package/lib/core/mva-telemetry.cjs +31 -143
  134. package/lib/core/navigation/edges.cjs +35 -0
  135. package/lib/core/navigation/memory-events.cjs +126 -0
  136. package/lib/core/room-auto-create.cjs +318 -0
  137. package/lib/core/room-auto-create.test.cjs +198 -0
  138. package/lib/core/room-discard-cascade.cjs +225 -0
  139. package/lib/core/room-discard-cascade.test.cjs +135 -0
  140. package/lib/core/room-name-validator.cjs +132 -0
  141. package/lib/core/room-name-validator.test.cjs +156 -0
  142. package/lib/core/room-naming-selector.cjs +357 -0
  143. package/lib/core/room-naming-selector.test.cjs +277 -0
  144. package/lib/core/room-receipt-emit.cjs +63 -0
  145. package/lib/core/room-skeleton-scaffold.cjs +315 -0
  146. package/lib/core/room-skeleton-scaffold.test.cjs +291 -0
  147. package/lib/core/rs-nl-to-query.cjs +1 -1
  148. package/lib/core/stale-copy-scanner.cjs +190 -0
  149. package/lib/core/state-aware-router.cjs +78 -0
  150. package/lib/core/telemetry/schema.cjs +168 -0
  151. package/lib/core/telemetry/schema.test.cjs +124 -0
  152. package/lib/core/telemetry/validator.cjs +200 -0
  153. package/lib/core/telemetry/validator.test.cjs +188 -0
  154. package/lib/core/telemetry/writer.cjs +141 -0
  155. package/lib/core/telemetry/writer.test.cjs +331 -0
  156. package/lib/core/terminal-capability.cjs +88 -0
  157. package/lib/core/tier0-messaging.cjs +109 -0
  158. package/lib/core/tier0-messaging.test.cjs +218 -0
  159. package/lib/core/venture-shape-nudge.cjs +163 -0
  160. package/lib/core/venture-shape-nudge.test.cjs +161 -0
  161. package/lib/core/visual-ops.cjs +70 -2
  162. package/lib/hmi/selector-dispatcher.cjs +90 -1
  163. package/lib/hmi/shape-f7-breakthrough-renderer.cjs +222 -0
  164. package/lib/hmi/shape-f7-breakthrough-renderer.test.cjs +233 -0
  165. package/lib/memory/body-shape-coverage.test.cjs +268 -0
  166. package/lib/memory/brain-derivation-graceful-degradation.test.cjs +2 -2
  167. package/lib/memory/doctor-deprecation-surface.test.cjs +185 -0
  168. package/lib/memory/first-touch-version.test.cjs +198 -0
  169. package/lib/memory/help-coverage.test.cjs +108 -0
  170. package/lib/memory/help-renderer.test.cjs +145 -0
  171. package/lib/memory/mos-status-renderer.test.cjs +2 -2
  172. package/lib/memory/navigation-engine-core.test.cjs +1 -1
  173. package/lib/memory/palette-consistency.test.cjs +127 -0
  174. package/lib/memory/pending-tension-store.cjs +80 -0
  175. package/lib/memory/render-v2-disposition.test.cjs +199 -0
  176. package/lib/memory/run-feynman-tests.cjs +223 -0
  177. package/lib/memory/sessionstart-coordinator.test.cjs +446 -0
  178. package/lib/memory/skill-vs-code-drift.test.cjs +257 -0
  179. package/lib/memory/soft-alias.test.cjs +144 -0
  180. package/lib/memory/stale-copy-scanner.test.cjs +291 -0
  181. package/lib/memory/state-aware-router.test.cjs +90 -0
  182. package/lib/memory/statusline-two-row.test.cjs +338 -0
  183. package/lib/memory/terminal-capability.test.cjs +155 -0
  184. package/lib/render/ROOM.md +74 -22
  185. package/lib/sessionstart/budget-compressor.cjs +130 -0
  186. package/lib/sessionstart/contributor-interface.cjs +134 -0
  187. package/lib/sessionstart/contributor-isolator.cjs +128 -0
  188. package/lib/sessionstart/precedence-ladder.cjs +47 -0
  189. package/lib/statusline/governing-thought-truncator.cjs +45 -0
  190. package/lib/statusline/two-row-renderer.cjs +186 -0
  191. package/lib/statusline/version-resolver.cjs +81 -0
  192. package/package.json +1 -1
  193. package/references/visual/ROOM.md +55 -0
  194. package/references/visual/palette.json +54 -0
  195. package/skills/larry-personality/SKILL.md +34 -0
  196. package/skills/ui-system/SKILL.md +109 -1
  197. package/skills/ui-system/rules/dual-palette.md +156 -0
  198. package/skills/ui-system/rules/glyph-disambiguation.md +171 -0
  199. package/skills/ui-system/rules/shape-f-zero-and-six.md +169 -0
@@ -1,32 +1,9 @@
1
1
  /*
2
2
  * Copyright (c) 2026 Mindrian. BSL 1.1.
3
- *
4
- * Phase 118-03 Plan 03 -- mva-telemetry.
5
- *
6
- * JSONL writer for the 6 Phase 121 MVA event types. Atomic append to
7
- * ~/.mindrian/telemetry/v1.13/mva.jsonl. Schema-enforced (rejects events
8
- * with raw user content; per-event ALLOWED_FIELDS is the source of truth
9
- * for Plan 118-06's Dror harness grep test).
10
- *
11
- * Per Plan 118-03 OQ8 (resolved): the 6 event types are
12
- * mva_pipeline_started, mva_agent_returned, mva_brief_rendered,
13
- * mva_option_selected, mva_brief_deployed, mva_pipeline_failed.
14
- *
15
- * CRITICAL invariant (WARN-2 from iteration 2): the mva_brief_rendered
16
- * event uses `total_duration_ms` (NOT `duration_ms`). Plan 118-06's
17
- * Dror harness greps ALLOWED_FIELDS.mva_brief_rendered to assert this.
18
- *
19
- * Canon Part 8 (LOCAL telemetry):
20
- * - Sentence-related identifier is sentence_sha256 ONLY (one-way hash).
21
- * - Every string field is capped (sentence_sha256=64 exact, error_short<=60,
22
- * other strings<=64) to prevent raw user content from sneaking through.
23
- * - Fields not in ALLOWED_FIELDS for the event type are rejected.
24
- *
25
- * Atomic append: fs.appendFileSync writes a single short line. POSIX
26
- * append semantics guarantee atomicity for writes within PIPE_BUF (4096
27
- * bytes on Linux). Our lines are < 512 bytes, well below the limit.
28
- *
29
- * Pure CJS, node built-ins only.
3
+ * Phase 121-01 -- mva-telemetry shim. Delegates to lib/core/telemetry/writer.cjs
4
+ * (the Canon Part 9 chokepoint), with a legacy dual-write to the historical
5
+ * ~/.mindrian/telemetry/v1.13/mva.jsonl path so existing readers keep working.
6
+ * TODO(v1.14.0): delete this shim; callers must import lib/core/telemetry/writer.cjs directly.
30
7
  */
31
8
  'use strict';
32
9
 
@@ -34,137 +11,48 @@ const fs = require('node:fs');
34
11
  const path = require('node:path');
35
12
  const os = require('node:os');
36
13
 
37
- // ---------- Frozen invariants ----------
14
+ const writer = require('./telemetry/writer.cjs');
15
+ const validator = require('./telemetry/validator.cjs');
16
+ const schema = require('./telemetry/schema.cjs');
38
17
 
39
18
  const EVENT_TYPES = Object.freeze([
40
- 'mva_pipeline_started',
41
- 'mva_agent_returned',
42
- 'mva_brief_rendered',
43
- 'mva_option_selected',
44
- 'mva_brief_deployed',
45
- 'mva_pipeline_failed'
19
+ 'mva_pipeline_started', 'mva_agent_returned', 'mva_brief_rendered',
20
+ 'mva_option_selected', 'mva_brief_deployed', 'mva_pipeline_failed',
46
21
  ]);
47
22
 
48
- // Per-event scalar field schema. Source-of-truth for Plan 118-06 Dror harness.
49
- // CRITICAL: mva_brief_rendered uses 'total_duration_ms' (NOT 'duration_ms').
50
23
  const ALLOWED_FIELDS = Object.freeze({
51
- mva_pipeline_started: Object.freeze(['sentence_sha256']),
52
- mva_agent_returned: Object.freeze(['sentence_sha256', 'agent_id', 'duration_ms', 'status', 'error_short']),
53
- mva_brief_rendered: Object.freeze(['sentence_sha256', 'total_duration_ms', 'agent_count_ok', 'agent_count_failed']),
54
- mva_option_selected: Object.freeze(['sentence_sha256', 'option_id', 'time_to_click_ms']),
55
- mva_brief_deployed: Object.freeze(['sentence_sha256', 'vercel_subdomain_hash', 'deploy_duration_ms', 'status', 'error_short']),
56
- mva_pipeline_failed: Object.freeze(['sentence_sha256', 'total_duration_ms', 'error_short'])
24
+ mva_pipeline_started: schema.ALLOWED_FIELDS.mva_pipeline_started,
25
+ mva_agent_returned: schema.ALLOWED_FIELDS.mva_agent_returned,
26
+ mva_brief_rendered: schema.ALLOWED_FIELDS.mva_brief_rendered,
27
+ mva_option_selected: schema.ALLOWED_FIELDS.mva_option_selected,
28
+ mva_brief_deployed: schema.ALLOWED_FIELDS.mva_brief_deployed,
29
+ mva_pipeline_failed: schema.ALLOWED_FIELDS.mva_pipeline_failed,
57
30
  });
58
31
 
59
- // String-length caps. error_short is special-cased to <= 60.
60
- // sentence_sha256 must be exactly 64 hex chars.
61
- const MAX_STRING_LEN = 64;
62
- const MAX_ERROR_SHORT_LEN = 60;
63
- const SHA256_LEN = 64;
64
-
65
- // ---------- Path resolvers (env-aware for hermetic testing) ----------
66
-
67
- function homeDir() {
32
+ function _homeDir() {
68
33
  return process.env.HOME || process.env.USERPROFILE || os.homedir();
69
34
  }
70
35
 
71
- function telemetryDir() {
72
- return path.join(homeDir(), '.mindrian', 'telemetry', 'v1.13');
73
- }
74
-
75
- function telemetryFile() {
76
- return path.join(telemetryDir(), 'mva.jsonl');
77
- }
78
-
79
- // ---------- Validation ----------
80
-
81
- /**
82
- * validateEventPayload(event, payload) -> { ok: boolean, error?: string }
83
- *
84
- * Returns ok:false if:
85
- * - event is not in EVENT_TYPES
86
- * - any key in payload is not in ALLOWED_FIELDS[event]
87
- * - any string value violates the per-field length cap
88
- *
89
- * Numeric fields are not length-checked. The session_id field is added
90
- * by emit() (not the caller), so it is not validated against ALLOWED_FIELDS.
91
- */
92
- function validateEventPayload(event, payload) {
93
- if (!EVENT_TYPES.includes(event)) {
94
- return { ok: false, error: 'unknown_event' };
95
- }
96
- if (!payload || typeof payload !== 'object') {
97
- return { ok: false, error: 'payload_not_object' };
98
- }
99
- const allowed = ALLOWED_FIELDS[event];
100
- for (const key of Object.keys(payload)) {
101
- if (!allowed.includes(key)) {
102
- return { ok: false, error: 'unknown_field:' + key };
103
- }
104
- const v = payload[key];
105
- if (typeof v === 'string') {
106
- if (key === 'sentence_sha256') {
107
- if (v.length !== SHA256_LEN) {
108
- return { ok: false, error: 'sha256_length_invalid' };
109
- }
110
- } else if (key === 'error_short') {
111
- if (v.length > MAX_ERROR_SHORT_LEN) {
112
- return { ok: false, error: 'error_short_too_long' };
113
- }
114
- } else {
115
- if (v.length > MAX_STRING_LEN) {
116
- return { ok: false, error: 'string_too_long:' + key };
117
- }
118
- }
119
- }
120
- }
121
- return { ok: true };
36
+ function _legacyMvaPath() {
37
+ return path.join(_homeDir(), '.mindrian', 'telemetry', 'v1.13', 'mva.jsonl');
122
38
  }
123
39
 
124
- // ---------- Public emit() ----------
125
-
126
- /**
127
- * emit(event, payload) -> appends one JSONL line to ~/.mindrian/telemetry/v1.13/mva.jsonl
128
- *
129
- * Validates first. On invalid payload throws a ValidationError (so callers
130
- * cannot silently leak). On disk error returns silently (best-effort: the
131
- * pipeline must not crash because telemetry is unavailable).
132
- */
133
40
  function emit(event, payload) {
134
- const v = validateEventPayload(event, payload);
135
- if (!v.ok) {
136
- const e = new Error('telemetry validation failed: ' + v.error);
137
- e.code = 'TELEMETRY_VALIDATION';
138
- throw e;
139
- }
140
-
141
- const record = Object.assign(
142
- {
143
- event: event,
144
- timestamp: new Date().toISOString(),
145
- session_id: (typeof process.env.CLAUDE_SESSION_ID === 'string' && process.env.CLAUDE_SESSION_ID.length > 0)
146
- ? process.env.CLAUDE_SESSION_ID.slice(0, MAX_STRING_LEN)
147
- : 'default'
148
- },
149
- payload
150
- );
151
-
41
+ writer.emit(event, payload); // Canon Part 8 gate + unified events-YYYY-WNN.jsonl append.
152
42
  try {
153
- fs.mkdirSync(telemetryDir(), { recursive: true });
154
- fs.appendFileSync(telemetryFile(), JSON.stringify(record) + '\n', 'utf8');
155
- } catch (_e) {
156
- // Best-effort. The MVA pipeline must not fail because telemetry disk
157
- // is unavailable. Plan 118-06's Dror harness checks for the file's
158
- // existence post-run as the success signal.
159
- }
43
+ const sid = (typeof process.env.CLAUDE_SESSION_ID === 'string' && process.env.CLAUDE_SESSION_ID.length > 0)
44
+ ? process.env.CLAUDE_SESSION_ID.slice(0, schema.MAX_STRING_LEN) : 'default';
45
+ const record = Object.assign({ event: event, timestamp: new Date().toISOString(), session_id: sid }, payload);
46
+ fs.mkdirSync(path.dirname(_legacyMvaPath()), { recursive: true });
47
+ fs.appendFileSync(_legacyMvaPath(), JSON.stringify(record) + '\n', 'utf8');
48
+ } catch (_) { /* best-effort legacy dual-write */ }
160
49
  }
161
50
 
162
51
  module.exports = {
163
- emit,
164
- validateEventPayload,
165
- EVENT_TYPES,
166
- ALLOWED_FIELDS,
167
- // Exposed for tests + downstream plans that need the canonical path
168
- telemetryDir,
169
- telemetryFile,
52
+ emit: emit,
53
+ validateEventPayload: validator.validateEventPayload,
54
+ EVENT_TYPES: EVENT_TYPES,
55
+ ALLOWED_FIELDS: ALLOWED_FIELDS,
56
+ telemetryDir: writer.telemetryDir,
57
+ telemetryFile: writer.telemetryFile,
170
58
  };
@@ -33,6 +33,41 @@ const ALLOWED_EDGE_TYPES = Object.freeze(new Set([
33
33
  // Phase 125 D7 -- F-selector decision edges (LOCKED LOCAL per Canon Part 8).
34
34
  'DEFERRED',
35
35
  'REJECTED',
36
+ // Phase 120-00 Wave 1 extension (Breakthrough Scan / Category G; D-18 HARD FLOOR enforcement
37
+ // + D-20 Cypher-provable principle). DERIVED_FROM is the structural enforcement: a
38
+ // Breakthrough node CANNOT surface without at least one DERIVED_FROM edge to an
39
+ // Artifact node. Mirrors the Phase 125-00 DEFERRED + REJECTED additive idiom.
40
+ //
41
+ // Canon Part 4: every choice is graph data. The Breakthrough node + its DERIVED_FROM
42
+ // edges are the graph-native artifact of pattern detection.
43
+ //
44
+ // Canon Part 8: writeEdge takes (db, params) over a LOCAL room.db handle; DERIVED_FROM
45
+ // never crosses to Brain. Cross-room aggregation forbidden (Phase 8 cross-room fence).
46
+ //
47
+ // D-20 enforcement: lib/core/breakthrough/schema.cjs::writeBreakthrough wraps the
48
+ // Breakthrough node insert + N DERIVED_FROM edge inserts in a single SQLite transaction.
49
+ // If any step fails, the transaction rolls back -- partial Breakthrough state CANNOT
50
+ // land. The Cypher invariant `MATCH (b:Breakthrough)-[:DERIVED_FROM]->(a:Artifact)
51
+ // RETURN count(a)` is guaranteed >= 1 by construction.
52
+ 'DERIVED_FROM',
53
+ // Phase 120-02 Wave 2 extension (Breakthrough Scan / Category G; D-09 file-as-decision
54
+ // bridge). FILED_AS_DECISION is the typed edge that promotes a Breakthrough node into
55
+ // the Phase 88 decision-log machinery when the user picks the [File as decision]
56
+ // verb on F.7. Mirrors the Phase 120-00 DERIVED_FROM additive idiom verbatim.
57
+ //
58
+ // Canon Part 4: every choice is graph data. The Breakthrough -> Decision edge is the
59
+ // graph-native bridge that lets future related breakthroughs reference the filed
60
+ // decision via ENABLES edges (per CONTEXT.md D-15 "may be referenced as ENABLES in
61
+ // future related breakthroughs").
62
+ //
63
+ // Canon Part 8: writeEdge takes (db, params) over a LOCAL room.db handle;
64
+ // FILED_AS_DECISION never crosses to Brain. Cross-room aggregation forbidden.
65
+ //
66
+ // Emitted by: lib/core/breakthrough/verb-dispatch.cjs::handleFileAsDecision.
67
+ // The destination Decision node id is 'decision:' + breakthroughId by convention;
68
+ // Phase 88 decision-log machinery (or a future Phase 121 housekeeping pass) is
69
+ // responsible for materializing the Decision node body when one does not yet exist.
70
+ 'FILED_AS_DECISION',
36
71
  ]));
37
72
 
38
73
  function isPlainObject(v) {
@@ -109,6 +109,132 @@ const EVENT_TYPES = Object.freeze(new Set([
109
109
  // investment_level_at_decision}. NO cascade edge written (miss is temporal-only).
110
110
  // Canon Part 8: user_intent stays LOCAL; never sent to Brain.
111
111
  'f_selector_miss',
112
+ // Phase 121.5-00 extension (SessionStart Coordinator: D-16 isolation + D-14 budget telemetry).
113
+ // Emitted by lib/sessionstart/contributor-isolator.cjs::runContributor on contributor failure
114
+ // and by scripts/sessionstart-coordinator.cjs::runAll on every coordinator pass.
115
+ // sessionstart_contributor_failed -> a single contributor threw / validation-failed; coordinator
116
+ // dropped it and continued. Payload: {contributor_id: <ladder id>,
117
+ // error_class: <constructor name; enum-only>}. No stack, no
118
+ // user content -- Canon Part 8 boundary preserved by the
119
+ // isolator (stack lives in the LOCAL JSONL telemetry only).
120
+ // sessionstart_coordinator_run -> one envelope emitted; payload carries scalar counts
121
+ // (fragments_total, fragments_compressed, fragments_dropped,
122
+ // bytes_emitted). Scalars + enums only.
123
+ // Additive extension only; mirrors the Phase 110-02 / 116-00 / 117-00 / 124-02 / 125-01 / 125-06
124
+ // / 125-07 idiom verbatim. logEvent already rejects event_type values outside EVENT_TYPES.
125
+ 'sessionstart_contributor_failed',
126
+ 'sessionstart_coordinator_run',
127
+ // Phase 119-00 Wave 1 extension (Room-as-Receipt Invariant; D-01 + D-04 + D-06 telemetry mirror).
128
+ // Per CONTEXT.md Implementation Decisions D-01 + D-04 + D-06: the auto-create entrypoint
129
+ // (room_auto_created) fires synchronously inside scripts/auto-explore-fingerprint.cjs BEFORE
130
+ // the detached auto-explore-fire spawn so the spawned auto-explore output lands in a real
131
+ // room.db. The naming-decided + discarded events land in Plan 119-01.
132
+ //
133
+ // Additive extension; mirrors the Phase 124-02 2-string idiom and the Phase 117-00 6-string
134
+ // idiom. logEvent already rejects event_type values outside EVENT_TYPES -- so these are
135
+ // accepted only because they are now IN the Set. Set size grows by 3 (was 38 before Phase
136
+ // 119; now 41 baseline; coexists additively with any concurrent phase extension).
137
+ //
138
+ // Canon Part 9: SQL is the local mind; every choice is graph data. These three events are
139
+ // the canonical Part 10 sub-claim 3 ("rooms are receipts, not entry points") telemetry mirror.
140
+ 'room_auto_created',
141
+ 'room_naming_decided',
142
+ 'room_discarded',
143
+ // Phase 119-01 Wave 2 extension (Room-as-Receipt Invariant; D-06 discard-cascade safety net).
144
+ // Per CONTEXT.md Architectural Decision item 4 (Claude's Discretion): the discard cascade
145
+ // is a SQLite transaction wrapping fs.rmSync + registry purge + memory_event emission.
146
+ // When the transaction fails partway (fs.rmSync raises EBUSY / EACCES, OR the registry
147
+ // purge fails non-atomically), the memory_event below lands so /mos:doctor can find
148
+ // orphaned rooms on next session-start.
149
+ //
150
+ // Additive extension only; mirrors the Plan 119-00 idiom verbatim. logEvent already
151
+ // rejects event_type values outside EVENT_TYPES -- so this is accepted only because
152
+ // it is now IN the Set. Set size grows by 1 (was 41 after Plan 119-00; now 42 baseline).
153
+ //
154
+ // Canon Part 9: SQL is the local mind; even partial failures become graph data so the
155
+ // recovery hook (/mos:doctor --orphaned-room-cleanup, deferred to v1.13.0 housekeeping)
156
+ // can scan + remediate.
157
+ 'room_discard_partial_failure',
158
+ // Phase 120-00 Wave 1 extension (Breakthrough Scan / Category G; D-01..D-06 detector tier
159
+ // + D-09 file-as-decision bridge + D-10 mandatory dismiss + D-19 canary auto-throttle).
160
+ //
161
+ // Six strings; mirrors the Phase 119-00 3-string + 117-00 6-string + 124-02 2-string
162
+ // additive idiom. logEvent already rejects event_type values outside EVENT_TYPES -- so
163
+ // these are accepted only because they are now IN the Set. Set size grows by 6 (was 42
164
+ // baseline after Phase 119-01; now 48 baseline).
165
+ //
166
+ // Canon Part 10 sub-claim 5: variable reward fires automatically; the math IS the surface.
167
+ // These six events are the canonical telemetry mirror for the breakthrough lifecycle:
168
+ // soft-fire (buffer-only) -> hard-fire (surfaced) -> user response (confirm/dismiss/file)
169
+ // -> canary auto-throttle (D-19 30%-over-100-fire-window static threshold).
170
+ //
171
+ // Canon Part 4: every choice is graph data. The breakthrough_filed_as_decision event is
172
+ // the bridge to Phase 88 decision-log machinery -- promotes a breakthrough to a
173
+ // first-class decision with audit trail.
174
+ //
175
+ // Canon Part 8: payloads carry scalar enums + framework names + sha256 hashes only;
176
+ // theme strings are sanitized at write time per the Phase 90-06 sanitizeDetailScalar
177
+ // precedent. Raw artifact content never lands in a memory_event.
178
+ 'breakthrough_detected_soft',
179
+ 'breakthrough_surfaced',
180
+ 'breakthrough_confirmed',
181
+ 'breakthrough_dismissed',
182
+ 'breakthrough_filed_as_decision',
183
+ 'breakthrough_throttled',
184
+ // Phase 120-02 Wave 2 additive extension (D-20 third structural enforcement
185
+ // point: surfaceBreakthrough refuses provenance-less Breakthrough nodes at
186
+ // surface time and emits this event for /mos:doctor traceability). Mirrors
187
+ // the Phase 120-00 6-string additive idiom verbatim. logEvent already
188
+ // rejects event_type values outside EVENT_TYPES -- so this is accepted only
189
+ // because it is now IN the Set. Set size grows additively by 1.
190
+ //
191
+ // Canon Part 4: every choice is graph data -- the refusal itself is a typed
192
+ // signal that an upstream caller attempted to bypass the D-20 invariant.
193
+ // Canon Part 8: pure LOCAL telemetry; no Brain coupling; payload carries
194
+ // breakthrough_id + reason scalars only.
195
+ 'breakthrough_surface_blocked',
196
+ // Phase 120-03 Wave 2 additive extension (D-18 SOFT_BAND review queue telemetry
197
+ // mirror). Mirrors the Phase 120-02 1-string + Phase 120-00 6-string + 117-00
198
+ // 6-string + 124-02 2-string additive idiom verbatim. logEvent already rejects
199
+ // event_type values outside EVENT_TYPES -- so this is accepted only because it
200
+ // is now IN the Set. Set size grows additively by 1.
201
+ //
202
+ // Canon Part 4: every choice is graph data; the SOFT_BAND review queue is the
203
+ // typed graph signal for D-18 mid-confidence candidates that the system queues
204
+ // for manual sample-20% weekly review (becomes retraining data per CONTEXT.md).
205
+ // Canon Part 8: payload carries scalar enums (kind), numeric confidence, and the
206
+ // queue_id handle; no raw artifact content lands in this event.
207
+ // Canon Part 9: ALL writes via navigation.cjs::logMemoryEvent chokepoint.
208
+ 'breakthrough_in_review_queue',
209
+ // 260517-dcw dogfood-bridge extension (Canon Part 6 Product-as-Venture; D-04
210
+ // dog-fooding mandate telemetry mirror). Six strings; mirrors the Phase 120-00
211
+ // 6-string + 117-00 6-string + 124-02 2-string + 110-02 3-string additive idiom.
212
+ // logEvent already rejects event_type values outside EVENT_TYPES -- so these are
213
+ // accepted only because they are now IN the Set. Set size grows by 6 (was 48
214
+ // baseline after Phase 120-00; now 54 baseline).
215
+ //
216
+ // Canon Part 9 binding: SQL is the local mind; the plugin's own development
217
+ // activity becomes graph data in the plugin's own venture room. Every Edit/
218
+ // Write/MultiEdit on the plugin repo that matches the dog-food filter is a
219
+ // file_changed event in ~/MindrianRooms/mindrian/room.db.
220
+ //
221
+ // Canon Part 8 binding: payloads carry the absolute path string (LOCAL data,
222
+ // already on the local box; never sent to Brain), the tool name (enum scalar:
223
+ // Edit / Write / MultiEdit), and the ISO timestamp. Zero user-content egress.
224
+ //
225
+ // Active emit site: scripts/dogfood-emit.cjs (file_changed only in this plan).
226
+ // Stub event types (no callers yet; reserved for future triggers per task_scope):
227
+ // commit_landed -> a git post-commit hook (future)
228
+ // phase_completed -> /gsd:phase-complete (future)
229
+ // release_shipped -> scripts/release.sh post-publish (future)
230
+ // tester_signal -> tester reply ingestion (future)
231
+ // decision_captured -> /mos:decide F.1 selector (future)
232
+ 'file_changed',
233
+ 'commit_landed',
234
+ 'phase_completed',
235
+ 'release_shipped',
236
+ 'tester_signal',
237
+ 'decision_captured',
112
238
  ]));
113
239
 
114
240
  function isPlainObject(v) {