opencode-swarm 7.143.5 → 7.144.0

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 (58) hide show
  1. package/.opencode/skills/swarm-pr-review/SKILL.md +5 -5
  2. package/.opencode/skills/swarm-pr-review/references/lane-output-recoverability.md +129 -0
  3. package/dist/background/delegation-health.d.ts +213 -0
  4. package/dist/background/pending-delegations.d.ts +164 -16
  5. package/dist/background/pr-review-trigger-contract.d.ts +17 -0
  6. package/dist/cli/{config-doctor-y8wfw196.js → config-doctor-7gy47evn.js} +2 -2
  7. package/dist/cli/{core-zszmexgm.js → core-cpcspaw5.js} +1 -1
  8. package/dist/cli/{curator-llm-factory-xsg7wesn.js → curator-llm-factory-fyjmgxyp.js} +18 -18
  9. package/dist/cli/{curator-e2sp925h.js → curator-v97jnwn2.js} +18 -18
  10. package/dist/cli/{evidence-summary-service-pfppq7mv.js → evidence-summary-service-79mtxzhd.js} +6 -6
  11. package/dist/cli/{gate-evidence-23jnh3mb.js → gate-evidence-kgyqz1g1.js} +2 -2
  12. package/dist/cli/{guardrail-explain-byzmrgg1.js → guardrail-explain-9ry66z5g.js} +19 -19
  13. package/dist/cli/{guardrail-log-nr2g7hbw.js → guardrail-log-fe6smme1.js} +3 -3
  14. package/dist/cli/{hive-promoter-cw08380z.js → hive-promoter-vwq1dbh1.js} +18 -18
  15. package/dist/cli/{index-qdarzed6.js → index-0ck3e366.js} +1 -1
  16. package/dist/cli/{index-xmje20we.js → index-1pr8x10a.js} +2 -2
  17. package/dist/cli/{index-p844tcrm.js → index-269b52r3.js} +3 -3
  18. package/dist/cli/{index-04x9wx7d.js → index-3q9w6e6v.js} +1 -1
  19. package/dist/cli/{index-5866smj5.js → index-3v3dxf75.js} +3 -3
  20. package/dist/cli/{index-8aabbfhv.js → index-4fda8kkw.js} +1057 -92
  21. package/dist/cli/{index-jqxgdvr9.js → index-6p09gyra.js} +1 -1
  22. package/dist/cli/{index-mnj0ter5.js → index-8xertnqz.js} +3 -3
  23. package/dist/cli/{index-a1p87gew.js → index-d45d4zyq.js} +1 -1
  24. package/dist/cli/{index-y8r7z30j.js → index-d45yrzkg.js} +1 -1
  25. package/dist/cli/{index-1kr1vey5.js → index-e70d3xr7.js} +20 -20
  26. package/dist/cli/{index-a4dkd7m7.js → index-evvbmbbv.js} +1 -1
  27. package/dist/cli/{index-dg1v2gnh.js → index-ewzmjm7m.js} +1 -1
  28. package/dist/cli/{index-47z3jbxk.js → index-ez18gjk2.js} +3 -3
  29. package/dist/cli/{index-51axj9vd.js → index-j1scj25g.js} +481 -80
  30. package/dist/cli/{index-m7v7gggs.js → index-jqabjy7t.js} +4 -4
  31. package/dist/cli/{index-7en3eq3k.js → index-jvbfrwt2.js} +1 -1
  32. package/dist/cli/{index-tmc43mkc.js → index-mw6p3nt6.js} +1 -1
  33. package/dist/cli/{index-x64vt6sc.js → index-rd2082y4.js} +2 -2
  34. package/dist/cli/{index-q2nd6q9e.js → index-tfkfyshg.js} +1 -1
  35. package/dist/cli/{index-mbczeqs3.js → index-vb9cpaz4.js} +5 -5
  36. package/dist/cli/{index-at0h6cd6.js → index-zv4pwyas.js} +2 -2
  37. package/dist/cli/index.js +18 -18
  38. package/dist/cli/{knowledge-escalator-1g4p844a.js → knowledge-escalator-rmy3jcx4.js} +6 -6
  39. package/dist/cli/{knowledge-events-5699zzw0.js → knowledge-events-1tqpbwvj.js} +4 -4
  40. package/dist/cli/{knowledge-store-m5qjn5kd.js → knowledge-store-389ck792.js} +1 -1
  41. package/dist/cli/{knowledge-validator-xxnp8ear.js → knowledge-validator-kvtk6633.js} +2 -2
  42. package/dist/cli/{pending-delegations-b3pt3w5w.js → pending-delegations-thy8g30k.js} +27 -1
  43. package/dist/cli/{scan-cursor-qvky2yem.js → scan-cursor-ahgm4f5p.js} +2 -2
  44. package/dist/cli/{schema-wgb37f83.js → schema-epdq7ykx.js} +1 -1
  45. package/dist/cli/{scope-persistence-0wrb7ptt.js → scope-persistence-37s9n40v.js} +4 -4
  46. package/dist/cli/{skill-generator-khaw3jjw.js → skill-generator-4d2t5gem.js} +7 -7
  47. package/dist/cli/{worktree-collision-ownership-bfz3drxm.js → worktree-collision-ownership-j6d33p49.js} +1 -1
  48. package/dist/cli/{worktree-isolation-bv41gn3k.js → worktree-isolation-4628yaka.js} +18 -18
  49. package/dist/evaluation/contracts.d.ts +4 -4
  50. package/dist/evaluation/gate-ground-truth.d.ts +1 -1
  51. package/dist/hooks/init-orphan-recovery.d.ts +2 -0
  52. package/dist/hooks/pr-workflow-gate.d.ts +135 -1
  53. package/dist/index.js +446 -441
  54. package/dist/services/status-service.d.ts +9 -0
  55. package/dist/tools/complete-pr-workflow.d.ts +3 -1
  56. package/dist/tools/pr-workflow-status.d.ts +2 -2
  57. package/dist/tools/write-pr-review-trigger-eval.d.ts +2 -1
  58. package/package.json +1 -1
@@ -1,13 +1,13 @@
1
1
  // @bun
2
2
  import {
3
3
  stableCanonicalStringify
4
- } from "./index-y8r7z30j.js";
4
+ } from "./index-d45yrzkg.js";
5
5
  import {
6
6
  detectStraySwarmDirs,
7
7
  readDoctorArtifact,
8
8
  removeStraySwarmDir,
9
9
  runConfigDoctor
10
- } from "./index-a4dkd7m7.js";
10
+ } from "./index-evvbmbbv.js";
11
11
  import {
12
12
  MAX_TRANSIENT_RETRIES,
13
13
  archiveEvidence,
@@ -54,7 +54,7 @@ import {
54
54
  updateTaskCheckpointReceipt,
55
55
  updateTaskStatus,
56
56
  validateProjectRoot
57
- } from "./index-5866smj5.js";
57
+ } from "./index-3v3dxf75.js";
58
58
  import {
59
59
  loadDatabaseCtor
60
60
  } from "./index-134d35c1.js";
@@ -106,7 +106,7 @@ import {
106
106
  alreadyCuratedThisGeneration,
107
107
  claimNextScanBatch,
108
108
  resolveCohortId
109
- } from "./index-tmc43mkc.js";
109
+ } from "./index-mw6p3nt6.js";
110
110
  import {
111
111
  CURATOR_INIT_PROMPT,
112
112
  CURATOR_PHASE_PROMPT,
@@ -141,7 +141,7 @@ import {
141
141
  startupOrphanRecovery,
142
142
  withTaskEvidenceTransaction,
143
143
  writeWorkflowWalFile
144
- } from "./index-7en3eq3k.js";
144
+ } from "./index-jvbfrwt2.js";
145
145
  import {
146
146
  changedFilesSinceSnapshot,
147
147
  parsePorcelainV2Snapshot,
@@ -188,16 +188,16 @@ import {
188
188
  retireSkill,
189
189
  selectCandidateEntries,
190
190
  syncBundledProjectSkillsIfMissingAsync
191
- } from "./index-p844tcrm.js";
191
+ } from "./index-269b52r3.js";
192
192
  import {
193
193
  readRecentEscalations
194
- } from "./index-mbczeqs3.js";
194
+ } from "./index-vb9cpaz4.js";
195
195
  import {
196
196
  MAX_PENDING_SCOPE_BINDINGS,
197
197
  clearAllScopes,
198
198
  clearScopeBindingFromDisk,
199
199
  clearScopeBindings
200
- } from "./index-at0h6cd6.js";
200
+ } from "./index-zv4pwyas.js";
201
201
  import {
202
202
  appendLedgerEvent,
203
203
  computePlanHash,
@@ -210,7 +210,7 @@ import {
210
210
  readPlanEpochIdentity,
211
211
  replayFromLedgerWithStatus,
212
212
  takeSnapshotEvent
213
- } from "./index-qdarzed6.js";
213
+ } from "./index-0ck3e366.js";
214
214
  import {
215
215
  isPathWithinDeclaredScope
216
216
  } from "./index-556ja8an.js";
@@ -232,13 +232,19 @@ import {
232
232
  removeWorktreeProvisioningOwner
233
233
  } from "./index-k3cxyk66.js";
234
234
  import {
235
+ DEFAULT_STALE_DELEGATION_TIMEOUT_MS,
236
+ DELEGATION_COMPACTION_HIGH_WATER_BYTES,
237
+ DELEGATION_COMPACTION_LOW_WATER_BYTES,
238
+ MAX_RECOVERY_LEDGER_BYTES,
239
+ collectDelegationLedgerHealth,
235
240
  findByBatchId,
236
- readDelegations
237
- } from "./index-8aabbfhv.js";
241
+ readDelegations,
242
+ sweepStaleDelegations
243
+ } from "./index-4fda8kkw.js";
238
244
  import {
239
245
  provisionWorktree,
240
246
  removeWorktree
241
- } from "./index-q2nd6q9e.js";
247
+ } from "./index-tfkfyshg.js";
242
248
  import {
243
249
  SandboxCapabilityProbe,
244
250
  init_capability_probe
@@ -262,10 +268,10 @@ import {
262
268
  recordKnowledgeEvent,
263
269
  recordPhaseCloseIntent,
264
270
  resolveKnowledgeEventsPath
265
- } from "./index-47z3jbxk.js";
271
+ } from "./index-ez18gjk2.js";
266
272
  import {
267
273
  resolveWorktreeIsolationConfig
268
- } from "./index-xmje20we.js";
274
+ } from "./index-1pr8x10a.js";
269
275
  import {
270
276
  RetrospectiveEvidenceSchema
271
277
  } from "./index-gprxjmm7.js";
@@ -275,7 +281,7 @@ import {
275
281
  init_loader,
276
282
  loadPluginConfig,
277
283
  loadPluginConfigWithMeta
278
- } from "./index-a1p87gew.js";
284
+ } from "./index-d45d4zyq.js";
279
285
  import {
280
286
  DEFAULT_SKILL_OPT_CONFIG,
281
287
  FALLBACK_MODELS_MAX,
@@ -289,7 +295,7 @@ import {
289
295
  package_default,
290
296
  resolveAutoReviewConfig,
291
297
  stripKnownSwarmPrefix
292
- } from "./index-04x9wx7d.js";
298
+ } from "./index-3q9w6e6v.js";
293
299
  import {
294
300
  readSwarmFileAsync,
295
301
  safeHook,
@@ -324,7 +330,7 @@ import {
324
330
  validateActionableFields,
325
331
  validateLesson,
326
332
  validateSkillPath
327
- } from "./index-dg1v2gnh.js";
333
+ } from "./index-ewzmjm7m.js";
328
334
  import {
329
335
  authorizeCuration,
330
336
  buildConfigFingerprintInput
@@ -361,7 +367,7 @@ import {
361
367
  transactFile,
362
368
  transactKnowledge,
363
369
  wordBigrams
364
- } from "./index-m7v7gggs.js";
370
+ } from "./index-jqabjy7t.js";
365
371
  import {
366
372
  resolveHiveDataDir,
367
373
  resolveHiveEventsPath,
@@ -4153,7 +4159,7 @@ async function cleanupRecoveredWorktree(directory, descriptor) {
4153
4159
  awaitingMergeByCallID,
4154
4160
  cleanupStandardWorktreeForCallId,
4155
4161
  standardWorktreeByCallID
4156
- } = await import("./worktree-isolation-bv41gn3k.js");
4162
+ } = await import("./worktree-isolation-4628yaka.js");
4157
4163
  standardWorktreeByCallID.delete(descriptor.callID);
4158
4164
  if (hasResidue)
4159
4165
  awaitingMergeByCallID.set(descriptor.callID, {
@@ -4232,7 +4238,7 @@ async function recoverCoderSettlement(directory, taskId) {
4232
4238
  awaitingMergeByCallID,
4233
4239
  finishStandardWorktreeDispatch,
4234
4240
  standardWorktreeByCallID
4235
- } = await import("./worktree-isolation-bv41gn3k.js");
4241
+ } = await import("./worktree-isolation-4628yaka.js");
4236
4242
  const descriptor = wal.worktree;
4237
4243
  const reconstructedDispatch = {
4238
4244
  callID: descriptor.callID,
@@ -6261,7 +6267,8 @@ var V2ReceiptSchema = ReceiptEnvelopeSchema.extend({
6261
6267
  not_triggered_count: exports_external.number().int().min(0),
6262
6268
  no_match_count: exports_external.number().int().min(0),
6263
6269
  rows: exports_external.array(V2RowSchema),
6264
- coverage_degradations: exports_external.array(TriggerCoverageDegradationSchema).default([])
6270
+ coverage_degradations: exports_external.array(TriggerCoverageDegradationSchema).default([]),
6271
+ base_verification: exports_external.enum(["live", "bound_fallback"]).optional()
6265
6272
  }).strict();
6266
6273
  function assertCanonicalDefinitionFields(rows) {
6267
6274
  const definitions = new Map(PR_REVIEW_TRIGGER_DEFINITIONS.map((definition) => [
@@ -6303,13 +6310,14 @@ var V1ReceiptSchema = ReceiptEnvelopeSchema.extend({
6303
6310
  rows: exports_external.array(LegacyRowSchema)
6304
6311
  }).strict();
6305
6312
  var UnversionedRowOnlyReceiptSchema = exports_external.object({ rows: exports_external.array(exports_external.unknown()) }).strict();
6306
- function parsedReceipt(schemaVersion, rows, coverageDegradations = []) {
6313
+ function parsedReceipt(schemaVersion, rows, coverageDegradations = [], baseVerification) {
6307
6314
  return {
6308
6315
  schemaVersion,
6309
6316
  rows,
6310
6317
  matchedRows: rows.filter((row) => row.result === "MATCHED"),
6311
6318
  notTriggeredRows: rows.filter((row) => row.result === "NOT_TRIGGERED"),
6312
- coverageDegradations
6319
+ coverageDegradations,
6320
+ ...baseVerification ? { baseVerification } : {}
6313
6321
  };
6314
6322
  }
6315
6323
  function parsePrReviewTriggerReceipt(input) {
@@ -6342,7 +6350,7 @@ function parsePrReviewTriggerReceipt(input) {
6342
6350
  throw new Error(`PR_REVIEW trigger receipt ${field} is inconsistent: expected ${expected}`);
6343
6351
  }
6344
6352
  }
6345
- return parsedReceipt(2, validated2.rows, receipt.coverage_degradations);
6353
+ return parsedReceipt(2, validated2.rows, receipt.coverage_degradations, receipt.base_verification);
6346
6354
  }
6347
6355
  if (schemaVersion !== undefined && schemaVersion !== 1) {
6348
6356
  throw new Error(`Unsupported PR_REVIEW trigger schema_version: ${schemaVersion}`);
@@ -6594,6 +6602,7 @@ var MAX_WORKFLOW_BATCHES = 128;
6594
6602
  var MAX_RETIRED_REVIEWER_SESSION_IDS = 1024;
6595
6603
  var MAX_RETIRED_CONSOLIDATED_LANES = 64;
6596
6604
  var MAX_RETIRED_FEEDBACK_ITEM_OWNERS = 4096;
6605
+ var MAX_PR_FEEDBACK_INVENTORY_AMENDMENTS = 128;
6597
6606
  var WINDOWS_RENAME_MAX_RETRIES = 3;
6598
6607
  var RENAME_RETRY_DELAY_MS = 10;
6599
6608
  var STATE_MUTATION_LOCK_MAX_ATTEMPTS = 50;
@@ -6700,6 +6709,11 @@ var PrFeedbackReadyToPublishRecordSchema = exports_external.object({
6700
6709
  remoteRef: exports_external.string().startsWith("refs/remotes/"),
6701
6710
  validatedAt: exports_external.string().min(1)
6702
6711
  }).strict();
6712
+ var PrFeedbackInventoryAmendmentRecordSchema = exports_external.object({
6713
+ entry: exports_external.string().min(1),
6714
+ amendedAt: exports_external.string().min(1),
6715
+ batch: exports_external.number().int().positive()
6716
+ }).strict();
6703
6717
  var PrReviewValidationBatchRecordSchema = exports_external.object({
6704
6718
  batchId: exports_external.string().min(1),
6705
6719
  phase: exports_external.enum(["council", "reviewer", "critic"]),
@@ -6789,6 +6803,7 @@ var PrWorkflowGateStateSchema = exports_external.object({
6789
6803
  prFeedbackTargetUrl: exports_external.string().url().max(2000).optional(),
6790
6804
  prFeedbackReviewHandoff: PrFeedbackReviewHandoffRecordSchema.optional(),
6791
6805
  prFeedbackInventory: exports_external.array(exports_external.string().min(1)).min(1).optional(),
6806
+ prFeedbackInventoryAmendments: exports_external.array(PrFeedbackInventoryAmendmentRecordSchema).max(MAX_PR_FEEDBACK_INVENTORY_AMENDMENTS).optional(),
6792
6807
  prFeedbackVerifications: exports_external.array(PrFeedbackVerificationRecordSchema).max(MAX_WORKFLOW_BATCHES).optional(),
6793
6808
  prFeedbackRetiredItemOwnership: exports_external.record(exports_external.string().min(1), exports_external.string().min(1)).refine((entries) => Object.keys(entries).length <= MAX_RETIRED_FEEDBACK_ITEM_OWNERS, `prFeedbackRetiredItemOwnership may not exceed ${MAX_RETIRED_FEEDBACK_ITEM_OWNERS} entries`).optional(),
6794
6809
  prFeedbackVerification: PrFeedbackVerificationRecordSchema.optional(),
@@ -6880,11 +6895,11 @@ async function readPrWorkflowGateState(directory, sessionID) {
6880
6895
  }
6881
6896
  return state;
6882
6897
  }
6883
- async function clearPrWorkflowGateState(directory, sessionID, expectedRevision) {
6898
+ async function clearPrWorkflowGateState(directory, sessionID, expectedRevision, options = {}) {
6884
6899
  const normalizedSessionID = normalizeSessionID(sessionID);
6885
6900
  await withSessionStateMutation(directory, normalizedSessionID, async () => {
6886
6901
  if (expectedRevision !== undefined) {
6887
- const current = await readPrWorkflowGateStateFromDisk(directory, normalizedSessionID);
6902
+ const current = options.allowSalvagedRead ? (await readPrWorkflowGateStateForRecovery(directory, normalizedSessionID))?.state ?? null : await readPrWorkflowGateStateFromDisk(directory, normalizedSessionID);
6888
6903
  if (!current || current.revision !== expectedRevision) {
6889
6904
  throw new Error("BLOCKED: PR workflow gate state changed during terminal completion; revalidate the current session state before retrying");
6890
6905
  }
@@ -6901,18 +6916,71 @@ async function clearPrWorkflowGateState(directory, sessionID, expectedRevision)
6901
6916
  trackedStatesByProjectSession.delete(stateCacheKey(directory, normalizedSessionID));
6902
6917
  });
6903
6918
  }
6919
+ var PR_WORKFLOW_STALE_LANE_TIMEOUT_MS = DEFAULT_STALE_DELEGATION_TIMEOUT_MS;
6920
+ var MAX_DISCLOSED_LANE_IDS = 10;
6921
+ var PR_WORKFLOW_SWEEPABLE_LANE_STATUSES = new Set(["pending", "running"]);
6922
+ var CAS_ESCAPE_DISCLOSURE = "state revision unsalvageable; cleared without compare-and-swap";
6923
+ function prWorkflowLaneLabel(record) {
6924
+ return record.laneId ?? record.subagentSessionId ?? "unknown";
6925
+ }
6926
+ function isOpenPrWorkflowLane(record, sessionID) {
6927
+ return record.parentSessionId === sessionID && record.mode?.startsWith("swarm-pr-") === true && (record.status === "pending" || record.status === "running");
6928
+ }
6929
+ async function settlePresumedStalePrWorkflowLanes(directory, sessionID) {
6930
+ const now = Date.now();
6931
+ const open2 = [];
6932
+ const presumedStale = [];
6933
+ for (const record of readDelegations(directory)) {
6934
+ if (!isOpenPrWorkflowLane(record, sessionID))
6935
+ continue;
6936
+ if (now - record.updatedAt > PR_WORKFLOW_STALE_LANE_TIMEOUT_MS) {
6937
+ presumedStale.push(record);
6938
+ } else {
6939
+ open2.push(record);
6940
+ }
6941
+ }
6942
+ const presumedStaleLaneIds = presumedStale.map(prWorkflowLaneLabel);
6943
+ const openLaneIds = open2.map(prWorkflowLaneLabel);
6944
+ if (presumedStale.length === 0) {
6945
+ return { openLaneIds, openLanes: open2.length, presumedStaleLaneIds };
6946
+ }
6947
+ const disclosure = `${presumedStaleLaneIds.length} lane(s) stale >` + `${Math.round(PR_WORKFLOW_STALE_LANE_TIMEOUT_MS / 60000)}min, ` + `treated as settled: ${presumedStaleLaneIds.slice(0, MAX_DISCLOSED_LANE_IDS).join(", ")}`;
6948
+ await sweepStaleDelegations(directory, PR_WORKFLOW_STALE_LANE_TIMEOUT_MS, {
6949
+ statuses: PR_WORKFLOW_SWEEPABLE_LANE_STATUSES
6950
+ });
6951
+ try {
6952
+ await fsp2.appendFile(validateSwarmPath(directory, "events.jsonl"), `${JSON.stringify({
6953
+ type: "pr_workflow_lanes_presumed_stale",
6954
+ timestamp: isoNow(),
6955
+ sessionID,
6956
+ presumedStaleLanes: presumedStaleLaneIds.slice(0, MAX_DISCLOSED_LANE_IDS),
6957
+ staleTimeoutMs: PR_WORKFLOW_STALE_LANE_TIMEOUT_MS,
6958
+ disclosure
6959
+ })}
6960
+ `, "utf-8");
6961
+ } catch {}
6962
+ return {
6963
+ openLaneIds,
6964
+ openLanes: open2.length,
6965
+ presumedStaleLaneIds,
6966
+ disclosure
6967
+ };
6968
+ }
6904
6969
  async function abortPrWorkflow(directory, sessionID, options = { kind: "recovery", reason: "" }) {
6905
- const state = await requireAnyActiveState(directory, sessionID);
6970
+ const recovery = await readPrWorkflowGateStateForRecovery(directory, sessionID);
6971
+ if (!recovery)
6972
+ throw noActiveGateError(sessionID);
6973
+ const state = recovery.state;
6906
6974
  if (options.expectedMode && state.mode !== options.expectedMode) {
6907
6975
  throw wrongModeError(state, options.expectedMode);
6908
6976
  }
6909
- if (state.prFeedbackReadyToPublish) {
6910
- throw new Error(`BLOCKED: ${state.mode} is armed for publication; abort is blocked. Complete the workflow with complete_pr_workflow (or push the bound commit first) before aborting.`);
6977
+ if (state.prFeedbackReadyToPublish || recovery.armedShapeUnreadable) {
6978
+ throw new Error(`BLOCKED: ${state.mode} is armed for publication; abort is blocked. Complete the workflow with complete_pr_workflow (or push the bound commit first) before aborting.` + (recovery.armedShapeUnreadable ? " The publication-arming record is itself unreadable, so it is treated as armed (fail-closed)." : ""));
6911
6979
  }
6912
- const openLanes = readDelegations(directory).filter((record) => record.parentSessionId === state.sessionID && record.mode?.startsWith("swarm-pr-") && (record.status === "pending" || record.status === "running"));
6913
- if (openLanes.length > 0) {
6914
- const laneIds = openLanes.map((record) => record.laneId ?? record.subagentSessionId ?? "unknown").filter(Boolean).slice(0, 10).join(", ");
6915
- throw new Error(`BLOCKED: ${state.mode} abort refused while ${openLanes.length} PR workflow lane(s) are still in flight (lane ids: ${laneIds}). Collect their results or let them settle before aborting.`);
6980
+ const laneSettlement = await settlePresumedStalePrWorkflowLanes(directory, state.sessionID);
6981
+ if (laneSettlement.openLanes > 0) {
6982
+ const laneIds = laneSettlement.openLaneIds.filter(Boolean).slice(0, MAX_DISCLOSED_LANE_IDS).join(", ");
6983
+ throw new Error(`BLOCKED: ${state.mode} abort refused while ${laneSettlement.openLanes} PR workflow lane(s) are still in flight (lane ids: ${laneIds}). Collect their results or let them settle before aborting.`);
6916
6984
  }
6917
6985
  const sanitizedReason = typeof options.reason === "string" && options.reason.trim().length > 0 ? options.reason.trim().slice(0, 500) : undefined;
6918
6986
  if (sanitizedReason === undefined) {
@@ -6926,7 +6994,16 @@ async function abortPrWorkflow(directory, sessionID, options = { kind: "recovery
6926
6994
  kind: options.kind,
6927
6995
  ...state.prHeadSha ? { prHeadSha: state.prHeadSha } : {},
6928
6996
  ...state.checkoutRecovery ? { hadTerminalRecovery: true } : {},
6929
- openLanes: openLanes.length,
6997
+ openLanes: laneSettlement.openLanes,
6998
+ ...laneSettlement.presumedStaleLaneIds.length > 0 ? {
6999
+ presumedStaleLanes: laneSettlement.presumedStaleLaneIds.slice(0, MAX_DISCLOSED_LANE_IDS),
7000
+ presumedStaleDisclosure: laneSettlement.disclosure
7001
+ } : {},
7002
+ ...recovery.salvaged ? {
7003
+ stateSalvaged: true,
7004
+ stateSalvageDisclosure: recovery.disclosure,
7005
+ ...recovery.revisionSalvageable ? {} : { casEscapeDisclosure: CAS_ESCAPE_DISCLOSURE }
7006
+ } : {},
6930
7007
  reason: sanitizedReason
6931
7008
  };
6932
7009
  try {
@@ -6934,11 +7011,39 @@ async function abortPrWorkflow(directory, sessionID, options = { kind: "recovery
6934
7011
  await fsp2.appendFile(eventsPath, `${JSON.stringify(abortEvent)}
6935
7012
  `, "utf-8");
6936
7013
  } catch {}
6937
- await clearPrWorkflowGateState(directory, sessionID, state.revision);
7014
+ const casEscape = recovery.salvaged && !recovery.revisionSalvageable;
7015
+ await _test_exports.beforeAbortClear?.();
7016
+ try {
7017
+ await clearPrWorkflowGateState(directory, sessionID, casEscape ? undefined : state.revision, { allowSalvagedRead: recovery.salvaged });
7018
+ } catch (error2) {
7019
+ try {
7020
+ await fsp2.appendFile(validateSwarmPath(directory, "events.jsonl"), `${JSON.stringify({
7021
+ type: "pr_workflow_abort_not_completed",
7022
+ timestamp: isoNow(),
7023
+ sessionID: state.sessionID,
7024
+ mode: state.mode,
7025
+ ...state.prHeadSha ? { prHeadSha: state.prHeadSha } : {},
7026
+ reason: sanitizedReason,
7027
+ failure: (error2 instanceof Error ? error2.message : String(error2)).slice(0, MAX_BASE_COVERAGE_DIAGNOSTIC_CHARS),
7028
+ disclosure: "RETRACTION: the pr_workflow_aborted record for this session did NOT complete \u2014 " + "the clear failed and the gate state may still be active. Revalidate the current " + "session state before retrying the abort."
7029
+ })}
7030
+ `, "utf-8");
7031
+ } catch {}
7032
+ throw error2;
7033
+ }
6938
7034
  return {
6939
7035
  mode: state.mode,
6940
7036
  ...state.prHeadSha ? { prHeadSha: state.prHeadSha } : {},
6941
- openLanes: openLanes.length
7037
+ openLanes: laneSettlement.openLanes,
7038
+ ...laneSettlement.presumedStaleLaneIds.length > 0 ? {
7039
+ presumedStaleLanes: laneSettlement.presumedStaleLaneIds,
7040
+ presumedStaleDisclosure: laneSettlement.disclosure
7041
+ } : {},
7042
+ ...recovery.salvaged ? {
7043
+ stateSalvaged: true,
7044
+ stateSalvageDisclosure: recovery.disclosure
7045
+ } : {},
7046
+ ...casEscape ? { casEscapeDisclosure: CAS_ESCAPE_DISCLOSURE } : {}
6942
7047
  };
6943
7048
  }
6944
7049
  async function bindPrWorkflowHeadWhileLocked(directory, normalizedSessionID, prHeadSha) {
@@ -7343,9 +7448,9 @@ function assertSamePrFeedbackHandoff(state, relativePath, read, requestedPrUrl)
7343
7448
  async function assertPrReviewTerminalReady(directory, sessionID) {
7344
7449
  const state = await requireBoundState(directory, sessionID, "PR_REVIEW");
7345
7450
  await assertPrReviewCleanCheckout(directory, "PR_REVIEW");
7346
- const open2 = readDelegations(directory).filter((record) => record.parentSessionId === state.sessionID && record.mode?.startsWith("swarm-pr-") && (record.status === "pending" || record.status === "running"));
7347
- if (open2.length > 0) {
7348
- throw new Error(`BLOCKED: PR_REVIEW transition has ${open2.length} unsettled PR workflow lane(s)`);
7451
+ const laneSettlement = await settlePresumedStalePrWorkflowLanes(directory, state.sessionID);
7452
+ if (laneSettlement.openLanes > 0) {
7453
+ throw new Error(`BLOCKED: PR_REVIEW transition has ${laneSettlement.openLanes} unsettled PR workflow lane(s)`);
7349
7454
  }
7350
7455
  const ctx = await createPrReviewGateContext(directory, state);
7351
7456
  await assertPrReviewBaseCoverageSettled(directory, sessionID, ctx);
@@ -7490,6 +7595,7 @@ var _test_exports = {
7490
7595
  pendingCheckoutMutationsByProject.clear();
7491
7596
  completedCheckoutLockOwners.clear();
7492
7597
  _test_exports.beforeTerminalClear = undefined;
7598
+ _test_exports.beforeAbortClear = undefined;
7493
7599
  _test_exports.beforePrFeedbackTransitionLock = undefined;
7494
7600
  _test_exports.beforePrFeedbackTrackingSwitch = undefined;
7495
7601
  _test_exports.afterPrFeedbackTrackingSwitch = undefined;
@@ -7506,6 +7612,7 @@ var _test_exports = {
7506
7612
  _test_exports.classifyPrWorkflowGitStateAsync = classifyPrWorkflowGitState;
7507
7613
  },
7508
7614
  beforeTerminalClear: undefined,
7615
+ beforeAbortClear: undefined,
7509
7616
  beforePrFeedbackTransitionLock: undefined,
7510
7617
  beforePrFeedbackTrackingSwitch: undefined,
7511
7618
  afterPrFeedbackTrackingSwitch: undefined,
@@ -7565,11 +7672,13 @@ var _test_exports = {
7565
7672
  rename: fsp2.rename,
7566
7673
  nowMs: () => Date.now()
7567
7674
  };
7675
+ function noActiveGateError(sessionID) {
7676
+ return new Error(`BLOCKED: no active PR workflow gate for session "${normalizeSessionID(sessionID)}". ` + `The gate is activated by running \`/swarm pr-review <pr-ref>\` (PR_REVIEW) or \`/swarm pr-feedback <pr-ref>\` (PR_FEEDBACK), ` + `or by the first dispatch_lanes_async call with mode "swarm-pr-review:*" / "swarm-pr-feedback:*".`);
7677
+ }
7568
7678
  async function requireAnyActiveState(directory, sessionID) {
7569
7679
  const state = await readPrWorkflowGateState(directory, sessionID);
7570
- if (!state) {
7571
- throw new Error(`BLOCKED: no active PR workflow gate for session "${normalizeSessionID(sessionID)}". ` + `The gate is activated by running \`/swarm pr-review <pr-ref>\` (PR_REVIEW) or \`/swarm pr-feedback <pr-ref>\` (PR_FEEDBACK), ` + `or by the first dispatch_lanes_async call with mode "swarm-pr-review:*" / "swarm-pr-feedback:*".`);
7572
- }
7680
+ if (!state)
7681
+ throw noActiveGateError(sessionID);
7573
7682
  return state;
7574
7683
  }
7575
7684
  async function requireBoundState(directory, sessionID, expectedMode) {
@@ -9263,6 +9372,76 @@ async function readPrWorkflowGateStateFileFromDisk(filePath, stateLabel) {
9263
9372
  }
9264
9373
  return parsed.data;
9265
9374
  }
9375
+ var MAX_SALVAGED_SCHEMA_ERRORS = 10;
9376
+ var MAX_SALVAGED_SCHEMA_ERROR_CHARS = 240;
9377
+ function boundSalvagedSchemaError(message) {
9378
+ return message.length <= MAX_SALVAGED_SCHEMA_ERROR_CHARS ? message : `${message.slice(0, MAX_SALVAGED_SCHEMA_ERROR_CHARS - 1)}\u2026`;
9379
+ }
9380
+ async function readPrWorkflowGateStateForRecovery(directory, sessionID) {
9381
+ const normalizedSessionID = normalizeSessionID(sessionID);
9382
+ const filePath = workflowGateStatePath(directory, normalizedSessionID);
9383
+ let raw;
9384
+ try {
9385
+ raw = await fsp2.readFile(filePath, "utf-8");
9386
+ } catch (error2) {
9387
+ if (error2.code === "ENOENT")
9388
+ return null;
9389
+ throw error2;
9390
+ }
9391
+ let parsedJson;
9392
+ try {
9393
+ parsedJson = JSON.parse(raw);
9394
+ } catch {
9395
+ throw new Error(`BLOCKED: PR workflow gate state for session "${normalizedSessionID}" is not valid JSON`);
9396
+ }
9397
+ const parsed = PrWorkflowGateStateSchema.safeParse(parsedJson);
9398
+ if (parsed.success) {
9399
+ return {
9400
+ state: parsed.data,
9401
+ salvaged: false,
9402
+ schemaErrors: [],
9403
+ revisionSalvageable: true,
9404
+ armedShapeUnreadable: false
9405
+ };
9406
+ }
9407
+ const invalidError = new Error(`BLOCKED: PR workflow gate state for session "${normalizedSessionID}" is invalid`);
9408
+ if (typeof parsedJson !== "object" || parsedJson === null || Array.isArray(parsedJson)) {
9409
+ throw invalidError;
9410
+ }
9411
+ const rawRecord = parsedJson;
9412
+ const salvagedSessionID = exports_external.string().min(1).safeParse(rawRecord.sessionID);
9413
+ const salvagedMode = exports_external.enum(["PR_REVIEW", "PR_FEEDBACK"]).safeParse(rawRecord.mode);
9414
+ if (!salvagedSessionID.success || !salvagedMode.success)
9415
+ throw invalidError;
9416
+ const salvagedRevision = exports_external.number().int().nonnegative().safeParse(rawRecord.revision);
9417
+ const salvagedHead = exports_external.string().min(1).safeParse(rawRecord.prHeadSha);
9418
+ const salvagedActivatedAt = exports_external.string().min(1).safeParse(rawRecord.activatedAt);
9419
+ const salvagedUpdatedAt = exports_external.string().min(1).safeParse(rawRecord.updatedAt);
9420
+ const armedKeyPresent = rawRecord.prFeedbackReadyToPublish !== undefined;
9421
+ const salvagedArmed = PrFeedbackReadyToPublishRecordSchema.safeParse(rawRecord.prFeedbackReadyToPublish);
9422
+ const salvagedCheckoutRecovery = PrWorkflowCheckoutRecoveryRecordSchema.safeParse(rawRecord.checkoutRecovery);
9423
+ const armedShapeUnreadable = armedKeyPresent && !salvagedArmed.success;
9424
+ const schemaErrors = parsed.error.issues.slice(0, MAX_SALVAGED_SCHEMA_ERRORS).map((issue) => boundSalvagedSchemaError(`${issue.path.join(".") || "(root)"}: ${issue.message}`));
9425
+ const disclosure = `DEGRADED: PR workflow gate state for session "${normalizedSessionID}" failed schema validation ` + `and was SALVAGED for recovery only (abort/status; write and completion paths still refuse it). ` + `Schema errors: ${schemaErrors.join("; ")}.` + (salvagedRevision.success ? "" : " state revision unsalvageable.") + (armedShapeUnreadable ? " prFeedbackReadyToPublish is present but unreadable; treated as ARMED (fail-closed)." : "");
9426
+ return {
9427
+ state: {
9428
+ schemaVersion: GATE_SCHEMA_VERSION,
9429
+ revision: salvagedRevision.success ? salvagedRevision.data : 0,
9430
+ sessionID: salvagedSessionID.data,
9431
+ mode: salvagedMode.data,
9432
+ activatedAt: salvagedActivatedAt.success ? salvagedActivatedAt.data : isoNow(),
9433
+ updatedAt: salvagedUpdatedAt.success ? salvagedUpdatedAt.data : isoNow(),
9434
+ ...salvagedHead.success ? { prHeadSha: salvagedHead.data } : {},
9435
+ ...salvagedArmed.success ? { prFeedbackReadyToPublish: salvagedArmed.data } : {},
9436
+ ...salvagedCheckoutRecovery.success ? { checkoutRecovery: salvagedCheckoutRecovery.data } : {}
9437
+ },
9438
+ salvaged: true,
9439
+ schemaErrors,
9440
+ disclosure,
9441
+ revisionSalvageable: salvagedRevision.success,
9442
+ armedShapeUnreadable
9443
+ };
9444
+ }
9266
9445
  function rememberState(directory, state) {
9267
9446
  const cacheKey = stateCacheKey(directory, state.sessionID);
9268
9447
  trackedStatesByProjectSession.delete(cacheKey);
@@ -14931,7 +15110,7 @@ function planMerges(active, threshold, maxComparisons, maxMerges) {
14931
15110
  };
14932
15111
  }
14933
15112
  async function sweepActiveNearDuplicates(directory, options = {}) {
14934
- const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-mnj0ter5.js");
15113
+ const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-8xertnqz.js");
14935
15114
  const { config } = loadPluginConfigWithMeta2(directory);
14936
15115
  const sweepConfig = config.learning?.dedup_sweep;
14937
15116
  if (sweepConfig?.enabled === false)
@@ -16015,7 +16194,7 @@ async function runCuratorPhase(directory, phase, agentsDispatched, config, knowl
16015
16194
  }
16016
16195
  if (config.skill_generation_enabled === true && skillCandidates.length > 0) {
16017
16196
  try {
16018
- const skillModule = await import("./skill-generator-khaw3jjw.js");
16197
+ const skillModule = await import("./skill-generator-4d2t5gem.js");
16019
16198
  for (const cand of skillCandidates) {
16020
16199
  if (cand.confidence < (config.min_skill_confidence ?? DEFAULT_SKILL_MIN_CONFIDENCE)) {
16021
16200
  continue;
@@ -16475,7 +16654,7 @@ async function applyCuratorKnowledgeUpdates(directory, recommendations, knowledg
16475
16654
  } catch {}
16476
16655
  }
16477
16656
  if (contradictedEntries.length > 0 && knowledgeConfig.contradiction_threshold_action === "quarantine") {
16478
- const { maybeQuarantineOnContradiction } = await import("./knowledge-escalator-1g4p844a.js");
16657
+ const { maybeQuarantineOnContradiction } = await import("./knowledge-escalator-rmy3jcx4.js");
16479
16658
  for (const { id } of contradictedEntries) {
16480
16659
  try {
16481
16660
  await maybeQuarantineOnContradiction(directory, id, knowledgeConfig.contradiction_quarantine_threshold, knowledgeConfig.contradiction_quarantine_window_days);
@@ -17294,7 +17473,7 @@ async function runCuratorPostMortem(directory, options = {}) {
17294
17473
  warnings.push("Failed to collect knowledge summary.");
17295
17474
  }
17296
17475
  try {
17297
- const { getScanStatus } = await import("./scan-cursor-qvky2yem.js");
17476
+ const { getScanStatus } = await import("./scan-cursor-ahgm4f5p.js");
17298
17477
  const scanStatus = await getScanStatus(directory);
17299
17478
  if (scanStatus.remaining_estimate > 0) {
17300
17479
  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.`);
@@ -17466,9 +17645,9 @@ var _internals23 = {
17466
17645
  verifyPostMortemKnowledgeActions,
17467
17646
  repairPostMortemActions,
17468
17647
  loadDefaultKnowledgeConfig: async (directory) => {
17469
- const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-wgb37f83.js");
17648
+ const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-epdq7ykx.js");
17470
17649
  try {
17471
- const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-mnj0ter5.js");
17650
+ const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-8xertnqz.js");
17472
17651
  const loaded = loadPluginConfigWithMeta2(directory);
17473
17652
  return KnowledgeConfigSchema2.parse(loaded.config.knowledge ?? {});
17474
17653
  } catch {
@@ -17476,11 +17655,11 @@ var _internals23 = {
17476
17655
  }
17477
17656
  },
17478
17657
  applyCuratorKnowledgeUpdates: async (directory, recommendations, knowledgeConfig, generation) => {
17479
- const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-e2sp925h.js");
17658
+ const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-v97jnwn2.js");
17480
17659
  return applyCuratorKnowledgeUpdates2(directory, recommendations, knowledgeConfig, generation);
17481
17660
  },
17482
17661
  checkHivePromotions: async (entries, knowledgeConfig, directory) => {
17483
- const { checkHivePromotions } = await import("./hive-promoter-cw08380z.js");
17662
+ const { checkHivePromotions } = await import("./hive-promoter-vwq1dbh1.js");
17484
17663
  return checkHivePromotions(entries, knowledgeConfig, directory);
17485
17664
  },
17486
17665
  applyProposalTriage: async (directory, triage) => {
@@ -17489,7 +17668,7 @@ var _internals23 = {
17489
17668
  activateProposal,
17490
17669
  listSkills: listSkills2,
17491
17670
  sanitizeSlug
17492
- } = await import("./skill-generator-khaw3jjw.js");
17671
+ } = await import("./skill-generator-4d2t5gem.js");
17493
17672
  const result = {
17494
17673
  approved: [],
17495
17674
  rejected: [],
@@ -18825,9 +19004,9 @@ function hashContent(content) {
18825
19004
  return createHash7("sha1").update(content).digest("hex");
18826
19005
  }
18827
19006
  async function loadConfigForPolicyCurator(directory) {
18828
- const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-wgb37f83.js");
19007
+ const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-epdq7ykx.js");
18829
19008
  try {
18830
- const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-mnj0ter5.js");
19009
+ const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-8xertnqz.js");
18831
19010
  const { config: loadedConfig } = loadPluginConfigWithMeta2(directory);
18832
19011
  return KnowledgeConfigSchema2.parse(loadedConfig.knowledge ?? {});
18833
19012
  } catch {
@@ -27267,7 +27446,11 @@ var ARCHIVE_ARTIFACTS = [
27267
27446
  "session-reflection.md",
27268
27447
  "spec.md",
27269
27448
  "spec-staleness.json",
27270
- "spec-snapshot.md"
27449
+ "spec-snapshot.md",
27450
+ "background-delegations.jsonl",
27451
+ "background-delegations.checkpoint.json",
27452
+ "background-delegations.manifest.json",
27453
+ "background-delegations-health.json"
27271
27454
  ];
27272
27455
  var ACTIVE_STATE_TO_CLEAN = [
27273
27456
  "plan.json",
@@ -27669,7 +27852,7 @@ async function runFinalizeStage(ctx) {
27669
27852
  }
27670
27853
  }
27671
27854
  try {
27672
- const { CuratorConfigSchema: CCS } = await import("./schema-wgb37f83.js");
27855
+ const { CuratorConfigSchema: CCS } = await import("./schema-epdq7ykx.js");
27673
27856
  const { config: pmLoadedConfig } = _internals36.loadPluginConfigWithMeta(ctx.directory);
27674
27857
  const curatorCfg = CCS.parse(pmLoadedConfig.curator ?? {});
27675
27858
  if (curatorCfg.enabled && curatorCfg.postmortem_enabled) {
@@ -29947,9 +30130,9 @@ var _internals41 = {
29947
30130
  loadPluginConfigWithMeta,
29948
30131
  loadCuratorDeps: async () => {
29949
30132
  const [{ CuratorConfigSchema }, curator, { createCuratorLLMDelegate: createCuratorLLMDelegate2 }] = await Promise.all([
29950
- import("./schema-wgb37f83.js"),
29951
- import("./curator-e2sp925h.js"),
29952
- import("./curator-llm-factory-xsg7wesn.js")
30133
+ import("./schema-epdq7ykx.js"),
30134
+ import("./curator-v97jnwn2.js"),
30135
+ import("./curator-llm-factory-fyjmgxyp.js")
29953
30136
  ]);
29954
30137
  return { CuratorConfigSchema, curator, createCuratorLLMDelegate: createCuratorLLMDelegate2 };
29955
30138
  }
@@ -30854,7 +31037,7 @@ async function computeCurationDiagnostics(directory, entries) {
30854
31037
  let scanCompleted = false;
30855
31038
  let scanRemaining = 0;
30856
31039
  try {
30857
- const { getScanStatus } = await import("./scan-cursor-qvky2yem.js");
31040
+ const { getScanStatus } = await import("./scan-cursor-ahgm4f5p.js");
30858
31041
  const status = await getScanStatus(directory);
30859
31042
  scanGeneration = status.generation;
30860
31043
  scanCompleted = status.completed;
@@ -30864,10 +31047,10 @@ async function computeCurationDiagnostics(directory, entries) {
30864
31047
  try {
30865
31048
  const { isLinked: isLinked2 } = await import("./knowledge-link-fn5j3r4q.js");
30866
31049
  if (isLinked2(directory)) {
30867
- const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-wgb37f83.js");
31050
+ const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-epdq7ykx.js");
30868
31051
  let config;
30869
31052
  try {
30870
- const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-mnj0ter5.js");
31053
+ const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-8xertnqz.js");
30871
31054
  const loaded = loadPluginConfigWithMeta2(directory);
30872
31055
  config = KnowledgeConfigSchema2.parse(loaded.config.knowledge ?? {});
30873
31056
  } catch {
@@ -32085,7 +32268,7 @@ async function handleDoctorCommand(directory, args) {
32085
32268
  const result = runConfigDoctor(config, directory);
32086
32269
  let output;
32087
32270
  if (enableAutoFix && result.hasAutoFixableIssues) {
32088
- const { runConfigDoctorWithFixes } = await import("./config-doctor-y8wfw196.js");
32271
+ const { runConfigDoctorWithFixes } = await import("./config-doctor-7gy47evn.js");
32089
32272
  const fixResult = await runConfigDoctorWithFixes(directory, config, true, {
32090
32273
  applyLossy: true
32091
32274
  });
@@ -32922,7 +33105,7 @@ async function handleEvidenceCommand(directory, args) {
32922
33105
  return formatTaskEvidenceMarkdown(evidenceData);
32923
33106
  }
32924
33107
  async function handleEvidenceSummaryCommand(directory) {
32925
- const { buildEvidenceSummary } = await import("./evidence-summary-service-pfppq7mv.js");
33108
+ const { buildEvidenceSummary } = await import("./evidence-summary-service-79mtxzhd.js");
32926
33109
  const artifact = await buildEvidenceSummary(directory);
32927
33110
  if (!artifact) {
32928
33111
  return "No plan found. Run `/swarm plan` to check plan status.";
@@ -32957,12 +33140,13 @@ async function handleEvidenceSummaryCommand(directory) {
32957
33140
  `);
32958
33141
  }
32959
33142
  // src/services/export-service.ts
33143
+ init_package();
32960
33144
  async function getExportData(directory) {
32961
33145
  const planStructured = await loadPlanJsonOnly(directory);
32962
33146
  const planContent = await readSwarmFileAsync(directory, "plan.md");
32963
33147
  const contextContent = await readSwarmFileAsync(directory, "context.md");
32964
33148
  return {
32965
- version: "4.5.0",
33149
+ version: package_default.version,
32966
33150
  exported: new Date().toISOString(),
32967
33151
  plan: planStructured || planContent,
32968
33152
  context: contextContent,
@@ -43175,6 +43359,7 @@ var _internals63 = {
43175
43359
  };
43176
43360
 
43177
43361
  // src/services/preflight-service.ts
43362
+ init_zod();
43178
43363
  import * as fs33 from "fs";
43179
43364
  import * as path78 from "path";
43180
43365
 
@@ -48546,6 +48731,15 @@ async function runEvidenceCheck(dir) {
48546
48731
  };
48547
48732
  }
48548
48733
  }
48734
+ var ReqCoverageReportSchema = exports_external.object({
48735
+ success: exports_external.boolean(),
48736
+ phase: exports_external.number().int().nonnegative(),
48737
+ totalRequirements: exports_external.number().int().nonnegative(),
48738
+ coveredCount: exports_external.number().int().nonnegative(),
48739
+ missingCount: exports_external.number().int().nonnegative(),
48740
+ requirements: exports_external.array(exports_external.unknown())
48741
+ });
48742
+ var REQ_COVERAGE_MAX_JSON_BYTES = 500 * 1024;
48549
48743
  async function runRequirementCoverageCheck(dir, currentPhase) {
48550
48744
  const startTime = Date.now();
48551
48745
  try {
@@ -48559,20 +48753,156 @@ async function runRequirementCoverageCheck(dir, currentPhase) {
48559
48753
  };
48560
48754
  }
48561
48755
  const coverage = await checkRequirementCoverage(currentPhase, dir);
48562
- if (coverage.exists) {
48756
+ if (!coverage.exists) {
48563
48757
  return {
48564
48758
  type: "req_coverage",
48565
- status: "pass",
48566
- message: "Requirement coverage report found",
48759
+ status: "fail",
48760
+ message: "Requirement coverage report missing but effective spec exists",
48761
+ details: { expectedPath: coverage.path },
48762
+ durationMs: Date.now() - startTime
48763
+ };
48764
+ }
48765
+ let raw;
48766
+ try {
48767
+ const stat7 = await fs33.promises.stat(coverage.path);
48768
+ if (stat7.size > REQ_COVERAGE_MAX_JSON_BYTES) {
48769
+ return {
48770
+ type: "req_coverage",
48771
+ status: "fail",
48772
+ message: `Requirement coverage report exceeds ${REQ_COVERAGE_MAX_JSON_BYTES} byte cap and cannot be validated`,
48773
+ details: { path: coverage.path, sizeBytes: stat7.size },
48774
+ durationMs: Date.now() - startTime
48775
+ };
48776
+ }
48777
+ raw = await fs33.promises.readFile(coverage.path, "utf-8");
48778
+ } catch (readError) {
48779
+ return {
48780
+ type: "req_coverage",
48781
+ status: "fail",
48782
+ message: `Requirement coverage report unreadable: ${readError instanceof Error ? readError.message : String(readError)}`,
48783
+ details: { path: coverage.path },
48784
+ durationMs: Date.now() - startTime
48785
+ };
48786
+ }
48787
+ const trimmed = raw.trim();
48788
+ if (trimmed.length === 0) {
48789
+ return {
48790
+ type: "req_coverage",
48791
+ status: "fail",
48792
+ message: "Requirement coverage report is empty",
48793
+ details: { path: coverage.path },
48794
+ durationMs: Date.now() - startTime
48795
+ };
48796
+ }
48797
+ let parsed;
48798
+ try {
48799
+ parsed = JSON.parse(trimmed);
48800
+ } catch (parseError) {
48801
+ const parseErrorMessage = parseError instanceof Error ? parseError.message : String(parseError);
48802
+ return {
48803
+ type: "req_coverage",
48804
+ status: "fail",
48805
+ message: `Requirement coverage report is not valid JSON: ${parseErrorMessage}`,
48806
+ details: { path: coverage.path },
48807
+ durationMs: Date.now() - startTime
48808
+ };
48809
+ }
48810
+ const report = ReqCoverageReportSchema.safeParse(parsed);
48811
+ if (!report.success) {
48812
+ return {
48813
+ type: "req_coverage",
48814
+ status: "fail",
48815
+ message: "Requirement coverage report does not match the expected report shape",
48567
48816
  details: { path: coverage.path },
48568
48817
  durationMs: Date.now() - startTime
48569
48818
  };
48570
48819
  }
48820
+ const {
48821
+ success,
48822
+ phase,
48823
+ totalRequirements,
48824
+ coveredCount,
48825
+ missingCount,
48826
+ requirements
48827
+ } = report.data;
48828
+ if (!success) {
48829
+ return {
48830
+ type: "req_coverage",
48831
+ status: "fail",
48832
+ message: "Requirement coverage report indicates the coverage run itself failed (success: false)",
48833
+ details: { path: coverage.path },
48834
+ durationMs: Date.now() - startTime
48835
+ };
48836
+ }
48837
+ if (phase !== currentPhase) {
48838
+ return {
48839
+ type: "req_coverage",
48840
+ status: "fail",
48841
+ message: `Requirement coverage report phase (${phase}) does not match the current phase (${currentPhase})`,
48842
+ details: { path: coverage.path, reportPhase: phase, currentPhase },
48843
+ durationMs: Date.now() - startTime
48844
+ };
48845
+ }
48846
+ if (totalRequirements === 0) {
48847
+ return {
48848
+ type: "req_coverage",
48849
+ status: "fail",
48850
+ message: "Requirement coverage report contains no requirements (totalRequirements is 0) but effective spec exists",
48851
+ details: { path: coverage.path, totalRequirements },
48852
+ durationMs: Date.now() - startTime
48853
+ };
48854
+ }
48855
+ if (coveredCount + missingCount !== totalRequirements) {
48856
+ return {
48857
+ type: "req_coverage",
48858
+ status: "fail",
48859
+ message: `Requirement coverage report counts are inconsistent: coveredCount (${coveredCount}) + missingCount (${missingCount}) !== totalRequirements (${totalRequirements})`,
48860
+ details: {
48861
+ path: coverage.path,
48862
+ totalRequirements,
48863
+ coveredCount,
48864
+ missingCount
48865
+ },
48866
+ durationMs: Date.now() - startTime
48867
+ };
48868
+ }
48869
+ if (requirements.length !== totalRequirements) {
48870
+ return {
48871
+ type: "req_coverage",
48872
+ status: "fail",
48873
+ message: `Requirement coverage report requirements array length (${requirements.length}) does not match totalRequirements (${totalRequirements})`,
48874
+ details: {
48875
+ path: coverage.path,
48876
+ totalRequirements,
48877
+ requirementsLength: requirements.length
48878
+ },
48879
+ durationMs: Date.now() - startTime
48880
+ };
48881
+ }
48882
+ if (missingCount > 0) {
48883
+ return {
48884
+ type: "req_coverage",
48885
+ status: "fail",
48886
+ message: `Requirement coverage report has ${missingCount} uncovered requirement(s)`,
48887
+ details: {
48888
+ path: coverage.path,
48889
+ totalRequirements,
48890
+ coveredCount,
48891
+ missingCount
48892
+ },
48893
+ durationMs: Date.now() - startTime
48894
+ };
48895
+ }
48571
48896
  return {
48572
48897
  type: "req_coverage",
48573
- status: "fail",
48574
- message: "Requirement coverage report missing but effective spec exists",
48575
- details: { expectedPath: coverage.path },
48898
+ status: "pass",
48899
+ message: `Requirement coverage report found: ${coveredCount}/${totalRequirements} requirement(s) covered`,
48900
+ details: {
48901
+ path: coverage.path,
48902
+ totalRequirements,
48903
+ coveredCount,
48904
+ missingCount
48905
+ },
48576
48906
  durationMs: Date.now() - startTime
48577
48907
  };
48578
48908
  } catch (error2) {
@@ -56157,11 +56487,11 @@ async function handleSpecifyCommand(_directory, args) {
56157
56487
  }
56158
56488
 
56159
56489
  // src/services/status-service.ts
56160
- init_loader();
56161
- init_schema();
56162
56490
  import * as fsSync3 from "fs";
56163
56491
  import { readFile as readFile23 } from "fs/promises";
56164
56492
  import * as path100 from "path";
56493
+ init_loader();
56494
+ init_schema();
56165
56495
 
56166
56496
  // src/consensus/store.ts
56167
56497
  import { readdir as readdir5, unlink as unlink4 } from "fs/promises";
@@ -56558,6 +56888,15 @@ var _internals85 = {
56558
56888
  getActiveFullAutoSessionID,
56559
56889
  loadFullAutoRunState
56560
56890
  };
56891
+ function formatLedgerBytes(bytes) {
56892
+ if (bytes >= 1024 * 1024) {
56893
+ return `${Math.round(bytes / (1024 * 1024) * 10) / 10} MiB`;
56894
+ }
56895
+ if (bytes >= 1024) {
56896
+ return `${Math.round(bytes / 1024 * 10) / 10} KiB`;
56897
+ }
56898
+ return `${bytes} B`;
56899
+ }
56561
56900
  function readSpecStalenessSnapshot(directory) {
56562
56901
  try {
56563
56902
  const p = path100.join(directory, ".swarm", "spec-staleness.json");
@@ -56675,6 +57014,15 @@ async function getStatusData(directory, agents, sessionId) {
56675
57014
  } catch {
56676
57015
  status.consensusReports = 0;
56677
57016
  }
57017
+ try {
57018
+ status.delegationLedgerHealth = collectDelegationLedgerHealth(directory, {
57019
+ ledgerLimitBytes: MAX_RECOVERY_LEDGER_BYTES,
57020
+ lowWaterBytes: DELEGATION_COMPACTION_LOW_WATER_BYTES,
57021
+ highWaterBytes: DELEGATION_COMPACTION_HIGH_WATER_BYTES
57022
+ }) ?? undefined;
57023
+ } catch {
57024
+ status.delegationLedgerHealth = undefined;
57025
+ }
56678
57026
  try {
56679
57027
  const pointer = readLinkPointer(directory);
56680
57028
  if (pointer) {
@@ -56973,6 +57321,32 @@ function formatStatusMarkdown(status) {
56973
57321
  } else {
56974
57322
  lines.push("", "**Memory Cohort**: local (not linked \u2014 run `/swarm memory link` to share memory across worktrees; requires `memory.link.enabled: true`)");
56975
57323
  }
57324
+ const delegationHealth = status.delegationLedgerHealth;
57325
+ if (delegationHealth) {
57326
+ lines.push("", "**Background Delegations**:");
57327
+ lines.push(` - Ledger tail: ${formatLedgerBytes(delegationHealth.ledger.bytes)} / ${formatLedgerBytes(delegationHealth.ledger.limitBytes)} recovery bound (${delegationHealth.ledger.pressurePct}% \u2014 ${delegationHealth.ledger.band})`);
57328
+ if (delegationHealth.checkpoint) {
57329
+ const checkpoint2 = delegationHealth.checkpoint;
57330
+ lines.push(` - Checkpoint #${checkpoint2.sequence}: ${checkpoint2.liveRecords} live records, ${checkpoint2.closedSummaries} archived summaries (${formatLedgerBytes(checkpoint2.bytes)}, ${new Date(checkpoint2.createdAt).toISOString()})`);
57331
+ } else {
57332
+ lines.push(" - Checkpoint: none (full-history recovery)");
57333
+ }
57334
+ if (delegationHealth.recovery) {
57335
+ const recovery = delegationHealth.recovery;
57336
+ lines.push(` - Recovery: ${recovery.source} (${recovery.ok ? "ok" : `FAILED: ${recovery.reason ?? "uncertain"}`})`);
57337
+ }
57338
+ if (delegationHealth.lastUncertainty) {
57339
+ const uncertainty = delegationHealth.lastUncertainty;
57340
+ lines.push(` - \u26A0 Last uncertainty (${new Date(uncertainty.at).toISOString()}, ${uncertainty.source}): ${uncertainty.reason}`);
57341
+ if (uncertainty.repairHint) {
57342
+ lines.push(` repair: ${uncertainty.repairHint}`);
57343
+ }
57344
+ }
57345
+ const counts = delegationHealth.counts;
57346
+ if (counts.activeOwners > 0 || counts.pendingAdvisories > 0 || counts.lateTerminals > 0 || counts.orphanWorktreeOwners > 0) {
57347
+ lines.push(` - Live set: ${counts.activeOwners} active owners, ${counts.pendingAdvisories} pending advisories, ${counts.lateTerminals} late terminals, ${counts.orphanWorktreeOwners} unsettled worktree owners`);
57348
+ }
57349
+ }
56976
57350
  return lines.join(`
56977
57351
  `);
56978
57352
  }
@@ -56989,6 +57363,33 @@ async function handleStatusCommand(directory, agents, sessionId) {
56989
57363
  `**Spec drift detected**: ${reason} (stored: ${stored}, current: ${current})`,
56990
57364
  "Run `/swarm clarify` to enter spec repair mode. Clarify alone does not clear drift: rewrite the spec so recovery can reconcile it, or run `/swarm acknowledge-spec-drift` to dismiss."
56991
57365
  ].join(`
57366
+ `);
57367
+ }
57368
+ const delegationHealth = statusData.delegationLedgerHealth;
57369
+ if (delegationHealth && (delegationHealth.checkpoint || delegationHealth.recovery || delegationHealth.lastUncertainty || delegationHealth.ledger.band !== "ok" || delegationHealth.counts.activeOwners > 0 || delegationHealth.counts.pendingAdvisories > 0 || delegationHealth.counts.lateTerminals > 0 || delegationHealth.counts.orphanWorktreeOwners > 0)) {
57370
+ const lines = [
57371
+ "No active swarm plan found.",
57372
+ "",
57373
+ "**Background Delegations**:"
57374
+ ];
57375
+ lines.push(` - Ledger tail: ${formatLedgerBytes(delegationHealth.ledger.bytes)} / ${formatLedgerBytes(delegationHealth.ledger.limitBytes)} recovery bound (${delegationHealth.ledger.pressurePct}% \u2014 ${delegationHealth.ledger.band})`);
57376
+ if (delegationHealth.checkpoint) {
57377
+ lines.push(` - Checkpoint #${delegationHealth.checkpoint.sequence} (${delegationHealth.checkpoint.liveRecords} live, ${delegationHealth.checkpoint.closedSummaries} archived)`);
57378
+ }
57379
+ if (delegationHealth.recovery) {
57380
+ lines.push(` - Recovery: ${delegationHealth.recovery.source} (${delegationHealth.recovery.ok ? "ok" : `FAILED: ${delegationHealth.recovery.reason ?? "uncertain"}`})`);
57381
+ }
57382
+ const compactCounts = delegationHealth.counts;
57383
+ if (compactCounts.activeOwners > 0 || compactCounts.pendingAdvisories > 0 || compactCounts.lateTerminals > 0 || compactCounts.orphanWorktreeOwners > 0) {
57384
+ lines.push(` - Live set: ${compactCounts.activeOwners} active owners, ${compactCounts.pendingAdvisories} pending advisories, ${compactCounts.lateTerminals} late terminals, ${compactCounts.orphanWorktreeOwners} unsettled worktree owners`);
57385
+ }
57386
+ if (delegationHealth.lastUncertainty) {
57387
+ lines.push(` - \u26A0 Last uncertainty (${new Date(delegationHealth.lastUncertainty.at).toISOString()}): ${delegationHealth.lastUncertainty.reason}`);
57388
+ if (delegationHealth.lastUncertainty.repairHint) {
57389
+ lines.push(` repair: ${delegationHealth.lastUncertainty.repairHint}`);
57390
+ }
57391
+ }
57392
+ return lines.join(`
56992
57393
  `);
56993
57394
  }
56994
57395
  return "No active swarm plan found.";
@@ -57474,7 +57875,7 @@ function buildDetailedHelp(commandName, entry) {
57474
57875
  async function handleHelpCommand(ctx) {
57475
57876
  const targetCommand = ctx.args.join(" ");
57476
57877
  if (!targetCommand) {
57477
- const { buildHelpText } = await import("./index-1kr1vey5.js");
57878
+ const { buildHelpText } = await import("./index-e70d3xr7.js");
57478
57879
  return buildHelpText();
57479
57880
  }
57480
57881
  const tokens = targetCommand.split(/\s+/);
@@ -57483,7 +57884,7 @@ async function handleHelpCommand(ctx) {
57483
57884
  return _internals87.buildDetailedHelp(resolved.key, resolved.entry);
57484
57885
  }
57485
57886
  const similar = _internals87.findSimilarCommands(targetCommand);
57486
- const { buildHelpText: fullHelp } = await import("./index-1kr1vey5.js");
57887
+ const { buildHelpText: fullHelp } = await import("./index-e70d3xr7.js");
57487
57888
  if (similar.length > 0) {
57488
57889
  return `Command '/swarm ${targetCommand}' not found.
57489
57890
 
@@ -57660,7 +58061,7 @@ var COMMAND_REGISTRY = {
57660
58061
  },
57661
58062
  "guardrail explain": {
57662
58063
  handler: async (ctx) => {
57663
- const { handleGuardrailExplain } = await import("./guardrail-explain-byzmrgg1.js");
58064
+ const { handleGuardrailExplain } = await import("./guardrail-explain-9ry66z5g.js");
57664
58065
  return handleGuardrailExplain(ctx.directory, ctx.args);
57665
58066
  },
57666
58067
  description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
@@ -57670,7 +58071,7 @@ var COMMAND_REGISTRY = {
57670
58071
  },
57671
58072
  "guardrail-explain": {
57672
58073
  handler: async (ctx) => {
57673
- const { handleGuardrailExplain } = await import("./guardrail-explain-byzmrgg1.js");
58074
+ const { handleGuardrailExplain } = await import("./guardrail-explain-9ry66z5g.js");
57674
58075
  return handleGuardrailExplain(ctx.directory, ctx.args);
57675
58076
  },
57676
58077
  description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
@@ -57680,7 +58081,7 @@ var COMMAND_REGISTRY = {
57680
58081
  },
57681
58082
  "guardrail-log": {
57682
58083
  handler: async (ctx) => {
57683
- const { handleGuardrailLog } = await import("./guardrail-log-nr2g7hbw.js");
58084
+ const { handleGuardrailLog } = await import("./guardrail-log-fe6smme1.js");
57684
58085
  return handleGuardrailLog(ctx.directory, ctx.args);
57685
58086
  },
57686
58087
  description: "Read the guardrail decision log (use --blocks-only for blocks)",
@@ -64892,7 +65293,7 @@ function isLaneOwnedByCurrentSession(branchName, expectedSessionId) {
64892
65293
  return extracted === expectedSessionId;
64893
65294
  }
64894
65295
  async function inspectStandardWorktreeCollisionOwnership(identity) {
64895
- const collisionOwnership = await import("./worktree-collision-ownership-bfz3drxm.js");
65296
+ const collisionOwnership = await import("./worktree-collision-ownership-j6d33p49.js");
64896
65297
  return collisionOwnership.inspectStandardWorktreeCollisionOwnership(identity);
64897
65298
  }
64898
65299
  async function precreateStandardWorktreeSession(args) {
@@ -65040,7 +65441,7 @@ async function precreateStandardWorktreeSession(args) {
65040
65441
  const laneProfile = computeLaneRuntimeProfile(worktreeConfig.runtime_isolation, laneIndex, provisionResult.worktreePath);
65041
65442
  if (laneProfile) {
65042
65443
  try {
65043
- const { writeLaneProfileToDiskReal } = await import("./core-zszmexgm.js");
65444
+ const { writeLaneProfileToDiskReal } = await import("./core-cpcspaw5.js");
65044
65445
  await writeLaneProfileToDiskReal(provisionResult.worktreePath, laneProfile.laneIndex, laneProfile.envOverrides);
65045
65446
  } catch {}
65046
65447
  }
@@ -65539,7 +65940,7 @@ async function finishStandardWorktreeDispatch(directory, dispatch, config, callI
65539
65940
  }
65540
65941
  clearWorktreeMergeStatus(statusKey);
65541
65942
  try {
65542
- const { removeLaneProfileFromDiskReal } = await import("./core-zszmexgm.js");
65943
+ const { removeLaneProfileFromDiskReal } = await import("./core-cpcspaw5.js");
65543
65944
  await removeLaneProfileFromDiskReal(dispatch.handle.worktreePath, dispatch.laneIndex);
65544
65945
  } catch {}
65545
65946
  const state = serializationStateBySessionID.get(dispatch.parentSessionID);