@resolveio/server-lib 22.3.157 → 22.3.159
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/methods/ai-terminal.d.ts +1 -0
- package/methods/ai-terminal.js +133 -3
- package/methods/ai-terminal.js.map +1 -1
- package/package.json +1 -1
- package/util/ai-run-evidence-adapters.d.ts +37 -0
- package/util/ai-run-evidence-adapters.js +988 -79
- package/util/ai-run-evidence-adapters.js.map +1 -1
- package/util/ai-run-evidence.d.ts +1 -1
- package/util/ai-run-evidence.js.map +1 -1
- package/util/ai-runner-manager-autopilot.d.ts +99 -1
- package/util/ai-runner-manager-autopilot.js +370 -41
- package/util/ai-runner-manager-autopilot.js.map +1 -1
- package/util/ai-runner-manager-policy.d.ts +163 -0
- package/util/ai-runner-manager-policy.js +791 -26
- package/util/ai-runner-manager-policy.js.map +1 -1
- package/util/aicoder-runner-v6.d.ts +93 -3
- package/util/aicoder-runner-v6.js +699 -27
- package/util/aicoder-runner-v6.js.map +1 -1
- package/util/support-runner-v5.d.ts +236 -1
- package/util/support-runner-v5.js +1336 -54
- package/util/support-runner-v5.js.map +1 -1
|
@@ -47,9 +47,14 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
|
47
47
|
return to.concat(ar || Array.prototype.slice.call(from));
|
|
48
48
|
};
|
|
49
49
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
|
+
exports.estimateResolveIOAIManagerRetryExpectedValue = estimateResolveIOAIManagerRetryExpectedValue;
|
|
51
|
+
exports.decideResolveIOAIManagerAutonomyPolicy = decideResolveIOAIManagerAutonomyPolicy;
|
|
50
52
|
exports.normalizeResolveIOAIManagerHotfixEvidence = normalizeResolveIOAIManagerHotfixEvidence;
|
|
53
|
+
exports.evaluateResolveIOAIManagerHotfixGitProof = evaluateResolveIOAIManagerHotfixGitProof;
|
|
51
54
|
exports.validateResolveIOAIManagerHotfixEvidence = validateResolveIOAIManagerHotfixEvidence;
|
|
55
|
+
exports.buildResolveIOAIManagerHotfixEvidenceRecord = buildResolveIOAIManagerHotfixEvidenceRecord;
|
|
52
56
|
exports.decideResolveIOAIManagerHotfixContinuation = decideResolveIOAIManagerHotfixContinuation;
|
|
57
|
+
exports.decideResolveIOAIManagerHotfixCommitGuard = decideResolveIOAIManagerHotfixCommitGuard;
|
|
53
58
|
exports.buildResolveIOAIManagerHotfixFirstReleasePolicy = buildResolveIOAIManagerHotfixFirstReleasePolicy;
|
|
54
59
|
exports.isResolveIOAIManagerSafeAutoDispatch = isResolveIOAIManagerSafeAutoDispatch;
|
|
55
60
|
exports.normalizeResolveIOAIManagerFailureClass = normalizeResolveIOAIManagerFailureClass;
|
|
@@ -114,6 +119,291 @@ var HOTFIX_CHANNELS = new Set([
|
|
|
114
119
|
function cleanObject(value) {
|
|
115
120
|
return value && typeof value === 'object' && !Array.isArray(value) ? value : {};
|
|
116
121
|
}
|
|
122
|
+
function normalizeAutonomyMode(value) {
|
|
123
|
+
var normalized = cleanText(value, 120).toLowerCase().replace(/[\s-]+/g, '_');
|
|
124
|
+
if (/^(monitor|monitor_only|watch|watch_only)$/.test(normalized)) {
|
|
125
|
+
return 'monitor_only';
|
|
126
|
+
}
|
|
127
|
+
if (/^(auto|auto_retry|auto_retry_within_budget|autonomous|within_budget)$/.test(normalized)) {
|
|
128
|
+
return 'auto_retry_within_budget';
|
|
129
|
+
}
|
|
130
|
+
return 'manual_only';
|
|
131
|
+
}
|
|
132
|
+
function normalizeManagerEvidenceStrength(value) {
|
|
133
|
+
var normalized = cleanText(value, 40).toLowerCase().replace(/[\s-]+/g, '_');
|
|
134
|
+
if (normalized === 'proof') {
|
|
135
|
+
return 'proof';
|
|
136
|
+
}
|
|
137
|
+
if (normalized === 'material' || normalized === 'strong') {
|
|
138
|
+
return 'material';
|
|
139
|
+
}
|
|
140
|
+
if (normalized === 'weak') {
|
|
141
|
+
return 'weak';
|
|
142
|
+
}
|
|
143
|
+
return 'none';
|
|
144
|
+
}
|
|
145
|
+
function nonNegativeMoney(value) {
|
|
146
|
+
var parsed = Number(value);
|
|
147
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;
|
|
148
|
+
}
|
|
149
|
+
function finiteNumber(value) {
|
|
150
|
+
var parsed = Number(value);
|
|
151
|
+
return Number.isFinite(parsed) ? parsed : undefined;
|
|
152
|
+
}
|
|
153
|
+
function clampNumber(value, min, max) {
|
|
154
|
+
return Math.min(max, Math.max(min, value));
|
|
155
|
+
}
|
|
156
|
+
function isCheapEvidenceAutonomyAction(value) {
|
|
157
|
+
var action = cleanText(value, 120);
|
|
158
|
+
return !action || /^(run_evidence_probe|run_read_only_diagnosis|advance|continue_gate|park_manual)$/.test(action);
|
|
159
|
+
}
|
|
160
|
+
function estimateResolveIOAIManagerRetryExpectedValue(input) {
|
|
161
|
+
var e_2, _a;
|
|
162
|
+
if (input === void 0) { input = {}; }
|
|
163
|
+
var dispatchAction = cleanText(input.dispatchAction, 120);
|
|
164
|
+
var failureClass = normalizeResolveIOAIManagerFailureClass(input.failureClass);
|
|
165
|
+
var recoveryClass = cleanText(input.recoveryClass, 120);
|
|
166
|
+
var evidenceStrength = normalizeManagerEvidenceStrength(input.evidenceStrength);
|
|
167
|
+
var evidenceSignals = cleanList(input.evidenceSignals, 12, 120);
|
|
168
|
+
var projectedActionCostUsd = nonNegativeMoney(input.projectedActionCostUsd);
|
|
169
|
+
var budgetHardUsd = nonNegativeMoney(input.budgetHardUsd);
|
|
170
|
+
var materialEvidence = input.materialEvidence === true || evidenceStrength === 'material' || evidenceStrength === 'proof';
|
|
171
|
+
var newEvidence = input.newEvidence === true;
|
|
172
|
+
var signals = [];
|
|
173
|
+
var score = 0.1;
|
|
174
|
+
if (dispatchAction === 'run_evidence_probe') {
|
|
175
|
+
score = 0.75;
|
|
176
|
+
signals.push('cheap_evidence_probe');
|
|
177
|
+
}
|
|
178
|
+
else if (dispatchAction === 'run_read_only_diagnosis') {
|
|
179
|
+
score = 0.65;
|
|
180
|
+
signals.push('read_only_diagnosis');
|
|
181
|
+
}
|
|
182
|
+
else if (dispatchAction === 'advance' || dispatchAction === 'continue_gate') {
|
|
183
|
+
score = 0.55;
|
|
184
|
+
signals.push('gate_continuation');
|
|
185
|
+
}
|
|
186
|
+
else if (dispatchAction === 'run_infra_repair') {
|
|
187
|
+
score = 0.4;
|
|
188
|
+
signals.push('bounded_infra_repair');
|
|
189
|
+
}
|
|
190
|
+
else if (dispatchAction === 'run_compile_repair') {
|
|
191
|
+
score = 0.4;
|
|
192
|
+
signals.push('bounded_compile_repair');
|
|
193
|
+
}
|
|
194
|
+
else if (dispatchAction === 'run_release_repair') {
|
|
195
|
+
score = 0.3;
|
|
196
|
+
signals.push('bounded_release_repair');
|
|
197
|
+
}
|
|
198
|
+
else if (dispatchAction === 'run_journey_contract_repair' || dispatchAction === 'run_business_assertion_repair') {
|
|
199
|
+
score = 0.25;
|
|
200
|
+
signals.push('bounded_workflow_or_proof_repair');
|
|
201
|
+
}
|
|
202
|
+
else if (dispatchAction === 'run_targeted_product_repair') {
|
|
203
|
+
score = 0.15;
|
|
204
|
+
signals.push('targeted_product_repair');
|
|
205
|
+
}
|
|
206
|
+
if (evidenceStrength === 'proof') {
|
|
207
|
+
score += 0.3;
|
|
208
|
+
signals.push('proof_evidence');
|
|
209
|
+
}
|
|
210
|
+
else if (materialEvidence) {
|
|
211
|
+
score += 0.2;
|
|
212
|
+
signals.push('material_evidence');
|
|
213
|
+
}
|
|
214
|
+
else if (newEvidence) {
|
|
215
|
+
score += 0.1;
|
|
216
|
+
signals.push('new_evidence');
|
|
217
|
+
}
|
|
218
|
+
else if (evidenceStrength === 'weak') {
|
|
219
|
+
score -= 0.15;
|
|
220
|
+
signals.push('weak_evidence');
|
|
221
|
+
}
|
|
222
|
+
else if (!isCheapEvidenceAutonomyAction(dispatchAction)) {
|
|
223
|
+
score -= 0.25;
|
|
224
|
+
signals.push('no_material_evidence');
|
|
225
|
+
}
|
|
226
|
+
if ((failureClass === 'infra' || /infra/i.test(recoveryClass)) && dispatchAction === 'run_infra_repair') {
|
|
227
|
+
score += 0.15;
|
|
228
|
+
signals.push('failure_matches_infra_repair');
|
|
229
|
+
}
|
|
230
|
+
if ((failureClass === 'compile' || /compile/i.test(recoveryClass)) && dispatchAction === 'run_compile_repair') {
|
|
231
|
+
score += 0.15;
|
|
232
|
+
signals.push('failure_matches_compile_repair');
|
|
233
|
+
}
|
|
234
|
+
if (/release|publish|deploy/i.test("".concat(failureClass, " ").concat(recoveryClass)) && dispatchAction === 'run_release_repair') {
|
|
235
|
+
score += 0.1;
|
|
236
|
+
signals.push('failure_matches_release_repair');
|
|
237
|
+
}
|
|
238
|
+
if (projectedActionCostUsd >= 5) {
|
|
239
|
+
score -= 0.3;
|
|
240
|
+
signals.push('high_projected_cost');
|
|
241
|
+
}
|
|
242
|
+
else if (projectedActionCostUsd >= 2) {
|
|
243
|
+
score -= 0.18;
|
|
244
|
+
signals.push('medium_projected_cost');
|
|
245
|
+
}
|
|
246
|
+
else if (projectedActionCostUsd >= 1) {
|
|
247
|
+
score -= 0.08;
|
|
248
|
+
signals.push('low_projected_cost');
|
|
249
|
+
}
|
|
250
|
+
if (budgetHardUsd > 0 && projectedActionCostUsd > budgetHardUsd * 0.5) {
|
|
251
|
+
score -= 0.2;
|
|
252
|
+
signals.push('large_fraction_of_remaining_budget');
|
|
253
|
+
}
|
|
254
|
+
if (input.sameEvidenceAlreadyAttempted === true) {
|
|
255
|
+
score -= 0.35;
|
|
256
|
+
signals.push('same_evidence_already_attempted');
|
|
257
|
+
}
|
|
258
|
+
try {
|
|
259
|
+
for (var evidenceSignals_1 = __values(evidenceSignals), evidenceSignals_1_1 = evidenceSignals_1.next(); !evidenceSignals_1_1.done; evidenceSignals_1_1 = evidenceSignals_1.next()) {
|
|
260
|
+
var signal = evidenceSignals_1_1.value;
|
|
261
|
+
if (/passing_outcome|business|proof|diagnosis|compile|infra|release|artifact|fingerprint_changed|evidence_hash_changed/i.test(signal)) {
|
|
262
|
+
score += 0.03;
|
|
263
|
+
signals.push("evidence_signal:".concat(signal));
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
268
|
+
finally {
|
|
269
|
+
try {
|
|
270
|
+
if (evidenceSignals_1_1 && !evidenceSignals_1_1.done && (_a = evidenceSignals_1.return)) _a.call(evidenceSignals_1);
|
|
271
|
+
}
|
|
272
|
+
finally { if (e_2) throw e_2.error; }
|
|
273
|
+
}
|
|
274
|
+
var rounded = Number(clampNumber(score, -1, 1).toFixed(2));
|
|
275
|
+
var minScore = 0;
|
|
276
|
+
return {
|
|
277
|
+
score: rounded,
|
|
278
|
+
minScore: minScore,
|
|
279
|
+
positive: rounded >= minScore,
|
|
280
|
+
source: 'estimated',
|
|
281
|
+
confidence: evidenceStrength === 'proof' || materialEvidence ? 'medium' : 'low',
|
|
282
|
+
reason: rounded >= minScore
|
|
283
|
+
? 'estimated_retry_value_is_non_negative'
|
|
284
|
+
: 'estimated_retry_value_is_negative',
|
|
285
|
+
signals: Array.from(new Set(signals)).slice(0, 16)
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
function decideResolveIOAIManagerAutonomyPolicy(input) {
|
|
289
|
+
var _a;
|
|
290
|
+
if (input === void 0) { input = {}; }
|
|
291
|
+
var mode = normalizeAutonomyMode(input.mode);
|
|
292
|
+
var currentSpendUsd = nonNegativeMoney(input.currentSpendUsd);
|
|
293
|
+
var projectedActionCostUsd = nonNegativeMoney(input.projectedActionCostUsd);
|
|
294
|
+
var projectedSpendUsd = currentSpendUsd + projectedActionCostUsd;
|
|
295
|
+
var budgetSoftUsd = nonNegativeMoney(input.budgetSoftUsd);
|
|
296
|
+
var budgetHardUsd = nonNegativeMoney(input.budgetHardUsd);
|
|
297
|
+
var softBudgetExceeded = budgetSoftUsd > 0 && projectedSpendUsd >= budgetSoftUsd;
|
|
298
|
+
var hardBudgetExceeded = budgetHardUsd > 0 && projectedSpendUsd > budgetHardUsd;
|
|
299
|
+
var dispatchAction = cleanText(input.dispatchAction, 120);
|
|
300
|
+
var evidenceStrength = normalizeManagerEvidenceStrength(input.evidenceStrength);
|
|
301
|
+
var evidenceSignals = cleanList(input.evidenceSignals, 12, 120);
|
|
302
|
+
var materialEvidence = input.materialEvidence === true || evidenceStrength === 'material' || evidenceStrength === 'proof';
|
|
303
|
+
var newEvidence = input.newEvidence === true;
|
|
304
|
+
var evidenceBacked = materialEvidence || newEvidence || evidenceSignals.some(function (signal) { return /material|proof|business|compile|infra|release|diagnosis|journey|workflow|artifact|hash_changed|fingerprint_changed/i.test(signal); });
|
|
305
|
+
var cheapEvidenceAction = isCheapEvidenceAutonomyAction(dispatchAction);
|
|
306
|
+
var expectedValueEstimate = estimateResolveIOAIManagerRetryExpectedValue({
|
|
307
|
+
dispatchAction: dispatchAction,
|
|
308
|
+
projectedActionCostUsd: projectedActionCostUsd,
|
|
309
|
+
currentSpendUsd: currentSpendUsd,
|
|
310
|
+
budgetHardUsd: budgetHardUsd,
|
|
311
|
+
evidenceStrength: evidenceStrength,
|
|
312
|
+
materialEvidence: materialEvidence,
|
|
313
|
+
newEvidence: newEvidence,
|
|
314
|
+
evidenceSignals: evidenceSignals,
|
|
315
|
+
sameEvidenceAlreadyAttempted: input.sameEvidenceAlreadyAttempted === true
|
|
316
|
+
});
|
|
317
|
+
var providedExpectedValue = finiteNumber(input.expectedValueScore);
|
|
318
|
+
var expectedValueKnown = providedExpectedValue !== undefined;
|
|
319
|
+
var expectedValueScore = expectedValueKnown ? providedExpectedValue : expectedValueEstimate.score;
|
|
320
|
+
var minExpectedValue = (_a = finiteNumber(input.minExpectedValueScore)) !== null && _a !== void 0 ? _a : expectedValueEstimate.minScore;
|
|
321
|
+
var expectedValuePositive = expectedValueScore >= minExpectedValue;
|
|
322
|
+
var expectedValueSource = expectedValueKnown ? 'provided' : 'estimated';
|
|
323
|
+
var requiredEvidence = __spreadArray(__spreadArray(__spreadArray(__spreadArray([
|
|
324
|
+
'mode',
|
|
325
|
+
'projectedActionCostUsd'
|
|
326
|
+
], __read((budgetHardUsd > 0 ? ['budgetHardUsd'] : [])), false), __read((budgetSoftUsd > 0 ? ['budgetSoftUsd'] : [])), false), __read((dispatchAction ? ['dispatchAction'] : [])), false), __read((cheapEvidenceAction ? [] : ['materialEvidence or newEvidence', 'expectedValueScore when available'])), false);
|
|
327
|
+
var forbiddenActions = [];
|
|
328
|
+
var canAutoDispatch = false;
|
|
329
|
+
var canManualDispatch = true;
|
|
330
|
+
var blocked = false;
|
|
331
|
+
var requiresHumanApproval = true;
|
|
332
|
+
var reason = '';
|
|
333
|
+
var recommendedControl = mode;
|
|
334
|
+
if (mode === 'monitor_only') {
|
|
335
|
+
canManualDispatch = false;
|
|
336
|
+
reason = 'monitor_only_blocks_runner_dispatch';
|
|
337
|
+
forbiddenActions.push('Do not run recovery, repair, QA, publish, deploy, or customer reply actions while in Monitor Only mode.');
|
|
338
|
+
}
|
|
339
|
+
else if (mode === 'manual_only') {
|
|
340
|
+
reason = 'manual_only_requires_operator_dispatch';
|
|
341
|
+
forbiddenActions.push('Do not auto-dispatch manager recovery actions in Manual Only mode.');
|
|
342
|
+
}
|
|
343
|
+
else if (hardBudgetExceeded) {
|
|
344
|
+
blocked = true;
|
|
345
|
+
canAutoDispatch = false;
|
|
346
|
+
canManualDispatch = input.operatorApproved === true;
|
|
347
|
+
reason = 'auto_retry_budget_hard_cap_would_be_exceeded';
|
|
348
|
+
recommendedControl = 'increase_budget_or_manual';
|
|
349
|
+
forbiddenActions.push('Do not auto-dispatch because projected spend exceeds the hard budget.');
|
|
350
|
+
}
|
|
351
|
+
else if (!cheapEvidenceAction && !evidenceBacked) {
|
|
352
|
+
canAutoDispatch = false;
|
|
353
|
+
requiresHumanApproval = true;
|
|
354
|
+
reason = 'auto_retry_requires_material_evidence';
|
|
355
|
+
forbiddenActions.push('Do not auto-dispatch repair work until a deterministic artifact, changed blocker fingerprint, or material proof is recorded.');
|
|
356
|
+
}
|
|
357
|
+
else if (!cheapEvidenceAction && !expectedValuePositive) {
|
|
358
|
+
canAutoDispatch = false;
|
|
359
|
+
requiresHumanApproval = true;
|
|
360
|
+
reason = 'auto_retry_expected_value_not_positive';
|
|
361
|
+
forbiddenActions.push('Do not auto-dispatch repair work when the expected value score is below the configured minimum.');
|
|
362
|
+
}
|
|
363
|
+
else {
|
|
364
|
+
canAutoDispatch = true;
|
|
365
|
+
requiresHumanApproval = softBudgetExceeded;
|
|
366
|
+
reason = softBudgetExceeded
|
|
367
|
+
? 'auto_retry_soft_budget_warning_requires_review'
|
|
368
|
+
: 'auto_retry_within_budget_allows_auto_dispatch';
|
|
369
|
+
if (softBudgetExceeded) {
|
|
370
|
+
forbiddenActions.push('Do not escalate to a more expensive model or broader repair without operator review after soft budget warning.');
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
return {
|
|
374
|
+
mode: mode,
|
|
375
|
+
canAutoDispatch: canAutoDispatch,
|
|
376
|
+
canManualDispatch: canManualDispatch,
|
|
377
|
+
blocked: blocked,
|
|
378
|
+
requiresHumanApproval: requiresHumanApproval,
|
|
379
|
+
reason: reason,
|
|
380
|
+
currentSpendUsd: currentSpendUsd,
|
|
381
|
+
projectedActionCostUsd: projectedActionCostUsd,
|
|
382
|
+
projectedSpendUsd: projectedSpendUsd,
|
|
383
|
+
budgetSoftUsd: budgetSoftUsd,
|
|
384
|
+
budgetHardUsd: budgetHardUsd,
|
|
385
|
+
softBudgetExceeded: softBudgetExceeded,
|
|
386
|
+
hardBudgetExceeded: hardBudgetExceeded,
|
|
387
|
+
dispatchAction: dispatchAction,
|
|
388
|
+
expectedValueScore: expectedValueScore,
|
|
389
|
+
minExpectedValueScore: minExpectedValue,
|
|
390
|
+
expectedValueKnown: expectedValueKnown,
|
|
391
|
+
expectedValueSource: expectedValueSource,
|
|
392
|
+
expectedValuePositive: expectedValuePositive,
|
|
393
|
+
evidenceStrength: evidenceStrength,
|
|
394
|
+
materialEvidence: materialEvidence,
|
|
395
|
+
newEvidence: newEvidence,
|
|
396
|
+
evidenceBacked: evidenceBacked,
|
|
397
|
+
evidenceSignals: evidenceSignals,
|
|
398
|
+
recommendedControl: recommendedControl,
|
|
399
|
+
forbiddenActions: forbiddenActions,
|
|
400
|
+
requiredEvidence: requiredEvidence
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
function cleanDateString(value) {
|
|
404
|
+
var date = value instanceof Date ? value : new Date(value || Date.now());
|
|
405
|
+
return Number.isNaN(date.getTime()) ? new Date().toISOString() : date.toISOString();
|
|
406
|
+
}
|
|
117
407
|
function normalizeHotfixChannel(value) {
|
|
118
408
|
var normalized = cleanText(value, 120).toLowerCase().replace(/[\s-]+/g, '_');
|
|
119
409
|
return HOTFIX_CHANNELS.has(normalized) ? normalized : '';
|
|
@@ -182,6 +472,11 @@ function normalizeResolveIOAIManagerHotfixEvidence(value, policy) {
|
|
|
182
472
|
serviceRestartEvidence: cleanText(source.serviceRestartEvidence || source.service_restart_evidence, 1000),
|
|
183
473
|
releaseArtifactFingerprint: cleanText(source.releaseArtifactFingerprint || source.release_artifact_fingerprint || source.artifactFingerprint || source.artifact_fingerprint, 240),
|
|
184
474
|
lastReleaseArtifactFingerprint: cleanText(source.lastReleaseArtifactFingerprint || source.last_release_artifact_fingerprint || source.lastArtifactFingerprint || source.last_artifact_fingerprint, 240),
|
|
475
|
+
sourceCommitSha: cleanText(source.sourceCommitSha || source.source_commit_sha || source.gitCommitSha || source.git_commit_sha || source.commitSha || source.commit_sha, 120),
|
|
476
|
+
githubCommitUrl: cleanText(source.githubCommitUrl || source.github_commit_url || source.gitCommitUrl || source.git_commit_url || source.commitUrl || source.commit_url, 500),
|
|
477
|
+
gitCommitStatus: cleanText(source.gitCommitStatus || source.git_commit_status || source.githubCommitStatus || source.github_commit_status, 160),
|
|
478
|
+
gitPushStatus: cleanText(source.gitPushStatus || source.git_push_status || source.githubPushStatus || source.github_push_status || source.githubCommitReachableStatus || source.github_commit_reachable_status, 160),
|
|
479
|
+
committedAt: source.committedAt || source.committed_at,
|
|
185
480
|
forceDeployReason: cleanText(source.forceDeployReason || source.force_deploy_reason, 1000),
|
|
186
481
|
hotfixCannotResolveReason: cleanText(source.hotfixCannotResolveReason || source.hotfix_cannot_resolve_reason, 1000),
|
|
187
482
|
fullDeployRequested: source.fullDeployRequested === true || source.full_deploy_requested === true,
|
|
@@ -197,6 +492,100 @@ function pushMissing(blockers, condition, message) {
|
|
|
197
492
|
blockers.push(message);
|
|
198
493
|
}
|
|
199
494
|
}
|
|
495
|
+
function hotfixRequiresGithubCommit(channel) {
|
|
496
|
+
return /^(backend_js|static_ui|config|seed_data|release_artifact|new_artifact_deploy|artifact_build)$/.test(channel);
|
|
497
|
+
}
|
|
498
|
+
function extractGithubCommitSha(value) {
|
|
499
|
+
var _a;
|
|
500
|
+
var match = cleanText(value, 500).match(/^https:\/\/github\.com\/[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+\/commit\/([a-f0-9]{40})(?:$|[?#/])/i);
|
|
501
|
+
return ((_a = match === null || match === void 0 ? void 0 : match[1]) === null || _a === void 0 ? void 0 : _a.toLowerCase()) || '';
|
|
502
|
+
}
|
|
503
|
+
function isFullGitCommitSha(value) {
|
|
504
|
+
return /^[a-f0-9]{40}$/i.test(cleanText(value, 120));
|
|
505
|
+
}
|
|
506
|
+
function isStrongRemoteChecksum(value) {
|
|
507
|
+
return /^[a-f0-9]{12,128}$/i.test(cleanText(value, 160));
|
|
508
|
+
}
|
|
509
|
+
function githubCommitProofBlockers(value, channel) {
|
|
510
|
+
var blockers = [];
|
|
511
|
+
var sourceCommitSha = cleanText(value.sourceCommitSha, 120);
|
|
512
|
+
var githubCommitUrl = cleanText(value.githubCommitUrl, 500);
|
|
513
|
+
var gitCommitStatus = cleanText(value.gitCommitStatus, 160);
|
|
514
|
+
var remoteCommitProofStatus = cleanText(value.gitPushStatus || value.gitCommitStatus, 160);
|
|
515
|
+
var urlCommitSha = extractGithubCommitSha(githubCommitUrl);
|
|
516
|
+
if (!sourceCommitSha || !githubCommitUrl) {
|
|
517
|
+
blockers.push("".concat(channel, " hotfix requires sourceCommitSha, githubCommitUrl, and passed gitPushStatus so live hotfixes are backed by a GitHub commit pushed before continuation."));
|
|
518
|
+
return blockers;
|
|
519
|
+
}
|
|
520
|
+
if (!isFullGitCommitSha(sourceCommitSha)) {
|
|
521
|
+
blockers.push("".concat(channel, " hotfix sourceCommitSha must be a full 40-character git SHA."));
|
|
522
|
+
}
|
|
523
|
+
if (!urlCommitSha) {
|
|
524
|
+
blockers.push("".concat(channel, " hotfix githubCommitUrl must be a GitHub commit URL ending in a full 40-character git SHA."));
|
|
525
|
+
}
|
|
526
|
+
else if (isFullGitCommitSha(sourceCommitSha) && urlCommitSha !== sourceCommitSha.toLowerCase()) {
|
|
527
|
+
blockers.push("".concat(channel, " hotfix githubCommitUrl commit SHA must match sourceCommitSha."));
|
|
528
|
+
}
|
|
529
|
+
if (!remoteCommitProofStatus) {
|
|
530
|
+
blockers.push("".concat(channel, " hotfix requires passed gitPushStatus or gitCommitStatus so the manager knows the hotfix commit is present on GitHub before continuation."));
|
|
531
|
+
}
|
|
532
|
+
else if (!hotfixStatusPassed(remoteCommitProofStatus)) {
|
|
533
|
+
blockers.push("".concat(channel, " hotfix gitPushStatus or gitCommitStatus must be passed before continuation."));
|
|
534
|
+
}
|
|
535
|
+
if (gitCommitStatus && gitCommitStatus !== remoteCommitProofStatus && !hotfixStatusPassed(gitCommitStatus)) {
|
|
536
|
+
blockers.push("".concat(channel, " hotfix gitCommitStatus must be passed when provided."));
|
|
537
|
+
}
|
|
538
|
+
return blockers;
|
|
539
|
+
}
|
|
540
|
+
function evaluateResolveIOAIManagerHotfixGitProof(value, channelHint) {
|
|
541
|
+
if (channelHint === void 0) { channelHint = ''; }
|
|
542
|
+
var normalized = normalizeResolveIOAIManagerHotfixEvidence(value);
|
|
543
|
+
var source = (normalized || cleanObject(value));
|
|
544
|
+
var channel = (channelHint || (normalized === null || normalized === void 0 ? void 0 : normalized.channel) || source.channel || '');
|
|
545
|
+
var required = hotfixRequiresGithubCommit(channel);
|
|
546
|
+
var sourceCommitSha = cleanText(source.sourceCommitSha || source.source_commit_sha || source.gitCommitSha || source.git_commit_sha || source.commitSha || source.commit_sha, 120);
|
|
547
|
+
var githubCommitUrl = cleanText(source.githubCommitUrl || source.github_commit_url || source.gitCommitUrl || source.git_commit_url || source.commitUrl || source.commit_url, 500);
|
|
548
|
+
var githubCommitSha = extractGithubCommitSha(githubCommitUrl);
|
|
549
|
+
var gitCommitStatus = cleanText(source.gitCommitStatus || source.git_commit_status || source.githubCommitStatus || source.github_commit_status, 160);
|
|
550
|
+
var gitPushStatus = cleanText(source.gitPushStatus || source.git_push_status || source.githubPushStatus || source.github_push_status || source.githubCommitReachableStatus || source.github_commit_reachable_status || gitCommitStatus, 160);
|
|
551
|
+
var blockers = required
|
|
552
|
+
? githubCommitProofBlockers({
|
|
553
|
+
channel: channel,
|
|
554
|
+
target: (normalized === null || normalized === void 0 ? void 0 : normalized.target) || {},
|
|
555
|
+
sourceCommitSha: sourceCommitSha,
|
|
556
|
+
githubCommitUrl: githubCommitUrl,
|
|
557
|
+
gitCommitStatus: gitCommitStatus,
|
|
558
|
+
gitPushStatus: gitPushStatus
|
|
559
|
+
}, channel)
|
|
560
|
+
: [];
|
|
561
|
+
var status = !required
|
|
562
|
+
? 'not_required'
|
|
563
|
+
: (!sourceCommitSha || !githubCommitUrl || !gitPushStatus)
|
|
564
|
+
? 'missing'
|
|
565
|
+
: blockers.length
|
|
566
|
+
? 'invalid'
|
|
567
|
+
: 'passed';
|
|
568
|
+
var passed = !required || status === 'passed';
|
|
569
|
+
return {
|
|
570
|
+
required: required,
|
|
571
|
+
status: status,
|
|
572
|
+
passed: passed,
|
|
573
|
+
managerMustCommitBeforeHotfix: required && !passed,
|
|
574
|
+
channel: channel,
|
|
575
|
+
sourceCommitSha: sourceCommitSha,
|
|
576
|
+
githubCommitUrl: githubCommitUrl,
|
|
577
|
+
githubCommitSha: githubCommitSha,
|
|
578
|
+
gitCommitStatus: gitCommitStatus,
|
|
579
|
+
gitPushStatus: gitPushStatus,
|
|
580
|
+
blockers: blockers,
|
|
581
|
+
nextCommands: required && !passed
|
|
582
|
+
? ['commit_and_push_hotfix_to_github', 'verify_github_commit_url_and_push_status', 'record_hotfix_evidence']
|
|
583
|
+
: [],
|
|
584
|
+
requiredEvidence: required
|
|
585
|
+
? ['full 40-character sourceCommitSha', 'matching GitHub commit URL', 'passed gitPushStatus or gitCommitStatus']
|
|
586
|
+
: []
|
|
587
|
+
};
|
|
588
|
+
}
|
|
200
589
|
function validateResolveIOAIManagerHotfixEvidence(value, options) {
|
|
201
590
|
var _a, _b, _c, _d;
|
|
202
591
|
if (options === void 0) { options = {}; }
|
|
@@ -214,6 +603,7 @@ function validateResolveIOAIManagerHotfixEvidence(value, options) {
|
|
|
214
603
|
hotfixSatisfied: false,
|
|
215
604
|
requiredEvidence: ((_b = (_a = policy === null || policy === void 0 ? void 0 : policy.hotfixPlan) === null || _a === void 0 ? void 0 : _a.steps) === null || _b === void 0 ? void 0 : _b.flatMap(function (step) { return step.requiredEvidence; })) || [],
|
|
216
605
|
successEvidence: ((_d = (_c = policy === null || policy === void 0 ? void 0 : policy.hotfixPlan) === null || _c === void 0 ? void 0 : _c.steps) === null || _d === void 0 ? void 0 : _d.flatMap(function (step) { return step.successEvidence; })) || [],
|
|
606
|
+
githubCommitGuard: evaluateResolveIOAIManagerHotfixGitProof(value),
|
|
217
607
|
policy: policy,
|
|
218
608
|
nextAction: 'record_hotfix_evidence'
|
|
219
609
|
};
|
|
@@ -227,17 +617,24 @@ function validateResolveIOAIManagerHotfixEvidence(value, options) {
|
|
|
227
617
|
var successEvidence = (step === null || step === void 0 ? void 0 : step.successEvidence) || [];
|
|
228
618
|
var policyAllowsFullDeploy = (policy === null || policy === void 0 ? void 0 : policy.fullDeployAllowed) === true;
|
|
229
619
|
var policyBlocksDuplicate = (policy === null || policy === void 0 ? void 0 : policy.duplicateDeployBlocked) === true || (policy === null || policy === void 0 ? void 0 : policy.duplicatePublishBlocked) === true;
|
|
620
|
+
var githubCommitGuard = evaluateResolveIOAIManagerHotfixGitProof(normalized, channel);
|
|
230
621
|
if (normalized.fullDeployRequested && !policyAllowsFullDeploy && channel !== 'force_deploy_review' && channel !== 'new_artifact_deploy') {
|
|
231
622
|
blockers.push('Full deploy requested but hotfix-first policy does not allow a full deploy for this release state.');
|
|
232
623
|
}
|
|
233
624
|
if (normalized.fullDeployRequested && policyBlocksDuplicate && !normalized.forceDeployReason && channel !== 'force_deploy_review') {
|
|
234
625
|
blockers.push('Duplicate deploy/publish fingerprint requires force deploy/publish evidence before any full deploy.');
|
|
235
626
|
}
|
|
627
|
+
if (githubCommitGuard.required) {
|
|
628
|
+
blockers.push.apply(blockers, __spreadArray([], __read(githubCommitGuard.blockers), false));
|
|
629
|
+
}
|
|
236
630
|
if (channel === 'backend_js') {
|
|
237
631
|
pushMissing(blockers, !!normalized.compiledArtifactPath, 'Backend JS hotfix requires compiledArtifactPath.');
|
|
238
632
|
pushMissing(blockers, !!target.host, 'Backend JS hotfix requires target.host.');
|
|
239
633
|
pushMissing(blockers, !!target.path, 'Backend JS hotfix requires target.path.');
|
|
240
634
|
pushMissing(blockers, !!(normalized.remoteChecksumAfter || normalized.remoteChecksum), 'Backend JS hotfix requires remote checksum after replacement.');
|
|
635
|
+
if ((normalized.remoteChecksumAfter || normalized.remoteChecksum) && !isStrongRemoteChecksum(normalized.remoteChecksumAfter || normalized.remoteChecksum || '')) {
|
|
636
|
+
blockers.push('Backend JS hotfix remote checksum after replacement must be a strong hex checksum, not a label or placeholder.');
|
|
637
|
+
}
|
|
241
638
|
pushMissing(blockers, !!(normalized.restartEvidence || normalized.serviceRestartEvidence), 'Backend JS hotfix requires restart evidence.');
|
|
242
639
|
pushMissing(blockers, hotfixStatusPassed(normalized.healthCheckStatus), 'Backend JS hotfix requires passed healthCheckStatus.');
|
|
243
640
|
pushMissing(blockers, hotfixStatusPassed(normalized.selfTestStatus), 'Backend JS hotfix requires passed selfTestStatus.');
|
|
@@ -329,21 +726,228 @@ function validateResolveIOAIManagerHotfixEvidence(value, options) {
|
|
|
329
726
|
requiredEvidence: requiredEvidence,
|
|
330
727
|
successEvidence: successEvidence,
|
|
331
728
|
normalized: normalized,
|
|
729
|
+
githubCommitGuard: githubCommitGuard,
|
|
332
730
|
policy: policy,
|
|
333
731
|
nextAction: nextAction
|
|
334
732
|
};
|
|
335
733
|
}
|
|
336
|
-
function
|
|
734
|
+
function mergeHotfixEvidenceRecordInput(input) {
|
|
735
|
+
var e_3, _a;
|
|
736
|
+
var merged = __assign({}, cleanObject(input.evidence));
|
|
737
|
+
var directFields = [
|
|
738
|
+
'channel',
|
|
739
|
+
'status',
|
|
740
|
+
'target',
|
|
741
|
+
'compiledArtifactPath',
|
|
742
|
+
'builtDistPath',
|
|
743
|
+
'remoteChecksumBefore',
|
|
744
|
+
'remoteChecksumAfter',
|
|
745
|
+
'remoteChecksum',
|
|
746
|
+
'restartEvidence',
|
|
747
|
+
'healthCheckStatus',
|
|
748
|
+
'selfTestStatus',
|
|
749
|
+
'releaseGateStatus',
|
|
750
|
+
's3UploadResult',
|
|
751
|
+
'cloudfrontInvalidationId',
|
|
752
|
+
'publicProof',
|
|
753
|
+
'configChangeEvidence',
|
|
754
|
+
'seedDataEvidence',
|
|
755
|
+
'cacheInvalidationEvidence',
|
|
756
|
+
'serviceRestartEvidence',
|
|
757
|
+
'releaseArtifactFingerprint',
|
|
758
|
+
'lastReleaseArtifactFingerprint',
|
|
759
|
+
'sourceCommitSha',
|
|
760
|
+
'githubCommitUrl',
|
|
761
|
+
'gitCommitStatus',
|
|
762
|
+
'gitPushStatus',
|
|
763
|
+
'committedAt',
|
|
764
|
+
'forceDeployReason',
|
|
765
|
+
'hotfixCannotResolveReason',
|
|
766
|
+
'fullDeployRequested',
|
|
767
|
+
'recordedAt'
|
|
768
|
+
];
|
|
769
|
+
try {
|
|
770
|
+
for (var directFields_1 = __values(directFields), directFields_1_1 = directFields_1.next(); !directFields_1_1.done; directFields_1_1 = directFields_1.next()) {
|
|
771
|
+
var field = directFields_1_1.value;
|
|
772
|
+
var value = input[field];
|
|
773
|
+
if (value !== undefined && value !== null && value !== '') {
|
|
774
|
+
merged[field] = value;
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
|
779
|
+
finally {
|
|
780
|
+
try {
|
|
781
|
+
if (directFields_1_1 && !directFields_1_1.done && (_a = directFields_1.return)) _a.call(directFields_1);
|
|
782
|
+
}
|
|
783
|
+
finally { if (e_3) throw e_3.error; }
|
|
784
|
+
}
|
|
785
|
+
return merged;
|
|
786
|
+
}
|
|
787
|
+
function resolveHotfixEvidenceRequiredFields(channel) {
|
|
788
|
+
var fields = ['channel'];
|
|
789
|
+
if (hotfixRequiresGithubCommit(channel)) {
|
|
790
|
+
fields.push('sourceCommitSha', 'githubCommitUrl', 'gitPushStatus');
|
|
791
|
+
}
|
|
792
|
+
if (channel === 'backend_js') {
|
|
793
|
+
fields.push('compiledArtifactPath', 'target.host', 'target.path', 'remoteChecksumAfter', 'restartEvidence', 'healthCheckStatus', 'selfTestStatus');
|
|
794
|
+
}
|
|
795
|
+
else if (channel === 'static_ui') {
|
|
796
|
+
fields.push('builtDistPath', 'target.bucket', 'target.distributionId', 's3UploadResult', 'cloudfrontInvalidationId', 'publicProof');
|
|
797
|
+
}
|
|
798
|
+
else if (channel === 'config') {
|
|
799
|
+
fields.push('target.configKey', 'configChangeEvidence', 'releaseGateStatus');
|
|
800
|
+
}
|
|
801
|
+
else if (channel === 'seed_data') {
|
|
802
|
+
fields.push('target.seedKey', 'seedDataEvidence', 'releaseGateStatus');
|
|
803
|
+
}
|
|
804
|
+
else if (channel === 'cache_invalidation') {
|
|
805
|
+
fields.push('target.cacheKey', 'cacheInvalidationEvidence', 'releaseGateStatus_or_healthCheckStatus');
|
|
806
|
+
}
|
|
807
|
+
else if (channel === 'service_restart') {
|
|
808
|
+
fields.push('target.processName', 'serviceRestartEvidence', 'healthCheckStatus', 'selfTestStatus');
|
|
809
|
+
}
|
|
810
|
+
else if (channel === 'release_artifact') {
|
|
811
|
+
fields.push('releaseArtifactFingerprint', 'releaseGateStatus');
|
|
812
|
+
}
|
|
813
|
+
else if (channel === 'new_artifact_deploy') {
|
|
814
|
+
fields.push('releaseArtifactFingerprint', 'lastReleaseArtifactFingerprint', 'releaseGateStatus');
|
|
815
|
+
}
|
|
816
|
+
else if (channel === 'artifact_build') {
|
|
817
|
+
fields.push('releaseArtifactFingerprint');
|
|
818
|
+
}
|
|
819
|
+
else if (channel === 'force_deploy_review') {
|
|
820
|
+
fields.push('forceDeployReason', 'hotfixCannotResolveReason');
|
|
821
|
+
}
|
|
822
|
+
return Array.from(new Set(fields));
|
|
823
|
+
}
|
|
824
|
+
function hotfixEvidenceFieldPresent(evidence, field) {
|
|
825
|
+
if (!evidence) {
|
|
826
|
+
return false;
|
|
827
|
+
}
|
|
828
|
+
var target = evidence.target || {};
|
|
829
|
+
switch (field) {
|
|
830
|
+
case 'channel':
|
|
831
|
+
return !!evidence.channel;
|
|
832
|
+
case 'sourceCommitSha':
|
|
833
|
+
return isFullGitCommitSha(evidence.sourceCommitSha || '');
|
|
834
|
+
case 'githubCommitUrl':
|
|
835
|
+
return !!extractGithubCommitSha(evidence.githubCommitUrl || '');
|
|
836
|
+
case 'gitPushStatus':
|
|
837
|
+
return hotfixStatusPassed(evidence.gitPushStatus) || hotfixStatusPassed(evidence.gitCommitStatus);
|
|
838
|
+
case 'compiledArtifactPath':
|
|
839
|
+
return !!cleanText(evidence.compiledArtifactPath, 500);
|
|
840
|
+
case 'builtDistPath':
|
|
841
|
+
return !!cleanText(evidence.builtDistPath, 500);
|
|
842
|
+
case 'remoteChecksumAfter':
|
|
843
|
+
return !!cleanText(evidence.remoteChecksumAfter || evidence.remoteChecksum, 160);
|
|
844
|
+
case 'restartEvidence':
|
|
845
|
+
return !!cleanText(evidence.restartEvidence || evidence.serviceRestartEvidence, 1000);
|
|
846
|
+
case 'serviceRestartEvidence':
|
|
847
|
+
return !!cleanText(evidence.serviceRestartEvidence || evidence.restartEvidence, 1000);
|
|
848
|
+
case 'healthCheckStatus':
|
|
849
|
+
return hotfixStatusPassed(evidence.healthCheckStatus);
|
|
850
|
+
case 'selfTestStatus':
|
|
851
|
+
return hotfixStatusPassed(evidence.selfTestStatus);
|
|
852
|
+
case 'releaseGateStatus':
|
|
853
|
+
return hotfixStatusPassed(evidence.releaseGateStatus);
|
|
854
|
+
case 'releaseGateStatus_or_healthCheckStatus':
|
|
855
|
+
return hotfixStatusPassed(evidence.releaseGateStatus) || hotfixStatusPassed(evidence.healthCheckStatus);
|
|
856
|
+
case 's3UploadResult':
|
|
857
|
+
return !!cleanText(evidence.s3UploadResult, 1000);
|
|
858
|
+
case 'cloudfrontInvalidationId':
|
|
859
|
+
return !!cleanText(evidence.cloudfrontInvalidationId, 240);
|
|
860
|
+
case 'publicProof':
|
|
861
|
+
return !!cleanText(evidence.publicProof, 1000);
|
|
862
|
+
case 'configChangeEvidence':
|
|
863
|
+
return !!cleanText(evidence.configChangeEvidence, 1000);
|
|
864
|
+
case 'seedDataEvidence':
|
|
865
|
+
return !!cleanText(evidence.seedDataEvidence, 1000);
|
|
866
|
+
case 'cacheInvalidationEvidence':
|
|
867
|
+
return !!cleanText(evidence.cacheInvalidationEvidence, 1000);
|
|
868
|
+
case 'releaseArtifactFingerprint':
|
|
869
|
+
return !!cleanText(evidence.releaseArtifactFingerprint, 240);
|
|
870
|
+
case 'lastReleaseArtifactFingerprint':
|
|
871
|
+
return !!cleanText(evidence.lastReleaseArtifactFingerprint, 240);
|
|
872
|
+
case 'forceDeployReason':
|
|
873
|
+
return !!cleanText(evidence.forceDeployReason, 1000);
|
|
874
|
+
case 'hotfixCannotResolveReason':
|
|
875
|
+
return !!cleanText(evidence.hotfixCannotResolveReason, 1000);
|
|
876
|
+
case 'target.host':
|
|
877
|
+
return !!cleanText(target.host, 200);
|
|
878
|
+
case 'target.path':
|
|
879
|
+
return !!cleanText(target.path, 500);
|
|
880
|
+
case 'target.bucket':
|
|
881
|
+
return !!cleanText(target.bucket, 200);
|
|
882
|
+
case 'target.distributionId':
|
|
883
|
+
return !!cleanText(target.distributionId, 200);
|
|
884
|
+
case 'target.configKey':
|
|
885
|
+
return !!cleanText(target.configKey, 200);
|
|
886
|
+
case 'target.seedKey':
|
|
887
|
+
return !!cleanText(target.seedKey, 200);
|
|
888
|
+
case 'target.cacheKey':
|
|
889
|
+
return !!cleanText(target.cacheKey, 200);
|
|
890
|
+
case 'target.processName':
|
|
891
|
+
return !!cleanText(target.processName, 200);
|
|
892
|
+
default:
|
|
893
|
+
return false;
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
function buildResolveIOAIManagerHotfixEvidenceRecord(input) {
|
|
337
897
|
var _a, _b;
|
|
338
898
|
if (input === void 0) { input = {}; }
|
|
899
|
+
var merged = mergeHotfixEvidenceRecordInput(input);
|
|
900
|
+
var normalized = normalizeResolveIOAIManagerHotfixEvidence(merged, input.policy);
|
|
901
|
+
var validation = validateResolveIOAIManagerHotfixEvidence(merged, { policy: input.policy });
|
|
902
|
+
var channel = validation.channel || (normalized === null || normalized === void 0 ? void 0 : normalized.channel) || ((_b = (_a = input.policy) === null || _a === void 0 ? void 0 : _a.hotfixPlan) === null || _b === void 0 ? void 0 : _b.recommendedChannel) || '';
|
|
903
|
+
var requiredFields = resolveHotfixEvidenceRequiredFields(channel);
|
|
904
|
+
var missingFields = requiredFields.filter(function (field) { return !hotfixEvidenceFieldPresent(normalized, field); });
|
|
905
|
+
var recordedAt = cleanDateString(input.now || (normalized === null || normalized === void 0 ? void 0 : normalized.recordedAt) || new Date());
|
|
906
|
+
var githubCommitGuard = validation.githubCommitGuard || evaluateResolveIOAIManagerHotfixGitProof(normalized || merged, channel);
|
|
907
|
+
return {
|
|
908
|
+
recordId: cleanText(input.recordId, 160) || "hotfix-".concat(fingerprintResolveIOAIManagerBlocker("".concat(channel, ":").concat(githubCommitGuard.sourceCommitSha, ":").concat(recordedAt))),
|
|
909
|
+
recordedAt: recordedAt,
|
|
910
|
+
recordedBy: cleanText(input.recordedBy || 'manager', 160),
|
|
911
|
+
source: cleanText(input.source || 'unknown', 80),
|
|
912
|
+
reason: cleanText(input.reason, 1000),
|
|
913
|
+
channel: channel,
|
|
914
|
+
status: validation.status,
|
|
915
|
+
nextAction: validation.nextAction,
|
|
916
|
+
valid: validation.valid,
|
|
917
|
+
hotfixSatisfied: validation.hotfixSatisfied,
|
|
918
|
+
fullDeployAllowed: validation.fullDeployAllowed,
|
|
919
|
+
fullDeployBlocked: validation.fullDeployBlocked,
|
|
920
|
+
requiredFields: requiredFields,
|
|
921
|
+
missingFields: missingFields,
|
|
922
|
+
evidence: normalized,
|
|
923
|
+
validation: validation,
|
|
924
|
+
sourceCommitSha: githubCommitGuard.sourceCommitSha,
|
|
925
|
+
githubCommitUrl: githubCommitGuard.githubCommitUrl,
|
|
926
|
+
gitPushStatus: githubCommitGuard.gitPushStatus,
|
|
927
|
+
githubCommitRequired: githubCommitGuard.required,
|
|
928
|
+
githubCommitProofPassed: githubCommitGuard.passed,
|
|
929
|
+
commitProofStatus: githubCommitGuard.status,
|
|
930
|
+
managerMustCommitBeforeHotfix: githubCommitGuard.managerMustCommitBeforeHotfix,
|
|
931
|
+
githubCommitGuard: githubCommitGuard,
|
|
932
|
+
readyForReleaseGate: validation.valid === true && validation.nextAction === 'rerun_release_gate',
|
|
933
|
+
readyForContinuation: validation.valid === true && validation.hotfixSatisfied === true && hotfixStatusPassed(normalized === null || normalized === void 0 ? void 0 : normalized.releaseGateStatus)
|
|
934
|
+
};
|
|
935
|
+
}
|
|
936
|
+
function decideResolveIOAIManagerHotfixContinuation(input) {
|
|
937
|
+
var e_4, _a;
|
|
938
|
+
var _b, _c;
|
|
939
|
+
if (input === void 0) { input = {}; }
|
|
339
940
|
var validation = validateResolveIOAIManagerHotfixEvidence(input.evidence, { policy: input.policy });
|
|
340
941
|
var failureClass = cleanText(input.failureClass, 120) || 'release';
|
|
341
|
-
var blockerText = cleanText(input.blocker || validation.blockers.join('; ') || ((
|
|
942
|
+
var blockerText = cleanText(input.blocker || validation.blockers.join('; ') || ((_b = validation.normalized) === null || _b === void 0 ? void 0 : _b.hotfixCannotResolveReason), 1000);
|
|
342
943
|
var blockerFingerprint = fingerprintResolveIOAIManagerBlocker(blockerText || "".concat(validation.channel, ":").concat(validation.status, ":").concat(validation.nextAction));
|
|
343
944
|
var baseBlockers = __spreadArray([], __read(validation.blockers), false);
|
|
945
|
+
var githubCommitGuard = validation.githubCommitGuard || evaluateResolveIOAIManagerHotfixGitProof(input.evidence, validation.channel);
|
|
946
|
+
var needsGithubCommitProof = githubCommitGuard.managerMustCommitBeforeHotfix
|
|
947
|
+
|| validation.blockers.some(function (blocker) { return /sourceCommitSha|githubCommitUrl|gitPushStatus|gitCommitStatus|GitHub commit|pushed/i.test(blocker); });
|
|
344
948
|
var repeatedFailure = input.repeatedFailure === true;
|
|
345
949
|
var releaseGatePassed = input.releaseGatePassed === true
|
|
346
|
-
|| hotfixStatusPassed((
|
|
950
|
+
|| hotfixStatusPassed((_c = validation.normalized) === null || _c === void 0 ? void 0 : _c.releaseGateStatus);
|
|
347
951
|
var action = validation.nextAction;
|
|
348
952
|
var canContinueRun = false;
|
|
349
953
|
var canRunFullDeploy = validation.fullDeployAllowed;
|
|
@@ -351,13 +955,38 @@ function decideResolveIOAIManagerHotfixContinuation(input) {
|
|
|
351
955
|
var shouldPark = false;
|
|
352
956
|
var reason = '';
|
|
353
957
|
var nextCommands = [];
|
|
354
|
-
if (
|
|
958
|
+
if (githubCommitGuard.managerMustCommitBeforeHotfix) {
|
|
959
|
+
action = 'record_hotfix_evidence';
|
|
960
|
+
reason = githubCommitGuard.blockers.length
|
|
961
|
+
? "Manager hotfix cannot continue until the hotfix is committed and pushed: ".concat(githubCommitGuard.blockers.join('; '))
|
|
962
|
+
: 'Manager hotfix cannot continue until sourceCommitSha, githubCommitUrl, and passed gitPushStatus prove the hotfix is on GitHub.';
|
|
963
|
+
nextCommands.push.apply(nextCommands, __spreadArray(__spreadArray([], __read(githubCommitGuard.nextCommands), false), ['rerun_hotfix_evidence_validator'], false));
|
|
964
|
+
try {
|
|
965
|
+
for (var _d = __values(githubCommitGuard.blockers), _e = _d.next(); !_e.done; _e = _d.next()) {
|
|
966
|
+
var blocker = _e.value;
|
|
967
|
+
if (!baseBlockers.includes(blocker)) {
|
|
968
|
+
baseBlockers.push(blocker);
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
catch (e_4_1) { e_4 = { error: e_4_1 }; }
|
|
973
|
+
finally {
|
|
974
|
+
try {
|
|
975
|
+
if (_e && !_e.done && (_a = _d.return)) _a.call(_d);
|
|
976
|
+
}
|
|
977
|
+
finally { if (e_4) throw e_4.error; }
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
else if (!validation.valid || validation.status === 'missing' || validation.status === 'incomplete') {
|
|
355
981
|
action = validation.nextAction === 'request_force_deploy_reason'
|
|
356
982
|
? 'request_force_deploy_reason'
|
|
357
983
|
: 'record_hotfix_evidence';
|
|
358
984
|
reason = validation.blockers.length
|
|
359
985
|
? "Hotfix evidence is not complete: ".concat(validation.blockers.join('; '))
|
|
360
986
|
: 'Hotfix evidence is missing; record the hotfix target, checksum, restart, health, and self-test proof before continuing.';
|
|
987
|
+
if (needsGithubCommitProof) {
|
|
988
|
+
nextCommands.push('commit_and_push_hotfix_to_github', 'verify_github_commit_url_and_push_status');
|
|
989
|
+
}
|
|
361
990
|
nextCommands.push('record_hotfix_evidence', 'rerun_hotfix_evidence_validator');
|
|
362
991
|
}
|
|
363
992
|
else if (validation.fullDeployAllowed) {
|
|
@@ -402,13 +1031,49 @@ function decideResolveIOAIManagerHotfixContinuation(input) {
|
|
|
402
1031
|
warnings: validation.warnings,
|
|
403
1032
|
requiredEvidence: validation.requiredEvidence,
|
|
404
1033
|
successEvidence: validation.successEvidence,
|
|
405
|
-
nextCommands: nextCommands,
|
|
1034
|
+
nextCommands: Array.from(new Set(nextCommands)),
|
|
406
1035
|
failureClass: failureClass,
|
|
407
1036
|
blockerFingerprint: blockerFingerprint,
|
|
1037
|
+
githubCommitGuard: githubCommitGuard,
|
|
408
1038
|
validation: validation,
|
|
409
1039
|
recordedAt: isoNow(input.now)
|
|
410
1040
|
};
|
|
411
1041
|
}
|
|
1042
|
+
function decideResolveIOAIManagerHotfixCommitGuard(input) {
|
|
1043
|
+
if (input === void 0) { input = {}; }
|
|
1044
|
+
var normalized = normalizeResolveIOAIManagerHotfixEvidence(input.evidence, input.policy);
|
|
1045
|
+
var validation = validateResolveIOAIManagerHotfixEvidence(input.evidence, { policy: input.policy });
|
|
1046
|
+
var githubCommitGuard = validation.githubCommitGuard || evaluateResolveIOAIManagerHotfixGitProof(input.evidence, validation.channel);
|
|
1047
|
+
var active = !!normalized || githubCommitGuard.required === true;
|
|
1048
|
+
var hotfixCommitBlockers = validation.blockers.filter(function (blocker) { return /sourceCommitSha|githubCommitUrl|gitPushStatus|gitCommitStatus|GitHub commit|pushed/i.test(blocker); });
|
|
1049
|
+
var blockers = Array.from(new Set(__spreadArray(__spreadArray([], __read((githubCommitGuard.blockers || [])), false), __read(hotfixCommitBlockers), false)));
|
|
1050
|
+
var blocked = active && (githubCommitGuard.managerMustCommitBeforeHotfix === true
|
|
1051
|
+
|| (githubCommitGuard.required === true && githubCommitGuard.passed !== true)
|
|
1052
|
+
|| hotfixCommitBlockers.length > 0);
|
|
1053
|
+
var nextCommands = blocked
|
|
1054
|
+
? Array.from(new Set(__spreadArray(__spreadArray([], __read((githubCommitGuard.nextCommands || [])), false), [
|
|
1055
|
+
'commit_and_push_hotfix_to_github',
|
|
1056
|
+
'verify_github_commit_url_and_push_status',
|
|
1057
|
+
'record_hotfix_evidence'
|
|
1058
|
+
], false)))
|
|
1059
|
+
: [];
|
|
1060
|
+
return {
|
|
1061
|
+
active: active,
|
|
1062
|
+
blocked: blocked,
|
|
1063
|
+
reason: blocked
|
|
1064
|
+
? (blockers.length
|
|
1065
|
+
? "Hotfix continuation is blocked until GitHub commit proof is recorded: ".concat(blockers.join('; '))
|
|
1066
|
+
: 'Hotfix continuation is blocked until sourceCommitSha, githubCommitUrl, and passed gitPushStatus prove the hotfix is pushed to GitHub.')
|
|
1067
|
+
: (active ? 'Hotfix GitHub commit proof is recorded.' : 'No hotfix commit guard is active.'),
|
|
1068
|
+
nextAction: blocked ? 'record_hotfix_evidence' : 'continue',
|
|
1069
|
+
channel: validation.channel || githubCommitGuard.channel || '',
|
|
1070
|
+
blockers: blockers,
|
|
1071
|
+
nextCommands: nextCommands,
|
|
1072
|
+
requiredEvidence: githubCommitGuard.requiredEvidence,
|
|
1073
|
+
githubCommitGuard: githubCommitGuard,
|
|
1074
|
+
validation: validation
|
|
1075
|
+
};
|
|
1076
|
+
}
|
|
412
1077
|
function releaseStatusIsBlocked(value) {
|
|
413
1078
|
return /fail|error|blocked|missing|empty|not ready|not_ready|denied|invalid|timeout|stale/i.test(value);
|
|
414
1079
|
}
|
|
@@ -550,17 +1215,17 @@ function buildHotfixFirstReleasePlan(input) {
|
|
|
550
1215
|
steps: [
|
|
551
1216
|
hotfixStep('static_ui_hotfix', 'Static UI hotfix', 'static_ui', {
|
|
552
1217
|
safeToAutoRun: true,
|
|
553
|
-
requiredEvidence: ['built dist path', 'target S3 bucket and CloudFront distribution', 'changed frontend bundle or asset list'],
|
|
554
|
-
successEvidence: ['S3 upload result', 'CloudFront invalidation id', 'public bundle contains expected hotfix marker']
|
|
1218
|
+
requiredEvidence: ['sourceCommitSha, githubCommitUrl, and passed gitPushStatus', 'built dist path', 'target S3 bucket and CloudFront distribution', 'changed frontend bundle or asset list'],
|
|
1219
|
+
successEvidence: ['GitHub commit and push proof', 'S3 upload result', 'CloudFront invalidation id', 'public bundle contains expected hotfix marker']
|
|
555
1220
|
}),
|
|
556
1221
|
hotfixStep('backend_js_hotfix', 'Backend JS hotfix', 'backend_js', {
|
|
557
|
-
requiredEvidence: ['compiled JS artifact path', 'target backend host', 'diff limited to runner/operator code'],
|
|
558
|
-
successEvidence: ['remote file checksum', 'service restart or process reload evidence', 'self-test passes']
|
|
1222
|
+
requiredEvidence: ['sourceCommitSha, githubCommitUrl, and passed gitPushStatus', 'compiled JS artifact path', 'target backend host', 'diff limited to runner/operator code'],
|
|
1223
|
+
successEvidence: ['GitHub commit and push proof', 'remote file checksum', 'service restart or process reload evidence', 'self-test passes']
|
|
559
1224
|
}),
|
|
560
1225
|
hotfixStep('config_seed_cache_restart', 'Config, seed, cache, or restart repair', 'config', {
|
|
561
1226
|
safeToAutoRun: true,
|
|
562
|
-
requiredEvidence: ['exact config/seed/cache key or process name', 'why no product artifact changed'],
|
|
563
|
-
successEvidence: ['release gate rerun result', 'operator console release snapshot refreshed']
|
|
1227
|
+
requiredEvidence: ['sourceCommitSha, githubCommitUrl, and passed gitPushStatus', 'exact config/seed/cache key or process name', 'why no product artifact changed'],
|
|
1228
|
+
successEvidence: ['GitHub commit and push proof', 'release gate rerun result', 'operator console release snapshot refreshed']
|
|
564
1229
|
})
|
|
565
1230
|
],
|
|
566
1231
|
acceptanceEvidence: commonAcceptance,
|
|
@@ -1017,6 +1682,48 @@ function recoveryActionAutoRunnable(mode, probe) {
|
|
|
1017
1682
|
}
|
|
1018
1683
|
return probe.steps.some(function (step) { return step.commandHint || step.kind === 'rerun_same_gate' || step.kind === 'release_status' || step.kind === 'diff_scope_check'; });
|
|
1019
1684
|
}
|
|
1685
|
+
function recoveryActionCostCeilingUsd(mode) {
|
|
1686
|
+
var _a;
|
|
1687
|
+
var map = {
|
|
1688
|
+
advance: 0,
|
|
1689
|
+
collect_evidence: 0.25,
|
|
1690
|
+
read_only_diagnosis: 1,
|
|
1691
|
+
repair_infra: 0.5,
|
|
1692
|
+
repair_compile: 1.5,
|
|
1693
|
+
repair_journey_contract: 2,
|
|
1694
|
+
repair_business_assertion: 1.5,
|
|
1695
|
+
repair_release: 0.75,
|
|
1696
|
+
targeted_product_repair: 5,
|
|
1697
|
+
manual_review: 0,
|
|
1698
|
+
continue_gate: 0
|
|
1699
|
+
};
|
|
1700
|
+
return (_a = map[mode]) !== null && _a !== void 0 ? _a : 1;
|
|
1701
|
+
}
|
|
1702
|
+
function recoveryActionRequiredStateTransition(mode) {
|
|
1703
|
+
var map = {
|
|
1704
|
+
advance: 'current gate advances without repair after existing proof is accepted',
|
|
1705
|
+
collect_evidence: 'blockerFingerprint or evidenceHash changes with material proof, or run remains parked',
|
|
1706
|
+
read_only_diagnosis: 'diagnosis gate becomes valid or records a blocked-reproduction reason',
|
|
1707
|
+
repair_infra: 'infra preflight changes from failed/blocked to passed, or records a new infra blocker',
|
|
1708
|
+
repair_compile: 'compile/startup status changes from failed to passed, or records a new compile blocker',
|
|
1709
|
+
repair_journey_contract: 'journey contract validates with first/next/last workflow proof',
|
|
1710
|
+
repair_business_assertion: 'business assertion changes from missing/failed to passed with artifact proof',
|
|
1711
|
+
repair_release: 'hotfix/release gate changes from blocked to passed, rerun_release_gate, or parked manual',
|
|
1712
|
+
targeted_product_repair: 'owner-scoped diff is produced and deterministic proof advances to QA',
|
|
1713
|
+
manual_review: 'operator records one explicit decision',
|
|
1714
|
+
continue_gate: 'current gate records accepted proof and advances'
|
|
1715
|
+
};
|
|
1716
|
+
return map[mode] || 'runner records a validated state transition before continuing';
|
|
1717
|
+
}
|
|
1718
|
+
function recoveryActionProofRequiredBeforeContinuation(mode) {
|
|
1719
|
+
return mode !== 'advance' && mode !== 'continue_gate' && mode !== 'manual_review';
|
|
1720
|
+
}
|
|
1721
|
+
function recoveryActionExitCriteria(input) {
|
|
1722
|
+
return Array.from(new Set(__spreadArray(__spreadArray([
|
|
1723
|
+
"exact dispatch action ".concat(input.dispatchAction, " completed or was parked"),
|
|
1724
|
+
input.requiredStateTransition
|
|
1725
|
+
], __read((recoveryActionProofRequiredBeforeContinuation(input.mode) ? ['do not continue runner until required proof artifact is attached'] : [])), false), __read(input.stopWhen), false).map(function (entry) { return cleanText(entry, 500); }).filter(Boolean))).slice(0, 30);
|
|
1726
|
+
}
|
|
1020
1727
|
function buildResolveIOAIManagerRecoveryActionPacket(input) {
|
|
1021
1728
|
var checkpoint = input.checkpoint;
|
|
1022
1729
|
var probe = input.probe || buildResolveIOAIManagerRecoveryEvidenceProbe({
|
|
@@ -1048,6 +1755,15 @@ function buildResolveIOAIManagerRecoveryActionPacket(input) {
|
|
|
1048
1755
|
publishStatus: checkpoint.lane
|
|
1049
1756
|
})
|
|
1050
1757
|
: undefined;
|
|
1758
|
+
var allowedDispatchAction = dispatchActionForMode(mode);
|
|
1759
|
+
var requiredStateTransition = recoveryActionRequiredStateTransition(mode);
|
|
1760
|
+
var proofRequiredBeforeContinuation = recoveryActionProofRequiredBeforeContinuation(mode);
|
|
1761
|
+
var exitCriteria = recoveryActionExitCriteria({
|
|
1762
|
+
mode: mode,
|
|
1763
|
+
dispatchAction: allowedDispatchAction,
|
|
1764
|
+
requiredStateTransition: requiredStateTransition,
|
|
1765
|
+
stopWhen: stopWhen
|
|
1766
|
+
});
|
|
1051
1767
|
var now = isoNow(input.now);
|
|
1052
1768
|
return __assign(__assign(__assign({ actionId: stableHash('mgr-action', {
|
|
1053
1769
|
checkpointId: checkpoint.checkpointId,
|
|
@@ -1055,13 +1771,13 @@ function buildResolveIOAIManagerRecoveryActionPacket(input) {
|
|
|
1055
1771
|
mode: mode,
|
|
1056
1772
|
evidenceHash: checkpoint.evidenceHash,
|
|
1057
1773
|
blockerFingerprint: checkpoint.blockerFingerprint
|
|
1058
|
-
}), checkpointId: checkpoint.checkpointId, probeId: probe.probeId, recoveryClass: checkpoint.recoveryClass, mode: mode, label: recoveryActionLabelFor(mode, checkpoint), lane: checkpoint.lane, stepType: checkpoint.stepType, primaryStepKind: (primaryStep === null || primaryStep === void 0 ? void 0 : primaryStep.kind) || 'none', objective: mode === 'collect_evidence'
|
|
1774
|
+
}), checkpointId: checkpoint.checkpointId, probeId: probe.probeId, recoveryClass: checkpoint.recoveryClass, mode: mode, singleActionOnly: true, allowedDispatchAction: allowedDispatchAction, label: recoveryActionLabelFor(mode, checkpoint), lane: checkpoint.lane, stepType: checkpoint.stepType, primaryStepKind: (primaryStep === null || primaryStep === void 0 ? void 0 : primaryStep.kind) || 'none', objective: mode === 'collect_evidence'
|
|
1059
1775
|
? probe.objective
|
|
1060
|
-
: cleanText(checkpoint.objective || probe.objective, 1000), evidenceOnly: evidenceOnly, autoRunnable: recoveryActionAutoRunnable(mode, probe), productRepairAllowed: checkpoint.productRepairAllowed && !evidenceOnly && checkpoint.status !== 'parked', expensiveModelAllowed: checkpoint.expensiveModelAllowed && checkpoint.status !== 'parked', canResetLoopAfterEvidence: resetLoopWhen.length > 0, maxAttemptsBeforePark: checkpoint.maxAttemptsBeforePark, requiredArtifacts: probe.requiredArtifacts.slice(0, 20), nextCommands: releasePolicy
|
|
1776
|
+
: cleanText(checkpoint.objective || probe.objective, 1000), evidenceOnly: evidenceOnly, autoRunnable: recoveryActionAutoRunnable(mode, probe), productRepairAllowed: checkpoint.productRepairAllowed && !evidenceOnly && checkpoint.status !== 'parked', expensiveModelAllowed: checkpoint.expensiveModelAllowed && checkpoint.status !== 'parked', costCeilingUsd: recoveryActionCostCeilingUsd(mode), requiredStateTransition: requiredStateTransition, proofRequiredBeforeContinuation: proofRequiredBeforeContinuation, canResetLoopAfterEvidence: resetLoopWhen.length > 0, maxAttemptsBeforePark: checkpoint.maxAttemptsBeforePark, requiredArtifacts: probe.requiredArtifacts.slice(0, 20), nextCommands: releasePolicy
|
|
1061
1777
|
? Array.from(new Set(__spreadArray(__spreadArray([], __read(nextCommands), false), __read(releasePolicy.allowedActions), false))).slice(0, 12)
|
|
1062
1778
|
: nextCommands, successCriteria: releasePolicy
|
|
1063
1779
|
? Array.from(new Set(__spreadArray(__spreadArray([], __read(probe.acceptanceEvidence), false), __read(releasePolicy.requiredEvidence), false))).slice(0, 20)
|
|
1064
|
-
: probe.acceptanceEvidence.slice(0, 20), retryPolicy: {
|
|
1780
|
+
: probe.acceptanceEvidence.slice(0, 20), exitCriteria: exitCriteria, retryPolicy: {
|
|
1065
1781
|
allowImmediateRetry: checkpoint.status !== 'parked' && mode !== 'manual_review',
|
|
1066
1782
|
requireNewEvidence: requireNewEvidence,
|
|
1067
1783
|
resetLoopWhen: resetLoopWhen,
|
|
@@ -1098,6 +1814,7 @@ function buildRecoveryDispatchRecord(action, dispatchAction, status, reason, cur
|
|
|
1098
1814
|
}), actionId: action.actionId, checkpointId: action.checkpointId, probeId: action.probeId, mode: action.mode, dispatchAction: dispatchAction, status: status, evidenceHash: evidenceHash, blockerFingerprint: blockerFingerprint, productRepairAllowed: action.productRepairAllowed && dispatchAction === 'run_targeted_product_repair', expensiveModelAllowed: action.expensiveModelAllowed && dispatchAction !== 'run_evidence_probe', reason: reason, artifactPaths: artifactPaths }, (status === 'started' ? { startedAt: createdAt } : {})), (status === 'completed' ? { completedAt: createdAt } : {})), { createdAt: createdAt });
|
|
1099
1815
|
}
|
|
1100
1816
|
function decideResolveIOAIManagerRecoveryActionDispatch(input) {
|
|
1817
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
1101
1818
|
var action = input.action;
|
|
1102
1819
|
var history = Array.isArray(input.history) ? input.history.filter(Boolean).slice(-50) : [];
|
|
1103
1820
|
var current = input.current || {};
|
|
@@ -1115,6 +1832,7 @@ function decideResolveIOAIManagerRecoveryActionDispatch(input) {
|
|
|
1115
1832
|
};
|
|
1116
1833
|
}
|
|
1117
1834
|
var dispatchAction = dispatchActionForMode(action.mode);
|
|
1835
|
+
var allowedDispatchAction = action.allowedDispatchAction || dispatchAction;
|
|
1118
1836
|
var evidenceHash = current.evidenceHash || action.checkpointId || action.actionId;
|
|
1119
1837
|
var blockerFingerprint = resolveResolveIOAIManagerBlockerFingerprint(current, action.objective);
|
|
1120
1838
|
var sameActionHistory = history.filter(function (entry) { return entry.actionId === action.actionId; });
|
|
@@ -1124,11 +1842,20 @@ function decideResolveIOAIManagerRecoveryActionDispatch(input) {
|
|
|
1124
1842
|
var completedDispatch = sameEvidenceHistory.find(function (entry) { return entry.status === 'completed' || entry.status === 'failed'; });
|
|
1125
1843
|
var newEvidence = sameActionHistory.length > 0 && sameEvidenceHistory.length === 0;
|
|
1126
1844
|
var requiresNewEvidence = action.retryPolicy.requireNewEvidence === true;
|
|
1845
|
+
var sameEvidenceAlreadyAttempted = !!completedDispatch && requiresNewEvidence && !newEvidence;
|
|
1127
1846
|
var manualOnly = action.mode === 'manual_review' || !action.autoRunnable;
|
|
1128
1847
|
var productDispatch = dispatchAction === 'run_targeted_product_repair';
|
|
1129
1848
|
var expensiveDispatch = !['run_evidence_probe', 'advance', 'continue_gate', 'park_manual'].includes(dispatchAction);
|
|
1130
|
-
|
|
1131
|
-
|
|
1849
|
+
var evidenceAssessment = assessResolveIOAIManagerEvidenceChange(undefined, current, action.objective);
|
|
1850
|
+
var autonomyPolicy = input.autonomyPolicy
|
|
1851
|
+
? decideResolveIOAIManagerAutonomyPolicy(__assign(__assign({}, (input.autonomyPolicy || {})), { dispatchAction: dispatchAction, projectedActionCostUsd: (_b = (_a = input.autonomyPolicy) === null || _a === void 0 ? void 0 : _a.projectedActionCostUsd) !== null && _b !== void 0 ? _b : action.costCeilingUsd, newEvidence: (_d = (_c = input.autonomyPolicy) === null || _c === void 0 ? void 0 : _c.newEvidence) !== null && _d !== void 0 ? _d : newEvidence, materialEvidence: (_f = (_e = input.autonomyPolicy) === null || _e === void 0 ? void 0 : _e.materialEvidence) !== null && _f !== void 0 ? _f : evidenceAssessment.material, evidenceStrength: (_h = (_g = input.autonomyPolicy) === null || _g === void 0 ? void 0 : _g.evidenceStrength) !== null && _h !== void 0 ? _h : evidenceAssessment.strength, evidenceSignals: (_k = (_j = input.autonomyPolicy) === null || _j === void 0 ? void 0 : _j.evidenceSignals) !== null && _k !== void 0 ? _k : evidenceAssessment.signals, sameEvidenceAlreadyAttempted: (_m = (_l = input.autonomyPolicy) === null || _l === void 0 ? void 0 : _l.sameEvidenceAlreadyAttempted) !== null && _m !== void 0 ? _m : sameEvidenceAlreadyAttempted, operatorApproved: input.operatorApproved }))
|
|
1852
|
+
: undefined;
|
|
1853
|
+
var autonomyBlocksDispatch = !!autonomyPolicy && (autonomyPolicy.mode === 'monitor_only'
|
|
1854
|
+
|| (autonomyPolicy.requiresHumanApproval === true && input.operatorApproved !== true)
|
|
1855
|
+
|| (autonomyPolicy.canAutoDispatch !== true && input.operatorApproved !== true)
|
|
1856
|
+
|| (autonomyPolicy.blocked === true && autonomyPolicy.canManualDispatch !== true));
|
|
1857
|
+
if (autonomyBlocksDispatch) {
|
|
1858
|
+
var record_1 = buildRecoveryDispatchRecord(action, 'park_manual', 'parked', "recovery_dispatch_blocked_by_autonomy_policy:".concat((autonomyPolicy === null || autonomyPolicy === void 0 ? void 0 : autonomyPolicy.reason) || 'unknown'), current, input.now);
|
|
1132
1859
|
return {
|
|
1133
1860
|
dispatchAction: 'park_manual',
|
|
1134
1861
|
allowed: false,
|
|
@@ -1139,11 +1866,12 @@ function decideResolveIOAIManagerRecoveryActionDispatch(input) {
|
|
|
1139
1866
|
shouldRecordDispatch: true,
|
|
1140
1867
|
requiresNewEvidence: requiresNewEvidence,
|
|
1141
1868
|
newEvidence: newEvidence,
|
|
1869
|
+
autonomyPolicy: autonomyPolicy,
|
|
1142
1870
|
dispatchRecord: record_1
|
|
1143
1871
|
};
|
|
1144
1872
|
}
|
|
1145
|
-
if (
|
|
1146
|
-
var record_2 = buildRecoveryDispatchRecord(action, 'park_manual', 'parked', '
|
|
1873
|
+
if (action.singleActionOnly === true && allowedDispatchAction !== dispatchAction) {
|
|
1874
|
+
var record_2 = buildRecoveryDispatchRecord(action, 'park_manual', 'parked', 'recovery_dispatch_action_not_in_packet_contract', current, input.now);
|
|
1147
1875
|
return {
|
|
1148
1876
|
dispatchAction: 'park_manual',
|
|
1149
1877
|
allowed: false,
|
|
@@ -1154,9 +1882,42 @@ function decideResolveIOAIManagerRecoveryActionDispatch(input) {
|
|
|
1154
1882
|
shouldRecordDispatch: true,
|
|
1155
1883
|
requiresNewEvidence: true,
|
|
1156
1884
|
newEvidence: newEvidence,
|
|
1885
|
+
autonomyPolicy: autonomyPolicy,
|
|
1157
1886
|
dispatchRecord: record_2
|
|
1158
1887
|
};
|
|
1159
1888
|
}
|
|
1889
|
+
if (manualOnly && input.operatorApproved !== true) {
|
|
1890
|
+
var record_3 = buildRecoveryDispatchRecord(action, 'park_manual', 'parked', 'recovery_dispatch_requires_manual_review', current, input.now);
|
|
1891
|
+
return {
|
|
1892
|
+
dispatchAction: 'park_manual',
|
|
1893
|
+
allowed: false,
|
|
1894
|
+
reason: record_3.reason,
|
|
1895
|
+
status: 'parked',
|
|
1896
|
+
canRunProductRepair: false,
|
|
1897
|
+
canRunExpensiveModel: false,
|
|
1898
|
+
shouldRecordDispatch: true,
|
|
1899
|
+
requiresNewEvidence: requiresNewEvidence,
|
|
1900
|
+
newEvidence: newEvidence,
|
|
1901
|
+
autonomyPolicy: autonomyPolicy,
|
|
1902
|
+
dispatchRecord: record_3
|
|
1903
|
+
};
|
|
1904
|
+
}
|
|
1905
|
+
if (productDispatch && action.productRepairAllowed !== true) {
|
|
1906
|
+
var record_4 = buildRecoveryDispatchRecord(action, 'park_manual', 'parked', 'recovery_dispatch_product_repair_not_allowed', current, input.now);
|
|
1907
|
+
return {
|
|
1908
|
+
dispatchAction: 'park_manual',
|
|
1909
|
+
allowed: false,
|
|
1910
|
+
reason: record_4.reason,
|
|
1911
|
+
status: 'parked',
|
|
1912
|
+
canRunProductRepair: false,
|
|
1913
|
+
canRunExpensiveModel: false,
|
|
1914
|
+
shouldRecordDispatch: true,
|
|
1915
|
+
requiresNewEvidence: true,
|
|
1916
|
+
newEvidence: newEvidence,
|
|
1917
|
+
autonomyPolicy: autonomyPolicy,
|
|
1918
|
+
dispatchRecord: record_4
|
|
1919
|
+
};
|
|
1920
|
+
}
|
|
1160
1921
|
if (activeDispatch) {
|
|
1161
1922
|
return {
|
|
1162
1923
|
dispatchAction: 'park_manual',
|
|
@@ -1167,22 +1928,24 @@ function decideResolveIOAIManagerRecoveryActionDispatch(input) {
|
|
|
1167
1928
|
canRunExpensiveModel: false,
|
|
1168
1929
|
shouldRecordDispatch: false,
|
|
1169
1930
|
requiresNewEvidence: true,
|
|
1170
|
-
newEvidence: false
|
|
1931
|
+
newEvidence: false,
|
|
1932
|
+
autonomyPolicy: autonomyPolicy
|
|
1171
1933
|
};
|
|
1172
1934
|
}
|
|
1173
|
-
if (
|
|
1174
|
-
var
|
|
1935
|
+
if (sameEvidenceAlreadyAttempted) {
|
|
1936
|
+
var record_5 = buildRecoveryDispatchRecord(action, 'park_manual', 'parked', 'recovery_dispatch_same_evidence_already_attempted', current, input.now);
|
|
1175
1937
|
return {
|
|
1176
1938
|
dispatchAction: 'park_manual',
|
|
1177
1939
|
allowed: false,
|
|
1178
|
-
reason:
|
|
1940
|
+
reason: record_5.reason,
|
|
1179
1941
|
status: 'parked',
|
|
1180
1942
|
canRunProductRepair: false,
|
|
1181
1943
|
canRunExpensiveModel: false,
|
|
1182
1944
|
shouldRecordDispatch: true,
|
|
1183
1945
|
requiresNewEvidence: true,
|
|
1184
1946
|
newEvidence: false,
|
|
1185
|
-
|
|
1947
|
+
autonomyPolicy: autonomyPolicy,
|
|
1948
|
+
dispatchRecord: record_5
|
|
1186
1949
|
};
|
|
1187
1950
|
}
|
|
1188
1951
|
var status = dispatchAction === 'advance' || dispatchAction === 'continue_gate'
|
|
@@ -1199,6 +1962,7 @@ function decideResolveIOAIManagerRecoveryActionDispatch(input) {
|
|
|
1199
1962
|
shouldRecordDispatch: true,
|
|
1200
1963
|
requiresNewEvidence: requiresNewEvidence,
|
|
1201
1964
|
newEvidence: newEvidence,
|
|
1965
|
+
autonomyPolicy: autonomyPolicy,
|
|
1202
1966
|
dispatchRecord: record
|
|
1203
1967
|
};
|
|
1204
1968
|
}
|
|
@@ -1245,6 +2009,7 @@ function buildResolveIOAIManagerRecoveryExecutionDirective(input) {
|
|
|
1245
2009
|
var dispatchDecision = input.dispatchDecision || decideResolveIOAIManagerRecoveryActionDispatch({
|
|
1246
2010
|
action: action,
|
|
1247
2011
|
current: input.current,
|
|
2012
|
+
autonomyPolicy: input.autonomyPolicy,
|
|
1248
2013
|
now: input.now
|
|
1249
2014
|
});
|
|
1250
2015
|
var dispatchAction = dispatchDecision.dispatchAction;
|
|
@@ -1254,17 +2019,17 @@ function buildResolveIOAIManagerRecoveryExecutionDirective(input) {
|
|
|
1254
2019
|
var stepType = cleanText((action === null || action === void 0 ? void 0 : action.stepType) || ((_b = input.current) === null || _b === void 0 ? void 0 : _b.stepType) || '', 120);
|
|
1255
2020
|
var rerunReason = recoveryDirectiveReason(action, dispatchDecision, input.current);
|
|
1256
2021
|
var surface = cleanText(input.surface || 'runner', 120);
|
|
1257
|
-
return __assign(__assign(__assign({ directiveId: stableHash('mgr-directive', {
|
|
2022
|
+
return __assign(__assign(__assign(__assign(__assign({ directiveId: stableHash('mgr-directive', {
|
|
1258
2023
|
surface: surface,
|
|
1259
2024
|
actionId: (action === null || action === void 0 ? void 0 : action.actionId) || '',
|
|
1260
2025
|
dispatchAction: dispatchAction,
|
|
1261
2026
|
reason: dispatchDecision.reason,
|
|
1262
2027
|
evidenceHash: ((_c = dispatchDecision.dispatchRecord) === null || _c === void 0 ? void 0 : _c.evidenceHash) || ((_d = input.current) === null || _d === void 0 ? void 0 : _d.evidenceHash) || ''
|
|
1263
|
-
}), surface: surface, dispatchAction: dispatchAction, phase: phase, allowed: dispatchDecision.allowed, status: dispatchDecision.status, reason: dispatchDecision.reason, lane: lane, stepType: stepType, nextActionLabel: cleanText(action === null || action === void 0 ? void 0 : action.label, 160) || dispatchAction, rerunReason: rerunReason, evidenceOnly: (action === null || action === void 0 ? void 0 : action.evidenceOnly) !== false || dispatchAction === 'run_evidence_probe', autoRunnable: (action === null || action === void 0 ? void 0 : action.autoRunnable) === true, productRepairAllowed: (action === null || action === void 0 ? void 0 : action.productRepairAllowed) === true, expensiveModelAllowed: (action === null || action === void 0 ? void 0 : action.expensiveModelAllowed) === true, canRunProductRepair: dispatchDecision.canRunProductRepair, canRunExpensiveModel: dispatchDecision.canRunExpensiveModel, canResetLoopAfterEvidence: (action === null || action === void 0 ? void 0 : action.canResetLoopAfterEvidence) === true, requiresNewEvidence: dispatchDecision.requiresNewEvidence, newEvidence: dispatchDecision.newEvidence, maxAttemptsBeforePark: Math.max(1, Number((action === null || action === void 0 ? void 0 : action.maxAttemptsBeforePark) || 1) || 1), requiredArtifacts: cleanList(action === null || action === void 0 ? void 0 : action.requiredArtifacts, 20, 500), nextCommands: cleanList(action === null || action === void 0 ? void 0 : action.nextCommands, 20, 500), successCriteria: cleanList(action === null || action === void 0 ? void 0 : action.successCriteria, 20, 500), forbiddenActions: (action === null || action === void 0 ? void 0 : action.productRepairAllowed) === true
|
|
2028
|
+
}), surface: surface, dispatchAction: dispatchAction, phase: phase, allowed: dispatchDecision.allowed, status: dispatchDecision.status, reason: dispatchDecision.reason, singleActionOnly: (action === null || action === void 0 ? void 0 : action.singleActionOnly) !== false, allowedDispatchAction: (action === null || action === void 0 ? void 0 : action.allowedDispatchAction) || dispatchAction, lane: lane, stepType: stepType, nextActionLabel: cleanText(action === null || action === void 0 ? void 0 : action.label, 160) || dispatchAction, rerunReason: rerunReason, evidenceOnly: (action === null || action === void 0 ? void 0 : action.evidenceOnly) !== false || dispatchAction === 'run_evidence_probe', autoRunnable: (action === null || action === void 0 ? void 0 : action.autoRunnable) === true, productRepairAllowed: (action === null || action === void 0 ? void 0 : action.productRepairAllowed) === true, expensiveModelAllowed: (action === null || action === void 0 ? void 0 : action.expensiveModelAllowed) === true, costCeilingUsd: Math.max(0, Number((action === null || action === void 0 ? void 0 : action.costCeilingUsd) || 0) || 0), requiredStateTransition: cleanText(action === null || action === void 0 ? void 0 : action.requiredStateTransition, 500), proofRequiredBeforeContinuation: (action === null || action === void 0 ? void 0 : action.proofRequiredBeforeContinuation) === true, canRunProductRepair: dispatchDecision.canRunProductRepair, canRunExpensiveModel: dispatchDecision.canRunExpensiveModel, canResetLoopAfterEvidence: (action === null || action === void 0 ? void 0 : action.canResetLoopAfterEvidence) === true, requiresNewEvidence: dispatchDecision.requiresNewEvidence, newEvidence: dispatchDecision.newEvidence }, (dispatchDecision.autonomyPolicy ? { autonomyPolicy: dispatchDecision.autonomyPolicy } : {})), { maxAttemptsBeforePark: Math.max(1, Number((action === null || action === void 0 ? void 0 : action.maxAttemptsBeforePark) || 1) || 1), requiredArtifacts: cleanList(action === null || action === void 0 ? void 0 : action.requiredArtifacts, 20, 500), nextCommands: cleanList(action === null || action === void 0 ? void 0 : action.nextCommands, 20, 500), successCriteria: cleanList(action === null || action === void 0 ? void 0 : action.successCriteria, 20, 500), exitCriteria: cleanList(action === null || action === void 0 ? void 0 : action.exitCriteria, 30, 500), forbiddenActions: (action === null || action === void 0 ? void 0 : action.productRepairAllowed) === true
|
|
1264
2029
|
? []
|
|
1265
2030
|
: Array.from(new Set(__spreadArray([
|
|
1266
2031
|
'Do not run product-code repair from this directive unless canRunProductRepair is true.'
|
|
1267
|
-
], __read((((_e = action === null || action === void 0 ? void 0 : action.releasePolicy) === null || _e === void 0 ? void 0 : _e.forbiddenActions) || [])), false))).slice(0, 20) }, (dispatchDecision.dispatchRecord ? { dispatchRecord: dispatchDecision.dispatchRecord } : {})), ((action === null || action === void 0 ? void 0 : action.releasePolicy) ? { releasePolicy: action.releasePolicy } : {})), { createdAt: now });
|
|
2032
|
+
], __read((((_e = action === null || action === void 0 ? void 0 : action.releasePolicy) === null || _e === void 0 ? void 0 : _e.forbiddenActions) || [])), false))).slice(0, 20) }), (dispatchDecision.dispatchRecord ? { dispatchRecord: dispatchDecision.dispatchRecord } : {})), ((action === null || action === void 0 ? void 0 : action.releasePolicy) ? { releasePolicy: action.releasePolicy } : {})), { createdAt: now });
|
|
1268
2033
|
}
|
|
1269
2034
|
function newListEntries(current, previous) {
|
|
1270
2035
|
var existing = new Set(previous.map(function (entry) { return cleanText(entry, 500); }).filter(Boolean));
|