@teamscala/service-boot 0.23.367 → 0.23.368

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.
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  },
7
7
  "name": "@teamscala/service-boot",
8
8
  "type": "module",
9
- "version": "0.23.367",
9
+ "version": "0.23.368",
10
10
  "sideEffects": false,
11
11
  "imports": {
12
12
  "#service-boot/*": "./src/*",
@@ -40,6 +40,7 @@ export interface EscalationEpisode {
40
40
  workItemId: string | null;
41
41
  resolvedAt: Date | null;
42
42
  lastUpdatedAt: Date | null;
43
+ deliveredCommentId?: string | null;
43
44
  }
44
45
 
45
46
  export interface FaultEscalationPolicy {
@@ -82,8 +82,11 @@ const FaultEscalationConfigSchema = v.object({
82
82
  ),
83
83
  resolve_after_minutes: v.number(),
84
84
  update_after_minutes: v.number(),
85
- /** The developer-session project escalations are parented to. */
86
- parent_project_id: v.string(),
85
+ /** The orchestrator's work item — escalations are COMMENTS on it, never
86
+ * task rows (the fleet-task-placement CHECK constraint refuses a system
87
+ * task without session identity, and an escalation is a finding, not an
88
+ * assigned unit of work). */
89
+ orchestrator_work_item_id: v.string(),
87
90
  /** Per-kind copy for the message (impact + recommendation). Falls back to default_copy. */
88
91
  copy: v.record(v.string(), v.object({ impact: v.string(), recommendation: v.string() })),
89
92
  default_copy: v.object({ impact: v.string(), recommendation: v.string() }),
@@ -316,26 +319,21 @@ async function deliverEscalation(
316
319
  );
317
320
  }
318
321
 
319
- // 4. Durable record: the work_items task the PA reads back / the operator answers on.
320
- const workItem = await (await orpc()).work_items.create({
322
+ // 4. Durable record: a COMMENT on the orchestrator's work item — an
323
+ // escalation is a finding the orchestrator/operator triages, not an
324
+ // assigned task (the fleet-task-placement constraint refuses task rows
325
+ // without session identity by design).
326
+ const comment = await (await orpc()).comments.create({
321
327
  data: {
322
- kind: "task",
323
- parent_id: config.parent_project_id,
324
- organisation_id: bot.organisation_id,
325
- title: `Fault: ${kind}`.slice(0, 50),
326
- description: composeEscalationDescription({ aggregate, impact: copy.impact, recommendation: copy.recommendation }),
327
- status: "pending",
328
- kind_data: {
329
- platform_fault: true,
330
- event_kind: kind,
331
- event_count: aggregate.count,
332
- first_seen_at: aggregate.firstSeen.toISOString(),
333
- last_seen_at: aggregate.lastSeen.toISOString(),
334
- delivered_message_id: messageId,
335
- escalated_at: now.toISOString(),
336
- },
328
+ work_item_id: config.orchestrator_work_item_id,
329
+ content: composeEscalationMessage({
330
+ kind,
331
+ aggregate,
332
+ impact: copy.impact,
333
+ recommendation: copy.recommendation,
334
+ }),
335
+ source_cli_session_id: null,
337
336
  },
338
- select: { id: true },
339
337
  });
340
338
 
341
339
  // 5. Readback-correct the episode: delivered + linked in one update.
@@ -343,7 +341,8 @@ async function deliverEscalation(
343
341
  where: { kind },
344
342
  data: {
345
343
  escalated_at: now.toISOString(),
346
- work_item_id: workItem.id,
344
+ work_item_id: config.orchestrator_work_item_id,
345
+ delivered_comment_id: comment.id,
347
346
  delivered_message_id: messageId,
348
347
  last_updated_at: now.toISOString(),
349
348
  updated_at: now.toISOString(),
@@ -355,11 +354,12 @@ async function deliverEscalation(
355
354
  payload: {
356
355
  event_kind: kind,
357
356
  count: aggregate.count,
358
- work_item_id: workItem.id,
357
+ work_item_id: config.orchestrator_work_item_id,
358
+ delivered_comment_id: comment.id,
359
359
  delivered_message_id: messageId,
360
360
  },
361
361
  });
362
- return { messageId, workItemId: workItem.id };
362
+ return { messageId, workItemId: config.orchestrator_work_item_id };
363
363
  }
364
364
 
365
365
  async function updateEpisode(aggregate: FaultAggregate, episode: EscalationEpisode): Promise<void> {