opencode-swarm 7.159.1 → 7.159.3

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 (67) hide show
  1. package/.opencode/skills/engineering-conventions/SKILL.md +20 -0
  2. package/.opencode/skills/execute/SKILL.md +2 -2
  3. package/dist/cli/{coder-settlement-d89tqam8.js → coder-settlement-50p7dsya.js} +6 -6
  4. package/dist/cli/{config-doctor-8zawz3qh.js → config-doctor-a7drgs33.js} +2 -2
  5. package/dist/cli/{core-pp64ys5v.js → core-madqgdsc.js} +1 -1
  6. package/dist/cli/{curation-policy-2gq8307w.js → curation-policy-ray8h55z.js} +4 -4
  7. package/dist/cli/{curator-mpqpbr0r.js → curator-3sz7refy.js} +28 -28
  8. package/dist/cli/{curator-llm-factory-m3yw6sn5.js → curator-llm-factory-pyp5kmra.js} +28 -28
  9. package/dist/cli/{evidence-summary-service-qaq1eba9.js → evidence-summary-service-cwyjkdsa.js} +10 -10
  10. package/dist/cli/{gate-evidence-r0c71n04.js → gate-evidence-95k5ap1z.js} +4 -4
  11. package/dist/cli/{guardrail-explain-5z64w3ah.js → guardrail-explain-a13kbmrt.js} +29 -29
  12. package/dist/cli/{guardrail-log-f9nf687y.js → guardrail-log-nerqk9qb.js} +3 -3
  13. package/dist/cli/{guardrail-reset-yjwk20rb.js → guardrail-reset-chbc0mep.js} +28 -28
  14. package/dist/cli/{hive-promoter-zjtgbh4w.js → hive-promoter-4rtxhw7n.js} +28 -28
  15. package/dist/cli/{index-54pkyasv.js → index-2fq4a3vk.js} +1 -1
  16. package/dist/cli/{index-bea260ta.js → index-2jzmg2km.js} +6 -6
  17. package/dist/cli/{index-3scbg6n2.js → index-40t6s98s.js} +2 -2
  18. package/dist/cli/{index-1qpagg2t.js → index-515nwvdp.js} +1 -1
  19. package/dist/cli/{index-yw26j0q7.js → index-5hfqc3h3.js} +5 -5
  20. package/dist/cli/{index-60mzwj91.js → index-6jp5yxye.js} +1 -1
  21. package/dist/cli/{index-6z53bew2.js → index-8fyebh3w.js} +1 -1
  22. package/dist/cli/{index-9fphcxes.js → index-8zw60wya.js} +1 -1
  23. package/dist/cli/{index-a5w29k1t.js → index-9qw4sbg1.js} +3 -3
  24. package/dist/cli/{index-k6y6btb6.js → index-bxpqq9th.js} +1 -1
  25. package/dist/cli/{index-wae55z9w.js → index-ebxmfr4j.js} +1 -1
  26. package/dist/cli/{index-gprxjmm7.js → index-ebz97mks.js} +3 -1
  27. package/dist/cli/{index-gkw7kq6z.js → index-fnxmg8sz.js} +5 -5
  28. package/dist/cli/{index-zxkv8x5n.js → index-gk6gpe7r.js} +1 -1
  29. package/dist/cli/{index-4k9pqbxw.js → index-h96xp4t0.js} +1 -1
  30. package/dist/cli/{index-4nc9npx5.js → index-m9m3emns.js} +2 -2
  31. package/dist/cli/{index-ve3v09kq.js → index-mqfs5f8a.js} +1 -1
  32. package/dist/cli/{index-g6d8xam2.js → index-nhhek8yw.js} +1 -1
  33. package/dist/cli/{index-9yxyc1gb.js → index-nvz4mp5w.js} +4 -4
  34. package/dist/cli/{index-8819vcke.js → index-p3ym3y8b.js} +4 -4
  35. package/dist/cli/{index-2z00wqvb.js → index-qxpfmryw.js} +4 -4
  36. package/dist/cli/{index-zmc8mm7v.js → index-rq4jcw64.js} +2 -2
  37. package/dist/cli/{index-36sgq7n9.js → index-sn6mtxxc.js} +30 -30
  38. package/dist/cli/{index-7yg4ypyg.js → index-t3wk7q51.js} +1 -1
  39. package/dist/cli/{index-86dvzyac.js → index-txwx9p21.js} +241 -91
  40. package/dist/cli/{index-wttqayp1.js → index-v3ybemb1.js} +2 -2
  41. package/dist/cli/{index-v3jy0tc6.js → index-ve0xj03m.js} +1 -1
  42. package/dist/cli/{index-f3yphmk6.js → index-wwpe4am7.js} +5 -5
  43. package/dist/cli/{index-29wav1x0.js → index-xqjhbfbx.js} +4 -4
  44. package/dist/cli/{index-tvz43tea.js → index-xs32znyz.js} +1 -1
  45. package/dist/cli/{index-3rcqxbwt.js → index-y2d381ce.js} +1 -1
  46. package/dist/cli/{index-bz7ayg01.js → index-zswy6xgb.js} +3 -3
  47. package/dist/cli/index.js +28 -28
  48. package/dist/cli/{knowledge-escalator-585m4927.js → knowledge-escalator-f80n84ch.js} +10 -10
  49. package/dist/cli/{knowledge-events-ssegqfmy.js → knowledge-events-1d7v2krw.js} +8 -8
  50. package/dist/cli/{knowledge-link-a9fafeb3.js → knowledge-link-vm4caewt.js} +3 -3
  51. package/dist/cli/{knowledge-store-nznky6cv.js → knowledge-store-66yxeet7.js} +4 -4
  52. package/dist/cli/{knowledge-validator-3byea8gp.js → knowledge-validator-p0xcx7jx.js} +6 -6
  53. package/dist/cli/{pending-delegations-qrjq3s29.js → pending-delegations-vad1z71d.js} +1 -1
  54. package/dist/cli/{pr-review-reentry-authorization-w8ja0m2p.js → pr-review-reentry-authorization-kn3nny7h.js} +28 -28
  55. package/dist/cli/{pr-subscriptions-fvmey1x6.js → pr-subscriptions-482gzvt6.js} +2 -2
  56. package/dist/cli/{runner-atbehryj.js → runner-sn7a6zd0.js} +4 -4
  57. package/dist/cli/{scan-cursor-kv9scb2v.js → scan-cursor-2v7995nb.js} +5 -5
  58. package/dist/cli/{schema-a7f88yc3.js → schema-dy8fqycb.js} +1 -1
  59. package/dist/cli/{scope-persistence-x6de46s4.js → scope-persistence-baty62vx.js} +5 -5
  60. package/dist/cli/{skill-generator-vwcrfrw3.js → skill-generator-nwrvtqbz.js} +12 -12
  61. package/dist/cli/{worktree-collision-ownership-7kf9mm5z.js → worktree-collision-ownership-cy24p5mr.js} +3 -3
  62. package/dist/cli/{worktree-isolation-6zh5bxrd.js → worktree-isolation-8jbx0s8d.js} +28 -28
  63. package/dist/config/evidence-schema.d.ts +51 -0
  64. package/dist/index.js +7 -7
  65. package/dist/tools/sast-baseline.d.ts +120 -3
  66. package/dist/tools/sast-scan.d.ts +25 -1
  67. package/package.json +1 -1
@@ -6,7 +6,7 @@ import {
6
6
  resolveExecutableFromPath,
7
7
  runEvaluation,
8
8
  runExternalTool
9
- } from "./index-tvz43tea.js";
9
+ } from "./index-xs32znyz.js";
10
10
  import {
11
11
  finalizeShellAuditForClose,
12
12
  isPolicyProtectedPath,
@@ -15,13 +15,13 @@ import {
15
15
  protectedRoots,
16
16
  redactDecisionLineForArchive,
17
17
  stableCanonicalStringify
18
- } from "./index-9fphcxes.js";
18
+ } from "./index-8zw60wya.js";
19
19
  import {
20
20
  detectStraySwarmDirs,
21
21
  readDoctorArtifact,
22
22
  removeStraySwarmDir,
23
23
  runConfigDoctor
24
- } from "./index-60mzwj91.js";
24
+ } from "./index-6jp5yxye.js";
25
25
  import {
26
26
  MAX_TRANSIENT_RETRIES,
27
27
  archiveEvidence,
@@ -68,7 +68,7 @@ import {
68
68
  validateProjectRoot,
69
69
  validateSymlinkBoundary,
70
70
  validateTargetWithinRoot
71
- } from "./index-f3yphmk6.js";
71
+ } from "./index-wwpe4am7.js";
72
72
  import {
73
73
  EvaluationTaskV1Schema,
74
74
  GateAuditManifestV1Schema,
@@ -85,7 +85,7 @@ import {
85
85
  saveGateAuditResult,
86
86
  savePromotionDecision,
87
87
  saveTaskSetSnapshot
88
- } from "./index-zxkv8x5n.js";
88
+ } from "./index-gk6gpe7r.js";
89
89
  import {
90
90
  canonicalHash,
91
91
  canonicalJson,
@@ -129,15 +129,15 @@ import {
129
129
  retireSkill,
130
130
  selectCandidateEntries,
131
131
  syncBundledProjectSkillsIfMissingAsync
132
- } from "./index-29wav1x0.js";
132
+ } from "./index-xqjhbfbx.js";
133
133
  import {
134
134
  readRecentEscalations
135
- } from "./index-gkw7kq6z.js";
135
+ } from "./index-fnxmg8sz.js";
136
136
  import {
137
137
  alreadyCuratedThisGeneration,
138
138
  claimNextScanBatch,
139
139
  resolveCohortId
140
- } from "./index-4nc9npx5.js";
140
+ } from "./index-m9m3emns.js";
141
141
  import {
142
142
  CURATOR_INIT_PROMPT,
143
143
  CURATOR_PHASE_PROMPT,
@@ -161,7 +161,7 @@ import {
161
161
  listActive,
162
162
  subscribe,
163
163
  unsubscribe
164
- } from "./index-1qpagg2t.js";
164
+ } from "./index-515nwvdp.js";
165
165
  import {
166
166
  clearWorktreeMergeStatus,
167
167
  getAllWorktreeMergeFailures,
@@ -173,7 +173,7 @@ import {
173
173
  listCoderSettlementWalStates,
174
174
  recoverCoderSettlement,
175
175
  recoverStaleCoderSettlements
176
- } from "./index-9yxyc1gb.js";
176
+ } from "./index-nvz4mp5w.js";
177
177
  import {
178
178
  parsePorcelainV2Snapshot,
179
179
  resolveCommitCountSince,
@@ -206,7 +206,7 @@ import {
206
206
  WORKTREE_LIFECYCLE_LOCK_FILE,
207
207
  recordWorktreeProvisioningOwner,
208
208
  removeWorktreeProvisioningOwner
209
- } from "./index-6z53bew2.js";
209
+ } from "./index-8fyebh3w.js";
210
210
  import {
211
211
  appendUnactionable,
212
212
  quarantineEntry,
@@ -217,11 +217,11 @@ import {
217
217
  validateActionableFields,
218
218
  validateLesson,
219
219
  validateSkillPath
220
- } from "./index-8819vcke.js";
220
+ } from "./index-p3ym3y8b.js";
221
221
  import {
222
222
  authorizeCuration,
223
223
  buildConfigFingerprintInput
224
- } from "./index-54pkyasv.js";
224
+ } from "./index-2fq4a3vk.js";
225
225
  import {
226
226
  cohortConfigFingerprint
227
227
  } from "./index-rtry5xyf.js";
@@ -252,12 +252,12 @@ import {
252
252
  transitionTaskWorkflowEvidence,
253
253
  withTaskEvidenceTransaction,
254
254
  writeWorkflowWalFile
255
- } from "./index-zmc8mm7v.js";
255
+ } from "./index-rq4jcw64.js";
256
256
  import {
257
257
  makeWorktreeBranchName,
258
258
  provisionWorktree,
259
259
  removeWorktree
260
- } from "./index-ve3v09kq.js";
260
+ } from "./index-mqfs5f8a.js";
261
261
  import {
262
262
  DEFAULT_STALE_DELEGATION_TIMEOUT_MS,
263
263
  DELEGATION_COMPACTION_HIGH_WATER_BYTES,
@@ -272,7 +272,7 @@ import {
272
272
  scanBackgroundCoderReservationsForAdmission,
273
273
  scanDelegationsForRecovery,
274
274
  sweepStaleDelegations
275
- } from "./index-4k9pqbxw.js";
275
+ } from "./index-h96xp4t0.js";
276
276
  import {
277
277
  compositeSessionKey,
278
278
  sessionKeySuffix
@@ -283,7 +283,7 @@ import {
283
283
  clearAllScopes,
284
284
  clearScopeBindingFromDisk,
285
285
  clearScopeBindings
286
- } from "./index-bz7ayg01.js";
286
+ } from "./index-zswy6xgb.js";
287
287
  import {
288
288
  appendLedgerEvent,
289
289
  computePlanHash,
@@ -298,7 +298,7 @@ import {
298
298
  readPlanEpochIdentity,
299
299
  replayFromLedgerWithStatus,
300
300
  takeSnapshotEvent
301
- } from "./index-k6y6btb6.js";
301
+ } from "./index-bxpqq9th.js";
302
302
  import {
303
303
  CORE_EVENT_LOCKED,
304
304
  appendCoreEventSync,
@@ -357,7 +357,7 @@ import {
357
357
  transactFile,
358
358
  transactKnowledge,
359
359
  wordBigrams
360
- } from "./index-bea260ta.js";
360
+ } from "./index-2jzmg2km.js";
361
361
  import {
362
362
  MAX_EVENT_LOG_ENTRIES,
363
363
  _internals as _internals2,
@@ -373,13 +373,13 @@ import {
373
373
  recordKnowledgeEvent,
374
374
  recordPhaseCloseIntent,
375
375
  resolveKnowledgeEventsPath
376
- } from "./index-yw26j0q7.js";
376
+ } from "./index-5hfqc3h3.js";
377
377
  import {
378
378
  resolveWorktreeIsolationConfig
379
- } from "./index-3scbg6n2.js";
379
+ } from "./index-40t6s98s.js";
380
380
  import {
381
381
  RetrospectiveEvidenceSchema
382
- } from "./index-gprxjmm7.js";
382
+ } from "./index-ebz97mks.js";
383
383
  import {
384
384
  estimateTokens,
385
385
  readSwarmFileAsync,
@@ -399,7 +399,7 @@ import {
399
399
  init_loader,
400
400
  loadPluginConfig,
401
401
  loadPluginConfigWithMeta
402
- } from "./index-7yg4ypyg.js";
402
+ } from "./index-t3wk7q51.js";
403
403
  import {
404
404
  DEFAULT_HARNESS_EVOLUTION_CONFIG,
405
405
  DEFAULT_PR_REVIEW_RESILIENCE_CONFIG,
@@ -415,7 +415,7 @@ import {
415
415
  package_default,
416
416
  resolveAutoReviewConfig,
417
417
  stripKnownSwarmPrefix
418
- } from "./index-wae55z9w.js";
418
+ } from "./index-ebxmfr4j.js";
419
419
  import {
420
420
  init_git_executable,
421
421
  resolveGitExecutable,
@@ -455,10 +455,10 @@ import {
455
455
  resolveLinkDir,
456
456
  sanitizeLinkId,
457
457
  writeLinkPointer
458
- } from "./index-g6d8xam2.js";
458
+ } from "./index-nhhek8yw.js";
459
459
  import {
460
460
  atomicWriteFile
461
- } from "./index-v3jy0tc6.js";
461
+ } from "./index-ve0xj03m.js";
462
462
  import {
463
463
  KNOWLEDGE_SCHEMA_VERSION,
464
464
  OUTCOME_BLOCK_THRESHOLD,
@@ -470,7 +470,7 @@ import {
470
470
  atomicWriteSwarmFileSync,
471
471
  matchTempGrammar,
472
472
  parseTargetBasename
473
- } from "./index-a5w29k1t.js";
473
+ } from "./index-9qw4sbg1.js";
474
474
  import {
475
475
  assertProjectRoot,
476
476
  hasExplicitProjectBoundary,
@@ -4014,7 +4014,7 @@ function applyRetention(entries, maxEntriesPerSkill) {
4014
4014
  }
4015
4015
  let aged = entries;
4016
4016
  if (newestMs !== Number.NEGATIVE_INFINITY) {
4017
- const cutoff = newestMs - SKILL_USAGE_LIMITS.maxAgeMs;
4017
+ const cutoff = Math.min(newestMs, Date.now()) - SKILL_USAGE_LIMITS.maxAgeMs;
4018
4018
  aged = entries.filter((entry) => {
4019
4019
  const ms = Date.parse(entry.timestamp);
4020
4020
  return Number.isNaN(ms) ? true : ms >= cutoff;
@@ -21454,7 +21454,7 @@ function planMerges(active, threshold, maxComparisons, maxMerges) {
21454
21454
  };
21455
21455
  }
21456
21456
  async function sweepActiveNearDuplicates(directory, options = {}) {
21457
- const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-2z00wqvb.js");
21457
+ const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-qxpfmryw.js");
21458
21458
  const { config } = loadPluginConfigWithMeta2(directory);
21459
21459
  const sweepConfig = config.learning?.dedup_sweep;
21460
21460
  if (sweepConfig?.enabled === false)
@@ -22584,7 +22584,7 @@ async function runCuratorPhase(directory, phase, agentsDispatched, config, knowl
22584
22584
  }
22585
22585
  if (config.skill_generation_enabled === true && skillCandidates.length > 0) {
22586
22586
  try {
22587
- const skillModule = await import("./skill-generator-vwcrfrw3.js");
22587
+ const skillModule = await import("./skill-generator-nwrvtqbz.js");
22588
22588
  for (const cand of skillCandidates) {
22589
22589
  if (cand.confidence < (config.min_skill_confidence ?? DEFAULT_SKILL_MIN_CONFIDENCE)) {
22590
22590
  continue;
@@ -23056,7 +23056,7 @@ async function applyCuratorKnowledgeUpdates(directory, recommendations, knowledg
23056
23056
  } catch {}
23057
23057
  }
23058
23058
  if (contradictedEntries.length > 0 && knowledgeConfig.contradiction_threshold_action === "quarantine") {
23059
- const { maybeQuarantineOnContradiction } = await import("./knowledge-escalator-585m4927.js");
23059
+ const { maybeQuarantineOnContradiction } = await import("./knowledge-escalator-f80n84ch.js");
23060
23060
  for (const { id } of contradictedEntries) {
23061
23061
  try {
23062
23062
  await maybeQuarantineOnContradiction(directory, id, knowledgeConfig.contradiction_quarantine_threshold, knowledgeConfig.contradiction_quarantine_window_days);
@@ -23875,7 +23875,7 @@ async function runCuratorPostMortem(directory, options = {}) {
23875
23875
  warnings.push("Failed to collect knowledge summary.");
23876
23876
  }
23877
23877
  try {
23878
- const { getScanStatus } = await import("./scan-cursor-kv9scb2v.js");
23878
+ const { getScanStatus } = await import("./scan-cursor-2v7995nb.js");
23879
23879
  const scanStatus = await getScanStatus(directory);
23880
23880
  if (scanStatus.remaining_estimate > 0) {
23881
23881
  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.`);
@@ -24047,9 +24047,9 @@ var _internals27 = {
24047
24047
  verifyPostMortemKnowledgeActions,
24048
24048
  repairPostMortemActions,
24049
24049
  loadDefaultKnowledgeConfig: async (directory) => {
24050
- const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-a7f88yc3.js");
24050
+ const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-dy8fqycb.js");
24051
24051
  try {
24052
- const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-2z00wqvb.js");
24052
+ const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-qxpfmryw.js");
24053
24053
  const loaded = loadPluginConfigWithMeta2(directory);
24054
24054
  return KnowledgeConfigSchema2.parse(loaded.config.knowledge ?? {});
24055
24055
  } catch {
@@ -24057,11 +24057,11 @@ var _internals27 = {
24057
24057
  }
24058
24058
  },
24059
24059
  applyCuratorKnowledgeUpdates: async (directory, recommendations, knowledgeConfig, generation) => {
24060
- const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-mpqpbr0r.js");
24060
+ const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-3sz7refy.js");
24061
24061
  return applyCuratorKnowledgeUpdates2(directory, recommendations, knowledgeConfig, generation);
24062
24062
  },
24063
24063
  checkHivePromotions: async (entries, knowledgeConfig, directory) => {
24064
- const { checkHivePromotions } = await import("./hive-promoter-zjtgbh4w.js");
24064
+ const { checkHivePromotions } = await import("./hive-promoter-4rtxhw7n.js");
24065
24065
  return checkHivePromotions(entries, knowledgeConfig, directory);
24066
24066
  },
24067
24067
  applyProposalTriage: async (directory, triage) => {
@@ -24070,7 +24070,7 @@ var _internals27 = {
24070
24070
  activateProposal,
24071
24071
  listSkills: listSkills2,
24072
24072
  sanitizeSlug
24073
- } = await import("./skill-generator-vwcrfrw3.js");
24073
+ } = await import("./skill-generator-nwrvtqbz.js");
24074
24074
  const result = {
24075
24075
  approved: [],
24076
24076
  rejected: [],
@@ -25400,9 +25400,9 @@ function hashContent(content) {
25400
25400
  return createHash13("sha1").update(content).digest("hex");
25401
25401
  }
25402
25402
  async function loadConfigForPolicyCurator(directory) {
25403
- const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-a7f88yc3.js");
25403
+ const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-dy8fqycb.js");
25404
25404
  try {
25405
- const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-2z00wqvb.js");
25405
+ const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-qxpfmryw.js");
25406
25406
  const { config: loadedConfig } = loadPluginConfigWithMeta2(directory);
25407
25407
  return KnowledgeConfigSchema2.parse(loadedConfig.knowledge ?? {});
25408
25408
  } catch {
@@ -37655,7 +37655,7 @@ async function runFinalizeStage(ctx) {
37655
37655
  }
37656
37656
  }
37657
37657
  try {
37658
- const { CuratorConfigSchema: CCS } = await import("./schema-a7f88yc3.js");
37658
+ const { CuratorConfigSchema: CCS } = await import("./schema-dy8fqycb.js");
37659
37659
  const { config: pmLoadedConfig } = _internals41.loadPluginConfigWithMeta(ctx.directory);
37660
37660
  const curatorCfg = CCS.parse(pmLoadedConfig.curator ?? {});
37661
37661
  if (curatorCfg.enabled && curatorCfg.postmortem_enabled) {
@@ -39879,9 +39879,9 @@ var _internals45 = {
39879
39879
  loadPluginConfigWithMeta,
39880
39880
  loadCuratorDeps: async () => {
39881
39881
  const [{ CuratorConfigSchema }, curator, { createCuratorLLMDelegate: createCuratorLLMDelegate2 }] = await Promise.all([
39882
- import("./schema-a7f88yc3.js"),
39883
- import("./curator-mpqpbr0r.js"),
39884
- import("./curator-llm-factory-m3yw6sn5.js")
39882
+ import("./schema-dy8fqycb.js"),
39883
+ import("./curator-3sz7refy.js"),
39884
+ import("./curator-llm-factory-pyp5kmra.js")
39885
39885
  ]);
39886
39886
  return { CuratorConfigSchema, curator, createCuratorLLMDelegate: createCuratorLLMDelegate2 };
39887
39887
  }
@@ -40890,7 +40890,7 @@ async function computeCurationDiagnostics(directory, entries) {
40890
40890
  let scanCompleted = false;
40891
40891
  let scanRemaining = 0;
40892
40892
  try {
40893
- const { getScanStatus } = await import("./scan-cursor-kv9scb2v.js");
40893
+ const { getScanStatus } = await import("./scan-cursor-2v7995nb.js");
40894
40894
  const status = await getScanStatus(directory);
40895
40895
  scanGeneration = status.generation;
40896
40896
  scanCompleted = status.completed;
@@ -40898,19 +40898,19 @@ async function computeCurationDiagnostics(directory, entries) {
40898
40898
  } catch {}
40899
40899
  let configMatch = null;
40900
40900
  try {
40901
- const { isLinked: isLinked2 } = await import("./knowledge-link-a9fafeb3.js");
40901
+ const { isLinked: isLinked2 } = await import("./knowledge-link-vm4caewt.js");
40902
40902
  if (isLinked2(directory)) {
40903
- const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-a7f88yc3.js");
40903
+ const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-dy8fqycb.js");
40904
40904
  let config;
40905
40905
  try {
40906
- const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-2z00wqvb.js");
40906
+ const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-qxpfmryw.js");
40907
40907
  const loaded = loadPluginConfigWithMeta2(directory);
40908
40908
  config = KnowledgeConfigSchema2.parse(loaded.config.knowledge ?? {});
40909
40909
  } catch {
40910
40910
  config = KnowledgeConfigSchema2.parse({});
40911
40911
  }
40912
40912
  const { cohortConfigFingerprint: cohortConfigFingerprint2 } = await import("./config-fingerprint-v22xh5a2.js");
40913
- const { buildConfigFingerprintInput: buildConfigFingerprintInput2, readCohortConfigFingerprint } = await import("./curation-policy-2gq8307w.js");
40913
+ const { buildConfigFingerprintInput: buildConfigFingerprintInput2, readCohortConfigFingerprint } = await import("./curation-policy-ray8h55z.js");
40914
40914
  const currentFp = cohortConfigFingerprint2(buildConfigFingerprintInput2(config));
40915
40915
  const cohortFp = await readCohortConfigFingerprint(directory);
40916
40916
  configMatch = cohortFp === null ? null : currentFp === cohortFp;
@@ -42223,7 +42223,7 @@ async function handleDoctorCommand(directory, args) {
42223
42223
  const result = runConfigDoctor(config, directory);
42224
42224
  let output;
42225
42225
  if (enableAutoFix && result.hasAutoFixableIssues) {
42226
- const { runConfigDoctorWithFixes } = await import("./config-doctor-8zawz3qh.js");
42226
+ const { runConfigDoctorWithFixes } = await import("./config-doctor-a7drgs33.js");
42227
42227
  const fixResult = await runConfigDoctorWithFixes(directory, config, true, {
42228
42228
  applyLossy: true
42229
42229
  });
@@ -43163,7 +43163,7 @@ async function handleEvidenceCommand(directory, args) {
43163
43163
  return formatTaskEvidenceMarkdown(evidenceData);
43164
43164
  }
43165
43165
  async function handleEvidenceSummaryCommand(directory) {
43166
- const { buildEvidenceSummary } = await import("./evidence-summary-service-qaq1eba9.js");
43166
+ const { buildEvidenceSummary } = await import("./evidence-summary-service-cwyjkdsa.js");
43167
43167
  const artifact = await buildEvidenceSummary(directory);
43168
43168
  if (!artifact) {
43169
43169
  return "No plan found. Run `/swarm plan` to check plan status.";
@@ -47930,9 +47930,11 @@ function hasBundledRules(projectRoot) {
47930
47930
  import * as crypto3 from "crypto";
47931
47931
  import * as fs26 from "fs";
47932
47932
  import * as path62 from "path";
47933
- var BASELINE_SCHEMA_VERSION = "1.0.0";
47933
+ var BASELINE_SCHEMA_VERSION = "1.1.0";
47934
+ var LEGACY_BASELINE_SCHEMA_VERSION = "1.0.0";
47934
47935
  var MAX_BASELINE_FINDINGS = 2000;
47935
47936
  var MAX_BASELINE_BYTES = 2 * 1048576;
47937
+ var MAX_BLOCKED_LIST = 20;
47936
47938
  var LOCK_RETRY_DELAYS_MS = [50, 100, 200, 400, 800];
47937
47939
  function normalizeFindingPath(directory, file) {
47938
47940
  const resolved = path62.isAbsolute(file) ? file : path62.resolve(directory, file);
@@ -47991,6 +47993,7 @@ function assignOccurrenceIndices(findings, directory) {
47991
47993
  const relFile = normalizeFindingPath(directory, finding.location.file);
47992
47994
  const lineNum = finding.location.line;
47993
47995
  let baseKey;
47996
+ let reflowKey = "";
47994
47997
  try {
47995
47998
  if (relFile.startsWith(".."))
47996
47999
  throw new Error("escapes workspace");
@@ -48006,6 +48009,8 @@ function assignOccurrenceIndices(findings, directory) {
48006
48009
  `);
48007
48010
  const hash2 = crypto3.createHash("sha256").update(window).digest("hex").slice(0, 16);
48008
48011
  baseKey = `${relFile}|${finding.rule_id}|${hash2}`;
48012
+ const lineHash = crypto3.createHash("sha256").update(getLine(lines, idx)).digest("hex").slice(0, 16);
48013
+ reflowKey = `${relFile}|${finding.rule_id}|${lineHash}`;
48009
48014
  } catch {
48010
48015
  baseKey = `${relFile}|${finding.rule_id}|L${lineNum}|UNSTABLE`;
48011
48016
  }
@@ -48016,10 +48021,38 @@ function assignOccurrenceIndices(findings, directory) {
48016
48021
  finding,
48017
48022
  index: occIdx,
48018
48023
  stable: fp.stable,
48019
- fingerprint: fp.fingerprint
48024
+ fingerprint: fp.fingerprint,
48025
+ reflowKey
48020
48026
  };
48021
48027
  });
48022
48028
  }
48029
+ function partitionAgainstBaseline(indexed, baselineFingerprints, baselineReflowKeys) {
48030
+ const reflowCounts = new Map;
48031
+ for (const key of baselineReflowKeys) {
48032
+ if (!key)
48033
+ continue;
48034
+ reflowCounts.set(key, (reflowCounts.get(key) ?? 0) + 1);
48035
+ }
48036
+ const preExisting = [];
48037
+ const moved = [];
48038
+ const newFindings = [];
48039
+ for (const { finding, stable, fingerprint, reflowKey } of indexed) {
48040
+ if (stable && baselineFingerprints.has(fingerprint)) {
48041
+ preExisting.push(finding);
48042
+ if (reflowKey) {
48043
+ const count = reflowCounts.get(reflowKey) ?? 0;
48044
+ if (count > 0)
48045
+ reflowCounts.set(reflowKey, count - 1);
48046
+ }
48047
+ } else if (stable && reflowKey && (reflowCounts.get(reflowKey) ?? 0) > 0) {
48048
+ reflowCounts.set(reflowKey, (reflowCounts.get(reflowKey) ?? 1) - 1);
48049
+ moved.push(finding);
48050
+ } else {
48051
+ newFindings.push(finding);
48052
+ }
48053
+ }
48054
+ return { preExisting, moved, newFindings };
48055
+ }
48023
48056
  async function waitForLockRetry(delayMs, abortSignal) {
48024
48057
  if (abortSignal?.aborted)
48025
48058
  return false;
@@ -48110,25 +48143,96 @@ async function captureOrMergeBaseline(directory, phase, findings, engine, scanne
48110
48143
  try {
48111
48144
  const raw = fs26.readFileSync(baselinePath, "utf-8");
48112
48145
  const parsed = JSON.parse(raw);
48113
- if (parsed.schema_version === BASELINE_SCHEMA_VERSION) {
48146
+ if (parsed.schema_version === BASELINE_SCHEMA_VERSION || parsed.schema_version === LEGACY_BASELINE_SCHEMA_VERSION) {
48114
48147
  existing = parsed;
48115
48148
  }
48116
48149
  } catch {}
48117
48150
  const scannedRelFiles = new Set(scannedFiles.map((f) => normalizeFindingPath(directory, f)));
48118
48151
  const indexed = _internals56.assignOccurrenceIndices(findings, directory);
48119
48152
  if (existing && !opts?.force) {
48120
- const prunedFingerprints = existing.fingerprints.filter((fp) => {
48153
+ const prunedFingerprints = [];
48154
+ const prunedReflowKeys = [];
48155
+ existing.fingerprints.forEach((fp, i) => {
48121
48156
  const relFile = fp.slice(0, fp.indexOf("|"));
48122
- return !scannedRelFiles.has(relFile);
48157
+ if (scannedRelFiles.has(relFile))
48158
+ return;
48159
+ prunedFingerprints.push(fp);
48160
+ prunedReflowKeys.push(existing.reflow_keys?.[i] ?? "");
48123
48161
  });
48124
48162
  const prunedSnapshot = existing.findings_snapshot.filter((f) => {
48125
48163
  return !scannedRelFiles.has(normalizeFindingPath(directory, f.location.file));
48126
48164
  });
48127
48165
  const prunedFilesIndexed = existing.files_indexed.filter((f) => !scannedRelFiles.has(f));
48166
+ const priorFingerprintSet = new Set;
48167
+ const priorReflowCounts = new Map;
48168
+ existing.fingerprints.forEach((fp, i) => {
48169
+ const relFile = fp.slice(0, fp.indexOf("|"));
48170
+ if (!scannedRelFiles.has(relFile))
48171
+ return;
48172
+ priorFingerprintSet.add(fp);
48173
+ const key = existing.reflow_keys?.[i] ?? "";
48174
+ if (key) {
48175
+ priorReflowCounts.set(key, (priorReflowCounts.get(key) ?? 0) + 1);
48176
+ }
48177
+ });
48178
+ let blockedCount = 0;
48179
+ const blockedList = [];
48180
+ const triageEntries = [];
48181
+ const absorbedAt = new Date().toISOString();
48182
+ const actor = opts?.actor?.trim() ? opts.actor.trim() : "unknown-session";
48183
+ for (const { finding, stable, fingerprint, reflowKey } of indexed) {
48184
+ if (stable && priorFingerprintSet.has(fingerprint)) {
48185
+ if (reflowKey) {
48186
+ const count = priorReflowCounts.get(reflowKey) ?? 0;
48187
+ if (count > 0)
48188
+ priorReflowCounts.set(reflowKey, count - 1);
48189
+ }
48190
+ continue;
48191
+ }
48192
+ if (stable && reflowKey && (priorReflowCounts.get(reflowKey) ?? 0) > 0) {
48193
+ priorReflowCounts.set(reflowKey, (priorReflowCounts.get(reflowKey) ?? 1) - 1);
48194
+ continue;
48195
+ }
48196
+ const relFile = normalizeFindingPath(directory, finding.location.file);
48197
+ if (!opts?.refreshRationale) {
48198
+ blockedCount++;
48199
+ if (blockedList.length < MAX_BLOCKED_LIST) {
48200
+ blockedList.push({
48201
+ fingerprint,
48202
+ rel_file: relFile,
48203
+ rule_id: finding.rule_id
48204
+ });
48205
+ }
48206
+ continue;
48207
+ }
48208
+ triageEntries.push({
48209
+ fingerprint,
48210
+ rel_file: relFile,
48211
+ rule_id: finding.rule_id,
48212
+ rationale: opts.refreshRationale,
48213
+ actor,
48214
+ absorbed_at: absorbedAt
48215
+ });
48216
+ }
48217
+ if (blockedCount > 0) {
48218
+ const sample = blockedList.slice(0, 5);
48219
+ const sampleText = sample.map((b) => `${b.rel_file} (${b.rule_id})`).join(", ");
48220
+ const ellipsis = blockedCount > sample.length ? ", \u2026" : "";
48221
+ return {
48222
+ status: "absorption_blocked",
48223
+ path: baselinePath,
48224
+ blocked: blockedList,
48225
+ message: `capture_baseline would absorb ${blockedCount} finding(s) not present in the prior baseline ` + `(${sampleText}${ellipsis}). ` + `Pass baseline_refresh_rationale to record an audited refresh \u2014 the baseline was left unchanged (fail-closed).`
48226
+ };
48227
+ }
48128
48228
  const mergedFingerprints = [
48129
48229
  ...prunedFingerprints,
48130
48230
  ...indexed.map((i) => i.fingerprint)
48131
48231
  ];
48232
+ const mergedReflowKeys = [
48233
+ ...prunedReflowKeys,
48234
+ ...indexed.map((i) => i.reflowKey)
48235
+ ];
48132
48236
  const mergedSnapshot = [
48133
48237
  ...prunedSnapshot,
48134
48238
  ...indexed.map((i) => i.finding)
@@ -48140,6 +48244,7 @@ async function captureOrMergeBaseline(directory, phase, findings, engine, scanne
48140
48244
  const truncated2 = mergedSnapshot.length > MAX_BASELINE_FINDINGS;
48141
48245
  const cappedSnapshot2 = truncated2 ? mergedSnapshot.slice(-MAX_BASELINE_FINDINGS) : mergedSnapshot;
48142
48246
  const cappedFingerprints2 = truncated2 ? mergedFingerprints.slice(-MAX_BASELINE_FINDINGS) : mergedFingerprints;
48247
+ const cappedReflowKeys2 = truncated2 ? mergedReflowKeys.slice(-MAX_BASELINE_FINDINGS) : mergedReflowKeys;
48143
48248
  let cappedFilesIndexed = mergedFilesIndexed;
48144
48249
  if (truncated2) {
48145
48250
  const survivingFiles = new Set;
@@ -48149,6 +48254,9 @@ async function captureOrMergeBaseline(directory, phase, findings, engine, scanne
48149
48254
  }
48150
48255
  cappedFilesIndexed = Array.from(survivingFiles);
48151
48256
  }
48257
+ const cappedFingerprintSet = new Set(cappedFingerprints2);
48258
+ const retainedTriage = (existing.triage_log ?? []).filter((e) => cappedFingerprintSet.has(e.fingerprint));
48259
+ const mergedTriageLog = [...retainedTriage, ...triageEntries].slice(-MAX_BASELINE_FINDINGS);
48152
48260
  const now3 = new Date().toISOString();
48153
48261
  const bundle2 = {
48154
48262
  schema_version: BASELINE_SCHEMA_VERSION,
@@ -48158,14 +48266,16 @@ async function captureOrMergeBaseline(directory, phase, findings, engine, scanne
48158
48266
  engine,
48159
48267
  files_indexed: cappedFilesIndexed,
48160
48268
  fingerprints: cappedFingerprints2,
48269
+ reflow_keys: cappedReflowKeys2,
48161
48270
  findings_snapshot: cappedSnapshot2,
48271
+ triage_log: mergedTriageLog,
48162
48272
  truncated: truncated2
48163
48273
  };
48164
48274
  const json2 = JSON.stringify(bundle2, null, 2);
48165
48275
  if (json2.length > MAX_BASELINE_BYTES) {
48166
48276
  return {
48167
48277
  status: "error",
48168
- message: `Baseline would exceed size cap (${json2.length} bytes > ${MAX_BASELINE_BYTES})`
48278
+ message: `Baseline would exceed size cap (${json2.length} bytes > ${MAX_BASELINE_BYTES} bytes)`
48169
48279
  };
48170
48280
  }
48171
48281
  if (opts?.abortSignal?.aborted) {
@@ -48181,14 +48291,17 @@ async function captureOrMergeBaseline(directory, phase, findings, engine, scanne
48181
48291
  return {
48182
48292
  status: "merged",
48183
48293
  path: baselinePath,
48184
- fingerprint_count: cappedFingerprints2.length
48294
+ fingerprint_count: cappedFingerprints2.length,
48295
+ absorbed_finding_count: triageEntries.length
48185
48296
  };
48186
48297
  }
48187
48298
  const newFingerprints = indexed.map((i) => i.fingerprint);
48299
+ const newReflowKeys = indexed.map((i) => i.reflowKey);
48188
48300
  const newSnapshot = indexed.map((i) => i.finding);
48189
48301
  const truncated = newSnapshot.length > MAX_BASELINE_FINDINGS;
48190
48302
  const cappedSnapshot = truncated ? newSnapshot.slice(0, MAX_BASELINE_FINDINGS) : newSnapshot;
48191
48303
  const cappedFingerprints = truncated ? newFingerprints.slice(0, MAX_BASELINE_FINDINGS) : newFingerprints;
48304
+ const cappedReflowKeys = truncated ? newReflowKeys.slice(0, MAX_BASELINE_FINDINGS) : newReflowKeys;
48192
48305
  const now2 = new Date().toISOString();
48193
48306
  const bundle = {
48194
48307
  schema_version: BASELINE_SCHEMA_VERSION,
@@ -48198,7 +48311,9 @@ async function captureOrMergeBaseline(directory, phase, findings, engine, scanne
48198
48311
  engine,
48199
48312
  files_indexed: Array.from(scannedRelFiles),
48200
48313
  fingerprints: cappedFingerprints,
48314
+ reflow_keys: cappedReflowKeys,
48201
48315
  findings_snapshot: cappedSnapshot,
48316
+ triage_log: [],
48202
48317
  truncated
48203
48318
  };
48204
48319
  const json = JSON.stringify(bundle, null, 2);
@@ -48244,7 +48359,7 @@ function loadBaseline(directory, phase) {
48244
48359
  try {
48245
48360
  const raw = fs26.readFileSync(baselinePath, "utf-8");
48246
48361
  const parsed = JSON.parse(raw);
48247
- if (parsed.schema_version !== BASELINE_SCHEMA_VERSION) {
48362
+ if (parsed.schema_version !== BASELINE_SCHEMA_VERSION && parsed.schema_version !== LEGACY_BASELINE_SCHEMA_VERSION) {
48248
48363
  return {
48249
48364
  status: "invalid_schema",
48250
48365
  errors: [`Unknown schema version: ${String(parsed.schema_version)}`]
@@ -48256,9 +48371,25 @@ function loadBaseline(directory, phase) {
48256
48371
  errors: ["Missing or invalid fingerprints array"]
48257
48372
  };
48258
48373
  }
48374
+ let reflowKeys = [];
48375
+ if (parsed.schema_version === BASELINE_SCHEMA_VERSION) {
48376
+ if (parsed.reflow_keys === undefined) {
48377
+ reflowKeys = [];
48378
+ } else if (!Array.isArray(parsed.reflow_keys) || parsed.reflow_keys.some((k) => typeof k !== "string") || parsed.reflow_keys.length !== parsed.fingerprints.length) {
48379
+ return {
48380
+ status: "invalid_schema",
48381
+ errors: [
48382
+ "reflow_keys must be a string array aligned 1:1 with fingerprints"
48383
+ ]
48384
+ };
48385
+ } else {
48386
+ reflowKeys = parsed.reflow_keys;
48387
+ }
48388
+ }
48259
48389
  return {
48260
48390
  status: "found",
48261
48391
  fingerprints: new Set(parsed.fingerprints),
48392
+ reflowKeys,
48262
48393
  bundle: parsed
48263
48394
  };
48264
48395
  } catch (e) {
@@ -48274,6 +48405,7 @@ function loadBaseline(directory, phase) {
48274
48405
  var _internals56 = {
48275
48406
  fingerprintFinding,
48276
48407
  assignOccurrenceIndices,
48408
+ partitionAgainstBaseline,
48277
48409
  captureOrMergeBaseline,
48278
48410
  loadBaseline
48279
48411
  };
@@ -48614,10 +48746,18 @@ async function sastScan(input, directory, config) {
48614
48746
  if (abort_signal?.aborted) {
48615
48747
  return cancelledScanResult(allFindings, filesScanned);
48616
48748
  }
48617
- const captureResult = await captureOrMergeBaseline(directory, phase, captureFindings, engine, scannedFilePaths, { abortSignal: abort_signal });
48618
- const captureStatus = captureResult.status === "written" ? "baseline_captured" : captureResult.status === "merged" ? "baseline_merged" : undefined;
48749
+ const captureResult = await captureOrMergeBaseline(directory, phase, captureFindings, engine, scannedFilePaths, {
48750
+ abortSignal: abort_signal,
48751
+ refreshRationale: input.baseline_refresh_rationale,
48752
+ actor: input.session_id
48753
+ });
48754
+ const captureStatus = captureResult.status === "written" ? "baseline_captured" : captureResult.status === "merged" ? "baseline_merged" : captureResult.status === "absorption_blocked" ? "baseline_absorption_blocked" : undefined;
48619
48755
  if (captureResult.status === "error") {
48620
48756
  warn(`SAST Baseline: capture failed \u2014 ${captureResult.message}`);
48757
+ } else if (captureResult.status === "absorption_blocked") {
48758
+ warn(`SAST Baseline: ${captureResult.message}`);
48759
+ } else if (captureResult.status === "merged" && captureResult.absorbed_finding_count > 0) {
48760
+ warn(`SAST Baseline: merged and absorbed ${captureResult.absorbed_finding_count} novel finding(s) ` + "under the supplied refresh rationale. If this capture ran after a gate failure, " + "those findings may be coder-introduced \u2014 verify before proceeding.");
48621
48761
  }
48622
48762
  const finalFindings2 = allFindings.slice(0, MAX_FINDINGS);
48623
48763
  const summary2 = {
@@ -48645,33 +48785,31 @@ async function sastScan(input, directory, config) {
48645
48785
  findings: finalFindings2,
48646
48786
  summary: summary2,
48647
48787
  status: captureStatus,
48648
- finding_count: captureResult.status !== "error" ? captureResult.fingerprint_count : undefined,
48788
+ finding_count: captureResult.status === "written" || captureResult.status === "merged" ? captureResult.fingerprint_count : undefined,
48789
+ ...captureResult.status === "merged" && captureResult.absorbed_finding_count > 0 ? { absorbed_finding_count: captureResult.absorbed_finding_count } : {},
48649
48790
  baseline_used: false
48650
48791
  };
48651
48792
  }
48652
48793
  let newFindings;
48653
48794
  let preExistingFindings;
48795
+ let movedFindings;
48654
48796
  let baselineUsed = false;
48655
48797
  let truncatedPreExisting = false;
48798
+ let truncatedMoved = false;
48656
48799
  if (phase !== undefined && Number.isInteger(phase) && phase >= 1) {
48657
48800
  const baselineResult = loadBaseline(directory, phase);
48658
48801
  if (baselineResult.status === "found") {
48659
48802
  baselineUsed = true;
48660
48803
  const baselineSet = baselineResult.fingerprints;
48661
48804
  const indexed = assignOccurrenceIndices(allFindings, directory);
48662
- const rawNew = [];
48663
- const rawPreExisting = [];
48664
- for (const { finding, stable, fingerprint } of indexed) {
48665
- if (!stable || !baselineSet.has(fingerprint)) {
48666
- rawNew.push(finding);
48667
- } else {
48668
- rawPreExisting.push(finding);
48669
- }
48670
- }
48671
- newFindings = rawNew.slice(0, MAX_FINDINGS);
48805
+ const partition = partitionAgainstBaseline(indexed, baselineSet, baselineResult.reflowKeys ?? []);
48806
+ newFindings = partition.newFindings.slice(0, MAX_FINDINGS);
48672
48807
  const preExistingBudget = Math.max(0, MAX_FINDINGS - newFindings.length);
48673
- preExistingFindings = rawPreExisting.slice(0, preExistingBudget);
48674
- truncatedPreExisting = rawPreExisting.length > preExistingBudget;
48808
+ preExistingFindings = partition.preExisting.slice(0, preExistingBudget);
48809
+ truncatedPreExisting = partition.preExisting.length > preExistingBudget;
48810
+ const movedBudget = Math.max(0, preExistingBudget - preExistingFindings.length);
48811
+ movedFindings = partition.moved.slice(0, movedBudget);
48812
+ truncatedMoved = partition.moved.length > movedBudget;
48675
48813
  } else if (baselineResult.status === "invalid_schema") {
48676
48814
  warn(`SAST Baseline: could not load baseline for phase ${phase} \u2014 ${baselineResult.errors.join(", ")}. Falling back to legacy behavior.`);
48677
48815
  }
@@ -48686,7 +48824,8 @@ async function sastScan(input, directory, config) {
48686
48824
  } else {
48687
48825
  finalFindings = [
48688
48826
  ...newFindings ?? [],
48689
- ...preExistingFindings ?? []
48827
+ ...preExistingFindings ?? [],
48828
+ ...movedFindings ?? []
48690
48829
  ].slice(0, MAX_FINDINGS);
48691
48830
  }
48692
48831
  const findingsBySeverity = countBySeverity(finalFindings);
@@ -48730,6 +48869,7 @@ async function sastScan(input, directory, config) {
48730
48869
  ...baselineUsed && {
48731
48870
  new_findings: newFindings,
48732
48871
  pre_existing_findings: preExistingFindings,
48872
+ moved_findings: movedFindings,
48733
48873
  baseline_used: true
48734
48874
  }
48735
48875
  }, abort_signal);
@@ -48743,9 +48883,12 @@ async function sastScan(input, directory, config) {
48743
48883
  if (baselineUsed) {
48744
48884
  result.new_findings = newFindings;
48745
48885
  result.pre_existing_findings = preExistingFindings;
48886
+ result.moved_findings = movedFindings;
48746
48887
  result.baseline_used = true;
48747
48888
  if (truncatedPreExisting)
48748
48889
  result.truncated_pre_existing = true;
48890
+ if (truncatedMoved)
48891
+ result.truncated_moved_findings = true;
48749
48892
  }
48750
48893
  return result;
48751
48894
  }
@@ -48756,8 +48899,9 @@ var sast_scan = createSwarmTool({
48756
48899
  directory: exports_external.string().describe("Directory to scan for security vulnerabilities"),
48757
48900
  changed_files: exports_external.array(exports_external.string()).optional().describe("List of files to scan (leave empty to scan none)"),
48758
48901
  severity_threshold: exports_external.enum(["low", "medium", "high", "critical"]).optional().default("medium").describe("Minimum severity that causes failure"),
48759
- capture_baseline: exports_external.boolean().optional().describe("When true, capture/merge a phase-scoped baseline of pre-existing findings. Requires phase. Subsequent scans with phase only fail on NEW findings."),
48760
- phase: exports_external.number().int().min(1).optional().describe("Current phase number (positive integer >= 1). Required with capture_baseline. Enables baseline diff when provided on non-capture scans.")
48902
+ capture_baseline: exports_external.boolean().optional().describe("When true, capture/merge a phase-scoped baseline of pre-existing findings. Requires phase. Subsequent scans with phase only fail on NEW findings. Merging findings not previously in the baseline (any file) is BLOCKED unless baseline_refresh_rationale is provided."),
48903
+ phase: exports_external.number().int().min(1).optional().describe("Current phase number (positive integer >= 1). Required with capture_baseline. Enables baseline diff when provided on non-capture scans."),
48904
+ baseline_refresh_rationale: exports_external.string().trim().min(1).max(500).optional().describe('Audited rationale required when capture_baseline would absorb findings not previously in the baseline \u2014 for already-indexed AND first-time files (e.g. "pre-delegation capture for task 2.1; findings verified pre-existing"). Recorded per finding in the baseline triage log. Only meaningful with capture_baseline: true.')
48761
48905
  },
48762
48906
  execute: async (args, directory, ctx) => {
48763
48907
  let safeArgs;
@@ -48765,12 +48909,14 @@ var sast_scan = createSwarmTool({
48765
48909
  if (args && typeof args === "object") {
48766
48910
  const rawPhase = args.phase;
48767
48911
  const rawCapture = args.capture_baseline;
48912
+ const rawRationale = args.baseline_refresh_rationale;
48768
48913
  safeArgs = {
48769
48914
  directory: args.directory,
48770
48915
  changed_files: args.changed_files,
48771
48916
  severity_threshold: args.severity_threshold,
48772
48917
  phase: typeof rawPhase === "number" && Number.isInteger(rawPhase) && rawPhase >= 1 ? rawPhase : undefined,
48773
- capture_baseline: typeof rawCapture === "boolean" ? rawCapture : undefined
48918
+ capture_baseline: typeof rawCapture === "boolean" ? rawCapture : undefined,
48919
+ baseline_refresh_rationale: typeof rawRationale === "string" && rawRationale.trim().length >= 1 && rawRationale.trim().length <= 500 ? rawRationale.trim() : undefined
48774
48920
  };
48775
48921
  } else {
48776
48922
  safeArgs = {
@@ -48778,7 +48924,8 @@ var sast_scan = createSwarmTool({
48778
48924
  changed_files: undefined,
48779
48925
  severity_threshold: undefined,
48780
48926
  capture_baseline: undefined,
48781
- phase: undefined
48927
+ phase: undefined,
48928
+ baseline_refresh_rationale: undefined
48782
48929
  };
48783
48930
  }
48784
48931
  } catch {
@@ -48787,7 +48934,8 @@ var sast_scan = createSwarmTool({
48787
48934
  changed_files: undefined,
48788
48935
  severity_threshold: undefined,
48789
48936
  capture_baseline: undefined,
48790
- phase: undefined
48937
+ phase: undefined,
48938
+ baseline_refresh_rationale: undefined
48791
48939
  };
48792
48940
  }
48793
48941
  if (safeArgs.directory === undefined) {
@@ -48813,6 +48961,8 @@ var sast_scan = createSwarmTool({
48813
48961
  severity_threshold: safeArgs.severity_threshold ?? "medium",
48814
48962
  capture_baseline: safeArgs.capture_baseline,
48815
48963
  phase: safeArgs.phase,
48964
+ baseline_refresh_rationale: safeArgs.baseline_refresh_rationale,
48965
+ session_id: ctx?.sessionID,
48816
48966
  abort_signal: ctx?.abort
48817
48967
  };
48818
48968
  const result = await _internals57.sastScan(input, directory);
@@ -78241,7 +78391,7 @@ async function runValidationWithTransientRetry(input, candidateContent, baseline
78241
78391
  if (!input.dispatcher) {
78242
78392
  throw new Error("no evaluation dispatcher available (cannot run validation)");
78243
78393
  }
78244
- const { createModelEvaluationExecutor: createModelEvaluationExecutor2 } = await import("./runner-atbehryj.js");
78394
+ const { createModelEvaluationExecutor: createModelEvaluationExecutor2 } = await import("./runner-sn7a6zd0.js");
78245
78395
  const executor = createModelEvaluationExecutor2(input.dispatcher, input.sessionId);
78246
78396
  const result = await withProtectedSetIntegrity([evalInputRoot, ...protectedRoots(input.directory)], () => _internals98.evaluateCandidateV1({
78247
78397
  projectRoot: input.directory,
@@ -80336,7 +80486,7 @@ function buildDetailedHelp(commandName, entry) {
80336
80486
  async function handleHelpCommand(ctx) {
80337
80487
  const targetCommand = ctx.args.join(" ");
80338
80488
  if (!targetCommand) {
80339
- const { buildHelpText } = await import("./index-36sgq7n9.js");
80489
+ const { buildHelpText } = await import("./index-sn6mtxxc.js");
80340
80490
  return buildHelpText();
80341
80491
  }
80342
80492
  const tokens = targetCommand.split(/\s+/);
@@ -80345,7 +80495,7 @@ async function handleHelpCommand(ctx) {
80345
80495
  return _internals101.buildDetailedHelp(resolved.key, resolved.entry);
80346
80496
  }
80347
80497
  const similar = _internals101.findSimilarCommands(targetCommand);
80348
- const { buildHelpText: fullHelp } = await import("./index-36sgq7n9.js");
80498
+ const { buildHelpText: fullHelp } = await import("./index-sn6mtxxc.js");
80349
80499
  if (similar.length > 0) {
80350
80500
  return `Command '/swarm ${targetCommand}' not found.
80351
80501
 
@@ -80676,7 +80826,7 @@ var COMMAND_REGISTRY = {
80676
80826
  },
80677
80827
  "guardrail explain": {
80678
80828
  handler: async (ctx) => {
80679
- const { handleGuardrailExplain } = await import("./guardrail-explain-5z64w3ah.js");
80829
+ const { handleGuardrailExplain } = await import("./guardrail-explain-a13kbmrt.js");
80680
80830
  return handleGuardrailExplain(ctx.directory, ctx.args);
80681
80831
  },
80682
80832
  description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
@@ -80686,7 +80836,7 @@ var COMMAND_REGISTRY = {
80686
80836
  },
80687
80837
  "guardrail reset": {
80688
80838
  handler: async (ctx) => {
80689
- const { handleGuardrailReset } = await import("./guardrail-reset-yjwk20rb.js");
80839
+ const { handleGuardrailReset } = await import("./guardrail-reset-chbc0mep.js");
80690
80840
  return handleGuardrailReset(ctx.args, ctx.sessionID);
80691
80841
  },
80692
80842
  description: "Reset one exact active invocation/action circuit after repair",
@@ -80695,7 +80845,7 @@ var COMMAND_REGISTRY = {
80695
80845
  },
80696
80846
  "guardrail-explain": {
80697
80847
  handler: async (ctx) => {
80698
- const { handleGuardrailExplain } = await import("./guardrail-explain-5z64w3ah.js");
80848
+ const { handleGuardrailExplain } = await import("./guardrail-explain-a13kbmrt.js");
80699
80849
  return handleGuardrailExplain(ctx.directory, ctx.args);
80700
80850
  },
80701
80851
  description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
@@ -80705,7 +80855,7 @@ var COMMAND_REGISTRY = {
80705
80855
  },
80706
80856
  "guardrail-reset": {
80707
80857
  handler: async (ctx) => {
80708
- const { handleGuardrailReset } = await import("./guardrail-reset-yjwk20rb.js");
80858
+ const { handleGuardrailReset } = await import("./guardrail-reset-chbc0mep.js");
80709
80859
  return handleGuardrailReset(ctx.args, ctx.sessionID);
80710
80860
  },
80711
80861
  description: "Reset one exact active invocation/action circuit after repair",
@@ -80715,7 +80865,7 @@ var COMMAND_REGISTRY = {
80715
80865
  },
80716
80866
  "guardrail-log": {
80717
80867
  handler: async (ctx) => {
80718
- const { handleGuardrailLog } = await import("./guardrail-log-f9nf687y.js");
80868
+ const { handleGuardrailLog } = await import("./guardrail-log-nerqk9qb.js");
80719
80869
  return handleGuardrailLog(ctx.directory, ctx.args);
80720
80870
  },
80721
80871
  description: "Read the guardrail decision log (use --blocks-only for blocks)",
@@ -86708,7 +86858,7 @@ function getDisplayFinalPromptPressure() {
86708
86858
  async function rehydratePrSubscriptions(sessionID, directory) {
86709
86859
  const map = new Map;
86710
86860
  try {
86711
- const { listActive: listActive2 } = await import("./pr-subscriptions-fvmey1x6.js");
86861
+ const { listActive: listActive2 } = await import("./pr-subscriptions-482gzvt6.js");
86712
86862
  const records = await listActive2(directory);
86713
86863
  for (const record of records) {
86714
86864
  if (record.sessionID !== sessionID)
@@ -87154,7 +87304,7 @@ function isLaneOwnedByCurrentSession(branchName, expectedSessionId) {
87154
87304
  return extracted === expectedSessionId;
87155
87305
  }
87156
87306
  async function inspectStandardWorktreeCollisionOwnership(identity) {
87157
- const collisionOwnership = await import("./worktree-collision-ownership-7kf9mm5z.js");
87307
+ const collisionOwnership = await import("./worktree-collision-ownership-cy24p5mr.js");
87158
87308
  return collisionOwnership.inspectStandardWorktreeCollisionOwnership(identity);
87159
87309
  }
87160
87310
  async function runRecoveryGit(directory, args, timeoutMs = 15000) {
@@ -87563,7 +87713,7 @@ async function precreateStandardWorktreeSession(args) {
87563
87713
  const laneProfile = computeLaneRuntimeProfile(worktreeConfig.runtime_isolation, laneIndex, handle.worktreePath);
87564
87714
  if (laneProfile) {
87565
87715
  try {
87566
- const { writeLaneProfileToDiskReal } = await import("./core-pp64ys5v.js");
87716
+ const { writeLaneProfileToDiskReal } = await import("./core-madqgdsc.js");
87567
87717
  await writeLaneProfileToDiskReal(handle.worktreePath, laneProfile.laneIndex, laneProfile.envOverrides);
87568
87718
  } catch {}
87569
87719
  }
@@ -88488,7 +88638,7 @@ async function finishStandardWorktreeDispatch(directory, dispatch, config, callI
88488
88638
  }
88489
88639
  clearWorktreeMergeStatus(statusKey);
88490
88640
  try {
88491
- const { removeLaneProfileFromDiskReal } = await import("./core-pp64ys5v.js");
88641
+ const { removeLaneProfileFromDiskReal } = await import("./core-madqgdsc.js");
88492
88642
  await removeLaneProfileFromDiskReal(dispatch.handle.worktreePath, dispatch.laneIndex);
88493
88643
  } catch {}
88494
88644
  const state = serializationStateBySessionID.get(dispatch.parentSessionID);