@mcoda/codali 0.1.90 → 0.1.94

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 (105) hide show
  1. package/dist/cli/DatasetCommand.d.ts +38 -0
  2. package/dist/cli/DatasetCommand.d.ts.map +1 -0
  3. package/dist/cli/DatasetCommand.js +959 -0
  4. package/dist/cli/EvalCommand.d.ts +3 -0
  5. package/dist/cli/EvalCommand.d.ts.map +1 -1
  6. package/dist/cli/EvalCommand.js +55 -1
  7. package/dist/cli/ImprovementCommand.d.ts +97 -0
  8. package/dist/cli/ImprovementCommand.d.ts.map +1 -0
  9. package/dist/cli/ImprovementCommand.js +1879 -0
  10. package/dist/cli.d.ts.map +1 -1
  11. package/dist/cli.js +15 -0
  12. package/dist/dataset-cli.d.ts +3 -0
  13. package/dist/dataset-cli.d.ts.map +1 -0
  14. package/dist/dataset-cli.js +30 -0
  15. package/dist/eval/CodaliGatewayLiveHarness.d.ts +90 -1
  16. package/dist/eval/CodaliGatewayLiveHarness.d.ts.map +1 -1
  17. package/dist/eval/CodaliGatewayLiveHarness.js +443 -9
  18. package/dist/eval/GatewayDatasetEval.d.ts +70 -0
  19. package/dist/eval/GatewayDatasetEval.d.ts.map +1 -0
  20. package/dist/eval/GatewayDatasetEval.js +477 -0
  21. package/dist/eval/GatewayEvalSuite.d.ts +52 -0
  22. package/dist/eval/GatewayEvalSuite.d.ts.map +1 -1
  23. package/dist/eval/GatewayEvalSuite.js +135 -1
  24. package/dist/gateway/CodaliGateway.d.ts +4 -0
  25. package/dist/gateway/CodaliGateway.d.ts.map +1 -1
  26. package/dist/gateway/CodaliGateway.js +37 -1
  27. package/dist/gateway/CodaliGatewaySchemas.d.ts.map +1 -1
  28. package/dist/gateway/CodaliGatewaySchemas.js +0 -4
  29. package/dist/gateway/CodaliGatewayStore.d.ts.map +1 -1
  30. package/dist/gateway/CodaliGatewayStore.js +1 -0
  31. package/dist/gateway/GatewayPlanner.d.ts.map +1 -1
  32. package/dist/gateway/GatewayPlanner.js +355 -41
  33. package/dist/gateway/GatewayStateMachine.d.ts +1 -0
  34. package/dist/gateway/GatewayStateMachine.d.ts.map +1 -1
  35. package/dist/gateway/GatewayStateMachine.js +221 -5
  36. package/dist/improvement/CandidateReleaseBuilder.d.ts +201 -0
  37. package/dist/improvement/CandidateReleaseBuilder.d.ts.map +1 -0
  38. package/dist/improvement/CandidateReleaseBuilder.js +1175 -0
  39. package/dist/improvement/DatasetEligibilityGate.d.ts +75 -0
  40. package/dist/improvement/DatasetEligibilityGate.d.ts.map +1 -0
  41. package/dist/improvement/DatasetEligibilityGate.js +497 -0
  42. package/dist/improvement/DatasetExportManifestReader.d.ts +88 -0
  43. package/dist/improvement/DatasetExportManifestReader.d.ts.map +1 -0
  44. package/dist/improvement/DatasetExportManifestReader.js +333 -0
  45. package/dist/improvement/DocdexRetrievalCandidateBuilder.d.ts +192 -0
  46. package/dist/improvement/DocdexRetrievalCandidateBuilder.d.ts.map +1 -0
  47. package/dist/improvement/DocdexRetrievalCandidateBuilder.js +625 -0
  48. package/dist/improvement/EvalReplayCandidateBuilder.d.ts +173 -0
  49. package/dist/improvement/EvalReplayCandidateBuilder.d.ts.map +1 -0
  50. package/dist/improvement/EvalReplayCandidateBuilder.js +363 -0
  51. package/dist/improvement/FineTuneJobPlanner.d.ts +281 -0
  52. package/dist/improvement/FineTuneJobPlanner.d.ts.map +1 -0
  53. package/dist/improvement/FineTuneJobPlanner.js +823 -0
  54. package/dist/improvement/ImprovementEvalRunner.d.ts +50 -0
  55. package/dist/improvement/ImprovementEvalRunner.d.ts.map +1 -0
  56. package/dist/improvement/ImprovementEvalRunner.js +648 -0
  57. package/dist/improvement/ImprovementPolicy.d.ts +272 -0
  58. package/dist/improvement/ImprovementPolicy.d.ts.map +1 -0
  59. package/dist/improvement/ImprovementPolicy.js +1450 -0
  60. package/dist/improvement/ModelRouterCandidateBuilder.d.ts +186 -0
  61. package/dist/improvement/ModelRouterCandidateBuilder.d.ts.map +1 -0
  62. package/dist/improvement/ModelRouterCandidateBuilder.js +880 -0
  63. package/dist/improvement/OperatorInspector.d.ts +182 -0
  64. package/dist/improvement/OperatorInspector.d.ts.map +1 -0
  65. package/dist/improvement/OperatorInspector.js +604 -0
  66. package/dist/improvement/ProductionGovernance.d.ts +91 -0
  67. package/dist/improvement/ProductionGovernance.d.ts.map +1 -0
  68. package/dist/improvement/ProductionGovernance.js +329 -0
  69. package/dist/improvement/PromptSchemaToolMetadataCandidateBuilder.d.ts +152 -0
  70. package/dist/improvement/PromptSchemaToolMetadataCandidateBuilder.d.ts.map +1 -0
  71. package/dist/improvement/PromptSchemaToolMetadataCandidateBuilder.js +480 -0
  72. package/dist/improvement/PublishOrchestrator.d.ts +113 -0
  73. package/dist/improvement/PublishOrchestrator.d.ts.map +1 -0
  74. package/dist/improvement/PublishOrchestrator.js +590 -0
  75. package/dist/improvement/ReleaseOutcomeReporter.d.ts +133 -0
  76. package/dist/improvement/ReleaseOutcomeReporter.d.ts.map +1 -0
  77. package/dist/improvement/ReleaseOutcomeReporter.js +501 -0
  78. package/dist/improvement/StorageServiceImprovementClient.d.ts +71 -0
  79. package/dist/improvement/StorageServiceImprovementClient.d.ts.map +1 -0
  80. package/dist/improvement/StorageServiceImprovementClient.js +245 -0
  81. package/dist/index.d.ts +43 -0
  82. package/dist/index.d.ts.map +1 -1
  83. package/dist/index.js +21 -0
  84. package/dist/runtime/CodaliRuntime.d.ts +0 -2
  85. package/dist/runtime/CodaliRuntime.d.ts.map +1 -1
  86. package/dist/runtime/CodaliRuntime.js +0 -5
  87. package/dist/storage/CodaliDatasetPrivacyEngine.d.ts +138 -0
  88. package/dist/storage/CodaliDatasetPrivacyEngine.d.ts.map +1 -0
  89. package/dist/storage/CodaliDatasetPrivacyEngine.js +417 -0
  90. package/dist/storage/CodaliFeedbackReviewIngestion.d.ts +50 -0
  91. package/dist/storage/CodaliFeedbackReviewIngestion.d.ts.map +1 -0
  92. package/dist/storage/CodaliFeedbackReviewIngestion.js +141 -0
  93. package/dist/storage/CodaliStorageContracts.d.ts +337 -0
  94. package/dist/storage/CodaliStorageContracts.d.ts.map +1 -0
  95. package/dist/storage/CodaliStorageContracts.js +1555 -0
  96. package/dist/storage/DatasetExportJob.d.ts +51 -0
  97. package/dist/storage/DatasetExportJob.d.ts.map +1 -0
  98. package/dist/storage/DatasetExportJob.js +358 -0
  99. package/dist/storage/DatasetReviewQueue.d.ts +98 -0
  100. package/dist/storage/DatasetReviewQueue.d.ts.map +1 -0
  101. package/dist/storage/DatasetReviewQueue.js +426 -0
  102. package/dist/storage/GatewayDatasetStore.d.ts +233 -0
  103. package/dist/storage/GatewayDatasetStore.d.ts.map +1 -0
  104. package/dist/storage/GatewayDatasetStore.js +2070 -0
  105. package/package.json +5 -4
@@ -0,0 +1,133 @@
1
+ import { type CodaliImprovementOutcome, type CodaliImprovementScope } from "./ImprovementPolicy.js";
2
+ import { type StorageServiceImprovementClient, type StorageServiceImprovementWriteResult } from "./StorageServiceImprovementClient.js";
3
+ import type { GatewayDatasetStorageScope } from "../storage/GatewayDatasetStore.js";
4
+ export declare const CODALI_RELEASE_OUTCOME_REPORTER_SCHEMA_VERSION: "codali.improvement.release_outcome_report.v1";
5
+ export declare const CODALI_RELEASE_RUNTIME_PACKAGE_KINDS: readonly ["prompt_package", "router_policy", "retrieval_policy", "schema", "fine_tune_adapter"];
6
+ export type CodaliReleaseRuntimePackageKind = (typeof CODALI_RELEASE_RUNTIME_PACKAGE_KINDS)[number];
7
+ export declare const CODALI_RELEASE_ROLLBACK_TRIGGER_CODES: readonly ["schema_failures", "accepted_answer_rate_drop", "verifier_contradictions", "tool_failures", "latency_increase", "cost_increase", "privacy_security_warnings"];
8
+ export type CodaliReleaseRollbackTriggerCode = (typeof CODALI_RELEASE_ROLLBACK_TRIGGER_CODES)[number];
9
+ export type CodaliReleaseMonitorStatus = "healthy" | "watch" | "rollback_required" | "rolled_back";
10
+ export interface CodaliReleaseMonitorWindow {
11
+ startedAt: string;
12
+ endedAt: string;
13
+ durationMinutes: number;
14
+ }
15
+ export interface CodaliReleaseMonitorThresholds {
16
+ maxSchemaFailures: number;
17
+ minAcceptedAnswerRate: number;
18
+ maxAcceptedAnswerRateDrop: number;
19
+ maxVerifierContradictions: number;
20
+ maxToolFailures: number;
21
+ maxP95LatencyIncreaseRatio: number;
22
+ maxCostIncreaseRatio: number;
23
+ maxPrivacySecurityWarnings: number;
24
+ }
25
+ export interface CodaliReleaseObservedMetrics {
26
+ eligibleRequestCount: number;
27
+ shadowRequestCount: number;
28
+ schemaFailures: number;
29
+ acceptedAnswerRate?: number;
30
+ baselineAcceptedAnswerRate?: number;
31
+ verifierContradictions: number;
32
+ toolFailures: number;
33
+ p95LatencyMs?: number;
34
+ baselineP95LatencyMs?: number;
35
+ costUsd?: number;
36
+ baselineCostUsd?: number;
37
+ privacySecurityWarnings: number;
38
+ }
39
+ export interface CodaliReleaseRuntimePackageFlag {
40
+ packageKind: CodaliReleaseRuntimePackageKind;
41
+ version: string;
42
+ enabled: boolean;
43
+ disableOnRollback: boolean;
44
+ rollbackDisabled: boolean;
45
+ reason?: string;
46
+ }
47
+ export interface CodaliReleaseShadowTrafficReport {
48
+ enabled: boolean;
49
+ nonBlocking: true;
50
+ eligibleRequestCount: number;
51
+ shadowRequestCount: number;
52
+ coverageRate: number;
53
+ status: "not_eligible" | "skipped" | "partial" | "completed";
54
+ }
55
+ export interface CodaliReleaseRollbackTrigger {
56
+ code: CodaliReleaseRollbackTriggerCode;
57
+ triggered: boolean;
58
+ observed: number;
59
+ threshold: number;
60
+ message: string;
61
+ }
62
+ export interface CodaliReleaseRolloutEvent {
63
+ eventId: string;
64
+ releaseId: string;
65
+ eventType: "monitor_started" | "runtime_flags_applied" | "shadow_traffic_started" | "shadow_traffic_completed";
66
+ createdAt: string;
67
+ metadata: Record<string, unknown>;
68
+ }
69
+ export interface CodaliReleaseRollbackEvent {
70
+ eventId: string;
71
+ releaseId: string;
72
+ eventType: "rollback_triggered" | "runtime_package_disabled" | "rollback_applied";
73
+ createdAt: string;
74
+ triggerCodes: CodaliReleaseRollbackTriggerCode[];
75
+ runtimePackageKind?: CodaliReleaseRuntimePackageKind;
76
+ runtimePackageVersion?: string;
77
+ unpublishNpm: false;
78
+ metadata: Record<string, unknown>;
79
+ }
80
+ export interface CodaliReleaseImprovementCycleFeedback {
81
+ status: "recorded" | "queued";
82
+ releaseId: string;
83
+ nextCycleReasons: string[];
84
+ recommendedArtifactTypes: string[];
85
+ source: "release_monitor";
86
+ }
87
+ export interface CodaliReleaseOutcomeReport {
88
+ schemaVersion: typeof CODALI_RELEASE_OUTCOME_REPORTER_SCHEMA_VERSION;
89
+ releaseId: string;
90
+ status: CodaliReleaseMonitorStatus;
91
+ generatedAt: string;
92
+ monitorWindow: CodaliReleaseMonitorWindow;
93
+ thresholds: CodaliReleaseMonitorThresholds;
94
+ metrics: CodaliReleaseObservedMetrics;
95
+ runtimeFlags: CodaliReleaseRuntimePackageFlag[];
96
+ shadowTraffic: CodaliReleaseShadowTrafficReport;
97
+ rollbackTriggers: CodaliReleaseRollbackTrigger[];
98
+ rolloutEvents: CodaliReleaseRolloutEvent[];
99
+ rollbackEvents: CodaliReleaseRollbackEvent[];
100
+ outcome: CodaliImprovementOutcome;
101
+ improvementCycleFeedback: CodaliReleaseImprovementCycleFeedback;
102
+ storageWrites: Array<{
103
+ accepted: boolean;
104
+ status: number;
105
+ scope: GatewayDatasetStorageScope;
106
+ }>;
107
+ }
108
+ export interface RunCodaliReleaseOutcomeReporterInput {
109
+ releaseId: string;
110
+ scope?: CodaliImprovementScope;
111
+ monitorWindowMinutes?: number;
112
+ monitorWindowStartedAt?: string;
113
+ monitorWindowEndedAt?: string;
114
+ thresholds?: Partial<CodaliReleaseMonitorThresholds>;
115
+ metrics?: Partial<CodaliReleaseObservedMetrics>;
116
+ runtimeVersions?: Partial<Record<CodaliReleaseRuntimePackageKind, string>>;
117
+ disabledRuntimePackages?: readonly CodaliReleaseRuntimePackageKind[];
118
+ rollbackApplied?: boolean;
119
+ published?: boolean;
120
+ tagged?: boolean;
121
+ trainingUsed?: boolean;
122
+ exportUsed?: boolean;
123
+ now?: () => Date;
124
+ }
125
+ export interface WriteCodaliReleaseOutcomeReportToStorageInput {
126
+ report: CodaliReleaseOutcomeReport;
127
+ scope: GatewayDatasetStorageScope;
128
+ client: StorageServiceImprovementClient;
129
+ }
130
+ export declare const DEFAULT_CODALI_RELEASE_MONITOR_THRESHOLDS: CodaliReleaseMonitorThresholds;
131
+ export declare const runCodaliReleaseOutcomeReporter: (input: RunCodaliReleaseOutcomeReporterInput) => CodaliReleaseOutcomeReport;
132
+ export declare const writeCodaliReleaseOutcomeReportToStorageService: (input: WriteCodaliReleaseOutcomeReportToStorageInput) => Promise<Array<StorageServiceImprovementWriteResult<unknown>>>;
133
+ //# sourceMappingURL=ReleaseOutcomeReporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ReleaseOutcomeReporter.d.ts","sourceRoot":"","sources":["../../src/improvement/ReleaseOutcomeReporter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,501 @@
1
+ import { createHash } from "node:crypto";
2
+ import { CODALI_IMPROVEMENT_CONTRACT_SCHEMA_VERSION, } from "./ImprovementPolicy.js";
3
+ export const CODALI_RELEASE_OUTCOME_REPORTER_SCHEMA_VERSION = "codali.improvement.release_outcome_report.v1";
4
+ export const CODALI_RELEASE_RUNTIME_PACKAGE_KINDS = [
5
+ "prompt_package",
6
+ "router_policy",
7
+ "retrieval_policy",
8
+ "schema",
9
+ "fine_tune_adapter",
10
+ ];
11
+ export const CODALI_RELEASE_ROLLBACK_TRIGGER_CODES = [
12
+ "schema_failures",
13
+ "accepted_answer_rate_drop",
14
+ "verifier_contradictions",
15
+ "tool_failures",
16
+ "latency_increase",
17
+ "cost_increase",
18
+ "privacy_security_warnings",
19
+ ];
20
+ const DEFAULT_SCOPE = {
21
+ tenantHash: "local_tenant",
22
+ productId: "local_product",
23
+ };
24
+ export const DEFAULT_CODALI_RELEASE_MONITOR_THRESHOLDS = {
25
+ maxSchemaFailures: 0,
26
+ minAcceptedAnswerRate: 0.85,
27
+ maxAcceptedAnswerRateDrop: 0.05,
28
+ maxVerifierContradictions: 0,
29
+ maxToolFailures: 0,
30
+ maxP95LatencyIncreaseRatio: 0.2,
31
+ maxCostIncreaseRatio: 0.15,
32
+ maxPrivacySecurityWarnings: 0,
33
+ };
34
+ const DEFAULT_MONITOR_WINDOW_MINUTES = 60;
35
+ const stableJson = (value) => {
36
+ if (Array.isArray(value))
37
+ return `[${value.map((item) => stableJson(item)).join(",")}]`;
38
+ if (value && typeof value === "object") {
39
+ return `{${Object.entries(value)
40
+ .filter(([, item]) => item !== undefined)
41
+ .sort(([left], [right]) => left.localeCompare(right))
42
+ .map(([key, item]) => `${JSON.stringify(key)}:${stableJson(item)}`)
43
+ .join(",")}}`;
44
+ }
45
+ return JSON.stringify(value);
46
+ };
47
+ const stableId = (prefix, value) => `${prefix}-${createHash("sha256").update(stableJson(value)).digest("hex").slice(0, 16)}`;
48
+ const finiteNumber = (value, fallback) => typeof value === "number" && Number.isFinite(value) ? value : fallback;
49
+ const nonNegativeInteger = (value, fallback = 0) => {
50
+ const numberValue = finiteNumber(value, fallback);
51
+ return Number.isInteger(numberValue) && numberValue >= 0 ? numberValue : fallback;
52
+ };
53
+ const optionalNumber = (value) => typeof value === "number" && Number.isFinite(value) ? value : undefined;
54
+ const ratioIncrease = (current, baseline) => {
55
+ if (current === undefined || baseline === undefined || baseline <= 0)
56
+ return 0;
57
+ return Math.max(0, (current - baseline) / baseline);
58
+ };
59
+ const acceptedAnswerDrop = (current, baseline) => {
60
+ if (current === undefined || baseline === undefined)
61
+ return 0;
62
+ return Math.max(0, baseline - current);
63
+ };
64
+ const monitorWindowFor = (input) => {
65
+ const now = input.now ?? (() => new Date());
66
+ const endedAt = input.monitorWindowEndedAt ?? now().toISOString();
67
+ const durationMinutes = input.monitorWindowMinutes ?? DEFAULT_MONITOR_WINDOW_MINUTES;
68
+ const startedAt = input.monitorWindowStartedAt ??
69
+ new Date(Date.parse(endedAt) - durationMinutes * 60000).toISOString();
70
+ return {
71
+ startedAt,
72
+ endedAt,
73
+ durationMinutes,
74
+ };
75
+ };
76
+ const metricsFor = (metrics) => {
77
+ const acceptedAnswerRate = optionalNumber(metrics?.acceptedAnswerRate);
78
+ const baselineAcceptedAnswerRate = optionalNumber(metrics?.baselineAcceptedAnswerRate);
79
+ const p95LatencyMs = optionalNumber(metrics?.p95LatencyMs);
80
+ const baselineP95LatencyMs = optionalNumber(metrics?.baselineP95LatencyMs);
81
+ const costUsd = optionalNumber(metrics?.costUsd);
82
+ const baselineCostUsd = optionalNumber(metrics?.baselineCostUsd);
83
+ return {
84
+ eligibleRequestCount: nonNegativeInteger(metrics?.eligibleRequestCount),
85
+ shadowRequestCount: nonNegativeInteger(metrics?.shadowRequestCount),
86
+ schemaFailures: nonNegativeInteger(metrics?.schemaFailures),
87
+ ...(acceptedAnswerRate !== undefined ? { acceptedAnswerRate } : {}),
88
+ ...(baselineAcceptedAnswerRate !== undefined ? { baselineAcceptedAnswerRate } : {}),
89
+ verifierContradictions: nonNegativeInteger(metrics?.verifierContradictions),
90
+ toolFailures: nonNegativeInteger(metrics?.toolFailures),
91
+ ...(p95LatencyMs !== undefined ? { p95LatencyMs } : {}),
92
+ ...(baselineP95LatencyMs !== undefined ? { baselineP95LatencyMs } : {}),
93
+ ...(costUsd !== undefined ? { costUsd } : {}),
94
+ ...(baselineCostUsd !== undefined ? { baselineCostUsd } : {}),
95
+ privacySecurityWarnings: nonNegativeInteger(metrics?.privacySecurityWarnings),
96
+ };
97
+ };
98
+ const scopeFor = (scope) => {
99
+ const effectiveScope = scope ?? DEFAULT_SCOPE;
100
+ return {
101
+ tenantHash: effectiveScope.tenantHash,
102
+ productId: effectiveScope.productId,
103
+ ...(effectiveScope.deploymentId ? { deploymentId: effectiveScope.deploymentId } : {}),
104
+ };
105
+ };
106
+ const triggerFor = (input) => ({
107
+ code: input.code,
108
+ observed: input.observed,
109
+ threshold: input.threshold,
110
+ triggered: input.triggered,
111
+ message: input.message,
112
+ });
113
+ const rollbackTriggersFor = (metrics, thresholds) => {
114
+ const acceptedDrop = acceptedAnswerDrop(metrics.acceptedAnswerRate, metrics.baselineAcceptedAnswerRate);
115
+ const acceptedRate = metrics.acceptedAnswerRate ?? 1;
116
+ const latencyIncrease = ratioIncrease(metrics.p95LatencyMs, metrics.baselineP95LatencyMs);
117
+ const costIncrease = ratioIncrease(metrics.costUsd, metrics.baselineCostUsd);
118
+ return [
119
+ triggerFor({
120
+ code: "schema_failures",
121
+ observed: metrics.schemaFailures,
122
+ threshold: thresholds.maxSchemaFailures,
123
+ triggered: metrics.schemaFailures > thresholds.maxSchemaFailures,
124
+ message: "Schema failures exceeded the release monitor threshold.",
125
+ }),
126
+ triggerFor({
127
+ code: "accepted_answer_rate_drop",
128
+ observed: Math.max(acceptedDrop, thresholds.minAcceptedAnswerRate - acceptedRate),
129
+ threshold: Math.max(thresholds.maxAcceptedAnswerRateDrop, Math.max(0, thresholds.minAcceptedAnswerRate - acceptedRate)),
130
+ triggered: acceptedRate < thresholds.minAcceptedAnswerRate ||
131
+ acceptedDrop > thresholds.maxAcceptedAnswerRateDrop,
132
+ message: "Accepted-answer rate dropped below release expectations.",
133
+ }),
134
+ triggerFor({
135
+ code: "verifier_contradictions",
136
+ observed: metrics.verifierContradictions,
137
+ threshold: thresholds.maxVerifierContradictions,
138
+ triggered: metrics.verifierContradictions > thresholds.maxVerifierContradictions,
139
+ message: "Verifier contradictions exceeded the release monitor threshold.",
140
+ }),
141
+ triggerFor({
142
+ code: "tool_failures",
143
+ observed: metrics.toolFailures,
144
+ threshold: thresholds.maxToolFailures,
145
+ triggered: metrics.toolFailures > thresholds.maxToolFailures,
146
+ message: "Tool failures exceeded the release monitor threshold.",
147
+ }),
148
+ triggerFor({
149
+ code: "latency_increase",
150
+ observed: latencyIncrease,
151
+ threshold: thresholds.maxP95LatencyIncreaseRatio,
152
+ triggered: latencyIncrease > thresholds.maxP95LatencyIncreaseRatio,
153
+ message: "p95 latency increased beyond the release monitor threshold.",
154
+ }),
155
+ triggerFor({
156
+ code: "cost_increase",
157
+ observed: costIncrease,
158
+ threshold: thresholds.maxCostIncreaseRatio,
159
+ triggered: costIncrease > thresholds.maxCostIncreaseRatio,
160
+ message: "Cost increased beyond the release monitor threshold.",
161
+ }),
162
+ triggerFor({
163
+ code: "privacy_security_warnings",
164
+ observed: metrics.privacySecurityWarnings,
165
+ threshold: thresholds.maxPrivacySecurityWarnings,
166
+ triggered: metrics.privacySecurityWarnings > thresholds.maxPrivacySecurityWarnings,
167
+ message: "Privacy or security warnings exceeded the release monitor threshold.",
168
+ }),
169
+ ];
170
+ };
171
+ const runtimeFlagsFor = (input) => {
172
+ const disabled = new Set(input.disabledRuntimePackages ?? []);
173
+ return CODALI_RELEASE_RUNTIME_PACKAGE_KINDS.map((packageKind) => {
174
+ const rollbackDisabled = input.rollbackRequired || disabled.has(packageKind);
175
+ return {
176
+ packageKind,
177
+ version: input.runtimeVersions?.[packageKind] ?? "baseline",
178
+ enabled: !rollbackDisabled,
179
+ disableOnRollback: true,
180
+ rollbackDisabled,
181
+ ...(rollbackDisabled
182
+ ? { reason: "release_monitor_rollback_runtime_package_disable" }
183
+ : {}),
184
+ };
185
+ });
186
+ };
187
+ const shadowTrafficFor = (metrics) => {
188
+ const coverageRate = metrics.eligibleRequestCount > 0
189
+ ? metrics.shadowRequestCount / metrics.eligibleRequestCount
190
+ : 0;
191
+ const status = metrics.eligibleRequestCount === 0
192
+ ? "not_eligible"
193
+ : metrics.shadowRequestCount === 0
194
+ ? "skipped"
195
+ : metrics.shadowRequestCount >= metrics.eligibleRequestCount
196
+ ? "completed"
197
+ : "partial";
198
+ return {
199
+ enabled: metrics.eligibleRequestCount > 0,
200
+ nonBlocking: true,
201
+ eligibleRequestCount: metrics.eligibleRequestCount,
202
+ shadowRequestCount: metrics.shadowRequestCount,
203
+ coverageRate,
204
+ status,
205
+ };
206
+ };
207
+ const rolloutEventsFor = (input) => {
208
+ const events = [
209
+ {
210
+ eventId: stableId("rollout-event", {
211
+ releaseId: input.releaseId,
212
+ eventType: "monitor_started",
213
+ createdAt: input.createdAt,
214
+ }),
215
+ releaseId: input.releaseId,
216
+ eventType: "monitor_started",
217
+ createdAt: input.createdAt,
218
+ metadata: { schemaVersion: CODALI_RELEASE_OUTCOME_REPORTER_SCHEMA_VERSION },
219
+ },
220
+ {
221
+ eventId: stableId("rollout-event", {
222
+ releaseId: input.releaseId,
223
+ eventType: "runtime_flags_applied",
224
+ runtimeFlags: input.runtimeFlags,
225
+ }),
226
+ releaseId: input.releaseId,
227
+ eventType: "runtime_flags_applied",
228
+ createdAt: input.createdAt,
229
+ metadata: { runtimeFlags: input.runtimeFlags },
230
+ },
231
+ ];
232
+ if (input.shadowTraffic.enabled) {
233
+ events.push({
234
+ eventId: stableId("rollout-event", {
235
+ releaseId: input.releaseId,
236
+ eventType: "shadow_traffic_started",
237
+ eligibleRequestCount: input.shadowTraffic.eligibleRequestCount,
238
+ }),
239
+ releaseId: input.releaseId,
240
+ eventType: "shadow_traffic_started",
241
+ createdAt: input.createdAt,
242
+ metadata: { shadowTraffic: input.shadowTraffic },
243
+ });
244
+ events.push({
245
+ eventId: stableId("rollout-event", {
246
+ releaseId: input.releaseId,
247
+ eventType: "shadow_traffic_completed",
248
+ shadowRequestCount: input.shadowTraffic.shadowRequestCount,
249
+ }),
250
+ releaseId: input.releaseId,
251
+ eventType: "shadow_traffic_completed",
252
+ createdAt: input.createdAt,
253
+ metadata: { shadowTraffic: input.shadowTraffic },
254
+ });
255
+ }
256
+ return events;
257
+ };
258
+ const rollbackEventsFor = (input) => {
259
+ const triggerCodes = input.triggers
260
+ .filter((trigger) => trigger.triggered)
261
+ .map((trigger) => trigger.code);
262
+ if (triggerCodes.length === 0)
263
+ return [];
264
+ const events = [
265
+ {
266
+ eventId: stableId("rollback-event", {
267
+ releaseId: input.releaseId,
268
+ eventType: "rollback_triggered",
269
+ triggerCodes,
270
+ }),
271
+ releaseId: input.releaseId,
272
+ eventType: "rollback_triggered",
273
+ createdAt: input.createdAt,
274
+ triggerCodes,
275
+ unpublishNpm: false,
276
+ metadata: { triggers: input.triggers.filter((trigger) => trigger.triggered) },
277
+ },
278
+ ];
279
+ for (const flag of input.runtimeFlags.filter((item) => item.rollbackDisabled)) {
280
+ events.push({
281
+ eventId: stableId("rollback-event", {
282
+ releaseId: input.releaseId,
283
+ eventType: "runtime_package_disabled",
284
+ packageKind: flag.packageKind,
285
+ version: flag.version,
286
+ }),
287
+ releaseId: input.releaseId,
288
+ eventType: "runtime_package_disabled",
289
+ createdAt: input.createdAt,
290
+ triggerCodes,
291
+ runtimePackageKind: flag.packageKind,
292
+ runtimePackageVersion: flag.version,
293
+ unpublishNpm: false,
294
+ metadata: {
295
+ enabled: false,
296
+ reason: flag.reason,
297
+ npmPackageUnpublished: false,
298
+ },
299
+ });
300
+ }
301
+ if (input.rollbackApplied) {
302
+ events.push({
303
+ eventId: stableId("rollback-event", {
304
+ releaseId: input.releaseId,
305
+ eventType: "rollback_applied",
306
+ triggerCodes,
307
+ }),
308
+ releaseId: input.releaseId,
309
+ eventType: "rollback_applied",
310
+ createdAt: input.createdAt,
311
+ triggerCodes,
312
+ unpublishNpm: false,
313
+ metadata: {
314
+ rollbackApplied: true,
315
+ npmPackageUnpublished: false,
316
+ },
317
+ });
318
+ }
319
+ return events;
320
+ };
321
+ const recommendedArtifactTypesFor = (triggers) => {
322
+ const recommendations = new Set();
323
+ for (const trigger of triggers.filter((item) => item.triggered)) {
324
+ if (trigger.code === "schema_failures")
325
+ recommendations.add("schema");
326
+ if (trigger.code === "accepted_answer_rate_drop")
327
+ recommendations.add("eval");
328
+ if (trigger.code === "verifier_contradictions")
329
+ recommendations.add("eval");
330
+ if (trigger.code === "tool_failures")
331
+ recommendations.add("tool-metadata");
332
+ if (trigger.code === "latency_increase")
333
+ recommendations.add("model-router");
334
+ if (trigger.code === "cost_increase")
335
+ recommendations.add("model-router");
336
+ if (trigger.code === "privacy_security_warnings")
337
+ recommendations.add("policy");
338
+ }
339
+ return Array.from(recommendations).sort();
340
+ };
341
+ export const runCodaliReleaseOutcomeReporter = (input) => {
342
+ const now = input.now ?? (() => new Date());
343
+ const generatedAt = now().toISOString();
344
+ const monitorWindow = monitorWindowFor(input);
345
+ const thresholds = {
346
+ ...DEFAULT_CODALI_RELEASE_MONITOR_THRESHOLDS,
347
+ ...(input.thresholds ?? {}),
348
+ };
349
+ const metrics = metricsFor(input.metrics);
350
+ const triggers = rollbackTriggersFor(metrics, thresholds);
351
+ const rollbackRequired = triggers.some((trigger) => trigger.triggered);
352
+ const runtimeFlags = runtimeFlagsFor({
353
+ runtimeVersions: input.runtimeVersions,
354
+ disabledRuntimePackages: input.disabledRuntimePackages,
355
+ rollbackRequired,
356
+ });
357
+ const shadowTraffic = shadowTrafficFor(metrics);
358
+ const rollbackApplied = input.rollbackApplied === true && rollbackRequired;
359
+ const status = rollbackRequired
360
+ ? rollbackApplied ? "rolled_back" : "rollback_required"
361
+ : metrics.eligibleRequestCount > 0 && metrics.shadowRequestCount === 0
362
+ ? "watch"
363
+ : "healthy";
364
+ const rolloutEvents = rolloutEventsFor({
365
+ releaseId: input.releaseId,
366
+ createdAt: generatedAt,
367
+ runtimeFlags,
368
+ shadowTraffic,
369
+ });
370
+ const rollbackEvents = rollbackEventsFor({
371
+ releaseId: input.releaseId,
372
+ createdAt: generatedAt,
373
+ triggers,
374
+ runtimeFlags,
375
+ rollbackApplied,
376
+ });
377
+ const triggeredCodes = triggers
378
+ .filter((trigger) => trigger.triggered)
379
+ .map((trigger) => trigger.code);
380
+ const scope = scopeFor(input.scope);
381
+ const outcome = {
382
+ schemaVersion: CODALI_IMPROVEMENT_CONTRACT_SCHEMA_VERSION,
383
+ outcomeId: stableId("monitor-outcome", {
384
+ releaseId: input.releaseId,
385
+ status,
386
+ triggeredCodes,
387
+ generatedAt,
388
+ }),
389
+ releaseId: input.releaseId,
390
+ scope,
391
+ status: status === "rolled_back"
392
+ ? "rolled_back"
393
+ : rollbackRequired
394
+ ? "degraded"
395
+ : "succeeded",
396
+ published: input.published ?? false,
397
+ tagged: input.tagged ?? false,
398
+ trainingUsed: input.trainingUsed ?? false,
399
+ exportUsed: input.exportUsed ?? false,
400
+ createdAt: generatedAt,
401
+ ...(triggeredCodes.length ? { reasons: triggeredCodes } : {}),
402
+ telemetry: {
403
+ eligible_request_count: metrics.eligibleRequestCount,
404
+ shadow_request_count: metrics.shadowRequestCount,
405
+ schema_failures: metrics.schemaFailures,
406
+ verifier_contradictions: metrics.verifierContradictions,
407
+ tool_failures: metrics.toolFailures,
408
+ privacy_security_warnings: metrics.privacySecurityWarnings,
409
+ ...(metrics.acceptedAnswerRate !== undefined
410
+ ? { accepted_answer_rate: metrics.acceptedAnswerRate }
411
+ : {}),
412
+ ...(metrics.p95LatencyMs !== undefined ? { p95_latency_ms: metrics.p95LatencyMs } : {}),
413
+ ...(metrics.costUsd !== undefined ? { cost_usd: metrics.costUsd } : {}),
414
+ },
415
+ metadata: {
416
+ schemaVersion: CODALI_RELEASE_OUTCOME_REPORTER_SCHEMA_VERSION,
417
+ monitorWindow,
418
+ thresholds,
419
+ runtimeFlags,
420
+ shadowTraffic,
421
+ rolloutEvents,
422
+ rollbackEvents,
423
+ rollbackRequired,
424
+ npmPackageUnpublished: false,
425
+ },
426
+ };
427
+ return {
428
+ schemaVersion: CODALI_RELEASE_OUTCOME_REPORTER_SCHEMA_VERSION,
429
+ releaseId: input.releaseId,
430
+ status,
431
+ generatedAt,
432
+ monitorWindow,
433
+ thresholds,
434
+ metrics,
435
+ runtimeFlags,
436
+ shadowTraffic,
437
+ rollbackTriggers: triggers,
438
+ rolloutEvents,
439
+ rollbackEvents,
440
+ outcome,
441
+ improvementCycleFeedback: {
442
+ status: triggeredCodes.length ? "queued" : "recorded",
443
+ releaseId: input.releaseId,
444
+ nextCycleReasons: triggeredCodes,
445
+ recommendedArtifactTypes: recommendedArtifactTypesFor(triggers),
446
+ source: "release_monitor",
447
+ },
448
+ storageWrites: [],
449
+ };
450
+ };
451
+ export const writeCodaliReleaseOutcomeReportToStorageService = async (input) => {
452
+ const runWrite = await input.client.recordRun({
453
+ scope: input.scope,
454
+ idempotencyKey: `improvement-monitor:${input.report.releaseId}`,
455
+ body: {
456
+ improvement_run_id: input.scope.runId,
457
+ run_kind: "release_monitor",
458
+ status: input.report.status === "healthy" || input.report.status === "watch"
459
+ ? "completed"
460
+ : "blocked",
461
+ source_export_id: input.report.releaseId,
462
+ metadata: {
463
+ schemaVersion: input.report.schemaVersion,
464
+ releaseId: input.report.releaseId,
465
+ monitorWindow: input.report.monitorWindow,
466
+ thresholds: input.report.thresholds,
467
+ metrics: input.report.metrics,
468
+ runtimeFlags: input.report.runtimeFlags,
469
+ shadowTraffic: input.report.shadowTraffic,
470
+ rollbackTriggers: input.report.rollbackTriggers,
471
+ rolloutEvents: input.report.rolloutEvents,
472
+ rollbackEvents: input.report.rollbackEvents,
473
+ outcome: input.report.outcome,
474
+ improvementCycleFeedback: input.report.improvementCycleFeedback,
475
+ },
476
+ },
477
+ });
478
+ const candidateWrite = await input.client.recordCandidate({
479
+ scope: input.scope,
480
+ idempotencyKey: `improvement-monitor-candidate:${input.report.releaseId}`,
481
+ body: {
482
+ candidate_id: input.report.releaseId,
483
+ improvement_run_id: input.scope.runId,
484
+ source_export_id: input.report.releaseId,
485
+ source_record_ids: [],
486
+ candidate_kind: "release",
487
+ candidate_ref: input.report.releaseId,
488
+ status: input.report.status === "healthy" || input.report.status === "watch"
489
+ ? "released"
490
+ : "blocked",
491
+ metadata: {
492
+ schemaVersion: input.report.schemaVersion,
493
+ outcome: input.report.outcome,
494
+ rolloutEvents: input.report.rolloutEvents,
495
+ rollbackEvents: input.report.rollbackEvents,
496
+ improvementCycleFeedback: input.report.improvementCycleFeedback,
497
+ },
498
+ },
499
+ });
500
+ return [runWrite, candidateWrite];
501
+ };