@resolveio/server-lib 22.3.105 → 22.3.107

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.
@@ -1,6 +1,56 @@
1
1
  export type ResolveIOSupportV5StepType = 'compile_check' | 'startup_check' | 'live_seed' | 'auth_bootstrap' | 'route_probe' | 'qa_row' | 'build_repair' | 'qa_retest' | 'pr_review' | 'artifact_package' | 'cleanup';
2
2
  export type ResolveIOSupportV5Outcome = 'pass' | 'needs_repair' | 'retry_same_step' | 'park_manual' | 'budget_stop' | 'infra_retry' | 'ready_for_merge';
3
3
  export type ResolveIOSupportV5Lane = 'build' | 'qa' | 'review' | 'supervisor';
4
+ export type ResolveIOSupportV5MicrotaskStatus = 'pending' | 'in_progress' | 'pass' | 'needs_repair' | 'blocked' | 'parked';
5
+ export type ResolveIOSupportV5MicrotaskType = ResolveIOSupportV5StepType | 'planning' | 'scope_slice' | 'product_repair' | 'runner_repair';
6
+ export interface ResolveIOSupportV5PromptBudget {
7
+ initialPlannerCap: number;
8
+ buildMicrotaskCap: number;
9
+ buildMicrotaskHardCap: number;
10
+ qaMicrotaskCap: number;
11
+ qaMicrotaskHardCap: number;
12
+ repairMicrotaskCap: number;
13
+ repairMicrotaskHardCap: number;
14
+ }
15
+ export interface ResolveIOSupportV5Microtask {
16
+ microtaskId: string;
17
+ lane: ResolveIOSupportV5Lane;
18
+ type: ResolveIOSupportV5MicrotaskType;
19
+ status: ResolveIOSupportV5MicrotaskStatus;
20
+ objective: string;
21
+ targetFiles: string[];
22
+ contextRefs: string[];
23
+ selfGate: string;
24
+ acceptanceProof: string;
25
+ threadKey: string;
26
+ promptTokenEstimate?: number;
27
+ attempts: number;
28
+ dependsOn: string[];
29
+ parentScopeId?: string;
30
+ blocker?: string;
31
+ createdAt: string;
32
+ updatedAt: string;
33
+ }
34
+ export interface ResolveIOSupportV5UsageSection {
35
+ name: string;
36
+ tokenEstimate: number;
37
+ }
38
+ export interface ResolveIOSupportV5MicrotaskUsage {
39
+ microtaskId: string;
40
+ lane: ResolveIOSupportV5Lane;
41
+ model?: string;
42
+ threadKey?: string;
43
+ reuseThread: boolean;
44
+ freshReason?: string;
45
+ promptTokenEstimate: number;
46
+ promptSections: ResolveIOSupportV5UsageSection[];
47
+ actualInputTokens?: number;
48
+ actualCachedInputTokens?: number;
49
+ actualOutputTokens?: number;
50
+ durationMs?: number;
51
+ outcome?: ResolveIOSupportV5Outcome | ResolveIOSupportV5MicrotaskStatus;
52
+ recordedAt: string;
53
+ }
4
54
  export interface ResolveIOSupportV5Budget {
5
55
  maxPromptTokensPerNonInitialStep: number;
6
56
  maxLoopsPerTicket: number;
@@ -81,6 +131,10 @@ export interface ResolveIOSupportV5StateBundle {
81
131
  supportV5StepHistory: ResolveIOSupportV5StepRecord[];
82
132
  supportV5Budget: ResolveIOSupportV5Budget;
83
133
  supportV5RunnerIncidents: ResolveIOSupportV5RunnerIncident[];
134
+ supportV5MicrotaskLedger: ResolveIOSupportV5Microtask[];
135
+ supportV5ActiveMicrotaskId?: string;
136
+ supportV5ScopeDigest?: string;
137
+ supportV5MicrotaskUsageHistory: ResolveIOSupportV5MicrotaskUsage[];
84
138
  }
85
139
  export interface ResolveIOSupportV5InitializeInput {
86
140
  jobId: string;
@@ -121,8 +175,25 @@ export interface ResolveIOSupportV5ContinuationDecision {
121
175
  }
122
176
  export declare function fingerprintResolveIOSupportV5Blocker(value: any): string;
123
177
  export declare function buildResolveIOSupportV5Budget(existing?: Partial<ResolveIOSupportV5Budget>): ResolveIOSupportV5Budget;
178
+ export declare function buildResolveIOSupportV5PromptBudget(existing?: Partial<ResolveIOSupportV5PromptBudget>): ResolveIOSupportV5PromptBudget;
179
+ export declare function buildResolveIOSupportV5ScopeDigest(input: {
180
+ goal?: string;
181
+ approvedScope?: string | string[];
182
+ prBranch?: string;
183
+ maxTokens?: number;
184
+ }): string;
185
+ export declare function buildResolveIOSupportV5MicrotaskLedger(input: {
186
+ scopeDigest: string;
187
+ requirements?: string[];
188
+ buildThreadKey: string;
189
+ qaThreadKey: string;
190
+ now?: Date | string;
191
+ existing?: ResolveIOSupportV5Microtask[];
192
+ }): ResolveIOSupportV5Microtask[];
193
+ export declare function selectResolveIOSupportV5ActiveMicrotask(ledger?: ResolveIOSupportV5Microtask[], preferredId?: string): ResolveIOSupportV5Microtask | undefined;
124
194
  export declare function initializeResolveIOSupportV5State(input: ResolveIOSupportV5InitializeInput): ResolveIOSupportV5StateBundle;
125
195
  export declare function recordResolveIOSupportV5Step(bundle: ResolveIOSupportV5StateBundle, step: ResolveIOSupportV5StepInput): ResolveIOSupportV5StateBundle;
196
+ export declare function recordResolveIOSupportV5MicrotaskUsage(bundle: ResolveIOSupportV5StateBundle, usage: Omit<ResolveIOSupportV5MicrotaskUsage, 'recordedAt'>): ResolveIOSupportV5StateBundle;
126
197
  export declare function decideResolveIOSupportV5Continuation(bundle: ResolveIOSupportV5StateBundle): ResolveIOSupportV5ContinuationDecision;
127
198
  export declare function buildResolveIOSupportV5DiagnoseFirstPrompt(lines: {
128
199
  goal?: string;
@@ -135,6 +206,38 @@ export declare function buildResolveIOSupportV5DiagnoseFirstPrompt(lines: {
135
206
  artifactPaths?: string[];
136
207
  changedFiles?: string[];
137
208
  }): string[];
209
+ export declare function buildResolveIOSupportV5MicrotaskPrompt(input: {
210
+ bundle: ResolveIOSupportV5StateBundle;
211
+ lane: 'build' | 'qa';
212
+ model?: string;
213
+ stage?: string;
214
+ failureText?: string;
215
+ changedFiles?: string[];
216
+ artifactPaths?: string[];
217
+ targetFiles?: string[];
218
+ contextSnippets?: string[];
219
+ activeQaRow?: ResolveIOSupportV5LaneMemory['activeQaRow'];
220
+ }): {
221
+ prompt: string;
222
+ promptTokenEstimate: number;
223
+ promptSections: ResolveIOSupportV5UsageSection[];
224
+ activeMicrotask?: ResolveIOSupportV5Microtask;
225
+ withinCap: boolean;
226
+ withinHardCap: boolean;
227
+ cap: number;
228
+ hardCap: number;
229
+ reason?: string;
230
+ };
231
+ export declare function summarizeResolveIOSupportV5MicrotaskUsage(bundle: ResolveIOSupportV5StateBundle): {
232
+ totalPromptTokenEstimate: number;
233
+ byMicrotask: Array<{
234
+ microtaskId: string;
235
+ promptTokenEstimate: number;
236
+ calls: number;
237
+ }>;
238
+ bySection: ResolveIOSupportV5UsageSection[];
239
+ broadPromptViolations: ResolveIOSupportV5MicrotaskUsage[];
240
+ };
138
241
  export declare function buildResolveIOSupportV5Incident(input: {
139
242
  incidentClass: string;
140
243
  summary: string;
@@ -49,10 +49,17 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
49
49
  Object.defineProperty(exports, "__esModule", { value: true });
50
50
  exports.fingerprintResolveIOSupportV5Blocker = fingerprintResolveIOSupportV5Blocker;
51
51
  exports.buildResolveIOSupportV5Budget = buildResolveIOSupportV5Budget;
52
+ exports.buildResolveIOSupportV5PromptBudget = buildResolveIOSupportV5PromptBudget;
53
+ exports.buildResolveIOSupportV5ScopeDigest = buildResolveIOSupportV5ScopeDigest;
54
+ exports.buildResolveIOSupportV5MicrotaskLedger = buildResolveIOSupportV5MicrotaskLedger;
55
+ exports.selectResolveIOSupportV5ActiveMicrotask = selectResolveIOSupportV5ActiveMicrotask;
52
56
  exports.initializeResolveIOSupportV5State = initializeResolveIOSupportV5State;
53
57
  exports.recordResolveIOSupportV5Step = recordResolveIOSupportV5Step;
58
+ exports.recordResolveIOSupportV5MicrotaskUsage = recordResolveIOSupportV5MicrotaskUsage;
54
59
  exports.decideResolveIOSupportV5Continuation = decideResolveIOSupportV5Continuation;
55
60
  exports.buildResolveIOSupportV5DiagnoseFirstPrompt = buildResolveIOSupportV5DiagnoseFirstPrompt;
61
+ exports.buildResolveIOSupportV5MicrotaskPrompt = buildResolveIOSupportV5MicrotaskPrompt;
62
+ exports.summarizeResolveIOSupportV5MicrotaskUsage = summarizeResolveIOSupportV5MicrotaskUsage;
56
63
  exports.buildResolveIOSupportV5Incident = buildResolveIOSupportV5Incident;
57
64
  function isoNow(value) {
58
65
  if (value instanceof Date) {
@@ -97,6 +104,21 @@ function cleanList(values, limit, max) {
97
104
  }
98
105
  return result;
99
106
  }
107
+ function stableIdFromText(prefix, value) {
108
+ var text = cleanText(value, 2000).toLowerCase();
109
+ var hash = 0;
110
+ for (var index = 0; index < text.length; index += 1) {
111
+ hash = ((hash << 5) - hash + text.charCodeAt(index)) | 0;
112
+ }
113
+ return "".concat(prefix, "-").concat(Math.abs(hash).toString(36) || '0');
114
+ }
115
+ function estimateTextTokens(value) {
116
+ var text = String(value || '');
117
+ if (!text) {
118
+ return 0;
119
+ }
120
+ return Math.max(1, Math.ceil(text.length / 4));
121
+ }
100
122
  function fingerprintResolveIOSupportV5Blocker(value) {
101
123
  var text = cleanText(value, 4000)
102
124
  .toLowerCase()
@@ -111,7 +133,7 @@ function fingerprintResolveIOSupportV5Blocker(value) {
111
133
  }
112
134
  function buildResolveIOSupportV5Budget(existing) {
113
135
  return {
114
- maxPromptTokensPerNonInitialStep: Number((existing === null || existing === void 0 ? void 0 : existing.maxPromptTokensPerNonInitialStep) || 4000),
136
+ maxPromptTokensPerNonInitialStep: Number((existing === null || existing === void 0 ? void 0 : existing.maxPromptTokensPerNonInitialStep) || 1800),
115
137
  maxLoopsPerTicket: Number((existing === null || existing === void 0 ? void 0 : existing.maxLoopsPerTicket) || 24),
116
138
  maxRepeatedNoProgress: Number((existing === null || existing === void 0 ? void 0 : existing.maxRepeatedNoProgress) || 2),
117
139
  maxRuntimeMinutesPerLoop: Number((existing === null || existing === void 0 ? void 0 : existing.maxRuntimeMinutesPerLoop) || 15),
@@ -120,6 +142,110 @@ function buildResolveIOSupportV5Budget(existing) {
120
142
  loopCount: Number((existing === null || existing === void 0 ? void 0 : existing.loopCount) || 0)
121
143
  };
122
144
  }
145
+ function buildResolveIOSupportV5PromptBudget(existing) {
146
+ return {
147
+ initialPlannerCap: Number((existing === null || existing === void 0 ? void 0 : existing.initialPlannerCap) || 6000),
148
+ buildMicrotaskCap: Number((existing === null || existing === void 0 ? void 0 : existing.buildMicrotaskCap) || 1800),
149
+ buildMicrotaskHardCap: Number((existing === null || existing === void 0 ? void 0 : existing.buildMicrotaskHardCap) || 2500),
150
+ qaMicrotaskCap: Number((existing === null || existing === void 0 ? void 0 : existing.qaMicrotaskCap) || 1500),
151
+ qaMicrotaskHardCap: Number((existing === null || existing === void 0 ? void 0 : existing.qaMicrotaskHardCap) || 2200),
152
+ repairMicrotaskCap: Number((existing === null || existing === void 0 ? void 0 : existing.repairMicrotaskCap) || 1200),
153
+ repairMicrotaskHardCap: Number((existing === null || existing === void 0 ? void 0 : existing.repairMicrotaskHardCap) || 1800)
154
+ };
155
+ }
156
+ function buildResolveIOSupportV5ScopeDigest(input) {
157
+ var scope = Array.isArray(input.approvedScope)
158
+ ? cleanList(input.approvedScope, 30, 220).join(' | ')
159
+ : cleanText(input.approvedScope, 4000);
160
+ var raw = [
161
+ input.goal ? "Goal: ".concat(cleanText(input.goal, 300)) : '',
162
+ scope ? "Approved scope: ".concat(scope) : '',
163
+ input.prBranch ? "PR branch: ".concat(cleanText(input.prBranch, 160)) : ''
164
+ ].filter(Boolean).join('\n');
165
+ var maxChars = Math.max(400, Math.floor(Number(input.maxTokens || 1000) * 4));
166
+ return raw.slice(0, maxChars);
167
+ }
168
+ function buildResolveIOSupportV5MicrotaskLedger(input) {
169
+ var e_2, _a;
170
+ var existing = Array.isArray(input.existing) ? input.existing : [];
171
+ var completedByObjective = new Map();
172
+ try {
173
+ for (var existing_1 = __values(existing), existing_1_1 = existing_1.next(); !existing_1_1.done; existing_1_1 = existing_1.next()) {
174
+ var task = existing_1_1.value;
175
+ if (task && (task.status === 'pass' || task.status === 'parked')) {
176
+ completedByObjective.set(cleanText(task.objective, 500).toLowerCase(), task);
177
+ }
178
+ }
179
+ }
180
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
181
+ finally {
182
+ try {
183
+ if (existing_1_1 && !existing_1_1.done && (_a = existing_1.return)) _a.call(existing_1);
184
+ }
185
+ finally { if (e_2) throw e_2.error; }
186
+ }
187
+ var now = isoNow(input.now);
188
+ var requirements = cleanList(input.requirements, 30, 240);
189
+ var sourceRequirements = requirements.length
190
+ ? requirements
191
+ : cleanText(input.scopeDigest, 1000).split(/\s+\|\s+|\r?\n/g).map(function (line) { return line.trim(); }).filter(Boolean).slice(0, 12);
192
+ var ledger = [];
193
+ sourceRequirements.forEach(function (requirement, index) {
194
+ var objective = cleanText(requirement, 240);
195
+ if (!objective) {
196
+ return;
197
+ }
198
+ var existingCompleted = completedByObjective.get(objective.toLowerCase());
199
+ var buildId = stableIdFromText("build-".concat(index + 1), objective);
200
+ var qaId = stableIdFromText("qa-".concat(index + 1), objective);
201
+ ledger.push(existingCompleted && existingCompleted.lane === 'build' ? existingCompleted : {
202
+ microtaskId: buildId,
203
+ lane: 'build',
204
+ type: 'build_repair',
205
+ status: 'pending',
206
+ objective: objective,
207
+ targetFiles: [],
208
+ contextRefs: ['scope_digest'],
209
+ selfGate: 'Run the smallest compile/type/unit check that proves this one behavior.',
210
+ acceptanceProof: 'Concrete code/data proof for this behavior, with changed files listed.',
211
+ threadKey: input.buildThreadKey,
212
+ attempts: 0,
213
+ dependsOn: [],
214
+ parentScopeId: stableIdFromText('scope', objective),
215
+ createdAt: now,
216
+ updatedAt: now
217
+ });
218
+ ledger.push({
219
+ microtaskId: qaId,
220
+ lane: 'qa',
221
+ type: 'qa_row',
222
+ status: 'pending',
223
+ objective: "QA proof for: ".concat(objective),
224
+ targetFiles: [],
225
+ contextRefs: ['scope_digest', buildId],
226
+ selfGate: 'Drive this one customer-facing workflow row in browser/localhost and capture one captioned proof artifact.',
227
+ acceptanceProof: 'QA matrix row pass with route/data assertion and screenshot/caption artifact.',
228
+ threadKey: input.qaThreadKey,
229
+ attempts: 0,
230
+ dependsOn: [buildId],
231
+ parentScopeId: stableIdFromText('scope', objective),
232
+ createdAt: now,
233
+ updatedAt: now
234
+ });
235
+ });
236
+ return ledger.length ? ledger : existing.slice(-80);
237
+ }
238
+ function selectResolveIOSupportV5ActiveMicrotask(ledger, preferredId) {
239
+ if (ledger === void 0) { ledger = []; }
240
+ var byPreferred = preferredId ? ledger.find(function (task) { return task.microtaskId === preferredId && !['pass', 'parked'].includes(task.status); }) : undefined;
241
+ if (byPreferred) {
242
+ return byPreferred;
243
+ }
244
+ return ledger.find(function (task) { return task.status === 'needs_repair'; })
245
+ || ledger.find(function (task) { return task.status === 'in_progress'; })
246
+ || ledger.find(function (task) { return task.status === 'pending'; })
247
+ || ledger.find(function (task) { return task.status === 'blocked'; });
248
+ }
123
249
  function initializeResolveIOSupportV5State(input) {
124
250
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
125
251
  var now = isoNow(input.now);
@@ -133,6 +259,20 @@ function initializeResolveIOSupportV5State(input) {
133
259
  var buildThreadKey = cleanText(input.buildThreadKey || ((_a = existingLaneMemory.build) === null || _a === void 0 ? void 0 : _a.threadKey) || "support:".concat(input.ticketId || input.jobId, ":job:").concat(input.jobId, ":build"), 240);
134
260
  var qaThreadKey = cleanText(input.qaThreadKey || ((_b = existingLaneMemory.qa) === null || _b === void 0 ? void 0 : _b.threadKey) || "support:".concat(input.ticketId || input.jobId, ":job:").concat(input.jobId, ":qa"), 240);
135
261
  var budget = buildResolveIOSupportV5Budget(existing.supportV5Budget);
262
+ var scopeDigest = cleanText(existing.supportV5ScopeDigest, 4000) || buildResolveIOSupportV5ScopeDigest({
263
+ goal: (existingSupervisor === null || existingSupervisor === void 0 ? void 0 : existingSupervisor.currentGoal) || "Resolve support ticket ".concat(ticketLabel),
264
+ approvedScope: scope,
265
+ prBranch: input.prBranch || (existingSupervisor === null || existingSupervisor === void 0 ? void 0 : existingSupervisor.prBranch) || ''
266
+ });
267
+ var ledger = buildResolveIOSupportV5MicrotaskLedger({
268
+ scopeDigest: scopeDigest,
269
+ requirements: cleanList(input.approvedScopeRequirements, 30, 240),
270
+ buildThreadKey: buildThreadKey,
271
+ qaThreadKey: qaThreadKey,
272
+ now: now,
273
+ existing: existing.supportV5MicrotaskLedger
274
+ });
275
+ var activeMicrotask = selectResolveIOSupportV5ActiveMicrotask(ledger, existing.supportV5ActiveMicrotaskId);
136
276
  return {
137
277
  supportWorkflowVersion: 'v5',
138
278
  supportV5SupervisorState: {
@@ -182,6 +322,12 @@ function initializeResolveIOSupportV5State(input) {
182
322
  supportV5Budget: budget,
183
323
  supportV5RunnerIncidents: Array.isArray(existing.supportV5RunnerIncidents)
184
324
  ? existing.supportV5RunnerIncidents.slice(-80)
325
+ : [],
326
+ supportV5MicrotaskLedger: ledger,
327
+ supportV5ActiveMicrotaskId: activeMicrotask === null || activeMicrotask === void 0 ? void 0 : activeMicrotask.microtaskId,
328
+ supportV5ScopeDigest: scopeDigest,
329
+ supportV5MicrotaskUsageHistory: Array.isArray(existing.supportV5MicrotaskUsageHistory)
330
+ ? existing.supportV5MicrotaskUsageHistory.slice(-200)
185
331
  : []
186
332
  };
187
333
  }
@@ -212,7 +358,34 @@ function recordResolveIOSupportV5Step(bundle, step) {
212
358
  var supervisor = __assign(__assign({}, bundle.supportV5SupervisorState), { status: step.outcome === 'ready_for_merge' ? 'complete' : (step.outcome === 'park_manual' || step.outcome === 'budget_stop' ? 'parked' : 'active'), activeStep: step.stepType, activeBlocker: record.blocker || '', currentQaRow: step.activeQaRow || bundle.supportV5SupervisorState.currentQaRow, lastGoodCheckpoint: step.outcome === 'pass' || step.outcome === 'ready_for_merge'
213
359
  ? step.stepType
214
360
  : bundle.supportV5SupervisorState.lastGoodCheckpoint, artifactLinks: Array.from(new Set(__spreadArray(__spreadArray([], __read(bundle.supportV5SupervisorState.artifactLinks), false), __read((record.artifactPaths || [])), false))).slice(-80), updatedAt: now });
215
- return __assign(__assign({}, bundle), { supportV5SupervisorState: supervisor, supportV5LaneMemory: laneMemory, supportV5StepHistory: __spreadArray(__spreadArray([], __read(bundle.supportV5StepHistory), false), [record], false).slice(-100), supportV5Budget: __assign(__assign({}, bundle.supportV5Budget), { totalPromptTokenEstimate: bundle.supportV5Budget.totalPromptTokenEstimate + promptTokens, totalRuntimeMs: bundle.supportV5Budget.totalRuntimeMs + runtimeMs, loopCount: bundle.supportV5Budget.loopCount + 1 }) });
361
+ var ledger = (bundle.supportV5MicrotaskLedger || []).map(function (task) {
362
+ if (task.microtaskId !== bundle.supportV5ActiveMicrotaskId) {
363
+ return task;
364
+ }
365
+ var status = step.outcome === 'pass' || step.outcome === 'ready_for_merge'
366
+ ? 'pass'
367
+ : step.outcome === 'park_manual' || step.outcome === 'budget_stop'
368
+ ? 'parked'
369
+ : step.outcome === 'needs_repair' || step.outcome === 'retry_same_step'
370
+ ? 'needs_repair'
371
+ : 'in_progress';
372
+ return __assign(__assign({}, task), { status: status, blocker: record.blocker || task.blocker, promptTokenEstimate: promptTokens || task.promptTokenEstimate, attempts: task.attempts + (step.outcome === 'pass' || step.outcome === 'ready_for_merge' ? 0 : 1), updatedAt: now });
373
+ });
374
+ var nextMicrotask = selectResolveIOSupportV5ActiveMicrotask(ledger, bundle.supportV5ActiveMicrotaskId);
375
+ return __assign(__assign({}, bundle), { supportV5SupervisorState: supervisor, supportV5LaneMemory: laneMemory, supportV5StepHistory: __spreadArray(__spreadArray([], __read(bundle.supportV5StepHistory), false), [record], false).slice(-100), supportV5Budget: __assign(__assign({}, bundle.supportV5Budget), { totalPromptTokenEstimate: bundle.supportV5Budget.totalPromptTokenEstimate + promptTokens, totalRuntimeMs: bundle.supportV5Budget.totalRuntimeMs + runtimeMs, loopCount: bundle.supportV5Budget.loopCount + 1 }), supportV5MicrotaskLedger: ledger, supportV5ActiveMicrotaskId: nextMicrotask === null || nextMicrotask === void 0 ? void 0 : nextMicrotask.microtaskId, supportV5MicrotaskUsageHistory: bundle.supportV5MicrotaskUsageHistory || [] });
376
+ }
377
+ function recordResolveIOSupportV5MicrotaskUsage(bundle, usage) {
378
+ var record = __assign(__assign({}, usage), { microtaskId: cleanText(usage.microtaskId, 160), threadKey: cleanText(usage.threadKey, 240), model: cleanText(usage.model, 80), promptTokenEstimate: Math.max(0, Number(usage.promptTokenEstimate || 0) || 0), promptSections: Array.isArray(usage.promptSections)
379
+ ? usage.promptSections.map(function (section) { return ({
380
+ name: cleanText(section.name, 120),
381
+ tokenEstimate: Math.max(0, Number(section.tokenEstimate || 0) || 0)
382
+ }); }).filter(function (section) { return section.name; })
383
+ : [], recordedAt: isoNow() });
384
+ var ledger = (bundle.supportV5MicrotaskLedger || []).map(function (task) { return task.microtaskId === record.microtaskId
385
+ ? __assign(__assign({}, task), { promptTokenEstimate: record.promptTokenEstimate, updatedAt: record.recordedAt }) : task; });
386
+ return __assign(__assign({}, bundle), { supportV5MicrotaskLedger: ledger, supportV5MicrotaskUsageHistory: __spreadArray(__spreadArray([], __read((bundle.supportV5MicrotaskUsageHistory || [])), false), [
387
+ record
388
+ ], false).slice(-200) });
216
389
  }
217
390
  function decideResolveIOSupportV5Continuation(bundle) {
218
391
  var history = bundle.supportV5StepHistory || [];
@@ -233,7 +406,7 @@ function decideResolveIOSupportV5Continuation(bundle) {
233
406
  }
234
407
  }
235
408
  var budgetExceeded = budget.loopCount >= budget.maxLoopsPerTicket
236
- || ((last === null || last === void 0 ? void 0 : last.promptTokenEstimate) || 0) > budget.maxPromptTokensPerNonInitialStep * 2;
409
+ || ((last === null || last === void 0 ? void 0 : last.promptTokenEstimate) || 0) > budget.maxPromptTokensPerNonInitialStep;
237
410
  if (budgetExceeded) {
238
411
  return {
239
412
  action: 'park',
@@ -281,6 +454,153 @@ function buildResolveIOSupportV5DiagnoseFirstPrompt(lines) {
281
454
  cleanList(lines.artifactPaths, 12, 240).length ? "Artifacts: ".concat(cleanList(lines.artifactPaths, 12, 240).join(', ')) : ''
282
455
  ].filter(Boolean);
283
456
  }
457
+ function buildResolveIOSupportV5MicrotaskPrompt(input) {
458
+ var _a, _b, _c;
459
+ var activeMicrotask = selectResolveIOSupportV5ActiveMicrotask(input.bundle.supportV5MicrotaskLedger || [], input.bundle.supportV5ActiveMicrotaskId);
460
+ var budget = buildResolveIOSupportV5PromptBudget();
461
+ var repairLike = Boolean(input.failureText || (activeMicrotask === null || activeMicrotask === void 0 ? void 0 : activeMicrotask.status) === 'needs_repair' || /repair/i.test(String(input.stage || (activeMicrotask === null || activeMicrotask === void 0 ? void 0 : activeMicrotask.type) || '')));
462
+ var cap = repairLike
463
+ ? budget.repairMicrotaskCap
464
+ : input.lane === 'qa'
465
+ ? budget.qaMicrotaskCap
466
+ : budget.buildMicrotaskCap;
467
+ var hardCap = repairLike
468
+ ? budget.repairMicrotaskHardCap
469
+ : input.lane === 'qa'
470
+ ? budget.qaMicrotaskHardCap
471
+ : budget.buildMicrotaskHardCap;
472
+ var laneMemory = input.bundle.supportV5LaneMemory[input.lane];
473
+ var taskThreadKey = (activeMicrotask === null || activeMicrotask === void 0 ? void 0 : activeMicrotask.threadKey) || laneMemory.threadKey;
474
+ var changedFiles = cleanList(((_a = input.changedFiles) === null || _a === void 0 ? void 0 : _a.length) ? input.changedFiles : laneMemory.changedFiles, 8, 160);
475
+ var artifactPaths = cleanList(((_b = input.artifactPaths) === null || _b === void 0 ? void 0 : _b.length) ? input.artifactPaths : laneMemory.artifactPaths, 8, 200);
476
+ var targetFiles = cleanList(((_c = input.targetFiles) === null || _c === void 0 ? void 0 : _c.length) ? input.targetFiles : activeMicrotask === null || activeMicrotask === void 0 ? void 0 : activeMicrotask.targetFiles, 5, 160);
477
+ var contextSnippets = cleanList(input.contextSnippets, 5, 360);
478
+ var qaRow = input.activeQaRow || (activeMicrotask === null || activeMicrotask === void 0 ? void 0 : activeMicrotask.lane) === 'qa' ? input.activeQaRow || laneMemory.activeQaRow || input.bundle.supportV5SupervisorState.currentQaRow : undefined;
479
+ var sections = [
480
+ {
481
+ name: 'microtask_contract',
482
+ text: [
483
+ 'Support Runner V5 Microtask Contract.',
484
+ 'Use the existing persistent lane thread. Do not start a fresh thread.',
485
+ 'Do exactly one microtask and one proof gate. Do not replay ticket triage, prior plans, attachments, broad QA checklist, or unrelated scope.',
486
+ 'If context is insufficient, request the smallest missing file/log/artifact by path and park this microtask; do not broaden the prompt.',
487
+ 'Do not send customer email. Do not deploy. Do not spawn duplicate server/client/Mongo/browser/Codex processes.'
488
+ ].join('\n')
489
+ },
490
+ {
491
+ name: 'scope_digest',
492
+ text: cleanText(input.bundle.supportV5ScopeDigest || input.bundle.supportV5SupervisorState.approvedScope, 900)
493
+ },
494
+ {
495
+ name: 'active_microtask',
496
+ text: activeMicrotask ? [
497
+ "Microtask id: ".concat(activeMicrotask.microtaskId),
498
+ "Lane: ".concat(input.lane),
499
+ "Type: ".concat(activeMicrotask.type),
500
+ "Status: ".concat(activeMicrotask.status),
501
+ "Objective: ".concat(cleanText(activeMicrotask.objective, 360)),
502
+ "Self-gate: ".concat(cleanText(activeMicrotask.selfGate, 260)),
503
+ "Acceptance proof: ".concat(cleanText(activeMicrotask.acceptanceProof, 260)),
504
+ "Attempts on this microtask: ".concat(activeMicrotask.attempts),
505
+ "Thread key: ".concat(taskThreadKey)
506
+ ].join('\n') : 'No active microtask found. Park and report support_v5_microtask_missing.'
507
+ },
508
+ {
509
+ name: 'failure_delta',
510
+ text: input.failureText ? "Latest blocker/failure delta: ".concat(cleanText(input.failureText, 700)) : ''
511
+ },
512
+ {
513
+ name: 'target_context',
514
+ text: [
515
+ targetFiles.length ? "Target files: ".concat(targetFiles.join(', ')) : '',
516
+ changedFiles.length ? "Changed files: ".concat(changedFiles.join(', ')) : '',
517
+ artifactPaths.length ? "Artifacts: ".concat(artifactPaths.join(', ')) : '',
518
+ (qaRow === null || qaRow === void 0 ? void 0 : qaRow.workflow) ? "QA row workflow: ".concat(cleanText(qaRow.workflow, 220)) : '',
519
+ (qaRow === null || qaRow === void 0 ? void 0 : qaRow.route) ? "QA row route: ".concat(cleanText(qaRow.route, 220)) : '',
520
+ (qaRow === null || qaRow === void 0 ? void 0 : qaRow.assertion) ? "QA row assertion: ".concat(cleanText(qaRow.assertion, 260)) : '',
521
+ contextSnippets.length ? "Relevant snippets:\n".concat(contextSnippets.join('\n---\n')) : ''
522
+ ].filter(Boolean).join('\n')
523
+ },
524
+ {
525
+ name: 'return_contract',
526
+ text: input.lane === 'qa'
527
+ ? 'Return strict JSON only: {"status":"pass"|"needs-fix"|"blocked","microtaskId":"","summary":"","evidence":[""],"artifacts":[""],"next_actions":[""]}.'
528
+ : 'Return concise Markdown with: Microtask Result, Root Cause, Changes, Self-Gate, Acceptance Proof, Residual Risk.'
529
+ }
530
+ ].filter(function (section) { return cleanText(section.text, 20); });
531
+ var promptSections = sections.map(function (section) { return ({
532
+ name: section.name,
533
+ tokenEstimate: estimateTextTokens(section.text)
534
+ }); });
535
+ var prompt = sections.map(function (section) { return section.text; }).join('\n\n');
536
+ var promptTokenEstimate = estimateTextTokens(prompt);
537
+ return {
538
+ prompt: prompt,
539
+ promptTokenEstimate: promptTokenEstimate,
540
+ promptSections: promptSections,
541
+ activeMicrotask: activeMicrotask,
542
+ withinCap: promptTokenEstimate <= cap,
543
+ withinHardCap: promptTokenEstimate <= hardCap,
544
+ cap: cap,
545
+ hardCap: hardCap,
546
+ reason: promptTokenEstimate > hardCap
547
+ ? 'support_v5_microtask_prompt_hard_cap'
548
+ : promptTokenEstimate > cap
549
+ ? 'support_v5_microtask_prompt_soft_cap'
550
+ : undefined
551
+ };
552
+ }
553
+ function summarizeResolveIOSupportV5MicrotaskUsage(bundle) {
554
+ var e_3, _a, e_4, _b;
555
+ var byMicrotask = new Map();
556
+ var bySection = new Map();
557
+ var totalPromptTokenEstimate = 0;
558
+ var broadPromptViolations = [];
559
+ var promptBudget = buildResolveIOSupportV5PromptBudget();
560
+ try {
561
+ for (var _c = __values(bundle.supportV5MicrotaskUsageHistory || []), _d = _c.next(); !_d.done; _d = _c.next()) {
562
+ var usage = _d.value;
563
+ totalPromptTokenEstimate += usage.promptTokenEstimate || 0;
564
+ var existing = byMicrotask.get(usage.microtaskId) || { microtaskId: usage.microtaskId, promptTokenEstimate: 0, calls: 0 };
565
+ existing.promptTokenEstimate += usage.promptTokenEstimate || 0;
566
+ existing.calls += 1;
567
+ byMicrotask.set(usage.microtaskId, existing);
568
+ try {
569
+ for (var _e = (e_4 = void 0, __values(usage.promptSections || [])), _f = _e.next(); !_f.done; _f = _e.next()) {
570
+ var section = _f.value;
571
+ bySection.set(section.name, (bySection.get(section.name) || 0) + section.tokenEstimate);
572
+ }
573
+ }
574
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
575
+ finally {
576
+ try {
577
+ if (_f && !_f.done && (_b = _e.return)) _b.call(_e);
578
+ }
579
+ finally { if (e_4) throw e_4.error; }
580
+ }
581
+ var hardCap = usage.lane === 'qa' ? promptBudget.qaMicrotaskHardCap : promptBudget.buildMicrotaskHardCap;
582
+ if ((usage.promptTokenEstimate || 0) > hardCap) {
583
+ broadPromptViolations.push(usage);
584
+ }
585
+ }
586
+ }
587
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
588
+ finally {
589
+ try {
590
+ if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
591
+ }
592
+ finally { if (e_3) throw e_3.error; }
593
+ }
594
+ return {
595
+ totalPromptTokenEstimate: totalPromptTokenEstimate,
596
+ byMicrotask: Array.from(byMicrotask.values()),
597
+ bySection: Array.from(bySection.entries()).map(function (_a) {
598
+ var _b = __read(_a, 2), name = _b[0], tokenEstimate = _b[1];
599
+ return ({ name: name, tokenEstimate: tokenEstimate });
600
+ }),
601
+ broadPromptViolations: broadPromptViolations
602
+ };
603
+ }
284
604
  function buildResolveIOSupportV5Incident(input) {
285
605
  return {
286
606
  incidentClass: cleanText(input.incidentClass, 120) || 'support_v5_runner_incident',