opencode-swarm 7.136.5 → 7.137.1
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/.opencode/skills/swarm-pr-review/SKILL.md +35 -3
- package/.opencode/skills/swarm-pr-review/references/prompt-templates.md +7 -3
- package/dist/agents/agent-output-schema.d.ts +2 -2
- package/dist/background/candidate-contract.d.ts +14 -0
- package/dist/cli/{config-doctor-n3hatm9d.js → config-doctor-b9r9rt2c.js} +2 -2
- package/dist/cli/{core-jpjk2qvt.js → core-6w5sd5bc.js} +1 -1
- package/dist/cli/{curation-policy-c4g08bg1.js → curation-policy-ftx2emfw.js} +7 -6
- package/dist/cli/{curator-jc5cc980.js → curator-1sxxtbq7.js} +25 -25
- package/dist/cli/{curator-llm-factory-atfnhbn6.js → curator-llm-factory-yhqbkc5w.js} +25 -25
- package/dist/cli/{evidence-summary-service-nse06dqr.js → evidence-summary-service-85gw9p2m.js} +7 -7
- package/dist/cli/{gate-evidence-kdygjr56.js → gate-evidence-s2kytsrj.js} +4 -4
- package/dist/cli/{guardrail-explain-v6f8efve.js → guardrail-explain-qh1y8jsz.js} +26 -26
- package/dist/cli/{guardrail-log-0mrq14g9.js → guardrail-log-84zffdv3.js} +3 -3
- package/dist/cli/{hive-promoter-wyejhz8b.js → hive-promoter-hpe29xrz.js} +25 -25
- package/dist/cli/{index-eeb35dnx.js → index-1qn2gchc.js} +3 -2
- package/dist/cli/{index-45y0y3xh.js → index-1zrb3vt2.js} +7 -7
- package/dist/cli/{index-d2sf9an1.js → index-5r6kkhd7.js} +4 -4
- package/dist/cli/{index-ne28wyyc.js → index-5wjw05dy.js} +2 -2
- package/dist/cli/{index-xvcctb2t.js → index-7e60c7ay.js} +27 -27
- package/dist/cli/{index-7t3vjw5e.js → index-877ah4kx.js} +1 -1
- package/dist/cli/{index-tncy55bp.js → index-8ehyt3rx.js} +1 -1
- package/dist/cli/{index-hbzh7yyz.js → index-9vqxf9pd.js} +633 -209
- package/dist/cli/{index-6kd0ezgd.js → index-a3gpeb4f.js} +2 -2
- package/dist/cli/{index-nfm9f10v.js → index-b2s3t517.js} +5 -3
- package/dist/cli/{index-8f4346kf.js → index-bxk0a1r9.js} +2 -2
- package/dist/cli/{index-pyz1p8qv.js → index-d67810xe.js} +1 -1
- package/dist/cli/{index-akc6rp3x.js → index-d8rc8c9y.js} +2 -2
- package/dist/cli/{index-hh34tyv7.js → index-dxatvs3f.js} +1 -1
- package/dist/cli/{index-bqan4y2y.js → index-e0nvge1c.js} +2 -2
- package/dist/cli/{index-f5qs217h.js → index-em10pmph.js} +1 -1
- package/dist/cli/{index-j7ja83v5.js → index-gd47gp2q.js} +1 -1
- package/dist/cli/{index-w6j1n5az.js → index-gv00q5gc.js} +1 -1
- package/dist/cli/index-h5sbn1zr.js +1670 -0
- package/dist/cli/{index-vm05set2.js → index-k8y41t4y.js} +4 -4
- package/dist/cli/{index-tr0ctbhq.js → index-m4s91910.js} +5 -5
- package/dist/cli/{index-b3jfcptk.js → index-n3h6rmbe.js} +1 -1
- package/dist/cli/{index-xp2pfbpq.js → index-pbe51g7h.js} +1 -1
- package/dist/cli/{index-kym0cctr.js → index-qy3rgmkc.js} +1 -1
- package/dist/cli/{index-d61h3f3h.js → index-s3j9fsab.js} +2 -2
- package/dist/cli/{index-qhbr4h5n.js → index-t2mv25yf.js} +6 -6
- package/dist/cli/{index-84se71v1.js → index-t5099rx9.js} +3 -3
- package/dist/cli/{index-zzhyws9g.js → index-vft1pg34.js} +1 -1
- package/dist/cli/{index-yj61bped.js → index-zxf5w0jj.js} +3 -3
- package/dist/cli/index.js +25 -25
- package/dist/cli/{knowledge-escalator-2xe8z24p.js → knowledge-escalator-3ds615yq.js} +8 -7
- package/dist/cli/{knowledge-events-wecrshsx.js → knowledge-events-3c0g2xbm.js} +6 -5
- package/dist/cli/{knowledge-link-zr40rnwr.js → knowledge-link-t94b79qe.js} +5 -4
- package/dist/cli/{knowledge-store-9f74whxw.js → knowledge-store-pq43990j.js} +6 -5
- package/dist/cli/{knowledge-validator-4ng7x9dr.js → knowledge-validator-gepda374.js} +9 -8
- package/dist/cli/{pending-delegations-0h5b18p7.js → pending-delegations-kshh66s2.js} +3 -3
- package/dist/cli/{pr-subscriptions-jn0h047q.js → pr-subscriptions-5fpzz4f3.js} +3 -3
- package/dist/cli/{runner-deeswadt.js → runner-9rqc8y3m.js} +5 -5
- package/dist/cli/{scan-cursor-yzj9n225.js → scan-cursor-5hq37qdg.js} +7 -6
- package/dist/cli/{schema-cr1nr1w0.js → schema-mrbyt7dg.js} +1 -1
- package/dist/cli/{scope-persistence-5xc9ntdh.js → scope-persistence-sjz200dt.js} +4 -4
- package/dist/cli/{skill-generator-ybncj9et.js → skill-generator-3gt8em6v.js} +10 -9
- package/dist/cli/{telemetry-6678gya0.js → telemetry-h7h7f0ez.js} +2 -1
- package/dist/cli/{worktree-collision-ownership-wt7cc850.js → worktree-collision-ownership-xzwab4xt.js} +3 -3
- package/dist/config/constants.d.ts +1 -1
- package/dist/config/evidence-schema.d.ts +103 -103
- package/dist/config/plan-schema.d.ts +10 -10
- package/dist/config/schema.d.ts +8 -8
- package/dist/consensus/contracts.d.ts +3 -3
- package/dist/evaluation/index.d.ts +1 -0
- package/dist/evaluation/model-dispatcher.d.ts +19 -1
- package/dist/evaluation/pr-review-recovery.d.ts +41 -0
- package/dist/evaluation/public-api.d.ts +2 -0
- package/dist/evaluation/runner.d.ts +9 -0
- package/dist/hooks/hive-promoter.d.ts +1 -1
- package/dist/hooks/pr-workflow-gate.d.ts +69 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +225 -225
- package/dist/observability/catalog.d.ts +84 -0
- package/dist/observability/envelope.d.ts +401 -0
- package/dist/observability/ids.d.ts +97 -0
- package/dist/observability/index.d.ts +58 -0
- package/dist/observability/legacy.d.ts +68 -0
- package/dist/observability/observe.d.ts +112 -0
- package/dist/observability/otel-mapping.d.ts +48 -0
- package/dist/observability/relationships.d.ts +44 -0
- package/dist/observability/sampling.d.ts +77 -0
- package/dist/summaries/schema.d.ts +2 -2
- package/dist/telemetry.d.ts +4 -1
- package/dist/tools/dispatch-lanes.d.ts +1 -0
- package/evaluation-fixtures/pr-review-recovery/baseline/SKILL.md +1823 -0
- package/evaluation-fixtures/pr-review-recovery/baseline-manifest.json +1 -0
- package/evaluation-fixtures/pr-review-recovery/environment/score-recovery.cjs +135 -0
- package/evaluation-fixtures/pr-review-recovery/instruction.md +40 -0
- package/evaluation-fixtures/pr-review-recovery/scorer-fixtures/blind-full-wave-retry/model-output.json +1 -0
- package/evaluation-fixtures/pr-review-recovery/scorer-fixtures/contradictory/model-output.json +1 -0
- package/evaluation-fixtures/pr-review-recovery/scorer-fixtures/copied-contract/model-output.json +1 -0
- package/evaluation-fixtures/pr-review-recovery/scorer-fixtures/critical-without-harm/model-output.json +1 -0
- package/evaluation-fixtures/pr-review-recovery/scorer-fixtures/invented-harm/model-output.json +1 -0
- package/evaluation-fixtures/pr-review-recovery/scorer-fixtures/malformed/model-output.json +1 -0
- package/evaluation-fixtures/pr-review-recovery/scorer-fixtures/missing-reproduction/model-output.json +1 -0
- package/evaluation-fixtures/pr-review-recovery/scorer-fixtures/parser-only/model-output.json +1 -0
- package/evaluation-fixtures/pr-review-recovery/scorer-fixtures/passing/model-output.json +1 -0
- package/evaluation-fixtures/pr-review-recovery/scorer-fixtures/premature-systemic-claim/model-output.json +1 -0
- package/evaluation-fixtures/pr-review-recovery/scorer-fixtures/profile-b-fallback/model-output.json +1 -0
- package/evaluation-fixtures/pr-review-recovery/scorer-fixtures/underclaimed-harm/model-output.json +1 -0
- package/evaluation-fixtures/pr-review-recovery/scorer-fixtures/unsupported-severity/model-output.json +1 -0
- package/package.json +3 -2
- package/dist/cli/index-cze4bq1x.js +0 -358
|
@@ -8,20 +8,21 @@ import {
|
|
|
8
8
|
} from "./index-vm4xw9z3.js";
|
|
9
9
|
import {
|
|
10
10
|
captureWorkingTreeFingerprint,
|
|
11
|
+
createModelEvaluationExecutor,
|
|
11
12
|
pLimit,
|
|
12
13
|
resolveExecutableFromPath,
|
|
13
14
|
runEvaluation,
|
|
14
15
|
runExternalTool
|
|
15
|
-
} from "./index-
|
|
16
|
+
} from "./index-b2s3t517.js";
|
|
16
17
|
import {
|
|
17
18
|
stableCanonicalStringify
|
|
18
|
-
} from "./index-
|
|
19
|
+
} from "./index-em10pmph.js";
|
|
19
20
|
import {
|
|
20
21
|
detectStraySwarmDirs,
|
|
21
22
|
readDoctorArtifact,
|
|
22
23
|
removeStraySwarmDir,
|
|
23
24
|
runConfigDoctor
|
|
24
|
-
} from "./index-
|
|
25
|
+
} from "./index-gd47gp2q.js";
|
|
25
26
|
import {
|
|
26
27
|
MAX_TRANSIENT_RETRIES,
|
|
27
28
|
archiveEvidence,
|
|
@@ -58,7 +59,7 @@ import {
|
|
|
58
59
|
savePlan,
|
|
59
60
|
transientBackoff,
|
|
60
61
|
validateProjectRoot
|
|
61
|
-
} from "./index-
|
|
62
|
+
} from "./index-1zrb3vt2.js";
|
|
62
63
|
import {
|
|
63
64
|
EvaluationTaskV1Schema,
|
|
64
65
|
GateAuditManifestV1Schema,
|
|
@@ -75,7 +76,7 @@ import {
|
|
|
75
76
|
saveGateAuditResult,
|
|
76
77
|
savePromotionDecision,
|
|
77
78
|
saveTaskSetSnapshot
|
|
78
|
-
} from "./index-
|
|
79
|
+
} from "./index-5wjw05dy.js";
|
|
79
80
|
import {
|
|
80
81
|
canonicalHash,
|
|
81
82
|
canonicalJson,
|
|
@@ -113,15 +114,15 @@ import {
|
|
|
113
114
|
retireSkill,
|
|
114
115
|
selectCandidateEntries,
|
|
115
116
|
syncBundledProjectSkillsIfMissingAsync
|
|
116
|
-
} from "./index-
|
|
117
|
+
} from "./index-zxf5w0jj.js";
|
|
117
118
|
import {
|
|
118
119
|
readRecentEscalations
|
|
119
|
-
} from "./index-
|
|
120
|
+
} from "./index-m4s91910.js";
|
|
120
121
|
import {
|
|
121
122
|
alreadyCuratedThisGeneration,
|
|
122
123
|
claimNextScanBatch,
|
|
123
124
|
resolveCohortId
|
|
124
|
-
} from "./index-
|
|
125
|
+
} from "./index-bxk0a1r9.js";
|
|
125
126
|
import {
|
|
126
127
|
CURATOR_INIT_PROMPT,
|
|
127
128
|
CURATOR_PHASE_PROMPT,
|
|
@@ -174,11 +175,11 @@ import {
|
|
|
174
175
|
validateActionableFields,
|
|
175
176
|
validateLesson,
|
|
176
177
|
validateSkillPath
|
|
177
|
-
} from "./index-
|
|
178
|
+
} from "./index-k8y41t4y.js";
|
|
178
179
|
import {
|
|
179
180
|
authorizeCuration,
|
|
180
181
|
buildConfigFingerprintInput
|
|
181
|
-
} from "./index-
|
|
182
|
+
} from "./index-a3gpeb4f.js";
|
|
182
183
|
import {
|
|
183
184
|
cohortConfigFingerprint
|
|
184
185
|
} from "./index-rtry5xyf.js";
|
|
@@ -211,7 +212,7 @@ import {
|
|
|
211
212
|
transactFile,
|
|
212
213
|
transactKnowledge,
|
|
213
214
|
wordBigrams
|
|
214
|
-
} from "./index-
|
|
215
|
+
} from "./index-t2mv25yf.js";
|
|
215
216
|
import {
|
|
216
217
|
MAX_EVENT_LOG_ENTRIES,
|
|
217
218
|
_internals,
|
|
@@ -221,7 +222,7 @@ import {
|
|
|
221
222
|
recordHiveKnowledgeEvent,
|
|
222
223
|
recordKnowledgeEvent,
|
|
223
224
|
resolveKnowledgeEventsPath
|
|
224
|
-
} from "./index-
|
|
225
|
+
} from "./index-t5099rx9.js";
|
|
225
226
|
import {
|
|
226
227
|
resolveHiveDataDir,
|
|
227
228
|
resolveHiveEventsPath,
|
|
@@ -237,16 +238,16 @@ import {
|
|
|
237
238
|
resolveLinkDir,
|
|
238
239
|
sanitizeLinkId,
|
|
239
240
|
writeLinkPointer
|
|
240
|
-
} from "./index-
|
|
241
|
+
} from "./index-vft1pg34.js";
|
|
241
242
|
import {
|
|
242
243
|
atomicWriteFile
|
|
243
|
-
} from "./index-
|
|
244
|
+
} from "./index-n3h6rmbe.js";
|
|
244
245
|
import {
|
|
245
246
|
exports_loader,
|
|
246
247
|
init_loader,
|
|
247
248
|
loadPluginConfig,
|
|
248
249
|
loadPluginConfigWithMeta
|
|
249
|
-
} from "./index-
|
|
250
|
+
} from "./index-d67810xe.js";
|
|
250
251
|
import {
|
|
251
252
|
RetrospectiveEvidenceSchema
|
|
252
253
|
} from "./index-k5jrywpr.js";
|
|
@@ -262,7 +263,7 @@ import {
|
|
|
262
263
|
package_default,
|
|
263
264
|
resolveAutoReviewConfig,
|
|
264
265
|
stripKnownSwarmPrefix
|
|
265
|
-
} from "./index-
|
|
266
|
+
} from "./index-1qn2gchc.js";
|
|
266
267
|
import {
|
|
267
268
|
KNOWLEDGE_SCHEMA_VERSION,
|
|
268
269
|
OUTCOME_BLOCK_THRESHOLD,
|
|
@@ -278,13 +279,13 @@ import {
|
|
|
278
279
|
listActive,
|
|
279
280
|
subscribe,
|
|
280
281
|
unsubscribe
|
|
281
|
-
} from "./index-
|
|
282
|
+
} from "./index-qy3rgmkc.js";
|
|
282
283
|
import {
|
|
283
284
|
MAX_PENDING_SCOPE_BINDINGS,
|
|
284
285
|
clearAllScopes,
|
|
285
286
|
clearScopeBindingFromDisk,
|
|
286
287
|
clearScopeBindings
|
|
287
|
-
} from "./index-
|
|
288
|
+
} from "./index-gv00q5gc.js";
|
|
288
289
|
import {
|
|
289
290
|
appendLedgerEvent,
|
|
290
291
|
computePlanHash,
|
|
@@ -292,7 +293,7 @@ import {
|
|
|
292
293
|
derivePlanId,
|
|
293
294
|
initLedger,
|
|
294
295
|
takeSnapshotEvent
|
|
295
|
-
} from "./index-
|
|
296
|
+
} from "./index-s3j9fsab.js";
|
|
296
297
|
import {
|
|
297
298
|
PlanSchema
|
|
298
299
|
} from "./index-1kz6da87.js";
|
|
@@ -319,7 +320,7 @@ import {
|
|
|
319
320
|
import {
|
|
320
321
|
findByBatchId,
|
|
321
322
|
readDelegations
|
|
322
|
-
} from "./index-
|
|
323
|
+
} from "./index-877ah4kx.js";
|
|
323
324
|
import {
|
|
324
325
|
readSwarmFileAsync,
|
|
325
326
|
safeHook,
|
|
@@ -328,19 +329,19 @@ import {
|
|
|
328
329
|
import {
|
|
329
330
|
tryAcquireLock,
|
|
330
331
|
withEvidenceLock
|
|
331
|
-
} from "./index-
|
|
332
|
+
} from "./index-8ehyt3rx.js";
|
|
332
333
|
import {
|
|
333
334
|
require_proper_lockfile
|
|
334
335
|
} from "./index-7g4c7s5r.js";
|
|
335
|
-
import {
|
|
336
|
-
exports_external,
|
|
337
|
-
init_zod
|
|
338
|
-
} from "./index-bpmtbmy9.js";
|
|
339
336
|
import {
|
|
340
337
|
emit,
|
|
341
338
|
getLastHeartbeat,
|
|
342
339
|
telemetry
|
|
343
|
-
} from "./index-
|
|
340
|
+
} from "./index-h5sbn1zr.js";
|
|
341
|
+
import {
|
|
342
|
+
exports_external,
|
|
343
|
+
init_zod
|
|
344
|
+
} from "./index-bpmtbmy9.js";
|
|
344
345
|
import {
|
|
345
346
|
bunSpawn,
|
|
346
347
|
bunWrite,
|
|
@@ -410,8 +411,28 @@ var CANDIDATE_FIELDS = {
|
|
|
410
411
|
"confidence"
|
|
411
412
|
]
|
|
412
413
|
};
|
|
414
|
+
var CANDIDATE_MARKER = "[CANDIDATE]";
|
|
415
|
+
var CLEAN_MARKER = "[CLEAN]";
|
|
416
|
+
function formatCandidateHeader(family) {
|
|
417
|
+
return [
|
|
418
|
+
CANDIDATE_MARKER,
|
|
419
|
+
...CANDIDATE_FIELDS[family].map((name) => name === "file_line" ? "file:line" : name)
|
|
420
|
+
].join(" | ");
|
|
421
|
+
}
|
|
422
|
+
function formatCleanTemplate(family) {
|
|
423
|
+
const laneField = family === "base_explorer" ? "lane" : "micro_lane";
|
|
424
|
+
return [CLEAN_MARKER, laneField, "coverage_scope", "evidence"].join(" | ");
|
|
425
|
+
}
|
|
426
|
+
var CANDIDATE_HEADERS = {
|
|
427
|
+
base_explorer: formatCandidateHeader("base_explorer"),
|
|
428
|
+
micro_lane: formatCandidateHeader("micro_lane")
|
|
429
|
+
};
|
|
430
|
+
var CLEAN_TEMPLATES = {
|
|
431
|
+
base_explorer: formatCleanTemplate("base_explorer"),
|
|
432
|
+
micro_lane: formatCleanTemplate("micro_lane")
|
|
433
|
+
};
|
|
413
434
|
function candidateHeaderFamily(fields) {
|
|
414
|
-
if (fields[0]?.trim() !==
|
|
435
|
+
if (fields[0]?.trim() !== CANDIDATE_MARKER)
|
|
415
436
|
return null;
|
|
416
437
|
const normalized = fields.slice(1).map((field) => field.trim());
|
|
417
438
|
for (const family of ["base_explorer", "micro_lane"]) {
|
|
@@ -1943,6 +1964,7 @@ var CHECKOUT_MUTATION_ACTION_TIMEOUT_MS = 5 * 60000;
|
|
|
1943
1964
|
var MAX_CANDIDATE_ISSUES_PER_ARTIFACT = 8;
|
|
1944
1965
|
var MAX_BASE_COVERAGE_DIAGNOSTICS = 8;
|
|
1945
1966
|
var MAX_BASE_COVERAGE_DIAGNOSTIC_CHARS = 1000;
|
|
1967
|
+
var MAX_LANE_VALIDATION_VALUE_CHARS = 240;
|
|
1946
1968
|
var WORKFLOW_GATE_DIR = "pr-workflow-gates";
|
|
1947
1969
|
var trackedStatesByProjectSession = new Map;
|
|
1948
1970
|
var pendingStateMutationsByProjectSession = new Map;
|
|
@@ -2434,7 +2456,7 @@ async function assertPrReviewBaseCoverageSettled(directory, sessionID, gateConte
|
|
|
2434
2456
|
}
|
|
2435
2457
|
const missing = PR_REVIEW_BASE_DIMENSION_IDS.filter((dimension) => !covered.has(dimension));
|
|
2436
2458
|
if (missing.length > 0 || covered.size !== PR_REVIEW_BASE_DIMENSION_IDS.length) {
|
|
2437
|
-
throw new Error(`BLOCKED: PR_REVIEW base coverage is incomplete; missing dimensions: ${missing.join(", ") || "(none)"}${malformedDiagnostics.length > 0 ? `;
|
|
2459
|
+
throw new Error(`BLOCKED: PR_REVIEW base coverage is incomplete; missing dimensions: ${missing.join(", ") || "(none)"}${malformedDiagnostics.length > 0 ? `; first failed lane predicates: ${malformedDiagnostics.join(" | ")}` : ""}; valid dimensions: ${PR_REVIEW_BASE_DIMENSION_IDS.join(", ")}; expected candidate row: ${CANDIDATE_HEADERS.base_explorer}; expected clean row: ${CLEAN_TEMPLATES.base_explorer}`);
|
|
2438
2460
|
}
|
|
2439
2461
|
return state;
|
|
2440
2462
|
}
|
|
@@ -2787,6 +2809,7 @@ async function transitionPrReviewToFeedback(directory, sessionID, request) {
|
|
|
2787
2809
|
}
|
|
2788
2810
|
var _test_exports = {
|
|
2789
2811
|
minimumConsolidatedLaneCover,
|
|
2812
|
+
analyzePrReviewBatchRecordIntegrity,
|
|
2790
2813
|
MAX_COVER_UNIVERSE_BITS,
|
|
2791
2814
|
workflowGateStateRelativePath,
|
|
2792
2815
|
workflowGateStateLockRelativePath,
|
|
@@ -3356,47 +3379,169 @@ function derivePrReviewCriticInventoryForCoverageGate(directory, state, ctx, ori
|
|
|
3356
3379
|
}
|
|
3357
3380
|
return derivePrReviewCriticInventory(directory, state, ctx);
|
|
3358
3381
|
}
|
|
3359
|
-
function
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
});
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
|
|
3374
|
-
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
|
|
3382
|
+
function boundedLaneValidationValue(value) {
|
|
3383
|
+
let rendered;
|
|
3384
|
+
try {
|
|
3385
|
+
rendered = typeof value === "string" ? value : JSON.stringify(value);
|
|
3386
|
+
} catch {
|
|
3387
|
+
rendered = String(value);
|
|
3388
|
+
}
|
|
3389
|
+
const sanitized = [...rendered ?? String(value)].map((character) => {
|
|
3390
|
+
const code = character.charCodeAt(0);
|
|
3391
|
+
return code <= 31 || code === 127 ? " " : character;
|
|
3392
|
+
}).join("").trim();
|
|
3393
|
+
return sanitized.length <= MAX_LANE_VALIDATION_VALUE_CHARS ? sanitized : `${sanitized.slice(0, MAX_LANE_VALIDATION_VALUE_CHARS - 1)}\u2026`;
|
|
3394
|
+
}
|
|
3395
|
+
function failedLaneValidation(predicate, expected, actual) {
|
|
3396
|
+
return {
|
|
3397
|
+
ok: false,
|
|
3398
|
+
failure: {
|
|
3399
|
+
predicate,
|
|
3400
|
+
expected: boundedLaneValidationValue(expected),
|
|
3401
|
+
actual: boundedLaneValidationValue(actual)
|
|
3379
3402
|
}
|
|
3403
|
+
};
|
|
3404
|
+
}
|
|
3405
|
+
function formatPrReviewLaneValidationFailure(failure) {
|
|
3406
|
+
return `predicate=${failure.predicate} expected=${JSON.stringify(failure.expected)} actual=${JSON.stringify(failure.actual)}`.slice(0, MAX_BASE_COVERAGE_DIAGNOSTIC_CHARS);
|
|
3407
|
+
}
|
|
3408
|
+
function analyzeLaneRecordResultIntegrity(args) {
|
|
3409
|
+
const { record, result, expected } = args;
|
|
3410
|
+
if (expected.checkWorkflowLane && record.workflowLane !== expected.workflowLane) {
|
|
3411
|
+
return failedLaneValidation("record.workflow_lane", expected.workflowLane, record.workflowLane ?? "(missing)");
|
|
3380
3412
|
}
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3413
|
+
if (expected.checkWorkflowLane && !ownedLaneSetsEqual(record.ownedWorkflowLanes, expected.ownedWorkflowLanes)) {
|
|
3414
|
+
return failedLaneValidation("record.owned_workflow_lanes", expected.ownedWorkflowLanes, record.ownedWorkflowLanes ?? (record.workflowLane ? [record.workflowLane] : []));
|
|
3415
|
+
}
|
|
3416
|
+
if (record.mode !== expected.mode) {
|
|
3417
|
+
return failedLaneValidation("record.mode", expected.mode, record.mode ?? "(missing)");
|
|
3418
|
+
}
|
|
3419
|
+
if (record.workspace?.prHeadSha !== expected.prHeadSha) {
|
|
3420
|
+
return failedLaneValidation("record.pr_head_sha", expected.prHeadSha, record.workspace?.prHeadSha ?? "(missing)");
|
|
3421
|
+
}
|
|
3422
|
+
if (record.workspace?.gitHead !== expected.gitHead) {
|
|
3423
|
+
return failedLaneValidation("record.git_head", expected.gitHead, record.workspace?.gitHead ?? "(missing)");
|
|
3424
|
+
}
|
|
3425
|
+
if (args.requireCompleted && record.status !== "completed") {
|
|
3426
|
+
return failedLaneValidation("record.status", "completed", record.status);
|
|
3427
|
+
}
|
|
3428
|
+
if (result?.outputDegraded === true) {
|
|
3429
|
+
return failedLaneValidation("result.output_degraded", "not true", true);
|
|
3430
|
+
}
|
|
3431
|
+
if (result?.transcriptIncomplete === true) {
|
|
3432
|
+
return failedLaneValidation("result.transcript_incomplete", "not true", true);
|
|
3433
|
+
}
|
|
3434
|
+
if (result?.truncated === true) {
|
|
3435
|
+
return failedLaneValidation("result.truncated", "not true", true);
|
|
3436
|
+
}
|
|
3437
|
+
if ((result?.chars ?? 0) <= 0) {
|
|
3438
|
+
return failedLaneValidation("result.chars", "greater than 0", result?.chars ?? 0);
|
|
3439
|
+
}
|
|
3440
|
+
if (!result?.digest?.trim()) {
|
|
3441
|
+
return failedLaneValidation("result.digest", "non-empty digest", result?.digest ?? "(missing)");
|
|
3442
|
+
}
|
|
3443
|
+
if (!result?.outputRef?.trim()) {
|
|
3444
|
+
return failedLaneValidation("result.output_ref", "non-empty output ref", result?.outputRef ?? "(missing)");
|
|
3445
|
+
}
|
|
3446
|
+
return { ok: true };
|
|
3447
|
+
}
|
|
3448
|
+
function analyzePrReviewBatchRecordIntegrity(args) {
|
|
3449
|
+
const validatedAtMs = Date.parse(args.validatedAt);
|
|
3450
|
+
const expectedByLaneId = new Map(args.expectedLanes.map((lane) => [lane.laneId, lane]));
|
|
3451
|
+
const batchFailure = !Number.isFinite(validatedAtMs) ? failedLaneValidation("batch.validated_at", "valid ISO timestamp", args.validatedAt) : expectedByLaneId.size !== args.expectedLanes.length ? failedLaneValidation("batch.expected_lane_unique", "unique expected lane ids", args.expectedLanes.map((lane) => lane.laneId)) : null;
|
|
3452
|
+
const relevantRecords = args.records.filter((record) => record.laneId && expectedByLaneId.has(record.laneId));
|
|
3453
|
+
const recordsByLaneId = new Map;
|
|
3454
|
+
const recordCountBySubagentSessionId = new Map;
|
|
3455
|
+
for (const record of relevantRecords) {
|
|
3456
|
+
const laneRecords = recordsByLaneId.get(record.laneId) ?? [];
|
|
3457
|
+
laneRecords.push(record);
|
|
3458
|
+
recordsByLaneId.set(record.laneId, laneRecords);
|
|
3459
|
+
const sessionId = record.subagentSessionId?.trim();
|
|
3460
|
+
if (sessionId) {
|
|
3461
|
+
recordCountBySubagentSessionId.set(sessionId, (recordCountBySubagentSessionId.get(sessionId) ?? 0) + 1);
|
|
3462
|
+
}
|
|
3463
|
+
}
|
|
3464
|
+
return args.expectedLanes.map((expectedLane) => {
|
|
3465
|
+
const expectedWorkflowLane = expectedLane.workflowLane;
|
|
3466
|
+
const expectedOwnedLanes = expectedLane.ownedWorkflowLanes?.length ? expectedLane.ownedWorkflowLanes : [expectedWorkflowLane];
|
|
3467
|
+
const failed = (failure) => ({
|
|
3468
|
+
ok: false,
|
|
3469
|
+
expectedLane,
|
|
3470
|
+
expectedWorkflowLane,
|
|
3471
|
+
expectedOwnedLanes,
|
|
3472
|
+
failure
|
|
3473
|
+
});
|
|
3474
|
+
if (batchFailure && !batchFailure.ok)
|
|
3475
|
+
return failed(batchFailure.failure);
|
|
3476
|
+
const laneRecords = recordsByLaneId.get(expectedLane.laneId) ?? [];
|
|
3477
|
+
if (laneRecords.length === 0) {
|
|
3478
|
+
return failed(failedLaneValidation("record.missing", "exactly one record", 0).failure);
|
|
3479
|
+
}
|
|
3480
|
+
if (laneRecords.length !== 1) {
|
|
3481
|
+
return failed(failedLaneValidation("record.duplicate_lane", "exactly one record", laneRecords.length).failure);
|
|
3482
|
+
}
|
|
3483
|
+
const record = laneRecords[0];
|
|
3385
3484
|
const subagentSessionId = record.subagentSessionId?.trim();
|
|
3386
|
-
if (
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
|
|
3485
|
+
if (!subagentSessionId) {
|
|
3486
|
+
return failed(failedLaneValidation("record.subagent_session_id", "non-empty child session id", record.subagentSessionId ?? "(missing)").failure);
|
|
3487
|
+
}
|
|
3488
|
+
if (recordCountBySubagentSessionId.get(subagentSessionId) !== 1) {
|
|
3489
|
+
return failed(failedLaneValidation("record.duplicate_subagent_session_id", "one record per child session", recordCountBySubagentSessionId.get(subagentSessionId)).failure);
|
|
3490
|
+
}
|
|
3491
|
+
if (args.forbiddenSubagentSessionIds.has(subagentSessionId)) {
|
|
3492
|
+
return failed(failedLaneValidation("record.forbidden_subagent_session_id", "child session not reused from a forbidden phase", subagentSessionId).failure);
|
|
3493
|
+
}
|
|
3494
|
+
if (record.createdAt < validatedAtMs) {
|
|
3495
|
+
return failed(failedLaneValidation("record.created_at", `at or after ${args.validatedAt}`, new Date(record.createdAt).toISOString()).failure);
|
|
3496
|
+
}
|
|
3497
|
+
const recordIntegrity = analyzeLaneRecordResultIntegrity({
|
|
3498
|
+
record,
|
|
3499
|
+
result: record.result,
|
|
3500
|
+
expected: {
|
|
3501
|
+
mode: args.expectedMode,
|
|
3502
|
+
workflowLane: expectedWorkflowLane,
|
|
3503
|
+
ownedWorkflowLanes: expectedOwnedLanes,
|
|
3504
|
+
prHeadSha: args.expectedPrHeadSha ?? record.workspace?.prHeadSha ?? "",
|
|
3505
|
+
gitHead: args.expectedPrHeadSha ?? record.workspace?.gitHead ?? "",
|
|
3506
|
+
checkWorkflowLane: args.checkWorkflowLane
|
|
3507
|
+
},
|
|
3508
|
+
requireCompleted: true
|
|
3509
|
+
});
|
|
3510
|
+
if (!recordIntegrity.ok)
|
|
3511
|
+
return failed(recordIntegrity.failure);
|
|
3512
|
+
return {
|
|
3513
|
+
ok: true,
|
|
3514
|
+
record,
|
|
3515
|
+
expectedLane,
|
|
3516
|
+
expectedWorkflowLane,
|
|
3517
|
+
expectedOwnedLanes
|
|
3518
|
+
};
|
|
3519
|
+
});
|
|
3520
|
+
}
|
|
3521
|
+
function recordsPassingBatchIntegrity(directory, state, batchId, expectedLanes, expectedMode, validatedAt, checkWorkflowLane = true, forbiddenSubagentSessionIds = new Set, diagnostics) {
|
|
3522
|
+
const records = findByBatchId(directory, batchId, {
|
|
3523
|
+
parentSessionId: state.sessionID
|
|
3524
|
+
});
|
|
3525
|
+
const analyses = analyzePrReviewBatchRecordIntegrity({
|
|
3526
|
+
batchId,
|
|
3527
|
+
expectedLanes,
|
|
3528
|
+
expectedMode,
|
|
3529
|
+
validatedAt,
|
|
3530
|
+
checkWorkflowLane,
|
|
3531
|
+
forbiddenSubagentSessionIds,
|
|
3532
|
+
records,
|
|
3533
|
+
expectedPrHeadSha: state.prHeadSha
|
|
3534
|
+
});
|
|
3535
|
+
for (const analysis of analyses) {
|
|
3536
|
+
if (!analysis.ok && diagnostics && diagnostics.length < MAX_BASE_COVERAGE_DIAGNOSTICS) {
|
|
3537
|
+
diagnostics.push(`batch=${batchId} lane=${analysis.expectedLane.laneId} workflow_lane=${analysis.expectedWorkflowLane}: ${formatPrReviewLaneValidationFailure(analysis.failure)}`.slice(0, MAX_BASE_COVERAGE_DIAGNOSTIC_CHARS));
|
|
3393
3538
|
}
|
|
3394
3539
|
}
|
|
3395
|
-
return
|
|
3540
|
+
return analyses.filter((analysis) => analysis.ok);
|
|
3396
3541
|
}
|
|
3397
3542
|
function successfulObligationsFromExactBatch(directory, state, batchId, expectedLanes, expectedMode, validatedAt, checkWorkflowLane = true, forbiddenSubagentSessionIds = new Set, expectedRevisionDigest, diagnostics, reviewerClaims) {
|
|
3398
3543
|
const successful = new Set;
|
|
3399
|
-
for (const qualified of recordsPassingBatchIntegrity(directory, state, batchId, expectedLanes, expectedMode, validatedAt, checkWorkflowLane, forbiddenSubagentSessionIds)) {
|
|
3544
|
+
for (const qualified of recordsPassingBatchIntegrity(directory, state, batchId, expectedLanes, expectedMode, validatedAt, checkWorkflowLane, forbiddenSubagentSessionIds, diagnostics)) {
|
|
3400
3545
|
if (workflowArtifactHasContractMarker(directory, state, qualified.record, expectedMode, qualified.expectedWorkflowLane, qualified.expectedLane.reviewItemIds, expectedRevisionDigest, qualified.expectedOwnedLanes, diagnostics, reviewerClaims)) {
|
|
3401
3546
|
for (const obligation of qualified.expectedOwnedLanes) {
|
|
3402
3547
|
successful.add(obligation);
|
|
@@ -3416,25 +3561,98 @@ function ownedLaneSetsEqual(recordOwned, expectedOwned) {
|
|
|
3416
3561
|
}
|
|
3417
3562
|
return recordOwned.every((owned) => expectedSet.has(owned));
|
|
3418
3563
|
}
|
|
3419
|
-
function
|
|
3564
|
+
function analyzeLaneArtifactIntegrity(args) {
|
|
3565
|
+
const { record, result, artifact, expected } = args;
|
|
3566
|
+
if (!artifact) {
|
|
3567
|
+
return failedLaneValidation("artifact.readable", "readable stored artifact", "missing or invalid");
|
|
3568
|
+
}
|
|
3569
|
+
if (artifact.ref !== result.outputRef?.trim()) {
|
|
3570
|
+
return failedLaneValidation("artifact.ref", result.outputRef?.trim() ?? "(missing)", artifact.ref);
|
|
3571
|
+
}
|
|
3572
|
+
if (artifact.batchId !== record.batchId) {
|
|
3573
|
+
return failedLaneValidation("artifact.batch_id", record.batchId ?? "(missing)", artifact.batchId);
|
|
3574
|
+
}
|
|
3575
|
+
if (artifact.laneId !== record.laneId) {
|
|
3576
|
+
return failedLaneValidation("artifact.lane_id", record.laneId ?? "(missing)", artifact.laneId);
|
|
3577
|
+
}
|
|
3578
|
+
if (artifact.mode !== expected.mode) {
|
|
3579
|
+
return failedLaneValidation("artifact.mode", expected.mode, artifact.mode ?? "(missing)");
|
|
3580
|
+
}
|
|
3581
|
+
if (artifact.sessionId !== record.subagentSessionId) {
|
|
3582
|
+
return failedLaneValidation("artifact.session_id", record.subagentSessionId, artifact.sessionId ?? "(missing)");
|
|
3583
|
+
}
|
|
3584
|
+
if (artifact.parentSessionId !== record.parentSessionId) {
|
|
3585
|
+
return failedLaneValidation("artifact.parent_session_id", record.parentSessionId, artifact.parentSessionId ?? "(missing)");
|
|
3586
|
+
}
|
|
3587
|
+
if (artifact.agent !== record.swarmPrefixedAgent) {
|
|
3588
|
+
return failedLaneValidation("artifact.agent", record.swarmPrefixedAgent, artifact.agent);
|
|
3589
|
+
}
|
|
3590
|
+
if (artifact.role !== record.normalizedAgent) {
|
|
3591
|
+
return failedLaneValidation("artifact.role", record.normalizedAgent, artifact.role);
|
|
3592
|
+
}
|
|
3593
|
+
if (artifact.source !== "collect_lane_results") {
|
|
3594
|
+
return failedLaneValidation("artifact.source", "collect_lane_results", artifact.source);
|
|
3595
|
+
}
|
|
3596
|
+
if (artifact.workflowLane !== record.workflowLane) {
|
|
3597
|
+
return failedLaneValidation("artifact.workflow_lane_record", record.workflowLane ?? "(missing)", artifact.workflowLane ?? "(missing)");
|
|
3598
|
+
}
|
|
3599
|
+
if (artifact.workflowLane !== expected.workflowLane) {
|
|
3600
|
+
return failedLaneValidation("artifact.workflow_lane_expected", expected.workflowLane, artifact.workflowLane ?? "(missing)");
|
|
3601
|
+
}
|
|
3602
|
+
if (artifact.prHeadSha !== expected.prHeadSha) {
|
|
3603
|
+
return failedLaneValidation("artifact.pr_head_sha", expected.prHeadSha, artifact.prHeadSha ?? "(missing)");
|
|
3604
|
+
}
|
|
3605
|
+
if (artifact.gitHead !== expected.gitHead) {
|
|
3606
|
+
return failedLaneValidation("artifact.git_head", expected.gitHead, artifact.gitHead ?? "(missing)");
|
|
3607
|
+
}
|
|
3608
|
+
if (artifact.revisionDigest !== expected.revisionDigest) {
|
|
3609
|
+
return failedLaneValidation("artifact.revision_digest", expected.revisionDigest, artifact.revisionDigest ?? "(missing)");
|
|
3610
|
+
}
|
|
3611
|
+
if (expected.reviewScope !== undefined && record.workspace?.scope !== expected.reviewScope) {
|
|
3612
|
+
return failedLaneValidation("record.scope", expected.reviewScope, record.workspace?.scope ?? "(missing)");
|
|
3613
|
+
}
|
|
3614
|
+
if (expected.reviewScope !== undefined && artifact.scope !== expected.reviewScope) {
|
|
3615
|
+
return failedLaneValidation("artifact.scope", expected.reviewScope, artifact.scope ?? "(missing)");
|
|
3616
|
+
}
|
|
3617
|
+
if (artifact.digest !== result.digest) {
|
|
3618
|
+
return failedLaneValidation("artifact.digest", result.digest, artifact.digest);
|
|
3619
|
+
}
|
|
3620
|
+
if (artifact.chars !== result.chars) {
|
|
3621
|
+
return failedLaneValidation("artifact.chars", result.chars, artifact.chars);
|
|
3622
|
+
}
|
|
3623
|
+
return { ok: true };
|
|
3624
|
+
}
|
|
3625
|
+
function loadArtifactPassingLaneIntegrity(directory, state, record, expectedMode, expectedWorkflowLane, expectedRevisionDigest, diagnostics) {
|
|
3420
3626
|
const ref = record.result?.outputRef?.trim();
|
|
3421
3627
|
if (!ref)
|
|
3422
3628
|
return null;
|
|
3423
3629
|
const loaded = readLaneOutput(directory, ref);
|
|
3424
|
-
|
|
3425
|
-
return null;
|
|
3426
|
-
const artifact = loaded.artifact;
|
|
3427
|
-
const recordPrHeadSha = record.workspace?.prHeadSha;
|
|
3428
|
-
const recordGitHead = record.workspace?.gitHead;
|
|
3630
|
+
const artifact = loaded?.artifact ?? null;
|
|
3429
3631
|
const expectedReviewScope = state.mode === "PR_REVIEW" && state.prReviewBaseSha && state.prHeadSha ? `complete PR diff ${state.prReviewBaseSha}...${state.prHeadSha}` : undefined;
|
|
3430
|
-
|
|
3632
|
+
const integrity = analyzeLaneArtifactIntegrity({
|
|
3633
|
+
record,
|
|
3634
|
+
result: record.result,
|
|
3635
|
+
artifact,
|
|
3636
|
+
expected: {
|
|
3637
|
+
mode: expectedMode,
|
|
3638
|
+
workflowLane: expectedWorkflowLane,
|
|
3639
|
+
prHeadSha: record.workspace?.prHeadSha ?? "",
|
|
3640
|
+
gitHead: record.workspace?.gitHead ?? "",
|
|
3641
|
+
revisionDigest: expectedRevisionDigest,
|
|
3642
|
+
reviewScope: expectedReviewScope
|
|
3643
|
+
}
|
|
3644
|
+
});
|
|
3645
|
+
if (!integrity.ok) {
|
|
3646
|
+
if (diagnostics && diagnostics.length < MAX_BASE_COVERAGE_DIAGNOSTICS) {
|
|
3647
|
+
diagnostics.push(`batch=${record.batchId ?? "(missing)"} lane=${record.laneId ?? "(missing)"} workflow_lane=${expectedWorkflowLane} output_ref=${ref}: ${formatPrReviewLaneValidationFailure(integrity.failure)}`.slice(0, MAX_BASE_COVERAGE_DIAGNOSTIC_CHARS));
|
|
3648
|
+
}
|
|
3431
3649
|
return null;
|
|
3432
3650
|
}
|
|
3433
3651
|
return artifact;
|
|
3434
3652
|
}
|
|
3435
3653
|
function workflowArtifactHasContractMarker(directory, state, record, expectedMode, expectedWorkflowLane, reviewItemIds, expectedRevisionDigest, ownedWorkflowLanes, diagnostics, reviewerClaims) {
|
|
3436
3654
|
const ref = record.result?.outputRef?.trim();
|
|
3437
|
-
const artifact = expectedRevisionDigest ? loadArtifactPassingLaneIntegrity(directory, state, record, expectedMode, expectedWorkflowLane, expectedRevisionDigest) : null;
|
|
3655
|
+
const artifact = expectedRevisionDigest ? loadArtifactPassingLaneIntegrity(directory, state, record, expectedMode, expectedWorkflowLane, expectedRevisionDigest, diagnostics) : null;
|
|
3438
3656
|
if (!artifact)
|
|
3439
3657
|
return false;
|
|
3440
3658
|
if (expectedMode === "swarm-pr-review:reviewer" || expectedMode === "swarm-pr-review:critic") {
|
|
@@ -3454,6 +3672,30 @@ function workflowArtifactHasContractMarker(directory, state, record, expectedMod
|
|
|
3454
3672
|
if (feedbackVerdict) {
|
|
3455
3673
|
return Boolean(reviewItemIds?.length && reviewItemIds.every((itemId) => artifactHasExactPositiveVerdictRow(artifact.text, feedbackVerdict[0], itemId, feedbackVerdict[1])));
|
|
3456
3674
|
}
|
|
3675
|
+
if (expectedMode === "swarm-pr-review:base" || expectedMode === "swarm-pr-review:micro") {
|
|
3676
|
+
const reviewScope = state.mode === "PR_REVIEW" && state.prReviewBaseSha && state.prHeadSha ? `complete PR diff ${state.prReviewBaseSha}...${state.prHeadSha}` : undefined;
|
|
3677
|
+
const validation = validatePrReviewDiscoveryLaneCompletion({
|
|
3678
|
+
record,
|
|
3679
|
+
result: record.result,
|
|
3680
|
+
artifact,
|
|
3681
|
+
expected: {
|
|
3682
|
+
mode: expectedMode,
|
|
3683
|
+
workflowLane: expectedWorkflowLane,
|
|
3684
|
+
ownedWorkflowLanes,
|
|
3685
|
+
prHeadSha: state.prHeadSha ?? "",
|
|
3686
|
+
gitHead: state.prHeadSha ?? "",
|
|
3687
|
+
revisionDigest: expectedRevisionDigest ?? "",
|
|
3688
|
+
reviewScope
|
|
3689
|
+
}
|
|
3690
|
+
});
|
|
3691
|
+
if (!validation.ok) {
|
|
3692
|
+
if (diagnostics && diagnostics.length < MAX_BASE_COVERAGE_DIAGNOSTICS) {
|
|
3693
|
+
diagnostics.push(`batch=${record.batchId ?? "(missing)"} lane=${record.laneId ?? "(missing)"} workflow_lane=${expectedWorkflowLane} output_ref=${ref}: ${formatPrReviewLaneValidationFailure(validation.failure)}`.slice(0, MAX_BASE_COVERAGE_DIAGNOSTIC_CHARS));
|
|
3694
|
+
}
|
|
3695
|
+
return false;
|
|
3696
|
+
}
|
|
3697
|
+
return true;
|
|
3698
|
+
}
|
|
3457
3699
|
const coveredLanes = ownedWorkflowLanes?.length ? ownedWorkflowLanes : [expectedWorkflowLane];
|
|
3458
3700
|
const coverageAnalyses = coveredLanes.map((coveredLane) => ({
|
|
3459
3701
|
coveredLane,
|
|
@@ -3491,7 +3733,12 @@ function analyzePrReviewDiscoveryArtifact(text, expectedWorkflowLane, ownedWorkf
|
|
|
3491
3733
|
const header = selectCandidateHeader(canonicalText.split(/\r?\n/));
|
|
3492
3734
|
if (header === null || !header.markerBearing || header.family !== fallbackFamily) {
|
|
3493
3735
|
appendBoundedCandidateIssue(issues, `field header: expected one exact canonical ${fallbackFamily} [CANDIDATE] header before discovery rows`);
|
|
3494
|
-
return {
|
|
3736
|
+
return {
|
|
3737
|
+
covered: false,
|
|
3738
|
+
evidence: null,
|
|
3739
|
+
issues,
|
|
3740
|
+
failurePredicate: "discovery.header"
|
|
3741
|
+
};
|
|
3495
3742
|
}
|
|
3496
3743
|
const parsed = parseCandidates({
|
|
3497
3744
|
output_ref: "pr-workflow:discovery-artifact",
|
|
@@ -3525,7 +3772,12 @@ function analyzePrReviewDiscoveryArtifact(text, expectedWorkflowLane, ownedWorkf
|
|
|
3525
3772
|
appendBoundedCandidateIssue(issues, `row ${detail.row_index + 1} field ${detail.field}: ${detail.message}`);
|
|
3526
3773
|
}
|
|
3527
3774
|
if (parsed.error || parsed.diagnostics.parse_error_details.length > 0) {
|
|
3528
|
-
return {
|
|
3775
|
+
return {
|
|
3776
|
+
covered: false,
|
|
3777
|
+
evidence: null,
|
|
3778
|
+
issues,
|
|
3779
|
+
failurePredicate: "discovery.row"
|
|
3780
|
+
};
|
|
3529
3781
|
}
|
|
3530
3782
|
const matchingCandidate = parsed.candidates.find((candidate) => (candidate.lane ?? candidate.micro_lane) === expectedWorkflowLane);
|
|
3531
3783
|
if (matchingCandidate) {
|
|
@@ -3551,7 +3803,67 @@ function analyzePrReviewDiscoveryArtifact(text, expectedWorkflowLane, ownedWorkf
|
|
|
3551
3803
|
issues
|
|
3552
3804
|
};
|
|
3553
3805
|
}
|
|
3554
|
-
return {
|
|
3806
|
+
return {
|
|
3807
|
+
covered: false,
|
|
3808
|
+
evidence: null,
|
|
3809
|
+
issues,
|
|
3810
|
+
failurePredicate: "discovery.coverage"
|
|
3811
|
+
};
|
|
3812
|
+
}
|
|
3813
|
+
function validatePrReviewDiscoveryLaneCompletion(input) {
|
|
3814
|
+
const ownedWorkflowLanes = input.expected.ownedWorkflowLanes?.length ? [...input.expected.ownedWorkflowLanes] : [input.expected.workflowLane];
|
|
3815
|
+
const recordIntegrity = analyzeLaneRecordResultIntegrity({
|
|
3816
|
+
record: input.record,
|
|
3817
|
+
result: input.result,
|
|
3818
|
+
expected: {
|
|
3819
|
+
mode: input.expected.mode,
|
|
3820
|
+
workflowLane: input.expected.workflowLane,
|
|
3821
|
+
ownedWorkflowLanes,
|
|
3822
|
+
prHeadSha: input.expected.prHeadSha,
|
|
3823
|
+
gitHead: input.expected.gitHead,
|
|
3824
|
+
checkWorkflowLane: input.expected.checkWorkflowLane ?? true
|
|
3825
|
+
},
|
|
3826
|
+
requireCompleted: false
|
|
3827
|
+
});
|
|
3828
|
+
if (!recordIntegrity.ok)
|
|
3829
|
+
return recordIntegrity;
|
|
3830
|
+
const artifactIntegrity = analyzeLaneArtifactIntegrity({
|
|
3831
|
+
record: input.record,
|
|
3832
|
+
result: input.result,
|
|
3833
|
+
artifact: input.artifact,
|
|
3834
|
+
expected: {
|
|
3835
|
+
mode: input.expected.mode,
|
|
3836
|
+
workflowLane: input.expected.workflowLane,
|
|
3837
|
+
prHeadSha: input.expected.prHeadSha,
|
|
3838
|
+
gitHead: input.expected.gitHead,
|
|
3839
|
+
revisionDigest: input.expected.revisionDigest,
|
|
3840
|
+
reviewScope: input.expected.reviewScope
|
|
3841
|
+
}
|
|
3842
|
+
});
|
|
3843
|
+
if (!artifactIntegrity.ok)
|
|
3844
|
+
return artifactIntegrity;
|
|
3845
|
+
const artifact = input.artifact;
|
|
3846
|
+
const analyses = ownedWorkflowLanes.map((workflowLane) => ({
|
|
3847
|
+
workflowLane,
|
|
3848
|
+
analysis: analyzePrReviewDiscoveryArtifact(artifact.text, workflowLane, ownedWorkflowLanes)
|
|
3849
|
+
}));
|
|
3850
|
+
const failedCoverage = analyses.find(({ analysis }) => !analysis.covered);
|
|
3851
|
+
if (failedCoverage) {
|
|
3852
|
+
return failedLaneValidation(failedCoverage.analysis.failurePredicate ?? "discovery.coverage", `one valid ${input.expected.mode === "swarm-pr-review:base" ? "base_explorer" : "micro_lane"} [CANDIDATE] row or [CLEAN] attestation for ${failedCoverage.workflowLane}`, failedCoverage.analysis.issues.join("; ") || "no matching lane row");
|
|
3853
|
+
}
|
|
3854
|
+
if (ownedWorkflowLanes.length > 1) {
|
|
3855
|
+
const seenEvidence = new Map;
|
|
3856
|
+
for (const { workflowLane, analysis } of analyses) {
|
|
3857
|
+
if (analysis.evidence === null)
|
|
3858
|
+
continue;
|
|
3859
|
+
const priorLane = seenEvidence.get(analysis.evidence);
|
|
3860
|
+
if (priorLane) {
|
|
3861
|
+
return failedLaneValidation("discovery.duplicate_evidence", "distinct evidence for every owned workflow lane", `${priorLane} and ${workflowLane} share evidence`);
|
|
3862
|
+
}
|
|
3863
|
+
seenEvidence.set(analysis.evidence, workflowLane);
|
|
3864
|
+
}
|
|
3865
|
+
}
|
|
3866
|
+
return { ok: true };
|
|
3555
3867
|
}
|
|
3556
3868
|
function prReviewDiscoveryArtifactCoversLane(text, expectedWorkflowLane, ownedWorkflowLanes = [expectedWorkflowLane]) {
|
|
3557
3869
|
return analyzePrReviewDiscoveryArtifact(text, expectedWorkflowLane, ownedWorkflowLanes).covered;
|
|
@@ -6106,7 +6418,7 @@ function hasActiveEpicMode(sessionID) {
|
|
|
6106
6418
|
async function rehydratePrSubscriptions(sessionID, directory) {
|
|
6107
6419
|
const map = new Map;
|
|
6108
6420
|
try {
|
|
6109
|
-
const { listActive: listActive2 } = await import("./pr-subscriptions-
|
|
6421
|
+
const { listActive: listActive2 } = await import("./pr-subscriptions-5fpzz4f3.js");
|
|
6110
6422
|
const records = await listActive2(directory);
|
|
6111
6423
|
for (const record of records) {
|
|
6112
6424
|
if (record.sessionID !== sessionID)
|
|
@@ -18157,7 +18469,7 @@ function planMerges(active, threshold, maxComparisons, maxMerges) {
|
|
|
18157
18469
|
};
|
|
18158
18470
|
}
|
|
18159
18471
|
async function sweepActiveNearDuplicates(directory, options = {}) {
|
|
18160
|
-
const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-
|
|
18472
|
+
const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-e0nvge1c.js");
|
|
18161
18473
|
const { config } = loadPluginConfigWithMeta2(directory);
|
|
18162
18474
|
const sweepConfig = config.learning?.dedup_sweep;
|
|
18163
18475
|
if (sweepConfig?.enabled === false)
|
|
@@ -19750,7 +20062,7 @@ async function runCuratorPhase(directory, phase, agentsDispatched, config, knowl
|
|
|
19750
20062
|
}
|
|
19751
20063
|
if (config.skill_generation_enabled === true && skillCandidates.length > 0) {
|
|
19752
20064
|
try {
|
|
19753
|
-
const skillModule = await import("./skill-generator-
|
|
20065
|
+
const skillModule = await import("./skill-generator-3gt8em6v.js");
|
|
19754
20066
|
for (const cand of skillCandidates) {
|
|
19755
20067
|
if (cand.confidence < (config.min_skill_confidence ?? DEFAULT_SKILL_MIN_CONFIDENCE)) {
|
|
19756
20068
|
continue;
|
|
@@ -20210,7 +20522,7 @@ async function applyCuratorKnowledgeUpdates(directory, recommendations, knowledg
|
|
|
20210
20522
|
} catch {}
|
|
20211
20523
|
}
|
|
20212
20524
|
if (contradictedEntries.length > 0 && knowledgeConfig.contradiction_threshold_action === "quarantine") {
|
|
20213
|
-
const { maybeQuarantineOnContradiction } = await import("./knowledge-escalator-
|
|
20525
|
+
const { maybeQuarantineOnContradiction } = await import("./knowledge-escalator-3ds615yq.js");
|
|
20214
20526
|
for (const { id } of contradictedEntries) {
|
|
20215
20527
|
try {
|
|
20216
20528
|
await maybeQuarantineOnContradiction(directory, id, knowledgeConfig.contradiction_quarantine_threshold, knowledgeConfig.contradiction_quarantine_window_days);
|
|
@@ -21029,7 +21341,7 @@ async function runCuratorPostMortem(directory, options = {}) {
|
|
|
21029
21341
|
warnings.push("Failed to collect knowledge summary.");
|
|
21030
21342
|
}
|
|
21031
21343
|
try {
|
|
21032
|
-
const { getScanStatus } = await import("./scan-cursor-
|
|
21344
|
+
const { getScanStatus } = await import("./scan-cursor-5hq37qdg.js");
|
|
21033
21345
|
const scanStatus = await getScanStatus(directory);
|
|
21034
21346
|
if (scanStatus.remaining_estimate > 0) {
|
|
21035
21347
|
warnings.push(`Fair scan: reviewed ${knowledgeSummary.length} entries this sweep (generation ${scanStatus.generation}); ${scanStatus.remaining_estimate} more eligible entries will be visited in future curation sweeps.`);
|
|
@@ -21201,9 +21513,9 @@ var _internals24 = {
|
|
|
21201
21513
|
verifyPostMortemKnowledgeActions,
|
|
21202
21514
|
repairPostMortemActions,
|
|
21203
21515
|
loadDefaultKnowledgeConfig: async (directory) => {
|
|
21204
|
-
const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-
|
|
21516
|
+
const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-mrbyt7dg.js");
|
|
21205
21517
|
try {
|
|
21206
|
-
const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-
|
|
21518
|
+
const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-e0nvge1c.js");
|
|
21207
21519
|
const loaded = loadPluginConfigWithMeta2(directory);
|
|
21208
21520
|
return KnowledgeConfigSchema2.parse(loaded.config.knowledge ?? {});
|
|
21209
21521
|
} catch {
|
|
@@ -21211,11 +21523,11 @@ var _internals24 = {
|
|
|
21211
21523
|
}
|
|
21212
21524
|
},
|
|
21213
21525
|
applyCuratorKnowledgeUpdates: async (directory, recommendations, knowledgeConfig, generation) => {
|
|
21214
|
-
const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-
|
|
21526
|
+
const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-1sxxtbq7.js");
|
|
21215
21527
|
return applyCuratorKnowledgeUpdates2(directory, recommendations, knowledgeConfig, generation);
|
|
21216
21528
|
},
|
|
21217
21529
|
checkHivePromotions: async (entries, knowledgeConfig, directory) => {
|
|
21218
|
-
const { checkHivePromotions } = await import("./hive-promoter-
|
|
21530
|
+
const { checkHivePromotions } = await import("./hive-promoter-hpe29xrz.js");
|
|
21219
21531
|
return checkHivePromotions(entries, knowledgeConfig, directory);
|
|
21220
21532
|
},
|
|
21221
21533
|
applyProposalTriage: async (directory, triage) => {
|
|
@@ -21224,7 +21536,7 @@ var _internals24 = {
|
|
|
21224
21536
|
activateProposal,
|
|
21225
21537
|
listSkills: listSkills2,
|
|
21226
21538
|
sanitizeSlug
|
|
21227
|
-
} = await import("./skill-generator-
|
|
21539
|
+
} = await import("./skill-generator-3gt8em6v.js");
|
|
21228
21540
|
const result = {
|
|
21229
21541
|
approved: [],
|
|
21230
21542
|
rejected: [],
|
|
@@ -23851,9 +24163,9 @@ function hashContent(content) {
|
|
|
23851
24163
|
return createHash9("sha1").update(content).digest("hex");
|
|
23852
24164
|
}
|
|
23853
24165
|
async function loadConfigForPolicyCurator(directory) {
|
|
23854
|
-
const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-
|
|
24166
|
+
const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-mrbyt7dg.js");
|
|
23855
24167
|
try {
|
|
23856
|
-
const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-
|
|
24168
|
+
const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-e0nvge1c.js");
|
|
23857
24169
|
const { config: loadedConfig } = loadPluginConfigWithMeta2(directory);
|
|
23858
24170
|
return KnowledgeConfigSchema2.parse(loadedConfig.knowledge ?? {});
|
|
23859
24171
|
} catch {
|
|
@@ -27198,7 +27510,7 @@ async function runFinalizeStage(ctx) {
|
|
|
27198
27510
|
}
|
|
27199
27511
|
}
|
|
27200
27512
|
try {
|
|
27201
|
-
const { CuratorConfigSchema: CCS } = await import("./schema-
|
|
27513
|
+
const { CuratorConfigSchema: CCS } = await import("./schema-mrbyt7dg.js");
|
|
27202
27514
|
const { config: pmLoadedConfig } = _internals34.loadPluginConfigWithMeta(ctx.directory);
|
|
27203
27515
|
const curatorCfg = CCS.parse(pmLoadedConfig.curator ?? {});
|
|
27204
27516
|
if (curatorCfg.enabled && curatorCfg.postmortem_enabled) {
|
|
@@ -29428,9 +29740,9 @@ var _internals39 = {
|
|
|
29428
29740
|
loadPluginConfigWithMeta,
|
|
29429
29741
|
loadCuratorDeps: async () => {
|
|
29430
29742
|
const [{ CuratorConfigSchema }, curator, { createCuratorLLMDelegate: createCuratorLLMDelegate2 }] = await Promise.all([
|
|
29431
|
-
import("./schema-
|
|
29432
|
-
import("./curator-
|
|
29433
|
-
import("./curator-llm-factory-
|
|
29743
|
+
import("./schema-mrbyt7dg.js"),
|
|
29744
|
+
import("./curator-1sxxtbq7.js"),
|
|
29745
|
+
import("./curator-llm-factory-yhqbkc5w.js")
|
|
29434
29746
|
]);
|
|
29435
29747
|
return { CuratorConfigSchema, curator, createCuratorLLMDelegate: createCuratorLLMDelegate2 };
|
|
29436
29748
|
}
|
|
@@ -30335,7 +30647,7 @@ async function computeCurationDiagnostics(directory, entries) {
|
|
|
30335
30647
|
let scanCompleted = false;
|
|
30336
30648
|
let scanRemaining = 0;
|
|
30337
30649
|
try {
|
|
30338
|
-
const { getScanStatus } = await import("./scan-cursor-
|
|
30650
|
+
const { getScanStatus } = await import("./scan-cursor-5hq37qdg.js");
|
|
30339
30651
|
const status = await getScanStatus(directory);
|
|
30340
30652
|
scanGeneration = status.generation;
|
|
30341
30653
|
scanCompleted = status.completed;
|
|
@@ -30343,19 +30655,19 @@ async function computeCurationDiagnostics(directory, entries) {
|
|
|
30343
30655
|
} catch {}
|
|
30344
30656
|
let configMatch = null;
|
|
30345
30657
|
try {
|
|
30346
|
-
const { isLinked: isLinked2 } = await import("./knowledge-link-
|
|
30658
|
+
const { isLinked: isLinked2 } = await import("./knowledge-link-t94b79qe.js");
|
|
30347
30659
|
if (isLinked2(directory)) {
|
|
30348
|
-
const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-
|
|
30660
|
+
const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-mrbyt7dg.js");
|
|
30349
30661
|
let config;
|
|
30350
30662
|
try {
|
|
30351
|
-
const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-
|
|
30663
|
+
const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-e0nvge1c.js");
|
|
30352
30664
|
const loaded = loadPluginConfigWithMeta2(directory);
|
|
30353
30665
|
config = KnowledgeConfigSchema2.parse(loaded.config.knowledge ?? {});
|
|
30354
30666
|
} catch {
|
|
30355
30667
|
config = KnowledgeConfigSchema2.parse({});
|
|
30356
30668
|
}
|
|
30357
30669
|
const { cohortConfigFingerprint: cohortConfigFingerprint2 } = await import("./config-fingerprint-v22xh5a2.js");
|
|
30358
|
-
const { buildConfigFingerprintInput: buildConfigFingerprintInput2, readCohortConfigFingerprint } = await import("./curation-policy-
|
|
30670
|
+
const { buildConfigFingerprintInput: buildConfigFingerprintInput2, readCohortConfigFingerprint } = await import("./curation-policy-ftx2emfw.js");
|
|
30359
30671
|
const currentFp = cohortConfigFingerprint2(buildConfigFingerprintInput2(config));
|
|
30360
30672
|
const cohortFp = await readCohortConfigFingerprint(directory);
|
|
30361
30673
|
configMatch = cohortFp === null ? null : currentFp === cohortFp;
|
|
@@ -31566,7 +31878,7 @@ async function handleDoctorCommand(directory, args) {
|
|
|
31566
31878
|
const result = runConfigDoctor(config, directory);
|
|
31567
31879
|
let output;
|
|
31568
31880
|
if (enableAutoFix && result.hasAutoFixableIssues) {
|
|
31569
|
-
const { runConfigDoctorWithFixes } = await import("./config-doctor-
|
|
31881
|
+
const { runConfigDoctorWithFixes } = await import("./config-doctor-b9r9rt2c.js");
|
|
31570
31882
|
const fixResult = await runConfigDoctorWithFixes(directory, config, true, {
|
|
31571
31883
|
applyLossy: true
|
|
31572
31884
|
});
|
|
@@ -32403,7 +32715,7 @@ async function handleEvidenceCommand(directory, args) {
|
|
|
32403
32715
|
return formatTaskEvidenceMarkdown(evidenceData);
|
|
32404
32716
|
}
|
|
32405
32717
|
async function handleEvidenceSummaryCommand(directory) {
|
|
32406
|
-
const { buildEvidenceSummary } = await import("./evidence-summary-service-
|
|
32718
|
+
const { buildEvidenceSummary } = await import("./evidence-summary-service-85gw9p2m.js");
|
|
32407
32719
|
const artifact = await buildEvidenceSummary(directory);
|
|
32408
32720
|
if (!artifact) {
|
|
32409
32721
|
return "No plan found. Run `/swarm plan` to check plan status.";
|
|
@@ -36407,13 +36719,14 @@ function errorCell(args) {
|
|
|
36407
36719
|
function parseModelVerdict(text) {
|
|
36408
36720
|
return ModelVerdictSchema.parse(JSON.parse(text.trim()));
|
|
36409
36721
|
}
|
|
36410
|
-
function modelPrompt(task, instruction, variant) {
|
|
36722
|
+
function modelPrompt(task, instruction, variant, fixtureDir) {
|
|
36411
36723
|
return [
|
|
36412
36724
|
"You are executing a read-only production gate audit against a curated defect fixture.",
|
|
36413
36725
|
`Defect id: ${task.id}`,
|
|
36414
36726
|
`Category: ${task.category}`,
|
|
36415
36727
|
variant === "defect" ? instruction : "This is a reviewed clean control. Report caught=false unless you find a concrete defect in the supplied implementation.",
|
|
36416
|
-
|
|
36728
|
+
`Inspect ONLY the files under: ${fixtureDir}`,
|
|
36729
|
+
"Do not modify them and do not inspect files outside that directory.",
|
|
36417
36730
|
"Return exactly one JSON object and no markdown:",
|
|
36418
36731
|
'{"v":1,"caught":true|false,"reason":"concise evidence"}'
|
|
36419
36732
|
].join(`
|
|
@@ -36691,11 +37004,11 @@ async function runCell(args) {
|
|
|
36691
37004
|
});
|
|
36692
37005
|
}
|
|
36693
37006
|
const dispatch = await args.options.dispatcher({
|
|
36694
|
-
|
|
37007
|
+
sessionDirectory: args.options.projectRoot,
|
|
36695
37008
|
agentName: args.gate === "reviewer" ? "reviewer" : "test_engineer",
|
|
36696
37009
|
modelId: args.model,
|
|
36697
37010
|
preferredSwarm: args.options.manifest.preferredSwarm,
|
|
36698
|
-
prompt: modelPrompt(args.task, instruction, args.variant),
|
|
37011
|
+
prompt: modelPrompt(args.task, instruction, args.variant, tempRoot),
|
|
36699
37012
|
timeoutMs: Math.min(args.options.manifest.maxTimeMs, 120000),
|
|
36700
37013
|
parentSessionId: args.options.parentSessionId,
|
|
36701
37014
|
abortSignal: args.signal
|
|
@@ -51400,7 +51713,7 @@ Ensure this is a git repository with commit history.`;
|
|
|
51400
51713
|
// src/commands/skill-opt.ts
|
|
51401
51714
|
init_schema();
|
|
51402
51715
|
import { copyFileSync as copyFileSync5, existsSync as existsSync57, mkdirSync as mkdirSync31, readFileSync as readFileSync43 } from "fs";
|
|
51403
|
-
import * as
|
|
51716
|
+
import * as path100 from "path";
|
|
51404
51717
|
|
|
51405
51718
|
// src/services/skill-optimizer/activation.ts
|
|
51406
51719
|
import {
|
|
@@ -51860,7 +52173,117 @@ async function rollbackCandidate(input) {
|
|
|
51860
52173
|
// src/services/skill-optimizer/controller.ts
|
|
51861
52174
|
import { randomUUID as randomUUID11 } from "crypto";
|
|
51862
52175
|
import { existsSync as existsSync55, mkdirSync as mkdirSync29, readFileSync as readFileSync42, writeFileSync as writeFileSync19 } from "fs";
|
|
51863
|
-
import * as
|
|
52176
|
+
import * as path98 from "path";
|
|
52177
|
+
|
|
52178
|
+
// src/evaluation/pr-review-recovery.ts
|
|
52179
|
+
import * as fs48 from "fs/promises";
|
|
52180
|
+
import * as path96 from "path";
|
|
52181
|
+
var PR_REVIEW_RECOVERY_BASE_SHA = "3811fe5981072c7fa541523e9f08430f18594590";
|
|
52182
|
+
var FIXTURE_ROOT = "evaluation-fixtures/pr-review-recovery";
|
|
52183
|
+
var BASELINE_MANIFEST_PATH = `${FIXTURE_ROOT}/baseline-manifest.json`;
|
|
52184
|
+
var BASELINE_PAYLOAD_PATH = `${FIXTURE_ROOT}/baseline/SKILL.md`;
|
|
52185
|
+
var CANDIDATE_PAYLOAD_PATH = ".opencode/skills/swarm-pr-review/SKILL.md";
|
|
52186
|
+
var INSTRUCTION_PATH = `${FIXTURE_ROOT}/instruction.md`;
|
|
52187
|
+
var ENVIRONMENT_PATH = `${FIXTURE_ROOT}/environment`;
|
|
52188
|
+
var SCORER_PATH = `${ENVIRONMENT_PATH}/score-recovery.cjs`;
|
|
52189
|
+
function parseBaselineManifest(value) {
|
|
52190
|
+
if (value === null || typeof value !== "object" || Array.isArray(value) || Object.keys(value).sort().join("\x00") !== ["v", "sourceSha", "payloadPath", "sha256"].sort().join("\x00")) {
|
|
52191
|
+
throw new Error("PR-review recovery baseline manifest is invalid");
|
|
52192
|
+
}
|
|
52193
|
+
const manifest = value;
|
|
52194
|
+
if (manifest.v !== 1 || typeof manifest.sourceSha !== "string" || typeof manifest.payloadPath !== "string" || typeof manifest.sha256 !== "string") {
|
|
52195
|
+
throw new Error("PR-review recovery baseline manifest is invalid");
|
|
52196
|
+
}
|
|
52197
|
+
return manifest;
|
|
52198
|
+
}
|
|
52199
|
+
async function candidate(packageRoot, input) {
|
|
52200
|
+
return {
|
|
52201
|
+
...input,
|
|
52202
|
+
contentHash: await computeCandidateInputContentHash(packageRoot, input)
|
|
52203
|
+
};
|
|
52204
|
+
}
|
|
52205
|
+
async function task(packageRoot) {
|
|
52206
|
+
const input = {
|
|
52207
|
+
v: 1,
|
|
52208
|
+
id: "pr-review-controller-recovery",
|
|
52209
|
+
source: "curated",
|
|
52210
|
+
split: "train",
|
|
52211
|
+
category: "pr-review-recovery",
|
|
52212
|
+
protected: true,
|
|
52213
|
+
instructionPath: INSTRUCTION_PATH,
|
|
52214
|
+
environment: { kind: "fixture", path: ENVIRONMENT_PATH },
|
|
52215
|
+
scorer: {
|
|
52216
|
+
kind: "project",
|
|
52217
|
+
argv: [SCORER_PATH],
|
|
52218
|
+
timeoutMs: 30000,
|
|
52219
|
+
scoreRange: [0, 1]
|
|
52220
|
+
},
|
|
52221
|
+
provenance: {
|
|
52222
|
+
origin: "https://github.com/ZaxbyHub/opencode-swarm/issues/2075",
|
|
52223
|
+
license: "MIT"
|
|
52224
|
+
}
|
|
52225
|
+
};
|
|
52226
|
+
return {
|
|
52227
|
+
...input,
|
|
52228
|
+
contentHash: await computeTaskInputContentHash(packageRoot, input)
|
|
52229
|
+
};
|
|
52230
|
+
}
|
|
52231
|
+
async function verifyBaseline(packageRoot, requestedSourceSha) {
|
|
52232
|
+
if (requestedSourceSha !== PR_REVIEW_RECOVERY_BASE_SHA) {
|
|
52233
|
+
throw new Error(`PR-review recovery baseline source SHA must be ${PR_REVIEW_RECOVERY_BASE_SHA}`);
|
|
52234
|
+
}
|
|
52235
|
+
const manifest = parseBaselineManifest(JSON.parse(await fs48.readFile(path96.join(packageRoot, BASELINE_MANIFEST_PATH), "utf8")));
|
|
52236
|
+
if (manifest.sourceSha !== PR_REVIEW_RECOVERY_BASE_SHA || manifest.payloadPath !== BASELINE_PAYLOAD_PATH) {
|
|
52237
|
+
throw new Error("PR-review recovery baseline source SHA is invalid");
|
|
52238
|
+
}
|
|
52239
|
+
const payload = await fs48.readFile(path96.join(packageRoot, manifest.payloadPath));
|
|
52240
|
+
if (sha256(payload) !== manifest.sha256) {
|
|
52241
|
+
throw new Error("PR-review recovery baseline payload hash is invalid");
|
|
52242
|
+
}
|
|
52243
|
+
}
|
|
52244
|
+
async function evaluatePrReviewRecoveryV1(options) {
|
|
52245
|
+
const packageRoot = path96.resolve(options.packageRoot ?? options.projectRoot);
|
|
52246
|
+
await verifyBaseline(packageRoot, options.baselineSourceSha ?? PR_REVIEW_RECOVERY_BASE_SHA);
|
|
52247
|
+
const model = options.model ?? "configured";
|
|
52248
|
+
const baseline = await candidate(packageRoot, {
|
|
52249
|
+
v: 1,
|
|
52250
|
+
id: "pr-review-recovery-baseline",
|
|
52251
|
+
kind: "baseline",
|
|
52252
|
+
payloadPath: BASELINE_PAYLOAD_PATH,
|
|
52253
|
+
model,
|
|
52254
|
+
agent: "reviewer"
|
|
52255
|
+
});
|
|
52256
|
+
const current = await candidate(packageRoot, {
|
|
52257
|
+
v: 1,
|
|
52258
|
+
id: "pr-review-recovery-candidate",
|
|
52259
|
+
kind: "skill",
|
|
52260
|
+
payloadPath: CANDIDATE_PAYLOAD_PATH,
|
|
52261
|
+
model,
|
|
52262
|
+
agent: "reviewer"
|
|
52263
|
+
});
|
|
52264
|
+
const budgets = {
|
|
52265
|
+
maxTasks: 1,
|
|
52266
|
+
maxRepetitions: 1,
|
|
52267
|
+
maxConcurrency: 1,
|
|
52268
|
+
maxTaskTimeMs: 60000,
|
|
52269
|
+
maxRetries: 0,
|
|
52270
|
+
maxOutputBytes: 32 * 1024,
|
|
52271
|
+
...options.budgets
|
|
52272
|
+
};
|
|
52273
|
+
return runEvaluation({
|
|
52274
|
+
projectRoot: options.projectRoot,
|
|
52275
|
+
inputRoot: packageRoot,
|
|
52276
|
+
tasks: [await task(packageRoot)],
|
|
52277
|
+
baseline,
|
|
52278
|
+
candidate: current,
|
|
52279
|
+
split: "train",
|
|
52280
|
+
seed: options.seed ?? "pr-review-recovery-v1",
|
|
52281
|
+
models: [model],
|
|
52282
|
+
budgets,
|
|
52283
|
+
executor: createModelEvaluationExecutor(options.dispatcher, options.parentSessionId),
|
|
52284
|
+
abortSignal: options.abortSignal
|
|
52285
|
+
});
|
|
52286
|
+
}
|
|
51864
52287
|
|
|
51865
52288
|
// src/evaluation/statistics.ts
|
|
51866
52289
|
function normalize8(result) {
|
|
@@ -51881,16 +52304,16 @@ function collectPairs(candidateResults, referenceResults) {
|
|
|
51881
52304
|
const referenceResult = references.get(resultKey(candidateResult));
|
|
51882
52305
|
if (!referenceResult)
|
|
51883
52306
|
continue;
|
|
51884
|
-
const
|
|
52307
|
+
const candidate2 = normalize8(candidateResult);
|
|
51885
52308
|
const reference = normalize8(referenceResult);
|
|
51886
|
-
if (
|
|
52309
|
+
if (candidate2 === undefined || reference === undefined)
|
|
51887
52310
|
continue;
|
|
51888
52311
|
pairs.push({
|
|
51889
52312
|
key: resultKey(candidateResult),
|
|
51890
52313
|
category: candidateResult.category,
|
|
51891
52314
|
protected: candidateResult.protected || referenceResult.protected,
|
|
51892
52315
|
reference,
|
|
51893
|
-
candidate,
|
|
52316
|
+
candidate: candidate2,
|
|
51894
52317
|
referenceResult,
|
|
51895
52318
|
candidateResult
|
|
51896
52319
|
});
|
|
@@ -52074,6 +52497,7 @@ async function evaluateCandidateV1(options) {
|
|
|
52074
52497
|
}
|
|
52075
52498
|
var evaluationV1 = Object.freeze(Object.assign((options) => evaluateCandidateV1(options), {
|
|
52076
52499
|
evaluateCandidate: evaluateCandidateV1,
|
|
52500
|
+
evaluatePrReviewRecovery: evaluatePrReviewRecoveryV1,
|
|
52077
52501
|
runEvaluation,
|
|
52078
52502
|
decidePromotion: (input) => decidePromotion(input),
|
|
52079
52503
|
hashTaskInput: computeTaskInputContentHash,
|
|
@@ -52153,8 +52577,8 @@ ${section}`;
|
|
|
52153
52577
|
}
|
|
52154
52578
|
};
|
|
52155
52579
|
}
|
|
52156
|
-
function enforceTrustRegion(
|
|
52157
|
-
const v =
|
|
52580
|
+
function enforceTrustRegion(candidate2, budget) {
|
|
52581
|
+
const v = candidate2.diffSummary;
|
|
52158
52582
|
const breaches = [];
|
|
52159
52583
|
if (v.changedLines > budget.maxChangedLines) {
|
|
52160
52584
|
breaches.push(`changedLines ${v.changedLines} > ${budget.maxChangedLines}`);
|
|
@@ -52183,9 +52607,9 @@ function countChangedLines(a, b) {
|
|
|
52183
52607
|
return changed;
|
|
52184
52608
|
}
|
|
52185
52609
|
function draftCandidate(inputs) {
|
|
52186
|
-
const
|
|
52187
|
-
enforceTrustRegion(
|
|
52188
|
-
return
|
|
52610
|
+
const candidate2 = _internals78.draftDeterministic(inputs);
|
|
52611
|
+
enforceTrustRegion(candidate2, inputs.budget);
|
|
52612
|
+
return candidate2;
|
|
52189
52613
|
}
|
|
52190
52614
|
|
|
52191
52615
|
// src/services/skill-optimizer/deterministic-seed.ts
|
|
@@ -52221,7 +52645,7 @@ async function deterministicSeed(input) {
|
|
|
52221
52645
|
|
|
52222
52646
|
// src/services/skill-optimizer/smoke.ts
|
|
52223
52647
|
import { existsSync as existsSync54, lstatSync as lstatSync10, readFileSync as readFileSync41, realpathSync as realpathSync9 } from "fs";
|
|
52224
|
-
import * as
|
|
52648
|
+
import * as path97 from "path";
|
|
52225
52649
|
|
|
52226
52650
|
// src/hooks/spawn-helper.ts
|
|
52227
52651
|
import * as child_process9 from "child_process";
|
|
@@ -52230,7 +52654,7 @@ var _internals79 = {
|
|
|
52230
52654
|
spawn: child_process9.spawn
|
|
52231
52655
|
};
|
|
52232
52656
|
function spawnAsync(command, cwd, timeoutMs) {
|
|
52233
|
-
return new Promise((
|
|
52657
|
+
return new Promise((resolve33) => {
|
|
52234
52658
|
try {
|
|
52235
52659
|
const [rawCmd, ...args] = command;
|
|
52236
52660
|
const cmd = process.platform === "win32" && WIN32_CMD_BINARIES.has(rawCmd) && !rawCmd.includes(".") ? `${rawCmd}.cmd` : rawCmd;
|
|
@@ -52277,24 +52701,24 @@ function spawnAsync(command, cwd, timeoutMs) {
|
|
|
52277
52701
|
try {
|
|
52278
52702
|
proc.kill();
|
|
52279
52703
|
} catch {}
|
|
52280
|
-
|
|
52704
|
+
resolve33(null);
|
|
52281
52705
|
}, timeoutMs);
|
|
52282
52706
|
proc.on("close", (code) => {
|
|
52283
52707
|
if (done)
|
|
52284
52708
|
return;
|
|
52285
52709
|
done = true;
|
|
52286
52710
|
clearTimeout(timer);
|
|
52287
|
-
|
|
52711
|
+
resolve33({ exitCode: code ?? 1, stdout, stderr });
|
|
52288
52712
|
});
|
|
52289
52713
|
proc.on("error", () => {
|
|
52290
52714
|
if (done)
|
|
52291
52715
|
return;
|
|
52292
52716
|
done = true;
|
|
52293
52717
|
clearTimeout(timer);
|
|
52294
|
-
|
|
52718
|
+
resolve33(null);
|
|
52295
52719
|
});
|
|
52296
52720
|
} catch {
|
|
52297
|
-
|
|
52721
|
+
resolve33(null);
|
|
52298
52722
|
}
|
|
52299
52723
|
});
|
|
52300
52724
|
}
|
|
@@ -52310,8 +52734,8 @@ var _internals80 = {
|
|
|
52310
52734
|
}
|
|
52311
52735
|
},
|
|
52312
52736
|
escapedRoot: (root, target) => {
|
|
52313
|
-
const rel =
|
|
52314
|
-
return rel.startsWith("..") ||
|
|
52737
|
+
const rel = path97.relative(path97.resolve(root), path97.resolve(target));
|
|
52738
|
+
return rel.startsWith("..") || path97.isAbsolute(rel);
|
|
52315
52739
|
},
|
|
52316
52740
|
realpath: (p) => realpathSync9(p),
|
|
52317
52741
|
evaluateSkillChange,
|
|
@@ -52320,7 +52744,7 @@ var _internals80 = {
|
|
|
52320
52744
|
};
|
|
52321
52745
|
async function validateSkillSmoke(input) {
|
|
52322
52746
|
const notes = [];
|
|
52323
|
-
const repoRel =
|
|
52747
|
+
const repoRel = path97.join(".opencode", "skills", "generated", input.skillSlug, "SKILL.md");
|
|
52324
52748
|
if (!_internals80.validateSkillPath(repoRel)) {
|
|
52325
52749
|
return {
|
|
52326
52750
|
ok: false,
|
|
@@ -52328,7 +52752,7 @@ async function validateSkillSmoke(input) {
|
|
|
52328
52752
|
notes: [`skill path not in an allowlisted root: ${repoRel}`]
|
|
52329
52753
|
};
|
|
52330
52754
|
}
|
|
52331
|
-
const skillRoot =
|
|
52755
|
+
const skillRoot = path97.join(input.directory, ".opencode", "skills", "generated", input.skillSlug);
|
|
52332
52756
|
if (existsSync54(skillRoot)) {
|
|
52333
52757
|
if (_internals80.isSymbolicLink(skillRoot)) {
|
|
52334
52758
|
return {
|
|
@@ -52414,7 +52838,7 @@ function checkFrontmatter(content) {
|
|
|
52414
52838
|
return null;
|
|
52415
52839
|
}
|
|
52416
52840
|
function readIncumbentContent(directory, skillSlug) {
|
|
52417
|
-
const incumbent =
|
|
52841
|
+
const incumbent = path97.join(directory, ".opencode", "skills", "generated", skillSlug, "SKILL.md");
|
|
52418
52842
|
if (!existsSync54(incumbent))
|
|
52419
52843
|
return "";
|
|
52420
52844
|
try {
|
|
@@ -52425,16 +52849,16 @@ function readIncumbentContent(directory, skillSlug) {
|
|
|
52425
52849
|
}
|
|
52426
52850
|
|
|
52427
52851
|
// src/services/skill-optimizer/controller.ts
|
|
52428
|
-
var PROJECT_LOCK_PATH =
|
|
52429
|
-
var CONVERGENCE_FILE =
|
|
52852
|
+
var PROJECT_LOCK_PATH = path98.join(".swarm", "evolution", "skills", ".run.lock");
|
|
52853
|
+
var CONVERGENCE_FILE = path98.join(".swarm", "evolution", "skills", ".convergence.json");
|
|
52430
52854
|
async function prepareCandidatePayloads(inputRoot, candidateId2, skillSlug, baselineModel, candidateModel, baselineContent, candidateContent) {
|
|
52431
|
-
const payloadSubdir =
|
|
52855
|
+
const payloadSubdir = path98.join(inputRoot, "candidates", candidateId2);
|
|
52432
52856
|
if (!existsSync55(payloadSubdir))
|
|
52433
52857
|
mkdirSync29(payloadSubdir, { recursive: true });
|
|
52434
|
-
const baselinePayloadRel =
|
|
52435
|
-
const candidatePayloadRel =
|
|
52436
|
-
writeFileSync19(
|
|
52437
|
-
writeFileSync19(
|
|
52858
|
+
const baselinePayloadRel = path98.join("candidates", candidateId2, "baseline.md");
|
|
52859
|
+
const candidatePayloadRel = path98.join("candidates", candidateId2, "candidate.md");
|
|
52860
|
+
writeFileSync19(path98.join(payloadSubdir, "baseline.md"), baselineContent, "utf8");
|
|
52861
|
+
writeFileSync19(path98.join(payloadSubdir, "candidate.md"), candidateContent, "utf8");
|
|
52438
52862
|
const { computeCandidateInputContentHash: computeCandidateInputContentHash2 } = await import("./hashing-mjwn6j4y.js");
|
|
52439
52863
|
const baseline = {
|
|
52440
52864
|
v: 1,
|
|
@@ -52444,7 +52868,7 @@ async function prepareCandidatePayloads(inputRoot, candidateId2, skillSlug, base
|
|
|
52444
52868
|
model: baselineModel,
|
|
52445
52869
|
contentHash: ""
|
|
52446
52870
|
};
|
|
52447
|
-
const
|
|
52871
|
+
const candidate2 = {
|
|
52448
52872
|
v: 1,
|
|
52449
52873
|
id: `${skillSlug}-candidate-${randomUUID11().slice(0, 8)}`,
|
|
52450
52874
|
kind: "skill",
|
|
@@ -52453,8 +52877,8 @@ async function prepareCandidatePayloads(inputRoot, candidateId2, skillSlug, base
|
|
|
52453
52877
|
contentHash: ""
|
|
52454
52878
|
};
|
|
52455
52879
|
baseline.contentHash = await computeCandidateInputContentHash2(inputRoot, baseline);
|
|
52456
|
-
|
|
52457
|
-
return { baseline, candidate };
|
|
52880
|
+
candidate2.contentHash = await computeCandidateInputContentHash2(inputRoot, candidate2);
|
|
52881
|
+
return { baseline, candidate: candidate2 };
|
|
52458
52882
|
}
|
|
52459
52883
|
var _internals81 = {
|
|
52460
52884
|
tryAcquireLock,
|
|
@@ -52475,7 +52899,7 @@ async function acquireProjectLock(directory) {
|
|
|
52475
52899
|
};
|
|
52476
52900
|
}
|
|
52477
52901
|
async function acquireSkillLock(directory, skillSlug) {
|
|
52478
|
-
const lockPath =
|
|
52902
|
+
const lockPath = path98.join(".swarm", "evolution", "skills", skillSlug, ".skill.lock");
|
|
52479
52903
|
const result = await _internals81.tryAcquireLock(directory, lockPath, "skill-opt-controller", `skill-${skillSlug}`);
|
|
52480
52904
|
if (!result.acquired)
|
|
52481
52905
|
return null;
|
|
@@ -52540,7 +52964,7 @@ async function runRoundLocked(input, candidateId2) {
|
|
|
52540
52964
|
budget: input.config,
|
|
52541
52965
|
claimedTestTaskIds: input.claimedTestTaskIds ?? new Set
|
|
52542
52966
|
});
|
|
52543
|
-
const
|
|
52967
|
+
const candidate2 = draftCandidate(generatorInputs);
|
|
52544
52968
|
await recordTransition({
|
|
52545
52969
|
directory: input.directory,
|
|
52546
52970
|
skillSlug: input.skillSlug,
|
|
@@ -52549,16 +52973,16 @@ async function runRoundLocked(input, candidateId2) {
|
|
|
52549
52973
|
eventType: "draft",
|
|
52550
52974
|
actor: input.sessionId ?? "unknown",
|
|
52551
52975
|
origin: input.origin,
|
|
52552
|
-
reason:
|
|
52976
|
+
reason: candidate2.rationale,
|
|
52553
52977
|
contentHashBefore: baselineHash,
|
|
52554
|
-
contentHashAfter: computeContentHash2(
|
|
52978
|
+
contentHashAfter: computeContentHash2(candidate2.content),
|
|
52555
52979
|
payload: {
|
|
52556
|
-
metric:
|
|
52557
|
-
risks:
|
|
52558
|
-
diffSummary:
|
|
52980
|
+
metric: candidate2.metric,
|
|
52981
|
+
risks: candidate2.risks,
|
|
52982
|
+
diffSummary: candidate2.diffSummary
|
|
52559
52983
|
}
|
|
52560
52984
|
});
|
|
52561
|
-
if (
|
|
52985
|
+
if (candidate2.content === incumbent) {
|
|
52562
52986
|
await recordTransition({
|
|
52563
52987
|
directory: input.directory,
|
|
52564
52988
|
skillSlug: input.skillSlug,
|
|
@@ -52569,7 +52993,7 @@ async function runRoundLocked(input, candidateId2) {
|
|
|
52569
52993
|
origin: input.origin,
|
|
52570
52994
|
reason: "drafted candidate is identical to baseline (convergence)",
|
|
52571
52995
|
contentHashBefore: baselineHash,
|
|
52572
|
-
contentHashAfter: computeContentHash2(
|
|
52996
|
+
contentHashAfter: computeContentHash2(candidate2.content)
|
|
52573
52997
|
});
|
|
52574
52998
|
return {
|
|
52575
52999
|
candidateId: candidateId2,
|
|
@@ -52578,7 +53002,7 @@ async function runRoundLocked(input, candidateId2) {
|
|
|
52578
53002
|
stopReason: "equivalent-patch"
|
|
52579
53003
|
};
|
|
52580
53004
|
}
|
|
52581
|
-
writeArtifact(input.directory, input.skillSlug, candidateId2, "candidate.md",
|
|
53005
|
+
writeArtifact(input.directory, input.skillSlug, candidateId2, "candidate.md", candidate2.content);
|
|
52582
53006
|
if (input.dryRun) {
|
|
52583
53007
|
return {
|
|
52584
53008
|
candidateId: candidateId2,
|
|
@@ -52590,7 +53014,7 @@ async function runRoundLocked(input, candidateId2) {
|
|
|
52590
53014
|
const smoke = await validateSkillSmoke({
|
|
52591
53015
|
directory: input.directory,
|
|
52592
53016
|
skillSlug: input.skillSlug,
|
|
52593
|
-
candidateContent:
|
|
53017
|
+
candidateContent: candidate2.content,
|
|
52594
53018
|
incumbentContent: incumbent
|
|
52595
53019
|
});
|
|
52596
53020
|
if (!smoke.ok) {
|
|
@@ -52604,7 +53028,7 @@ async function runRoundLocked(input, candidateId2) {
|
|
|
52604
53028
|
origin: input.origin,
|
|
52605
53029
|
reason: smoke.notes.join("; "),
|
|
52606
53030
|
contentHashBefore: baselineHash,
|
|
52607
|
-
contentHashAfter: computeContentHash2(
|
|
53031
|
+
contentHashAfter: computeContentHash2(candidate2.content)
|
|
52608
53032
|
});
|
|
52609
53033
|
return {
|
|
52610
53034
|
candidateId: candidateId2,
|
|
@@ -52623,7 +53047,7 @@ async function runRoundLocked(input, candidateId2) {
|
|
|
52623
53047
|
origin: input.origin,
|
|
52624
53048
|
reason: smoke.notes.join("; "),
|
|
52625
53049
|
contentHashBefore: baselineHash,
|
|
52626
|
-
contentHashAfter: computeContentHash2(
|
|
53050
|
+
contentHashAfter: computeContentHash2(candidate2.content)
|
|
52627
53051
|
});
|
|
52628
53052
|
await recordTransition({
|
|
52629
53053
|
directory: input.directory,
|
|
@@ -52635,9 +53059,9 @@ async function runRoundLocked(input, candidateId2) {
|
|
|
52635
53059
|
origin: input.origin,
|
|
52636
53060
|
reason: "PR1 validation via evaluateCandidateV1 (split:test)",
|
|
52637
53061
|
contentHashBefore: baselineHash,
|
|
52638
|
-
contentHashAfter: computeContentHash2(
|
|
53062
|
+
contentHashAfter: computeContentHash2(candidate2.content)
|
|
52639
53063
|
});
|
|
52640
|
-
const decision = await runValidationWithTransientRetry(input,
|
|
53064
|
+
const decision = await runValidationWithTransientRetry(input, candidate2.content, incumbent, candidateId2);
|
|
52641
53065
|
const toState = decision.status === "accept" ? "accepted_pending_approval" : decision.status === "reject" ? "rejected" : "inconclusive";
|
|
52642
53066
|
await recordTransition({
|
|
52643
53067
|
directory: input.directory,
|
|
@@ -52649,7 +53073,7 @@ async function runRoundLocked(input, candidateId2) {
|
|
|
52649
53073
|
origin: input.origin,
|
|
52650
53074
|
reason: decision.reasons.join("; "),
|
|
52651
53075
|
contentHashBefore: baselineHash,
|
|
52652
|
-
contentHashAfter: computeContentHash2(
|
|
53076
|
+
contentHashAfter: computeContentHash2(candidate2.content),
|
|
52653
53077
|
evidenceRefs: decision.runId ? [decision.runId] : [],
|
|
52654
53078
|
payload: {
|
|
52655
53079
|
deadband: decision.deadband,
|
|
@@ -52673,18 +53097,18 @@ async function runValidationWithTransientRetry(input, candidateContent, baseline
|
|
|
52673
53097
|
while (true) {
|
|
52674
53098
|
try {
|
|
52675
53099
|
const evalInputRoot = input.inputRoot ?? input.directory;
|
|
52676
|
-
const { baseline, candidate } = await _internals81.prepareCandidatePayloads(evalInputRoot, candidateId2, input.skillSlug, input.baselineModel, input.candidateModel, baselineContent, candidateContent);
|
|
53100
|
+
const { baseline, candidate: candidate2 } = await _internals81.prepareCandidatePayloads(evalInputRoot, candidateId2, input.skillSlug, input.baselineModel, input.candidateModel, baselineContent, candidateContent);
|
|
52677
53101
|
if (!input.dispatcher) {
|
|
52678
53102
|
throw new Error("no evaluation dispatcher available (cannot run validation)");
|
|
52679
53103
|
}
|
|
52680
|
-
const { createModelEvaluationExecutor } = await import("./runner-
|
|
52681
|
-
const executor =
|
|
53104
|
+
const { createModelEvaluationExecutor: createModelEvaluationExecutor2 } = await import("./runner-9rqc8y3m.js");
|
|
53105
|
+
const executor = createModelEvaluationExecutor2(input.dispatcher, input.sessionId);
|
|
52682
53106
|
const result = await _internals81.evaluateCandidateV1({
|
|
52683
53107
|
projectRoot: input.directory,
|
|
52684
53108
|
inputRoot: input.inputRoot ?? input.directory,
|
|
52685
53109
|
tasks: input.validationTasks,
|
|
52686
53110
|
baseline,
|
|
52687
|
-
candidate,
|
|
53111
|
+
candidate: candidate2,
|
|
52688
53112
|
split: "test",
|
|
52689
53113
|
seed: randomUUID11(),
|
|
52690
53114
|
models: input.models,
|
|
@@ -52752,7 +53176,7 @@ async function runValidationWithTransientRetry(input, candidateContent, baseline
|
|
|
52752
53176
|
}
|
|
52753
53177
|
}
|
|
52754
53178
|
function readConvergenceState(directory) {
|
|
52755
|
-
const file =
|
|
53179
|
+
const file = path98.join(directory, CONVERGENCE_FILE);
|
|
52756
53180
|
if (!existsSync55(file))
|
|
52757
53181
|
return { nonImprovements: 0 };
|
|
52758
53182
|
try {
|
|
@@ -52762,10 +53186,10 @@ function readConvergenceState(directory) {
|
|
|
52762
53186
|
}
|
|
52763
53187
|
}
|
|
52764
53188
|
function writeConvergenceState(directory, nonImprovements) {
|
|
52765
|
-
const dir =
|
|
53189
|
+
const dir = path98.dirname(path98.join(directory, CONVERGENCE_FILE));
|
|
52766
53190
|
if (!existsSync55(dir))
|
|
52767
53191
|
mkdirSync29(dir, { recursive: true });
|
|
52768
|
-
writeFileSync19(
|
|
53192
|
+
writeFileSync19(path98.join(directory, CONVERGENCE_FILE), JSON.stringify({ nonImprovements }), "utf8");
|
|
52769
53193
|
}
|
|
52770
53194
|
async function runOptimizationLoop(input) {
|
|
52771
53195
|
const rounds = [];
|
|
@@ -52821,7 +53245,7 @@ async function runOptimizationLoop(input) {
|
|
|
52821
53245
|
|
|
52822
53246
|
// src/services/skill-optimizer/skill-eval-tasks.ts
|
|
52823
53247
|
import { existsSync as existsSync56, mkdirSync as mkdirSync30, writeFileSync as writeFileSync20 } from "fs";
|
|
52824
|
-
import * as
|
|
53248
|
+
import * as path99 from "path";
|
|
52825
53249
|
var DEFAULT_SKILL_EVAL_TASKS = [
|
|
52826
53250
|
{
|
|
52827
53251
|
id: "skill-eval-trigger-clarity",
|
|
@@ -52861,20 +53285,20 @@ function buildSkillEvalTasks(args) {
|
|
|
52861
53285
|
const tasks = args.tasks ?? DEFAULT_SKILL_EVAL_TASKS;
|
|
52862
53286
|
const result = [];
|
|
52863
53287
|
for (const spec of tasks) {
|
|
52864
|
-
const taskDir =
|
|
53288
|
+
const taskDir = path99.join(args.inputRoot, "skill-eval", spec.id);
|
|
52865
53289
|
if (!existsSync56(taskDir))
|
|
52866
53290
|
mkdirSync30(taskDir, { recursive: true });
|
|
52867
|
-
const instructionPath =
|
|
52868
|
-
writeFileSync20(
|
|
53291
|
+
const instructionPath = path99.join("skill-eval", spec.id, "instruction.md");
|
|
53292
|
+
writeFileSync20(path99.join(args.inputRoot, instructionPath), `${spec.instruction}
|
|
52869
53293
|
`, "utf8");
|
|
52870
|
-
const envRelPath =
|
|
52871
|
-
writeFileSync20(
|
|
52872
|
-
const phraseSpecPath =
|
|
52873
|
-
writeFileSync20(
|
|
53294
|
+
const envRelPath = path99.join("skill-eval", spec.id, "environment.md");
|
|
53295
|
+
writeFileSync20(path99.join(args.inputRoot, envRelPath), spec.environmentBody, "utf8");
|
|
53296
|
+
const phraseSpecPath = path99.join("skill-eval", spec.id, "phrase-spec.json");
|
|
53297
|
+
writeFileSync20(path99.join(args.inputRoot, phraseSpecPath), JSON.stringify({
|
|
52874
53298
|
required_phrases: spec.requiredPhrases,
|
|
52875
53299
|
forbidden_phrases: spec.forbiddenPhrases
|
|
52876
53300
|
}), "utf8");
|
|
52877
|
-
const
|
|
53301
|
+
const task2 = {
|
|
52878
53302
|
v: 1,
|
|
52879
53303
|
id: spec.id,
|
|
52880
53304
|
source: "curated",
|
|
@@ -52906,8 +53330,8 @@ function buildSkillEvalTasks(args) {
|
|
|
52906
53330
|
},
|
|
52907
53331
|
contentHash: ""
|
|
52908
53332
|
};
|
|
52909
|
-
|
|
52910
|
-
result.push(
|
|
53333
|
+
task2.contentHash = computeTaskContentHash(task2);
|
|
53334
|
+
result.push(task2);
|
|
52911
53335
|
}
|
|
52912
53336
|
return result;
|
|
52913
53337
|
}
|
|
@@ -52960,7 +53384,7 @@ ${JSON.stringify(result, null, 2)}
|
|
|
52960
53384
|
}
|
|
52961
53385
|
function readSkillOptConfigFromProject(directory) {
|
|
52962
53386
|
try {
|
|
52963
|
-
const cfgPath =
|
|
53387
|
+
const cfgPath = path100.join(directory, "opencode.json");
|
|
52964
53388
|
if (!existsSync57(cfgPath))
|
|
52965
53389
|
return { ...DEFAULT_SKILL_OPT_CONFIG };
|
|
52966
53390
|
const raw = JSON.parse(readFileSync43(cfgPath, "utf8"));
|
|
@@ -53010,18 +53434,18 @@ async function handleSkillOptRun(directory, args, runtime = {}) {
|
|
|
53010
53434
|
}, parsed.json);
|
|
53011
53435
|
}
|
|
53012
53436
|
const models = parsed.models.length > 0 ? parsed.models : ["default"];
|
|
53013
|
-
const inputRoot =
|
|
53437
|
+
const inputRoot = path100.join(directory, ".swarm", "evolution", "skills", "_eval-input");
|
|
53014
53438
|
if (!existsSync57(inputRoot))
|
|
53015
53439
|
mkdirSync31(inputRoot, { recursive: true });
|
|
53016
|
-
const scorerDir =
|
|
53440
|
+
const scorerDir = path100.join(inputRoot, "scoring");
|
|
53017
53441
|
if (!existsSync57(scorerDir))
|
|
53018
53442
|
mkdirSync31(scorerDir, { recursive: true });
|
|
53019
|
-
const scorerSource =
|
|
53020
|
-
const scorerDest =
|
|
53443
|
+
const scorerSource = path100.join(directory, "evaluation-fixtures", "skill-eval", "scoring", "score-skill-eval.cjs");
|
|
53444
|
+
const scorerDest = path100.join(scorerDir, "score-skill-eval.cjs");
|
|
53021
53445
|
if (existsSync57(scorerSource)) {
|
|
53022
53446
|
copyFileSync5(scorerSource, scorerDest);
|
|
53023
53447
|
}
|
|
53024
|
-
const scorerRelPath =
|
|
53448
|
+
const scorerRelPath = path100.join("scoring", "score-skill-eval.cjs");
|
|
53025
53449
|
const validationTasks = buildSkillEvalTasks({ inputRoot, scorerRelPath });
|
|
53026
53450
|
const result = await runOptimizationLoop({
|
|
53027
53451
|
directory,
|
|
@@ -53064,11 +53488,11 @@ async function handleSkillOptDiff(directory, args) {
|
|
|
53064
53488
|
if (idError)
|
|
53065
53489
|
return idError;
|
|
53066
53490
|
const baseline = readArtifact(directory, parsed.skillSlug, parsed.candidateId, "baseline.md") ?? "";
|
|
53067
|
-
const
|
|
53491
|
+
const candidate2 = readArtifact(directory, parsed.skillSlug, parsed.candidateId, "candidate.md") ?? "";
|
|
53068
53492
|
const replay = replayCandidate(directory, parsed.skillSlug, parsed.candidateId);
|
|
53069
53493
|
const baselineLines = baseline.split(`
|
|
53070
53494
|
`);
|
|
53071
|
-
const candidateLines =
|
|
53495
|
+
const candidateLines = candidate2.split(`
|
|
53072
53496
|
`);
|
|
53073
53497
|
const max = Math.max(baselineLines.length, candidateLines.length);
|
|
53074
53498
|
let added = 0;
|
|
@@ -53091,11 +53515,11 @@ async function handleSkillOptDiff(directory, args) {
|
|
|
53091
53515
|
candidateId: parsed.candidateId,
|
|
53092
53516
|
lastState: replay.state,
|
|
53093
53517
|
baselineBytes: baseline.length,
|
|
53094
|
-
candidateBytes:
|
|
53518
|
+
candidateBytes: candidate2.length,
|
|
53095
53519
|
linesAdded: added,
|
|
53096
53520
|
linesRemoved: removed,
|
|
53097
53521
|
baselinePreview: baseline.slice(0, 400),
|
|
53098
|
-
candidatePreview:
|
|
53522
|
+
candidatePreview: candidate2.slice(0, 400),
|
|
53099
53523
|
truncated: replay.truncated
|
|
53100
53524
|
}, parsed.json);
|
|
53101
53525
|
}
|
|
@@ -53194,12 +53618,12 @@ async function handleSpecifyCommand(_directory, args) {
|
|
|
53194
53618
|
init_loader();
|
|
53195
53619
|
init_schema();
|
|
53196
53620
|
import * as fsSync3 from "fs";
|
|
53197
|
-
import { readFile as
|
|
53198
|
-
import * as
|
|
53621
|
+
import { readFile as readFile22 } from "fs/promises";
|
|
53622
|
+
import * as path103 from "path";
|
|
53199
53623
|
|
|
53200
53624
|
// src/consensus/store.ts
|
|
53201
53625
|
import { readdir as readdir5, unlink as unlink3 } from "fs/promises";
|
|
53202
|
-
import * as
|
|
53626
|
+
import * as path101 from "path";
|
|
53203
53627
|
|
|
53204
53628
|
// src/consensus/contracts.ts
|
|
53205
53629
|
init_zod();
|
|
@@ -53370,10 +53794,10 @@ var SENTENCE_TERMINATOR_CLASS = "\\p{Sentence_Terminal}\\u2025\\u2026\\u22EF\\uF
|
|
|
53370
53794
|
var SINGLE_SENTENCE_RE = new RegExp(`^[^${SENTENCE_TERMINATOR_CLASS}]*(?:[${SENTENCE_TERMINATOR_CLASS}]+["')]?)?$`, "u");
|
|
53371
53795
|
|
|
53372
53796
|
// src/consensus/store.ts
|
|
53373
|
-
var CONSENSUS_RELATIVE_DIR =
|
|
53797
|
+
var CONSENSUS_RELATIVE_DIR = path101.join("evolution", "consensus");
|
|
53374
53798
|
var REPORT_ID_RE = /^[A-Za-z0-9][A-Za-z0-9._-]{0,159}$/;
|
|
53375
53799
|
function swarmPath(directory, ...segments) {
|
|
53376
|
-
return
|
|
53800
|
+
return path101.join(directory, ".swarm", ...segments);
|
|
53377
53801
|
}
|
|
53378
53802
|
async function countConsensusReportFiles(directory) {
|
|
53379
53803
|
const root = swarmPath(directory, CONSENSUS_RELATIVE_DIR);
|
|
@@ -53389,16 +53813,16 @@ async function countConsensusReportFiles(directory) {
|
|
|
53389
53813
|
|
|
53390
53814
|
// src/turbo/lean/state.ts
|
|
53391
53815
|
init_logger();
|
|
53392
|
-
import * as
|
|
53393
|
-
import * as
|
|
53816
|
+
import * as fs49 from "fs";
|
|
53817
|
+
import * as path102 from "path";
|
|
53394
53818
|
var STATE_FILE3 = "turbo-state.json";
|
|
53395
53819
|
function nowISO3() {
|
|
53396
53820
|
return new Date().toISOString();
|
|
53397
53821
|
}
|
|
53398
53822
|
function ensureSwarmDir2(directory) {
|
|
53399
|
-
const swarmDir =
|
|
53400
|
-
if (!
|
|
53401
|
-
|
|
53823
|
+
const swarmDir = path102.resolve(directory, ".swarm");
|
|
53824
|
+
if (!fs49.existsSync(swarmDir)) {
|
|
53825
|
+
fs49.mkdirSync(swarmDir, { recursive: true });
|
|
53402
53826
|
}
|
|
53403
53827
|
return swarmDir;
|
|
53404
53828
|
}
|
|
@@ -53441,17 +53865,17 @@ function markStateUnreadable2(directory, reason) {
|
|
|
53441
53865
|
}
|
|
53442
53866
|
function readPersisted2(directory) {
|
|
53443
53867
|
try {
|
|
53444
|
-
const filePath =
|
|
53445
|
-
if (!
|
|
53868
|
+
const filePath = path102.join(directory, ".swarm", STATE_FILE3);
|
|
53869
|
+
if (!fs49.existsSync(filePath)) {
|
|
53446
53870
|
const seed = emptyPersisted2();
|
|
53447
53871
|
try {
|
|
53448
53872
|
ensureSwarmDir2(directory);
|
|
53449
|
-
|
|
53873
|
+
fs49.writeFileSync(filePath, `${JSON.stringify(seed, null, 2)}
|
|
53450
53874
|
`, "utf-8");
|
|
53451
53875
|
} catch {}
|
|
53452
53876
|
return seed;
|
|
53453
53877
|
}
|
|
53454
|
-
const raw =
|
|
53878
|
+
const raw = fs49.readFileSync(filePath, "utf-8");
|
|
53455
53879
|
const parsed = JSON.parse(raw);
|
|
53456
53880
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed) || parsed.version !== 1 || !parsed.sessions || typeof parsed.sessions !== "object" || Array.isArray(parsed.sessions)) {
|
|
53457
53881
|
markStateUnreadable2(directory, `malformed shape (version=${parsed?.version}, sessions type=${Array.isArray(parsed?.sessions) ? "array" : typeof parsed?.sessions})`);
|
|
@@ -53477,7 +53901,7 @@ function writePersisted2(directory, persisted) {
|
|
|
53477
53901
|
let payload;
|
|
53478
53902
|
try {
|
|
53479
53903
|
ensureSwarmDir2(directory);
|
|
53480
|
-
filePath =
|
|
53904
|
+
filePath = path102.join(directory, ".swarm", STATE_FILE3);
|
|
53481
53905
|
tmpPath = `${filePath}.tmp.${Date.now()}`;
|
|
53482
53906
|
persisted.updatedAt = nowISO3();
|
|
53483
53907
|
payload = `${JSON.stringify(persisted, null, 2)}
|
|
@@ -53488,14 +53912,14 @@ function writePersisted2(directory, persisted) {
|
|
|
53488
53912
|
throw new Error(`Lean Turbo state persistence prepare failed: ${msg}`);
|
|
53489
53913
|
}
|
|
53490
53914
|
try {
|
|
53491
|
-
|
|
53492
|
-
|
|
53915
|
+
fs49.writeFileSync(tmpPath, payload, "utf-8");
|
|
53916
|
+
fs49.renameSync(tmpPath, filePath);
|
|
53493
53917
|
} catch (error2) {
|
|
53494
53918
|
const msg = error2 instanceof Error ? error2.message : String(error2);
|
|
53495
53919
|
error(`[turbo/lean/state] Failed to persist ${STATE_FILE3} atomically: ${msg}`);
|
|
53496
53920
|
try {
|
|
53497
|
-
if (
|
|
53498
|
-
|
|
53921
|
+
if (fs49.existsSync(tmpPath)) {
|
|
53922
|
+
fs49.unlinkSync(tmpPath);
|
|
53499
53923
|
}
|
|
53500
53924
|
} catch {}
|
|
53501
53925
|
throw new Error(`Lean Turbo state persistence failed: ${msg}`);
|
|
@@ -53598,7 +54022,7 @@ var _internals82 = {
|
|
|
53598
54022
|
};
|
|
53599
54023
|
function readSpecStalenessSnapshot(directory) {
|
|
53600
54024
|
try {
|
|
53601
|
-
const p =
|
|
54025
|
+
const p = path103.join(directory, ".swarm", "spec-staleness.json");
|
|
53602
54026
|
if (!fsSync3.existsSync(p))
|
|
53603
54027
|
return { stale: false };
|
|
53604
54028
|
const raw = fsSync3.readFileSync(p, "utf-8");
|
|
@@ -53634,9 +54058,9 @@ async function getStatusData(directory, agents, sessionId) {
|
|
|
53634
54058
|
let completedTasks = 0;
|
|
53635
54059
|
let totalTasks = 0;
|
|
53636
54060
|
for (const phase of plan.phases) {
|
|
53637
|
-
for (const
|
|
54061
|
+
for (const task2 of phase.tasks) {
|
|
53638
54062
|
totalTasks++;
|
|
53639
|
-
if (
|
|
54063
|
+
if (task2.status === "completed")
|
|
53640
54064
|
completedTasks++;
|
|
53641
54065
|
}
|
|
53642
54066
|
}
|
|
@@ -53736,7 +54160,7 @@ async function getStatusData(directory, agents, sessionId) {
|
|
|
53736
54160
|
const memoryConfig = MemoryConfigSchema.parse(loadPluginConfig(directory).memory ?? {});
|
|
53737
54161
|
provider = memoryConfig.provider;
|
|
53738
54162
|
if (memoryPointer) {
|
|
53739
|
-
const cohortConfigPath =
|
|
54163
|
+
const cohortConfigPath = path103.join(resolveLinkDir(memoryPointer.linkId), "memory", "memory-cohort-config.json");
|
|
53740
54164
|
if (fsSync3.existsSync(cohortConfigPath)) {
|
|
53741
54165
|
const stored = JSON.parse(fsSync3.readFileSync(cohortConfigPath, "utf-8"));
|
|
53742
54166
|
const versionCheck = classifyStoredFingerprintAlgorithmVersion(stored.algorithm_version);
|
|
@@ -54030,7 +54454,7 @@ async function safeLineCount(filePath) {
|
|
|
54030
54454
|
try {
|
|
54031
54455
|
if (!fsSync3.existsSync(filePath))
|
|
54032
54456
|
return 0;
|
|
54033
|
-
const content = await
|
|
54457
|
+
const content = await readFile22(filePath, "utf-8");
|
|
54034
54458
|
let n = 0;
|
|
54035
54459
|
for (const line of content.split(`
|
|
54036
54460
|
`)) {
|
|
@@ -54314,7 +54738,7 @@ function buildStatusMessage2(session, directory, sessionID) {
|
|
|
54314
54738
|
}
|
|
54315
54739
|
|
|
54316
54740
|
// src/commands/unlink.ts
|
|
54317
|
-
import * as
|
|
54741
|
+
import * as path104 from "path";
|
|
54318
54742
|
async function handleUnlinkCommand(directory, args) {
|
|
54319
54743
|
const pointer = readLinkPointer(directory);
|
|
54320
54744
|
if (!pointer) {
|
|
@@ -54327,7 +54751,7 @@ async function handleUnlinkCommand(directory, args) {
|
|
|
54327
54751
|
let familySummary = "";
|
|
54328
54752
|
if (copyBack) {
|
|
54329
54753
|
try {
|
|
54330
|
-
const result = await migrateKnowledgeFamily(
|
|
54754
|
+
const result = await migrateKnowledgeFamily(path104.join(directory, ".swarm"), linkDir);
|
|
54331
54755
|
for (const m of result.perMember) {
|
|
54332
54756
|
totalMerged += m.merged;
|
|
54333
54757
|
totalSkipped += m.skipped;
|
|
@@ -54505,7 +54929,7 @@ function buildDetailedHelp(commandName, entry) {
|
|
|
54505
54929
|
async function handleHelpCommand(ctx) {
|
|
54506
54930
|
const targetCommand = ctx.args.join(" ");
|
|
54507
54931
|
if (!targetCommand) {
|
|
54508
|
-
const { buildHelpText } = await import("./index-
|
|
54932
|
+
const { buildHelpText } = await import("./index-7e60c7ay.js");
|
|
54509
54933
|
return buildHelpText();
|
|
54510
54934
|
}
|
|
54511
54935
|
const tokens = targetCommand.split(/\s+/);
|
|
@@ -54514,7 +54938,7 @@ async function handleHelpCommand(ctx) {
|
|
|
54514
54938
|
return _internals14.buildDetailedHelp(resolved.key, resolved.entry);
|
|
54515
54939
|
}
|
|
54516
54940
|
const similar = _internals14.findSimilarCommands(targetCommand);
|
|
54517
|
-
const { buildHelpText: fullHelp } = await import("./index-
|
|
54941
|
+
const { buildHelpText: fullHelp } = await import("./index-7e60c7ay.js");
|
|
54518
54942
|
if (similar.length > 0) {
|
|
54519
54943
|
return `Command '/swarm ${targetCommand}' not found.
|
|
54520
54944
|
|
|
@@ -54691,7 +55115,7 @@ var COMMAND_REGISTRY = {
|
|
|
54691
55115
|
},
|
|
54692
55116
|
"guardrail explain": {
|
|
54693
55117
|
handler: async (ctx) => {
|
|
54694
|
-
const { handleGuardrailExplain } = await import("./guardrail-explain-
|
|
55118
|
+
const { handleGuardrailExplain } = await import("./guardrail-explain-qh1y8jsz.js");
|
|
54695
55119
|
return handleGuardrailExplain(ctx.directory, ctx.args);
|
|
54696
55120
|
},
|
|
54697
55121
|
description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
|
|
@@ -54701,7 +55125,7 @@ var COMMAND_REGISTRY = {
|
|
|
54701
55125
|
},
|
|
54702
55126
|
"guardrail-explain": {
|
|
54703
55127
|
handler: async (ctx) => {
|
|
54704
|
-
const { handleGuardrailExplain } = await import("./guardrail-explain-
|
|
55128
|
+
const { handleGuardrailExplain } = await import("./guardrail-explain-qh1y8jsz.js");
|
|
54705
55129
|
return handleGuardrailExplain(ctx.directory, ctx.args);
|
|
54706
55130
|
},
|
|
54707
55131
|
description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
|
|
@@ -54711,7 +55135,7 @@ var COMMAND_REGISTRY = {
|
|
|
54711
55135
|
},
|
|
54712
55136
|
"guardrail-log": {
|
|
54713
55137
|
handler: async (ctx) => {
|
|
54714
|
-
const { handleGuardrailLog } = await import("./guardrail-log-
|
|
55138
|
+
const { handleGuardrailLog } = await import("./guardrail-log-84zffdv3.js");
|
|
54715
55139
|
return handleGuardrailLog(ctx.directory, ctx.args);
|
|
54716
55140
|
},
|
|
54717
55141
|
description: "Read the guardrail decision log (use --blocks-only for blocks)",
|
|
@@ -55656,24 +56080,24 @@ function validateAliases() {
|
|
|
55656
56080
|
continue;
|
|
55657
56081
|
}
|
|
55658
56082
|
const visited = new Set;
|
|
55659
|
-
const
|
|
56083
|
+
const path105 = [];
|
|
55660
56084
|
let current = target;
|
|
55661
56085
|
while (current) {
|
|
55662
56086
|
const currentEntry = COMMAND_REGISTRY[current];
|
|
55663
56087
|
if (!currentEntry)
|
|
55664
56088
|
break;
|
|
55665
56089
|
if (visited.has(current)) {
|
|
55666
|
-
const cycleStart =
|
|
56090
|
+
const cycleStart = path105.indexOf(current);
|
|
55667
56091
|
const fullChain = [
|
|
55668
56092
|
name,
|
|
55669
|
-
...
|
|
56093
|
+
...path105.slice(0, cycleStart > 0 ? cycleStart : path105.length),
|
|
55670
56094
|
current
|
|
55671
56095
|
].join(" \u2192 ");
|
|
55672
56096
|
errors.push(`Circular alias detected: ${fullChain}`);
|
|
55673
56097
|
break;
|
|
55674
56098
|
}
|
|
55675
56099
|
visited.add(current);
|
|
55676
|
-
|
|
56100
|
+
path105.push(current);
|
|
55677
56101
|
current = currentEntry.aliasOf || "";
|
|
55678
56102
|
}
|
|
55679
56103
|
}
|