@jungjaehoon/mama-os 0.51.2 → 0.52.0

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 (204) hide show
  1. package/dist/agent/agent-loop.d.ts +50 -0
  2. package/dist/agent/agent-loop.d.ts.map +1 -1
  3. package/dist/agent/agent-loop.js +480 -138
  4. package/dist/agent/agent-loop.js.map +1 -1
  5. package/dist/agent/code-act/constants.d.ts +1 -1
  6. package/dist/agent/code-act/constants.d.ts.map +1 -1
  7. package/dist/agent/code-act/constants.js +5 -2
  8. package/dist/agent/code-act/constants.js.map +1 -1
  9. package/dist/agent/code-act/host-bridge.d.ts.map +1 -1
  10. package/dist/agent/code-act/host-bridge.js +102 -4
  11. package/dist/agent/code-act/host-bridge.js.map +1 -1
  12. package/dist/agent/code-act/tool-catalog.d.ts +2 -0
  13. package/dist/agent/code-act/tool-catalog.d.ts.map +1 -1
  14. package/dist/agent/code-act/tool-catalog.js +20 -7
  15. package/dist/agent/code-act/tool-catalog.js.map +1 -1
  16. package/dist/agent/codex-app-server-process.d.ts +112 -0
  17. package/dist/agent/codex-app-server-process.d.ts.map +1 -1
  18. package/dist/agent/codex-app-server-process.js +518 -1
  19. package/dist/agent/codex-app-server-process.js.map +1 -1
  20. package/dist/agent/gateway-tool-executor.d.ts +17 -0
  21. package/dist/agent/gateway-tool-executor.d.ts.map +1 -1
  22. package/dist/agent/gateway-tool-executor.js +236 -53
  23. package/dist/agent/gateway-tool-executor.js.map +1 -1
  24. package/dist/agent/gateway-tools.md +9 -3
  25. package/dist/agent/model-runner.d.ts +5 -0
  26. package/dist/agent/model-runner.d.ts.map +1 -1
  27. package/dist/agent/model-runner.js.map +1 -1
  28. package/dist/agent/skill-loader.d.ts +7 -2
  29. package/dist/agent/skill-loader.d.ts.map +1 -1
  30. package/dist/agent/skill-loader.js +29 -8
  31. package/dist/agent/skill-loader.js.map +1 -1
  32. package/dist/agent/subagent-run-reconcile.d.ts +23 -0
  33. package/dist/agent/subagent-run-reconcile.d.ts.map +1 -0
  34. package/dist/agent/subagent-run-reconcile.js +56 -0
  35. package/dist/agent/subagent-run-reconcile.js.map +1 -0
  36. package/dist/agent/tool-registry.d.ts.map +1 -1
  37. package/dist/agent/tool-registry.js +126 -3
  38. package/dist/agent/tool-registry.js.map +1 -1
  39. package/dist/agent/types.d.ts +52 -2
  40. package/dist/agent/types.d.ts.map +1 -1
  41. package/dist/agent/types.js.map +1 -1
  42. package/dist/api/graph-api.d.ts.map +1 -1
  43. package/dist/api/graph-api.js +0 -22
  44. package/dist/api/graph-api.js.map +1 -1
  45. package/dist/cli/commands/start.d.ts +8 -7
  46. package/dist/cli/commands/start.d.ts.map +1 -1
  47. package/dist/cli/commands/start.js +148 -74
  48. package/dist/cli/commands/start.js.map +1 -1
  49. package/dist/cli/config/types.d.ts.map +1 -1
  50. package/dist/cli/config/types.js +2 -1
  51. package/dist/cli/config/types.js.map +1 -1
  52. package/dist/cli/runtime/api-routes-init.d.ts +1 -0
  53. package/dist/cli/runtime/api-routes-init.d.ts.map +1 -1
  54. package/dist/cli/runtime/api-routes-init.js +76 -32
  55. package/dist/cli/runtime/api-routes-init.js.map +1 -1
  56. package/dist/db/migrations/operator-procedures.d.ts +4 -0
  57. package/dist/db/migrations/operator-procedures.d.ts.map +1 -0
  58. package/dist/db/migrations/operator-procedures.js +63 -0
  59. package/dist/db/migrations/operator-procedures.js.map +1 -0
  60. package/dist/gateways/message-router.d.ts +4 -3
  61. package/dist/gateways/message-router.d.ts.map +1 -1
  62. package/dist/gateways/message-router.js +43 -131
  63. package/dist/gateways/message-router.js.map +1 -1
  64. package/dist/gateways/telegram-format.d.ts.map +1 -1
  65. package/dist/gateways/telegram-format.js +2 -0
  66. package/dist/gateways/telegram-format.js.map +1 -1
  67. package/dist/multi-agent/runtime-process.d.ts +8 -0
  68. package/dist/multi-agent/runtime-process.d.ts.map +1 -1
  69. package/dist/multi-agent/runtime-process.js +6 -0
  70. package/dist/multi-agent/runtime-process.js.map +1 -1
  71. package/dist/operator/board-delta-gate.d.ts +34 -10
  72. package/dist/operator/board-delta-gate.d.ts.map +1 -1
  73. package/dist/operator/board-delta-gate.js +68 -24
  74. package/dist/operator/board-delta-gate.js.map +1 -1
  75. package/dist/operator/board-refresh-gate.d.ts +11 -6
  76. package/dist/operator/board-refresh-gate.d.ts.map +1 -1
  77. package/dist/operator/board-refresh-gate.js +12 -11
  78. package/dist/operator/board-refresh-gate.js.map +1 -1
  79. package/dist/operator/board-slot-instructions.d.ts +30 -0
  80. package/dist/operator/board-slot-instructions.d.ts.map +1 -1
  81. package/dist/operator/board-slot-instructions.js +110 -6
  82. package/dist/operator/board-slot-instructions.js.map +1 -1
  83. package/dist/operator/console-brief.d.ts +26 -13
  84. package/dist/operator/console-brief.d.ts.map +1 -1
  85. package/dist/operator/console-brief.js +159 -83
  86. package/dist/operator/console-brief.js.map +1 -1
  87. package/dist/operator/experience-evidence.d.ts +18 -0
  88. package/dist/operator/experience-evidence.d.ts.map +1 -0
  89. package/dist/operator/experience-evidence.js +82 -0
  90. package/dist/operator/experience-evidence.js.map +1 -0
  91. package/dist/operator/experience-hints.d.ts +44 -0
  92. package/dist/operator/experience-hints.d.ts.map +1 -0
  93. package/dist/operator/experience-hints.js +98 -0
  94. package/dist/operator/experience-hints.js.map +1 -0
  95. package/dist/operator/mama-memory-port.js +1 -3
  96. package/dist/operator/mama-memory-port.js.map +1 -1
  97. package/dist/operator/operator-trigger-loop.d.ts.map +1 -1
  98. package/dist/operator/operator-trigger-loop.js +3 -2
  99. package/dist/operator/operator-trigger-loop.js.map +1 -1
  100. package/dist/operator/owner-action-effects.d.ts +13 -1
  101. package/dist/operator/owner-action-effects.d.ts.map +1 -1
  102. package/dist/operator/owner-action-effects.js +17 -4
  103. package/dist/operator/owner-action-effects.js.map +1 -1
  104. package/dist/operator/owner-event-inbox.d.ts +7 -1
  105. package/dist/operator/owner-event-inbox.d.ts.map +1 -1
  106. package/dist/operator/owner-event-inbox.js +8 -0
  107. package/dist/operator/owner-event-inbox.js.map +1 -1
  108. package/dist/operator/owner-event-loop.d.ts +28 -2
  109. package/dist/operator/owner-event-loop.d.ts.map +1 -1
  110. package/dist/operator/owner-event-loop.js +60 -2
  111. package/dist/operator/owner-event-loop.js.map +1 -1
  112. package/dist/operator/owner-event-policy.d.ts +20 -0
  113. package/dist/operator/owner-event-policy.d.ts.map +1 -1
  114. package/dist/operator/owner-event-policy.js +34 -5
  115. package/dist/operator/owner-event-policy.js.map +1 -1
  116. package/dist/operator/owner-event-prompt.d.ts +13 -4
  117. package/dist/operator/owner-event-prompt.d.ts.map +1 -1
  118. package/dist/operator/owner-event-prompt.js +31 -38
  119. package/dist/operator/owner-event-prompt.js.map +1 -1
  120. package/dist/operator/owner-runtime-journal.d.ts.map +1 -1
  121. package/dist/operator/owner-runtime-journal.js +7 -3
  122. package/dist/operator/owner-runtime-journal.js.map +1 -1
  123. package/dist/operator/owner-runtime.d.ts +6 -0
  124. package/dist/operator/owner-runtime.d.ts.map +1 -1
  125. package/dist/operator/owner-runtime.js +48 -5
  126. package/dist/operator/owner-runtime.js.map +1 -1
  127. package/dist/operator/procedure-activation.d.ts +7 -0
  128. package/dist/operator/procedure-activation.d.ts.map +1 -0
  129. package/dist/operator/procedure-activation.js +132 -0
  130. package/dist/operator/procedure-activation.js.map +1 -0
  131. package/dist/operator/procedure-projection.d.ts +25 -0
  132. package/dist/operator/procedure-projection.d.ts.map +1 -0
  133. package/dist/operator/procedure-projection.js +80 -0
  134. package/dist/operator/procedure-projection.js.map +1 -0
  135. package/dist/operator/procedure-runtime.d.ts +45 -0
  136. package/dist/operator/procedure-runtime.d.ts.map +1 -0
  137. package/dist/operator/procedure-runtime.js +496 -0
  138. package/dist/operator/procedure-runtime.js.map +1 -0
  139. package/dist/operator/procedure-store.d.ts +97 -0
  140. package/dist/operator/procedure-store.d.ts.map +1 -0
  141. package/dist/operator/procedure-store.js +368 -0
  142. package/dist/operator/procedure-store.js.map +1 -0
  143. package/dist/operator/subagent-stimulus.d.ts +34 -0
  144. package/dist/operator/subagent-stimulus.d.ts.map +1 -0
  145. package/dist/operator/subagent-stimulus.js +145 -0
  146. package/dist/operator/subagent-stimulus.js.map +1 -0
  147. package/dist/operator/task-ledger.d.ts +40 -3
  148. package/dist/operator/task-ledger.d.ts.map +1 -1
  149. package/dist/operator/task-ledger.js +63 -10
  150. package/dist/operator/task-ledger.js.map +1 -1
  151. package/dist/operator/thread-brief-memory.d.ts +29 -0
  152. package/dist/operator/thread-brief-memory.d.ts.map +1 -0
  153. package/dist/operator/thread-brief-memory.js +61 -0
  154. package/dist/operator/thread-brief-memory.js.map +1 -0
  155. package/dist/operator/trigger-author.d.ts +2 -1
  156. package/dist/operator/trigger-author.d.ts.map +1 -1
  157. package/dist/operator/trigger-author.js +23 -0
  158. package/dist/operator/trigger-author.js.map +1 -1
  159. package/dist/operator/trigger-matcher.js +1 -0
  160. package/dist/operator/trigger-matcher.js.map +1 -1
  161. package/dist/operator/trigger-registry.d.ts +5 -4
  162. package/dist/operator/trigger-registry.d.ts.map +1 -1
  163. package/dist/operator/trigger-registry.js +78 -24
  164. package/dist/operator/trigger-registry.js.map +1 -1
  165. package/dist/operator/trigger-review.d.ts +1 -1
  166. package/dist/operator/trigger-review.d.ts.map +1 -1
  167. package/dist/operator/trigger-review.js +24 -4
  168. package/dist/operator/trigger-review.js.map +1 -1
  169. package/dist/operator/trigger-types.d.ts +10 -1
  170. package/dist/operator/trigger-types.d.ts.map +1 -1
  171. package/dist/operator/worker-run.d.ts +7 -1
  172. package/dist/operator/worker-run.d.ts.map +1 -1
  173. package/dist/operator/worker-run.js +5 -2
  174. package/dist/operator/worker-run.js.map +1 -1
  175. package/dist/operator/workorder-consumer.d.ts +91 -14
  176. package/dist/operator/workorder-consumer.d.ts.map +1 -1
  177. package/dist/operator/workorder-consumer.js +272 -93
  178. package/dist/operator/workorder-consumer.js.map +1 -1
  179. package/dist/operator/workorder-hooks.d.ts +42 -9
  180. package/dist/operator/workorder-hooks.d.ts.map +1 -1
  181. package/dist/operator/workorder-hooks.js +52 -13
  182. package/dist/operator/workorder-hooks.js.map +1 -1
  183. package/dist/operator/workorder-publishers.d.ts +9 -1
  184. package/dist/operator/workorder-publishers.d.ts.map +1 -1
  185. package/dist/operator/workorder-publishers.js +21 -2
  186. package/dist/operator/workorder-publishers.js.map +1 -1
  187. package/package.json +2 -2
  188. package/dist/operator/learning-context.d.ts +0 -49
  189. package/dist/operator/learning-context.d.ts.map +0 -1
  190. package/dist/operator/learning-context.js +0 -129
  191. package/dist/operator/learning-context.js.map +0 -1
  192. package/dist/operator/learning-markers.d.ts +0 -19
  193. package/dist/operator/learning-markers.d.ts.map +0 -1
  194. package/dist/operator/learning-markers.js +0 -147
  195. package/dist/operator/learning-markers.js.map +0 -1
  196. package/dist/operator/learning-read.d.ts +0 -16
  197. package/dist/operator/learning-read.d.ts.map +0 -1
  198. package/dist/operator/learning-read.js +0 -18
  199. package/dist/operator/learning-read.js.map +0 -1
  200. package/dist/operator/turn-observer.d.ts +0 -34
  201. package/dist/operator/turn-observer.d.ts.map +0 -1
  202. package/dist/operator/turn-observer.js +0 -79
  203. package/dist/operator/turn-observer.js.map +0 -1
  204. package/templates/skills/heartbeat-report.md +0 -75
@@ -0,0 +1,368 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ProcedureStore = void 0;
4
+ exports.procedureScopeKey = procedureScopeKey;
5
+ const node_crypto_1 = require("node:crypto");
6
+ const operator_procedures_js_1 = require("../db/migrations/operator-procedures.js");
7
+ /** Stable scope identity for durable trigger references, independent of logical procedure ID. */
8
+ function procedureScopeKey(scope) {
9
+ return (0, node_crypto_1.createHash)('sha256')
10
+ .update(JSON.stringify([scope.ownerScope, scope.projectId]))
11
+ .digest('hex');
12
+ }
13
+ function stable(value) {
14
+ if (Array.isArray(value)) {
15
+ return `[${value.map(stable).join(',')}]`;
16
+ }
17
+ if (value !== null && typeof value === 'object') {
18
+ return `{${Object.entries(value)
19
+ .filter(([, v]) => v !== undefined)
20
+ .sort(([a], [b]) => a.localeCompare(b))
21
+ .map(([k, v]) => `${JSON.stringify(k)}:${stable(v)}`)
22
+ .join(',')}}`;
23
+ }
24
+ return JSON.stringify(value);
25
+ }
26
+ function hash(value) {
27
+ return (0, node_crypto_1.createHash)('sha256').update(stable(value)).digest('hex');
28
+ }
29
+ function required(value, name) {
30
+ if (typeof value !== 'string' || !value.trim()) {
31
+ throw new Error(`procedure ${name} required`);
32
+ }
33
+ }
34
+ /** TG-03/TG-05/TG-06: authorized heads, immutable instructions and receipt observations. */
35
+ class ProcedureStore {
36
+ db;
37
+ constructor(db) {
38
+ this.db = db;
39
+ db.pragma('busy_timeout = 5000');
40
+ (0, operator_procedures_js_1.applyOperatorProceduresMigration)(db);
41
+ }
42
+ /** Keep projection file publication serialized with every canonical writer. */
43
+ withWriteTransaction(work) {
44
+ return this.db.transaction(work, 'immediate')();
45
+ }
46
+ authorized(head, access) {
47
+ const channels = head.channel_ids_json === null ? undefined : JSON.parse(head.channel_ids_json);
48
+ return (head.owner_scope === access.ownerScope &&
49
+ head.project_id === access.projectId &&
50
+ (!channels || (access.channelId !== undefined && channels.includes(access.channelId))));
51
+ }
52
+ head(id, access) {
53
+ const row = this.db
54
+ .prepare('SELECT * FROM operator_procedures WHERE id = ? AND owner_scope = ? AND project_id = ?')
55
+ .get(id, access.ownerScope, access.projectId);
56
+ return row && this.authorized(row, access) ? row : null;
57
+ }
58
+ revision(id, revision, access) {
59
+ const row = this.db
60
+ .prepare('SELECT record_json FROM operator_procedure_revisions WHERE procedure_id = ? AND revision = ? AND owner_scope = ? AND project_id = ?')
61
+ .get(id, revision, access.ownerScope, access.projectId);
62
+ return row ? JSON.parse(row.record_json) : null;
63
+ }
64
+ list(access) {
65
+ const heads = this.db
66
+ .prepare("SELECT * FROM operator_procedures WHERE owner_scope = ? AND project_id = ? AND status = 'active' ORDER BY id")
67
+ .all(access.ownerScope, access.projectId);
68
+ return heads
69
+ .filter((head) => this.authorized(head, access))
70
+ .map((head) => {
71
+ const record = this.revision(head.id, head.revision, access);
72
+ if (!record) {
73
+ throw new Error('procedure head revision missing');
74
+ }
75
+ return record;
76
+ });
77
+ }
78
+ read(id, access, revision) {
79
+ const head = this.head(id, access);
80
+ if (!head || head.status !== 'active') {
81
+ return null;
82
+ }
83
+ return this.revision(id, revision ?? head.revision, access);
84
+ }
85
+ history(id, access) {
86
+ if (!this.head(id, access)) {
87
+ return [];
88
+ }
89
+ return this.db
90
+ .prepare('SELECT record_json FROM operator_procedure_revisions WHERE procedure_id = ? AND owner_scope = ? AND project_id = ? ORDER BY revision')
91
+ .all(id, access.ownerScope, access.projectId).map((row) => JSON.parse(row.record_json));
92
+ }
93
+ retry(correctionId, intentHash, access) {
94
+ const row = this.db
95
+ .prepare('SELECT record_json, intent_hash FROM operator_procedure_revisions WHERE owner_scope = ? AND project_id = ? AND correction_id = ?')
96
+ .get(access.ownerScope, access.projectId, correctionId);
97
+ if (!row) {
98
+ return null;
99
+ }
100
+ const record = JSON.parse(row.record_json);
101
+ if (!this.head(record.id, access)) {
102
+ throw new Error('procedure unavailable');
103
+ }
104
+ if (row.intent_hash !== intentHash) {
105
+ throw new Error('procedure correction conflict');
106
+ }
107
+ return record;
108
+ }
109
+ append(record, intentHash) {
110
+ this.db
111
+ .prepare('INSERT INTO operator_procedure_revisions (procedure_id, revision, owner_scope, project_id, correction_id, intent_hash, record_json) VALUES (?, ?, ?, ?, ?, ?, ?)')
112
+ .run(record.id, record.revision, record.scope.ownerScope, record.scope.projectId, record.correctionId, intentHash, JSON.stringify(record));
113
+ }
114
+ save(input, access) {
115
+ for (const field of ['id', 'correctionId', 'title', 'body', 'originalInstruction']) {
116
+ required(input[field], field);
117
+ }
118
+ if (input.scope.ownerScope !== access.ownerScope ||
119
+ input.scope.projectId !== access.projectId ||
120
+ (input.scope.channelIds &&
121
+ (input.scope.channelIds.length === 0 ||
122
+ input.scope.channelIds.some((channel) => channel !== access.channelId)))) {
123
+ throw new Error('procedure scope denied');
124
+ }
125
+ const expected = input.expectedRevision ?? 0;
126
+ if (!Number.isInteger(expected) || expected < 0) {
127
+ throw new Error('procedure expected revision invalid');
128
+ }
129
+ const intentHash = hash({ operation: 'save', ...input, expectedRevision: expected });
130
+ // better-sqlite3 creates a SAVEPOINT when the host already owns a transaction.
131
+ return this.db.transaction(() => {
132
+ const retry = this.retry(input.correctionId, intentHash, access);
133
+ if (retry) {
134
+ return retry;
135
+ }
136
+ const head = this.head(input.id, access);
137
+ if (expected !== (head?.revision ?? 0)) {
138
+ throw new Error('procedure revision conflict');
139
+ }
140
+ if (head && head.status !== 'active') {
141
+ throw new Error('procedure retired');
142
+ }
143
+ if (head &&
144
+ head.channel_ids_json !==
145
+ (input.scope.channelIds ? JSON.stringify(input.scope.channelIds) : null)) {
146
+ throw new Error('procedure scope change denied');
147
+ }
148
+ const previous = head ? this.revision(input.id, head.revision, access) : null;
149
+ if (head && !previous) {
150
+ throw new Error('procedure head revision missing');
151
+ }
152
+ const { expectedRevision: _expectedRevision, ...content } = input;
153
+ const now = Date.now();
154
+ const record = {
155
+ ...content,
156
+ supersededMemoryIds: [
157
+ ...new Set([
158
+ ...(previous?.supersededMemoryIds ?? []),
159
+ ...(input.supersededMemoryIds ?? []),
160
+ ]),
161
+ ],
162
+ scopeKey: procedureScopeKey(access),
163
+ revision: expected + 1,
164
+ status: 'active',
165
+ createdAt: previous?.createdAt ?? now,
166
+ updatedAt: now,
167
+ };
168
+ if (head) {
169
+ const result = this.db
170
+ .prepare('UPDATE operator_procedures SET revision = ? WHERE id = ? AND revision = ? AND owner_scope = ? AND project_id = ?')
171
+ .run(record.revision, input.id, expected, access.ownerScope, access.projectId);
172
+ if (result.changes !== 1) {
173
+ throw new Error('procedure revision conflict');
174
+ }
175
+ }
176
+ else {
177
+ this.db
178
+ .prepare('INSERT INTO operator_procedures (id, revision, status, owner_scope, project_id, channel_ids_json) VALUES (?, ?, ?, ?, ?, ?)')
179
+ .run(input.id, record.revision, record.status, input.scope.ownerScope, input.scope.projectId, input.scope.channelIds ? JSON.stringify(input.scope.channelIds) : null);
180
+ }
181
+ this.append(record, intentHash);
182
+ // Legacy operator DBs may not have trigger references yet. Never create a second truth.
183
+ const triggerColumns = this.db.prepare('PRAGMA table_info(operator_triggers)').all();
184
+ if (triggerColumns.some((column) => column.name === 'procedure_ref_json') &&
185
+ triggerColumns.some((column) => column.name === 'revision')) {
186
+ this.db
187
+ .prepare("UPDATE operator_triggers SET procedure_ref_json = ?, revision = revision + 1 WHERE status = 'active' AND json_extract(procedure_ref_json, '$.id') = ? AND json_extract(procedure_ref_json, '$.scopeKey') = ?")
188
+ .run(JSON.stringify({ id: record.id, revision: record.revision, scopeKey: record.scopeKey }), record.id, record.scopeKey);
189
+ this.db
190
+ .prepare("UPDATE operator_triggers SET revision = revision + 1 WHERE status = 'active' AND id IN (SELECT trigger_id FROM operator_trigger_procedure_bindings WHERE scope_key = ? AND procedure_id = ?) AND NOT (COALESCE(json_extract(procedure_ref_json, '$.id'), '') = ? AND COALESCE(json_extract(procedure_ref_json, '$.scopeKey'), '') = ?)")
191
+ .run(record.scopeKey, record.id, record.id, record.scopeKey);
192
+ }
193
+ return record;
194
+ }, 'immediate')();
195
+ }
196
+ /** The mapping records the original queued snapshot; current head is resolved separately. */
197
+ getLegacyTriggerBinding(triggerId, access) {
198
+ const triggerTable = this.db
199
+ .prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'operator_triggers'")
200
+ .get();
201
+ const trigger = triggerTable
202
+ ? this.db.prepare('SELECT status FROM operator_triggers WHERE id = ?').get(triggerId)
203
+ : undefined;
204
+ if (trigger && trigger.status !== 'active') {
205
+ throw new Error('legacy trigger not active');
206
+ }
207
+ const row = this.db
208
+ .prepare('SELECT procedure_id, procedure_revision, scope_key, snapshot_hash FROM operator_trigger_procedure_bindings WHERE trigger_id = ? AND owner_scope = ? AND project_id = ? AND channel_id = ?')
209
+ .get(triggerId, access.ownerScope, access.projectId, access.channelId ?? '');
210
+ if (!row) {
211
+ return null;
212
+ }
213
+ return {
214
+ id: row.procedure_id,
215
+ revision: row.procedure_revision,
216
+ scopeKey: row.scope_key,
217
+ snapshotHash: row.snapshot_hash,
218
+ };
219
+ }
220
+ /** TG-05: lazy legacy import never binds a global trigger to the first channel's private rule. */
221
+ importLegacyTrigger(input, access, binding) {
222
+ required(binding.triggerId, 'triggerId');
223
+ required(binding.snapshotHash, 'snapshotHash');
224
+ required(access.channelId ?? '', 'legacy channelId');
225
+ return this.withWriteTransaction(() => {
226
+ const triggerTable = this.db
227
+ .prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'operator_triggers'")
228
+ .get();
229
+ const trigger = triggerTable
230
+ ? this.db
231
+ .prepare('SELECT status, revision FROM operator_triggers WHERE id = ?')
232
+ .get(binding.triggerId)
233
+ : undefined;
234
+ if (trigger && trigger.status !== 'active') {
235
+ throw new Error('legacy trigger not active');
236
+ }
237
+ const existing = this.getLegacyTriggerBinding(binding.triggerId, access);
238
+ if (existing) {
239
+ const record = this.read(existing.id, access, existing.revision);
240
+ if (!record) {
241
+ throw new Error('legacy bound procedure unavailable');
242
+ }
243
+ return record;
244
+ }
245
+ const record = this.save(input, access);
246
+ this.db
247
+ .prepare('INSERT INTO operator_trigger_procedure_bindings (trigger_id, owner_scope, project_id, channel_id, procedure_id, procedure_revision, scope_key, snapshot_hash) VALUES (?, ?, ?, ?, ?, ?, ?, ?)')
248
+ .run(binding.triggerId, access.ownerScope, access.projectId, access.channelId, record.id, record.revision, record.scopeKey, binding.snapshotHash);
249
+ if (trigger) {
250
+ const changed = this.db
251
+ .prepare("UPDATE operator_triggers SET revision = revision + 1 WHERE id = ? AND status = 'active' AND revision = ?")
252
+ .run(binding.triggerId, trigger.revision);
253
+ if (changed.changes !== 1) {
254
+ throw new Error('legacy trigger revision conflict');
255
+ }
256
+ }
257
+ return record;
258
+ });
259
+ }
260
+ retire(id, expectedRevision, correctionId, reason, access) {
261
+ required(correctionId, 'correctionId');
262
+ required(reason, 'reason');
263
+ const intentHash = hash({ operation: 'retire', id, expectedRevision, correctionId, reason });
264
+ return this.db.transaction(() => {
265
+ const retry = this.retry(correctionId, intentHash, access);
266
+ if (retry) {
267
+ return retry;
268
+ }
269
+ const head = this.head(id, access);
270
+ if (!head) {
271
+ throw new Error('procedure unavailable');
272
+ }
273
+ if (head.revision !== expectedRevision || head.status !== 'active') {
274
+ throw new Error('procedure revision conflict');
275
+ }
276
+ const previous = this.revision(id, head.revision, access);
277
+ if (!previous) {
278
+ throw new Error('procedure head revision missing');
279
+ }
280
+ const record = {
281
+ ...previous,
282
+ revision: expectedRevision + 1,
283
+ status: 'retired',
284
+ correctionId,
285
+ reason,
286
+ updatedAt: Date.now(),
287
+ };
288
+ this.db
289
+ .prepare("UPDATE operator_procedures SET revision = ?, status = 'retired' WHERE id = ? AND revision = ? AND owner_scope = ? AND project_id = ?")
290
+ .run(record.revision, id, expectedRevision, access.ownerScope, access.projectId);
291
+ this.append(record, intentHash);
292
+ return record;
293
+ }, 'immediate')();
294
+ }
295
+ supersededMemoryIds(access) {
296
+ const heads = this.db
297
+ .prepare('SELECT * FROM operator_procedures WHERE owner_scope = ? AND project_id = ?')
298
+ .all(access.ownerScope, access.projectId);
299
+ return [
300
+ ...new Set(heads
301
+ .filter((head) => this.authorized(head, access))
302
+ .flatMap((head) => this.revision(head.id, head.revision, access)?.supersededMemoryIds ?? [])),
303
+ ];
304
+ }
305
+ recordOutcome(input, access) {
306
+ required(input.receiptId, 'receiptId');
307
+ return this.db.transaction(() => {
308
+ if (!this.head(input.procedureId, access) ||
309
+ !this.revision(input.procedureId, input.revision, access)) {
310
+ throw new Error('procedure unavailable');
311
+ }
312
+ const intentHash = hash(input);
313
+ const row = this.db
314
+ .prepare('SELECT intent_hash, outcome_json FROM operator_procedure_outcomes WHERE procedure_id = ? AND receipt_id = ? AND owner_scope = ? AND project_id = ?')
315
+ .get(input.procedureId, input.receiptId, access.ownerScope, access.projectId);
316
+ if (row) {
317
+ if (row.intent_hash !== intentHash) {
318
+ throw new Error('procedure receipt conflict');
319
+ }
320
+ return JSON.parse(row.outcome_json);
321
+ }
322
+ const record = { ...input, observedAt: Date.now() };
323
+ this.db
324
+ .prepare('INSERT INTO operator_procedure_outcomes (procedure_id, revision, receipt_id, intent_hash, outcome_json, owner_scope, project_id) VALUES (?, ?, ?, ?, ?, ?, ?)')
325
+ .run(input.procedureId, input.revision, input.receiptId, intentHash, JSON.stringify(record), access.ownerScope, access.projectId);
326
+ return record;
327
+ }, 'immediate')();
328
+ }
329
+ /** Durable intent is part of the immutable revision; publication is a separate receipt. */
330
+ pendingProjections(access) {
331
+ return this.list(access).filter((record) => record.projection &&
332
+ !this.db
333
+ .prepare('SELECT 1 FROM operator_procedure_projections WHERE procedure_id = ? AND revision = ? AND owner_scope = ? AND project_id = ?')
334
+ .get(record.id, record.revision, access.ownerScope, access.projectId));
335
+ }
336
+ markProjected(id, revision, publishedHash, access) {
337
+ this.db.transaction(() => {
338
+ const head = this.head(id, access);
339
+ if (!head || head.status !== 'active') {
340
+ throw new Error('procedure unavailable');
341
+ }
342
+ if (head.revision !== revision) {
343
+ throw new Error('procedure projection revision conflict');
344
+ }
345
+ const record = this.revision(id, revision, access);
346
+ if (!record?.projection) {
347
+ throw new Error('procedure projection missing');
348
+ }
349
+ const expected = (0, node_crypto_1.createHash)('sha256').update(record.projection.desiredText).digest('hex');
350
+ if (expected !== publishedHash) {
351
+ throw new Error('procedure projection hash conflict');
352
+ }
353
+ this.db
354
+ .prepare('INSERT INTO operator_procedure_projections (procedure_id, revision, published_hash, owner_scope, project_id) VALUES (?, ?, ?, ?, ?) ON CONFLICT(owner_scope, project_id, procedure_id, revision) DO NOTHING')
355
+ .run(id, revision, publishedHash, access.ownerScope, access.projectId);
356
+ }, 'immediate')();
357
+ }
358
+ getOutcomes(id, access) {
359
+ if (!this.head(id, access)) {
360
+ return [];
361
+ }
362
+ return this.db
363
+ .prepare('SELECT outcome_json FROM operator_procedure_outcomes WHERE procedure_id = ? AND owner_scope = ? AND project_id = ? ORDER BY rowid')
364
+ .all(id, access.ownerScope, access.projectId).map((row) => JSON.parse(row.outcome_json));
365
+ }
366
+ }
367
+ exports.ProcedureStore = ProcedureStore;
368
+ //# sourceMappingURL=procedure-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"procedure-store.js","sourceRoot":"","sources":["../../src/operator/procedure-store.ts"],"names":[],"mappings":";;;AAyEA,8CAMC;AA/ED,6CAAyC;AAEzC,oFAA2F;AAsE3F,iGAAiG;AACjG,SAAgB,iBAAiB,CAC/B,KAAwD;IAExD,OAAO,IAAA,wBAAU,EAAC,QAAQ,CAAC;SACxB,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;SAC3D,MAAM,CAAC,KAAK,CAAC,CAAC;AACnB,CAAC;AAED,SAAS,MAAM,CAAC,KAAc;IAC5B,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,IAAI,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;IAC5C,CAAC;IACD,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAChD,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;aAC7B,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC;aAClC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;aACtC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;aACpD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;IAClB,CAAC;IACD,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;AAC/B,CAAC;AACD,SAAS,IAAI,CAAC,KAAc;IAC1B,OAAO,IAAA,wBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAClE,CAAC;AACD,SAAS,QAAQ,CAAC,KAAa,EAAE,IAAY;IAC3C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;QAC/C,MAAM,IAAI,KAAK,CAAC,aAAa,IAAI,WAAW,CAAC,CAAC;IAChD,CAAC;AACH,CAAC;AAED,4FAA4F;AAC5F,MAAa,cAAc;IACI;IAA7B,YAA6B,EAAkB;QAAlB,OAAE,GAAF,EAAE,CAAgB;QAC7C,EAAE,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;QACjC,IAAA,yDAAgC,EAAC,EAAE,CAAC,CAAC;IACvC,CAAC;IAED,+EAA+E;IAC/E,oBAAoB,CAAI,IAAa;QACnC,OAAO,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,CAAC;IAClD,CAAC;IAEO,UAAU,CAAC,IAAU,EAAE,MAAuB;QACpD,MAAM,QAAQ,GACZ,IAAI,CAAC,gBAAgB,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAc,CAAC;QAC/F,OAAO,CACL,IAAI,CAAC,WAAW,KAAK,MAAM,CAAC,UAAU;YACtC,IAAI,CAAC,UAAU,KAAK,MAAM,CAAC,SAAS;YACpC,CAAC,CAAC,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,KAAK,SAAS,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CACvF,CAAC;IACJ,CAAC;IACO,IAAI,CAAC,EAAU,EAAE,MAAuB;QAC9C,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE;aAChB,OAAO,CACN,uFAAuF,CACxF;aACA,GAAG,CAAC,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,SAAS,CAAqB,CAAC;QACpE,OAAO,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;IAC1D,CAAC;IACO,QAAQ,CAAC,EAAU,EAAE,QAAgB,EAAE,MAAuB;QACpE,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE;aAChB,OAAO,CACN,qIAAqI,CACtI;aACA,GAAG,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,SAAS,CAA4B,CAAC;QACrF,OAAO,GAAG,CAAC,CAAC,CAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAqB,CAAC,CAAC,CAAC,IAAI,CAAC;IACvE,CAAC;IACD,IAAI,CAAC,MAAuB;QAC1B,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE;aAClB,OAAO,CACN,8GAA8G,CAC/G;aACA,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,SAAS,CAAW,CAAC;QACtD,OAAO,KAAK;aACT,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;aAC/C,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YACZ,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAC7D,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;YACrD,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC,CAAC,CAAC;IACP,CAAC;IACD,IAAI,CAAC,EAAU,EAAE,MAAuB,EAAE,QAAiB;QACzD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QACnC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YACtC,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,QAAQ,IAAI,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC9D,CAAC;IACD,OAAO,CAAC,EAAU,EAAE,MAAuB;QACzC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC;YAC3B,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,OACE,IAAI,CAAC,EAAE;aACJ,OAAO,CACN,sIAAsI,CACvI;aACA,GAAG,CAAC,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,SAAS,CAC/C,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAoB,CAAC,CAAC;IACjE,CAAC;IACO,KAAK,CACX,YAAoB,EACpB,UAAkB,EAClB,MAAuB;QAEvB,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE;aAChB,OAAO,CACN,kIAAkI,CACnI;aACA,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,SAAS,EAAE,YAAY,CAA4B,CAAC;QACrF,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAoB,CAAC;QAC9D,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;QAC3C,CAAC;QACD,IAAI,GAAG,CAAC,WAAW,KAAK,UAAU,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;QACnD,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IACO,MAAM,CAAC,MAAuB,EAAE,UAAkB;QACxD,IAAI,CAAC,EAAE;aACJ,OAAO,CACN,kKAAkK,CACnK;aACA,GAAG,CACF,MAAM,CAAC,EAAE,EACT,MAAM,CAAC,QAAQ,EACf,MAAM,CAAC,KAAK,CAAC,UAAU,EACvB,MAAM,CAAC,KAAK,CAAC,SAAS,EACtB,MAAM,CAAC,YAAY,EACnB,UAAU,EACV,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CACvB,CAAC;IACN,CAAC;IACD,IAAI,CAAC,KAAyB,EAAE,MAAuB;QACrD,KAAK,MAAM,KAAK,IAAI,CAAC,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,EAAE,qBAAqB,CAAU,EAAE,CAAC;YAC5F,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;QAChC,CAAC;QACD,IACE,KAAK,CAAC,KAAK,CAAC,UAAU,KAAK,MAAM,CAAC,UAAU;YAC5C,KAAK,CAAC,KAAK,CAAC,SAAS,KAAK,MAAM,CAAC,SAAS;YAC1C,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU;gBACrB,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC;oBAClC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,KAAK,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAC5E,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAC5C,CAAC;QACD,MAAM,QAAQ,GAAG,KAAK,CAAC,gBAAgB,IAAI,CAAC,CAAC;QAC7C,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;YAChD,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;QACzD,CAAC;QACD,MAAM,UAAU,GAAG,IAAI,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,CAAC,CAAC;QACrF,+EAA+E;QAC/E,OAAO,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE;YAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,YAAY,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;YACjE,IAAI,KAAK,EAAE,CAAC;gBACV,OAAO,KAAK,CAAC;YACf,CAAC;YACD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;YACzC,IAAI,QAAQ,KAAK,CAAC,IAAI,EAAE,QAAQ,IAAI,CAAC,CAAC,EAAE,CAAC;gBACvC,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;YACjD,CAAC;YACD,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;gBACrC,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;YACvC,CAAC;YACD,IACE,IAAI;gBACJ,IAAI,CAAC,gBAAgB;oBACnB,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAC1E,CAAC;gBACD,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;YACnD,CAAC;YACD,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAC9E,IAAI,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACtB,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;YACrD,CAAC;YACD,MAAM,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,GAAG,OAAO,EAAE,GAAG,KAAK,CAAC;YAClE,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACvB,MAAM,MAAM,GAAoB;gBAC9B,GAAG,OAAO;gBACV,mBAAmB,EAAE;oBACnB,GAAG,IAAI,GAAG,CAAC;wBACT,GAAG,CAAC,QAAQ,EAAE,mBAAmB,IAAI,EAAE,CAAC;wBACxC,GAAG,CAAC,KAAK,CAAC,mBAAmB,IAAI,EAAE,CAAC;qBACrC,CAAC;iBACH;gBACD,QAAQ,EAAE,iBAAiB,CAAC,MAAM,CAAC;gBACnC,QAAQ,EAAE,QAAQ,GAAG,CAAC;gBACtB,MAAM,EAAE,QAAQ;gBAChB,SAAS,EAAE,QAAQ,EAAE,SAAS,IAAI,GAAG;gBACrC,SAAS,EAAE,GAAG;aACf,CAAC;YACF,IAAI,IAAI,EAAE,CAAC;gBACT,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE;qBACnB,OAAO,CACN,kHAAkH,CACnH;qBACA,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;gBACjF,IAAI,MAAM,CAAC,OAAO,KAAK,CAAC,EAAE,CAAC;oBACzB,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;gBACjD,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,EAAE;qBACJ,OAAO,CACN,6HAA6H,CAC9H;qBACA,GAAG,CACF,KAAK,CAAC,EAAE,EACR,MAAM,CAAC,QAAQ,EACf,MAAM,CAAC,MAAM,EACb,KAAK,CAAC,KAAK,CAAC,UAAU,EACtB,KAAK,CAAC,KAAK,CAAC,SAAS,EACrB,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CACvE,CAAC;YACN,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;YAChC,wFAAwF;YACxF,MAAM,cAAc,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,sCAAsC,CAAC,CAAC,GAAG,EAE/E,CAAC;YACJ,IACE,cAAc,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,oBAAoB,CAAC;gBACrE,cAAc,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,UAAU,CAAC,EAC3D,CAAC;gBACD,IAAI,CAAC,EAAE;qBACJ,OAAO,CACN,8MAA8M,CAC/M;qBACA,GAAG,CACF,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,EACvF,MAAM,CAAC,EAAE,EACT,MAAM,CAAC,QAAQ,CAChB,CAAC;gBACJ,IAAI,CAAC,EAAE;qBACJ,OAAO,CACN,wUAAwU,CACzU;qBACA,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;YACjE,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC,EAAE,WAAW,CAAC,EAAE,CAAC;IACpB,CAAC;IACD,6FAA6F;IAC7F,uBAAuB,CACrB,SAAiB,EACjB,MAAuB;QAOvB,MAAM,YAAY,GAAG,IAAI,CAAC,EAAE;aACzB,OAAO,CAAC,iFAAiF,CAAC;aAC1F,GAAG,EAAE,CAAC;QACT,MAAM,OAAO,GAAG,YAAY;YAC1B,CAAC,CAAE,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,mDAAmD,CAAC,CAAC,GAAG,CAAC,SAAS,CAErE;YAChB,CAAC,CAAC,SAAS,CAAC;QACd,IAAI,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC3C,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAC/C,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE;aAChB,OAAO,CACN,2LAA2L,CAC5L;aACA,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,EAAE,CAOhE,CAAC;QACd,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO;YACL,EAAE,EAAE,GAAG,CAAC,YAAY;YACpB,QAAQ,EAAE,GAAG,CAAC,kBAAkB;YAChC,QAAQ,EAAE,GAAG,CAAC,SAAS;YACvB,YAAY,EAAE,GAAG,CAAC,aAAa;SAChC,CAAC;IACJ,CAAC;IAED,kGAAkG;IAClG,mBAAmB,CACjB,KAAyB,EACzB,MAAuB,EACvB,OAAoD;QAEpD,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;QACzC,QAAQ,CAAC,OAAO,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;QAC/C,QAAQ,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,EAAE,kBAAkB,CAAC,CAAC;QACrD,OAAO,IAAI,CAAC,oBAAoB,CAAC,GAAG,EAAE;YACpC,MAAM,YAAY,GAAG,IAAI,CAAC,EAAE;iBACzB,OAAO,CAAC,iFAAiF,CAAC;iBAC1F,GAAG,EAAE,CAAC;YACT,MAAM,OAAO,GAAG,YAAY;gBAC1B,CAAC,CAAE,IAAI,CAAC,EAAE;qBACL,OAAO,CAAC,6DAA6D,CAAC;qBACtE,GAAG,CAAC,OAAO,CAAC,SAAS,CAAsD;gBAChF,CAAC,CAAC,SAAS,CAAC;YACd,IAAI,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;gBAC3C,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;YAC/C,CAAC;YACD,MAAM,QAAQ,GAAG,IAAI,CAAC,uBAAuB,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;YACzE,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBACjE,IAAI,CAAC,MAAM,EAAE,CAAC;oBACZ,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;gBACxD,CAAC;gBACD,OAAO,MAAM,CAAC;YAChB,CAAC;YACD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YACxC,IAAI,CAAC,EAAE;iBACJ,OAAO,CACN,+LAA+L,CAChM;iBACA,GAAG,CACF,OAAO,CAAC,SAAS,EACjB,MAAM,CAAC,UAAU,EACjB,MAAM,CAAC,SAAS,EAChB,MAAM,CAAC,SAAS,EAChB,MAAM,CAAC,EAAE,EACT,MAAM,CAAC,QAAQ,EACf,MAAM,CAAC,QAAQ,EACf,OAAO,CAAC,YAAY,CACrB,CAAC;YACJ,IAAI,OAAO,EAAE,CAAC;gBACZ,MAAM,OAAO,GAAG,IAAI,CAAC,EAAE;qBACpB,OAAO,CACN,0GAA0G,CAC3G;qBACA,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;gBAC5C,IAAI,OAAO,CAAC,OAAO,KAAK,CAAC,EAAE,CAAC;oBAC1B,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;gBACtD,CAAC;YACH,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CACJ,EAAU,EACV,gBAAwB,EACxB,YAAoB,EACpB,MAAc,EACd,MAAuB;QAEvB,QAAQ,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;QACvC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAC3B,MAAM,UAAU,GAAG,IAAI,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC,CAAC;QAC7F,OAAO,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE;YAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;YAC3D,IAAI,KAAK,EAAE,CAAC;gBACV,OAAO,KAAK,CAAC;YACf,CAAC;YACD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;YACnC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;YAC3C,CAAC;YACD,IAAI,IAAI,CAAC,QAAQ,KAAK,gBAAgB,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;gBACnE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;YACjD,CAAC;YACD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAC1D,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;YACrD,CAAC;YACD,MAAM,MAAM,GAAoB;gBAC9B,GAAG,QAAQ;gBACX,QAAQ,EAAE,gBAAgB,GAAG,CAAC;gBAC9B,MAAM,EAAE,SAAS;gBACjB,YAAY;gBACZ,MAAM;gBACN,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;aACtB,CAAC;YACF,IAAI,CAAC,EAAE;iBACJ,OAAO,CACN,sIAAsI,CACvI;iBACA,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,EAAE,gBAAgB,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;YACnF,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;YAChC,OAAO,MAAM,CAAC;QAChB,CAAC,EAAE,WAAW,CAAC,EAAE,CAAC;IACpB,CAAC;IACD,mBAAmB,CAAC,MAAuB;QACzC,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE;aAClB,OAAO,CAAC,4EAA4E,CAAC;aACrF,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,SAAS,CAAW,CAAC;QACtD,OAAO;YACL,GAAG,IAAI,GAAG,CACR,KAAK;iBACF,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;iBAC/C,OAAO,CACN,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,mBAAmB,IAAI,EAAE,CACnF,CACJ;SACF,CAAC;IACJ,CAAC;IACD,aAAa,CAAC,KAA4B,EAAE,MAAuB;QACjE,QAAQ,CAAC,KAAK,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;QACvC,OAAO,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE;YAC9B,IACE,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,MAAM,CAAC;gBACrC,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,EACzD,CAAC;gBACD,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;YAC3C,CAAC;YACD,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;YAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE;iBAChB,OAAO,CACN,oJAAoJ,CACrJ;iBACA,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,SAAS,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,SAAS,CAEjE,CAAC;YACd,IAAI,GAAG,EAAE,CAAC;gBACR,IAAI,GAAG,CAAC,WAAW,KAAK,UAAU,EAAE,CAAC;oBACnC,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;gBAChD,CAAC;gBACD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAqB,CAAC;YAC1D,CAAC;YACD,MAAM,MAAM,GAAG,EAAE,GAAG,KAAK,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;YACpD,IAAI,CAAC,EAAE;iBACJ,OAAO,CACN,+JAA+J,CAChK;iBACA,GAAG,CACF,KAAK,CAAC,WAAW,EACjB,KAAK,CAAC,QAAQ,EACd,KAAK,CAAC,SAAS,EACf,UAAU,EACV,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EACtB,MAAM,CAAC,UAAU,EACjB,MAAM,CAAC,SAAS,CACjB,CAAC;YACJ,OAAO,MAAM,CAAC;QAChB,CAAC,EAAE,WAAW,CAAC,EAAE,CAAC;IACpB,CAAC;IACD,2FAA2F;IAC3F,kBAAkB,CAAC,MAAuB;QACxC,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAC7B,CAAC,MAAM,EAAE,EAAE,CACT,MAAM,CAAC,UAAU;YACjB,CAAC,IAAI,CAAC,EAAE;iBACL,OAAO,CACN,6HAA6H,CAC9H;iBACA,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,SAAS,CAAC,CAC1E,CAAC;IACJ,CAAC;IACD,aAAa,CACX,EAAU,EACV,QAAgB,EAChB,aAAqB,EACrB,MAAuB;QAEvB,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE;YACvB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;YACnC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;gBACtC,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;YAC3C,CAAC;YACD,IAAI,IAAI,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBAC/B,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;YAC5D,CAAC;YACD,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;YACnD,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC;gBACxB,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;YAClD,CAAC;YACD,MAAM,QAAQ,GAAG,IAAA,wBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC1F,IAAI,QAAQ,KAAK,aAAa,EAAE,CAAC;gBAC/B,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;YACxD,CAAC;YACD,IAAI,CAAC,EAAE;iBACJ,OAAO,CACN,6MAA6M,CAC9M;iBACA,GAAG,CAAC,EAAE,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;QAC3E,CAAC,EAAE,WAAW,CAAC,EAAE,CAAC;IACpB,CAAC;IACD,WAAW,CAAC,EAAU,EAAE,MAAuB;QAC7C,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC;YAC3B,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,OACE,IAAI,CAAC,EAAE;aACJ,OAAO,CACN,mIAAmI,CACpI;aACA,GAAG,CAAC,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,SAAS,CAC/C,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAqB,CAAC,CAAC;IACnE,CAAC;CACF;AApdD,wCAodC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Waking the standing owner when a native subagent finishes.
3
+ *
4
+ * The owner agent delegates long, bounded work to a native subagent and ends its
5
+ * turn, so the owner conversation is never blocked behind maintenance. The child's
6
+ * completion is therefore a HOST stimulus, delivered on the same one durable owner
7
+ * subject as heartbeat and cron stimuli, and treated exactly like a background task
8
+ * notification: the agent reads the result, verifies it, and decides what to do.
9
+ *
10
+ * The child's final text is text a model wrote outside this turn's authority. It is
11
+ * wrapped as untrusted data - it is evidence to check, not an instruction to obey.
12
+ */
13
+ import type { SubagentEvent } from '../multi-agent/runtime-process.js';
14
+ export type { SubagentEvent } from '../multi-agent/runtime-process.js';
15
+ /** Stable ref for dedupe and for the owner recovery journal. */
16
+ export declare function subagentStimulusSourceRef(event: SubagentEvent): string;
17
+ /**
18
+ * The evidence block alone - what the recovery journal stores. The host sentence is
19
+ * standing policy, not evidence, so it is not journalled.
20
+ */
21
+ export declare function buildSubagentStimulusBlock(event: SubagentEvent): string;
22
+ /** The owner-turn text for a completed subagent event. */
23
+ export declare function buildSubagentStimulus(event: SubagentEvent): string;
24
+ /** Only a finished child of the STANDING OWNER's own turn wakes the owner subject. */
25
+ export declare function shouldWakeOwner(event: SubagentEvent): boolean;
26
+ /**
27
+ * Subscribe an owner wake to a model runner's subagent events.
28
+ *
29
+ * Idempotent per child thread: a duplicate 'completed' event must not enqueue a
30
+ * second owner turn. A runner that does not emit subagent events (Claude CLI,
31
+ * test doubles) yields a no-op detach rather than a boot failure.
32
+ */
33
+ export declare function attachSubagentWake(runner: unknown, wake: (event: SubagentEvent) => Promise<unknown>, log?: (line: string) => void): () => void;
34
+ //# sourceMappingURL=subagent-stimulus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subagent-stimulus.d.ts","sourceRoot":"","sources":["../../src/operator/subagent-stimulus.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAIvE,YAAY,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAoDvE,gEAAgE;AAChE,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAEtE;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAUvE;AAED,0DAA0D;AAC1D,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAElE;AAED,sFAAsF;AACtF,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAE7D;AAgBD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,OAAO,EACf,IAAI,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,OAAO,CAAC,OAAO,CAAC,EAChD,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAC3B,MAAM,IAAI,CAsCZ"}
@@ -0,0 +1,145 @@
1
+ "use strict";
2
+ /**
3
+ * Waking the standing owner when a native subagent finishes.
4
+ *
5
+ * The owner agent delegates long, bounded work to a native subagent and ends its
6
+ * turn, so the owner conversation is never blocked behind maintenance. The child's
7
+ * completion is therefore a HOST stimulus, delivered on the same one durable owner
8
+ * subject as heartbeat and cron stimuli, and treated exactly like a background task
9
+ * notification: the agent reads the result, verifies it, and decides what to do.
10
+ *
11
+ * The child's final text is text a model wrote outside this turn's authority. It is
12
+ * wrapped as untrusted data - it is evidence to check, not an instruction to obey.
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.subagentStimulusSourceRef = subagentStimulusSourceRef;
16
+ exports.buildSubagentStimulusBlock = buildSubagentStimulusBlock;
17
+ exports.buildSubagentStimulus = buildSubagentStimulus;
18
+ exports.shouldWakeOwner = shouldWakeOwner;
19
+ exports.attachSubagentWake = attachSubagentWake;
20
+ const untrusted_content_js_1 = require("../utils/untrusted-content.js");
21
+ const owner_runtime_js_1 = require("./owner-runtime.js");
22
+ /** Upper bound on the quoted child result reaching the owner prompt. */
23
+ const MAX_RESULT_CHARS = 4000;
24
+ /**
25
+ * The one sentence the host adds. It names the situation and the standing
26
+ * obligation (verify, then carry the outcome) and stops there: choosing tools and
27
+ * ordering the follow-up is the agent's judgment, not the host's script.
28
+ */
29
+ const OWNER_OBLIGATION = 'Read its result (wait_agent/list_agents if you need ' +
30
+ 'more), verify what matters against the sources, and carry the outcome to the owner or the ' +
31
+ 'board as the original objective requires. Do not restate the result as your own work ' +
32
+ 'without checking it.';
33
+ const OWNER_SENTENCE = `A subagent you started has finished. ${OWNER_OBLIGATION}`;
34
+ /**
35
+ * A child that failed, was interrupted, or whose completion was never confirmed must not
36
+ * reach the owner wearing the success sentence. The status is named in the sentence.
37
+ */
38
+ function ownerSentence(event) {
39
+ const status = event.status ?? 'unknown';
40
+ return status === 'completed'
41
+ ? OWNER_SENTENCE
42
+ : `A subagent you started ended with status ${status}. ${OWNER_OBLIGATION}`;
43
+ }
44
+ /** Attribute values are host-visible identifiers; keep them from closing the tag. */
45
+ function attributeValue(raw) {
46
+ return raw.replace(/["<>]/g, '_');
47
+ }
48
+ function resultBody(event) {
49
+ const text = event.finalText ?? '';
50
+ const error = event.error?.trim() ? event.error.slice(0, MAX_RESULT_CHARS) : '';
51
+ const parts = [];
52
+ if (text.trim().length > 0) {
53
+ parts.push(text.length > MAX_RESULT_CHARS ? `${text.slice(0, MAX_RESULT_CHARS)}\n[truncated]` : text);
54
+ }
55
+ // Partial text never hides the failure: an error is reported alongside it, not instead.
56
+ if (error) {
57
+ parts.push(parts.length > 0 ? `error: ${error}` : `(no final answer) error: ${error}`);
58
+ }
59
+ if (parts.length === 0) {
60
+ return '(no result text returned)';
61
+ }
62
+ return parts.join('\n');
63
+ }
64
+ /** Stable ref for dedupe and for the owner recovery journal. */
65
+ function subagentStimulusSourceRef(event) {
66
+ return `subagent:${event.agentThreadId}`;
67
+ }
68
+ /**
69
+ * The evidence block alone - what the recovery journal stores. The host sentence is
70
+ * standing policy, not evidence, so it is not journalled.
71
+ */
72
+ function buildSubagentStimulusBlock(event) {
73
+ const header = `<subagent_completed path="${attributeValue(event.agentPath)}" ` +
74
+ `thread="${attributeValue(event.agentThreadId)}" ` +
75
+ `status="${attributeValue(event.status ?? 'unknown')}">`;
76
+ return [
77
+ header,
78
+ (0, untrusted_content_js_1.wrapUntrustedContent)(subagentStimulusSourceRef(event), resultBody(event)),
79
+ '</subagent_completed>',
80
+ ].join('\n');
81
+ }
82
+ /** The owner-turn text for a completed subagent event. */
83
+ function buildSubagentStimulus(event) {
84
+ return `${buildSubagentStimulusBlock(event)}\n\n${ownerSentence(event)}`;
85
+ }
86
+ /** Only a finished child of the STANDING OWNER's own turn wakes the owner subject. */
87
+ function shouldWakeOwner(event) {
88
+ return event.kind === 'completed' && event.sessionKey === owner_runtime_js_1.OWNER_RUNTIME_SESSION_KEY;
89
+ }
90
+ function asSubagentEmitter(runner) {
91
+ if (!runner || typeof runner !== 'object')
92
+ return null;
93
+ const candidate = runner;
94
+ return typeof candidate.on === 'function' ? candidate : null;
95
+ }
96
+ const MAX_HANDLED_THREADS = 200;
97
+ /**
98
+ * Subscribe an owner wake to a model runner's subagent events.
99
+ *
100
+ * Idempotent per child thread: a duplicate 'completed' event must not enqueue a
101
+ * second owner turn. A runner that does not emit subagent events (Claude CLI,
102
+ * test doubles) yields a no-op detach rather than a boot failure.
103
+ */
104
+ function attachSubagentWake(runner, wake, log) {
105
+ const emitter = asSubagentEmitter(runner);
106
+ if (!emitter) {
107
+ return () => { };
108
+ }
109
+ const emit = log ?? ((line) => console.log(line));
110
+ const handled = new Set();
111
+ const handler = (event) => {
112
+ if (!event || !shouldWakeOwner(event))
113
+ return;
114
+ const ref = subagentStimulusSourceRef(event);
115
+ if (handled.has(ref))
116
+ return;
117
+ handled.add(ref);
118
+ if (handled.size > MAX_HANDLED_THREADS) {
119
+ const oldest = handled.values().next().value;
120
+ if (oldest !== undefined)
121
+ handled.delete(oldest);
122
+ }
123
+ emit(`[subagent] wake owner path=${event.agentPath} thread=${event.agentThreadId} ` +
124
+ `status=${event.status ?? 'unknown'}`);
125
+ void wake(event).catch((error) => {
126
+ const message = error instanceof Error ? error.message : String(error);
127
+ const line = `[subagent] wake failed thread=${event.agentThreadId}: ${message}`;
128
+ if (log)
129
+ log(line);
130
+ else
131
+ console.error(line);
132
+ // A rejected wake delivered nothing, so the ref must leave the dedupe set: the
133
+ // guarantee is "no duplicate owner turn", not "one attempt and the result is lost".
134
+ handled.delete(ref);
135
+ });
136
+ };
137
+ emitter.on('subagent', handler);
138
+ return () => {
139
+ if (typeof emitter.off === 'function')
140
+ emitter.off('subagent', handler);
141
+ else if (typeof emitter.removeListener === 'function')
142
+ emitter.removeListener('subagent', handler);
143
+ };
144
+ }
145
+ //# sourceMappingURL=subagent-stimulus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subagent-stimulus.js","sourceRoot":"","sources":["../../src/operator/subagent-stimulus.ts"],"names":[],"mappings":"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"}