@synth-deploy/server 0.1.0 → 1.1.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 (96) hide show
  1. package/dist/agent/envoy-client.d.ts +62 -7
  2. package/dist/agent/envoy-client.d.ts.map +1 -1
  3. package/dist/agent/envoy-client.js +56 -6
  4. package/dist/agent/envoy-client.js.map +1 -1
  5. package/dist/agent/stale-deployment-detector.js +1 -1
  6. package/dist/agent/stale-deployment-detector.js.map +1 -1
  7. package/dist/agent/synth-agent.d.ts +7 -5
  8. package/dist/agent/synth-agent.d.ts.map +1 -1
  9. package/dist/agent/synth-agent.js +42 -39
  10. package/dist/agent/synth-agent.js.map +1 -1
  11. package/dist/alert-webhooks/alert-parsers.d.ts +21 -0
  12. package/dist/alert-webhooks/alert-parsers.d.ts.map +1 -0
  13. package/dist/alert-webhooks/alert-parsers.js +184 -0
  14. package/dist/alert-webhooks/alert-parsers.js.map +1 -0
  15. package/dist/api/agent.d.ts +0 -6
  16. package/dist/api/agent.d.ts.map +1 -1
  17. package/dist/api/agent.js +6 -459
  18. package/dist/api/agent.js.map +1 -1
  19. package/dist/api/alert-webhooks.d.ts +13 -0
  20. package/dist/api/alert-webhooks.d.ts.map +1 -0
  21. package/dist/api/alert-webhooks.js +279 -0
  22. package/dist/api/alert-webhooks.js.map +1 -0
  23. package/dist/api/envoy-reports.js +2 -2
  24. package/dist/api/envoy-reports.js.map +1 -1
  25. package/dist/api/envoys.js +1 -1
  26. package/dist/api/envoys.js.map +1 -1
  27. package/dist/api/fleet.d.ts.map +1 -1
  28. package/dist/api/fleet.js +14 -15
  29. package/dist/api/fleet.js.map +1 -1
  30. package/dist/api/graph.js +3 -3
  31. package/dist/api/graph.js.map +1 -1
  32. package/dist/api/operations.d.ts +7 -0
  33. package/dist/api/operations.d.ts.map +1 -0
  34. package/dist/api/operations.js +1883 -0
  35. package/dist/api/operations.js.map +1 -0
  36. package/dist/api/partitions.js +1 -1
  37. package/dist/api/partitions.js.map +1 -1
  38. package/dist/api/schemas.d.ts +194 -10
  39. package/dist/api/schemas.d.ts.map +1 -1
  40. package/dist/api/schemas.js +38 -5
  41. package/dist/api/schemas.js.map +1 -1
  42. package/dist/api/system.d.ts.map +1 -1
  43. package/dist/api/system.js +22 -21
  44. package/dist/api/system.js.map +1 -1
  45. package/dist/artifact-analyzer.js +2 -2
  46. package/dist/artifact-analyzer.js.map +1 -1
  47. package/dist/fleet/fleet-executor.js +1 -1
  48. package/dist/fleet/fleet-executor.js.map +1 -1
  49. package/dist/graph/graph-executor.js +2 -2
  50. package/dist/graph/graph-executor.js.map +1 -1
  51. package/dist/index.js +44 -40
  52. package/dist/index.js.map +1 -1
  53. package/dist/mcp/resources.js +3 -3
  54. package/dist/mcp/resources.js.map +1 -1
  55. package/dist/mcp/tools.d.ts.map +1 -1
  56. package/dist/mcp/tools.js +2 -9
  57. package/dist/mcp/tools.js.map +1 -1
  58. package/dist/middleware/auth.js +1 -1
  59. package/dist/middleware/auth.js.map +1 -1
  60. package/package.json +1 -1
  61. package/src/agent/envoy-client.ts +107 -15
  62. package/src/agent/stale-deployment-detector.ts +1 -1
  63. package/src/agent/synth-agent.ts +59 -45
  64. package/src/alert-webhooks/alert-parsers.ts +291 -0
  65. package/src/api/agent.ts +9 -528
  66. package/src/api/alert-webhooks.ts +354 -0
  67. package/src/api/envoy-reports.ts +2 -2
  68. package/src/api/envoys.ts +1 -1
  69. package/src/api/fleet.ts +14 -15
  70. package/src/api/graph.ts +3 -3
  71. package/src/api/operations.ts +2240 -0
  72. package/src/api/partitions.ts +1 -1
  73. package/src/api/schemas.ts +43 -7
  74. package/src/api/system.ts +23 -21
  75. package/src/artifact-analyzer.ts +2 -2
  76. package/src/fleet/fleet-executor.ts +1 -1
  77. package/src/graph/graph-executor.ts +2 -2
  78. package/src/index.ts +46 -40
  79. package/src/mcp/resources.ts +3 -3
  80. package/src/mcp/tools.ts +5 -9
  81. package/src/middleware/auth.ts +1 -1
  82. package/tests/agent-mode.test.ts +5 -376
  83. package/tests/api-handlers.test.ts +27 -27
  84. package/tests/composite-operations.test.ts +557 -0
  85. package/tests/decision-diary.test.ts +62 -63
  86. package/tests/diary-reader.test.ts +14 -18
  87. package/tests/mcp-tools.test.ts +1 -1
  88. package/tests/orchestration.test.ts +34 -30
  89. package/tests/partition-isolation.test.ts +4 -9
  90. package/tests/rbac-enforcement.test.ts +8 -8
  91. package/tests/ui-journey.test.ts +9 -9
  92. package/dist/api/deployments.d.ts +0 -11
  93. package/dist/api/deployments.d.ts.map +0 -1
  94. package/dist/api/deployments.js +0 -1098
  95. package/dist/api/deployments.js.map +0 -1
  96. package/src/api/deployments.ts +0 -1347
@@ -127,16 +127,19 @@ async function testDeploy(
127
127
  opts.envVars ?? {},
128
128
  );
129
129
 
130
- const trigger = {
130
+ const operationInput = {
131
+ type: "deploy" as const,
131
132
  artifactId: artifact.id,
132
133
  artifactVersionId: opts.version ?? "2.0.0",
134
+ };
135
+ const operationTrigger = {
133
136
  partitionId: opts.partitionId ?? partition.id,
134
137
  environmentId: env.id,
135
138
  triggeredBy: "user" as const,
136
139
  ...(opts.variables ? { variables: opts.variables } : {}),
137
140
  };
138
141
 
139
- return agent.triggerDeployment(trigger);
142
+ return agent.triggerOperation(operationInput, operationTrigger);
140
143
  }
141
144
 
142
145
  // ---------------------------------------------------------------------------
@@ -169,7 +172,7 @@ describe("Decision Diary — entry specificity", () => {
169
172
  variables: { LOG_LEVEL: "error" },
170
173
  });
171
174
 
172
- const entries = diary.getByDeployment(result.id);
175
+ const entries = diary.getByOperation(result.id);
173
176
  expect(entries.length).toBeGreaterThanOrEqual(5);
174
177
 
175
178
  for (const entry of entries) {
@@ -191,7 +194,7 @@ describe("Decision Diary — entry specificity", () => {
191
194
  variables: { LOG_LEVEL: "error" },
192
195
  });
193
196
 
194
- const entries = diary.getByDeployment(result.id);
197
+ const entries = diary.getByOperation(result.id);
195
198
 
196
199
  // Reasoning must contain at least one concrete reference
197
200
  const genericPhrases = [
@@ -222,7 +225,7 @@ describe("Decision Diary — entry specificity", () => {
222
225
 
223
226
  expect(result.status).toBe("failed");
224
227
 
225
- const entries = diary.getByDeployment(result.id);
228
+ const entries = diary.getByOperation(result.id);
226
229
  const failEntry = findDecisions(entries, "Deployment failed")[0];
227
230
 
228
231
  // Failure reasoning must contain recommended action
@@ -239,7 +242,7 @@ describe("Decision Diary — entry specificity", () => {
239
242
  variables: { LOG_LEVEL: "debug" },
240
243
  });
241
244
 
242
- const entries = diary.getByDeployment(result.id);
245
+ const entries = diary.getByOperation(result.id);
243
246
  const conflictEntries = findDecisions(entries, "conflict");
244
247
  expect(conflictEntries.length).toBeGreaterThanOrEqual(1);
245
248
 
@@ -280,7 +283,7 @@ describe("Decision Diary — orchestration completeness", () => {
280
283
 
281
284
  const result = await testDeploy(agent, artifactStore, environmentStore, partitionStore);
282
285
 
283
- const entries = diary.getByDeployment(result.id);
286
+ const entries = diary.getByOperation(result.id);
284
287
  const types = entries.map((e) => e.decisionType);
285
288
 
286
289
  expect(types).toContain("artifact-analysis");
@@ -297,7 +300,7 @@ describe("Decision Diary — orchestration completeness", () => {
297
300
 
298
301
  const result = await testDeploy(agent, artifactStore, environmentStore, partitionStore);
299
302
 
300
- const entries = diary.getByDeployment(result.id);
303
+ const entries = diary.getByOperation(result.id);
301
304
  const types = entries.map((e) => e.decisionType);
302
305
 
303
306
  // Should have artifact analysis, plan, config, health check (retry), and failure
@@ -318,16 +321,12 @@ describe("Decision Diary — orchestration completeness", () => {
318
321
  const partition = partitionStore.create("Acme Corp", { DB_HOST: "prod-db.internal" });
319
322
  const env = environmentStore.create("staging", { DB_HOST: "staging-db.internal" });
320
323
 
321
- const trigger = {
322
- artifactId: artifact.id,
323
- artifactVersionId: "2.0.0",
324
- partitionId: partition.id,
325
- environmentId: env.id,
326
- triggeredBy: "user" as const,
327
- };
328
- const result = await agent.triggerDeployment(trigger);
324
+ const result = await agent.triggerOperation(
325
+ { type: "deploy", artifactId: artifact.id, artifactVersionId: "2.0.0" },
326
+ { partitionId: partition.id, environmentId: env.id, triggeredBy: "user" },
327
+ );
329
328
 
330
- const entries = diary.getByDeployment(result.id);
329
+ const entries = diary.getByOperation(result.id);
331
330
  const types = entries.map((e) => e.decisionType);
332
331
 
333
332
  expect(types).toContain("variable-conflict");
@@ -394,8 +393,8 @@ describe("Decision Diary — retrieval dimensions", () => {
394
393
  const result1 = await testDeploy(agent, artifactStore, environmentStore, partitionStore, { version: "1.0.0" });
395
394
  const result2 = await testDeploy(agent, artifactStore, environmentStore, partitionStore, { version: "2.0.0" });
396
395
 
397
- const entries1 = diary.getByDeployment(result1.id);
398
- const entries2 = diary.getByDeployment(result2.id);
396
+ const entries1 = diary.getByOperation(result1.id);
397
+ const entries2 = diary.getByOperation(result2.id);
399
398
 
400
399
  // Each deployment has its own entries
401
400
  expect(entries1.length).toBeGreaterThanOrEqual(5);
@@ -403,10 +402,10 @@ describe("Decision Diary — retrieval dimensions", () => {
403
402
 
404
403
  // No cross-contamination
405
404
  for (const e of entries1) {
406
- expect(e.deploymentId).toBe(result1.id);
405
+ expect(e.operationId).toBe(result1.id);
407
406
  }
408
407
  for (const e of entries2) {
409
- expect(e.deploymentId).toBe(result2.id);
408
+ expect(e.operationId).toBe(result2.id);
410
409
  }
411
410
  });
412
411
 
@@ -421,14 +420,14 @@ describe("Decision Diary — retrieval dimensions", () => {
421
420
  const artifactA = seedArtifact(artifactStore, "app-a");
422
421
  const artifactB = seedArtifact(artifactStore, "app-b");
423
422
 
424
- await agent.triggerDeployment({
425
- artifactId: artifactA.id, artifactVersionId: "1.0.0",
426
- partitionId: partA.id, environmentId: envA.id, triggeredBy: "user",
427
- });
428
- await agent.triggerDeployment({
429
- artifactId: artifactB.id, artifactVersionId: "1.0.0",
430
- partitionId: partB.id, environmentId: envB.id, triggeredBy: "user",
431
- });
423
+ await agent.triggerOperation(
424
+ { type: "deploy", artifactId: artifactA.id, artifactVersionId: "1.0.0" },
425
+ { partitionId: partA.id, environmentId: envA.id, triggeredBy: "user" },
426
+ );
427
+ await agent.triggerOperation(
428
+ { type: "deploy", artifactId: artifactB.id, artifactVersionId: "1.0.0" },
429
+ { partitionId: partB.id, environmentId: envB.id, triggeredBy: "user" },
430
+ );
432
431
 
433
432
  const entriesA = diary.getByPartition(partA.id);
434
433
  const entriesB = diary.getByPartition(partB.id);
@@ -550,7 +549,7 @@ describe("PersistentDecisionDebrief — SQLite backing store", () => {
550
549
  it("persists entries across close and reopen", () => {
551
550
  const entry = diary.record({
552
551
  partitionId: "partition-1",
553
- deploymentId: "deploy-1",
552
+ operationId: "deploy-1",
554
553
  agent: "command",
555
554
  decisionType: "pipeline-plan",
556
555
  decision: "Planned deployment pipeline: resolve → execute → verify",
@@ -567,7 +566,7 @@ describe("PersistentDecisionDebrief — SQLite backing store", () => {
567
566
  expect(retrieved!.decision).toBe(entry.decision);
568
567
  expect(retrieved!.reasoning).toBe(entry.reasoning);
569
568
  expect(retrieved!.partitionId).toBe("partition-1");
570
- expect(retrieved!.deploymentId).toBe("deploy-1");
569
+ expect(retrieved!.operationId).toBe("deploy-1");
571
570
  expect(retrieved!.decisionType).toBe("pipeline-plan");
572
571
  expect(retrieved!.context).toEqual({ artifactId: "web-app", version: "1.0.0" });
573
572
  diary2.close();
@@ -576,7 +575,7 @@ describe("PersistentDecisionDebrief — SQLite backing store", () => {
576
575
  it("retrieval by deployment returns correct entries", () => {
577
576
  diary.record({
578
577
  partitionId: "t1",
579
- deploymentId: "d1",
578
+ operationId: "d1",
580
579
  agent: "command",
581
580
  decisionType: "pipeline-plan",
582
581
  decision: "Planned pipeline for d1",
@@ -584,7 +583,7 @@ describe("PersistentDecisionDebrief — SQLite backing store", () => {
584
583
  });
585
584
  diary.record({
586
585
  partitionId: "t1",
587
- deploymentId: "d2",
586
+ operationId: "d2",
588
587
  agent: "command",
589
588
  decisionType: "pipeline-plan",
590
589
  decision: "Planned pipeline for d2",
@@ -592,28 +591,28 @@ describe("PersistentDecisionDebrief — SQLite backing store", () => {
592
591
  });
593
592
  diary.record({
594
593
  partitionId: "t1",
595
- deploymentId: "d1",
594
+ operationId: "d1",
596
595
  agent: "command",
597
596
  decisionType: "deployment-completion",
598
597
  decision: "Deployment d1 completed",
599
598
  reasoning: "All steps passed.",
600
599
  });
601
600
 
602
- const d1Entries = diary.getByDeployment("d1");
601
+ const d1Entries = diary.getByOperation("d1");
603
602
  expect(d1Entries).toHaveLength(2);
604
603
  for (const e of d1Entries) {
605
- expect(e.deploymentId).toBe("d1");
604
+ expect(e.operationId).toBe("d1");
606
605
  }
607
606
 
608
- const d2Entries = diary.getByDeployment("d2");
607
+ const d2Entries = diary.getByOperation("d2");
609
608
  expect(d2Entries).toHaveLength(1);
610
- expect(d2Entries[0].deploymentId).toBe("d2");
609
+ expect(d2Entries[0].operationId).toBe("d2");
611
610
  });
612
611
 
613
612
  it("retrieval by partition returns correct entries", () => {
614
613
  diary.record({
615
614
  partitionId: "acme",
616
- deploymentId: "d1",
615
+ operationId: "d1",
617
616
  agent: "command",
618
617
  decisionType: "pipeline-plan",
619
618
  decision: "Acme deployment plan",
@@ -621,7 +620,7 @@ describe("PersistentDecisionDebrief — SQLite backing store", () => {
621
620
  });
622
621
  diary.record({
623
622
  partitionId: "beta",
624
- deploymentId: "d2",
623
+ operationId: "d2",
625
624
  agent: "command",
626
625
  decisionType: "pipeline-plan",
627
626
  decision: "Beta deployment plan",
@@ -640,7 +639,7 @@ describe("PersistentDecisionDebrief — SQLite backing store", () => {
640
639
  it("retrieval by decision type filters correctly", () => {
641
640
  diary.record({
642
641
  partitionId: "t1",
643
- deploymentId: "d1",
642
+ operationId: "d1",
644
643
  agent: "command",
645
644
  decisionType: "health-check",
646
645
  decision: "Health check passed",
@@ -648,7 +647,7 @@ describe("PersistentDecisionDebrief — SQLite backing store", () => {
648
647
  });
649
648
  diary.record({
650
649
  partitionId: "t1",
651
- deploymentId: "d1",
650
+ operationId: "d1",
652
651
  agent: "command",
653
652
  decisionType: "variable-conflict",
654
653
  decision: "LOG_LEVEL conflict resolved",
@@ -656,7 +655,7 @@ describe("PersistentDecisionDebrief — SQLite backing store", () => {
656
655
  });
657
656
  diary.record({
658
657
  partitionId: "t1",
659
- deploymentId: "d1",
658
+ operationId: "d1",
660
659
  agent: "command",
661
660
  decisionType: "health-check",
662
661
  decision: "Post-flight check passed",
@@ -678,7 +677,7 @@ describe("PersistentDecisionDebrief — SQLite backing store", () => {
678
677
  const before = new Date();
679
678
  diary.record({
680
679
  partitionId: "t1",
681
- deploymentId: "d1",
680
+ operationId: "d1",
682
681
  agent: "command",
683
682
  decisionType: "pipeline-plan",
684
683
  decision: "First entry",
@@ -686,7 +685,7 @@ describe("PersistentDecisionDebrief — SQLite backing store", () => {
686
685
  });
687
686
  diary.record({
688
687
  partitionId: "t1",
689
- deploymentId: "d1",
688
+ operationId: "d1",
690
689
  agent: "command",
691
690
  decisionType: "deployment-completion",
692
691
  decision: "Second entry",
@@ -709,7 +708,7 @@ describe("PersistentDecisionDebrief — SQLite backing store", () => {
709
708
  for (let i = 0; i < 5; i++) {
710
709
  diary.record({
711
710
  partitionId: "t1",
712
- deploymentId: `d${i}`,
711
+ operationId: `d${i}`,
713
712
  agent: "command",
714
713
  decisionType: "pipeline-plan",
715
714
  decision: `Entry ${i}`,
@@ -731,7 +730,7 @@ describe("PersistentDecisionDebrief — SQLite backing store", () => {
731
730
  it("context round-trips through JSON correctly", () => {
732
731
  const entry = diary.record({
733
732
  partitionId: "t1",
734
- deploymentId: "d1",
733
+ operationId: "d1",
735
734
  agent: "command",
736
735
  decisionType: "health-check",
737
736
  decision: "Health check with complex context",
@@ -800,14 +799,14 @@ describe("PersistentDecisionDebrief — integration with SynthAgent", () => {
800
799
  expect(result.status).toBe("succeeded");
801
800
 
802
801
  // Verify entries exist before close
803
- const entriesBefore = diary.getByDeployment(result.id);
802
+ const entriesBefore = diary.getByOperation(result.id);
804
803
  expect(entriesBefore.length).toBeGreaterThanOrEqual(5);
805
804
 
806
805
  diary.close();
807
806
 
808
807
  // Reopen and verify persistence
809
808
  const diary2 = new PersistentDecisionDebrief(dbPath);
810
- const entriesAfter = diary2.getByDeployment(result.id);
809
+ const entriesAfter = diary2.getByOperation(result.id);
811
810
  expect(entriesAfter).toHaveLength(entriesBefore.length);
812
811
 
813
812
  // Verify key decision types from the pipeline are present
@@ -832,18 +831,18 @@ describe("PersistentDecisionDebrief — integration with SynthAgent", () => {
832
831
  const artA = seedArtifact(artifactStore, "app-a");
833
832
  const artB = seedArtifact(artifactStore, "app-b");
834
833
 
835
- const result1 = await agent.triggerDeployment({
836
- artifactId: artA.id, artifactVersionId: "1.0.0",
837
- partitionId: partA.id, environmentId: envA.id, triggeredBy: "user",
838
- });
839
- const result2 = await agent.triggerDeployment({
840
- artifactId: artB.id, artifactVersionId: "1.0.0",
841
- partitionId: partB.id, environmentId: envB.id, triggeredBy: "user",
842
- });
834
+ const result1 = await agent.triggerOperation(
835
+ { type: "deploy", artifactId: artA.id, artifactVersionId: "1.0.0" },
836
+ { partitionId: partA.id, environmentId: envA.id, triggeredBy: "user" },
837
+ );
838
+ const result2 = await agent.triggerOperation(
839
+ { type: "deploy", artifactId: artB.id, artifactVersionId: "1.0.0" },
840
+ { partitionId: partB.id, environmentId: envB.id, triggeredBy: "user" },
841
+ );
843
842
 
844
843
  // By deployment
845
- const acmeEntries = diary.getByDeployment(result1.id);
846
- const betaEntries = diary.getByDeployment(result2.id);
844
+ const acmeEntries = diary.getByOperation(result1.id);
845
+ const betaEntries = diary.getByOperation(result2.id);
847
846
  expect(acmeEntries.length).toBeGreaterThanOrEqual(5);
848
847
  expect(betaEntries.length).toBeGreaterThanOrEqual(5);
849
848
 
@@ -879,7 +878,7 @@ describe("Decision Diary — human-readable format", () => {
879
878
  id: "abc-123-def-456",
880
879
  timestamp: new Date("2026-02-23T14:30:05.000Z"),
881
880
  partitionId: "partition-acme",
882
- deploymentId: "deploy-789",
881
+ operationId: "deploy-789",
883
882
  agent: "command",
884
883
  decisionType: "health-check",
885
884
  decision: "Pre-flight health check passed",
@@ -905,7 +904,7 @@ describe("Decision Diary — human-readable format", () => {
905
904
  id: "sys-001",
906
905
  timestamp: new Date("2026-02-23T12:00:00.000Z"),
907
906
  partitionId: null,
908
- deploymentId: null,
907
+ operationId: null,
909
908
  agent: "command",
910
909
  decisionType: "system",
911
910
  decision: "Command initialized with demo data",
@@ -925,7 +924,7 @@ describe("Decision Diary — human-readable format", () => {
925
924
  id: "e1",
926
925
  timestamp: new Date("2026-02-23T14:00:00.000Z"),
927
926
  partitionId: "t1",
928
- deploymentId: "d1",
927
+ operationId: "d1",
929
928
  agent: "command",
930
929
  decisionType: "pipeline-plan",
931
930
  decision: "Entry one",
@@ -936,7 +935,7 @@ describe("Decision Diary — human-readable format", () => {
936
935
  id: "e2",
937
936
  timestamp: new Date("2026-02-23T14:01:00.000Z"),
938
937
  partitionId: "t1",
939
- deploymentId: "d1",
938
+ operationId: "d1",
940
939
  agent: "command",
941
940
  decisionType: "deployment-completion",
942
941
  decision: "Entry two",
@@ -141,14 +141,10 @@ async function testDeploy(
141
141
  forceInsertEnvironment(stores.environments, e);
142
142
  forceInsertArtifact(stores.artifacts, DEFAULT_ARTIFACT_ID, "web-app");
143
143
 
144
- return agent.triggerDeployment({
145
- artifactId: DEFAULT_ARTIFACT_ID,
146
- artifactVersionId: version,
147
- environmentId: e.id,
148
- partitionId: effectivePartition.id,
149
- triggeredBy: "user",
150
- variables: oldTrigger.variables,
151
- });
144
+ return agent.triggerOperation(
145
+ { type: "deploy", artifactId: DEFAULT_ARTIFACT_ID, artifactVersionId: version },
146
+ { environmentId: e.id, partitionId: effectivePartition.id, triggeredBy: "user", variables: oldTrigger.variables },
147
+ );
152
148
  }
153
149
 
154
150
  // ---------------------------------------------------------------------------
@@ -190,7 +186,7 @@ describe("Simulated Postmortem — failed deployment read experience", () => {
190
186
 
191
187
  expect(deployment.status).toBe("failed");
192
188
 
193
- const entries = diary.getByDeployment(deployment.id);
189
+ const entries = diary.getByOperation(deployment.id);
194
190
  const postmortem = generatePostmortem(entries, deployment);
195
191
 
196
192
  // 1. Reviewer can identify WHAT was being deployed
@@ -241,7 +237,7 @@ describe("Simulated Postmortem — failed deployment read experience", () => {
241
237
 
242
238
  const deployment = await testDeploy(agent, stores, {});
243
239
 
244
- const entries = diary.getByDeployment(deployment.id);
240
+ const entries = diary.getByOperation(deployment.id);
245
241
  const postmortem = generatePostmortem(entries, deployment);
246
242
 
247
243
  // The postmortem should explain that DNS failures don't benefit from retry
@@ -284,7 +280,7 @@ describe("Simulated Postmortem — failed deployment read experience", () => {
284
280
 
285
281
  expect(deployment.status).toBe("failed");
286
282
 
287
- const entries = diary.getByDeployment(deployment.id);
283
+ const entries = diary.getByOperation(deployment.id);
288
284
  const postmortem = generatePostmortem(entries, deployment);
289
285
 
290
286
  // Should explain the configuration block
@@ -313,7 +309,7 @@ describe("Simulated Postmortem — failed deployment read experience", () => {
313
309
 
314
310
  expect(deployment.status).toBe("succeeded");
315
311
 
316
- const entries = diary.getByDeployment(deployment.id);
312
+ const entries = diary.getByOperation(deployment.id);
317
313
  const postmortem = generatePostmortem(entries, deployment);
318
314
 
319
315
  expect(postmortem.summary).toContain("SUCCEEDED");
@@ -333,7 +329,7 @@ describe("Simulated Postmortem — failed deployment read experience", () => {
333
329
 
334
330
  expect(deployment.status).toBe("succeeded");
335
331
 
336
- const entries = diary.getByDeployment(deployment.id);
332
+ const entries = diary.getByOperation(deployment.id);
337
333
  const postmortem = generatePostmortem(entries, deployment);
338
334
 
339
335
  // Timeline should show the retry decision chain
@@ -368,7 +364,7 @@ describe("Simulated Postmortem — failed deployment read experience", () => {
368
364
  makeEnvironment({ name: "staging" }),
369
365
  );
370
366
 
371
- const entries = diary.getByDeployment(deployment.id);
367
+ const entries = diary.getByOperation(deployment.id);
372
368
  const postmortem = generatePostmortem(entries, deployment);
373
369
 
374
370
  const text = postmortem.formatted;
@@ -724,7 +720,7 @@ describe("Postmortem report — structural guarantees", () => {
724
720
 
725
721
  const deployment = await testDeploy(agent, stores, {});
726
722
 
727
- const entries = diary.getByDeployment(deployment.id);
723
+ const entries = diary.getByOperation(deployment.id);
728
724
  const postmortem = generatePostmortem(entries, deployment);
729
725
 
730
726
  for (let i = 1; i < postmortem.timeline.length; i++) {
@@ -747,7 +743,7 @@ describe("Postmortem report — structural guarantees", () => {
747
743
 
748
744
  const deployment = await testDeploy(agent, stores, { variables: { LOG_LEVEL: "debug" } }, partition, env);
749
745
 
750
- const entries = diary.getByDeployment(deployment.id);
746
+ const entries = diary.getByOperation(deployment.id);
751
747
  const postmortem = generatePostmortem(entries, deployment);
752
748
 
753
749
  // LOG_LEVEL has three-way conflict (env → partition → trigger), total vars = 3
@@ -760,7 +756,7 @@ describe("Postmortem report — structural guarantees", () => {
760
756
 
761
757
  const deployment = await testDeploy(agent, stores, {});
762
758
 
763
- const entries = diary.getByDeployment(deployment.id);
759
+ const entries = diary.getByOperation(deployment.id);
764
760
  const postmortem = generatePostmortem(entries, deployment);
765
761
 
766
762
  expect(postmortem.failureAnalysis).toBeNull();
@@ -771,7 +767,7 @@ describe("Postmortem report — structural guarantees", () => {
771
767
 
772
768
  const deployment = await testDeploy(agent, stores, {});
773
769
 
774
- const entries = diary.getByDeployment(deployment.id);
770
+ const entries = diary.getByOperation(deployment.id);
775
771
  const postmortem = generatePostmortem(entries, deployment);
776
772
 
777
773
  expect(postmortem.failureAnalysis).not.toBeNull();
@@ -207,7 +207,7 @@ describe("get-deployment-status", () => {
207
207
  });
208
208
 
209
209
  expect(result.isError).toBe(true);
210
- expect(result.content[0].text).toContain("Deployment not found");
210
+ expect(result.content[0].text).toContain("Operation not found");
211
211
  expect(result.content[0].text).toContain("does-not-exist");
212
212
  });
213
213
  });