@lsctech/polaris 0.5.10 → 0.5.12
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/dist/autoresearch/proposal.js +61 -0
- package/dist/autoresearch/score.js +124 -0
- package/dist/cli/index.js +4 -0
- package/dist/cli/qc.js +97 -0
- package/dist/config/validator.js +16 -6
- package/dist/finalize/artifact-policy.js +35 -3
- package/dist/finalize/index.js +23 -4
- package/dist/finalize/run-report.js +189 -19
- package/dist/finalize/steps/05-generate-report.js +5 -1
- package/dist/finalize/steps/06-commit.js +2 -1
- package/dist/finalize/steps/12-archive.js +6 -0
- package/dist/loop/adapters/terminal-cli.js +131 -25
- package/dist/loop/body-parser.js +69 -6
- package/dist/loop/continue.js +19 -1
- package/dist/loop/dispatch.js +102 -67
- package/dist/loop/parent.js +22 -3
- package/dist/loop/router/engine.js +1 -0
- package/dist/loop/run-preflight.js +4 -1
- package/dist/loop/worker-packet.js +81 -2
- package/dist/medic/routing-signals.js +60 -0
- package/dist/qc/policy.js +2 -0
- package/dist/qc/providers/coderabbit.js +153 -14
- package/dist/qc/repair-loop.js +147 -1
- package/dist/qc/repair-packets.js +16 -3
- package/dist/qc/routing.js +6 -0
- package/dist/qc/types.js +3 -0
- package/dist/tracker/local-graph.js +106 -3
- package/package.json +1 -1
package/dist/loop/dispatch.js
CHANGED
|
@@ -139,6 +139,18 @@ function resolveProviderAndMode(options, role, config, routerContext) {
|
|
|
139
139
|
},
|
|
140
140
|
compatibilityMode: false,
|
|
141
141
|
});
|
|
142
|
+
const workerPolicy = exec?.providerPolicy?.[role];
|
|
143
|
+
const noFallback = workerPolicy?.noFallback === true;
|
|
144
|
+
const fallbackEligible = !noFallback && decision.providersTried.length > 1;
|
|
145
|
+
const routingSummary = {
|
|
146
|
+
selected_provider: decision.selectedProvider ?? null,
|
|
147
|
+
selected_adapter: adapter,
|
|
148
|
+
selection_reason: decision.selectionReason,
|
|
149
|
+
effective_policy_order: decision.providersTried,
|
|
150
|
+
compatibility_mode: false,
|
|
151
|
+
registry_present: true,
|
|
152
|
+
fallback_eligible: fallbackEligible,
|
|
153
|
+
};
|
|
142
154
|
return {
|
|
143
155
|
provider: decision.selectedProvider,
|
|
144
156
|
mode: decision.mode,
|
|
@@ -157,91 +169,108 @@ function resolveProviderAndMode(options, role, config, routerContext) {
|
|
|
157
169
|
activeSlotsByProvider: routerContext?.activeSlotsByProvider,
|
|
158
170
|
quotaAvailableByProvider: routerContext?.quotaAvailableByProvider,
|
|
159
171
|
},
|
|
172
|
+
routingSummary,
|
|
160
173
|
};
|
|
161
174
|
}
|
|
162
175
|
function resolveProviderAndModeLegacy(options, role, adapter, exec) {
|
|
163
|
-
if (options.provider) {
|
|
164
|
-
return {
|
|
165
|
-
provider: options.provider,
|
|
166
|
-
mode: "direct-worker",
|
|
167
|
-
adapter,
|
|
168
|
-
selectionReason: "cli-provider-override",
|
|
169
|
-
overrideSource: "dispatch-flag",
|
|
170
|
-
providersTried: [options.provider],
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
176
|
const rolePolicy = exec?.providerPolicy?.[role];
|
|
174
177
|
const roleProviders = rolePolicy?.providers ?? [];
|
|
178
|
+
const noFallback = rolePolicy?.noFallback === true;
|
|
175
179
|
const rotation = exec?.rotation ?? [];
|
|
176
|
-
|
|
180
|
+
const configuredProviders = new Set(Object.keys(exec?.providers ?? {}));
|
|
181
|
+
let provider;
|
|
182
|
+
let selectionReason;
|
|
183
|
+
let overrideSource;
|
|
184
|
+
let fallbackFrom;
|
|
185
|
+
let fallbackReason;
|
|
186
|
+
let exhaustedReason;
|
|
187
|
+
let effectivePolicyOrder;
|
|
188
|
+
if (options.provider) {
|
|
189
|
+
provider = options.provider;
|
|
190
|
+
selectionReason = "cli-provider-override";
|
|
191
|
+
overrideSource = "dispatch-flag";
|
|
192
|
+
effectivePolicyOrder = [options.provider];
|
|
193
|
+
}
|
|
194
|
+
else if (roleProviders.length > 0) {
|
|
177
195
|
// When a role policy is configured, filter the rotation to only include
|
|
178
196
|
// providers that are allowed by the policy. This ensures that a provider
|
|
179
197
|
// present in rotation but absent from the policy is never selected.
|
|
180
198
|
const allowedByPolicy = new Set(roleProviders);
|
|
181
|
-
const configuredProviders = new Set(Object.keys(exec?.providers ?? {}));
|
|
182
199
|
const filteredRotation = rotation.filter((p) => allowedByPolicy.has(p));
|
|
200
|
+
const availablePolicyProviders = roleProviders.filter((p) => configuredProviders.has(p));
|
|
183
201
|
if (filteredRotation.length > 0 && filteredRotation[0]) {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
202
|
+
provider = filteredRotation[0];
|
|
203
|
+
selectionReason = "policy-filtered-rotation";
|
|
204
|
+
effectivePolicyOrder = filteredRotation.slice();
|
|
205
|
+
// Surface remaining configured policy providers as fallback alternatives
|
|
206
|
+
for (const p of availablePolicyProviders) {
|
|
207
|
+
if (!effectivePolicyOrder.includes(p)) {
|
|
208
|
+
effectivePolicyOrder.push(p);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
191
211
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
selectionReason: "role-policy",
|
|
201
|
-
providersTried: [availablePolicyProviders[0]],
|
|
202
|
-
};
|
|
212
|
+
else if (availablePolicyProviders.length > 0 && availablePolicyProviders[0]) {
|
|
213
|
+
provider = availablePolicyProviders[0];
|
|
214
|
+
selectionReason = "role-policy";
|
|
215
|
+
effectivePolicyOrder = availablePolicyProviders.slice();
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
// No configured provider satisfies the policy — fail clearly before dispatch.
|
|
219
|
+
throw new Error(`provider dispatch forbidden: no configured provider satisfies the "${role}" role policy (policy=${roleProviders.join(",")})`);
|
|
203
220
|
}
|
|
204
|
-
// No configured provider satisfies the policy — fail clearly before dispatch.
|
|
205
|
-
throw new Error(`provider dispatch forbidden: no configured provider satisfies the "${role}" role policy (policy=${roleProviders.join(",")})`);
|
|
206
221
|
}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
222
|
+
else if (exec?.roles?.[role]?.provider) {
|
|
223
|
+
provider = exec.roles[role].provider;
|
|
224
|
+
selectionReason = "role-config";
|
|
225
|
+
effectivePolicyOrder = [provider];
|
|
226
|
+
// If a role policy exists for this role, include its other providers as alternatives
|
|
227
|
+
for (const p of roleProviders) {
|
|
228
|
+
if (p !== provider && !effectivePolicyOrder.includes(p)) {
|
|
229
|
+
effectivePolicyOrder.push(p);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
216
232
|
}
|
|
217
|
-
if (rotation.length > 0 && rotation[0]) {
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
adapter,
|
|
222
|
-
selectionReason: "config-rotation",
|
|
223
|
-
providersTried: [rotation[0]],
|
|
224
|
-
};
|
|
233
|
+
else if (rotation.length > 0 && rotation[0]) {
|
|
234
|
+
provider = rotation[0];
|
|
235
|
+
selectionReason = "config-rotation";
|
|
236
|
+
effectivePolicyOrder = rotation.slice();
|
|
225
237
|
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
provider
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
238
|
+
else {
|
|
239
|
+
const providers = Object.keys(exec?.providers ?? {});
|
|
240
|
+
if (providers.length > 0 && providers[0]) {
|
|
241
|
+
provider = providers[0];
|
|
242
|
+
selectionReason = "config-first-provider";
|
|
243
|
+
fallbackFrom = "rotation";
|
|
244
|
+
fallbackReason = "rotation-empty";
|
|
245
|
+
effectivePolicyOrder = providers.slice();
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
selectionReason = "delegated-no-provider";
|
|
249
|
+
exhaustedReason = "no-configured-provider";
|
|
250
|
+
effectivePolicyOrder = [];
|
|
251
|
+
}
|
|
237
252
|
}
|
|
253
|
+
const fallbackEligible = !noFallback && effectivePolicyOrder.length > 1;
|
|
254
|
+
const routingSummary = {
|
|
255
|
+
selected_provider: provider ?? null,
|
|
256
|
+
selected_adapter: adapter,
|
|
257
|
+
selection_reason: selectionReason,
|
|
258
|
+
effective_policy_order: effectivePolicyOrder,
|
|
259
|
+
compatibility_mode: true,
|
|
260
|
+
registry_present: false,
|
|
261
|
+
fallback_eligible: fallbackEligible,
|
|
262
|
+
};
|
|
238
263
|
return {
|
|
239
|
-
provider
|
|
240
|
-
mode: "delegated",
|
|
264
|
+
provider,
|
|
265
|
+
mode: provider ? "direct-worker" : "delegated",
|
|
241
266
|
adapter,
|
|
242
|
-
selectionReason
|
|
243
|
-
|
|
244
|
-
|
|
267
|
+
selectionReason,
|
|
268
|
+
overrideSource,
|
|
269
|
+
fallbackFrom,
|
|
270
|
+
fallbackReason,
|
|
271
|
+
providersTried: provider ? [provider] : [],
|
|
272
|
+
exhaustedReason,
|
|
273
|
+
routingSummary,
|
|
245
274
|
};
|
|
246
275
|
}
|
|
247
276
|
function fail(message) {
|
|
@@ -464,6 +493,7 @@ function emitProviderSelected(telemetryFile, dispatchId, runId, childId, decisio
|
|
|
464
493
|
...(decision.fallbackReason ? { fallback_reason: decision.fallbackReason } : {}),
|
|
465
494
|
...(decision.providersTried.length > 0 ? { providers_tried: decision.providersTried } : {}),
|
|
466
495
|
...(decision.exhaustedReason ? { router_exhausted_reason: decision.exhaustedReason } : {}),
|
|
496
|
+
...(decision.routingSummary ? { routing_summary: decision.routingSummary } : {}),
|
|
467
497
|
...(decision.routerEvidence?.candidates?.length
|
|
468
498
|
? {
|
|
469
499
|
router_candidates: decision.routerEvidence.candidates.map((candidate) => ({
|
|
@@ -484,6 +514,7 @@ function emitProviderSelected(telemetryFile, dispatchId, runId, childId, decisio
|
|
|
484
514
|
active_slots: candidate.evidence.activeSlots,
|
|
485
515
|
slot_limit: candidate.evidence.slotLimit,
|
|
486
516
|
policy_matched: candidate.evidence.policyMatched,
|
|
517
|
+
fallback_eligible: candidate.evidence.fallbackEligible,
|
|
487
518
|
},
|
|
488
519
|
})),
|
|
489
520
|
}
|
|
@@ -574,7 +605,7 @@ function assertProviderAllowedForRole(role, provider, policy, telemetryFile, dis
|
|
|
574
605
|
/**
|
|
575
606
|
* Create a dispatch record with all required evidence.
|
|
576
607
|
*/
|
|
577
|
-
function createDispatchRecord(runId, clusterId, childId, packetPath, resultPath, roleContext, provider, providerSelectionReason, providerOverrideSource, providersTried) {
|
|
608
|
+
function createDispatchRecord(runId, clusterId, childId, packetPath, resultPath, roleContext, provider, providerSelectionReason, providerOverrideSource, providersTried, routingSummary) {
|
|
578
609
|
const dispatchMode = determineDispatchMode(provider);
|
|
579
610
|
const runtimeState = determineRuntimeState(dispatchMode);
|
|
580
611
|
return {
|
|
@@ -588,6 +619,7 @@ function createDispatchRecord(runId, clusterId, childId, packetPath, resultPath,
|
|
|
588
619
|
provider_selection_reason: providerSelectionReason,
|
|
589
620
|
provider_override_source: providerOverrideSource,
|
|
590
621
|
providers_tried: providersTried && providersTried.length > 0 ? providersTried : undefined,
|
|
622
|
+
routing_summary: routingSummary,
|
|
591
623
|
dispatched_at: new Date().toISOString(),
|
|
592
624
|
status: "dispatched",
|
|
593
625
|
dispatch_mode: dispatchMode,
|
|
@@ -755,6 +787,7 @@ function ledgerLastCommit(state) {
|
|
|
755
787
|
return state.last_commit && state.last_commit.length > 0 ? state.last_commit : null;
|
|
756
788
|
}
|
|
757
789
|
function appendDispatchLedgerEvent(repoRoot, state, childId) {
|
|
790
|
+
const routingSummary = state.open_children_meta?.[childId]?.dispatch_record?.routing_summary;
|
|
758
791
|
new ledger_js_1.LedgerWriter((0, node_path_1.join)(repoRoot, ledger_js_1.DEFAULT_LEDGER_PATH)).append({
|
|
759
792
|
schema_version: 1,
|
|
760
793
|
event_id: (0, node_crypto_1.randomUUID)(),
|
|
@@ -772,6 +805,7 @@ function appendDispatchLedgerEvent(repoRoot, state, childId) {
|
|
|
772
805
|
pr_url: null,
|
|
773
806
|
timestamp: new Date().toISOString(),
|
|
774
807
|
dispatch_epoch: state.dispatch_boundary?.dispatch_epoch ?? 0,
|
|
808
|
+
...(routingSummary ? { routing_summary: routingSummary } : {}),
|
|
775
809
|
});
|
|
776
810
|
}
|
|
777
811
|
function selectChild(state, requestedChild) {
|
|
@@ -1189,7 +1223,7 @@ function runLoopDispatch(options) {
|
|
|
1189
1223
|
fail(`Failed to write packet artifact to ${packetPath}: ${errorMsg}`);
|
|
1190
1224
|
}
|
|
1191
1225
|
// Create dispatch record with all evidence
|
|
1192
|
-
const dispatchRecord = createDispatchRecord(state.run_id, state.cluster_id, childId, relativePacketPath, relativeEffectiveResultPath, packet.role_context, resolvedProvider, providerDecision.selectionReason, providerDecision.overrideSource, providerDecision.providersTried);
|
|
1226
|
+
const dispatchRecord = createDispatchRecord(state.run_id, state.cluster_id, childId, relativePacketPath, relativeEffectiveResultPath, packet.role_context, resolvedProvider, providerDecision.selectionReason, providerDecision.overrideSource, providerDecision.providersTried, providerDecision.routingSummary);
|
|
1193
1227
|
emitProviderFallbackAttempted(telemetryFile, dispatchRecord.dispatch_id, state.run_id, childId, providerDecision);
|
|
1194
1228
|
emitProviderExhausted(telemetryFile, dispatchRecord.dispatch_id, state.run_id, childId, providerDecision);
|
|
1195
1229
|
emitProviderSelected(telemetryFile, dispatchRecord.dispatch_id, state.run_id, childId, providerDecision);
|
|
@@ -1245,6 +1279,7 @@ function runLoopDispatch(options) {
|
|
|
1245
1279
|
dispatch_mode: dispatchRecord.dispatch_mode,
|
|
1246
1280
|
runtime_state: dispatchRecord.runtime_state,
|
|
1247
1281
|
provider: dispatchRecord.provider ?? null,
|
|
1282
|
+
routing_summary: dispatchRecord.routing_summary ?? null,
|
|
1248
1283
|
timestamp: new Date().toISOString(),
|
|
1249
1284
|
});
|
|
1250
1285
|
// ── Apply lifecycle transition for child-dispatch event ────────────────────
|
package/dist/loop/parent.js
CHANGED
|
@@ -254,6 +254,7 @@ function appendChildCompletedLedgerEvent(repoRoot, state, completedChild, lastCo
|
|
|
254
254
|
...(completion?.providersTried?.length
|
|
255
255
|
? { providers_tried: completion.providersTried }
|
|
256
256
|
: {}),
|
|
257
|
+
...(completion?.routingSummary ? { routing_summary: completion.routingSummary } : {}),
|
|
257
258
|
});
|
|
258
259
|
}
|
|
259
260
|
function appendClusterCompletedLedgerEvent(repoRoot, state) {
|
|
@@ -435,6 +436,7 @@ function buildParentDispatchRecord(args) {
|
|
|
435
436
|
provider: args.provider,
|
|
436
437
|
provider_selection_reason: args.providerSelectionReason,
|
|
437
438
|
providers_tried: args.providersTried,
|
|
439
|
+
routing_summary: args.routingSummary,
|
|
438
440
|
dispatched_at: args.dispatchedAt,
|
|
439
441
|
status: "dispatched",
|
|
440
442
|
dispatch_mode: "direct-worker",
|
|
@@ -557,15 +559,16 @@ async function syncClusterCompletion(args) {
|
|
|
557
559
|
output: String(args.validationSummary),
|
|
558
560
|
},
|
|
559
561
|
};
|
|
562
|
+
const relativeResultFile = args.resultFile ? (0, node_path_1.relative)(args.repoRoot, args.resultFile) : args.resultFile;
|
|
560
563
|
await (0, store_js_1.writeClusterState)(args.clusterId, {
|
|
561
564
|
...clusterState,
|
|
562
565
|
state_generation: clusterState.state_generation + 1,
|
|
563
566
|
child_states: childStates,
|
|
564
567
|
claim_metadata: Object.fromEntries(Object.entries(clusterState.claim_metadata).filter(([childId]) => childId !== args.childId)),
|
|
565
|
-
result_pointers:
|
|
568
|
+
result_pointers: relativeResultFile
|
|
566
569
|
? {
|
|
567
570
|
...clusterState.result_pointers,
|
|
568
|
-
[args.childId]:
|
|
571
|
+
[args.childId]: relativeResultFile,
|
|
569
572
|
}
|
|
570
573
|
: clusterState.result_pointers,
|
|
571
574
|
validation_results: nextValidationResults,
|
|
@@ -594,6 +597,7 @@ async function syncClusterDispatch(args) {
|
|
|
594
597
|
}
|
|
595
598
|
: child)
|
|
596
599
|
: [...clusterState.child_states, { id: args.childId, status: "dispatched" }];
|
|
600
|
+
const relativePacketPath = (0, node_path_1.relative)(args.repoRoot, args.packetPath);
|
|
597
601
|
await (0, store_js_1.writeClusterState)(args.clusterId, {
|
|
598
602
|
...clusterState,
|
|
599
603
|
state_generation: clusterState.state_generation + 1,
|
|
@@ -608,7 +612,7 @@ async function syncClusterDispatch(args) {
|
|
|
608
612
|
},
|
|
609
613
|
packet_pointers: {
|
|
610
614
|
...clusterState.packet_pointers,
|
|
611
|
-
[args.childId]:
|
|
615
|
+
[args.childId]: relativePacketPath,
|
|
612
616
|
},
|
|
613
617
|
}, args.repoRoot);
|
|
614
618
|
return true;
|
|
@@ -692,10 +696,20 @@ async function runParentLoop(options) {
|
|
|
692
696
|
let providerName;
|
|
693
697
|
let providerSelectionReason;
|
|
694
698
|
let providersTried;
|
|
699
|
+
let routingSummary;
|
|
695
700
|
if (adapterName === "agent-subtask") {
|
|
696
701
|
providerName = "agent-subtask";
|
|
697
702
|
providerSelectionReason = "agent-subtask-adapter";
|
|
698
703
|
providersTried = ["agent-subtask"];
|
|
704
|
+
routingSummary = {
|
|
705
|
+
selected_provider: "agent-subtask",
|
|
706
|
+
selected_adapter: "agent-subtask",
|
|
707
|
+
selection_reason: "agent-subtask-adapter",
|
|
708
|
+
effective_policy_order: ["agent-subtask"],
|
|
709
|
+
compatibility_mode: false,
|
|
710
|
+
registry_present: false,
|
|
711
|
+
fallback_eligible: false,
|
|
712
|
+
};
|
|
699
713
|
}
|
|
700
714
|
else {
|
|
701
715
|
let evidence;
|
|
@@ -713,6 +727,7 @@ async function runParentLoop(options) {
|
|
|
713
727
|
providerName = evidence.provider ?? "default";
|
|
714
728
|
providerSelectionReason = evidence.selectionReason;
|
|
715
729
|
providersTried = evidence.providersTried;
|
|
730
|
+
routingSummary = evidence.routingSummary;
|
|
716
731
|
}
|
|
717
732
|
const executionConfig = adapterName === "agent-subtask"
|
|
718
733
|
? { ...(config.execution ?? { providers: {} }), adapter: "agent-subtask" }
|
|
@@ -1489,6 +1504,7 @@ async function runParentLoop(options) {
|
|
|
1489
1504
|
provider: providerName,
|
|
1490
1505
|
providerSelectionReason,
|
|
1491
1506
|
providersTried,
|
|
1507
|
+
routingSummary,
|
|
1492
1508
|
workerId,
|
|
1493
1509
|
dispatchedAt,
|
|
1494
1510
|
});
|
|
@@ -1563,6 +1579,7 @@ async function runParentLoop(options) {
|
|
|
1563
1579
|
dry_run: dryRun,
|
|
1564
1580
|
selected_slot_claim: selectedSlotClaim ?? null,
|
|
1565
1581
|
slot_claims: nextSlotClaims,
|
|
1582
|
+
routing_summary: routingSummary ?? null,
|
|
1566
1583
|
timestamp: new Date().toISOString(),
|
|
1567
1584
|
});
|
|
1568
1585
|
emitBootstrapContextSize(telemetryFile, state.run_id, nextChild, stateFile, packet);
|
|
@@ -2213,6 +2230,7 @@ async function runParentLoop(options) {
|
|
|
2213
2230
|
model: modelUsed,
|
|
2214
2231
|
router_selection_reason: dispatchRecord?.provider_selection_reason,
|
|
2215
2232
|
providers_tried: dispatchRecord?.providers_tried,
|
|
2233
|
+
routing_summary: dispatchRecord?.routing_summary ?? null,
|
|
2216
2234
|
timestamp: new Date().toISOString(),
|
|
2217
2235
|
};
|
|
2218
2236
|
if (elapsedSeconds !== undefined) {
|
|
@@ -2228,6 +2246,7 @@ async function runParentLoop(options) {
|
|
|
2228
2246
|
completionStatus: workerStatus,
|
|
2229
2247
|
routerSelectionReason: dispatchRecord?.provider_selection_reason,
|
|
2230
2248
|
providersTried: dispatchRecord?.providers_tried,
|
|
2249
|
+
routingSummary: dispatchRecord?.routing_summary,
|
|
2231
2250
|
});
|
|
2232
2251
|
}
|
|
2233
2252
|
if (orchestrationMode === 'supervised') {
|
|
@@ -220,7 +220,10 @@ async function ensureClusterRunState(options) {
|
|
|
220
220
|
}
|
|
221
221
|
}
|
|
222
222
|
}
|
|
223
|
-
const
|
|
223
|
+
const graph = await loadOrSyncGraph(clusterId, repoRoot);
|
|
224
|
+
const { openChildren, openChildrenMeta } = buildBootstrapPlan(clusterId, graph, repoRoot);
|
|
225
|
+
// Persist canonical child ordering and any body-derived ordering dependencies.
|
|
226
|
+
await graph.save(clusterId, repoRoot);
|
|
224
227
|
await bootstrapHandler({
|
|
225
228
|
clusterId,
|
|
226
229
|
openChildren,
|
|
@@ -10,6 +10,39 @@
|
|
|
10
10
|
* WorkerPacket extends BootstrapPacket so all existing adapters that
|
|
11
11
|
* accept BootstrapPacket transparently accept WorkerPacket.
|
|
12
12
|
*/
|
|
13
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
16
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
17
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
18
|
+
}
|
|
19
|
+
Object.defineProperty(o, k2, desc);
|
|
20
|
+
}) : (function(o, m, k, k2) {
|
|
21
|
+
if (k2 === undefined) k2 = k;
|
|
22
|
+
o[k2] = m[k];
|
|
23
|
+
}));
|
|
24
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
25
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
26
|
+
}) : function(o, v) {
|
|
27
|
+
o["default"] = v;
|
|
28
|
+
});
|
|
29
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
30
|
+
var ownKeys = function(o) {
|
|
31
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
32
|
+
var ar = [];
|
|
33
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
34
|
+
return ar;
|
|
35
|
+
};
|
|
36
|
+
return ownKeys(o);
|
|
37
|
+
};
|
|
38
|
+
return function (mod) {
|
|
39
|
+
if (mod && mod.__esModule) return mod;
|
|
40
|
+
var result = {};
|
|
41
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
42
|
+
__setModuleDefault(result, mod);
|
|
43
|
+
return result;
|
|
44
|
+
};
|
|
45
|
+
})();
|
|
13
46
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
47
|
exports.REPAIR_RETURN_CONTRACT = exports.STARTUP_RETURN_CONTRACT = exports.PREFLIGHT_RETURN_CONTRACT = exports.WORKER_SYMPTOM_CATEGORIES = exports.WORKER_PROHIBITED_WRITE_PATHS = exports.FINALIZE_RETURN_CONTRACT = exports.IMPL_RETURN_CONTRACT = void 0;
|
|
15
48
|
exports.roleContextForWorkerRole = roleContextForWorkerRole;
|
|
@@ -20,6 +53,7 @@ exports.compileImplPacket = compileImplPacket;
|
|
|
20
53
|
exports.compileFinalizePacket = compileFinalizePacket;
|
|
21
54
|
exports.compilePreflightPacket = compilePreflightPacket;
|
|
22
55
|
exports.compileRepairWorkerPacket = compileRepairWorkerPacket;
|
|
56
|
+
const path = __importStar(require("node:path"));
|
|
23
57
|
const worker_prompt_js_1 = require("./worker-prompt.js");
|
|
24
58
|
const body_parser_js_1 = require("./body-parser.js");
|
|
25
59
|
const WORKER_ROLE_CONTEXT = {
|
|
@@ -172,6 +206,49 @@ function defaultLifecycle(maxConcurrent, cleanupOnExit) {
|
|
|
172
206
|
cleanup_on_exit: cleanupOnExit,
|
|
173
207
|
};
|
|
174
208
|
}
|
|
209
|
+
/** Derives the adjacent test file path(s) for a single source TypeScript file. */
|
|
210
|
+
function deriveTestPaths(sourcePath) {
|
|
211
|
+
if (!sourcePath.endsWith('.ts') || sourcePath.endsWith('.test.ts') || sourcePath.endsWith('.d.ts')) {
|
|
212
|
+
return [];
|
|
213
|
+
}
|
|
214
|
+
if (sourcePath.includes('*') || sourcePath.includes('?')) {
|
|
215
|
+
return [];
|
|
216
|
+
}
|
|
217
|
+
const candidates = [sourcePath.replace(/\.ts$/, '.test.ts')];
|
|
218
|
+
if (sourcePath.endsWith('/index.ts')) {
|
|
219
|
+
const dir = sourcePath.slice(0, -'/index.ts'.length);
|
|
220
|
+
const dirName = path.basename(dir);
|
|
221
|
+
if (dirName) {
|
|
222
|
+
candidates.push(`${dir}/${dirName}.test.ts`);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return candidates;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Expands an allowed scope list with adjacent test paths when the validation
|
|
229
|
+
* commands include a vitest run. This lets workers touch test files for source
|
|
230
|
+
* files they are modifying, matching the `*.test.ts` validation commands.
|
|
231
|
+
*/
|
|
232
|
+
function expandScopeWithTestPaths(scope, validationCommands) {
|
|
233
|
+
const hasVitest = validationCommands.some((cmd) => cmd.includes('vitest'));
|
|
234
|
+
if (!hasVitest || scope.length === 0)
|
|
235
|
+
return scope;
|
|
236
|
+
const testPaths = new Set();
|
|
237
|
+
for (const item of scope) {
|
|
238
|
+
for (const testPath of deriveTestPaths(item)) {
|
|
239
|
+
testPaths.add(testPath);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
if (testPaths.size === 0)
|
|
243
|
+
return scope;
|
|
244
|
+
const expanded = [...scope];
|
|
245
|
+
for (const testPath of testPaths) {
|
|
246
|
+
if (!expanded.includes(testPath)) {
|
|
247
|
+
expanded.push(testPath);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
return expanded;
|
|
251
|
+
}
|
|
175
252
|
/**
|
|
176
253
|
* Build a compiled startup worker packet.
|
|
177
254
|
* Startup workers prepare tracker/graph/config/run-state evidence; the parent
|
|
@@ -257,6 +334,8 @@ function compileImplPacket(input) {
|
|
|
257
334
|
const resolvedRequirements = input.issueContext?.key_requirements.length
|
|
258
335
|
? input.issueContext.key_requirements
|
|
259
336
|
: bodyParsed?.requirements ?? [];
|
|
337
|
+
// Include adjacent test files when the validation commands indicate a vitest run.
|
|
338
|
+
const expandedScope = expandScopeWithTestPaths(resolvedScope, resolvedValidation);
|
|
260
339
|
const requirementLines = resolvedRequirements.map((r, i) => ` ${i + 1}. ${r}`);
|
|
261
340
|
const bodyLines = input.issueContext?.body
|
|
262
341
|
? [`Issue description:\n${input.issueContext.body}`]
|
|
@@ -285,7 +364,7 @@ function compileImplPacket(input) {
|
|
|
285
364
|
stateFile: input.stateFile,
|
|
286
365
|
telemetryFile: input.telemetryFile,
|
|
287
366
|
issueContext: input.issueContext,
|
|
288
|
-
allowedScope:
|
|
367
|
+
allowedScope: expandedScope,
|
|
289
368
|
validationCommands: resolvedValidation,
|
|
290
369
|
mode: promptMode,
|
|
291
370
|
simplicityMode: input.simplicityMode,
|
|
@@ -301,7 +380,7 @@ function compileImplPacket(input) {
|
|
|
301
380
|
instructions: {
|
|
302
381
|
primary_goal: promptResult.prompt,
|
|
303
382
|
steps,
|
|
304
|
-
allowed_scope:
|
|
383
|
+
allowed_scope: expandedScope,
|
|
305
384
|
validation_commands: resolvedValidation,
|
|
306
385
|
issue_context: input.issueContext,
|
|
307
386
|
},
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Polaris routing anomaly → Medic/state-repair signal classification.
|
|
4
|
+
*
|
|
5
|
+
* These signals are emitted by the loop/dispatch/runtime boundary and are
|
|
6
|
+
* reviewed by Medic, not used to mutate routing.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.classifyRoutingTelemetryEvent = classifyRoutingTelemetryEvent;
|
|
10
|
+
/**
|
|
11
|
+
* Map a raw telemetry event to a state-repair review signal.
|
|
12
|
+
*
|
|
13
|
+
* Only loop/dispatch boundary events that indicate runtime state-repair work
|
|
14
|
+
* are classified. The returned signal has occurrences=1 and a single child_id;
|
|
15
|
+
* consumers (such as SOL scoring) should aggregate by signal name.
|
|
16
|
+
*/
|
|
17
|
+
function classifyRoutingTelemetryEvent(event) {
|
|
18
|
+
const eventName = event["event"];
|
|
19
|
+
if (typeof eventName !== "string")
|
|
20
|
+
return undefined;
|
|
21
|
+
const childId = typeof event["child_id"] === "string" ? event["child_id"] : undefined;
|
|
22
|
+
const childIds = childId ? [childId] : [];
|
|
23
|
+
switch (eventName) {
|
|
24
|
+
case "sealed-result-read-error":
|
|
25
|
+
return {
|
|
26
|
+
signal: "missing-sealed-result",
|
|
27
|
+
reason: "missing-sealed-result",
|
|
28
|
+
occurrences: 1,
|
|
29
|
+
child_ids: childIds,
|
|
30
|
+
};
|
|
31
|
+
case "stale-dispatch-aborted":
|
|
32
|
+
return {
|
|
33
|
+
signal: "stale-dispatch-abort",
|
|
34
|
+
reason: "stale-dispatch-abort",
|
|
35
|
+
occurrences: 1,
|
|
36
|
+
child_ids: childIds,
|
|
37
|
+
};
|
|
38
|
+
case "invalid-inline-attempt":
|
|
39
|
+
return {
|
|
40
|
+
signal: "invalid-inline-attempt",
|
|
41
|
+
reason: "invalid-inline-attempt",
|
|
42
|
+
occurrences: 1,
|
|
43
|
+
child_ids: childIds,
|
|
44
|
+
};
|
|
45
|
+
case "child-recovery-initiated": {
|
|
46
|
+
const recoveryReason = event["recovery_reason"];
|
|
47
|
+
if (recoveryReason === "stale-dispatch") {
|
|
48
|
+
return {
|
|
49
|
+
signal: "stale-dispatch-abort",
|
|
50
|
+
reason: "stale-dispatch",
|
|
51
|
+
occurrences: 1,
|
|
52
|
+
child_ids: childIds,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
default:
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
}
|
package/dist/qc/policy.js
CHANGED