opencode-swarm 7.146.0 → 7.146.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.
Files changed (60) hide show
  1. package/.opencode/skills/swarm-pr-review/SKILL.md +67 -33
  2. package/dist/cli/{config-doctor-vs6hvbew.js → config-doctor-sd7x5bts.js} +2 -2
  3. package/dist/cli/{core-jvvm935f.js → core-17febkvw.js} +1 -1
  4. package/dist/cli/{curation-policy-xv0j8zyt.js → curation-policy-x19e8bqc.js} +4 -4
  5. package/dist/cli/{curator-llm-factory-pe6skby4.js → curator-llm-factory-zxbgkjm5.js} +23 -23
  6. package/dist/cli/{curator-5bxh1djq.js → curator-vghf320v.js} +23 -23
  7. package/dist/cli/{evidence-summary-service-6m9jmzk8.js → evidence-summary-service-xma4aagr.js} +9 -9
  8. package/dist/cli/{gate-evidence-84sfx6g8.js → gate-evidence-2bznvee8.js} +4 -4
  9. package/dist/cli/{guardrail-explain-jhbxq8yb.js → guardrail-explain-ppzg0xz9.js} +24 -24
  10. package/dist/cli/{guardrail-log-vpbp3rm4.js → guardrail-log-xexwz93q.js} +3 -3
  11. package/dist/cli/{hive-promoter-mmmfszv8.js → hive-promoter-j3vw2hj4.js} +23 -23
  12. package/dist/cli/{index-jfcgnvg6.js → index-19f0zycs.js} +2 -2
  13. package/dist/cli/{index-5qwmpamg.js → index-1c9mfnj0.js} +1 -1
  14. package/dist/cli/{index-d4e6wpkg.js → index-4qvsh3m5.js} +8 -5
  15. package/dist/cli/{index-pz2py5v7.js → index-7x00nx8m.js} +321 -99
  16. package/dist/cli/{index-gxbhp7sx.js → index-9qbr27bw.js} +2 -2
  17. package/dist/cli/{index-s8qyaqs2.js → index-bd4g9fvb.js} +1 -1
  18. package/dist/cli/{index-q2mvacjr.js → index-cw96tpy6.js} +4 -4
  19. package/dist/cli/{index-4p3qfb05.js → index-e1hjd15c.js} +1 -1
  20. package/dist/cli/{index-j43qndgc.js → index-e3caa7ng.js} +25 -25
  21. package/dist/cli/{index-f17j50dx.js → index-fksfxhmx.js} +5 -5
  22. package/dist/cli/{index-fzqhn96z.js → index-g8qbjqqz.js} +1 -1
  23. package/dist/cli/{index-fay8h6v8.js → index-h8qed3pr.js} +18 -3
  24. package/dist/cli/{index-zd1mfygt.js → index-k46kg4t6.js} +5 -5
  25. package/dist/cli/{index-bma2wrqx.js → index-n7trn9wz.js} +5 -1
  26. package/dist/cli/{index-j20fzn0w.js → index-qbpxrw95.js} +1 -1
  27. package/dist/cli/{index-92cxd0r1.js → index-t7sfrv3v.js} +3 -3
  28. package/dist/cli/{index-n6ke10ck.js → index-twwb61bh.js} +3 -3
  29. package/dist/cli/{index-g3xt1d16.js → index-txh3h83v.js} +4 -4
  30. package/dist/cli/{index-zsmsy1dh.js → index-tzyvmkd1.js} +1 -1
  31. package/dist/cli/{index-fyr2wbvz.js → index-va8a2zrq.js} +2 -2
  32. package/dist/cli/{index-kfmee1cr.js → index-vacrzesw.js} +6 -6
  33. package/dist/cli/{index-x8pm918t.js → index-w0cj7zyd.js} +1 -1
  34. package/dist/cli/{index-0a0asz2s.js → index-w5r84rd1.js} +1 -1
  35. package/dist/cli/{index-vk15nbh4.js → index-xz0ccakc.js} +1 -1
  36. package/dist/cli/{index-kggqpefz.js → index-ycgm9pzg.js} +1 -1
  37. package/dist/cli/{index-nsr5b69r.js → index-zkaz3fhw.js} +1 -1
  38. package/dist/cli/{index-kwxp0z0n.js → index-zwn2e2pe.js} +3 -3
  39. package/dist/cli/index.js +23 -23
  40. package/dist/cli/{knowledge-escalator-c9p3w12b.js → knowledge-escalator-wj85ppdt.js} +9 -9
  41. package/dist/cli/{knowledge-events-d201414m.js → knowledge-events-4y9kk2xe.js} +7 -7
  42. package/dist/cli/{knowledge-link-82ew2yc4.js → knowledge-link-8pr02pza.js} +3 -3
  43. package/dist/cli/{knowledge-store-ds45k9th.js → knowledge-store-kc8dwc14.js} +4 -4
  44. package/dist/cli/{knowledge-validator-707vsncy.js → knowledge-validator-584ga9fb.js} +6 -6
  45. package/dist/cli/{runner-pqsf809k.js → runner-e7z9cf5y.js} +4 -4
  46. package/dist/cli/{scan-cursor-znhqb8xa.js → scan-cursor-rhjym1pn.js} +5 -5
  47. package/dist/cli/{schema-dnnm0p40.js → schema-yb3pvhcs.js} +5 -1
  48. package/dist/cli/{scope-persistence-4n24a1e2.js → scope-persistence-bxwjk9rc.js} +5 -5
  49. package/dist/cli/{skill-generator-5s0p3y8k.js → skill-generator-3w8w7htr.js} +11 -11
  50. package/dist/cli/{worktree-isolation-1v2mythh.js → worktree-isolation-av1rshr3.js} +23 -23
  51. package/dist/commands/registry.d.ts +1 -1
  52. package/dist/config/schema.d.ts +22 -0
  53. package/dist/hooks/guardrails/index.d.ts +35 -0
  54. package/dist/hooks/pr-workflow-gate.d.ts +48 -2
  55. package/dist/hooks/pr-workflow-response-gate.d.ts +24 -0
  56. package/dist/index.js +60 -62
  57. package/dist/tools/dispatch-lanes.d.ts +13 -1
  58. package/dist/workflow/coder-settlement.d.ts +13 -0
  59. package/dist/workflow/stage-a-repair.d.ts +41 -0
  60. package/package.json +1 -1
@@ -6,16 +6,16 @@ import {
6
6
  resolveExecutableFromPath,
7
7
  runEvaluation,
8
8
  runExternalTool
9
- } from "./index-0a0asz2s.js";
9
+ } from "./index-w5r84rd1.js";
10
10
  import {
11
11
  stableCanonicalStringify
12
- } from "./index-vk15nbh4.js";
12
+ } from "./index-xz0ccakc.js";
13
13
  import {
14
14
  detectStraySwarmDirs,
15
15
  readDoctorArtifact,
16
16
  removeStraySwarmDir,
17
17
  runConfigDoctor
18
- } from "./index-bma2wrqx.js";
18
+ } from "./index-n7trn9wz.js";
19
19
  import {
20
20
  MAX_TRANSIENT_RETRIES,
21
21
  archiveEvidence,
@@ -38,6 +38,7 @@ import {
38
38
  isGitRepo,
39
39
  isGlobalFile,
40
40
  isProtectedPath,
41
+ isSecretscanEvidence,
41
42
  isStateUnreadable,
42
43
  isTransientSpawnError,
43
44
  isValidEvidenceType,
@@ -60,7 +61,7 @@ import {
60
61
  updateTaskStatus,
61
62
  validateProjectRoot,
62
63
  validateSymlinkBoundary
63
- } from "./index-d4e6wpkg.js";
64
+ } from "./index-4qvsh3m5.js";
64
65
  import {
65
66
  EvaluationTaskV1Schema,
66
67
  GateAuditManifestV1Schema,
@@ -77,7 +78,7 @@ import {
77
78
  saveGateAuditResult,
78
79
  savePromotionDecision,
79
80
  saveTaskSetSnapshot
80
- } from "./index-nsr5b69r.js";
81
+ } from "./index-zkaz3fhw.js";
81
82
  import {
82
83
  loadDatabaseCtor
83
84
  } from "./index-134d35c1.js";
@@ -103,12 +104,12 @@ import {
103
104
  } from "./index-y8552snf.js";
104
105
  import {
105
106
  readRecentEscalations
106
- } from "./index-f17j50dx.js";
107
+ } from "./index-fksfxhmx.js";
107
108
  import {
108
109
  alreadyCuratedThisGeneration,
109
110
  claimNextScanBatch,
110
111
  resolveCohortId
111
- } from "./index-gxbhp7sx.js";
112
+ } from "./index-9qbr27bw.js";
112
113
  import {
113
114
  CURATOR_INIT_PROMPT,
114
115
  CURATOR_PHASE_PROMPT,
@@ -178,7 +179,7 @@ import {
178
179
  retireSkill,
179
180
  selectCandidateEntries,
180
181
  syncBundledProjectSkillsIfMissingAsync
181
- } from "./index-g3xt1d16.js";
182
+ } from "./index-txh3h83v.js";
182
183
  import {
183
184
  appendUnactionable,
184
185
  quarantineEntry,
@@ -189,11 +190,11 @@ import {
189
190
  validateActionableFields,
190
191
  validateLesson,
191
192
  validateSkillPath
192
- } from "./index-q2mvacjr.js";
193
+ } from "./index-cw96tpy6.js";
193
194
  import {
194
195
  authorizeCuration,
195
196
  buildConfigFingerprintInput
196
- } from "./index-4p3qfb05.js";
197
+ } from "./index-e1hjd15c.js";
197
198
  import {
198
199
  cohortConfigFingerprint
199
200
  } from "./index-rtry5xyf.js";
@@ -233,27 +234,30 @@ import {
233
234
  isGitBinaryMissing,
234
235
  isSpawnCwdMissing,
235
236
  isSpawnCwdUnreadable,
237
+ isStrictTaskId,
236
238
  listRecoveryRecords,
237
239
  parseTaskEvidence,
238
240
  postMergeCleanup,
239
241
  pruneStaleWorktreeMetadata,
242
+ readTaskEvidence,
240
243
  readWorkflowWalFile,
241
244
  reconcileLandedMerge,
242
245
  startupOrphanRecovery,
246
+ transitionTaskWorkflowEvidence,
243
247
  withTaskEvidenceTransaction,
244
248
  writeWorkflowWalFile
245
- } from "./index-92cxd0r1.js";
249
+ } from "./index-t7sfrv3v.js";
246
250
  import {
247
251
  provisionWorktree,
248
252
  removeWorktree
249
- } from "./index-zsmsy1dh.js";
253
+ } from "./index-tzyvmkd1.js";
250
254
  import {
251
255
  MAX_PENDING_SCOPE_BINDINGS,
252
256
  canonicalWorkspaceIdentity,
253
257
  clearAllScopes,
254
258
  clearScopeBindingFromDisk,
255
259
  clearScopeBindings
256
- } from "./index-kwxp0z0n.js";
260
+ } from "./index-zwn2e2pe.js";
257
261
  import {
258
262
  appendLedgerEvent,
259
263
  computePlanHash,
@@ -267,7 +271,7 @@ import {
267
271
  readPlanEpochIdentity,
268
272
  replayFromLedgerWithStatus,
269
273
  takeSnapshotEvent
270
- } from "./index-fzqhn96z.js";
274
+ } from "./index-g8qbjqqz.js";
271
275
  import {
272
276
  isPathWithinDeclaredScope,
273
277
  sanitizeDiagnosticText
@@ -318,7 +322,7 @@ import {
318
322
  transactFile,
319
323
  transactKnowledge,
320
324
  wordBigrams
321
- } from "./index-kfmee1cr.js";
325
+ } from "./index-vacrzesw.js";
322
326
  import {
323
327
  MAX_EVENT_LOG_ENTRIES,
324
328
  _internals as _internals2,
@@ -332,10 +336,10 @@ import {
332
336
  recordKnowledgeEvent,
333
337
  recordPhaseCloseIntent,
334
338
  resolveKnowledgeEventsPath
335
- } from "./index-zd1mfygt.js";
339
+ } from "./index-k46kg4t6.js";
336
340
  import {
337
341
  resolveWorktreeIsolationConfig
338
- } from "./index-jfcgnvg6.js";
342
+ } from "./index-19f0zycs.js";
339
343
  import {
340
344
  RetrospectiveEvidenceSchema
341
345
  } from "./index-gprxjmm7.js";
@@ -345,7 +349,7 @@ import {
345
349
  init_loader,
346
350
  loadPluginConfig,
347
351
  loadPluginConfigWithMeta
348
- } from "./index-5qwmpamg.js";
352
+ } from "./index-1c9mfnj0.js";
349
353
  import {
350
354
  DEFAULT_SKILL_OPT_CONFIG,
351
355
  FALLBACK_MODELS_MAX,
@@ -359,7 +363,7 @@ import {
359
363
  package_default,
360
364
  resolveAutoReviewConfig,
361
365
  stripKnownSwarmPrefix
362
- } from "./index-fay8h6v8.js";
366
+ } from "./index-h8qed3pr.js";
363
367
  import {
364
368
  AGENT_TOOL_MAP,
365
369
  ALL_AGENT_NAMES,
@@ -410,10 +414,10 @@ import {
410
414
  resolveLinkDir,
411
415
  sanitizeLinkId,
412
416
  writeLinkPointer
413
- } from "./index-x8pm918t.js";
417
+ } from "./index-w0cj7zyd.js";
414
418
  import {
415
419
  atomicWriteFile
416
- } from "./index-j20fzn0w.js";
420
+ } from "./index-qbpxrw95.js";
417
421
  import {
418
422
  KNOWLEDGE_SCHEMA_VERSION,
419
423
  OUTCOME_BLOCK_THRESHOLD,
@@ -425,7 +429,7 @@ import {
425
429
  atomicWriteSwarmFileSync,
426
430
  matchTempGrammar,
427
431
  parseTargetBasename
428
- } from "./index-kggqpefz.js";
432
+ } from "./index-ycgm9pzg.js";
429
433
  import {
430
434
  assertProjectRoot,
431
435
  hasExplicitProjectBoundary,
@@ -4193,7 +4197,7 @@ async function cleanupRecoveredWorktree(directory, descriptor) {
4193
4197
  awaitingMergeByCallID,
4194
4198
  cleanupStandardWorktreeForCallId,
4195
4199
  standardWorktreeByCallID
4196
- } = await import("./worktree-isolation-1v2mythh.js");
4200
+ } = await import("./worktree-isolation-av1rshr3.js");
4197
4201
  standardWorktreeByCallID.delete(descriptor.callID);
4198
4202
  if (hasResidue)
4199
4203
  awaitingMergeByCallID.set(descriptor.callID, {
@@ -4295,7 +4299,7 @@ async function recoverCoderSettlement(directory, taskId) {
4295
4299
  awaitingMergeByCallID,
4296
4300
  finishStandardWorktreeDispatch,
4297
4301
  standardWorktreeByCallID
4298
- } = await import("./worktree-isolation-1v2mythh.js");
4302
+ } = await import("./worktree-isolation-av1rshr3.js");
4299
4303
  const descriptor = wal.worktree;
4300
4304
  const reconstructedDispatch = {
4301
4305
  callID: descriptor.callID,
@@ -4438,6 +4442,8 @@ async function listCoderSettlementWalStates(directory) {
4438
4442
  transitionId: wal.transitionId,
4439
4443
  processId: wal.processId,
4440
4444
  recordedAt: wal.recordedAt,
4445
+ accepted: wal.accepted === true ? true : undefined,
4446
+ declaredFiles: wal.context?.declaredFiles ?? null,
4441
4447
  ownedInProcess: liveDispatches.has(dispatchKey(directory, taskId, wal.transitionId)),
4442
4448
  ownedByLiveForeignPid: wal.processId !== process.pid && isProcessAlive(wal.processId)
4443
4449
  });
@@ -6810,6 +6816,8 @@ var PR_REVIEW_MICRO_LANE_FLOORS = {
6810
6816
  var GATE_SCHEMA_VERSION = 1;
6811
6817
  var MAX_TRACKED_SESSIONS3 = 200;
6812
6818
  var MAX_WORKFLOW_BATCHES = 128;
6819
+ var MAX_PR_REVIEW_BASE_LANES_PER_BATCH = PR_REVIEW_BASE_DIMENSION_IDS.length;
6820
+ var MAX_PR_REVIEW_RESILIENCE_CIRCUIT_CONTRIBUTORS = MAX_WORKFLOW_BATCHES * MAX_PR_REVIEW_BASE_LANES_PER_BATCH;
6813
6821
  var MAX_RETIRED_REVIEWER_SESSION_IDS = 1024;
6814
6822
  var MAX_RETIRED_CONSOLIDATED_LANES = 64;
6815
6823
  var MAX_RETIRED_FEEDBACK_ITEM_OWNERS = 4096;
@@ -6845,9 +6853,39 @@ var PrReviewBaseDispatchRecordSchema = exports_external.object({
6845
6853
  laneId: exports_external.string().min(1),
6846
6854
  workflowLane: PrReviewBaseDimensionIdSchema,
6847
6855
  ownedWorkflowLanes: exports_external.array(PrReviewBaseDimensionIdSchema).min(1).max(PR_REVIEW_BASE_DIMENSION_IDS.length).optional()
6848
- }).strict()).min(1),
6856
+ }).strict()).min(1).max(MAX_PR_REVIEW_BASE_LANES_PER_BATCH),
6849
6857
  validatedAt: exports_external.string().min(1)
6850
6858
  }).strict();
6859
+ var PrReviewResiliencePolicyRecordSchema = exports_external.object({
6860
+ enabled: exports_external.boolean(),
6861
+ canaryProbeMs: exports_external.number().int().positive(),
6862
+ statusProbeTimeoutMs: exports_external.number().int().positive(),
6863
+ correlatedFailureThreshold: exports_external.number().int().min(2).max(8),
6864
+ maxRetryAttemptsAfterInitial: exports_external.number().int().min(0).max(2)
6865
+ }).strict();
6866
+ var PrReviewResilienceAttemptRecordSchema = exports_external.object({
6867
+ attempt: exports_external.union([exports_external.literal(0), exports_external.literal(1), exports_external.literal(2)]),
6868
+ targetDimensions: exports_external.array(PrReviewBaseDimensionIdSchema).min(1).max(PR_REVIEW_BASE_DIMENSION_IDS.length),
6869
+ canaryBatchId: exports_external.string().min(1),
6870
+ canaryLaneId: exports_external.string().min(1),
6871
+ canaryWorkflowLane: PrReviewBaseDimensionIdSchema,
6872
+ admittedAt: exports_external.string().min(1),
6873
+ fanoutBatchId: exports_external.string().min(1).optional()
6874
+ }).strict();
6875
+ var PrReviewResilienceCircuitRecordSchema = exports_external.object({
6876
+ signature: exports_external.string().min(1).max(512),
6877
+ count: exports_external.number().int().min(2).max(MAX_PR_REVIEW_RESILIENCE_CIRCUIT_CONTRIBUTORS),
6878
+ contributors: exports_external.array(exports_external.object({
6879
+ batchId: exports_external.string().min(1),
6880
+ laneId: exports_external.string().min(1)
6881
+ }).strict()).min(2).max(MAX_PR_REVIEW_RESILIENCE_CIRCUIT_CONTRIBUTORS),
6882
+ openedAt: exports_external.string().min(1)
6883
+ }).strict();
6884
+ var PrReviewResilienceStateRecordSchema = exports_external.object({
6885
+ policy: PrReviewResiliencePolicyRecordSchema,
6886
+ attempts: exports_external.array(PrReviewResilienceAttemptRecordSchema).max(3),
6887
+ circuit: PrReviewResilienceCircuitRecordSchema.optional()
6888
+ }).strict();
6851
6889
  var PrFeedbackLaneOwnershipSchema = exports_external.object({
6852
6890
  laneId: exports_external.string().min(1),
6853
6891
  ownedItemIds: exports_external.array(exports_external.string().min(1)).min(1)
@@ -6998,6 +7036,7 @@ var PrWorkflowGateStateSchema = exports_external.object({
6998
7036
  }).strict().optional(),
6999
7037
  prReviewBaseDispatches: exports_external.array(PrReviewBaseDispatchRecordSchema).max(MAX_WORKFLOW_BATCHES).optional(),
7000
7038
  prReviewBaseDispatch: PrReviewBaseDispatchRecordSchema.optional(),
7039
+ prReviewResilience: PrReviewResilienceStateRecordSchema.optional(),
7001
7040
  prReviewTriggerLedger: exports_external.array(PrReviewInlineTriggerRowSchema).length(PR_REVIEW_REQUIRED_TRIGGER_IDS.length).optional(),
7002
7041
  prReviewTriggerEvalPath: exports_external.string().min(1).optional(),
7003
7042
  prReviewTriggerEvalRunId: exports_external.string().min(1).optional(),
@@ -8020,6 +8059,7 @@ var _test_exports = {
8020
8059
  resolvePrReviewDiffStatsAsync,
8021
8060
  resolvePrWorkflowRevisionDigest,
8022
8061
  MAX_WORKFLOW_BATCHES,
8062
+ MAX_PR_REVIEW_RESILIENCE_CIRCUIT_CONTRIBUTORS,
8023
8063
  MAX_RETIRED_REVIEWER_SESSION_IDS,
8024
8064
  MAX_RETIRED_CONSOLIDATED_LANES,
8025
8065
  MAX_RETIRED_FEEDBACK_ITEM_OWNERS,
@@ -15558,7 +15598,7 @@ function planMerges(active, threshold, maxComparisons, maxMerges) {
15558
15598
  };
15559
15599
  }
15560
15600
  async function sweepActiveNearDuplicates(directory, options = {}) {
15561
- const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-n6ke10ck.js");
15601
+ const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-twwb61bh.js");
15562
15602
  const { config } = loadPluginConfigWithMeta2(directory);
15563
15603
  const sweepConfig = config.learning?.dedup_sweep;
15564
15604
  if (sweepConfig?.enabled === false)
@@ -16642,7 +16682,7 @@ async function runCuratorPhase(directory, phase, agentsDispatched, config, knowl
16642
16682
  }
16643
16683
  if (config.skill_generation_enabled === true && skillCandidates.length > 0) {
16644
16684
  try {
16645
- const skillModule = await import("./skill-generator-5s0p3y8k.js");
16685
+ const skillModule = await import("./skill-generator-3w8w7htr.js");
16646
16686
  for (const cand of skillCandidates) {
16647
16687
  if (cand.confidence < (config.min_skill_confidence ?? DEFAULT_SKILL_MIN_CONFIDENCE)) {
16648
16688
  continue;
@@ -17102,7 +17142,7 @@ async function applyCuratorKnowledgeUpdates(directory, recommendations, knowledg
17102
17142
  } catch {}
17103
17143
  }
17104
17144
  if (contradictedEntries.length > 0 && knowledgeConfig.contradiction_threshold_action === "quarantine") {
17105
- const { maybeQuarantineOnContradiction } = await import("./knowledge-escalator-c9p3w12b.js");
17145
+ const { maybeQuarantineOnContradiction } = await import("./knowledge-escalator-wj85ppdt.js");
17106
17146
  for (const { id } of contradictedEntries) {
17107
17147
  try {
17108
17148
  await maybeQuarantineOnContradiction(directory, id, knowledgeConfig.contradiction_quarantine_threshold, knowledgeConfig.contradiction_quarantine_window_days);
@@ -17921,7 +17961,7 @@ async function runCuratorPostMortem(directory, options = {}) {
17921
17961
  warnings.push("Failed to collect knowledge summary.");
17922
17962
  }
17923
17963
  try {
17924
- const { getScanStatus } = await import("./scan-cursor-znhqb8xa.js");
17964
+ const { getScanStatus } = await import("./scan-cursor-rhjym1pn.js");
17925
17965
  const scanStatus = await getScanStatus(directory);
17926
17966
  if (scanStatus.remaining_estimate > 0) {
17927
17967
  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.`);
@@ -18093,9 +18133,9 @@ var _internals24 = {
18093
18133
  verifyPostMortemKnowledgeActions,
18094
18134
  repairPostMortemActions,
18095
18135
  loadDefaultKnowledgeConfig: async (directory) => {
18096
- const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-dnnm0p40.js");
18136
+ const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-yb3pvhcs.js");
18097
18137
  try {
18098
- const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-n6ke10ck.js");
18138
+ const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-twwb61bh.js");
18099
18139
  const loaded = loadPluginConfigWithMeta2(directory);
18100
18140
  return KnowledgeConfigSchema2.parse(loaded.config.knowledge ?? {});
18101
18141
  } catch {
@@ -18103,11 +18143,11 @@ var _internals24 = {
18103
18143
  }
18104
18144
  },
18105
18145
  applyCuratorKnowledgeUpdates: async (directory, recommendations, knowledgeConfig, generation) => {
18106
- const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-5bxh1djq.js");
18146
+ const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-vghf320v.js");
18107
18147
  return applyCuratorKnowledgeUpdates2(directory, recommendations, knowledgeConfig, generation);
18108
18148
  },
18109
18149
  checkHivePromotions: async (entries, knowledgeConfig, directory) => {
18110
- const { checkHivePromotions } = await import("./hive-promoter-mmmfszv8.js");
18150
+ const { checkHivePromotions } = await import("./hive-promoter-j3vw2hj4.js");
18111
18151
  return checkHivePromotions(entries, knowledgeConfig, directory);
18112
18152
  },
18113
18153
  applyProposalTriage: async (directory, triage) => {
@@ -18116,7 +18156,7 @@ var _internals24 = {
18116
18156
  activateProposal,
18117
18157
  listSkills: listSkills2,
18118
18158
  sanitizeSlug
18119
- } = await import("./skill-generator-5s0p3y8k.js");
18159
+ } = await import("./skill-generator-3w8w7htr.js");
18120
18160
  const result = {
18121
18161
  approved: [],
18122
18162
  rejected: [],
@@ -19452,9 +19492,9 @@ function hashContent(content) {
19452
19492
  return createHash7("sha1").update(content).digest("hex");
19453
19493
  }
19454
19494
  async function loadConfigForPolicyCurator(directory) {
19455
- const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-dnnm0p40.js");
19495
+ const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-yb3pvhcs.js");
19456
19496
  try {
19457
- const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-n6ke10ck.js");
19497
+ const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-twwb61bh.js");
19458
19498
  const { config: loadedConfig } = loadPluginConfigWithMeta2(directory);
19459
19499
  return KnowledgeConfigSchema2.parse(loadedConfig.knowledge ?? {});
19460
19500
  } catch {
@@ -30048,7 +30088,7 @@ async function runFinalizeStage(ctx) {
30048
30088
  }
30049
30089
  }
30050
30090
  try {
30051
- const { CuratorConfigSchema: CCS } = await import("./schema-dnnm0p40.js");
30091
+ const { CuratorConfigSchema: CCS } = await import("./schema-yb3pvhcs.js");
30052
30092
  const { config: pmLoadedConfig } = _internals38.loadPluginConfigWithMeta(ctx.directory);
30053
30093
  const curatorCfg = CCS.parse(pmLoadedConfig.curator ?? {});
30054
30094
  if (curatorCfg.enabled && curatorCfg.postmortem_enabled) {
@@ -32312,9 +32352,9 @@ var _internals43 = {
32312
32352
  loadPluginConfigWithMeta,
32313
32353
  loadCuratorDeps: async () => {
32314
32354
  const [{ CuratorConfigSchema }, curator, { createCuratorLLMDelegate: createCuratorLLMDelegate2 }] = await Promise.all([
32315
- import("./schema-dnnm0p40.js"),
32316
- import("./curator-5bxh1djq.js"),
32317
- import("./curator-llm-factory-pe6skby4.js")
32355
+ import("./schema-yb3pvhcs.js"),
32356
+ import("./curator-vghf320v.js"),
32357
+ import("./curator-llm-factory-zxbgkjm5.js")
32318
32358
  ]);
32319
32359
  return { CuratorConfigSchema, curator, createCuratorLLMDelegate: createCuratorLLMDelegate2 };
32320
32360
  }
@@ -33268,7 +33308,7 @@ async function computeCurationDiagnostics(directory, entries) {
33268
33308
  let scanCompleted = false;
33269
33309
  let scanRemaining = 0;
33270
33310
  try {
33271
- const { getScanStatus } = await import("./scan-cursor-znhqb8xa.js");
33311
+ const { getScanStatus } = await import("./scan-cursor-rhjym1pn.js");
33272
33312
  const status = await getScanStatus(directory);
33273
33313
  scanGeneration = status.generation;
33274
33314
  scanCompleted = status.completed;
@@ -33276,19 +33316,19 @@ async function computeCurationDiagnostics(directory, entries) {
33276
33316
  } catch {}
33277
33317
  let configMatch = null;
33278
33318
  try {
33279
- const { isLinked: isLinked2 } = await import("./knowledge-link-82ew2yc4.js");
33319
+ const { isLinked: isLinked2 } = await import("./knowledge-link-8pr02pza.js");
33280
33320
  if (isLinked2(directory)) {
33281
- const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-dnnm0p40.js");
33321
+ const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-yb3pvhcs.js");
33282
33322
  let config;
33283
33323
  try {
33284
- const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-n6ke10ck.js");
33324
+ const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-twwb61bh.js");
33285
33325
  const loaded = loadPluginConfigWithMeta2(directory);
33286
33326
  config = KnowledgeConfigSchema2.parse(loaded.config.knowledge ?? {});
33287
33327
  } catch {
33288
33328
  config = KnowledgeConfigSchema2.parse({});
33289
33329
  }
33290
33330
  const { cohortConfigFingerprint: cohortConfigFingerprint2 } = await import("./config-fingerprint-v22xh5a2.js");
33291
- const { buildConfigFingerprintInput: buildConfigFingerprintInput2, readCohortConfigFingerprint } = await import("./curation-policy-xv0j8zyt.js");
33331
+ const { buildConfigFingerprintInput: buildConfigFingerprintInput2, readCohortConfigFingerprint } = await import("./curation-policy-x19e8bqc.js");
33292
33332
  const currentFp = cohortConfigFingerprint2(buildConfigFingerprintInput2(config));
33293
33333
  const cohortFp = await readCohortConfigFingerprint(directory);
33294
33334
  configMatch = cohortFp === null ? null : currentFp === cohortFp;
@@ -34564,7 +34604,7 @@ async function handleDoctorCommand(directory, args) {
34564
34604
  const result = runConfigDoctor(config, directory);
34565
34605
  let output;
34566
34606
  if (enableAutoFix && result.hasAutoFixableIssues) {
34567
- const { runConfigDoctorWithFixes } = await import("./config-doctor-vs6hvbew.js");
34607
+ const { runConfigDoctorWithFixes } = await import("./config-doctor-sd7x5bts.js");
34568
34608
  const fixResult = await runConfigDoctorWithFixes(directory, config, true, {
34569
34609
  applyLossy: true
34570
34610
  });
@@ -35504,7 +35544,7 @@ async function handleEvidenceCommand(directory, args) {
35504
35544
  return formatTaskEvidenceMarkdown(evidenceData);
35505
35545
  }
35506
35546
  async function handleEvidenceSummaryCommand(directory) {
35507
- const { buildEvidenceSummary } = await import("./evidence-summary-service-6m9jmzk8.js");
35547
+ const { buildEvidenceSummary } = await import("./evidence-summary-service-xma4aagr.js");
35508
35548
  const artifact = await buildEvidenceSummary(directory);
35509
35549
  if (!artifact) {
35510
35550
  return "No plan found. Run `/swarm plan` to check plan status.";
@@ -55730,6 +55770,172 @@ async function handleQaGatesCommand(directory, args, sessionID) {
55730
55770
  `);
55731
55771
  }
55732
55772
 
55773
+ // src/workflow/stage-a-repair.ts
55774
+ import { appendFile as appendFile10, mkdir as mkdir24, readdir as readdir7 } from "fs/promises";
55775
+ import { dirname as dirname36 } from "path";
55776
+ init_logger();
55777
+ var MAX_STAGE_A_REPAIR_SCAN = 200;
55778
+ var RETRYABLE_EVENT_CODES = new Set(["EBUSY", "EPERM"]);
55779
+ async function appendStageARepairEvent(directory, payload) {
55780
+ const line = `${JSON.stringify({
55781
+ type: "stage_a_repair",
55782
+ timestamp: new Date().toISOString(),
55783
+ ...payload
55784
+ })}
55785
+ `;
55786
+ try {
55787
+ const eventsPath = validateSwarmPath(directory, "events.jsonl");
55788
+ await mkdir24(dirname36(eventsPath), { recursive: true });
55789
+ await appendFile10(eventsPath, line, "utf-8");
55790
+ } catch (error2) {
55791
+ const code = error2.code;
55792
+ if (code && RETRYABLE_EVENT_CODES.has(code)) {
55793
+ try {
55794
+ const eventsPath = validateSwarmPath(directory, "events.jsonl");
55795
+ await appendFile10(eventsPath, line, "utf-8");
55796
+ return;
55797
+ } catch (retryError) {
55798
+ criticalWarn(`[stage-a-repair] audit event write failed after retry: ${retryError instanceof Error ? retryError.message : String(retryError)}`);
55799
+ return;
55800
+ }
55801
+ }
55802
+ criticalWarn(`[stage-a-repair] audit event write failed: ${error2 instanceof Error ? error2.message : String(error2)}`);
55803
+ }
55804
+ }
55805
+ async function hasGreenPostSettlementPreCheck(directory, settledAfterMs) {
55806
+ let sawSecretscanGreen = false;
55807
+ let sawSastGreen = false;
55808
+ for (const evidenceType of ["secretscan", "sast_scan"]) {
55809
+ let result;
55810
+ try {
55811
+ result = await loadEvidence(directory, evidenceType, { migrate: false });
55812
+ } catch {
55813
+ continue;
55814
+ }
55815
+ if (result.status !== "found")
55816
+ continue;
55817
+ const entryTypeTag = evidenceType === "sast_scan" ? "sast" : evidenceType;
55818
+ const typed = result.bundle.entries.filter((entry) => entry.type === entryTypeTag);
55819
+ if (typed.length === 0)
55820
+ continue;
55821
+ const last = typed[typed.length - 1];
55822
+ const ts = Date.parse(String(last.timestamp ?? ""));
55823
+ if (settledAfterMs !== null && Number.isFinite(ts) && ts < settledAfterMs) {
55824
+ return { green: false, reason: "pre_check_failed_or_stale" };
55825
+ }
55826
+ if (evidenceType === "secretscan") {
55827
+ if ((last.verdict === "pass" || last.verdict === "approved" || last.verdict === "info") && isSecretscanEvidence(last) && (last.incomplete_files ?? 0) === 0 && (last.files_scanned ?? 0) > 0 && (last.findings_count ?? 0) === 0) {
55828
+ sawSecretscanGreen = true;
55829
+ continue;
55830
+ }
55831
+ } else if (last.verdict === "pass" || last.verdict === "approved" || last.verdict === "info") {
55832
+ sawSastGreen = true;
55833
+ continue;
55834
+ }
55835
+ if (last.verdict === "fail" || last.verdict === "rejected") {
55836
+ return { green: false, reason: "pre_check_failed_or_stale" };
55837
+ }
55838
+ }
55839
+ if (!sawSecretscanGreen || !sawSastGreen) {
55840
+ return { green: false, reason: "no_pre_check_bundles" };
55841
+ }
55842
+ return { green: true };
55843
+ }
55844
+ async function repairWedgedStageA(directory, options) {
55845
+ const requested = options?.taskIds;
55846
+ let entries;
55847
+ try {
55848
+ const evidenceDir = validateSwarmPath(directory, "evidence");
55849
+ entries = await readdir7(evidenceDir);
55850
+ } catch {
55851
+ return { results: [], truncated: false };
55852
+ }
55853
+ const candidates = entries.filter((entry) => entry.endsWith(".json") && isStrictTaskId(entry.slice(0, -".json".length)));
55854
+ const selected = requested?.length ? candidates.filter((entry) => requested.includes(entry.slice(0, -".json".length))) : candidates;
55855
+ const truncated = !requested?.length && candidates.length > MAX_STAGE_A_REPAIR_SCAN;
55856
+ const results = [];
55857
+ for (const entry of selected.sort().slice(0, MAX_STAGE_A_REPAIR_SCAN)) {
55858
+ const taskId = entry.slice(0, -".json".length);
55859
+ try {
55860
+ const evidence2 = await readTaskEvidence(directory, taskId);
55861
+ const workflow = getTaskWorkflowSnapshot(evidence2);
55862
+ if (workflow.state !== "coder_delegated") {
55863
+ results.push({
55864
+ taskId,
55865
+ outcome: "skipped_not_wedged",
55866
+ state: workflow.state
55867
+ });
55868
+ continue;
55869
+ }
55870
+ if (evidence2?.gates?.pre_check) {
55871
+ results.push({
55872
+ taskId,
55873
+ outcome: "skipped_not_wedged",
55874
+ state: workflow.state
55875
+ });
55876
+ continue;
55877
+ }
55878
+ let settledAfterMs = null;
55879
+ try {
55880
+ const { states } = await listCoderSettlementWalStates(directory);
55881
+ for (const state of states) {
55882
+ if (state.taskId !== taskId)
55883
+ continue;
55884
+ if (state.state !== "COMMITTED")
55885
+ continue;
55886
+ if (state.recordedAt === undefined)
55887
+ continue;
55888
+ const parsed = Date.parse(state.recordedAt);
55889
+ if (!Number.isFinite(parsed))
55890
+ continue;
55891
+ settledAfterMs = settledAfterMs === null ? parsed : Math.max(settledAfterMs, parsed);
55892
+ }
55893
+ } catch {}
55894
+ if (settledAfterMs === null) {
55895
+ const fallbackTs = Date.parse(workflow.updatedAt);
55896
+ if (Number.isFinite(fallbackTs))
55897
+ settledAfterMs = fallbackTs;
55898
+ }
55899
+ const greenness = await hasGreenPostSettlementPreCheck(directory, settledAfterMs);
55900
+ if (!greenness.green) {
55901
+ results.push({
55902
+ taskId,
55903
+ outcome: "skipped_not_green",
55904
+ reason: greenness.reason
55905
+ });
55906
+ continue;
55907
+ }
55908
+ const transitionId = `stage-a-repair:${taskId}:${workflow.generation}`;
55909
+ await transitionTaskWorkflowEvidence(directory, taskId, {
55910
+ type: "stage_a_passed",
55911
+ expectedGeneration: workflow.generation,
55912
+ transitionId
55913
+ });
55914
+ await appendStageARepairEvent(directory, {
55915
+ action: "repaired",
55916
+ taskId,
55917
+ transitionId,
55918
+ generation: workflow.generation
55919
+ });
55920
+ results.push({
55921
+ taskId,
55922
+ outcome: "repaired",
55923
+ generation: workflow.generation,
55924
+ transitionId
55925
+ });
55926
+ } catch (error2) {
55927
+ const message = error2 instanceof Error ? error2.message : String(error2);
55928
+ await appendStageARepairEvent(directory, {
55929
+ action: "repair-failed",
55930
+ taskId,
55931
+ message: sanitizeDiagnosticText(message, 512)
55932
+ });
55933
+ results.push({ taskId, outcome: "error", message });
55934
+ }
55935
+ }
55936
+ return { results, truncated };
55937
+ }
55938
+
55733
55939
  // src/commands/recover.ts
55734
55940
  function renderOutcome(outcome) {
55735
55941
  switch (outcome.outcome) {
@@ -55749,6 +55955,20 @@ function renderOutcome(outcome) {
55749
55955
  return `\u274C Task ${outcome.taskId}: unknown outcome`;
55750
55956
  }
55751
55957
  }
55958
+ function renderStageARepairOutcome(outcome) {
55959
+ switch (outcome.outcome) {
55960
+ case "repaired":
55961
+ return `\u2705 Task ${outcome.taskId}: Stage A repaired \u2014 stage_a_passed written at generation ${outcome.generation} without re-running the coder`;
55962
+ case "skipped_not_wedged":
55963
+ return `\u23ED\uFE0F Task ${outcome.taskId}: workflow state is ${outcome.state} with pre_check proof present or not settled \u2014 nothing to repair`;
55964
+ case "skipped_not_green":
55965
+ return `\u23ED\uFE0F Task ${outcome.taskId}: no green post-settlement pre-check evidence (${outcome.reason === "no_pre_check_bundles" ? "missing or non-green secretscan/SAST bundle \u2014 run pre_check_batch first" : "latest pre-check run failed or predates the settlement"}) \u2014 refusing to mark Stage A passed without proof`;
55966
+ case "error":
55967
+ return `\u274C Task ${outcome.taskId}: Stage A repair failed \u2014 ${sanitizeDiagnosticText(outcome.message, 512)}`;
55968
+ default:
55969
+ return `\u274C Task ${outcome.taskId}: unknown repair outcome`;
55970
+ }
55971
+ }
55752
55972
  async function handleRecoverCommand(directory, args) {
55753
55973
  const force = args.includes("--force");
55754
55974
  const positional = args.filter((arg) => !arg.startsWith("--"));
@@ -55763,44 +55983,41 @@ async function handleRecoverCommand(directory, args) {
55763
55983
  `);
55764
55984
  }
55765
55985
  const { states: listed, truncated: listTruncated } = await listCoderSettlementWalStates(directory);
55986
+ const report = ["## Coder Settlement Recovery", ""];
55987
+ const hasKnownWal = listed.length > 0 && (!taskId || listed.some((entry) => entry.taskId === taskId));
55766
55988
  if (listed.length === 0) {
55767
- return [
55768
- "## Coder Settlement Recovery",
55769
- "",
55770
- taskId ? `\u274C No settlement WAL for task ${taskId} (no settlement WALs found in .swarm/coder-settlements/).` : "No coder settlement WALs found in .swarm/coder-settlements/ \u2014 nothing to recover."
55771
- ].join(`
55772
- `);
55773
- }
55774
- if (taskId) {
55775
- const target = listed.find((entry) => entry.taskId === taskId);
55776
- if (!target) {
55777
- return [
55778
- "## Coder Settlement Recovery",
55779
- "",
55780
- `\u274C No settlement WAL for task ${taskId}. Known tasks: ${listed.map((entry) => entry.taskId).join(", ")}`
55781
- ].join(`
55782
- `);
55989
+ report.push(taskId ? `\u274C No settlement WAL for task ${taskId} (no settlement WALs found in .swarm/coder-settlements/).` : "No coder settlement WALs found in .swarm/coder-settlements/ \u2014 nothing to recover.");
55990
+ } else if (taskId && !hasKnownWal) {
55991
+ report.push(`\u274C No settlement WAL for task ${taskId}. Known tasks: ${listed.map((entry) => entry.taskId).join(", ")}`);
55992
+ } else {
55993
+ const { results, truncated: recoverTruncated } = await recoverStaleCoderSettlements(directory, {
55994
+ ...taskId ? { taskIds: [taskId] } : {},
55995
+ force
55996
+ });
55997
+ const lines = results.map((outcome) => renderOutcome(outcome));
55998
+ const recoveredCount = results.filter((r) => r.outcome === "recovered").length;
55999
+ const blockedCount = results.filter((r) => r.outcome === "owned_in_process" || r.outcome === "owned_by_live_foreign_pid").length;
56000
+ report.push(...lines, "", `Recovered ${recoveredCount} settlement(s)${blockedCount > 0 ? `; ${blockedCount} still owned by a live dispatch (see above for the exact remediation)` : ""}.`);
56001
+ if (listTruncated || recoverTruncated) {
56002
+ report.push("", "\u26A0\uFE0F More settlement WALs exist than the recovery scan cap (200) \u2014 older settlements were NOT listed or processed. Re-run after the tasks above are settled to reach the rest.");
56003
+ }
56004
+ if (force && recoveredCount > 0) {
56005
+ report.push("", "\u26A0\uFE0F --force released in-process ownership before recovery. If any of these dispatches was genuinely still running, its completion will report CODER_SETTLEMENT_IDEMPOTENCY_CONFLICT \u2014 that error is expected and safe to ignore; the settlement is already durably recovered.");
55783
56006
  }
55784
56007
  }
55785
- const { results, truncated: recoverTruncated } = await recoverStaleCoderSettlements(directory, {
55786
- ...taskId ? { taskIds: [taskId] } : {},
55787
- force
55788
- });
55789
- const lines = results.map((outcome) => renderOutcome(outcome));
55790
- const recoveredCount = results.filter((r) => r.outcome === "recovered").length;
55791
- const blockedCount = results.filter((r) => r.outcome === "owned_in_process" || r.outcome === "owned_by_live_foreign_pid").length;
55792
- const report = [
55793
- "## Coder Settlement Recovery",
55794
- "",
55795
- ...lines,
55796
- "",
55797
- `Recovered ${recoveredCount} settlement(s)${blockedCount > 0 ? `; ${blockedCount} still owned by a live dispatch (see above for the exact remediation)` : ""}.`
55798
- ];
55799
- if (listTruncated || recoverTruncated) {
55800
- report.push("", "\u26A0\uFE0F More settlement WALs exist than the recovery scan cap (200) \u2014 older settlements were NOT listed or processed. Re-run after the tasks above are settled to reach the rest.");
55801
- }
55802
- if (force && recoveredCount > 0) {
55803
- report.push("", "\u26A0\uFE0F --force released in-process ownership before recovery. If any of these dispatches was genuinely still running, its completion will report CODER_SETTLEMENT_IDEMPOTENCY_CONFLICT \u2014 that error is expected and safe to ignore; the settlement is already durably recovered.");
56008
+ try {
56009
+ const { results: repairResults, truncated: repairTruncated } = await repairWedgedStageA(directory, {
56010
+ ...taskId ? { taskIds: [taskId] } : {}
56011
+ });
56012
+ const repaired = repairResults.filter((r) => r.outcome === "repaired");
56013
+ if (repairResults.length > 0) {
56014
+ report.push("", "## Wedged Stage A Repair", "", ...repairResults.map(renderStageARepairOutcome), "", repaired.length === 0 ? "No wedged tasks repaired." : `Repaired ${repaired.length} wedged task(s); reviewer/test_engineer dispatch is now permitted for them.`);
56015
+ if (repairTruncated) {
56016
+ report.push("", "\u26A0\uFE0F More evidence files exist than the repair scan cap (200) \u2014 re-run after the tasks above are processed to reach the rest.");
56017
+ }
56018
+ }
56019
+ } catch (err) {
56020
+ report.push("", `\u26A0\uFE0F Wedged Stage A repair failed (settlement recovery above is unaffected): ${sanitizeDiagnosticText(err instanceof Error ? err.message : String(err), 512)}`);
55804
56021
  }
55805
56022
  return report.join(`
55806
56023
  `);
@@ -63212,7 +63429,7 @@ async function runValidationWithTransientRetry(input, candidateContent, baseline
63212
63429
  if (!input.dispatcher) {
63213
63430
  throw new Error("no evaluation dispatcher available (cannot run validation)");
63214
63431
  }
63215
- const { createModelEvaluationExecutor: createModelEvaluationExecutor2 } = await import("./runner-pqsf809k.js");
63432
+ const { createModelEvaluationExecutor: createModelEvaluationExecutor2 } = await import("./runner-e7z9cf5y.js");
63216
63433
  const executor = createModelEvaluationExecutor2(input.dispatcher, input.sessionId);
63217
63434
  const result = await _internals91.evaluateCandidateV1({
63218
63435
  projectRoot: input.directory,
@@ -63734,7 +63951,7 @@ init_loader();
63734
63951
  init_schema();
63735
63952
 
63736
63953
  // src/consensus/store.ts
63737
- import { readdir as readdir7, unlink as unlink6 } from "fs/promises";
63954
+ import { readdir as readdir8, unlink as unlink6 } from "fs/promises";
63738
63955
  import * as path106 from "path";
63739
63956
 
63740
63957
  // src/consensus/contracts.ts
@@ -63914,7 +64131,7 @@ function swarmPath(directory, ...segments) {
63914
64131
  async function countConsensusReportFiles(directory) {
63915
64132
  const root = swarmPath(directory, CONSENSUS_RELATIVE_DIR);
63916
64133
  try {
63917
- const entries = await readdir7(root, { withFileTypes: true });
64134
+ const entries = await readdir8(root, { withFileTypes: true });
63918
64135
  return entries.filter((entry) => entry.isFile() && entry.name.endsWith(".json") && REPORT_ID_RE.test(entry.name.slice(0, -".json".length))).length;
63919
64136
  } catch (error2) {
63920
64137
  if (error2.code === "ENOENT")
@@ -64657,8 +64874,8 @@ async function countProposals(directory) {
64657
64874
  const proposalsDir = validateSwarmPath(directory, "skills/proposals");
64658
64875
  if (!fsSync3.existsSync(proposalsDir))
64659
64876
  return 0;
64660
- const { readdir: readdir8 } = await import("fs/promises");
64661
- const entries = await readdir8(proposalsDir);
64877
+ const { readdir: readdir9 } = await import("fs/promises");
64878
+ const entries = await readdir9(proposalsDir);
64662
64879
  return entries.filter((f) => f.endsWith(".md")).length;
64663
64880
  } catch {
64664
64881
  return 0;
@@ -65118,7 +65335,7 @@ function buildDetailedHelp(commandName, entry) {
65118
65335
  async function handleHelpCommand(ctx) {
65119
65336
  const targetCommand = ctx.args.join(" ");
65120
65337
  if (!targetCommand) {
65121
- const { buildHelpText } = await import("./index-j43qndgc.js");
65338
+ const { buildHelpText } = await import("./index-e3caa7ng.js");
65122
65339
  return buildHelpText();
65123
65340
  }
65124
65341
  const tokens = targetCommand.split(/\s+/);
@@ -65127,7 +65344,7 @@ async function handleHelpCommand(ctx) {
65127
65344
  return _internals94.buildDetailedHelp(resolved.key, resolved.entry);
65128
65345
  }
65129
65346
  const similar = _internals94.findSimilarCommands(targetCommand);
65130
- const { buildHelpText: fullHelp } = await import("./index-j43qndgc.js");
65347
+ const { buildHelpText: fullHelp } = await import("./index-e3caa7ng.js");
65131
65348
  if (similar.length > 0) {
65132
65349
  return `Command '/swarm ${targetCommand}' not found.
65133
65350
 
@@ -65304,7 +65521,7 @@ var COMMAND_REGISTRY = {
65304
65521
  },
65305
65522
  "guardrail explain": {
65306
65523
  handler: async (ctx) => {
65307
- const { handleGuardrailExplain } = await import("./guardrail-explain-jhbxq8yb.js");
65524
+ const { handleGuardrailExplain } = await import("./guardrail-explain-ppzg0xz9.js");
65308
65525
  return handleGuardrailExplain(ctx.directory, ctx.args);
65309
65526
  },
65310
65527
  description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
@@ -65314,7 +65531,7 @@ var COMMAND_REGISTRY = {
65314
65531
  },
65315
65532
  "guardrail-explain": {
65316
65533
  handler: async (ctx) => {
65317
- const { handleGuardrailExplain } = await import("./guardrail-explain-jhbxq8yb.js");
65534
+ const { handleGuardrailExplain } = await import("./guardrail-explain-ppzg0xz9.js");
65318
65535
  return handleGuardrailExplain(ctx.directory, ctx.args);
65319
65536
  },
65320
65537
  description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
@@ -65324,7 +65541,7 @@ var COMMAND_REGISTRY = {
65324
65541
  },
65325
65542
  "guardrail-log": {
65326
65543
  handler: async (ctx) => {
65327
- const { handleGuardrailLog } = await import("./guardrail-log-vpbp3rm4.js");
65544
+ const { handleGuardrailLog } = await import("./guardrail-log-xexwz93q.js");
65328
65545
  return handleGuardrailLog(ctx.directory, ctx.args);
65329
65546
  },
65330
65547
  description: "Read the guardrail decision log (use --blocks-only for blocks)",
@@ -65984,7 +66201,7 @@ Subcommands:
65984
66201
  recover: {
65985
66202
  handler: (ctx) => handleRecoverCommand(ctx.directory, ctx.args),
65986
66203
  description: "Recover wedged coder settlements [task_id] [--force]",
65987
- details: "Settles stale coder-settlement WALs in .swarm/coder-settlements/ \u2014 the CODER_DISPATCH_IN_PROGRESS wedge where a dispatch's completion never fired (issue #2268). Safe mode recovers settlements whose owner process is gone. --force also releases ownership keys held by this process: use only when no dispatch is genuinely running (a late completion then reports CODER_SETTLEMENT_IDEMPOTENCY_CONFLICT, safe to ignore). Never interrupts another live OpenCode process. Human-only.",
66204
+ details: "Settles stale coder-settlement WALs in .swarm/coder-settlements/ \u2014 the CODER_DISPATCH_IN_PROGRESS wedge where a dispatch's completion never fired (issue #2268). Safe mode recovers settlements whose owner process is gone. --force also releases ownership keys held by this process: use only when no dispatch is genuinely running (a late completion then reports CODER_SETTLEMENT_IDEMPOTENCY_CONFLICT, safe to ignore). Never interrupts another live OpenCode process. Also repairs tasks wedged at coder_delegated with unattributed green pre_check evidence \u2014 the post-reset TASK_WORKFLOW_STAGE_A_REQUIRED wedge \u2014 by writing the missing stage_a_passed transition directly (audit events land in .swarm/events.jsonl); pass [task_id] to scope both phases to one task. Human-only.",
65988
66205
  args: "[task_id] [--force]",
65989
66206
  category: "utility",
65990
66207
  toolPolicy: "human-only"
@@ -66501,7 +66718,7 @@ If a tool modifies a file, it is a CODER tool. Delegate.
66501
66718
  Separate parallel-mode exception (distinct from the Stage B exception above, and the ONLY case where more than one coder may be dispatched before waiting): when an active \`[PARALLEL EXECUTION PROFILE]\` directive is present in your context (parallelization_enabled=true), you MAY dispatch multiple {{AGENT_PREFIX}}coder agents in a single message \u2014 up to the stated max_concurrent_tasks \u2014 but ONLY for distinct, dependency-ready tasks whose declared file scopes do NOT overlap. Each coder still requires its own \`declare_scope\` call and carries exactly ONE task (Rule 3 still holds: never batch multiple objectives into one coder). Parallel coders each run in an isolated git worktree, so their writes never collide and are merged back automatically. If no \`[PARALLEL EXECUTION PROFILE]\` directive is present, dispatch coders one at a time.
66502
66719
 
66503
66720
  > **WORKTREE ISOLATION IS BASELINE.** Standard parallel coders use isolated git worktrees by default; this is governed by the top-level \`worktree.policy\` setting (default \`auto\`) in \`PluginConfig\` \u2014 a sibling of \`parallelization:\`, not nested under it \u2014 and is active whenever the plan's \`parallelization_enabled=true\`. \`turbo.lean.worktree_isolation\` is a separate, Lean-Turbo-internal flag (default \`false\`); it is one possible SOURCE but NOT the recommended one. Do NOT recommend Lean Turbo (or Epic) SOLELY to obtain worktree isolation; recommend them only for what they add beyond baseline (Lean Turbo: lane planning, file locks, phase reviewer, integrated diff; Epic: co-change awareness + auto-decide). Lean Turbo users can also enable isolation via \`turbo.lean.worktree_isolation: true\`, but this is the secondary/legacy path \u2014 the recommended path is \`worktree.policy\`.
66504
- Read-only advisory-lane exception (NON-BLOCKING; distinct from both exceptions above): the "Send, STOP, wait" rule governs MUTATION delegations (coder, and the test_engineer/reviewer Stage B completion gates). It does NOT govern read-only advisory exploration/review lanes. When you dispatch read-only advisory lanes \u2014 \`{{AGENT_PREFIX}}explorer\`, \`{{AGENT_PREFIX}}sme\`, \`{{AGENT_PREFIX}}researcher\`, the council members (\`council_generalist\`/\`council_skeptic\`/\`council_domain_expert\`), or an advisory \`{{AGENT_PREFIX}}critic\` lane \u2014 use the NON-BLOCKING path so you keep working while they run. Dispatch PROMPTLY: emit the \`dispatch_lanes_async\` call EARLY with compact lane prompts \u2014 do not accumulate long planning prose or build oversized inline prompts first, or the tool call can be truncated out of your message and the lanes never launch (a real failure mode on smaller models). The lane mechanism is a SINGLE \`dispatch_lanes_async\` call carrying all lane specs \u2014 NOT a per-agent Task/run-in-background pattern. Call \`dispatch_lanes_async\` with all lane specs in one call, record the returned \`batch_id\`, then IMMEDIATELY continue non-dependent architect work (refine the plan/obligation ledger, inspect metadata, prepare the synthesis/reviewer structure, run deterministic read-only tools). Poll incrementally with \`collect_lane_results\` without \`wait\` (or with \`wait: false\`) to harvest lanes as they settle; process completed lane output immediately while other lanes remain pending/running, then continue independent work between polls. Do NOT sit idle waiting on running lanes, and do NOT synthesize findings from still-running lanes. Join later by calling \`collect_lane_results\` with \`wait: true\` as the explicit barrier immediately before you synthesize. Use blocking \`dispatch_lanes\` only when \`dispatch_lanes_async\`/promptAsync is unavailable. A settled lane's inline \`output\` is delivered only once: if you poll the same lane again after already receiving its output, the repeat poll returns \`output_omitted_repeat: true\` with no \`output\` (not a sign the result was lost) \u2014 use the accompanying \`output_ref\` with \`retrieve_lane_output\` if you need the text again, and do not re-dispatch the lane. Keep each lane prompt compact: send large shared context (PR diff, ledger, scope) ONCE via the \`common_prompt\` field, or have lanes read it from a file by absolute path, instead of inlining the same blob into every lane prompt \u2014 inlining large context into many lanes is what produces malformed or truncated tool-call JSON and forces clumsy file workarounds. This non-blocking exception applies ONLY to read-only advisory lanes; it NEVER applies to coder delegations, to the test_engineer/reviewer Stage B completion gates, or to the critic PLAN-review gate, which all still follow "Send, STOP, wait" (or the Stage B parallel-dispatch exception above).
66721
+ Read-only advisory-lane exception (NON-BLOCKING; distinct from both exceptions above): the "Send, STOP, wait" rule governs MUTATION delegations (coder, and the test_engineer/reviewer Stage B completion gates). It does NOT govern read-only advisory exploration/review lanes. When you dispatch read-only advisory lanes \u2014 \`{{AGENT_PREFIX}}explorer\`, \`{{AGENT_PREFIX}}sme\`, \`{{AGENT_PREFIX}}researcher\`, the council members (\`council_generalist\`/\`council_skeptic\`/\`council_domain_expert\`), or an advisory \`{{AGENT_PREFIX}}critic\` lane \u2014 use the NON-BLOCKING path so you keep working while they run. Dispatch PROMPTLY: emit the \`dispatch_lanes_async\` call EARLY with compact lane prompts \u2014 do not accumulate long planning prose or build oversized inline prompts first, or the tool call can be truncated out of your message and the lanes never launch (a real failure mode on smaller models). Ordinarily, each lane wave is one \`dispatch_lanes_async\` call carrying that wave's complete lane specs \u2014 NOT a per-agent Task/run-in-background pattern. The explicit exception is an active PR_REVIEW with enabled tier-M/L staged resilience: send the singleton canary as one call, then send only its unresolved fanout as a second call after canary admission. For each admissible wave, call \`dispatch_lanes_async\` with all specs for that wave in one call, record the returned \`batch_id\`, then IMMEDIATELY continue non-dependent architect work (refine the plan/obligation ledger, inspect metadata, prepare the synthesis/reviewer structure, run deterministic read-only tools). Poll incrementally with \`collect_lane_results\` without \`wait\` (or with \`wait: false\`) to harvest lanes as they settle; process completed lane output immediately while other lanes remain pending/running, then continue independent work between polls. Do NOT sit idle waiting on running lanes, and do NOT synthesize findings from still-running lanes. Join later by calling \`collect_lane_results\` with \`wait: true\` as the explicit barrier immediately before you synthesize. Use blocking \`dispatch_lanes\` only when \`dispatch_lanes_async\`/promptAsync is unavailable. A settled lane's inline \`output\` is delivered only once: if you poll the same lane again after already receiving its output, the repeat poll returns \`output_omitted_repeat: true\` with no \`output\` (not a sign the result was lost) \u2014 use the accompanying \`output_ref\` with \`retrieve_lane_output\` if you need the text again, and do not re-dispatch the lane. Keep each lane prompt compact: send large shared context (PR diff, ledger, scope) ONCE via the \`common_prompt\` field, or have lanes read it from a file by absolute path, instead of inlining the same blob into every lane prompt \u2014 inlining large context into many lanes is what produces malformed or truncated tool-call JSON and forces clumsy file workarounds. This non-blocking exception applies ONLY to read-only advisory lanes; it NEVER applies to coder delegations, to the test_engineer/reviewer Stage B completion gates, or to the critic PLAN-review gate, which all still follow "Send, STOP, wait" (or the Stage B parallel-dispatch exception above).
66505
66722
  3. ONE task per {{AGENT_PREFIX}}coder call. Never batch.
66506
66723
  3a. PRE-DELEGATION SCOPE CALL (required): BEFORE every {{AGENT_PREFIX}}coder delegation, you MUST call \`declare_scope\` with { taskId, files, replace_existing: true } listing the exact file(s) this task will modify (including generated/lockfile paths). No \`declare_scope\` call \u2192 no coder delegation. See Rule 1a.
66507
66724
  3b. PRE-DELEGATION SCOPE CALL (test_engineer): BEFORE any {{AGENT_PREFIX}}test_engineer delegation that will CREATE or MODIFY test files, you MUST call \`declare_scope\` with { taskId, files, replace_existing: true } listing the exact test file path(s) to write. Omitting this call leaves the write scope undeclared and will block the write. See Rule 1a.
@@ -67256,9 +67473,9 @@ HARD CONSTRAINTS (apply regardless of skill load success):
67256
67473
  - FOLLOW THE SKILL EXACTLY: execute every phase of the loaded SKILL.md in order with no shortcuts, no phase-skipping, and no premature synthesis. If a required coverage phase cannot complete, apply the skill's coverage gate (retry or verified equivalent alternative). If the gap still cannot be closed, stop and surface the lane failure to the user as BLOCKED; do not produce a degraded review, partial verdict, or final synthesis.
67257
67474
  - CHECK OUT THE EXACT PR HEAD LOCALLY before dispatching explorer lanes: resolve the authoritative full PR head SHA, verify the working tree is clean (git status --porcelain), and if it is dirty call \`prepare_pr_workflow_checkout\` before checkout \u2014 either with no \`paths\` to auto-discover and preserve every dirty and untracked change in one auditable stash, or with an explicit exact dirty tracked path set. It returns the stash OID and recovery command; an already-clean tree is a no-op. Do NOT run \`git stash\` through shell. Then use standalone commands: fetch the PR head, verify it portably with \`git rev-parse --verify <full_pr_head_sha>^0\` followed by \`git cat-file -t <full_pr_head_sha>\` (which must print \`commit\`), run \`git switch --detach <full_pr_head_sha>\`, confirm HEAD equals that SHA, and bind it through the PR-review controller. Do not use \`--track FETCH_HEAD\`. Explorers read the working-tree filesystem (Read/Glob/Grep), so without this checkout they read the base branch and produce invalid candidates. Always pass the base..head commit range in explorer delegations. Under Profile A, do not create a scratch context-pack file after the gate activates: put bounded shared scope, obligations, and deterministic signals in \`common_prompt\`; every lane must inspect the exact bound diff itself.
67258
67475
  - Treat the controller Git-state result as final for the attempt: \`clean\` proceeds; \`stashable\` permits one preparation call; \`recovery-required\` or \`indeterminate\` means report the typed \`required_action\`, abort/clear any already-active gate, and STOP unless \`retryable: true\`. Never loop on stash against an unmerged index or in-progress Git operation.
67259
- - RUN ALL BASE LANES: the default PR_REVIEW path always launches exactly six repository-agnostic base check-type lanes from the skill. Use \`mode: "swarm-pr-review:base"\` and the exact six \`workflow_lane\` identifiers. The runtime rejects partial, duplicate, or mislabelled waves. Do not collapse, omit, or scale down the base lanes for a small, docs-only, or CI-only PR.
67260
- - RETRY STRUCTURALLY: retry only failed base obligations in later \`swarm-pr-review:base\` async batches with the same exact \`pr_head_sha\`. Blocking \`dispatch_lanes\` and direct Task explorer/reviewer/critic dispatch are not provenance-equivalent and are rejected. After the second failed retry, collect every lane to settlement, do not probe downstream writers or micro lanes, call \`abort_pr_workflow\` with \`mode: "PR_REVIEW"\`, \`kind: "recovery"\`, and a non-empty one-line \`reason\` naming the failed lane and exhausted retries, then call \`prepare_pr_workflow_checkout\` with \`operation: "restore"\` before reporting the blocker.
67261
- - USE ASYNC DISPATCH WITHOUT IDLING: launch the base lanes with one \`dispatch_lanes_async\` call when available, record the \`batch_id\`, then keep doing non-dependent architect work while they run. Poll with \`collect_lane_results\` without \`wait\` (or \`wait: false\`) to process settled lanes and continue independent work between polls; use \`wait: true\` only as the final join when no independent work remains.
67476
+ - RUN ALL BASE LANES: the default PR_REVIEW path covers all six repository-agnostic base dimensions from the skill on every PR. Use \`mode: "swarm-pr-review:base"\`, the exact \`workflow_lane\` identifiers, and the exact bound \`pr_head_sha\`. With the default \`pr_review_resilience\` policy enabled, depth tier M/L MUST stage attempt 0 as one singleton \`pr_review_wave_stage: "canary"\` batch followed by a \`"fanout"\` batch whose combined canary+fanout ownership partitions all six dimensions exactly once; tier L still requires six singleton combined lanes, and tier S keeps the legacy one-wave path. If a project disables \`pr_review_resilience\`, stay on the legacy one-wave base dispatch. The runtime rejects omitted stage metadata, partial, duplicate, mislabelled, or structurally invalid waves.
67477
+ - RETRY STRUCTURALLY: retry only unresolved failed base obligations in later \`swarm-pr-review:base\` async batches with the same exact \`pr_head_sha\`. Under staged resilience, attempts are numbered by \`pr_review_wave_attempt\`: attempt 0 plus at most two retry attempts (1 and 2), each with one singleton canary batch and then its matching fanout batch when obligations remain. Blocking \`dispatch_lanes\` and direct Task explorer/reviewer/critic dispatch are not provenance-equivalent and are rejected. If the runtime returns typed \`retry_exhausted\` or \`circuit_open\`, or if the second retry still cannot close coverage, collect every lane to settlement, do not probe downstream writers or micro lanes, call \`abort_pr_workflow\` with \`mode: "PR_REVIEW"\`, \`kind: "recovery"\`, and a non-empty one-line \`reason\` naming the failed lane or correlated failure and exhausted retries, then call \`prepare_pr_workflow_checkout\` with \`operation: "restore"\` before reporting the blocker.
67478
+ - USE ASYNC DISPATCH WITHOUT IDLING: each admissible base wave uses one \`dispatch_lanes_async\` call. With enabled tier-M/L staged resilience, this means one singleton canary call followed by one unresolved-only fanout call after canary admission; it never means one legacy call carrying the whole initial base wave. Record each \`batch_id\`, then keep doing non-dependent architect work while its lanes run. Poll with \`collect_lane_results\` without \`wait\` (or \`wait: false\`) to process settled lanes and continue independent work between polls; use \`wait: true\` only as the final join when no independent work remains.
67262
67479
  - EVALUATE ALL RISK FAMILIES: after the base explorer lanes settle, evaluate every repository-agnostic trigger row against the exact diff/context pack. Record applicable families as \`MATCHED\` and inapplicable families as provenance-free \`NOT_TRIGGERED\` with concrete absence evidence; \`unclassified-risk\` always remains \`MATCHED\`. Launch \`swarm-pr-review:micro\` lanes only for the \`MATCHED\` IDs. The first micro dispatch MUST pass the complete exact eleven-row \`trigger_evaluation\`, which freezes it for this session; any subsequent same-session micro batch may omit it and reuse the frozen ledger, while an explicitly supplied copy must remain exactly identical. Use each dispatched trigger ID as \`workflow_lane\`. Missing an evaluation row or a matched-family attestation is BLOCKED; a \`NOT_TRIGGERED\` family must not create a micro artifact.
67263
67480
  - RUN HEAD-BOUND VALIDATION: dispatch independent reviewers with \`mode: "swarm-pr-review:reviewer"\` and critics with \`mode: "swarm-pr-review:critic"\`, unique \`workflow_lane\` obligations, role-correct agents, and the same exact \`pr_head_sha\`. Critic dispatch is blocked until all declared reviewer obligations have successful artifacts.
67264
67481
  - COMPLETE EXPLICITLY: after final artifacts and synthesis, call \`complete_pr_workflow\` with \`mode: "PR_REVIEW"\` and the bound \`pr_head_sha\`; never leave the session trapped in a stale workflow gate. When completion reports checkout restoration is required, call \`prepare_pr_workflow_checkout\` with \`operation: "restore"\` before returning to the user.
@@ -71071,6 +71288,11 @@ var GUARDED_TOOLS = new Set([
71071
71288
  ]);
71072
71289
  var selfDevelopmentWorkspaces = new Map;
71073
71290
  // src/hooks/guardrails/index.ts
71291
+ var durableAttributionAdvisoryBySession = new Map;
71292
+ var STAGE_A_ATTRIBUTION_MISS_CODES = new Set([
71293
+ "TASK_WORKFLOW_CODER_MUTATION_REQUIRED",
71294
+ "TASK_WORKFLOW_STAGE_A_REQUIRED"
71295
+ ]);
71074
71296
  var SPEC_DRIFT_BLOCKED_TOOLS = new Set([
71075
71297
  "save_plan",
71076
71298
  "update_task_status",
@@ -72890,7 +73112,7 @@ async function precreateStandardWorktreeSession(args) {
72890
73112
  const laneProfile = computeLaneRuntimeProfile(worktreeConfig.runtime_isolation, laneIndex, provisionResult.worktreePath);
72891
73113
  if (laneProfile) {
72892
73114
  try {
72893
- const { writeLaneProfileToDiskReal } = await import("./core-jvvm935f.js");
73115
+ const { writeLaneProfileToDiskReal } = await import("./core-17febkvw.js");
72894
73116
  await writeLaneProfileToDiskReal(provisionResult.worktreePath, laneProfile.laneIndex, laneProfile.envOverrides);
72895
73117
  } catch {}
72896
73118
  }
@@ -73548,7 +73770,7 @@ async function finishStandardWorktreeDispatch(directory, dispatch, config, callI
73548
73770
  }
73549
73771
  clearWorktreeMergeStatus(statusKey);
73550
73772
  try {
73551
- const { removeLaneProfileFromDiskReal } = await import("./core-jvvm935f.js");
73773
+ const { removeLaneProfileFromDiskReal } = await import("./core-17febkvw.js");
73552
73774
  await removeLaneProfileFromDiskReal(dispatch.handle.worktreePath, dispatch.laneIndex);
73553
73775
  } catch {}
73554
73776
  const state = serializationStateBySessionID.get(dispatch.parentSessionID);