opencode-swarm 7.145.0 → 7.145.2

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 (105) hide show
  1. package/.opencode/skills/phase-wrap/SKILL.md +3 -2
  2. package/README.md +5 -1
  3. package/dist/background/workspace-snapshot.d.ts +29 -0
  4. package/dist/cli/{config-doctor-dzsv3pqy.js → config-doctor-j1r33f4q.js} +3 -3
  5. package/dist/cli/{core-qkh9me8x.js → core-c2zrd384.js} +4 -4
  6. package/dist/cli/{curation-policy-5x6346tf.js → curation-policy-xv0j8zyt.js} +6 -6
  7. package/dist/cli/{curator-zssndq5x.js → curator-gk2kmrk1.js} +31 -31
  8. package/dist/cli/{curator-llm-factory-q5p4578g.js → curator-llm-factory-sat3mn5n.js} +31 -31
  9. package/dist/cli/{evidence-summary-service-dqcpapj8.js → evidence-summary-service-0mhx0t0v.js} +14 -14
  10. package/dist/cli/{gate-evidence-bkdqryqg.js → gate-evidence-a5adh55x.js} +9 -9
  11. package/dist/cli/{guardrail-explain-kspf83x5.js → guardrail-explain-r50fery8.js} +32 -32
  12. package/dist/cli/{guardrail-log-qg4sq6gr.js → guardrail-log-p69eys6d.js} +4 -4
  13. package/dist/cli/{hive-promoter-3h7dhnek.js → hive-promoter-ay8a7sct.js} +31 -31
  14. package/dist/cli/{index-wk54ey3h.js → index-0a0asz2s.js} +1 -1
  15. package/dist/cli/{index-2dnqazyr.js → index-1g87esfp.js} +2 -2
  16. package/dist/cli/{index-0pcq32y2.js → index-2vefr1f8.js} +1 -1
  17. package/dist/cli/{index-fp464as8.js → index-4p3qfb05.js} +1 -1
  18. package/dist/cli/{index-77ef8gye.js → index-5e5a1y2r.js} +1 -1
  19. package/dist/cli/{index-0jr9zn34.js → index-612rr70a.js} +2 -2
  20. package/dist/cli/{index-apjdytwx.js → index-673axbjx.js} +3 -3
  21. package/dist/cli/{index-qfawexc8.js → index-6wf75rcm.js} +6 -6
  22. package/dist/cli/{index-k6pdsct6.js → index-7y5akvc9.js} +1 -1
  23. package/dist/cli/{index-hfzcztv6.js → index-9080b3de.js} +34 -34
  24. package/dist/cli/{index-v64kjqvg.js → index-917z76qr.js} +25 -18
  25. package/dist/cli/{index-ffdwj1an.js → index-97psh79d.js} +1 -1
  26. package/dist/cli/{index-kp87kr1a.js → index-9gt8g2qj.js} +4 -4
  27. package/dist/cli/{index-4e5a28h7.js → index-b9kxxd6k.js} +2 -2
  28. package/dist/cli/{index-pa86tpgt.js → index-bghwrr59.js} +1 -1
  29. package/dist/cli/{index-6ezbzd5e.js → index-cb2qtetk.js} +682 -181
  30. package/dist/cli/{index-v3y3qg48.js → index-cpg98bh1.js} +17 -1
  31. package/dist/cli/{index-c13ttmak.js → index-cxn95n7q.js} +180 -32
  32. package/dist/cli/{index-7g276m9m.js → index-czde45km.js} +3 -3
  33. package/dist/cli/{index-zfhe7vbb.js → index-gpnv14kq.js} +2 -2
  34. package/dist/cli/{index-6q3agdmr.js → index-j20fzn0w.js} +2 -2
  35. package/dist/cli/{index-mkks7jwg.js → index-jgb7mq2y.js} +4 -4
  36. package/dist/cli/{index-h4hasck4.js → index-jpppcckq.js} +4 -4
  37. package/dist/cli/{index-4evasm2b.js → index-kggqpefz.js} +5 -5
  38. package/dist/cli/{index-s6cwsnrw.js → index-n55a28zr.js} +254 -36
  39. package/dist/cli/{index-b3xret0a.js → index-ncfjxz9n.js} +5 -5
  40. package/dist/cli/{index-e00wbqw5.js → index-np4ytvvv.js} +2 -2
  41. package/dist/cli/{index-jy9bwa9k.js → index-nsr5b69r.js} +2 -2
  42. package/dist/cli/{index-zz5qsjd1.js → index-qyvjp0bq.js} +66 -38
  43. package/dist/cli/{index-6hqhyb0f.js → index-rk80jhef.js} +19 -5
  44. package/dist/cli/{index-4zwjc9sb.js → index-vav705md.js} +101 -4
  45. package/dist/cli/{index-s72naw1j.js → index-x8pm918t.js} +1 -1
  46. package/dist/cli/{index-b30x236n.js → index-z9yhhk6q.js} +96 -8
  47. package/dist/cli/index.js +32 -32
  48. package/dist/cli/{knowledge-escalator-w1mbaktt.js → knowledge-escalator-22apj3dj.js} +14 -14
  49. package/dist/cli/{knowledge-events-a0dj6gy6.js → knowledge-events-bx8xba9z.js} +12 -12
  50. package/dist/cli/{knowledge-link-mzdjvjsd.js → knowledge-link-82ew2yc4.js} +5 -5
  51. package/dist/cli/{knowledge-store-8kk3rghx.js → knowledge-store-nc71kfsg.js} +6 -6
  52. package/dist/cli/{knowledge-validator-91ym56e0.js → knowledge-validator-g8ne80v6.js} +8 -8
  53. package/dist/cli/model-preflight-7ea00h34.js +170 -0
  54. package/dist/cli/{pending-delegations-6vsrmw5w.js → pending-delegations-kkrczqv7.js} +3 -3
  55. package/dist/cli/{pr-subscriptions-zc3skxde.js → pr-subscriptions-2xn238xt.js} +3 -3
  56. package/dist/cli/{runner-jj32v8bk.js → runner-pqsf809k.js} +6 -6
  57. package/dist/cli/{scan-cursor-12jxwd14.js → scan-cursor-6ksgv514.js} +7 -7
  58. package/dist/cli/{schema-nq9tcz87.js → schema-mpcm7nje.js} +2 -2
  59. package/dist/cli/{scope-persistence-dv6z7n08.js → scope-persistence-mj1w3hqw.js} +11 -8
  60. package/dist/cli/{skill-generator-drscnzq9.js → skill-generator-gsa6qwwt.js} +16 -16
  61. package/dist/cli/{telemetry-z54dgdrh.js → telemetry-t109dhv7.js} +1 -1
  62. package/dist/cli/{workspace-snapshot-q21mgbsh.js → workspace-snapshot-kznz5e13.js} +4 -2
  63. package/dist/cli/{worktree-collision-ownership-rfyyjjct.js → worktree-collision-ownership-2jtg2my1.js} +8 -8
  64. package/dist/cli/{worktree-isolation-4tehtym5.js → worktree-isolation-ajzyp2gm.js} +33 -31
  65. package/dist/config/schema.d.ts +2 -2
  66. package/dist/evidence/task-gate-repair.d.ts +26 -0
  67. package/dist/evidence/task-gate-requirements.d.ts +20 -0
  68. package/dist/gate-evidence.d.ts +7 -0
  69. package/dist/hooks/delegation-gate/worktree-isolation.d.ts +4 -0
  70. package/dist/hooks/knowledge-receipt-ledger-storage.d.ts +2 -0
  71. package/dist/hooks/knowledge-receipt-ledger.d.ts +72 -3
  72. package/dist/hooks/knowledge-receipt-observability.d.ts +1 -1
  73. package/dist/hooks/phase-complete-directive-gate.d.ts +9 -0
  74. package/dist/index.js +566 -546
  75. package/dist/observability/catalog.d.ts +2 -2
  76. package/dist/plan/manager.d.ts +8 -0
  77. package/dist/review/diff-source.d.ts +30 -0
  78. package/dist/review/engine.d.ts +1 -0
  79. package/dist/review/evidence.d.ts +16 -2
  80. package/dist/review/phase-runner.d.ts +1 -0
  81. package/dist/scope/scope-binding.d.ts +16 -0
  82. package/dist/services/model-preflight.d.ts +151 -0
  83. package/dist/services/session-reflection.d.ts +24 -0
  84. package/dist/telemetry.d.ts +12 -1
  85. package/dist/tools/completion-verify.d.ts +2 -0
  86. package/dist/tools/convene-council.d.ts +1 -1
  87. package/dist/tools/index.d.ts +4 -0
  88. package/dist/tools/manifest.d.ts +4 -0
  89. package/dist/tools/phase-complete/gates/final-review-gate.d.ts +3 -3
  90. package/dist/tools/phase-complete/gates/types.d.ts +2 -2
  91. package/dist/tools/phase-complete/preflight-report.d.ts +66 -0
  92. package/dist/tools/phase-complete/snapshot-identity.d.ts +1 -0
  93. package/dist/tools/phase-complete.d.ts +66 -3
  94. package/dist/tools/placeholder-scan.d.ts +64 -0
  95. package/dist/tools/record-directive-override.d.ts +14 -0
  96. package/dist/tools/repair-gate-evidence.d.ts +6 -0
  97. package/dist/tools/repair-knowledge-receipt-ledger.d.ts +27 -0
  98. package/dist/tools/run-phase-review.d.ts +37 -0
  99. package/dist/tools/sast-scan.d.ts +6 -0
  100. package/dist/tools/submit-phase-council-verdicts.d.ts +1 -1
  101. package/dist/tools/tool-metadata.d.ts +32 -16
  102. package/dist/tools/write-final-council-evidence.d.ts +1 -1
  103. package/dist/tools/write-retro.d.ts +2 -0
  104. package/package.json +1 -1
  105. package/dist/cli/{curator-drift-yn5d0mvq.js → curator-drift-r50x1rac.js} +1 -1
@@ -1,13 +1,21 @@
1
1
  // @bun
2
+ import {
3
+ captureWorkingTreeFingerprint,
4
+ createModelEvaluationExecutor,
5
+ pLimit,
6
+ resolveExecutableFromPath,
7
+ runEvaluation,
8
+ runExternalTool
9
+ } from "./index-0a0asz2s.js";
2
10
  import {
3
11
  stableCanonicalStringify
4
- } from "./index-2dnqazyr.js";
12
+ } from "./index-1g87esfp.js";
5
13
  import {
6
14
  detectStraySwarmDirs,
7
15
  readDoctorArtifact,
8
16
  removeStraySwarmDir,
9
17
  runConfigDoctor
10
- } from "./index-0jr9zn34.js";
18
+ } from "./index-612rr70a.js";
11
19
  import {
12
20
  MAX_TRANSIENT_RETRIES,
13
21
  archiveEvidence,
@@ -52,27 +60,7 @@ import {
52
60
  updateTaskStatus,
53
61
  validateProjectRoot,
54
62
  validateSymlinkBoundary
55
- } from "./index-v64kjqvg.js";
56
- import {
57
- loadDatabaseCtor
58
- } from "./index-134d35c1.js";
59
- import {
60
- LANGUAGE_REGISTRY,
61
- _internals as _internals3,
62
- _internals1 as _internals4,
63
- buildNativeTargetCommand,
64
- getProfileForFile,
65
- isCommandAvailable,
66
- tool
67
- } from "./index-abtrcs16.js";
68
- import {
69
- captureWorkingTreeFingerprint,
70
- createModelEvaluationExecutor,
71
- pLimit,
72
- resolveExecutableFromPath,
73
- runEvaluation,
74
- runExternalTool
75
- } from "./index-wk54ey3h.js";
63
+ } from "./index-917z76qr.js";
76
64
  import {
77
65
  EvaluationTaskV1Schema,
78
66
  GateAuditManifestV1Schema,
@@ -89,7 +77,19 @@ import {
89
77
  saveGateAuditResult,
90
78
  savePromotionDecision,
91
79
  saveTaskSetSnapshot
92
- } from "./index-jy9bwa9k.js";
80
+ } from "./index-nsr5b69r.js";
81
+ import {
82
+ loadDatabaseCtor
83
+ } from "./index-134d35c1.js";
84
+ import {
85
+ LANGUAGE_REGISTRY,
86
+ _internals as _internals3,
87
+ _internals1 as _internals4,
88
+ buildNativeTargetCommand,
89
+ getProfileForFile,
90
+ isCommandAvailable,
91
+ tool
92
+ } from "./index-abtrcs16.js";
93
93
  import {
94
94
  canonicalHash,
95
95
  canonicalJson,
@@ -101,11 +101,14 @@ import {
101
101
  resolveContainedExistingPath,
102
102
  sha256
103
103
  } from "./index-y8552snf.js";
104
+ import {
105
+ readRecentEscalations
106
+ } from "./index-ncfjxz9n.js";
104
107
  import {
105
108
  alreadyCuratedThisGeneration,
106
109
  claimNextScanBatch,
107
110
  resolveCohortId
108
- } from "./index-e00wbqw5.js";
111
+ } from "./index-np4ytvvv.js";
109
112
  import {
110
113
  CURATOR_INIT_PROMPT,
111
114
  CURATOR_PHASE_PROMPT,
@@ -148,13 +151,13 @@ import {
148
151
  resolveRemoteRefsContainingHead,
149
152
  resolveRemoteRefsContainingHeadAsync,
150
153
  switchPrFeedbackTrackingCandidateAsync
151
- } from "./index-b30x236n.js";
154
+ } from "./index-z9yhhk6q.js";
152
155
  import {
153
156
  buildCorrelationId,
154
157
  listActive,
155
158
  subscribe,
156
159
  unsubscribe
157
- } from "./index-77ef8gye.js";
160
+ } from "./index-5e5a1y2r.js";
158
161
  import {
159
162
  BUNDLED_PROJECT_SKILL_ROOT,
160
163
  DEFAULT_SKILL_MIN_CONFIDENCE,
@@ -175,10 +178,7 @@ import {
175
178
  retireSkill,
176
179
  selectCandidateEntries,
177
180
  syncBundledProjectSkillsIfMissingAsync
178
- } from "./index-mkks7jwg.js";
179
- import {
180
- readRecentEscalations
181
- } from "./index-b3xret0a.js";
181
+ } from "./index-jgb7mq2y.js";
182
182
  import {
183
183
  appendUnactionable,
184
184
  quarantineEntry,
@@ -189,11 +189,11 @@ import {
189
189
  validateActionableFields,
190
190
  validateLesson,
191
191
  validateSkillPath
192
- } from "./index-h4hasck4.js";
192
+ } from "./index-jpppcckq.js";
193
193
  import {
194
194
  authorizeCuration,
195
195
  buildConfigFingerprintInput
196
- } from "./index-fp464as8.js";
196
+ } from "./index-4p3qfb05.js";
197
197
  import {
198
198
  cohortConfigFingerprint
199
199
  } from "./index-rtry5xyf.js";
@@ -212,7 +212,7 @@ import {
212
212
  findByBatchId,
213
213
  readDelegations,
214
214
  sweepStaleDelegations
215
- } from "./index-ffdwj1an.js";
215
+ } from "./index-97psh79d.js";
216
216
  import {
217
217
  WORKTREE_LIFECYCLE_LOCK_FILE,
218
218
  recordWorktreeProvisioningOwner,
@@ -242,18 +242,18 @@ import {
242
242
  startupOrphanRecovery,
243
243
  withTaskEvidenceTransaction,
244
244
  writeWorkflowWalFile
245
- } from "./index-s6cwsnrw.js";
245
+ } from "./index-n55a28zr.js";
246
246
  import {
247
247
  provisionWorktree,
248
248
  removeWorktree
249
- } from "./index-6hqhyb0f.js";
249
+ } from "./index-rk80jhef.js";
250
250
  import {
251
251
  MAX_PENDING_SCOPE_BINDINGS,
252
252
  canonicalWorkspaceIdentity,
253
253
  clearAllScopes,
254
254
  clearScopeBindingFromDisk,
255
255
  clearScopeBindings
256
- } from "./index-4zwjc9sb.js";
256
+ } from "./index-vav705md.js";
257
257
  import {
258
258
  appendLedgerEvent,
259
259
  computePlanHash,
@@ -262,11 +262,12 @@ import {
262
262
  derivePlanIdentityHash,
263
263
  getOrAdoptPlanEpochUnderLock,
264
264
  initLedger,
265
+ ledgerExists,
265
266
  readLedgerEvents,
266
267
  readPlanEpochIdentity,
267
268
  replayFromLedgerWithStatus,
268
269
  takeSnapshotEvent
269
- } from "./index-apjdytwx.js";
270
+ } from "./index-673axbjx.js";
270
271
  import {
271
272
  isPathWithinDeclaredScope,
272
273
  sanitizeDiagnosticText
@@ -317,7 +318,7 @@ import {
317
318
  transactFile,
318
319
  transactKnowledge,
319
320
  wordBigrams
320
- } from "./index-qfawexc8.js";
321
+ } from "./index-6wf75rcm.js";
321
322
  import {
322
323
  MAX_EVENT_LOG_ENTRIES,
323
324
  _internals as _internals2,
@@ -331,31 +332,20 @@ import {
331
332
  recordKnowledgeEvent,
332
333
  recordPhaseCloseIntent,
333
334
  resolveKnowledgeEventsPath
334
- } from "./index-c13ttmak.js";
335
+ } from "./index-cxn95n7q.js";
335
336
  import {
336
337
  resolveWorktreeIsolationConfig
337
- } from "./index-7g276m9m.js";
338
+ } from "./index-czde45km.js";
338
339
  import {
339
340
  RetrospectiveEvidenceSchema
340
341
  } from "./index-gprxjmm7.js";
341
- import {
342
- readSwarmFileAsync,
343
- safeHook,
344
- validateSwarmPath
345
- } from "./index-w8pgjr75.js";
346
- import {
347
- bunSpawn,
348
- bunSpawnSync,
349
- bunWrite,
350
- mergeEnvForChild
351
- } from "./index-zj6t9zgx.js";
352
342
  import {
353
343
  PlanSchema,
354
344
  exports_loader,
355
345
  init_loader,
356
346
  loadPluginConfig,
357
347
  loadPluginConfigWithMeta
358
- } from "./index-0pcq32y2.js";
348
+ } from "./index-2vefr1f8.js";
359
349
  import {
360
350
  DEFAULT_SKILL_OPT_CONFIG,
361
351
  FALLBACK_MODELS_MAX,
@@ -369,7 +359,7 @@ import {
369
359
  package_default,
370
360
  resolveAutoReviewConfig,
371
361
  stripKnownSwarmPrefix
372
- } from "./index-zfhe7vbb.js";
362
+ } from "./index-gpnv14kq.js";
373
363
  import {
374
364
  AGENT_TOOL_MAP,
375
365
  ALL_AGENT_NAMES,
@@ -383,7 +373,7 @@ import {
383
373
  init_agent_names,
384
374
  init_constants,
385
375
  init_tool_metadata
386
- } from "./index-v3y3qg48.js";
376
+ } from "./index-cpg98bh1.js";
387
377
  import {
388
378
  init_git_executable,
389
379
  resolveGitExecutable,
@@ -394,6 +384,17 @@ import {
394
384
  getDeferredWarnings,
395
385
  init_warning_buffer
396
386
  } from "./index-4rhhvd1a.js";
387
+ import {
388
+ readSwarmFileAsync,
389
+ safeHook,
390
+ validateSwarmPath
391
+ } from "./index-w8pgjr75.js";
392
+ import {
393
+ bunSpawn,
394
+ bunSpawnSync,
395
+ bunWrite,
396
+ mergeEnvForChild
397
+ } from "./index-zj6t9zgx.js";
397
398
  import {
398
399
  resolveHiveDataDir,
399
400
  resolveHiveEventsPath,
@@ -409,10 +410,10 @@ import {
409
410
  resolveLinkDir,
410
411
  sanitizeLinkId,
411
412
  writeLinkPointer
412
- } from "./index-s72naw1j.js";
413
+ } from "./index-x8pm918t.js";
413
414
  import {
414
415
  atomicWriteFile
415
- } from "./index-6q3agdmr.js";
416
+ } from "./index-j20fzn0w.js";
416
417
  import {
417
418
  KNOWLEDGE_SCHEMA_VERSION,
418
419
  OUTCOME_BLOCK_THRESHOLD,
@@ -424,7 +425,7 @@ import {
424
425
  atomicWriteSwarmFileSync,
425
426
  matchTempGrammar,
426
427
  parseTargetBasename
427
- } from "./index-4evasm2b.js";
428
+ } from "./index-kggqpefz.js";
428
429
  import {
429
430
  assertProjectRoot,
430
431
  hasExplicitProjectBoundary,
@@ -432,12 +433,12 @@ import {
432
433
  listActiveLocks,
433
434
  tryAcquireLock,
434
435
  withEvidenceLock
435
- } from "./index-pa86tpgt.js";
436
+ } from "./index-bghwrr59.js";
436
437
  import {
437
438
  emit,
438
439
  getLastHeartbeat,
439
440
  telemetry
440
- } from "./index-zz5qsjd1.js";
441
+ } from "./index-qyvjp0bq.js";
441
442
  import {
442
443
  require_proper_lockfile
443
444
  } from "./index-7g4c7s5r.js";
@@ -464,7 +465,7 @@ import {
464
465
 
465
466
  // src/hooks/delegation-gate/worktree-isolation.ts
466
467
  init_constants();
467
- import { createHash as createHash22 } from "crypto";
468
+ import { createHash as createHash23 } from "crypto";
468
469
  import * as fs53 from "fs/promises";
469
470
  import * as path113 from "path";
470
471
  init_executor();
@@ -940,6 +941,7 @@ init_zod();
940
941
  import * as fs51 from "fs";
941
942
  import * as path111 from "path";
942
943
  init_agent_names();
944
+ init_constants();
943
945
  init_schema();
944
946
 
945
947
  // src/full-auto/policy.ts
@@ -4191,7 +4193,7 @@ async function cleanupRecoveredWorktree(directory, descriptor) {
4191
4193
  awaitingMergeByCallID,
4192
4194
  cleanupStandardWorktreeForCallId,
4193
4195
  standardWorktreeByCallID
4194
- } = await import("./worktree-isolation-4tehtym5.js");
4196
+ } = await import("./worktree-isolation-ajzyp2gm.js");
4195
4197
  standardWorktreeByCallID.delete(descriptor.callID);
4196
4198
  if (hasResidue)
4197
4199
  awaitingMergeByCallID.set(descriptor.callID, {
@@ -4293,7 +4295,7 @@ async function recoverCoderSettlement(directory, taskId) {
4293
4295
  awaitingMergeByCallID,
4294
4296
  finishStandardWorktreeDispatch,
4295
4297
  standardWorktreeByCallID
4296
- } = await import("./worktree-isolation-4tehtym5.js");
4298
+ } = await import("./worktree-isolation-ajzyp2gm.js");
4297
4299
  const descriptor = wal.worktree;
4298
4300
  const reconstructedDispatch = {
4299
4301
  callID: descriptor.callID,
@@ -15556,7 +15558,7 @@ function planMerges(active, threshold, maxComparisons, maxMerges) {
15556
15558
  };
15557
15559
  }
15558
15560
  async function sweepActiveNearDuplicates(directory, options = {}) {
15559
- const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-kp87kr1a.js");
15561
+ const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-9gt8g2qj.js");
15560
15562
  const { config } = loadPluginConfigWithMeta2(directory);
15561
15563
  const sweepConfig = config.learning?.dedup_sweep;
15562
15564
  if (sweepConfig?.enabled === false)
@@ -16640,7 +16642,7 @@ async function runCuratorPhase(directory, phase, agentsDispatched, config, knowl
16640
16642
  }
16641
16643
  if (config.skill_generation_enabled === true && skillCandidates.length > 0) {
16642
16644
  try {
16643
- const skillModule = await import("./skill-generator-drscnzq9.js");
16645
+ const skillModule = await import("./skill-generator-gsa6qwwt.js");
16644
16646
  for (const cand of skillCandidates) {
16645
16647
  if (cand.confidence < (config.min_skill_confidence ?? DEFAULT_SKILL_MIN_CONFIDENCE)) {
16646
16648
  continue;
@@ -17100,7 +17102,7 @@ async function applyCuratorKnowledgeUpdates(directory, recommendations, knowledg
17100
17102
  } catch {}
17101
17103
  }
17102
17104
  if (contradictedEntries.length > 0 && knowledgeConfig.contradiction_threshold_action === "quarantine") {
17103
- const { maybeQuarantineOnContradiction } = await import("./knowledge-escalator-w1mbaktt.js");
17105
+ const { maybeQuarantineOnContradiction } = await import("./knowledge-escalator-22apj3dj.js");
17104
17106
  for (const { id } of contradictedEntries) {
17105
17107
  try {
17106
17108
  await maybeQuarantineOnContradiction(directory, id, knowledgeConfig.contradiction_quarantine_threshold, knowledgeConfig.contradiction_quarantine_window_days);
@@ -17919,7 +17921,7 @@ async function runCuratorPostMortem(directory, options = {}) {
17919
17921
  warnings.push("Failed to collect knowledge summary.");
17920
17922
  }
17921
17923
  try {
17922
- const { getScanStatus } = await import("./scan-cursor-12jxwd14.js");
17924
+ const { getScanStatus } = await import("./scan-cursor-6ksgv514.js");
17923
17925
  const scanStatus = await getScanStatus(directory);
17924
17926
  if (scanStatus.remaining_estimate > 0) {
17925
17927
  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.`);
@@ -18091,9 +18093,9 @@ var _internals24 = {
18091
18093
  verifyPostMortemKnowledgeActions,
18092
18094
  repairPostMortemActions,
18093
18095
  loadDefaultKnowledgeConfig: async (directory) => {
18094
- const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-nq9tcz87.js");
18096
+ const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-mpcm7nje.js");
18095
18097
  try {
18096
- const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-kp87kr1a.js");
18098
+ const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-9gt8g2qj.js");
18097
18099
  const loaded = loadPluginConfigWithMeta2(directory);
18098
18100
  return KnowledgeConfigSchema2.parse(loaded.config.knowledge ?? {});
18099
18101
  } catch {
@@ -18101,11 +18103,11 @@ var _internals24 = {
18101
18103
  }
18102
18104
  },
18103
18105
  applyCuratorKnowledgeUpdates: async (directory, recommendations, knowledgeConfig, generation) => {
18104
- const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-zssndq5x.js");
18106
+ const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-gk2kmrk1.js");
18105
18107
  return applyCuratorKnowledgeUpdates2(directory, recommendations, knowledgeConfig, generation);
18106
18108
  },
18107
18109
  checkHivePromotions: async (entries, knowledgeConfig, directory) => {
18108
- const { checkHivePromotions } = await import("./hive-promoter-3h7dhnek.js");
18110
+ const { checkHivePromotions } = await import("./hive-promoter-ay8a7sct.js");
18109
18111
  return checkHivePromotions(entries, knowledgeConfig, directory);
18110
18112
  },
18111
18113
  applyProposalTriage: async (directory, triage) => {
@@ -18114,7 +18116,7 @@ var _internals24 = {
18114
18116
  activateProposal,
18115
18117
  listSkills: listSkills2,
18116
18118
  sanitizeSlug
18117
- } = await import("./skill-generator-drscnzq9.js");
18119
+ } = await import("./skill-generator-gsa6qwwt.js");
18118
18120
  const result = {
18119
18121
  approved: [],
18120
18122
  rejected: [],
@@ -18156,7 +18158,7 @@ var _internals24 = {
18156
18158
  return result;
18157
18159
  },
18158
18160
  readPriorDriftReports: async (directory) => {
18159
- const { readPriorDriftReports } = await import("./curator-drift-yn5d0mvq.js");
18161
+ const { readPriorDriftReports } = await import("./curator-drift-r50x1rac.js");
18160
18162
  return readPriorDriftReports(directory);
18161
18163
  },
18162
18164
  readSwarmKnowledge: (directory) => readKnowledge(resolveSwarmKnowledgePath(directory))
@@ -19450,9 +19452,9 @@ function hashContent(content) {
19450
19452
  return createHash7("sha1").update(content).digest("hex");
19451
19453
  }
19452
19454
  async function loadConfigForPolicyCurator(directory) {
19453
- const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-nq9tcz87.js");
19455
+ const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-mpcm7nje.js");
19454
19456
  try {
19455
- const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-kp87kr1a.js");
19457
+ const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-9gt8g2qj.js");
19456
19458
  const { config: loadedConfig } = loadPluginConfigWithMeta2(directory);
19457
19459
  return KnowledgeConfigSchema2.parse(loadedConfig.knowledge ?? {});
19458
19460
  } catch {
@@ -26227,6 +26229,78 @@ async function gatherGateFailures(directory) {
26227
26229
  } catch {}
26228
26230
  return [...failures.values()].sort((a, b) => b.count - a.count);
26229
26231
  }
26232
+ var REJECTION_LEDGER_EVENT_TYPES = new Set([
26233
+ "coder_retry_circuit_breaker",
26234
+ "plan_critic_gate_manual_approval",
26235
+ "architect_loop_detected",
26236
+ "agent_conflict_detected"
26237
+ ]);
26238
+ var MAX_LEDGER_BYTES = 16 * 1024 * 1024;
26239
+ async function gatherLedgerRejections(directory, sessionId) {
26240
+ const counts = {};
26241
+ const readLedger = async (filePath) => {
26242
+ try {
26243
+ const handle = await fs13.open(filePath, "r");
26244
+ try {
26245
+ const stat5 = await handle.stat();
26246
+ if (!stat5.isFile())
26247
+ return null;
26248
+ const length = Math.min(stat5.size, MAX_LEDGER_BYTES);
26249
+ const buffer = Buffer.alloc(length);
26250
+ await handle.read(buffer, 0, length, stat5.size - length);
26251
+ return buffer.toString("utf-8");
26252
+ } finally {
26253
+ await handle.close().catch(() => {});
26254
+ }
26255
+ } catch {
26256
+ return null;
26257
+ }
26258
+ };
26259
+ const readContained = async (root, ...segments) => {
26260
+ const target = path36.join(root, ...segments);
26261
+ try {
26262
+ const realRoot = await fs13.realpath(path36.join(root));
26263
+ const realTarget = await fs13.realpath(target);
26264
+ const rel = path36.relative(realRoot, realTarget);
26265
+ if (rel.startsWith("..") || path36.isAbsolute(rel))
26266
+ return null;
26267
+ } catch {
26268
+ return null;
26269
+ }
26270
+ return readLedger(target);
26271
+ };
26272
+ let content = await readLedger(path36.join(directory, ".swarm", "events.jsonl"));
26273
+ if (content === null) {
26274
+ try {
26275
+ const archiveRoot = path36.join(directory, ".swarm", "archive");
26276
+ const archiveEntries = await fs13.readdir(archiveRoot);
26277
+ const archives = archiveEntries.filter((entry) => entry.startsWith("swarm-")).sort();
26278
+ for (let index = archives.length - 1;index >= 0 && content === null; index--) {
26279
+ content = await readContained(archiveRoot, archives[index], "events.jsonl");
26280
+ }
26281
+ } catch {}
26282
+ }
26283
+ if (content === null)
26284
+ return counts;
26285
+ for (const line of content.split(`
26286
+ `)) {
26287
+ const trimmed = line.trim();
26288
+ if (!trimmed)
26289
+ continue;
26290
+ try {
26291
+ const parsed = JSON.parse(trimmed);
26292
+ if (typeof parsed.type === "string" && REJECTION_LEDGER_EVENT_TYPES.has(parsed.type)) {
26293
+ if (sessionId !== undefined) {
26294
+ const eventSession = typeof parsed.sessionId === "string" ? parsed.sessionId : typeof parsed.sessionID === "string" ? parsed.sessionID : undefined;
26295
+ if (eventSession !== undefined && eventSession !== sessionId)
26296
+ continue;
26297
+ }
26298
+ counts[parsed.type] = (counts[parsed.type] ?? 0) + 1;
26299
+ }
26300
+ } catch {}
26301
+ }
26302
+ return counts;
26303
+ }
26230
26304
  var CONTRADICTION_LOWER = 0.45;
26231
26305
  var CONTRADICTION_SESSION_CAP = 50;
26232
26306
  var CONTRADICTION_PAIR_CAP = 10;
@@ -26581,8 +26655,22 @@ function buildDeterministicReport(data) {
26581
26655
  const lines = [];
26582
26656
  lines.push("## Problems Encountered");
26583
26657
  lines.push("");
26658
+ const ledgerEntries = Object.entries(data.ledgerRejections ?? {}).filter(([, count]) => count > 0).sort((a, b) => b[1] - a[1]);
26659
+ const ledgerTotal = ledgerEntries.reduce((sum, [, count]) => sum + count, 0);
26660
+ const ledgerLines = () => {
26661
+ if (ledgerTotal === 0)
26662
+ return;
26663
+ lines.push(`${ledgerTotal} rejection/circuit-breaker event(s) in the session ledger (events.jsonl):`);
26664
+ for (const [type, count] of ledgerEntries.slice(0, 8)) {
26665
+ lines.push(`- ${type}: ${count}`);
26666
+ }
26667
+ };
26584
26668
  if (data.totalToolFailures === 0 && data.gateFailures.length === 0) {
26585
- lines.push("No tool failures or gate rejections recorded this session.");
26669
+ if (ledgerTotal > 0) {
26670
+ ledgerLines();
26671
+ } else {
26672
+ lines.push("No tool failures or gate rejections recorded this session.");
26673
+ }
26586
26674
  lines.push("");
26587
26675
  } else {
26588
26676
  if (data.totalToolFailures > 0) {
@@ -26603,6 +26691,10 @@ function buildDeterministicReport(data) {
26603
26691
  lines.push(`- ${cat}: ${count} occurrence(s)`);
26604
26692
  }
26605
26693
  }
26694
+ if (ledgerTotal > 0) {
26695
+ lines.push("");
26696
+ ledgerLines();
26697
+ }
26606
26698
  lines.push("");
26607
26699
  }
26608
26700
  if (data.toolProblems.length > 0) {
@@ -26624,7 +26716,7 @@ function buildDeterministicReport(data) {
26624
26716
  }
26625
26717
  lines.push("## Process Improvements");
26626
26718
  lines.push("");
26627
- if (data.totalToolFailures === 0 && data.gateFailures.length === 0 && data.lessonsFromRetros.length === 0) {
26719
+ if (data.totalToolFailures === 0 && data.gateFailures.length === 0 && ledgerTotal === 0 && data.lessonsFromRetros.length === 0) {
26628
26720
  lines.push("Session completed without notable issues.");
26629
26721
  } else {
26630
26722
  lines.push("_Deterministic fallback: no LLM client available for deep analysis. Review the data above manually._");
@@ -26638,6 +26730,7 @@ async function runSessionReflection(input) {
26638
26730
  const agentDispatches = gatherAgentDispatches(input.agentSessions);
26639
26731
  const { lessons, taxonomy } = await gatherRetroLessonsAndTaxonomy(input.directory);
26640
26732
  const gateFailures = await gatherGateFailures(input.directory);
26733
+ const ledgerRejections = await _internals32.gatherLedgerRejections(input.directory, input.sessionId);
26641
26734
  const skillViolations = _internals32.gatherSkillViolations(input.directory, input.sessionId);
26642
26735
  const contradictionCandidates = await _internals32.gatherContradictionCandidates(input.directory, input.sessionStart, input.dedupThreshold ?? DEFAULT_DEDUP_THRESHOLD2);
26643
26736
  const realtimeCounts = await _internals32.gatherRealtimeAdmissionCounts(input.directory, input.sessionStart);
@@ -26658,7 +26751,8 @@ async function runSessionReflection(input) {
26658
26751
  errorTaxonomy: taxonomy,
26659
26752
  knowledgeDelta,
26660
26753
  skillViolations,
26661
- contradictionCandidates
26754
+ contradictionCandidates,
26755
+ ledgerRejections
26662
26756
  };
26663
26757
  const signalsReport = buildSignalsBlock(data);
26664
26758
  const actionProposals = buildActionProposals(data);
@@ -26705,6 +26799,7 @@ var _internals32 = {
26705
26799
  gatherAgentDispatches,
26706
26800
  gatherRetroLessonsAndTaxonomy,
26707
26801
  gatherGateFailures,
26802
+ gatherLedgerRejections,
26708
26803
  buildReflectionDataSummary,
26709
26804
  buildDeterministicReport,
26710
26805
  gatherSkillViolations,
@@ -28433,12 +28528,20 @@ async function executeWriteRetro(args, directory) {
28433
28528
  }
28434
28529
  }
28435
28530
  const taskId = args.task_id ?? `retro-${phase}`;
28531
+ if (args.verdict !== "pass" && args.verdict !== "fail") {
28532
+ return JSON.stringify({
28533
+ success: false,
28534
+ phase,
28535
+ reason: "RETRO_VERDICT_REQUIRED",
28536
+ message: 'Invalid verdict: write_retro requires an explicit verdict of "pass" or "fail".'
28537
+ }, null, 2);
28538
+ }
28436
28539
  const retroEntry = {
28437
28540
  task_id: taskId,
28438
28541
  type: "retrospective",
28439
28542
  timestamp: new Date().toISOString(),
28440
28543
  agent: "architect",
28441
- verdict: "pass",
28544
+ verdict: args.verdict,
28442
28545
  summary,
28443
28546
  metadata: args.metadata,
28444
28547
  phase_number: phase,
@@ -28527,6 +28630,7 @@ var write_retro = createSwarmTool({
28527
28630
  description: "Write a retrospective evidence bundle for a completed phase. " + "Accepts flat retro fields and writes a correctly-wrapped EvidenceBundle to " + ".swarm/evidence/retro-{phase}/evidence.json. " + "Use this instead of manually writing retro JSON to avoid schema validation failures in phase_complete.",
28528
28631
  args: {
28529
28632
  phase: exports_external.number().int().min(1).max(99).describe("The phase number being completed (e.g., 1, 2, 3)"),
28633
+ verdict: exports_external.enum(["pass", "fail"]).describe("Explicit retrospective verdict for the phase"),
28530
28634
  summary: exports_external.string().describe("Human-readable summary of the phase"),
28531
28635
  task_count: exports_external.number().int().min(1).max(9999).describe("Count of tasks completed in this phase"),
28532
28636
  task_complexity: exports_external.enum(["trivial", "simple", "moderate", "complex"]).describe("Complexity level of the completed tasks"),
@@ -28548,6 +28652,7 @@ var write_retro = createSwarmTool({
28548
28652
  try {
28549
28653
  const writeRetroArgs = {
28550
28654
  phase: Number(args.phase),
28655
+ verdict: args.verdict,
28551
28656
  summary: String(args.summary ?? ""),
28552
28657
  task_count: Number(args.task_count),
28553
28658
  task_complexity: args.task_complexity,
@@ -29280,6 +29385,7 @@ async function runFinalizeStage(ctx) {
29280
29385
  try {
29281
29386
  retroResult = await executeWriteRetro({
29282
29387
  phase: phase.id,
29388
+ verdict: ctx.isForced ? "fail" : "pass",
29283
29389
  summary: ctx.isForced ? `Phase force-closed via /swarm close --force` : `Phase closed via /swarm close`,
29284
29390
  task_count: Math.max(1, (phase.tasks ?? []).length),
29285
29391
  task_complexity: "simple",
@@ -29327,6 +29433,7 @@ async function runFinalizeStage(ctx) {
29327
29433
  try {
29328
29434
  const sessionRetroResult = await executeWriteRetro({
29329
29435
  phase: 1,
29436
+ verdict: ctx.isForced ? "fail" : "pass",
29330
29437
  task_id: "retro-session",
29331
29438
  summary: ctx.isForced ? "Plan-free session force-closed via /swarm close --force" : "Plan-free session closed via /swarm close",
29332
29439
  task_count: 1,
@@ -29579,7 +29686,7 @@ async function runFinalizeStage(ctx) {
29579
29686
  }
29580
29687
  }
29581
29688
  try {
29582
- const { CuratorConfigSchema: CCS } = await import("./schema-nq9tcz87.js");
29689
+ const { CuratorConfigSchema: CCS } = await import("./schema-mpcm7nje.js");
29583
29690
  const { config: pmLoadedConfig } = _internals38.loadPluginConfigWithMeta(ctx.directory);
29584
29691
  const curatorCfg = CCS.parse(pmLoadedConfig.curator ?? {});
29585
29692
  if (curatorCfg.enabled && curatorCfg.postmortem_enabled) {
@@ -30437,7 +30544,7 @@ var _internals38 = {
30437
30544
  closePlanTerminalState: reconcileCloseTerminalStateForPlan,
30438
30545
  endAgentSession,
30439
30546
  flushAndDrainTelemetry: async () => {
30440
- const { flushAndDrainTelemetry } = await import("./telemetry-z54dgdrh.js");
30547
+ const { flushAndDrainTelemetry } = await import("./telemetry-t109dhv7.js");
30441
30548
  return flushAndDrainTelemetry();
30442
30549
  }
30443
30550
  };
@@ -31843,9 +31950,9 @@ var _internals43 = {
31843
31950
  loadPluginConfigWithMeta,
31844
31951
  loadCuratorDeps: async () => {
31845
31952
  const [{ CuratorConfigSchema }, curator, { createCuratorLLMDelegate: createCuratorLLMDelegate2 }] = await Promise.all([
31846
- import("./schema-nq9tcz87.js"),
31847
- import("./curator-zssndq5x.js"),
31848
- import("./curator-llm-factory-q5p4578g.js")
31953
+ import("./schema-mpcm7nje.js"),
31954
+ import("./curator-gk2kmrk1.js"),
31955
+ import("./curator-llm-factory-sat3mn5n.js")
31849
31956
  ]);
31850
31957
  return { CuratorConfigSchema, curator, createCuratorLLMDelegate: createCuratorLLMDelegate2 };
31851
31958
  }
@@ -32799,7 +32906,7 @@ async function computeCurationDiagnostics(directory, entries) {
32799
32906
  let scanCompleted = false;
32800
32907
  let scanRemaining = 0;
32801
32908
  try {
32802
- const { getScanStatus } = await import("./scan-cursor-12jxwd14.js");
32909
+ const { getScanStatus } = await import("./scan-cursor-6ksgv514.js");
32803
32910
  const status = await getScanStatus(directory);
32804
32911
  scanGeneration = status.generation;
32805
32912
  scanCompleted = status.completed;
@@ -32807,19 +32914,19 @@ async function computeCurationDiagnostics(directory, entries) {
32807
32914
  } catch {}
32808
32915
  let configMatch = null;
32809
32916
  try {
32810
- const { isLinked: isLinked2 } = await import("./knowledge-link-mzdjvjsd.js");
32917
+ const { isLinked: isLinked2 } = await import("./knowledge-link-82ew2yc4.js");
32811
32918
  if (isLinked2(directory)) {
32812
- const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-nq9tcz87.js");
32919
+ const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-mpcm7nje.js");
32813
32920
  let config;
32814
32921
  try {
32815
- const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-kp87kr1a.js");
32922
+ const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-9gt8g2qj.js");
32816
32923
  const loaded = loadPluginConfigWithMeta2(directory);
32817
32924
  config = KnowledgeConfigSchema2.parse(loaded.config.knowledge ?? {});
32818
32925
  } catch {
32819
32926
  config = KnowledgeConfigSchema2.parse({});
32820
32927
  }
32821
32928
  const { cohortConfigFingerprint: cohortConfigFingerprint2 } = await import("./config-fingerprint-v22xh5a2.js");
32822
- const { buildConfigFingerprintInput: buildConfigFingerprintInput2, readCohortConfigFingerprint } = await import("./curation-policy-5x6346tf.js");
32929
+ const { buildConfigFingerprintInput: buildConfigFingerprintInput2, readCohortConfigFingerprint } = await import("./curation-policy-xv0j8zyt.js");
32823
32930
  const currentFp = cohortConfigFingerprint2(buildConfigFingerprintInput2(config));
32824
32931
  const cohortFp = await readCohortConfigFingerprint(directory);
32825
32932
  configMatch = cohortFp === null ? null : currentFp === cohortFp;
@@ -34095,7 +34202,7 @@ async function handleDoctorCommand(directory, args) {
34095
34202
  const result = runConfigDoctor(config, directory);
34096
34203
  let output;
34097
34204
  if (enableAutoFix && result.hasAutoFixableIssues) {
34098
- const { runConfigDoctorWithFixes } = await import("./config-doctor-dzsv3pqy.js");
34205
+ const { runConfigDoctorWithFixes } = await import("./config-doctor-j1r33f4q.js");
34099
34206
  const fixResult = await runConfigDoctorWithFixes(directory, config, true, {
34100
34207
  applyLossy: true
34101
34208
  });
@@ -34132,6 +34239,29 @@ async function handleDoctorCommand(directory, args) {
34132
34239
  `)}
34133
34240
  `;
34134
34241
  }
34242
+ try {
34243
+ const { runModelPreflight } = await import("./model-preflight-7ea00h34.js");
34244
+ const preflight = await runModelPreflight(config, swarmState.opencodeClient);
34245
+ if (preflight.catalogAvailable) {
34246
+ const unresolved = preflight.resolutions.filter((resolution) => resolution.status === "unresolved");
34247
+ if (unresolved.length > 0) {
34248
+ output += `
34249
+ ---
34250
+
34251
+ ## Agent Model Resolution
34252
+
34253
+ `;
34254
+ output += `${unresolved.length} configured agent model(s) do not resolve against the provider catalog:
34255
+
34256
+ `;
34257
+ for (const resolution of unresolved) {
34258
+ output += `- \`${resolution.agent}\` \u2192 \`${resolution.model}\`: ${resolution.detail ?? "does not resolve"}
34259
+ `;
34260
+ }
34261
+ output += "\nDispatching these agents will fail permanently. Fix `agents.<role>.model` in opencode-swarm.json or remove the override.\n";
34262
+ }
34263
+ }
34264
+ } catch {}
34135
34265
  const strayDirs = detectStraySwarmDirs(directory);
34136
34266
  if (strayDirs.length > 0) {
34137
34267
  if (enableAutoFix) {
@@ -35012,7 +35142,7 @@ async function handleEvidenceCommand(directory, args) {
35012
35142
  return formatTaskEvidenceMarkdown(evidenceData);
35013
35143
  }
35014
35144
  async function handleEvidenceSummaryCommand(directory) {
35015
- const { buildEvidenceSummary } = await import("./evidence-summary-service-dqcpapj8.js");
35145
+ const { buildEvidenceSummary } = await import("./evidence-summary-service-0mhx0t0v.js");
35016
35146
  const artifact = await buildEvidenceSummary(directory);
35017
35147
  if (!artifact) {
35018
35148
  return "No plan found. Run `/swarm plan` to check plan status.";
@@ -38377,6 +38507,7 @@ async function sastScan(input, directory, config) {
38377
38507
  const allFindings = [];
38378
38508
  let filesScanned = 0;
38379
38509
  let _filesSkipped = 0;
38510
+ let nonCodeSkipped = 0;
38380
38511
  const scannedFilePaths = [];
38381
38512
  if (abort_signal?.aborted) {
38382
38513
  return cancelledScanResult(allFindings, filesScanned);
@@ -38414,6 +38545,7 @@ async function sastScan(input, directory, config) {
38414
38545
  const langDef = getLanguageForExtension(ext);
38415
38546
  if (!profile && !langDef) {
38416
38547
  _filesSkipped++;
38548
+ nonCodeSkipped++;
38417
38549
  continue;
38418
38550
  }
38419
38551
  const language = profile?.id ?? langDef.id;
@@ -38649,15 +38781,21 @@ async function sastScan(input, directory, config) {
38649
38781
  }
38650
38782
  }
38651
38783
  let zeroCoverageError;
38784
+ let nonCodeOnly = false;
38652
38785
  if (filesScanned === 0) {
38653
- verdict = "fail";
38654
- zeroCoverageError = "SAST requires at least one file to scan; zero files were scanned";
38786
+ if (!baselineUsed && nonCodeSkipped > 0 && nonCodeSkipped === changed_files.length) {
38787
+ nonCodeOnly = true;
38788
+ } else {
38789
+ verdict = "fail";
38790
+ zeroCoverageError = "SAST requires at least one file to scan; zero files were scanned";
38791
+ }
38655
38792
  }
38656
38793
  const summary = {
38657
38794
  engine,
38658
38795
  files_scanned: filesScanned,
38659
38796
  findings_count: finalFindings.length,
38660
- findings_by_severity: findingsBySeverity
38797
+ findings_by_severity: findingsBySeverity,
38798
+ ...nonCodeOnly ? { files_skipped_non_code: nonCodeSkipped } : {}
38661
38799
  };
38662
38800
  if (abort_signal?.aborted) {
38663
38801
  return cancelledScanResult(allFindings, filesScanned);
@@ -38668,7 +38806,7 @@ async function sastScan(input, directory, config) {
38668
38806
  timestamp: new Date().toISOString(),
38669
38807
  agent: "sast_scan",
38670
38808
  verdict,
38671
- summary: `Scanned ${filesScanned} files, found ${finalFindings.length} finding(s) using ${engine}`,
38809
+ summary: nonCodeOnly ? `No scannable code files in input (${nonCodeSkipped} non-code file(s) skipped); nothing to scan` : `Scanned ${filesScanned} files, found ${finalFindings.length} finding(s) using ${engine}`,
38672
38810
  ...summary,
38673
38811
  findings: finalFindings,
38674
38812
  ...baselineUsed && {
@@ -46324,10 +46462,10 @@ function rustModulePathToSpecifier(modulePath, sourceFile, workspaceRoot) {
46324
46462
  }
46325
46463
  if (parts[0] === "crate" && sourceFile && workspaceRoot) {
46326
46464
  const target = path72.join(workspaceRoot, ...parts.slice(1));
46327
- let relative9 = path72.relative(path72.dirname(sourceFile), target).replace(/\\/g, "/");
46328
- if (!relative9.startsWith("."))
46329
- relative9 = `./${relative9}`;
46330
- return relative9;
46465
+ let relative10 = path72.relative(path72.dirname(sourceFile), target).replace(/\\/g, "/");
46466
+ if (!relative10.startsWith("."))
46467
+ relative10 = `./${relative10}`;
46468
+ return relative10;
46331
46469
  }
46332
46470
  return modulePath;
46333
46471
  }
@@ -46768,10 +46906,10 @@ function safeRelativePath(value) {
46768
46906
  return normalized;
46769
46907
  }
46770
46908
  function relativeFromRoot(root, absolutePath2) {
46771
- const relative10 = path73.relative(path73.resolve(root), path73.resolve(absolutePath2));
46772
- if (relative10.startsWith("..") || path73.isAbsolute(relative10))
46909
+ const relative11 = path73.relative(path73.resolve(root), path73.resolve(absolutePath2));
46910
+ if (relative11.startsWith("..") || path73.isAbsolute(relative11))
46773
46911
  return null;
46774
- return safeRelativePath(relative10);
46912
+ return safeRelativePath(relative11);
46775
46913
  }
46776
46914
  function absoluteFromRelative(root, relativePath2) {
46777
46915
  const safe = safeRelativePath(relativePath2);
@@ -46779,8 +46917,8 @@ function absoluteFromRelative(root, relativePath2) {
46779
46917
  return null;
46780
46918
  const resolvedRoot = path73.resolve(root);
46781
46919
  const absolute = path73.resolve(resolvedRoot, safe);
46782
- const relative10 = path73.relative(resolvedRoot, absolute);
46783
- if (relative10.startsWith("..") || path73.isAbsolute(relative10))
46920
+ const relative11 = path73.relative(resolvedRoot, absolute);
46921
+ if (relative11.startsWith("..") || path73.isAbsolute(relative11))
46784
46922
  return null;
46785
46923
  return absolute;
46786
46924
  }
@@ -46810,8 +46948,8 @@ function diagnosticPaths(root, diagnostics) {
46810
46948
  if (witness.kind === "stable-skip")
46811
46949
  stable.add(safe);
46812
46950
  }
46813
- for (const relative10 of reportedStable) {
46814
- if (witnesses.get(relative10)?.kind !== "stable-skip")
46951
+ for (const relative11 of reportedStable) {
46952
+ if (witnesses.get(relative11)?.kind !== "stable-skip")
46815
46953
  return null;
46816
46954
  }
46817
46955
  return { stable, witnesses };
@@ -46833,50 +46971,50 @@ async function writeFingerprint(root, graph, options) {
46833
46971
  return refuseFingerprint(root);
46834
46972
  const current = new Map;
46835
46973
  for (const input of walk.metadata) {
46836
- const relative10 = relativeFromRoot(root, input.absolutePath);
46837
- if (relative10 === null)
46974
+ const relative11 = relativeFromRoot(root, input.absolutePath);
46975
+ if (relative11 === null)
46838
46976
  return refuseFingerprint(root);
46839
- current.set(relative10, {
46977
+ current.set(relative11, {
46840
46978
  size: input.sizeBytes,
46841
46979
  mtimeMs: input.mtimeMs
46842
46980
  });
46843
46981
  }
46844
- for (const [relative10, witness] of certifiedInputs.witnesses) {
46845
- const observed = current.get(relative10);
46982
+ for (const [relative11, witness] of certifiedInputs.witnesses) {
46983
+ const observed = current.get(relative11);
46846
46984
  if (observed === undefined || observed.size !== witness.sizeBytes || observed.mtimeMs !== witness.mtimeMs) {
46847
46985
  return refuseFingerprint(root);
46848
46986
  }
46849
46987
  }
46850
46988
  const nodePaths = new Set;
46851
46989
  for (const node of Object.values(graph.nodes)) {
46852
- const relative10 = relativeFromRoot(root, node.filePath);
46853
- if (relative10 === null)
46990
+ const relative11 = relativeFromRoot(root, node.filePath);
46991
+ if (relative11 === null)
46854
46992
  return refuseFingerprint(root);
46855
46993
  if (typeof node.sizeBytes !== "number" || !Number.isFinite(node.sizeBytes) || node.sizeBytes < 0 || typeof node.mtimeMs !== "number" || !Number.isFinite(node.mtimeMs) || node.mtimeMs < 0) {
46856
46994
  return refuseFingerprint(root);
46857
46995
  }
46858
- const observed = current.get(relative10);
46996
+ const observed = current.get(relative11);
46859
46997
  if (observed === undefined || observed.size !== node.sizeBytes || observed.mtimeMs !== node.mtimeMs) {
46860
46998
  return refuseFingerprint(root);
46861
46999
  }
46862
- nodePaths.add(relative10);
47000
+ nodePaths.add(relative11);
46863
47001
  }
46864
47002
  for (const input of walk.metadata) {
46865
- const relative10 = relativeFromRoot(root, input.absolutePath);
46866
- if (relative10 === null)
47003
+ const relative11 = relativeFromRoot(root, input.absolutePath);
47004
+ if (relative11 === null)
46867
47005
  return refuseFingerprint(root);
46868
- if (input.kind === "manifest" && certifiedInputs.witnesses.get(relative10)?.kind !== "manifest") {
47006
+ if (input.kind === "manifest" && certifiedInputs.witnesses.get(relative11)?.kind !== "manifest") {
46869
47007
  return refuseFingerprint(root);
46870
47008
  }
46871
47009
  if (input.kind !== "source")
46872
47010
  continue;
46873
- if (!nodePaths.has(relative10) && !certifiedInputs.stable.has(relative10)) {
47011
+ if (!nodePaths.has(relative11) && !certifiedInputs.stable.has(relative11)) {
46874
47012
  return refuseFingerprint(root);
46875
47013
  }
46876
47014
  }
46877
47015
  const files = Object.create(null);
46878
- for (const relative10 of [...current.keys()].sort((a, b) => a.localeCompare(b))) {
46879
- files[relative10] = current.get(relative10);
47016
+ for (const relative11 of [...current.keys()].sort((a, b) => a.localeCompare(b))) {
47017
+ files[relative11] = current.get(relative11);
46880
47018
  }
46881
47019
  if (Object.keys(files).length > MAX_FINGERPRINT_ENTRIES)
46882
47020
  return refuseFingerprint(root);
@@ -49508,8 +49646,8 @@ function resolvePathShimTarget(shimPath, linter, platform = _internals70.platfor
49508
49646
  }
49509
49647
  const allowedRoots = [canonicalShimDir, canonicalShimParent];
49510
49648
  const isContained = allowedRoots.some((root) => {
49511
- const relative11 = path79.relative(root, canonicalTarget);
49512
- return relative11 === "" || !relative11.startsWith("..") && !path79.isAbsolute(relative11);
49649
+ const relative12 = path79.relative(root, canonicalTarget);
49650
+ return relative12 === "" || !relative12.startsWith("..") && !path79.isAbsolute(relative12);
49513
49651
  });
49514
49652
  if (!isContained)
49515
49653
  return null;
@@ -49689,8 +49827,8 @@ function resolveContainedWindowsBatchCommand(cwd, fileName, args) {
49689
49827
  } catch {
49690
49828
  return null;
49691
49829
  }
49692
- const relative11 = path79.relative(canonicalCwd, canonicalCandidate);
49693
- if (relative11 === "" || relative11.startsWith("..") || path79.isAbsolute(relative11)) {
49830
+ const relative12 = path79.relative(canonicalCwd, canonicalCandidate);
49831
+ if (relative12 === "" || relative12.startsWith("..") || path79.isAbsolute(relative12)) {
49694
49832
  return null;
49695
49833
  }
49696
49834
  return buildWindowsBatchCommand(canonicalCandidate, args);
@@ -50613,14 +50751,14 @@ function isPathWithinScope(realPath, scanDir) {
50613
50751
  }
50614
50752
  var DISCOVERY_YIELD_INTERVAL = 100;
50615
50753
  function toSafeRelativePath(rootDir, targetPath) {
50616
- const relative12 = path80.relative(rootDir, targetPath).replace(/\\/g, "/");
50617
- if (!relative12 || relative12 === ".")
50754
+ const relative13 = path80.relative(rootDir, targetPath).replace(/\\/g, "/");
50755
+ if (!relative13 || relative13 === ".")
50618
50756
  return ".";
50619
- if (relative12.startsWith("..") || path80.isAbsolute(relative12)) {
50757
+ if (relative13.startsWith("..") || path80.isAbsolute(relative13)) {
50620
50758
  const basename19 = path80.basename(targetPath).replace(/\\/g, "/");
50621
50759
  return basename19 || ".";
50622
50760
  }
50623
- return relative12;
50761
+ return relative13;
50624
50762
  }
50625
50763
  function recordIncompletePath(target, rootDir, targetPath, reason) {
50626
50764
  if (target.length >= MAX_INCOMPLETE_PATHS) {
@@ -52138,8 +52276,8 @@ function resolveNativeTarget(target, workingDir) {
52138
52276
  } catch {
52139
52277
  return { success: false, error: "Native target path does not exist" };
52140
52278
  }
52141
- const relative13 = path83.relative(rootReal, targetReal);
52142
- if (relative13.startsWith("..") || path83.isAbsolute(relative13)) {
52279
+ const relative14 = path83.relative(rootReal, targetReal);
52280
+ if (relative14.startsWith("..") || path83.isAbsolute(relative14)) {
52143
52281
  return { success: false, error: "Native target path escapes project root" };
52144
52282
  }
52145
52283
  if (!_internals74.isCommandAvailable(target.framework === "go-test" ? "go" : "ctest")) {
@@ -52149,7 +52287,7 @@ function resolveNativeTarget(target, workingDir) {
52149
52287
  };
52150
52288
  }
52151
52289
  let executionDirectory = rootReal;
52152
- let commandRelative = relative13;
52290
+ let commandRelative = relative14;
52153
52291
  if (target.framework === "go-test") {
52154
52292
  const hasRootWorkspace = fs35.existsSync(path83.join(rootReal, "go.work"));
52155
52293
  let moduleRoot;
@@ -52187,7 +52325,7 @@ function resolveNativeTarget(target, workingDir) {
52187
52325
  path: commandRelative.length === 0 ? "." : commandRelative.replace(/\\/g, "/")
52188
52326
  },
52189
52327
  executionDirectory,
52190
- historyPath: relative13.length === 0 ? "." : relative13.replace(/\\/g, "/")
52328
+ historyPath: relative14.length === 0 ? "." : relative14.replace(/\\/g, "/")
52191
52329
  };
52192
52330
  }
52193
52331
  function hasPackageJsonDependency(deps, ...patterns) {
@@ -53598,11 +53736,11 @@ function normalizeHistoryTestFile(testFile, workingDir) {
53598
53736
  const normalized = testFile.replace(/\\/g, "/");
53599
53737
  if (!path83.isAbsolute(testFile))
53600
53738
  return normalized;
53601
- const relative13 = path83.relative(workingDir, testFile);
53602
- if (relative13.startsWith("..") || path83.isAbsolute(relative13)) {
53739
+ const relative14 = path83.relative(workingDir, testFile);
53740
+ if (relative14.startsWith("..") || path83.isAbsolute(relative14)) {
53603
53741
  return normalized;
53604
53742
  }
53605
- return relative13.replace(/\\/g, "/");
53743
+ return relative14.replace(/\\/g, "/");
53606
53744
  }
53607
53745
  function combineAggregateResult(current, next) {
53608
53746
  if (current === "fail" || next === "fail")
@@ -56412,6 +56550,9 @@ var DEFAULT_MAX_UNTRACKED_FILE_BYTES = 64 * 1024;
56412
56550
  var MAX_REVIEW_BYTES = 8 * 1024 * 1024;
56413
56551
  var MAX_UNTRACKED_FILE_BYTES = 1024 * 1024;
56414
56552
  var MAX_TIMEOUT_MS2 = 60000;
56553
+ var WORKTREE_IDENTITY_MAX_FILE_BYTES = 2 * 1024 * 1024;
56554
+ var WORKTREE_IDENTITY_TOTAL_BYTES = 8 * 1024 * 1024;
56555
+ var WORKTREE_IDENTITY_MAX_DURATION_MS = 2000;
56415
56556
  var METADATA_OUTPUT_LIMIT = 256 * 1024;
56416
56557
  var STDERR_OUTPUT_LIMIT = 64 * 1024;
56417
56558
  var MAX_REF_LENGTH = 200;
@@ -56779,8 +56920,8 @@ function sameFileSnapshot(left, right) {
56779
56920
  return sameFileIdentity(left, right) && left.size === right.size && left.mtimeNs === right.mtimeNs && left.ctimeNs === right.ctimeNs;
56780
56921
  }
56781
56922
  function isContained(root, candidate) {
56782
- const relative16 = path89.relative(root, candidate);
56783
- return relative16.length > 0 && !relative16.startsWith(`..${path89.sep}`) && relative16 !== ".." && !path89.isAbsolute(relative16);
56923
+ const relative17 = path89.relative(root, candidate);
56924
+ return relative17.length > 0 && !relative17.startsWith(`..${path89.sep}`) && relative17 !== ".." && !path89.isAbsolute(relative17);
56784
56925
  }
56785
56926
  function selectorKey(selector) {
56786
56927
  switch (selector.kind) {
@@ -56794,6 +56935,204 @@ function selectorKey(selector) {
56794
56935
  return "working-tree";
56795
56936
  }
56796
56937
  }
56938
+ function reviewTargetKind(selector) {
56939
+ switch (selector.kind) {
56940
+ case "range":
56941
+ return "exact-committed-range";
56942
+ case "working-tree":
56943
+ return "checkout-index-working-tree";
56944
+ default:
56945
+ return "checkout-history-index-working-tree";
56946
+ }
56947
+ }
56948
+ function compareUtf8Bytes(left, right) {
56949
+ return Buffer.compare(Buffer.from(left, "utf8"), Buffer.from(right, "utf8"));
56950
+ }
56951
+ function uniqueSkipCodes(skipReasons) {
56952
+ return [...new Set(skipReasons.map((item) => item.code))].sort();
56953
+ }
56954
+ function hashManifestPayload(payload) {
56955
+ return createHash17("sha256").update(JSON.stringify(payload), "utf8").digest("hex");
56956
+ }
56957
+ function parseObjectFormat(stdout) {
56958
+ const objectFormat = stdout.trim();
56959
+ return objectFormat.length > 0 && !hasControlCharacter(objectFormat) ? objectFormat : null;
56960
+ }
56961
+ function parseLsTreeBlobId(stdout, expectedPath) {
56962
+ const trimmed = stdout.endsWith("\x00") ? stdout.slice(0, -1) : stdout;
56963
+ if (!trimmed)
56964
+ return null;
56965
+ const tabIndex = trimmed.indexOf("\t");
56966
+ if (tabIndex === -1)
56967
+ return null;
56968
+ const metadata = trimmed.slice(0, tabIndex).trim().split(/\s+/);
56969
+ const actualPath = normalizeRelativePath(trimmed.slice(tabIndex + 1));
56970
+ if (metadata.length < 3 || metadata[1] !== "blob" || actualPath !== expectedPath || !SHA_PATTERN.test(metadata[2] ?? "")) {
56971
+ return null;
56972
+ }
56973
+ return metadata[2];
56974
+ }
56975
+ async function resolveGitObjectFormat(root, timeoutMs) {
56976
+ const result = await runGit2(root, ["rev-parse", "--show-object-format"], {
56977
+ timeoutMs,
56978
+ maxStdoutBytes: METADATA_OUTPUT_LIMIT
56979
+ });
56980
+ return result.ok ? parseObjectFormat(result.stdout) : null;
56981
+ }
56982
+ async function readGitBlobIdentity(root, treeish, relativePath2, timeoutMs, objectFormat) {
56983
+ const result = await runGit2(root, ["ls-tree", "-z", treeish, "--", relativePath2], {
56984
+ timeoutMs,
56985
+ maxStdoutBytes: METADATA_OUTPUT_LIMIT
56986
+ });
56987
+ if (!result.ok)
56988
+ return null;
56989
+ const blobId = parseLsTreeBlobId(result.stdout, relativePath2);
56990
+ if (!blobId)
56991
+ return null;
56992
+ return {
56993
+ algorithm: "git-blob",
56994
+ git_blob_oid: blobId,
56995
+ git_object_format: objectFormat
56996
+ };
56997
+ }
56998
+ function compareStats(left, right) {
56999
+ return sameFileIdentity(left, right) && left.size === right.size && left.mtimeNs === right.mtimeNs && left.ctimeNs === right.ctimeNs;
57000
+ }
57001
+ function hashWorkingTreeIdentity(root, rawPath, budget) {
57002
+ const normalized = normalizeRelativePath(rawPath);
57003
+ if (!normalized)
57004
+ return { identity: null };
57005
+ const candidate = path89.resolve(root, ...normalized.split("/"));
57006
+ if (!isContained(root, candidate))
57007
+ return { identity: null };
57008
+ let handle;
57009
+ const deadlineExceeded = (detail) => ({
57010
+ identity: null,
57011
+ failure: {
57012
+ code: "UNREADABLE_FILE",
57013
+ path: normalized,
57014
+ detail
57015
+ }
57016
+ });
57017
+ try {
57018
+ if (_internals78.now() > budget.deadlineMs) {
57019
+ return deadlineExceeded("working-tree content identity deadline expired before file hashing started");
57020
+ }
57021
+ const pathStat = _internals78.lstatBigIntSync(candidate);
57022
+ if (!pathStat.isFile() || pathStat.isSymbolicLink())
57023
+ return { identity: null };
57024
+ const canonicalBeforeOpen = _internals78.realpathSync(candidate);
57025
+ if (!isContained(root, canonicalBeforeOpen))
57026
+ return { identity: null };
57027
+ handle = _internals78.openSync(canonicalBeforeOpen, "r");
57028
+ const openedBeforeRead = _internals78.fstatBigIntSync(handle);
57029
+ const canonicalAfterOpen = _internals78.realpathSync(candidate);
57030
+ if (!openedBeforeRead.isFile() || !compareStats(pathStat, openedBeforeRead) || !samePath(canonicalBeforeOpen, canonicalAfterOpen) || !isContained(root, canonicalAfterOpen)) {
57031
+ return { identity: null };
57032
+ }
57033
+ if (openedBeforeRead.size > BigInt(Number.MAX_SAFE_INTEGER)) {
57034
+ return deadlineExceeded("working-tree content identity byte length exceeds safe integer bounds");
57035
+ }
57036
+ if (openedBeforeRead.size > BigInt(WORKTREE_IDENTITY_MAX_FILE_BYTES)) {
57037
+ return deadlineExceeded(`working-tree content identity exceeded the ${WORKTREE_IDENTITY_MAX_FILE_BYTES}-byte per-file cap`);
57038
+ }
57039
+ const fileBytes = Number(openedBeforeRead.size);
57040
+ if (fileBytes > budget.remainingBytes) {
57041
+ return deadlineExceeded(`working-tree content identity exceeded the ${WORKTREE_IDENTITY_TOTAL_BYTES}-byte aggregate cap`);
57042
+ }
57043
+ const hash2 = createHash17("sha256");
57044
+ const buffer = Buffer.alloc(64 * 1024);
57045
+ let offset = 0;
57046
+ while (offset < fileBytes) {
57047
+ if (_internals78.now() > budget.deadlineMs) {
57048
+ return deadlineExceeded("working-tree content identity deadline expired while hashing file content");
57049
+ }
57050
+ const read = _internals78.readSync(handle, buffer, 0, Math.min(buffer.byteLength, fileBytes - offset), offset);
57051
+ if (read === 0)
57052
+ break;
57053
+ hash2.update(buffer.subarray(0, read));
57054
+ offset += read;
57055
+ }
57056
+ const openedAfterRead = _internals78.fstatBigIntSync(handle);
57057
+ const canonicalAfterRead = _internals78.realpathSync(candidate);
57058
+ if (!compareStats(openedBeforeRead, openedAfterRead) || !samePath(canonicalBeforeOpen, canonicalAfterRead) || !isContained(root, canonicalAfterRead) || offset !== fileBytes) {
57059
+ return { identity: null };
57060
+ }
57061
+ budget.remainingBytes -= fileBytes;
57062
+ return {
57063
+ identity: {
57064
+ algorithm: "sha256",
57065
+ sha256: hash2.digest("hex"),
57066
+ byte_length: Number(openedAfterRead.size)
57067
+ }
57068
+ };
57069
+ } catch {
57070
+ return { identity: null };
57071
+ } finally {
57072
+ if (handle !== undefined) {
57073
+ try {
57074
+ _internals78.closeSync(handle);
57075
+ } catch {}
57076
+ }
57077
+ }
57078
+ }
57079
+ async function buildReviewManifest(root, selector, files, completeness, timeoutMs, revisionContext, contentHash) {
57080
+ const objectFormat = await resolveGitObjectFormat(root, timeoutMs) ?? "sha1";
57081
+ const pathRecords = [];
57082
+ const identityFailures = [];
57083
+ const missingIdentityBindings = new Set;
57084
+ const workingTreeBudget = selector.kind === "range" ? undefined : {
57085
+ remainingBytes: WORKTREE_IDENTITY_TOTAL_BYTES,
57086
+ deadlineMs: _internals78.now() + Math.min(timeoutMs, WORKTREE_IDENTITY_MAX_DURATION_MS)
57087
+ };
57088
+ const orderedScopes = [...files.values()].sort((left, right) => compareUtf8Bytes(left.newPath ?? left.oldPath ?? "", right.newPath ?? right.oldPath ?? ""));
57089
+ const oldTreeForSelector = selector.kind === "working-tree" ? revisionContext.headSha : selector.kind === "range" ? selector.operator === "..." ? revisionContext.mergeBase : revisionContext.baseSha : revisionContext.mergeBase;
57090
+ const newTreeForSelector = selector.kind === "range" ? revisionContext.rangeToSha : undefined;
57091
+ for (const scope of orderedScopes) {
57092
+ const record = {
57093
+ kind: scope.kind,
57094
+ old_path: scope.oldPath,
57095
+ new_path: scope.newPath
57096
+ };
57097
+ if (scope.kind !== "added" && scope.oldPath && oldTreeForSelector) {
57098
+ record.old_identity = await readGitBlobIdentity(root, oldTreeForSelector, scope.oldPath, timeoutMs, objectFormat) ?? undefined;
57099
+ }
57100
+ if (scope.newPath) {
57101
+ if (selector.kind === "range" && newTreeForSelector) {
57102
+ record.new_identity = await readGitBlobIdentity(root, newTreeForSelector, scope.newPath, timeoutMs, objectFormat) ?? undefined;
57103
+ } else if (workingTreeBudget) {
57104
+ const hashed = hashWorkingTreeIdentity(root, scope.newPath, workingTreeBudget);
57105
+ record.new_identity = hashed.identity ?? undefined;
57106
+ if (hashed.failure) {
57107
+ identityFailures.push(hashed.failure);
57108
+ missingIdentityBindings.add(`new:${scope.newPath}`);
57109
+ }
57110
+ }
57111
+ }
57112
+ pathRecords.push(record);
57113
+ }
57114
+ const payload = {
57115
+ schema_version: 2,
57116
+ content_hash: contentHash,
57117
+ selector,
57118
+ selector_key: selectorKey(selector),
57119
+ review_target_kind: reviewTargetKind(selector),
57120
+ completeness: {
57121
+ complete: completeness.complete,
57122
+ truncated: completeness.truncated,
57123
+ skip_reason_codes: uniqueSkipCodes(completeness.skipReasons)
57124
+ },
57125
+ path_records: pathRecords
57126
+ };
57127
+ return {
57128
+ manifest: {
57129
+ ...payload,
57130
+ hash: hashManifestPayload(payload)
57131
+ },
57132
+ identityFailures,
57133
+ missingIdentityBindings
57134
+ };
57135
+ }
56797
57136
  function boundedPositiveInteger(value, fallback, maximum) {
56798
57137
  if (value === undefined || !Number.isFinite(value))
56799
57138
  return fallback;
@@ -57282,6 +57621,11 @@ async function collectReviewDiff(options) {
57282
57621
  fileListFallback: fileListFallback ?? null
57283
57622
  });
57284
57623
  const scopeHash = createHash17("sha256").update(hashPayload, "utf8").digest("hex");
57624
+ const reviewContentHash = createHash17("sha256").update(JSON.stringify({
57625
+ selector,
57626
+ canonicalText,
57627
+ fileListFallback: fileListFallback ?? null
57628
+ }), "utf8").digest("hex");
57285
57629
  const completeness = {
57286
57630
  complete: skipReasons.length === 0 && !truncated,
57287
57631
  truncated,
@@ -57295,6 +57639,39 @@ async function collectReviewDiff(options) {
57295
57639
  includesWorkingTree,
57296
57640
  scopeHash
57297
57641
  };
57642
+ const { manifest, identityFailures, missingIdentityBindings } = await buildReviewManifest(root, selector, parsed.files, completeness, timeoutMs, {
57643
+ headSha,
57644
+ mergeBase,
57645
+ baseSha,
57646
+ rangeToSha
57647
+ }, reviewContentHash);
57648
+ skipReasons.push(...identityFailures);
57649
+ for (const record of manifest.path_records) {
57650
+ if (record.kind !== "added" && record.old_path && !record.old_identity) {
57651
+ skipReasons.push({
57652
+ code: "UNREADABLE_FILE",
57653
+ path: record.old_path,
57654
+ detail: "could not bind the reviewed old-side file to a complete content identity"
57655
+ });
57656
+ }
57657
+ if (record.kind !== "deleted" && record.new_path && !record.new_identity && !missingIdentityBindings.has(`new:${record.new_path}`)) {
57658
+ skipReasons.push({
57659
+ code: "UNREADABLE_FILE",
57660
+ path: record.new_path,
57661
+ detail: "could not bind the reviewed new-side file to a complete content identity"
57662
+ });
57663
+ }
57664
+ }
57665
+ if (skipReasons.length > manifest.completeness.skip_reason_codes.length) {
57666
+ completeness.complete = false;
57667
+ manifest.completeness = {
57668
+ complete: false,
57669
+ truncated: completeness.truncated,
57670
+ skip_reason_codes: uniqueSkipCodes(skipReasons)
57671
+ };
57672
+ const { hash: _oldHash, ...manifestPayload } = manifest;
57673
+ manifest.hash = hashManifestPayload(manifestPayload);
57674
+ }
57298
57675
  const scope = {
57299
57676
  selector,
57300
57677
  canonicalText,
@@ -57309,7 +57686,8 @@ async function collectReviewDiff(options) {
57309
57686
  deletedLines: parsed.deletedLines,
57310
57687
  files: parsed.files,
57311
57688
  completeness,
57312
- staleness
57689
+ staleness,
57690
+ manifest
57313
57691
  };
57314
57692
  const clean = canonicalText.trim().length === 0 && untrackedCount === 0 && skipReasons.length === 0;
57315
57693
  return { status: clean ? "clean" : "ok", ...scope };
@@ -57322,7 +57700,8 @@ var _internals78 = {
57322
57700
  fstatBigIntSync: (fd) => fs40.fstatSync(fd, { bigint: true }),
57323
57701
  readSync: fs40.readSync,
57324
57702
  closeSync: fs40.closeSync,
57325
- resolveGitExecutable: resolveGitExecutableAsync
57703
+ resolveGitExecutable: resolveGitExecutableAsync,
57704
+ now: () => Date.now()
57326
57705
  };
57327
57706
 
57328
57707
  // src/review/engine.ts
@@ -58094,15 +58473,15 @@ function normalizedProjectFile(directory, file) {
58094
58473
  return null;
58095
58474
  const root = path91.resolve(directory);
58096
58475
  const absolute = path91.resolve(root, file);
58097
- const relative17 = path91.relative(root, absolute).replaceAll("\\", "/");
58098
- if (!relative17 || relative17 === ".." || relative17.startsWith("../") || path91.isAbsolute(relative17)) {
58476
+ const relative18 = path91.relative(root, absolute).replaceAll("\\", "/");
58477
+ if (!relative18 || relative18 === ".." || relative18.startsWith("../") || path91.isAbsolute(relative18)) {
58099
58478
  return null;
58100
58479
  }
58101
- return relative17;
58480
+ return relative18;
58102
58481
  }
58103
58482
  function isWithinRoot2(root, candidate) {
58104
- const relative17 = path91.relative(root, candidate);
58105
- return relative17 === "" || relative17 !== ".." && !relative17.startsWith(`..${path91.sep}`) && !path91.isAbsolute(relative17);
58483
+ const relative18 = path91.relative(root, candidate);
58484
+ return relative18 === "" || relative18 !== ".." && !relative18.startsWith(`..${path91.sep}`) && !path91.isAbsolute(relative18);
58106
58485
  }
58107
58486
  function deletedPathIsContained(canonicalRoot, absolute) {
58108
58487
  let current = path91.dirname(absolute);
@@ -58488,8 +58867,8 @@ function hasControlCharacter3(value) {
58488
58867
  return false;
58489
58868
  }
58490
58869
  function isContained2(root, candidate) {
58491
- const relative18 = path92.relative(root, candidate);
58492
- return relative18.length > 0 && relative18 !== ".." && !relative18.startsWith(`..${path92.sep}`) && !path92.isAbsolute(relative18);
58870
+ const relative19 = path92.relative(root, candidate);
58871
+ return relative19.length > 0 && relative19 !== ".." && !relative19.startsWith(`..${path92.sep}`) && !path92.isAbsolute(relative19);
58493
58872
  }
58494
58873
  function canonicalPath(relativePath2) {
58495
58874
  return relativePath2.split(path92.sep).join("/");
@@ -58868,8 +59247,22 @@ var _internals82 = {
58868
59247
  };
58869
59248
 
58870
59249
  // src/review/evidence.ts
59250
+ import { createHash as createHash21 } from "crypto";
58871
59251
  import * as fs44 from "fs";
58872
59252
  import * as path93 from "path";
59253
+ function computeAutoReviewManifestHash(manifest) {
59254
+ return createHash21("sha256").update(JSON.stringify({
59255
+ schema_version: manifest.schema_version,
59256
+ content_hash: manifest.content_hash,
59257
+ plan_requirements_hash: manifest.plan_requirements_hash,
59258
+ review_policy_digest: manifest.review_policy_digest,
59259
+ selector: manifest.selector,
59260
+ selector_key: manifest.selector_key,
59261
+ review_target_kind: manifest.review_target_kind,
59262
+ completeness: manifest.completeness,
59263
+ path_records: manifest.path_records
59264
+ }), "utf8").digest("hex");
59265
+ }
58873
59266
  function autoReviewEvidenceRelativePath(trigger, scopeHash, phase) {
58874
59267
  if ((trigger === "phase_completion" || trigger === "plan_completion") && Number.isInteger(phase) && (phase ?? 0) > 0) {
58875
59268
  return path93.join("evidence", String(phase), "auto-review.json");
@@ -58921,7 +59314,7 @@ function isAutoReviewEvidence(value) {
58921
59314
  if (!value || typeof value !== "object")
58922
59315
  return false;
58923
59316
  const candidate = value;
58924
- if (!(candidate.schema_version === 1 && typeof candidate.timestamp === "string" && [
59317
+ if (!((candidate.schema_version === 1 || candidate.schema_version === 2) && typeof candidate.timestamp === "string" && [
58925
59318
  "task_completion",
58926
59319
  "phase_completion",
58927
59320
  "plan_completion",
@@ -58929,8 +59322,91 @@ function isAutoReviewEvidence(value) {
58929
59322
  ].includes(String(candidate.trigger)) && typeof candidate.session_id === "string" && Boolean(candidate.scope) && typeof candidate.scope?.hash === "string" && typeof candidate.scope?.head_sha === "string" && Boolean(candidate.scope?.selector) && Boolean(candidate.scope?.completeness) && Boolean(candidate.policy) && (candidate.policy?.mode === "advisory" || candidate.policy?.mode === "gate") && typeof candidate.policy?.min_confidence === "number" && typeof candidate.policy?.structured_findings === "boolean" && typeof candidate.policy?.validate_findings === "boolean" && Array.isArray(candidate.findings) && Array.isArray(candidate.blocking_finding_ids) && typeof candidate.validation_complete === "boolean" && Boolean(candidate.review) && ["completed", "clean", "error"].includes(String(candidate.review?.status)))) {
58930
59323
  return false;
58931
59324
  }
59325
+ if (candidate.schema_version === 2) {
59326
+ if (!candidate.scope?.manifest || candidate.scope.manifest.schema_version !== 2 || typeof candidate.scope.manifest.content_hash !== "string" || typeof candidate.scope.manifest.plan_requirements_hash !== "string" || typeof candidate.scope.manifest.review_policy_digest !== "string" || typeof candidate.scope.manifest.hash !== "string" || typeof candidate.policy?.digest !== "string") {
59327
+ return false;
59328
+ }
59329
+ const { hash: hash2, ...manifestPayload } = candidate.scope.manifest;
59330
+ if (hash2 !== computeAutoReviewManifestHash(manifestPayload)) {
59331
+ return false;
59332
+ }
59333
+ }
58932
59334
  return candidate.findings.every(isAutoReviewEvidenceFinding);
58933
59335
  }
59336
+ async function computePlanRequirementsHash(directory) {
59337
+ const plan = await loadReviewRequirementsPlan(directory);
59338
+ return plan ? computeReviewPlanRequirementsHash(plan) : "plan:none";
59339
+ }
59340
+ function computeAutoReviewPolicyDigest(config) {
59341
+ return createHash21("sha256").update(JSON.stringify({
59342
+ mode: config.final_review.mode,
59343
+ min_confidence: config.min_confidence,
59344
+ structured_findings: config.structured_findings,
59345
+ validate_findings: config.validate_findings,
59346
+ final_review: {
59347
+ on_phase_complete: config.final_review.on_phase_complete,
59348
+ on_plan_complete: config.final_review.on_plan_complete,
59349
+ max_diff_bytes: config.final_review.max_diff_bytes,
59350
+ timeout_ms: config.final_review.timeout_ms,
59351
+ model: config.final_review.model
59352
+ },
59353
+ validation_timeout_ms: config.validation_timeout_ms,
59354
+ validation_model: config.validation_model
59355
+ }), "utf8").digest("hex");
59356
+ }
59357
+ async function materializeAutoReviewManifest(directory, manifest, config) {
59358
+ const planRequirementsHash = await computePlanRequirementsHash(directory);
59359
+ const policyDigest = computeAutoReviewPolicyDigest(config);
59360
+ const payload = {
59361
+ ...manifest,
59362
+ plan_requirements_hash: planRequirementsHash,
59363
+ review_policy_digest: policyDigest
59364
+ };
59365
+ const hash2 = computeAutoReviewManifestHash(payload);
59366
+ return { ...payload, hash: hash2 };
59367
+ }
59368
+ async function loadReviewRequirementsPlan(directory) {
59369
+ if (!await ledgerExists(directory)) {
59370
+ return loadPlanJsonOnly(directory);
59371
+ }
59372
+ let replayed;
59373
+ try {
59374
+ replayed = await replayFromLedgerWithStatus(directory);
59375
+ } catch (error2) {
59376
+ throw new Error(`authoritative plan ledger replay failed for final-review requirements: ${error2 instanceof Error ? error2.message : String(error2)}`);
59377
+ }
59378
+ if (replayed.truncated) {
59379
+ throw new Error("authoritative plan ledger replay is truncated; final-review requirements are unavailable");
59380
+ }
59381
+ if (!replayed.plan) {
59382
+ throw new Error("authoritative plan ledger replay returned no plan; final-review requirements are unavailable");
59383
+ }
59384
+ return replayed.plan;
59385
+ }
59386
+ function computeReviewPlanRequirementsHash(plan) {
59387
+ return createHash21("sha256").update(JSON.stringify({
59388
+ schema_version: plan.schema_version,
59389
+ title: plan.title,
59390
+ swarm: plan.swarm,
59391
+ migration_status: plan.migration_status,
59392
+ phases: plan.phases.map((phase) => ({
59393
+ id: phase.id,
59394
+ name: phase.name,
59395
+ type: phase.type,
59396
+ required_agents: phase.required_agents ? [...phase.required_agents].sort() : undefined,
59397
+ tasks: phase.tasks.map((task) => ({
59398
+ id: task.id,
59399
+ phase: task.phase,
59400
+ size: task.size,
59401
+ description: task.description,
59402
+ depends: [...task.depends].sort(),
59403
+ acceptance: task.acceptance,
59404
+ files_touched: [...task.files_touched].sort(),
59405
+ fr_refs: task.fr_refs ? [...task.fr_refs].sort() : undefined
59406
+ }))
59407
+ }))
59408
+ }), "utf8").digest("hex");
59409
+ }
58934
59410
  function baseFinding(finding) {
58935
59411
  return {
58936
59412
  title: finding.title,
@@ -59051,13 +59527,9 @@ function scopeFreshnessMismatches(reviewed, current) {
59051
59527
  };
59052
59528
  compare("status", reviewed.status, current.status);
59053
59529
  compare("scopeHash", reviewed.scopeHash, current.scopeHash);
59530
+ compare("manifestHash", reviewed.manifest.hash, current.manifest.hash);
59054
59531
  compare("canonicalText", reviewed.canonicalText, current.canonicalText);
59055
59532
  compare("reviewTextBytes", reviewed.reviewTextBytes, current.reviewTextBytes);
59056
- compare("headSha", reviewed.headSha, current.headSha);
59057
- compare("baseRef", reviewed.baseRef, current.baseRef);
59058
- compare("baseSha", reviewed.baseSha, current.baseSha);
59059
- compare("mergeBase", reviewed.mergeBase, current.mergeBase);
59060
- compare("rangeToSha", reviewed.rangeToSha, current.rangeToSha);
59061
59533
  compare("selector", JSON.stringify(reviewed.selector), JSON.stringify(current.selector));
59062
59534
  compare("completeness", JSON.stringify(reviewed.completeness), JSON.stringify(current.completeness));
59063
59535
  compare("includesWorkingTree", reviewed.staleness.includesWorkingTree, current.staleness.includesWorkingTree);
@@ -59083,6 +59555,7 @@ async function stalePersistenceResult(input, maxBytes, message, modelCalls) {
59083
59555
  result.modelCalls = modelCalls;
59084
59556
  if (current.status !== "error") {
59085
59557
  result.scopeHash = current.scopeHash;
59558
+ result.manifestHash = current.manifest.hash;
59086
59559
  result.scopeComplete = current.completeness.complete;
59087
59560
  Object.assign(result, scopeResultFields(current));
59088
59561
  }
@@ -59148,14 +59621,14 @@ var REVIEW_SYSTEM_PROMPT = [
59148
59621
  function renderReviewPrompt(input, renderedFallbackFiles, omittedFallbackFiles) {
59149
59622
  const { diff } = input;
59150
59623
  const exactRange = diff.selector.kind === "range";
59151
- const reviewTargetKind = diff.selector.kind === "range" ? "exact-committed-range" : diff.selector.kind === "working-tree" ? "checkout-index-working-tree" : "checkout-history-index-working-tree";
59624
+ const reviewTargetKind2 = diff.selector.kind === "range" ? "exact-committed-range" : diff.selector.kind === "working-tree" ? "checkout-index-working-tree" : "checkout-history-index-working-tree";
59152
59625
  const fallback = diff.completeness.fileListFallback;
59153
59626
  const promptFallbackComplete = fallback?.complete && omittedFallbackFiles === 0;
59154
59627
  return [
59155
59628
  `TASK: Review the complete ${input.trigger.replaceAll("_", " ")} diff.`,
59156
59629
  input.phase ? `PHASE: ${input.phase}` : "",
59157
59630
  `REVIEW_SELECTOR: ${JSON.stringify(diff.selector)}`,
59158
- `REVIEW_TARGET_KIND: ${reviewTargetKind}`,
59631
+ `REVIEW_TARGET_KIND: ${reviewTargetKind2}`,
59159
59632
  `SCOPE_HASH: ${diff.scopeHash}`,
59160
59633
  `BASE_REF: ${diff.baseRef ?? "none"}`,
59161
59634
  `BASE_SHA: ${diff.baseSha ?? "none"}`,
@@ -59254,8 +59727,8 @@ function normalizedRelativePath(file) {
59254
59727
  return normalized.replace(/^\.\//, "");
59255
59728
  }
59256
59729
  function isWithinRoot3(root, candidate) {
59257
- const relative20 = path94.relative(root, candidate);
59258
- return relative20.length > 0 && relative20 !== ".." && !relative20.startsWith(`..${path94.sep}`) && !path94.isAbsolute(relative20);
59730
+ const relative21 = path94.relative(root, candidate);
59731
+ return relative21.length > 0 && relative21 !== ".." && !relative21.startsWith(`..${path94.sep}`) && !path94.isAbsolute(relative21);
59259
59732
  }
59260
59733
  function rangesOverlap(start, end, ranges) {
59261
59734
  return ranges.some((range) => start <= range.end && end >= range.start);
@@ -59372,7 +59845,7 @@ function addCost(evidence2, dispatches) {
59372
59845
  }
59373
59846
  function baseEvidence(input, diff, status) {
59374
59847
  return {
59375
- schema_version: 1,
59848
+ schema_version: 2,
59376
59849
  timestamp: new Date().toISOString(),
59377
59850
  trigger: input.trigger,
59378
59851
  session_id: input.sessionID,
@@ -59392,7 +59865,8 @@ function baseEvidence(input, diff, status) {
59392
59865
  mode: input.config.final_review.mode,
59393
59866
  min_confidence: input.config.min_confidence,
59394
59867
  structured_findings: input.config.structured_findings,
59395
- validate_findings: input.config.validate_findings
59868
+ validate_findings: input.config.validate_findings,
59869
+ digest: undefined
59396
59870
  },
59397
59871
  review: { status },
59398
59872
  findings: [],
@@ -59451,6 +59925,8 @@ function emptyResult2(status, message, blocked, blockReason) {
59451
59925
  }
59452
59926
  async function persistErrorResult(input, diff, result, error2, dispatches, promptRequest) {
59453
59927
  const evidence2 = baseEvidence(input, diff, "error");
59928
+ evidence2.scope.manifest = await materializeAutoReviewManifest(input.directory, diff.manifest, input.config);
59929
+ evidence2.policy.digest = evidence2.scope.manifest.review_policy_digest;
59454
59930
  evidence2.review.error = error2;
59455
59931
  addCost(evidence2, dispatches);
59456
59932
  try {
@@ -59462,6 +59938,7 @@ async function persistErrorResult(input, diff, result, error2, dispatches, promp
59462
59938
  }
59463
59939
  }
59464
59940
  result.scopeHash = diff.scopeHash;
59941
+ result.manifestHash = evidence2.scope.manifest.hash;
59465
59942
  result.scopeComplete = diff.completeness.complete;
59466
59943
  Object.assign(result, scopeResultFields(diff, promptRequest));
59467
59944
  return result;
@@ -59482,6 +59959,8 @@ async function runReviewEngine(input) {
59482
59959
  }
59483
59960
  if (diff.status === "clean") {
59484
59961
  const evidence3 = baseEvidence(input, diff, "clean");
59962
+ evidence3.scope.manifest = await materializeAutoReviewManifest(input.directory, diff.manifest, input.config);
59963
+ evidence3.policy.digest = evidence3.scope.manifest.review_policy_digest;
59485
59964
  let evidencePath2;
59486
59965
  try {
59487
59966
  evidencePath2 = await _internals83.persistEvidence(input.directory, evidence3, { verifyCurrent: createScopeVerifier(input, diff, maxBytes) });
@@ -59495,6 +59974,7 @@ async function runReviewEngine(input) {
59495
59974
  ...emptyResult2("clean", "Review scope is clean.", blocked2, blocked2 ? "EVIDENCE_PERSISTENCE_FAILED" : undefined),
59496
59975
  validationComplete: true,
59497
59976
  scopeHash: diff.scopeHash,
59977
+ manifestHash: evidence3.scope.manifest.hash,
59498
59978
  scopeComplete: diff.completeness.complete,
59499
59979
  ...scopeResultFields(diff),
59500
59980
  evidencePath: evidencePath2
@@ -59505,6 +59985,7 @@ async function runReviewEngine(input) {
59505
59985
  diff,
59506
59986
  phase: input.phase
59507
59987
  });
59988
+ const reviewManifest = await materializeAutoReviewManifest(input.directory, diff.manifest, input.config);
59508
59989
  if (input.phase !== undefined && (input.trigger === "phase_completion" || input.trigger === "plan_completion")) {
59509
59990
  const existing = _internals83.readPhaseEvidence(input.directory, input.phase);
59510
59991
  const integrity = existing ? validateAutoReviewEvidenceIntegrity(input.directory, existing, {
@@ -59519,7 +60000,7 @@ async function runReviewEngine(input) {
59519
60000
  },
59520
60001
  scopeContent: diff.canonicalText
59521
60002
  }) : undefined;
59522
- if (existing?.review.status === "completed" && existing.scope.head_sha === diff.headSha && integrity?.ok && integrity.receipt) {
60003
+ if (existing?.review.status === "completed" && existing.schema_version === 2 && existing.scope.manifest?.hash === reviewManifest.hash && integrity?.ok && integrity.receipt) {
59523
60004
  const validationsById = new Map((integrity.receipt.finding_validations ?? []).map((validation) => [
59524
60005
  validation.finding_id,
59525
60006
  validation
@@ -59548,6 +60029,7 @@ async function runReviewEngine(input) {
59548
60029
  receiptPath: existing.receipt_path,
59549
60030
  evidencePath: path94.join(input.directory, ".swarm", "evidence", String(input.phase), "auto-review.json"),
59550
60031
  scopeHash: existing.scope.hash,
60032
+ manifestHash: existing.scope.manifest?.hash,
59551
60033
  scopeComplete: diff.completeness.complete,
59552
60034
  ...scopeResultFields(diff, promptRequest),
59553
60035
  reviewModel: existing.review.model,
@@ -59654,6 +60136,8 @@ async function runReviewEngine(input) {
59654
60136
  }
59655
60137
  const blockingFindings = findings.filter((finding) => finding.anchored && isGateSeverity(finding.effective_severity) && finding.validation?.disposition === "CONFIRMED");
59656
60138
  const evidence2 = baseEvidence(input, diff, "completed");
60139
+ evidence2.scope.manifest = reviewManifest;
60140
+ evidence2.policy.digest = reviewManifest.review_policy_digest;
59657
60141
  evidence2.review = {
59658
60142
  status: "completed",
59659
60143
  output_mode: parsed.outputMode,
@@ -59771,6 +60255,7 @@ async function runReviewEngine(input) {
59771
60255
  receiptPath,
59772
60256
  evidencePath,
59773
60257
  scopeHash: diff.scopeHash,
60258
+ manifestHash: reviewManifest.hash,
59774
60259
  scopeComplete: diff.completeness.complete,
59775
60260
  ...scopeResultFields(diff, promptRequest),
59776
60261
  reviewModel: dispatched.result.modelId,
@@ -59821,8 +60306,8 @@ function formatSelector(selector) {
59821
60306
  }
59822
60307
  }
59823
60308
  function isPathInside(parent, candidate) {
59824
- const relative21 = path95.relative(parent, candidate);
59825
- return relative21.length > 0 && relative21 !== ".." && !relative21.startsWith(`..${path95.sep}`) && !path95.isAbsolute(relative21);
60309
+ const relative22 = path95.relative(parent, candidate);
60310
+ return relative22.length > 0 && relative22 !== ".." && !relative22.startsWith(`..${path95.sep}`) && !path95.isAbsolute(relative22);
59826
60311
  }
59827
60312
  function sameFileSnapshot3(left, right) {
59828
60313
  return (left.dev !== 0n || left.ino !== 0n) && (right.dev !== 0n || right.ino !== 0n) && left.dev === right.dev && left.ino === right.ino && left.size === right.size && left.mtimeNs === right.mtimeNs && left.ctimeNs === right.ctimeNs;
@@ -60907,7 +61392,7 @@ import {
60907
61392
  import * as path99 from "path";
60908
61393
 
60909
61394
  // src/services/skill-optimizer/store.ts
60910
- import { createHash as createHash21, randomUUID as randomUUID12 } from "crypto";
61395
+ import { createHash as createHash22, randomUUID as randomUUID12 } from "crypto";
60911
61396
  import {
60912
61397
  closeSync as closeSync16,
60913
61398
  existsSync as existsSync55,
@@ -60932,10 +61417,10 @@ function canonicalJson3(value) {
60932
61417
  return `{${entries.map(([k, v]) => `${JSON.stringify(k)}:${canonicalJson3(v)}`).join(",")}}`;
60933
61418
  }
60934
61419
  function computeStateHash(value) {
60935
- return createHash21("sha256").update(canonicalJson3(value), "utf8").digest("hex");
61420
+ return createHash22("sha256").update(canonicalJson3(value), "utf8").digest("hex");
60936
61421
  }
60937
61422
  function computeContentHash2(content) {
60938
- return createHash21("sha256").update(content, "utf8").digest("hex");
61423
+ return createHash22("sha256").update(content, "utf8").digest("hex");
60939
61424
  }
60940
61425
  function computeEventHash(event) {
60941
61426
  return computeStateHash({
@@ -62287,7 +62772,7 @@ async function runValidationWithTransientRetry(input, candidateContent, baseline
62287
62772
  if (!input.dispatcher) {
62288
62773
  throw new Error("no evaluation dispatcher available (cannot run validation)");
62289
62774
  }
62290
- const { createModelEvaluationExecutor: createModelEvaluationExecutor2 } = await import("./runner-jj32v8bk.js");
62775
+ const { createModelEvaluationExecutor: createModelEvaluationExecutor2 } = await import("./runner-pqsf809k.js");
62291
62776
  const executor = createModelEvaluationExecutor2(input.dispatcher, input.sessionId);
62292
62777
  const result = await _internals91.evaluateCandidateV1({
62293
62778
  projectRoot: input.directory,
@@ -64058,6 +64543,7 @@ Writes a retrospective evidence bundle for a completed phase.
64058
64543
  \`\`\`json
64059
64544
  {
64060
64545
  "phase": 1,
64546
+ "verdict": "pass",
64061
64547
  "summary": "Phase summary here",
64062
64548
  "task_count": 3,
64063
64549
  "task_complexity": "simple",
@@ -64076,6 +64562,8 @@ Writes a retrospective evidence bundle for a completed phase.
64076
64562
  - \`task_id\`: string (defaults to \`retro-{phase}\`)
64077
64563
  - \`metadata\`: Record<string, unknown>
64078
64564
 
64565
+ ### verdict values: pass | fail
64566
+
64079
64567
  ### task_complexity values: trivial | simple | moderate | complex`;
64080
64568
  }
64081
64569
  let parsedArgs;
@@ -64190,7 +64678,7 @@ function buildDetailedHelp(commandName, entry) {
64190
64678
  async function handleHelpCommand(ctx) {
64191
64679
  const targetCommand = ctx.args.join(" ");
64192
64680
  if (!targetCommand) {
64193
- const { buildHelpText } = await import("./index-hfzcztv6.js");
64681
+ const { buildHelpText } = await import("./index-9080b3de.js");
64194
64682
  return buildHelpText();
64195
64683
  }
64196
64684
  const tokens = targetCommand.split(/\s+/);
@@ -64199,7 +64687,7 @@ async function handleHelpCommand(ctx) {
64199
64687
  return _internals94.buildDetailedHelp(resolved.key, resolved.entry);
64200
64688
  }
64201
64689
  const similar = _internals94.findSimilarCommands(targetCommand);
64202
- const { buildHelpText: fullHelp } = await import("./index-hfzcztv6.js");
64690
+ const { buildHelpText: fullHelp } = await import("./index-9080b3de.js");
64203
64691
  if (similar.length > 0) {
64204
64692
  return `Command '/swarm ${targetCommand}' not found.
64205
64693
 
@@ -64376,7 +64864,7 @@ var COMMAND_REGISTRY = {
64376
64864
  },
64377
64865
  "guardrail explain": {
64378
64866
  handler: async (ctx) => {
64379
- const { handleGuardrailExplain } = await import("./guardrail-explain-kspf83x5.js");
64867
+ const { handleGuardrailExplain } = await import("./guardrail-explain-r50fery8.js");
64380
64868
  return handleGuardrailExplain(ctx.directory, ctx.args);
64381
64869
  },
64382
64870
  description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
@@ -64386,7 +64874,7 @@ var COMMAND_REGISTRY = {
64386
64874
  },
64387
64875
  "guardrail-explain": {
64388
64876
  handler: async (ctx) => {
64389
- const { handleGuardrailExplain } = await import("./guardrail-explain-kspf83x5.js");
64877
+ const { handleGuardrailExplain } = await import("./guardrail-explain-r50fery8.js");
64390
64878
  return handleGuardrailExplain(ctx.directory, ctx.args);
64391
64879
  },
64392
64880
  description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
@@ -64396,7 +64884,7 @@ var COMMAND_REGISTRY = {
64396
64884
  },
64397
64885
  "guardrail-log": {
64398
64886
  handler: async (ctx) => {
64399
- const { handleGuardrailLog } = await import("./guardrail-log-qg4sq6gr.js");
64887
+ const { handleGuardrailLog } = await import("./guardrail-log-p69eys6d.js");
64400
64888
  return handleGuardrailLog(ctx.directory, ctx.args);
64401
64889
  },
64402
64890
  description: "Read the guardrail decision log (use --blocks-only for blocks)",
@@ -68226,8 +68714,8 @@ function dcEvaluateRecursiveDeleteTargets(input) {
68226
68714
  }
68227
68715
  const filesystemTarget = target.replace(/[\\/]+/g, path109.sep);
68228
68716
  const resolved = path109.resolve(input.cwd, filesystemTarget);
68229
- const relative23 = path109.relative(path109.resolve(input.cwd), resolved);
68230
- if (relative23 === "" || relative23 === ".." || relative23.startsWith(`..${path109.sep}`) || path109.isAbsolute(relative23)) {
68717
+ const relative24 = path109.relative(path109.resolve(input.cwd), resolved);
68718
+ if (relative24 === "" || relative24 === ".." || relative24.startsWith(`..${path109.sep}`) || path109.isAbsolute(relative24)) {
68231
68719
  return {
68232
68720
  allowed: false,
68233
68721
  code: "DESTRUCTIVE_TARGET_OUTSIDE_WORKSPACE",
@@ -68242,7 +68730,7 @@ function dcEvaluateRecursiveDeleteTargets(input) {
68242
68730
  reason: `BLOCKED: Recursive delete target "${safeTarget}" is not an allowlisted build/cache artifact.`
68243
68731
  };
68244
68732
  }
68245
- const normalizedRelative = relative23.replace(/\\/g, "/");
68733
+ const normalizedRelative = relative24.replace(/\\/g, "/");
68246
68734
  const isBare = components.length === 1;
68247
68735
  if (!isBare) {
68248
68736
  hasNested = true;
@@ -71390,7 +71878,7 @@ function getDisplayBudget() {
71390
71878
  async function rehydratePrSubscriptions(sessionID, directory) {
71391
71879
  const map = new Map;
71392
71880
  try {
71393
- const { listActive: listActive2 } = await import("./pr-subscriptions-zc3skxde.js");
71881
+ const { listActive: listActive2 } = await import("./pr-subscriptions-2xn238xt.js");
71394
71882
  const records = await listActive2(directory);
71395
71883
  for (const record of records) {
71396
71884
  if (record.sessionID !== sessionID)
@@ -71622,14 +72110,23 @@ function serializeStandardWorktreeDispatches(sessionID, message) {
71622
72110
  pushAdvisory(session2, `${message} Serialization tracking is at capacity (256 sessions active); ` + `continuing in normal parallel mode.`);
71623
72111
  return;
71624
72112
  }
72113
+ standardWorktreeDegradationReasonBySession.set(sessionID, {
72114
+ reason: message,
72115
+ at: Date.now()
72116
+ });
71625
72117
  const session = ensureAgentSession(sessionID);
71626
72118
  session.maxConcurrencyOverride = 1;
71627
72119
  pushAdvisory(session, `${message} Serializing standard coder dispatches for this session.`);
71628
72120
  }
72121
+ var standardWorktreeDegradationReasonBySession = new Map;
72122
+ function getStandardWorktreeDegradationReason(sessionID) {
72123
+ return standardWorktreeDegradationReasonBySession.get(sessionID);
72124
+ }
71629
72125
  function resetStandardWorktreeIsolationState() {
71630
72126
  standardWorktreeByCallID.clear();
71631
72127
  standardWorktreeSerializationSessions.clear();
71632
72128
  serializationStateBySessionID.clear();
72129
+ standardWorktreeDegradationReasonBySession.clear();
71633
72130
  awaitingMergeByCallID.clear();
71634
72131
  standardWorktreeMergeQueue = Promise.resolve();
71635
72132
  standardWorktreeLaneIndexBySession.clear();
@@ -71639,6 +72136,7 @@ function releaseStandardWorktreeSerialization(sessionID) {
71639
72136
  return false;
71640
72137
  standardWorktreeSerializationSessions.delete(sessionID);
71641
72138
  serializationStateBySessionID.delete(sessionID);
72139
+ standardWorktreeDegradationReasonBySession.delete(sessionID);
71642
72140
  const session = ensureAgentSession(sessionID);
71643
72141
  session.maxConcurrencyOverride = undefined;
71644
72142
  pushAdvisory(session, `WORKTREE_SERIALIZATION_RELEASED: ${sessionID} regains parallel dispatch eligibility (release-after-dispatches or TTL).`);
@@ -71665,6 +72163,7 @@ function rememberStandardWorktreeSerializationSession(sessionID) {
71665
72163
  if (!hasInFlightStandardWorktreeDispatch(key)) {
71666
72164
  standardWorktreeSerializationSessions.delete(key);
71667
72165
  serializationStateBySessionID.delete(key);
72166
+ standardWorktreeDegradationReasonBySession.delete(key);
71668
72167
  evicted = true;
71669
72168
  break;
71670
72169
  }
@@ -71795,7 +72294,7 @@ function isLaneOwnedByCurrentSession(branchName, expectedSessionId) {
71795
72294
  return extracted === expectedSessionId;
71796
72295
  }
71797
72296
  async function inspectStandardWorktreeCollisionOwnership(identity) {
71798
- const collisionOwnership = await import("./worktree-collision-ownership-rfyyjjct.js");
72297
+ const collisionOwnership = await import("./worktree-collision-ownership-2jtg2my1.js");
71799
72298
  return collisionOwnership.inspectStandardWorktreeCollisionOwnership(identity);
71800
72299
  }
71801
72300
  async function precreateStandardWorktreeSession(args) {
@@ -71943,7 +72442,7 @@ async function precreateStandardWorktreeSession(args) {
71943
72442
  const laneProfile = computeLaneRuntimeProfile(worktreeConfig.runtime_isolation, laneIndex, provisionResult.worktreePath);
71944
72443
  if (laneProfile) {
71945
72444
  try {
71946
- const { writeLaneProfileToDiskReal } = await import("./core-qkh9me8x.js");
72445
+ const { writeLaneProfileToDiskReal } = await import("./core-c2zrd384.js");
71947
72446
  await writeLaneProfileToDiskReal(provisionResult.worktreePath, laneProfile.laneIndex, laneProfile.envOverrides);
71948
72447
  } catch {}
71949
72448
  }
@@ -71967,7 +72466,9 @@ async function precreateStandardWorktreeSession(args) {
71967
72466
  await _internals96.removeWorktree(provisionResult.worktreePath, args.directory, {
71968
72467
  force: true,
71969
72468
  worktreeDir: worktreeConfig.worktree_dir
71970
- }).catch(() => {});
72469
+ }).catch((cleanupError) => {
72470
+ log(`[worktree-isolation] session-create failure cleanup could not remove lane ${provisionResult.worktreePath}: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}`);
72471
+ });
71971
72472
  _internals96.removeWorktreeProvisioningOwner(args.directory, args.callID);
71972
72473
  const createError = createResult.error;
71973
72474
  const detail = typeof createError === "string" ? createError : JSON.stringify(createError ?? "missing session id");
@@ -72037,7 +72538,7 @@ async function preserveBackgroundWorktreeOwnershipForCallId(callID) {
72037
72538
  }
72038
72539
  const session = Buffer.from(dispatch.handle.sessionId, "utf8").toString("base64url");
72039
72540
  const lane = Buffer.from(dispatch.handle.id, "utf8").toString("base64url");
72040
- const callDigest = createHash22("sha256").update(callID).digest("hex").slice(0, 12);
72541
+ const callDigest = createHash23("sha256").update(callID).digest("hex").slice(0, 12);
72041
72542
  const tag = `swarm-preserved-owner/${session}/${lane}/${callDigest}`;
72042
72543
  let tagProc;
72043
72544
  try {
@@ -72599,7 +73100,7 @@ async function finishStandardWorktreeDispatch(directory, dispatch, config, callI
72599
73100
  }
72600
73101
  clearWorktreeMergeStatus(statusKey);
72601
73102
  try {
72602
- const { removeLaneProfileFromDiskReal } = await import("./core-qkh9me8x.js");
73103
+ const { removeLaneProfileFromDiskReal } = await import("./core-c2zrd384.js");
72603
73104
  await removeLaneProfileFromDiskReal(dispatch.handle.worktreePath, dispatch.laneIndex);
72604
73105
  } catch {}
72605
73106
  const state = serializationStateBySessionID.get(dispatch.parentSessionID);
@@ -72745,4 +73246,4 @@ var _internals96 = {
72745
73246
  resolveGitExecutable
72746
73247
  };
72747
73248
 
72748
- export { parseLeanLaneIndex, computeLaneRuntimeProfile, MAX_TRACKED_STANDARD_WORKTREE_CALLS, awaitingMergeByCallID, standardWorktreeByCallID, standardWorktreeSerializationSessions, resetStandardWorktreeIsolationState, checkStandardWorktreeSerializationRelease, sanitizeWorktreeTaskId, preProvisionCollisionCheck, isLaneOwnedByCurrentSession, precreateStandardWorktreeSession, preserveBackgroundWorktreeOwnershipForCallId, preserveDirtyWorktreeForCallId, preserveDirtyWorktreeAtPath, cleanupStandardWorktreeForCallId, abortStandardWorktreeDispatch, finishStandardWorktreeDispatch, readLaneEnvFileFromDisk, _internals96 as _internals, dcNormalizeCommand, dcUnwrapWrappers, dcSplitSegments, dcExtractRecursiveRmTargets, dcEvaluateRecursiveDeleteTargets, dcCheckJunctionCreation, dcExtractWindowsCmdTargets, dcExtractPowerShellTargets, normalizeSwarmCommandInput, canonicalCommandKey, formatCommandNotFound, executeSwarmCommand, SWARM_COMMAND_TOOL_COMMANDS, SWARM_COMMAND_TOOL_ALLOWLIST, HUMAN_ONLY_SWARM_COMMANDS, classifySwarmCommandToolUse, classifySwarmCommandChatFallbackUse, detectPosixWrites, detectWindowsWrites, resolveWriteTargets, handleAcknowledgeSpecDriftCommand, handleAgentsCommand, handleAnalyzeCommand, handleArchiveCommand, handleAutoProceedCommand, handleBenchmarkCommand, handleBrainstormCommand, handleCheckpointCommand, handleCiSimulateCommand, handleClarifyCommand, createCuratorLLMDelegate, _internals23 as _internals1, normalizeRecommendationEntryIdToken, parseKnowledgeRecommendations, parseKnowledgeRecommendationsWithDiagnostics, parseStructuredCuratorBlocks, readCuratorSummary, writeCuratorSummary, appendCuratorRecommendation, mergeCuratorPhaseSummary, filterPhaseEvents, checkPhaseCompliance, runCuratorInit, runCuratorPhase, applyCuratorKnowledgeUpdates, isHiveEligible, countDistinctProjects, checkHivePromotions, _internals27 as _internals2, createHivePromoterHook, promoteToHive, promoteFromSwarm, handleCloseCommand, handleCodebaseReviewCommand, handleConcurrencyCommand, handleConfigCommand, handleConsolidateCommand, handleCostsCommand, handleCouncilCommand, handleCurateCommand, handleDarkMatterCommand, handleDeepDiveCommand, handleDeepResearchCommand, getPluginConfigDir, getPluginCachePaths, getPluginLockFilePaths, VERSION_PINNED_LEAF, discoverVersionPinnedCachePaths, readCachePackageVersion, handleDiagnoseCommand, handleDoctorCommand, handleEvidenceCommand, handleEvidenceSummaryCommand, handleExportCommand, handleFullAutoCommand, handleGateAuditCommand, handleGateStatsCommand, handleHandoffCommand, handleHistoryCommand, handleKnowledgeQuarantineCommand, handleKnowledgeRestoreCommand, handleKnowledgeMigrateCommand, handleKnowledgeListCommand, handleKnowledgeUnactionableCommand, handleKnowledgeRetryHardeningCommand, handleLearningCommand, handleLinkCommand, safeRealpathSync, handleMemoryCommand, handleMemoryStatusCommand, handleMemoryValueLogCommand, handleMemoryMigrateCommand, handleMemoryImportCommand, handleMemoryExportCommand, handlePlanCommand, handlePreflightCommand, handlePromoteCommand, handleQaGatesCommand, handleRecoverCommand, handleResetCommand, handleResetSessionCommand, handleRetrieveCommand, handleReviewCommand, handleRollbackCommand, handleSddStatusCommand, handleSddValidateCommand, handleSddProjectCommand, handleSddCommand, handleSimulateCommand, handleSpecifyCommand, handleStatusCommand, handleSyncPlanCommand, handleTurboCommand, handleUnlinkCommand, handleWriteRetroCommand, handleHelpCommand, COMMAND_REGISTRY, VALID_COMMANDS, _internals94 as _internals3, resolveCommand };
73249
+ export { parseLeanLaneIndex, computeLaneRuntimeProfile, MAX_TRACKED_STANDARD_WORKTREE_CALLS, awaitingMergeByCallID, standardWorktreeByCallID, standardWorktreeSerializationSessions, getStandardWorktreeDegradationReason, resetStandardWorktreeIsolationState, checkStandardWorktreeSerializationRelease, sanitizeWorktreeTaskId, preProvisionCollisionCheck, isLaneOwnedByCurrentSession, precreateStandardWorktreeSession, preserveBackgroundWorktreeOwnershipForCallId, preserveDirtyWorktreeForCallId, preserveDirtyWorktreeAtPath, cleanupStandardWorktreeForCallId, abortStandardWorktreeDispatch, finishStandardWorktreeDispatch, readLaneEnvFileFromDisk, _internals96 as _internals, dcNormalizeCommand, dcUnwrapWrappers, dcSplitSegments, dcExtractRecursiveRmTargets, dcEvaluateRecursiveDeleteTargets, dcCheckJunctionCreation, dcExtractWindowsCmdTargets, dcExtractPowerShellTargets, normalizeSwarmCommandInput, canonicalCommandKey, formatCommandNotFound, executeSwarmCommand, SWARM_COMMAND_TOOL_COMMANDS, SWARM_COMMAND_TOOL_ALLOWLIST, HUMAN_ONLY_SWARM_COMMANDS, classifySwarmCommandToolUse, classifySwarmCommandChatFallbackUse, detectPosixWrites, detectWindowsWrites, resolveWriteTargets, handleAcknowledgeSpecDriftCommand, handleAgentsCommand, handleAnalyzeCommand, handleArchiveCommand, handleAutoProceedCommand, handleBenchmarkCommand, handleBrainstormCommand, handleCheckpointCommand, handleCiSimulateCommand, handleClarifyCommand, createCuratorLLMDelegate, _internals23 as _internals1, normalizeRecommendationEntryIdToken, parseKnowledgeRecommendations, parseKnowledgeRecommendationsWithDiagnostics, parseStructuredCuratorBlocks, readCuratorSummary, writeCuratorSummary, appendCuratorRecommendation, mergeCuratorPhaseSummary, filterPhaseEvents, checkPhaseCompliance, runCuratorInit, runCuratorPhase, applyCuratorKnowledgeUpdates, isHiveEligible, countDistinctProjects, checkHivePromotions, _internals27 as _internals2, createHivePromoterHook, promoteToHive, promoteFromSwarm, handleCloseCommand, handleCodebaseReviewCommand, handleConcurrencyCommand, handleConfigCommand, handleConsolidateCommand, handleCostsCommand, handleCouncilCommand, handleCurateCommand, handleDarkMatterCommand, handleDeepDiveCommand, handleDeepResearchCommand, getPluginConfigDir, getPluginCachePaths, getPluginLockFilePaths, VERSION_PINNED_LEAF, discoverVersionPinnedCachePaths, readCachePackageVersion, handleDiagnoseCommand, handleDoctorCommand, handleEvidenceCommand, handleEvidenceSummaryCommand, handleExportCommand, handleFullAutoCommand, handleGateAuditCommand, handleGateStatsCommand, handleHandoffCommand, handleHistoryCommand, handleKnowledgeQuarantineCommand, handleKnowledgeRestoreCommand, handleKnowledgeMigrateCommand, handleKnowledgeListCommand, handleKnowledgeUnactionableCommand, handleKnowledgeRetryHardeningCommand, handleLearningCommand, handleLinkCommand, safeRealpathSync, handleMemoryCommand, handleMemoryStatusCommand, handleMemoryValueLogCommand, handleMemoryMigrateCommand, handleMemoryImportCommand, handleMemoryExportCommand, handlePlanCommand, handlePreflightCommand, handlePromoteCommand, handleQaGatesCommand, handleRecoverCommand, handleResetCommand, handleResetSessionCommand, handleRetrieveCommand, handleReviewCommand, handleRollbackCommand, handleSddStatusCommand, handleSddValidateCommand, handleSddProjectCommand, handleSddCommand, handleSimulateCommand, handleSpecifyCommand, handleStatusCommand, handleSyncPlanCommand, handleTurboCommand, handleUnlinkCommand, handleWriteRetroCommand, handleHelpCommand, COMMAND_REGISTRY, VALID_COMMANDS, _internals94 as _internals3, resolveCommand };