@resolveio/server-lib 22.3.131 → 22.3.133
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/util/ai-runner-manager-policy.d.ts +88 -0
- package/util/ai-runner-manager-policy.js +328 -9
- package/util/ai-runner-manager-policy.js.map +1 -1
- package/util/aicoder-runner-v6.d.ts +3 -0
- package/util/aicoder-runner-v6.js +57 -11
- package/util/aicoder-runner-v6.js.map +1 -1
- package/util/support-runner-v5.d.ts +5 -0
- package/util/support-runner-v5.js +78 -9
- package/util/support-runner-v5.js.map +1 -1
package/package.json
CHANGED
|
@@ -12,6 +12,89 @@ export interface ResolveIOAIManagerFailureRecord {
|
|
|
12
12
|
summary?: string;
|
|
13
13
|
recordedAt?: Date | string;
|
|
14
14
|
}
|
|
15
|
+
export type ResolveIOAIManagerRecoveryClass = 'advance_after_proof' | 'diagnosis_only' | 'diagnosis_revision' | 'infra_repair' | 'compile_repair' | 'journey_contract_repair' | 'business_proof_repair' | 'release_repair' | 'product_code_repair' | 'blocked_until_new_evidence' | 'manual_handoff' | 'continue';
|
|
16
|
+
export interface ResolveIOAIManagerRecoveryPlan {
|
|
17
|
+
recoveryClass: ResolveIOAIManagerRecoveryClass;
|
|
18
|
+
lane: string;
|
|
19
|
+
stepType: string;
|
|
20
|
+
nextActionLabel: string;
|
|
21
|
+
objective: string;
|
|
22
|
+
allowedAction: string;
|
|
23
|
+
productRepairAllowed: boolean;
|
|
24
|
+
expensiveModelAllowed: boolean;
|
|
25
|
+
maxAttemptsBeforePark: number;
|
|
26
|
+
finiteSteps: string[];
|
|
27
|
+
requiredEvidence: string[];
|
|
28
|
+
loopResetEvidence: string[];
|
|
29
|
+
forbiddenActions: string[];
|
|
30
|
+
notes: string[];
|
|
31
|
+
}
|
|
32
|
+
export type ResolveIOAIManagerRecoveryCheckpointStatus = 'active' | 'parked' | 'manual_handoff' | 'complete';
|
|
33
|
+
export interface ResolveIOAIManagerRecoveryCheckpoint {
|
|
34
|
+
checkpointId: string;
|
|
35
|
+
recoveryClass: ResolveIOAIManagerRecoveryClass;
|
|
36
|
+
status: ResolveIOAIManagerRecoveryCheckpointStatus;
|
|
37
|
+
lane: string;
|
|
38
|
+
stepType: string;
|
|
39
|
+
allowedAction: string;
|
|
40
|
+
productRepairAllowed: boolean;
|
|
41
|
+
expensiveModelAllowed: boolean;
|
|
42
|
+
attempts: number;
|
|
43
|
+
maxAttemptsBeforePark: number;
|
|
44
|
+
blockerFingerprint: string;
|
|
45
|
+
evidenceHash: string;
|
|
46
|
+
changedFiles: string[];
|
|
47
|
+
artifactPaths: string[];
|
|
48
|
+
requiredEvidence: string[];
|
|
49
|
+
loopResetEvidence: string[];
|
|
50
|
+
forbiddenActions: string[];
|
|
51
|
+
objective: string;
|
|
52
|
+
nextActionLabel: string;
|
|
53
|
+
createdAt: string;
|
|
54
|
+
updatedAt: string;
|
|
55
|
+
}
|
|
56
|
+
export interface ResolveIOAIManagerRecoveryCheckpointInput {
|
|
57
|
+
plan: ResolveIOAIManagerRecoveryPlan;
|
|
58
|
+
current?: ResolveIOAIManagerFailureRecord;
|
|
59
|
+
previousCheckpoint?: ResolveIOAIManagerRecoveryCheckpoint;
|
|
60
|
+
now?: Date | string;
|
|
61
|
+
}
|
|
62
|
+
export type ResolveIOAIManagerRecoveryGateAction = 'allow' | 'collect_new_evidence' | 'reject_action' | 'manual_handoff' | 'complete';
|
|
63
|
+
export interface ResolveIOAIManagerRecoveryGateInput {
|
|
64
|
+
checkpoint: ResolveIOAIManagerRecoveryCheckpoint;
|
|
65
|
+
current?: ResolveIOAIManagerFailureRecord;
|
|
66
|
+
proposedAction?: string;
|
|
67
|
+
operatorApproved?: boolean;
|
|
68
|
+
now?: Date | string;
|
|
69
|
+
}
|
|
70
|
+
export interface ResolveIOAIManagerRecoveryGateDecision {
|
|
71
|
+
action: ResolveIOAIManagerRecoveryGateAction;
|
|
72
|
+
reason: string;
|
|
73
|
+
canRunProductRepair: boolean;
|
|
74
|
+
canRunExpensiveModel: boolean;
|
|
75
|
+
shouldResetLoopBudget: boolean;
|
|
76
|
+
shouldIncrementAttempt: boolean;
|
|
77
|
+
newEvidence: boolean;
|
|
78
|
+
blockerFingerprint: string;
|
|
79
|
+
evidenceHash: string;
|
|
80
|
+
missingEvidence: string[];
|
|
81
|
+
checkpoint: ResolveIOAIManagerRecoveryCheckpoint;
|
|
82
|
+
}
|
|
83
|
+
export interface ResolveIOAIManagerRecoveryPlanInput {
|
|
84
|
+
action?: ResolveIOAIManagerAction | string;
|
|
85
|
+
reason?: string;
|
|
86
|
+
failureClass?: string;
|
|
87
|
+
lane?: string;
|
|
88
|
+
stepType?: string;
|
|
89
|
+
blocker?: string;
|
|
90
|
+
sameFailureCount?: number;
|
|
91
|
+
pingPongCount?: number;
|
|
92
|
+
newEvidence?: boolean;
|
|
93
|
+
productRepairFailure?: boolean;
|
|
94
|
+
changedFiles?: string[];
|
|
95
|
+
artifactPaths?: string[];
|
|
96
|
+
maxSameFailureRepeats?: number;
|
|
97
|
+
}
|
|
15
98
|
export interface ResolveIOAIManagerPolicyInput {
|
|
16
99
|
history?: ResolveIOAIManagerFailureRecord[];
|
|
17
100
|
current?: ResolveIOAIManagerFailureRecord;
|
|
@@ -31,8 +114,13 @@ export interface ResolveIOAIManagerPolicyDecision {
|
|
|
31
114
|
newEvidence: boolean;
|
|
32
115
|
loopBudgetShouldReset: boolean;
|
|
33
116
|
productRepairFailure: boolean;
|
|
117
|
+
recoveryPlan: ResolveIOAIManagerRecoveryPlan;
|
|
118
|
+
recoveryCheckpoint: ResolveIOAIManagerRecoveryCheckpoint;
|
|
34
119
|
}
|
|
35
120
|
export declare function normalizeResolveIOAIManagerFailureClass(value: any): string;
|
|
36
121
|
export declare function fingerprintResolveIOAIManagerBlocker(value: any): string;
|
|
37
122
|
export declare function hashResolveIOAIManagerEvidence(record: ResolveIOAIManagerFailureRecord | undefined): string;
|
|
123
|
+
export declare function buildResolveIOAIManagerRecoveryCheckpoint(input: ResolveIOAIManagerRecoveryCheckpointInput): ResolveIOAIManagerRecoveryCheckpoint;
|
|
124
|
+
export declare function decideResolveIOAIManagerRecoveryGate(input: ResolveIOAIManagerRecoveryGateInput): ResolveIOAIManagerRecoveryGateDecision;
|
|
125
|
+
export declare function buildResolveIOAIManagerRecoveryPlan(input?: ResolveIOAIManagerRecoveryPlanInput): ResolveIOAIManagerRecoveryPlan;
|
|
38
126
|
export declare function decideResolveIOAIManagerPolicy(input: ResolveIOAIManagerPolicyInput): ResolveIOAIManagerPolicyDecision;
|
|
@@ -25,6 +25,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
25
25
|
exports.normalizeResolveIOAIManagerFailureClass = normalizeResolveIOAIManagerFailureClass;
|
|
26
26
|
exports.fingerprintResolveIOAIManagerBlocker = fingerprintResolveIOAIManagerBlocker;
|
|
27
27
|
exports.hashResolveIOAIManagerEvidence = hashResolveIOAIManagerEvidence;
|
|
28
|
+
exports.buildResolveIOAIManagerRecoveryCheckpoint = buildResolveIOAIManagerRecoveryCheckpoint;
|
|
29
|
+
exports.decideResolveIOAIManagerRecoveryGate = decideResolveIOAIManagerRecoveryGate;
|
|
30
|
+
exports.buildResolveIOAIManagerRecoveryPlan = buildResolveIOAIManagerRecoveryPlan;
|
|
28
31
|
exports.decideResolveIOAIManagerPolicy = decideResolveIOAIManagerPolicy;
|
|
29
32
|
function cleanText(value, max) {
|
|
30
33
|
if (max === void 0) { max = 2000; }
|
|
@@ -59,6 +62,16 @@ function cleanList(values, limit, max) {
|
|
|
59
62
|
}
|
|
60
63
|
return result;
|
|
61
64
|
}
|
|
65
|
+
function isoNow(value) {
|
|
66
|
+
if (value instanceof Date) {
|
|
67
|
+
return value.toISOString();
|
|
68
|
+
}
|
|
69
|
+
var parsed = value ? new Date(value) : new Date();
|
|
70
|
+
if (Number.isFinite(parsed.getTime())) {
|
|
71
|
+
return parsed.toISOString();
|
|
72
|
+
}
|
|
73
|
+
return new Date().toISOString();
|
|
74
|
+
}
|
|
62
75
|
function stableHash(prefix, value) {
|
|
63
76
|
var normalized = typeof value === 'string'
|
|
64
77
|
? cleanText(value, 12000)
|
|
@@ -113,6 +126,152 @@ function hashResolveIOAIManagerEvidence(record) {
|
|
|
113
126
|
artifactPaths: cleanList(record.artifactPaths, 80, 500).sort()
|
|
114
127
|
});
|
|
115
128
|
}
|
|
129
|
+
function buildResolveIOAIManagerRecoveryCheckpoint(input) {
|
|
130
|
+
var plan = input.plan;
|
|
131
|
+
var current = input.current || {};
|
|
132
|
+
var blockerFingerprint = cleanText(current.blockerFingerprint, 120)
|
|
133
|
+
|| fingerprintResolveIOAIManagerBlocker(current.blocker || current.summary || plan.objective || '');
|
|
134
|
+
var evidenceHash = hashResolveIOAIManagerEvidence(current);
|
|
135
|
+
var changedFiles = cleanList(current.changedFiles, 80, 500);
|
|
136
|
+
var artifactPaths = cleanList(current.artifactPaths, 80, 500);
|
|
137
|
+
var previous = input.previousCheckpoint;
|
|
138
|
+
var sameCheckpointBase = previous
|
|
139
|
+
&& previous.recoveryClass === plan.recoveryClass
|
|
140
|
+
&& previous.lane === plan.lane
|
|
141
|
+
&& previous.stepType === plan.stepType
|
|
142
|
+
&& previous.blockerFingerprint === blockerFingerprint
|
|
143
|
+
&& previous.evidenceHash === evidenceHash;
|
|
144
|
+
var attempts = sameCheckpointBase ? Math.max(0, Number(previous.attempts || 0)) + 1 : 1;
|
|
145
|
+
var status = plan.recoveryClass === 'manual_handoff'
|
|
146
|
+
? 'manual_handoff'
|
|
147
|
+
: plan.recoveryClass === 'blocked_until_new_evidence'
|
|
148
|
+
? 'parked'
|
|
149
|
+
: plan.recoveryClass === 'advance_after_proof'
|
|
150
|
+
? 'complete'
|
|
151
|
+
: 'active';
|
|
152
|
+
var now = isoNow(input.now);
|
|
153
|
+
var checkpointId = stableHash('mgr-recovery', {
|
|
154
|
+
recoveryClass: plan.recoveryClass,
|
|
155
|
+
lane: plan.lane,
|
|
156
|
+
stepType: plan.stepType,
|
|
157
|
+
allowedAction: plan.allowedAction,
|
|
158
|
+
blockerFingerprint: blockerFingerprint,
|
|
159
|
+
evidenceHash: evidenceHash
|
|
160
|
+
});
|
|
161
|
+
return {
|
|
162
|
+
checkpointId: checkpointId,
|
|
163
|
+
recoveryClass: plan.recoveryClass,
|
|
164
|
+
status: status,
|
|
165
|
+
lane: plan.lane,
|
|
166
|
+
stepType: plan.stepType,
|
|
167
|
+
allowedAction: plan.allowedAction,
|
|
168
|
+
productRepairAllowed: plan.productRepairAllowed,
|
|
169
|
+
expensiveModelAllowed: plan.expensiveModelAllowed,
|
|
170
|
+
attempts: attempts,
|
|
171
|
+
maxAttemptsBeforePark: plan.maxAttemptsBeforePark,
|
|
172
|
+
blockerFingerprint: blockerFingerprint,
|
|
173
|
+
evidenceHash: evidenceHash,
|
|
174
|
+
changedFiles: changedFiles,
|
|
175
|
+
artifactPaths: artifactPaths,
|
|
176
|
+
requiredEvidence: cleanList(plan.requiredEvidence, 40, 500),
|
|
177
|
+
loopResetEvidence: cleanList(plan.loopResetEvidence, 40, 500),
|
|
178
|
+
forbiddenActions: cleanList(plan.forbiddenActions, 40, 500),
|
|
179
|
+
objective: cleanText(plan.objective, 1000),
|
|
180
|
+
nextActionLabel: cleanText(plan.nextActionLabel, 160),
|
|
181
|
+
createdAt: sameCheckpointBase && (previous === null || previous === void 0 ? void 0 : previous.createdAt) ? previous.createdAt : now,
|
|
182
|
+
updatedAt: now
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
function listHasNewEntry(current, previous) {
|
|
186
|
+
var existing = new Set(previous.map(function (entry) { return cleanText(entry, 500); }).filter(Boolean));
|
|
187
|
+
return current.some(function (entry) {
|
|
188
|
+
var normalized = cleanText(entry, 500);
|
|
189
|
+
return !!normalized && !existing.has(normalized);
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
function proposedActionIsProductRepair(value) {
|
|
193
|
+
var normalized = cleanText(value, 120);
|
|
194
|
+
return /product|code|repair|build|business|journey|workflow/i.test(normalized)
|
|
195
|
+
&& !/infra|compile|diagnosis|manual|evidence|release|publish/i.test(normalized);
|
|
196
|
+
}
|
|
197
|
+
function decideResolveIOAIManagerRecoveryGate(input) {
|
|
198
|
+
var checkpoint = input.checkpoint;
|
|
199
|
+
var current = input.current || {};
|
|
200
|
+
var blockerFingerprint = cleanText(current.blockerFingerprint, 120)
|
|
201
|
+
|| fingerprintResolveIOAIManagerBlocker(current.blocker || current.summary || checkpoint.objective || '');
|
|
202
|
+
var evidenceHash = hashResolveIOAIManagerEvidence(current);
|
|
203
|
+
var changedFiles = cleanList(current.changedFiles, 80, 500);
|
|
204
|
+
var artifactPaths = cleanList(current.artifactPaths, 80, 500);
|
|
205
|
+
var evidenceChanged = evidenceHash !== checkpoint.evidenceHash
|
|
206
|
+
|| blockerFingerprint !== checkpoint.blockerFingerprint
|
|
207
|
+
|| listHasNewEntry(changedFiles, checkpoint.changedFiles)
|
|
208
|
+
|| listHasNewEntry(artifactPaths, checkpoint.artifactPaths);
|
|
209
|
+
var proposedAction = cleanText(input.proposedAction || checkpoint.allowedAction, 120);
|
|
210
|
+
var productRepairRequested = proposedActionIsProductRepair(proposedAction);
|
|
211
|
+
var missingEvidence = checkpoint.requiredEvidence.filter(function (required) {
|
|
212
|
+
var normalized = cleanText(required, 120).toLowerCase();
|
|
213
|
+
if (!normalized) {
|
|
214
|
+
return false;
|
|
215
|
+
}
|
|
216
|
+
if (/artifact|log|proof|gate|evidence/.test(normalized)) {
|
|
217
|
+
return !artifactPaths.length && !current.evidenceHash;
|
|
218
|
+
}
|
|
219
|
+
if (/diff|changed files|owner|scope|file/.test(normalized)) {
|
|
220
|
+
return !changedFiles.length;
|
|
221
|
+
}
|
|
222
|
+
return false;
|
|
223
|
+
});
|
|
224
|
+
var makeDecision = function (action, reason, overrides) {
|
|
225
|
+
if (overrides === void 0) { overrides = {}; }
|
|
226
|
+
return (__assign({ action: action, reason: reason, canRunProductRepair: checkpoint.productRepairAllowed, canRunExpensiveModel: checkpoint.expensiveModelAllowed, shouldResetLoopBudget: false, shouldIncrementAttempt: action === 'allow', newEvidence: evidenceChanged, blockerFingerprint: blockerFingerprint, evidenceHash: evidenceHash, missingEvidence: missingEvidence, checkpoint: __assign(__assign({}, checkpoint), { updatedAt: isoNow(input.now) }) }, overrides));
|
|
227
|
+
};
|
|
228
|
+
if (checkpoint.status === 'complete') {
|
|
229
|
+
return makeDecision('complete', 'recovery_gate_checkpoint_already_complete', {
|
|
230
|
+
canRunProductRepair: false,
|
|
231
|
+
canRunExpensiveModel: false,
|
|
232
|
+
shouldIncrementAttempt: false
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
if (checkpoint.status === 'manual_handoff' && input.operatorApproved !== true) {
|
|
236
|
+
return makeDecision('manual_handoff', 'recovery_gate_manual_handoff_requires_operator_approval', {
|
|
237
|
+
canRunProductRepair: false,
|
|
238
|
+
canRunExpensiveModel: false,
|
|
239
|
+
shouldIncrementAttempt: false
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
if (productRepairRequested && !checkpoint.productRepairAllowed) {
|
|
243
|
+
return makeDecision('reject_action', 'recovery_gate_product_repair_not_allowed_for_checkpoint', {
|
|
244
|
+
canRunProductRepair: false,
|
|
245
|
+
canRunExpensiveModel: false,
|
|
246
|
+
shouldIncrementAttempt: false
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
if (checkpoint.status === 'parked' && !evidenceChanged) {
|
|
250
|
+
return makeDecision('collect_new_evidence', 'recovery_gate_parked_until_new_evidence', {
|
|
251
|
+
canRunProductRepair: false,
|
|
252
|
+
canRunExpensiveModel: false,
|
|
253
|
+
shouldIncrementAttempt: false
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
if (checkpoint.attempts >= checkpoint.maxAttemptsBeforePark && !evidenceChanged) {
|
|
257
|
+
return makeDecision('collect_new_evidence', 'recovery_gate_attempt_limit_requires_new_evidence', {
|
|
258
|
+
canRunProductRepair: false,
|
|
259
|
+
canRunExpensiveModel: false,
|
|
260
|
+
shouldIncrementAttempt: false
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
if (evidenceChanged) {
|
|
264
|
+
var currentFailureClass = normalizeResolveIOAIManagerFailureClass(current.failureClass);
|
|
265
|
+
var currentCanRunProductRepair = checkpoint.productRepairAllowed
|
|
266
|
+
|| !/^(infra|compile|diagnosis|release)$/i.test(currentFailureClass);
|
|
267
|
+
return makeDecision('allow', 'recovery_gate_new_evidence_unblocks_retry', {
|
|
268
|
+
canRunProductRepair: currentCanRunProductRepair,
|
|
269
|
+
canRunExpensiveModel: checkpoint.expensiveModelAllowed || currentCanRunProductRepair,
|
|
270
|
+
shouldResetLoopBudget: true
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
return makeDecision('allow', 'recovery_gate_action_allowed');
|
|
274
|
+
}
|
|
116
275
|
function failureKey(record) {
|
|
117
276
|
if (!record) {
|
|
118
277
|
return '';
|
|
@@ -131,6 +290,136 @@ function isPassingOutcome(record) {
|
|
|
131
290
|
function isManualOutcome(record) {
|
|
132
291
|
return /^(manual_handoff|park_manual|stopped)$/i.test(cleanText(record === null || record === void 0 ? void 0 : record.outcome, 80));
|
|
133
292
|
}
|
|
293
|
+
function buildResolveIOAIManagerRecoveryPlan(input) {
|
|
294
|
+
if (input === void 0) { input = {}; }
|
|
295
|
+
var action = cleanText(input.action, 80) || 'continue';
|
|
296
|
+
var reason = cleanText(input.reason, 240);
|
|
297
|
+
var failureClass = normalizeResolveIOAIManagerFailureClass(input.failureClass);
|
|
298
|
+
var lane = cleanText(input.lane, 80) || 'supervisor';
|
|
299
|
+
var stepType = cleanText(input.stepType, 80) || 'unknown';
|
|
300
|
+
var blocker = cleanText(input.blocker, 700);
|
|
301
|
+
var changedFiles = cleanList(input.changedFiles, 12, 240);
|
|
302
|
+
var artifactPaths = cleanList(input.artifactPaths, 12, 240);
|
|
303
|
+
var maxAttemptsBeforePark = Math.max(1, Number(input.maxSameFailureRepeats || 3) || 3);
|
|
304
|
+
var commonNotes = [
|
|
305
|
+
reason ? "policy_reason=".concat(reason) : '',
|
|
306
|
+
blocker ? "blocker=".concat(blocker) : '',
|
|
307
|
+
changedFiles.length ? "changed_files=".concat(changedFiles.join(', ')) : '',
|
|
308
|
+
artifactPaths.length ? "artifacts=".concat(artifactPaths.join(', ')) : ''
|
|
309
|
+
].filter(Boolean);
|
|
310
|
+
var base = {
|
|
311
|
+
lane: lane,
|
|
312
|
+
stepType: stepType,
|
|
313
|
+
maxAttemptsBeforePark: maxAttemptsBeforePark,
|
|
314
|
+
notes: commonNotes
|
|
315
|
+
};
|
|
316
|
+
var makePlan = function (recoveryClass, nextActionLabel, objective, allowedAction, productRepairAllowed, expensiveModelAllowed, finiteSteps, requiredEvidence, loopResetEvidence, forbiddenActions) { return (__assign(__assign({}, base), { recoveryClass: recoveryClass, nextActionLabel: nextActionLabel, objective: objective, allowedAction: allowedAction, productRepairAllowed: productRepairAllowed, expensiveModelAllowed: expensiveModelAllowed, finiteSteps: finiteSteps, requiredEvidence: requiredEvidence, loopResetEvidence: loopResetEvidence, forbiddenActions: forbiddenActions })); };
|
|
317
|
+
if (action === 'reset_loop_budget') {
|
|
318
|
+
return makePlan('advance_after_proof', 'Advance After Proof', 'Checkpoint the passing evidence and move to the next required gate.', 'advance_to_next_gate', false, false, [
|
|
319
|
+
'Record the passing artifact, changed files, and gate result.',
|
|
320
|
+
'Reset the loop counter because a real gate passed.',
|
|
321
|
+
'Select the next unmet deterministic gate instead of repeating the previous repair.'
|
|
322
|
+
], ['passing gate record', 'artifact or log proving the passed check'], ['new passing gate result', 'new business proof artifact'], ['rerun the same repair after a pass', 'mark accepted without the required downstream gate']);
|
|
323
|
+
}
|
|
324
|
+
if (action === 'manual_handoff') {
|
|
325
|
+
return makePlan('manual_handoff', 'Manual Review', 'Stop autonomous repair and expose the blocker, evidence, and last safe state.', 'manual_review_only', false, false, [
|
|
326
|
+
'Freeze further product-code edits.',
|
|
327
|
+
'Show the blocker fingerprint, evidence hash, and prior attempts.',
|
|
328
|
+
'Require a human edit to classification, scope, or retry policy before another model/code loop.'
|
|
329
|
+
], ['blocker fingerprint', 'evidence hash', 'attempt history'], ['manual policy change', 'new external evidence'], ['start another automatic model repair', 'hide the failed evidence']);
|
|
330
|
+
}
|
|
331
|
+
if (action === 'budget_stop') {
|
|
332
|
+
return makePlan('manual_handoff', 'Budget Stop Review', 'Stop autonomous model/code loops until a cheaper scoped next action is selected.', 'budget_review_only', false, false, [
|
|
333
|
+
'Freeze further model repair loops.',
|
|
334
|
+
'Show the prompt/token/runtime budget that tripped the guard.',
|
|
335
|
+
'Select a cheaper deterministic gate, infra repair, diagnosis revision, or manual scope edit before resuming.'
|
|
336
|
+
], ['budget guard reason', 'latest prompt estimate', 'last blocker/evidence hash'], ['manual scope reduction', 'new deterministic evidence', 'approved budget policy change'], ['start another broad model prompt', 'reset budget without new evidence', 'hide cost context']);
|
|
337
|
+
}
|
|
338
|
+
if (failureClass === 'diagnosis' || stepType === 'diagnosis_gate') {
|
|
339
|
+
return makePlan('diagnosis_only', 'Run Diagnosis Gate', 'Produce a falsifiable root-cause diagnosis before any repair.', 'read_only_diagnosis', false, true, [
|
|
340
|
+
'Reproduce or explicitly classify the customer issue.',
|
|
341
|
+
'Accept one falsifiable hypothesis and record rejected alternatives.',
|
|
342
|
+
'Identify the frontend/backend/shared failing path.',
|
|
343
|
+
'Select a small owner_files set.',
|
|
344
|
+
'Define exact before/action/after business proof.'
|
|
345
|
+
], ['issue_case', 'accepted_hypothesis', 'rejected_alternatives', 'failing_path', 'owner_files', 'proof_plan'], ['new reproduction artifact', 'new query/log/code evidence', 'validated diagnosis gate'], ['edit product code', 'run broad repo repair', 'accept route-load evidence as success']);
|
|
346
|
+
}
|
|
347
|
+
if (failureClass === 'owner_scope' || failureClass === 'out_of_scope' || /out.?of.?scope|owner_files/i.test(reason)) {
|
|
348
|
+
return makePlan('diagnosis_revision', 'Revise Diagnosis Scope', 'Revise owner_files only when new evidence proves the current scope is wrong.', 'diagnosis_revision_only', false, true, [
|
|
349
|
+
'Compare changed files against the diagnosis owner_files.',
|
|
350
|
+
'Collect evidence proving why the new file is in the failing path.',
|
|
351
|
+
'Update accepted_hypothesis, failing_path, owner_files, and proof_plan together.',
|
|
352
|
+
'Resume repair only after the revised gate validates.'
|
|
353
|
+
], ['out-of-scope file list', 'new failing-path evidence', 'revalidated diagnosis gate'], ['revised owner_files with evidence', 'new business proof requirement'], ['keep broad edits without diagnosis', 'add convenience refactors', 'continue repair outside owner_files']);
|
|
354
|
+
}
|
|
355
|
+
if (action === 'retry_infra') {
|
|
356
|
+
var isCompile = failureClass === 'compile';
|
|
357
|
+
return makePlan(isCompile ? 'compile_repair' : 'infra_repair', isCompile ? 'Repair Compile Gate' : 'Repair Infra Gate', isCompile
|
|
358
|
+
? 'Fix the deterministic compile/build blocker before spending another product repair loop.'
|
|
359
|
+
: 'Fix the deterministic harness/browser/server/Mongo blocker before product repair.', isCompile ? 'compile_repair_only' : 'infra_repair_only', false, false, isCompile
|
|
360
|
+
? [
|
|
361
|
+
'Read the exact compile/build log and identify the first actionable error.',
|
|
362
|
+
'Fix missing dependency, stale artifact, command, cache, or type wiring required by the compile gate.',
|
|
363
|
+
'Rerun the same finite compile command.',
|
|
364
|
+
'Return the compile log artifact and status.'
|
|
365
|
+
]
|
|
366
|
+
: [
|
|
367
|
+
'Run preflight for Puppeteer, Chrome executable, ports, Mongo/settings, and startup command.',
|
|
368
|
+
'Repair only the failing harness/environment item.',
|
|
369
|
+
'Rerun the same infra check.',
|
|
370
|
+
'Return the infra log and pass/fail status.'
|
|
371
|
+
], isCompile
|
|
372
|
+
? ['compile command', 'compile log artifact', 'first failing error fixed or still failing']
|
|
373
|
+
: ['preflight command', 'infra log artifact', 'specific repaired environment item'], ['same check now passes', 'new infra/compile blocker hash'], ['run product-code model repair', 'count this as product failure', 'accept route/business success without the compile/infra gate']);
|
|
374
|
+
}
|
|
375
|
+
if (action === 'park_repeated_failure' || action === 'park_ping_pong') {
|
|
376
|
+
return makePlan('blocked_until_new_evidence', action === 'park_ping_pong' ? 'Park Ping-Pong Loop' : 'Park Repeated Failure', 'Stop the current loop until new evidence changes the diagnosis, route, or repair target.', 'collect_new_evidence_only', false, false, [
|
|
377
|
+
'Do not rerun the same prompt or same repair.',
|
|
378
|
+
'Show the repeated blocker and evidence hash.',
|
|
379
|
+
'Collect a new artifact: failing DOM state, stack trace, network response, Mongo delta, compile log, or revised diagnosis.',
|
|
380
|
+
'Reset the loop only after the new evidence hash changes.'
|
|
381
|
+
], ['same failure count', 'blocker fingerprint', 'evidence hash'], ['changed evidence hash', 'new artifact path', 'revised diagnosis or journey contract'], ['alternate between two failed patches', 'increase loop budget without evidence', 'hide the park reason']);
|
|
382
|
+
}
|
|
383
|
+
if (failureClass === 'journey') {
|
|
384
|
+
return makePlan('journey_contract_repair', 'Repair Journey Contract', 'Fix the first/next/last workflow contract before app code work continues.', 'journey_contract_repair', false, true, [
|
|
385
|
+
'Open docs/APP_JOURNEY_CONTRACT.md.',
|
|
386
|
+
'Define first_screen, north_star_workflow, screen_sequence, data_story, completion_states, and qa_assertions.',
|
|
387
|
+
'Ensure each CTA maps to an action, route, method, calculation, or state transition.',
|
|
388
|
+
'Validate that sample data can drive the promised workflow.'
|
|
389
|
+
], ['validated journey_contract JSON', 'CTA-to-action mapping', 'workflow QA assertions'], ['journey validation passes', 'new workflow QA rows generated'], ['build empty routes', 'add link-only dashboard actions', 'defer workflow design to wow pass']);
|
|
390
|
+
}
|
|
391
|
+
if (failureClass === 'release') {
|
|
392
|
+
return makePlan('release_repair', 'Repair Release Gate', 'Repair deploy/publish/sample-data release evidence without rewriting working app flow.', 'release_repair_only', false, false, [
|
|
393
|
+
'Read the deploy/publish/sample-data log.',
|
|
394
|
+
'Identify whether the blocker is domain, asset, seed data, route, permission, or CDN.',
|
|
395
|
+
'Repair the release artifact/config/seed issue.',
|
|
396
|
+
'Rerun only the failed release gate.'
|
|
397
|
+
], ['deploy or publish log', 'sample-data status', 'failed release gate rerun'], ['release gate passes', 'new release blocker hash'], ['change core workflow after business QA passed', 'mark accepted from scorecard only', 'rerun full builder loop']);
|
|
398
|
+
}
|
|
399
|
+
if (failureClass === 'business' || failureClass === 'qa_evidence' || failureClass === 'route') {
|
|
400
|
+
return makePlan('business_proof_repair', 'Repair Business Proof', 'Fix the exact failing workflow assertion and prove before/action/after behavior.', 'business_repair', true, true, [
|
|
401
|
+
'Open the failing QA row or proof_plan.',
|
|
402
|
+
'Trace the UI action to method/publication/query/calculation.',
|
|
403
|
+
'Patch the smallest owner or workflow files.',
|
|
404
|
+
'Rerun only the failed business assertion.',
|
|
405
|
+
'Record DOM/data/Mongo/artifact proof.'
|
|
406
|
+
], ['failing assertion', 'action trace', 'business proof artifact'], ['business assertion passes', 'new failed assertion with new evidence'], ['treat route load as success', 'rerun unrelated QA rows first', 'accept scorecard-only evidence']);
|
|
407
|
+
}
|
|
408
|
+
if (input.productRepairFailure !== false || failureClass === 'product_code') {
|
|
409
|
+
return makePlan('product_code_repair', 'Run Targeted Product Repair', 'Repair the current product-code blocker with the smallest scoped edit and immediate proof.', 'targeted_product_repair', true, true, [
|
|
410
|
+
'Inspect the current blocker, artifacts, changed files, and owner/workflow scope.',
|
|
411
|
+
'Form one small repair hypothesis.',
|
|
412
|
+
'Patch only files justified by the active diagnosis or journey contract.',
|
|
413
|
+
'Rerun the smallest failed gate.',
|
|
414
|
+
'Record new evidence before any additional loop.'
|
|
415
|
+
], ['owner/workflow scope', 'repair diff', 'failed gate rerun artifact'], ['new evidence hash', 'same gate passes'], ['broad repo search-and-edit', 'rerun the same prompt without inspecting artifacts', 'change unrelated UI polish']);
|
|
416
|
+
}
|
|
417
|
+
return makePlan('continue', 'Continue Current Gate', 'Continue the current lane because no blocking loop or infra condition was detected.', 'continue', false, false, [
|
|
418
|
+
'Use the active lane memory.',
|
|
419
|
+
'Run the next finite gate.',
|
|
420
|
+
'Record artifacts and evidence hash.'
|
|
421
|
+
], ['active lane memory', 'finite gate artifact'], ['new gate result', 'new artifact path'], ['spawn duplicate runners', 'advance without evidence']);
|
|
422
|
+
}
|
|
134
423
|
function collectOpenTail(records) {
|
|
135
424
|
var tail = [];
|
|
136
425
|
for (var index = records.length - 1; index >= 0; index -= 1) {
|
|
@@ -208,27 +497,57 @@ function decideResolveIOAIManagerPolicy(input) {
|
|
|
208
497
|
loopBudgetShouldReset: false,
|
|
209
498
|
productRepairFailure: !infraClasses.has(failureClass) && !ignoredClasses.has(failureClass)
|
|
210
499
|
};
|
|
500
|
+
var withPlan = function (action, reason, overrides) {
|
|
501
|
+
if (overrides === void 0) { overrides = {}; }
|
|
502
|
+
var merged = __assign(__assign({}, base), overrides);
|
|
503
|
+
var recoveryPlan = buildResolveIOAIManagerRecoveryPlan({
|
|
504
|
+
action: action,
|
|
505
|
+
reason: reason,
|
|
506
|
+
failureClass: merged.failureClass,
|
|
507
|
+
lane: current.lane,
|
|
508
|
+
stepType: current.stepType,
|
|
509
|
+
blocker: current.blocker || current.summary,
|
|
510
|
+
sameFailureCount: merged.sameFailureCount,
|
|
511
|
+
pingPongCount: merged.pingPongCount,
|
|
512
|
+
newEvidence: merged.newEvidence,
|
|
513
|
+
productRepairFailure: merged.productRepairFailure,
|
|
514
|
+
changedFiles: current.changedFiles,
|
|
515
|
+
artifactPaths: current.artifactPaths,
|
|
516
|
+
maxSameFailureRepeats: maxSameFailureRepeats
|
|
517
|
+
});
|
|
518
|
+
return __assign(__assign({}, merged), { action: action, reason: reason, recoveryPlan: recoveryPlan, recoveryCheckpoint: buildResolveIOAIManagerRecoveryCheckpoint({
|
|
519
|
+
plan: recoveryPlan,
|
|
520
|
+
current: current
|
|
521
|
+
}) });
|
|
522
|
+
};
|
|
211
523
|
if (isPassingOutcome(current)) {
|
|
212
|
-
return
|
|
524
|
+
return withPlan('reset_loop_budget', 'manager_policy_progress_passed', {
|
|
525
|
+
loopBudgetShouldReset: true,
|
|
526
|
+
productRepairFailure: false
|
|
527
|
+
});
|
|
213
528
|
}
|
|
214
529
|
if (isManualOutcome(current)) {
|
|
215
|
-
return
|
|
530
|
+
return withPlan('manual_handoff', 'manager_policy_manual_or_stopped');
|
|
216
531
|
}
|
|
217
532
|
if (infraClasses.has(failureClass)) {
|
|
218
|
-
return
|
|
533
|
+
return withPlan('retry_infra', 'manager_policy_infra_failure_routes_to_infra_repair', {
|
|
534
|
+
productRepairFailure: false
|
|
535
|
+
});
|
|
219
536
|
}
|
|
220
537
|
if (pingPongCount >= maxPingPongTransitions) {
|
|
221
|
-
return
|
|
538
|
+
return withPlan('park_ping_pong', 'manager_policy_ping_pong_failure_loop');
|
|
222
539
|
}
|
|
223
540
|
if (sameFailureCount >= maxSameFailureRepeats && !newEvidence) {
|
|
224
|
-
return
|
|
541
|
+
return withPlan('park_repeated_failure', 'manager_policy_same_failure_without_new_evidence');
|
|
225
542
|
}
|
|
226
543
|
if (newEvidence || !previousSameFailure) {
|
|
227
|
-
return
|
|
228
|
-
|
|
229
|
-
|
|
544
|
+
return withPlan('continue', newEvidence
|
|
545
|
+
? 'manager_policy_new_evidence_resets_loop_budget'
|
|
546
|
+
: 'manager_policy_new_failure_or_lane', {
|
|
547
|
+
loopBudgetShouldReset: true
|
|
548
|
+
});
|
|
230
549
|
}
|
|
231
|
-
return
|
|
550
|
+
return withPlan('continue', 'manager_policy_retry_below_repeat_limit');
|
|
232
551
|
}
|
|
233
552
|
|
|
234
553
|
//# sourceMappingURL=ai-runner-manager-policy.js.map
|