@cat-factory/orchestration 0.191.0 → 0.192.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 (44) hide show
  1. package/dist/container/dependencies.d.ts +14 -1
  2. package/dist/container/dependencies.d.ts.map +1 -1
  3. package/dist/container/platform-modules.d.ts.map +1 -1
  4. package/dist/container/platform-modules.js +1 -0
  5. package/dist/container/platform-modules.js.map +1 -1
  6. package/dist/index.d.ts +4 -3
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +4 -3
  9. package/dist/index.js.map +1 -1
  10. package/dist/modules/execution/ExecutionServiceDependencies.d.ts +8 -1
  11. package/dist/modules/execution/ExecutionServiceDependencies.d.ts.map +1 -1
  12. package/dist/modules/execution/GateStepController.d.ts +15 -0
  13. package/dist/modules/execution/GateStepController.d.ts.map +1 -1
  14. package/dist/modules/execution/GateStepController.js +19 -0
  15. package/dist/modules/execution/GateStepController.js.map +1 -1
  16. package/dist/modules/execution/PollRunningController.d.ts +8 -0
  17. package/dist/modules/execution/PollRunningController.d.ts.map +1 -1
  18. package/dist/modules/execution/PollRunningController.js +14 -0
  19. package/dist/modules/execution/PollRunningController.js.map +1 -1
  20. package/dist/modules/execution/RunDispatcher.d.ts +6 -20
  21. package/dist/modules/execution/RunDispatcher.d.ts.map +1 -1
  22. package/dist/modules/execution/RunDispatcher.js +29 -6
  23. package/dist/modules/execution/RunDispatcher.js.map +1 -1
  24. package/dist/modules/observability/GateOutcomeRecorder.d.ts +33 -0
  25. package/dist/modules/observability/GateOutcomeRecorder.d.ts.map +1 -0
  26. package/dist/modules/observability/GateOutcomeRecorder.js +45 -0
  27. package/dist/modules/observability/GateOutcomeRecorder.js.map +1 -0
  28. package/dist/modules/observability/PlatformObservabilityService.d.ts +32 -1
  29. package/dist/modules/observability/PlatformObservabilityService.d.ts.map +1 -1
  30. package/dist/modules/observability/PlatformObservabilityService.js +71 -10
  31. package/dist/modules/observability/PlatformObservabilityService.js.map +1 -1
  32. package/dist/modules/observability/platform-health.logic.d.ts +35 -4
  33. package/dist/modules/observability/platform-health.logic.d.ts.map +1 -1
  34. package/dist/modules/observability/platform-health.logic.js +45 -0
  35. package/dist/modules/observability/platform-health.logic.js.map +1 -1
  36. package/dist/modules/observability/platform-observability.logic.d.ts +41 -4
  37. package/dist/modules/observability/platform-observability.logic.d.ts.map +1 -1
  38. package/dist/modules/observability/platform-observability.logic.js +88 -6
  39. package/dist/modules/observability/platform-observability.logic.js.map +1 -1
  40. package/dist/modules/observability/retentionPass.d.ts +22 -0
  41. package/dist/modules/observability/retentionPass.d.ts.map +1 -1
  42. package/dist/modules/observability/retentionPass.js +12 -0
  43. package/dist/modules/observability/retentionPass.js.map +1 -1
  44. package/package.json +11 -11
@@ -1,8 +1,9 @@
1
- import type { PlatformAlert, PlatformAlertReason, PlatformObservability, PlatformObservabilityWindow } from '@cat-factory/contracts';
1
+ import type { PlatformAlert, PlatformAlertReason, PlatformAlertSettings, PlatformAlertWindow, PlatformObservability } from '@cat-factory/contracts';
2
2
  /**
3
3
  * The operator-configured ceilings a deployment's aggregate health is checked against. Each
4
- * maps to one {@link PlatformAlertReason}. Deployment-level config (env-driven defaults today;
5
- * a settings surface is a later slice), NOT per-workspace.
4
+ * maps to one {@link PlatformAlertReason}. Deployment-level config: the env vars set the
5
+ * defaults at boot and an account's stored settings may override any of them per field
6
+ * (see {@link resolveAccountAlertConfig}), NOT per-workspace.
6
7
  */
7
8
  export interface PlatformAlertThresholds {
8
9
  /**
@@ -45,6 +46,36 @@ export interface PlatformAlertThresholds {
45
46
  }
46
47
  /** Conservative defaults: quiet unless the deployment is genuinely unhealthy. */
47
48
  export declare const DEFAULT_PLATFORM_ALERT_THRESHOLDS: PlatformAlertThresholds;
49
+ /**
50
+ * The alert configuration one account is actually evaluated under: the deployment's
51
+ * env-derived defaults with that account's stored settings layered on top.
52
+ */
53
+ export interface ResolvedAccountAlertConfig {
54
+ /** Whether this account is alerted on at all. */
55
+ enabled: boolean;
56
+ window: PlatformAlertWindow;
57
+ thresholds: PlatformAlertThresholds;
58
+ }
59
+ /**
60
+ * Layer an account's stored alert settings over the deployment defaults, field by field.
61
+ *
62
+ * ABSENT INHERITS; it never means zero. That is the whole contract of this function and the
63
+ * reason it exists rather than a spread: a zero is a live, meaningful value in three of these
64
+ * thresholds (`minStalledPriorRuns: 0` says "page even on an idle window"), so a merge that
65
+ * treated a missing key and a stored `0` alike would turn "I did not set this" into the most
66
+ * aggressive setting available, on every account that ever saved any unrelated field.
67
+ *
68
+ * `enabled` is deliberately a ONE-WAY switch: an account may mute itself, but cannot turn
69
+ * alerting on where the deployment never started the sweep: there would be no timer to
70
+ * honour it, and a stored `true` that does nothing is worse than an absent one.
71
+ */
72
+ export declare function resolveAccountAlertConfig(deployment: {
73
+ enabled: boolean;
74
+ window: PlatformAlertWindow;
75
+ thresholds: PlatformAlertThresholds;
76
+ }, stored: PlatformAlertSettings | undefined): ResolvedAccountAlertConfig;
77
+ /** Whether a fired reason set has failing runs behind it worth linking to. */
78
+ export declare function alertsHaveRunEvidence(reasons: readonly PlatformAlertReason[]): boolean;
48
79
  /**
49
80
  * Evaluate one account's windowed projection against the thresholds, returning every fired
50
81
  * alert (empty when healthy). Each alert carries its observed value + the threshold it crossed
@@ -78,7 +109,7 @@ export declare function platformAlertReasons(alerts: PlatformAlert[]): PlatformA
78
109
  * `payload.platformAlerts` as the dedup identity and the seam for a future localized rendering
79
110
  * (the `usePipelineErrorToast` mapping pattern), not yet wired in the SPA.
80
111
  */
81
- export declare function platformHealthCardContent(reasons: PlatformAlertReason[], window: PlatformObservabilityWindow): {
112
+ export declare function platformHealthCardContent(reasons: PlatformAlertReason[], window: PlatformAlertWindow): {
82
113
  title: string;
83
114
  body: string;
84
115
  };
@@ -1 +1 @@
1
- {"version":3,"file":"platform-health.logic.d.ts","sourceRoot":"","sources":["../../../src/modules/observability/platform-health.logic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,mBAAmB,EACnB,qBAAqB,EACrB,2BAA2B,EAC5B,MAAM,wBAAwB,CAAA;AAc/B;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAA;IACf,2EAA2E;IAC3E,cAAc,EAAE,MAAM,CAAA;IACtB,oFAAoF;IACpF,gBAAgB,EAAE,MAAM,CAAA;IACxB,wFAAwF;IACxF,UAAU,EAAE,MAAM,CAAA;IAClB;;;;;OAKG;IACH,cAAc,EAAE,MAAM,CAAA;IACtB;;;;;OAKG;IACH,mBAAmB,EAAE,MAAM,CAAA;IAC3B;;;;OAIG;IACH,mBAAmB,EAAE,MAAM,CAAA;IAC3B;;;;OAIG;IACH,gBAAgB,EAAE,MAAM,CAAA;CACzB;AAED,iFAAiF;AACjF,eAAO,MAAM,iCAAiC,EAAE,uBAa/C,CAAA;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,qBAAqB,EAC/B,UAAU,EAAE,uBAAuB;AACnC;;;;;GAKG;AACH,aAAa,CAAC,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GACrD,aAAa,EAAE,CAyEjB;AA6CD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,mBAAmB,EAAE,CAEnF;AAkBD;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,mBAAmB,EAAE,EAC9B,MAAM,EAAE,2BAA2B,GAClC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAUjC"}
1
+ {"version":3,"file":"platform-health.logic.d.ts","sourceRoot":"","sources":["../../../src/modules/observability/platform-health.logic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,EACnB,qBAAqB,EACtB,MAAM,wBAAwB,CAAA;AAc/B;;;;;GAKG;AACH,MAAM,WAAW,uBAAuB;IACtC;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAA;IACf,2EAA2E;IAC3E,cAAc,EAAE,MAAM,CAAA;IACtB,oFAAoF;IACpF,gBAAgB,EAAE,MAAM,CAAA;IACxB,wFAAwF;IACxF,UAAU,EAAE,MAAM,CAAA;IAClB;;;;;OAKG;IACH,cAAc,EAAE,MAAM,CAAA;IACtB;;;;;OAKG;IACH,mBAAmB,EAAE,MAAM,CAAA;IAC3B;;;;OAIG;IACH,mBAAmB,EAAE,MAAM,CAAA;IAC3B;;;;OAIG;IACH,gBAAgB,EAAE,MAAM,CAAA;CACzB;AAED,iFAAiF;AACjF,eAAO,MAAM,iCAAiC,EAAE,uBAa/C,CAAA;AAED;;;GAGG;AACH,MAAM,WAAW,0BAA0B;IACzC,iDAAiD;IACjD,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,mBAAmB,CAAA;IAC3B,UAAU,EAAE,uBAAuB,CAAA;CACpC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,yBAAyB,CACvC,UAAU,EAAE;IACV,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,mBAAmB,CAAA;IAC3B,UAAU,EAAE,uBAAuB,CAAA;CACpC,EACD,MAAM,EAAE,qBAAqB,GAAG,SAAS,GACxC,0BAA0B,CAgB5B;AAcD,8EAA8E;AAC9E,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,SAAS,mBAAmB,EAAE,GAAG,OAAO,CAEtF;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,qBAAqB,EAC/B,UAAU,EAAE,uBAAuB;AACnC;;;;;GAKG;AACH,aAAa,CAAC,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GACrD,aAAa,EAAE,CAyEjB;AA6CD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,mBAAmB,EAAE,CAEnF;AAkBD;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,mBAAmB,EAAE,EAC9B,MAAM,EAAE,mBAAmB,GAC1B;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAUjC"}
@@ -13,6 +13,51 @@ export const DEFAULT_PLATFORM_ALERT_THRESHOLDS = {
13
13
  maxFailureKindShare: 0.8,
14
14
  maxSweepFailures: 3,
15
15
  };
16
+ /**
17
+ * Layer an account's stored alert settings over the deployment defaults, field by field.
18
+ *
19
+ * ABSENT INHERITS; it never means zero. That is the whole contract of this function and the
20
+ * reason it exists rather than a spread: a zero is a live, meaningful value in three of these
21
+ * thresholds (`minStalledPriorRuns: 0` says "page even on an idle window"), so a merge that
22
+ * treated a missing key and a stored `0` alike would turn "I did not set this" into the most
23
+ * aggressive setting available, on every account that ever saved any unrelated field.
24
+ *
25
+ * `enabled` is deliberately a ONE-WAY switch: an account may mute itself, but cannot turn
26
+ * alerting on where the deployment never started the sweep: there would be no timer to
27
+ * honour it, and a stored `true` that does nothing is worse than an absent one.
28
+ */
29
+ export function resolveAccountAlertConfig(deployment, stored) {
30
+ const t = stored?.thresholds;
31
+ return {
32
+ enabled: deployment.enabled && stored?.enabled !== false,
33
+ window: stored?.window ?? deployment.window,
34
+ thresholds: {
35
+ minRuns: t?.minRuns ?? deployment.thresholds.minRuns,
36
+ maxFailureRate: t?.maxFailureRate ?? deployment.thresholds.maxFailureRate,
37
+ maxP99DurationMs: t?.maxP99DurationMs ?? deployment.thresholds.maxP99DurationMs,
38
+ maxBacklog: t?.maxBacklog ?? deployment.thresholds.maxBacklog,
39
+ stalledBuckets: t?.stalledBuckets ?? deployment.thresholds.stalledBuckets,
40
+ minStalledPriorRuns: t?.minStalledPriorRuns ?? deployment.thresholds.minStalledPriorRuns,
41
+ maxFailureKindShare: t?.maxFailureKindShare ?? deployment.thresholds.maxFailureKindShare,
42
+ maxSweepFailures: t?.maxSweepFailures ?? deployment.thresholds.maxSweepFailures,
43
+ },
44
+ };
45
+ }
46
+ /**
47
+ * The alert reasons whose evidence is a set of FAILED RUNS, so a card firing any of them can
48
+ * deep-link to the runs it is aggregating. The other conditions are about depth, latency or
49
+ * the absence of work, and have no failing run to point at. A link that resolved to nothing
50
+ * would read as "there are no failures", which is the opposite of what a backlog or stall
51
+ * alert is saying.
52
+ */
53
+ const RUN_EVIDENCED_REASONS = new Set([
54
+ 'failure_rate_high',
55
+ 'failure_kind_dominant',
56
+ ]);
57
+ /** Whether a fired reason set has failing runs behind it worth linking to. */
58
+ export function alertsHaveRunEvidence(reasons) {
59
+ return reasons.some((r) => RUN_EVIDENCED_REASONS.has(r));
60
+ }
16
61
  /**
17
62
  * Evaluate one account's windowed projection against the thresholds, returning every fired
18
63
  * alert (empty when healthy). Each alert carries its observed value + the threshold it crossed
@@ -1 +1 @@
1
- {"version":3,"file":"platform-health.logic.js","sourceRoot":"","sources":["../../../src/modules/observability/platform-health.logic.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"platform-health.logic.js","sourceRoot":"","sources":["../../../src/modules/observability/platform-health.logic.ts"],"names":[],"mappings":"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"}
@@ -1,16 +1,53 @@
1
- import type { PlatformObservabilityWindow, PlatformOutcomeTotals, PlatformTrendPoint } from '@cat-factory/contracts';
2
- import type { PlatformRunOutcome, PlatformRunTrendPoint } from '@cat-factory/kernel';
3
- /** Per-window sizing: how far back to aggregate and how wide each trend bucket is. */
1
+ import type { PlatformFailureSlice, PlatformGateStat, PlatformObservabilityWindow, PlatformOutcomeTotals, PlatformTrendPoint, PlatformTrendSource } from '@cat-factory/contracts';
2
+ import type { PlatformDailyRunCount, PlatformGateOutcomeCount, PlatformRunTrendPoint } from '@cat-factory/kernel';
3
+ /** A day, in ms: the daily rollup's bucket width and the long windows' trend resolution. */
4
+ export declare const DAY_MS: number;
5
+ /**
6
+ * Per-window sizing: how far back to aggregate, how wide each trend bucket is, and which
7
+ * store answers it.
8
+ *
9
+ * The short windows scan `agent_runs` live. The long ones read the daily rollup: a `90d`
10
+ * window at any finer resolution would scan a quarter of every run the deployment has ever
11
+ * made on each dashboard load, which is the cost the rollup exists to remove, and it would
12
+ * do it while producing a series nobody can read at that density anyway.
13
+ */
4
14
  export declare const PLATFORM_WINDOWS: Record<PlatformObservabilityWindow, {
5
15
  windowMs: number;
6
16
  bucketMs: number;
17
+ source: PlatformTrendSource;
7
18
  }>;
8
19
  /** Reduce the `(kind, status)` outcome rows into per-status totals + the success rate. */
9
- export declare function summarizeOutcomes(rows: PlatformRunOutcome[]): PlatformOutcomeTotals;
20
+ export declare function summarizeOutcomes(rows: readonly {
21
+ status: string;
22
+ count: number;
23
+ }[]): PlatformOutcomeTotals;
10
24
  /**
11
25
  * Fold the sparse `(bucketStart, status)` trend rows into a contiguous, zero-filled,
12
26
  * oldest-first series spanning `[since, now]` at `bucketMs` resolution — so the sparkline
13
27
  * shows empty buckets as zeros rather than collapsing gaps.
14
28
  */
15
29
  export declare function buildTrend(points: PlatformRunTrendPoint[], since: number, now: number, bucketMs: number): PlatformTrendPoint[];
30
+ /**
31
+ * The daily-rollup rows as trend input. The rollup splits a `failed` day into one row per
32
+ * failure kind, so the same day appears several times; `buildTrend` sums them, which is why
33
+ * this is a projection rather than a regrouping.
34
+ */
35
+ export declare function dailyTrendRows(rows: readonly PlatformDailyRunCount[]): PlatformRunTrendPoint[];
36
+ /**
37
+ * The failure taxonomy folded out of the daily-rollup rows, most frequent first: the
38
+ * long-window counterpart of `failureKindBreakdown`. Only `failed` rows carry a kind; a row
39
+ * that somehow lacks one is counted as `unknown` rather than dropped, so the slice totals
40
+ * still add up to the window's failure count.
41
+ */
42
+ export declare function dailyFailureSlices(rows: readonly PlatformDailyRunCount[]): PlatformFailureSlice[];
43
+ /**
44
+ * Fold the `(gateKind, helperKind, outcome)` buckets into one statistic per gate kind, busiest
45
+ * first. The port groups by outcome because that is one `GROUP BY`; the dashboard reads a gate
46
+ * kind as a single row, so passed/exhausted become columns here rather than rows.
47
+ *
48
+ * `helperKind` is taken from whichever bucket names one: a gate's helper is a property of the
49
+ * gate definition, so the buckets agree, but a gate that passed cleanly every time in the
50
+ * window legitimately recorded no helper at all and must not blank out the label.
51
+ */
52
+ export declare function summarizeGateOutcomes(rows: readonly PlatformGateOutcomeCount[]): PlatformGateStat[];
16
53
  //# sourceMappingURL=platform-observability.logic.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"platform-observability.logic.d.ts","sourceRoot":"","sources":["../../../src/modules/observability/platform-observability.logic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,2BAA2B,EAC3B,qBAAqB,EACrB,kBAAkB,EACnB,MAAM,wBAAwB,CAAA;AAC/B,OAAO,KAAK,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAMpF,sFAAsF;AACtF,eAAO,MAAM,gBAAgB,EAAE,MAAM,CACnC,2BAA2B,EAC3B;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAKvC,CAAA;AAED,0FAA0F;AAC1F,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,kBAAkB,EAAE,GAAG,qBAAqB,CAoCnF;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,qBAAqB,EAAE,EAC/B,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,GACf,kBAAkB,EAAE,CAkBtB"}
1
+ {"version":3,"file":"platform-observability.logic.d.ts","sourceRoot":"","sources":["../../../src/modules/observability/platform-observability.logic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,oBAAoB,EACpB,gBAAgB,EAChB,2BAA2B,EAC3B,qBAAqB,EACrB,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,wBAAwB,CAAA;AAC/B,OAAO,KAAK,EACV,qBAAqB,EACrB,wBAAwB,EACxB,qBAAqB,EACtB,MAAM,qBAAqB,CAAA;AAM5B,4FAA4F;AAC5F,eAAO,MAAM,MAAM,QAAmB,CAAA;AAEtC;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAAM,CACnC,2BAA2B,EAC3B;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,mBAAmB,CAAA;CAAE,CAOpE,CAAA;AAED,0FAA0F;AAC1F,wBAAgB,iBAAiB,CAI/B,IAAI,EAAE,SAAS;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,GACjD,qBAAqB,CAoCvB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,qBAAqB,EAAE,EAC/B,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,GACf,kBAAkB,EAAE,CAkBtB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,qBAAqB,EAAE,GAAG,qBAAqB,EAAE,CAE9F;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,SAAS,qBAAqB,EAAE,GAAG,oBAAoB,EAAE,CAUjG;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,SAAS,wBAAwB,EAAE,GACxC,gBAAgB,EAAE,CA+BpB"}
@@ -1,14 +1,30 @@
1
1
  // Pure reshaping behind the platform-observability read: the port returns raw grouped
2
2
  // rows; these functions fold them into the wire projection. Kept pure (no clock, no I/O)
3
- // so they're unit-tested directly and reused by the future alert sweep.
4
- /** Per-window sizing: how far back to aggregate and how wide each trend bucket is. */
3
+ // so they're unit-tested directly and reused by the alert sweep.
4
+ /** A day, in ms: the daily rollup's bucket width and the long windows' trend resolution. */
5
+ export const DAY_MS = 24 * 60 * 60_000;
6
+ /**
7
+ * Per-window sizing: how far back to aggregate, how wide each trend bucket is, and which
8
+ * store answers it.
9
+ *
10
+ * The short windows scan `agent_runs` live. The long ones read the daily rollup: a `90d`
11
+ * window at any finer resolution would scan a quarter of every run the deployment has ever
12
+ * made on each dashboard load, which is the cost the rollup exists to remove, and it would
13
+ * do it while producing a series nobody can read at that density anyway.
14
+ */
5
15
  export const PLATFORM_WINDOWS = {
6
- '1h': { windowMs: 60 * 60_000, bucketMs: 5 * 60_000 }, // 12 × 5min buckets
7
- '24h': { windowMs: 24 * 60 * 60_000, bucketMs: 60 * 60_000 }, // 24 × 1h buckets
8
- '7d': { windowMs: 7 * 24 * 60 * 60_000, bucketMs: 6 * 60 * 60_000 }, // 28 × 6h buckets
16
+ '1h': { windowMs: 60 * 60_000, bucketMs: 5 * 60_000, source: 'runs' }, // 12 × 5min buckets
17
+ '24h': { windowMs: 24 * 60 * 60_000, bucketMs: 60 * 60_000, source: 'runs' }, // 24 × 1h
18
+ '7d': { windowMs: 7 * DAY_MS, bucketMs: 6 * 60 * 60_000, source: 'runs' }, // 28 × 6h
19
+ '30d': { windowMs: 30 * DAY_MS, bucketMs: DAY_MS, source: 'daily-rollup' },
20
+ '90d': { windowMs: 90 * DAY_MS, bucketMs: DAY_MS, source: 'daily-rollup' },
9
21
  };
10
22
  /** Reduce the `(kind, status)` outcome rows into per-status totals + the success rate. */
11
- export function summarizeOutcomes(rows) {
23
+ export function summarizeOutcomes(
24
+ // Only `status` + `count` are read, so this also folds the daily-rollup rows, which carry
25
+ // no run kind. Typed structurally rather than against `PlatformRunOutcome` so the two
26
+ // sources share one reduction instead of drifting into two that must agree.
27
+ rows) {
12
28
  const totals = {
13
29
  total: 0,
14
30
  done: 0,
@@ -72,4 +88,70 @@ export function buildTrend(points, since, now, bucketMs) {
72
88
  }
73
89
  return [...byStart.values()].sort((a, b) => a.start - b.start);
74
90
  }
91
+ /**
92
+ * The daily-rollup rows as trend input. The rollup splits a `failed` day into one row per
93
+ * failure kind, so the same day appears several times; `buildTrend` sums them, which is why
94
+ * this is a projection rather than a regrouping.
95
+ */
96
+ export function dailyTrendRows(rows) {
97
+ return rows.map((r) => ({ bucketStart: r.dayStart, status: r.status, count: r.count }));
98
+ }
99
+ /**
100
+ * The failure taxonomy folded out of the daily-rollup rows, most frequent first: the
101
+ * long-window counterpart of `failureKindBreakdown`. Only `failed` rows carry a kind; a row
102
+ * that somehow lacks one is counted as `unknown` rather than dropped, so the slice totals
103
+ * still add up to the window's failure count.
104
+ */
105
+ export function dailyFailureSlices(rows) {
106
+ const byKind = new Map();
107
+ for (const r of rows) {
108
+ if (r.status !== 'failed')
109
+ continue;
110
+ const kind = r.failureKind ?? 'unknown';
111
+ byKind.set(kind, (byKind.get(kind) ?? 0) + r.count);
112
+ }
113
+ return [...byKind.entries()]
114
+ .map(([kind, count]) => ({ kind, count }))
115
+ .sort((a, b) => b.count - a.count || a.kind.localeCompare(b.kind));
116
+ }
117
+ /**
118
+ * Fold the `(gateKind, helperKind, outcome)` buckets into one statistic per gate kind, busiest
119
+ * first. The port groups by outcome because that is one `GROUP BY`; the dashboard reads a gate
120
+ * kind as a single row, so passed/exhausted become columns here rather than rows.
121
+ *
122
+ * `helperKind` is taken from whichever bucket names one: a gate's helper is a property of the
123
+ * gate definition, so the buckets agree, but a gate that passed cleanly every time in the
124
+ * window legitimately recorded no helper at all and must not blank out the label.
125
+ */
126
+ export function summarizeGateOutcomes(rows) {
127
+ const byKind = new Map();
128
+ for (const r of rows) {
129
+ let stat = byKind.get(r.gateKind);
130
+ if (!stat) {
131
+ stat = {
132
+ gateKind: r.gateKind,
133
+ helperKind: null,
134
+ gates: 0,
135
+ passed: 0,
136
+ exhausted: 0,
137
+ cleanPasses: 0,
138
+ attempts: 0,
139
+ helperFailures: 0,
140
+ };
141
+ byKind.set(r.gateKind, stat);
142
+ }
143
+ stat.helperKind ??= r.helperKind;
144
+ stat.gates += r.gates;
145
+ stat.attempts += r.attempts;
146
+ stat.helperFailures += r.helperFailures;
147
+ if (r.outcome === 'passed') {
148
+ stat.passed += r.gates;
149
+ stat.cleanPasses += r.cleanGates;
150
+ }
151
+ else {
152
+ stat.exhausted += r.gates;
153
+ }
154
+ }
155
+ return [...byKind.values()].sort((a, b) => b.gates - a.gates || a.gateKind.localeCompare(b.gateKind));
156
+ }
75
157
  //# sourceMappingURL=platform-observability.logic.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"platform-observability.logic.js","sourceRoot":"","sources":["../../../src/modules/observability/platform-observability.logic.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"platform-observability.logic.js","sourceRoot":"","sources":["../../../src/modules/observability/platform-observability.logic.ts"],"names":[],"mappings":"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"}
@@ -12,6 +12,17 @@ export interface RetentionPass {
12
12
  * tokens, subscription activations), where there is no window to disable.
13
13
  */
14
14
  expire(table: string, del: () => Promise<number>): Promise<number>;
15
+ /**
16
+ * The same isolation for a table this pass WRITES rather than prunes: today the daily run
17
+ * rollup, which is materialised on the same schedule that bounds its neighbours.
18
+ *
19
+ * It shares the isolation for the reason the prunes do: a failing rollup must not abort the
20
+ * prunes that follow it, and it must be NAMED when it fails rather than reported as "0
21
+ * rows", which is also what a fully caught-up rollup returns. Kept a distinct verb from
22
+ * {@link prune} so a reader of the sweep can see at a glance which tables it is bounding and
23
+ * which it is filling.
24
+ */
25
+ materialize(table: string, write: () => Promise<number>): Promise<number>;
15
26
  /**
16
27
  * The tables whose prune threw this pass, in the order they were attempted. EMPTY on a
17
28
  * clean pass — a caller logs it only when non-empty, so a healthy deployment stays quiet.
@@ -23,4 +34,15 @@ export interface RetentionPass {
23
34
  * list is per-pass state), then read `failed` after the last table.
24
35
  */
25
36
  export declare function createRetentionPass(logger?: Logger): RetentionPass;
37
+ /**
38
+ * How far back each rollup pass recomputes the daily run buckets.
39
+ *
40
+ * Not just "today": the sweep that owns it runs daily on the Worker and hourly on Node, so a
41
+ * missed pass (a deploy, an isolate that never fired, a restart) would otherwise leave a day
42
+ * permanently half-counted, and a half-counted day is indistinguishable from a quiet one once
43
+ * it is written. Recomputing a short trailing window makes every pass self-healing, at the
44
+ * cost of re-aggregating a few days of runs, which is one indexed GROUP BY, not a scan of
45
+ * history. Shared by both facades so the two cannot drift on how much they heal.
46
+ */
47
+ export declare const RUN_DAY_ROLLUP_LOOKBACK_MS: number;
26
48
  //# sourceMappingURL=retentionPass.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"retentionPass.d.ts","sourceRoot":"","sources":["../../../src/modules/observability/retentionPass.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAiB,MAAM,qBAAqB,CAAA;AAiBhE,0FAA0F;AAC1F,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,KAAK,CACH,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GACvC,OAAO,CAAC,MAAM,CAAC,CAAA;IAClB;;;OAGG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IAClE;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAC1B;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,aAAa,CAwBlE"}
1
+ {"version":3,"file":"retentionPass.d.ts","sourceRoot":"","sources":["../../../src/modules/observability/retentionPass.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAiB,MAAM,qBAAqB,CAAA;AAiBhE,0FAA0F;AAC1F,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,KAAK,CACH,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GACvC,OAAO,CAAC,MAAM,CAAC,CAAA;IAClB;;;OAGG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IAClE;;;;;;;;;OASG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IACzE;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAC1B;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,aAAa,CAyBlE;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,0BAA0B,QAAuB,CAAA"}
@@ -25,7 +25,19 @@ export function createRetentionPass(logger) {
25
25
  return {
26
26
  prune: (table, windowMs, now, del) => windowMs <= 0 ? Promise.resolve(0) : isolate(table, () => del(now - windowMs)),
27
27
  expire: (table, del) => isolate(table, del),
28
+ materialize: (table, write) => isolate(table, write),
28
29
  failed,
29
30
  };
30
31
  }
32
+ /**
33
+ * How far back each rollup pass recomputes the daily run buckets.
34
+ *
35
+ * Not just "today": the sweep that owns it runs daily on the Worker and hourly on Node, so a
36
+ * missed pass (a deploy, an isolate that never fired, a restart) would otherwise leave a day
37
+ * permanently half-counted, and a half-counted day is indistinguishable from a quiet one once
38
+ * it is written. Recomputing a short trailing window makes every pass self-healing, at the
39
+ * cost of re-aggregating a few days of runs, which is one indexed GROUP BY, not a scan of
40
+ * history. Shared by both facades so the two cannot drift on how much they heal.
41
+ */
42
+ export const RUN_DAY_ROLLUP_LOOKBACK_MS = 3 * 24 * 60 * 60_000;
31
43
  //# sourceMappingURL=retentionPass.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"retentionPass.js","sourceRoot":"","sources":["../../../src/modules/observability/retentionPass.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,aAAa,EAAE,MAAM,qBAAqB,CAAA;AA0ChE;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAe;IACjD,MAAM,MAAM,GAAa,EAAE,CAAA;IAC3B,MAAM,OAAO,GAAG,KAAK,EAAE,KAAa,EAAE,GAA0B,EAAmB,EAAE;QACnF,IAAI,CAAC;YACH,OAAO,MAAM,GAAG,EAAE,CAAA;QACpB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YAClB,yFAAyF;YACzF,uFAAuF;YACvF,6DAA6D;YAC7D,MAAM,EAAE,IAAI,CAAC,0DAA0D,EAAE;gBACvE,KAAK,EAAE,WAAW;gBAClB,KAAK;gBACL,GAAG,aAAa,CAAC,KAAK,CAAC;aACxB,CAAC,CAAA;YACF,OAAO,CAAC,CAAA;QACV,CAAC;IACH,CAAC,CAAA;IACD,OAAO;QACL,KAAK,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,CACnC,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,GAAG,QAAQ,CAAC,CAAC;QAChF,MAAM,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;QAC3C,MAAM;KACP,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"retentionPass.js","sourceRoot":"","sources":["../../../src/modules/observability/retentionPass.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAqDhE;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAe;IACjD,MAAM,MAAM,GAAa,EAAE,CAAA;IAC3B,MAAM,OAAO,GAAG,KAAK,EAAE,KAAa,EAAE,GAA0B,EAAmB,EAAE;QACnF,IAAI,CAAC;YACH,OAAO,MAAM,GAAG,EAAE,CAAA;QACpB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YAClB,yFAAyF;YACzF,uFAAuF;YACvF,6DAA6D;YAC7D,MAAM,EAAE,IAAI,CAAC,0DAA0D,EAAE;gBACvE,KAAK,EAAE,WAAW;gBAClB,KAAK;gBACL,GAAG,aAAa,CAAC,KAAK,CAAC;aACxB,CAAC,CAAA;YACF,OAAO,CAAC,CAAA;QACV,CAAC;IACH,CAAC,CAAA;IACD,OAAO;QACL,KAAK,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,CACnC,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,GAAG,QAAQ,CAAC,CAAC;QAChF,MAAM,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;QAC3C,WAAW,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;QACpD,MAAM;KACP,CAAA;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,MAAM,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cat-factory/orchestration",
3
- "version": "0.191.0",
3
+ "version": "0.192.0",
4
4
  "description": "Delivery-workflow engine for the Agent Architecture Board (execution, bootstrap, pipelines, board, boardScan, requirements, and composition root).",
5
5
  "repository": {
6
6
  "type": "git",
@@ -25,20 +25,20 @@
25
25
  },
26
26
  "dependencies": {
27
27
  "ai": "^7.0.47",
28
- "@cat-factory/agents": "0.106.7",
29
- "@cat-factory/caching": "0.13.8",
30
- "@cat-factory/contracts": "0.220.0",
31
- "@cat-factory/integrations": "0.121.0",
32
- "@cat-factory/kernel": "0.222.0",
33
- "@cat-factory/prompt-fragments": "0.15.45",
34
- "@cat-factory/sandbox": "0.11.39",
35
- "@cat-factory/spend": "0.13.10",
36
- "@cat-factory/workspaces": "0.21.32"
28
+ "@cat-factory/agents": "0.106.8",
29
+ "@cat-factory/caching": "0.13.9",
30
+ "@cat-factory/contracts": "0.221.0",
31
+ "@cat-factory/integrations": "0.121.1",
32
+ "@cat-factory/kernel": "0.223.0",
33
+ "@cat-factory/prompt-fragments": "0.15.46",
34
+ "@cat-factory/sandbox": "0.11.40",
35
+ "@cat-factory/spend": "0.13.11",
36
+ "@cat-factory/workspaces": "0.21.33"
37
37
  },
38
38
  "devDependencies": {
39
39
  "typescript": "7.0.2",
40
40
  "vitest": "^4.1.10",
41
- "@cat-factory/sandbox-fixtures": "0.7.253"
41
+ "@cat-factory/sandbox-fixtures": "0.7.254"
42
42
  },
43
43
  "scripts": {
44
44
  "build": "tsc -b tsconfig.build.json",