opencode-swarm 7.146.2 → 7.146.4

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 (86) hide show
  1. package/.opencode/skills/swarm-pr-review/SKILL.md +27 -44
  2. package/.opencode/skills/swarm-pr-review/references/findings-persistence-contract.md +52 -12
  3. package/.opencode/skills/swarm-pr-review/references/lane-output-recoverability.md +6 -3
  4. package/.opencode/skills/swarm-pr-review/references/parser-dry-run.md +19 -1
  5. package/.opencode/skills/swarm-pr-review/references/verdict-settlement-contract.md +41 -0
  6. package/dist/agents/council-prompts.d.ts +3 -3
  7. package/dist/background/candidate-contract.d.ts +21 -1
  8. package/dist/background/candidate-parser.d.ts +21 -1
  9. package/dist/background/pending-delegations.d.ts +8 -1
  10. package/dist/background/pr-review-collection-receipt.d.ts +70 -0
  11. package/dist/cli/{config-doctor-vstrprja.js → config-doctor-578ebqhn.js} +2 -2
  12. package/dist/cli/{core-3wzpwe5z.js → core-2ne03a43.js} +1 -1
  13. package/dist/cli/{curation-policy-x19e8bqc.js → curation-policy-g353f457.js} +6 -6
  14. package/dist/cli/{curator-llm-factory-6bra0bfd.js → curator-llm-factory-6hgn7p6n.js} +27 -27
  15. package/dist/cli/{curator-cvy1s7wd.js → curator-w52frg17.js} +27 -27
  16. package/dist/cli/{evidence-summary-service-yhap2xph.js → evidence-summary-service-nj4p6a0d.js} +11 -11
  17. package/dist/cli/{gate-evidence-vxbyq5sb.js → gate-evidence-4vnjdh9y.js} +6 -6
  18. package/dist/cli/{guardrail-explain-h8cnwa02.js → guardrail-explain-rq01z1yz.js} +28 -28
  19. package/dist/cli/{guardrail-log-syb7tz2w.js → guardrail-log-ratb651f.js} +3 -3
  20. package/dist/cli/{hive-promoter-3tex870c.js → hive-promoter-pbm9kee1.js} +27 -27
  21. package/dist/cli/{index-yxhcy5cm.js → index-1mbdwy12.js} +55 -1
  22. package/dist/cli/{index-01ybcsa5.js → index-3neh2mxk.js} +2 -2
  23. package/dist/cli/{index-5e5a1y2r.js → index-3p4wgm0d.js} +1 -1
  24. package/dist/cli/{index-4vwn66wk.js → index-5cbbtbvf.js} +3 -3
  25. package/dist/cli/{index-z5ppkn8y.js → index-6eycwm3v.js} +6 -6
  26. package/dist/cli/{index-bghwrr59.js → index-6q35swn2.js} +1 -1
  27. package/dist/cli/{index-qbpxrw95.js → index-8py21zn6.js} +2 -2
  28. package/dist/cli/{index-tj861zhd.js → index-96zkay2e.js} +4 -4
  29. package/dist/cli/{index-y3hmyvt6.js → index-bq4mvwht.js} +2 -2
  30. package/dist/cli/{index-rfph0nhf.js → index-brb64k96.js} +1426 -635
  31. package/dist/cli/{index-p0m03xa6.js → index-df8xj9hr.js} +4 -4
  32. package/dist/cli/{index-cr90rcg3.js → index-dp5w9s5z.js} +7 -7
  33. package/dist/cli/{index-w0cj7zyd.js → index-f75qjtn5.js} +1 -1
  34. package/dist/cli/{index-vmfaafte.js → index-ffqdah8s.js} +5 -5
  35. package/dist/cli/{index-f3x2gsby.js → index-fp2d44f5.js} +1 -1
  36. package/dist/cli/{index-jv9xs6mb.js → index-g2r8nknz.js} +2 -2
  37. package/dist/cli/{index-n4k0pt5f.js → index-g335vrc7.js} +4 -4
  38. package/dist/cli/{index-z9ed68jt.js → index-gr3zfcsh.js} +18 -4
  39. package/dist/cli/{index-w5r84rd1.js → index-hcb25p12.js} +1 -1
  40. package/dist/cli/{index-ycgm9pzg.js → index-hw1yghpg.js} +7 -6
  41. package/dist/cli/{index-a1febb2k.js → index-jgwhpza8.js} +2 -2
  42. package/dist/cli/{index-cx67qa9g.js → index-kjmcp9mf.js} +1 -1
  43. package/dist/cli/{index-42nq97rb.js → index-kv2j4cnq.js} +6 -6
  44. package/dist/cli/{index-zkaz3fhw.js → index-p3k155dv.js} +2 -2
  45. package/dist/cli/{index-qyvjp0bq.js → index-q81s0m8k.js} +66 -37
  46. package/dist/cli/{index-97psh79d.js → index-rpy0bent.js} +178 -18
  47. package/dist/cli/{index-r46q6996.js → index-t798v5pq.js} +29 -29
  48. package/dist/cli/{index-e1hjd15c.js → index-tp5ytzzg.js} +1 -1
  49. package/dist/cli/{index-vj9bba5k.js → index-vdrwj7z0.js} +4 -4
  50. package/dist/cli/{index-46cypnz3.js → index-wesj94x0.js} +4 -4
  51. package/dist/cli/{index-c9jr4j2q.js → index-xsxj4vbf.js} +1 -1
  52. package/dist/cli/index.js +27 -27
  53. package/dist/cli/{knowledge-escalator-mn4sx4qd.js → knowledge-escalator-jbazxmk5.js} +11 -11
  54. package/dist/cli/{knowledge-events-x975ngy4.js → knowledge-events-jyqy3st8.js} +9 -9
  55. package/dist/cli/{knowledge-link-8pr02pza.js → knowledge-link-jkx8xjxp.js} +5 -5
  56. package/dist/cli/{knowledge-store-33p762ey.js → knowledge-store-e2defagd.js} +6 -6
  57. package/dist/cli/{knowledge-validator-q5jc0scs.js → knowledge-validator-pnmdsw2b.js} +8 -8
  58. package/dist/cli/{pending-delegations-kkrczqv7.js → pending-delegations-k2yqg1sj.js} +3 -3
  59. package/dist/cli/{pr-subscriptions-2xn238xt.js → pr-subscriptions-js5v2xr6.js} +3 -3
  60. package/dist/cli/{runner-e7z9cf5y.js → runner-q7d22d1w.js} +6 -6
  61. package/dist/cli/{scan-cursor-p7t5mb4x.js → scan-cursor-snx85enn.js} +7 -7
  62. package/dist/cli/{schema-t8bmshhj.js → schema-6rmxzg6g.js} +1 -1
  63. package/dist/cli/{scope-persistence-2kyrgsca.js → scope-persistence-23cqafkx.js} +7 -7
  64. package/dist/cli/{skill-generator-fwvmcv8m.js → skill-generator-980zjk9q.js} +13 -13
  65. package/dist/cli/{telemetry-t109dhv7.js → telemetry-xzy0qeap.js} +1 -1
  66. package/dist/cli/{worktree-collision-ownership-2jtg2my1.js → worktree-collision-ownership-xj0bsg92.js} +3 -3
  67. package/dist/cli/{worktree-isolation-87j70zg1.js → worktree-isolation-4d0nc04c.js} +27 -27
  68. package/dist/commands/close.d.ts +1 -0
  69. package/dist/commands/context-map-stats.d.ts +5 -0
  70. package/dist/config/schema.d.ts +16 -0
  71. package/dist/context-map/telemetry.d.ts +168 -26
  72. package/dist/council/council-evidence-writer.d.ts +2 -1
  73. package/dist/council/council-freshness.d.ts +49 -0
  74. package/dist/council/council-review-identity.d.ts +133 -0
  75. package/dist/council/council-round-state.d.ts +27 -3
  76. package/dist/council/disagreement-detector.d.ts +12 -2
  77. package/dist/council/general-council-types.d.ts +32 -0
  78. package/dist/council/types.d.ts +43 -7
  79. package/dist/hooks/pr-workflow-gate.d.ts +58 -5
  80. package/dist/index.js +177 -152
  81. package/dist/observability/catalog.d.ts +7 -5
  82. package/dist/telemetry.d.ts +22 -1
  83. package/dist/tools/dispatch-lanes.d.ts +30 -8
  84. package/dist/tools/phase-complete/gates/types.d.ts +7 -0
  85. package/dist/tools/write-final-council-evidence.d.ts +1 -7
  86. package/package.json +2 -1
@@ -6,16 +6,16 @@ import {
6
6
  resolveExecutableFromPath,
7
7
  runEvaluation,
8
8
  runExternalTool
9
- } from "./index-w5r84rd1.js";
9
+ } from "./index-hcb25p12.js";
10
10
  import {
11
11
  stableCanonicalStringify
12
- } from "./index-c9jr4j2q.js";
12
+ } from "./index-xsxj4vbf.js";
13
13
  import {
14
14
  detectStraySwarmDirs,
15
15
  readDoctorArtifact,
16
16
  removeStraySwarmDir,
17
17
  runConfigDoctor
18
- } from "./index-yxhcy5cm.js";
18
+ } from "./index-1mbdwy12.js";
19
19
  import {
20
20
  MAX_TRANSIENT_RETRIES,
21
21
  archiveEvidence,
@@ -61,7 +61,7 @@ import {
61
61
  updateTaskStatus,
62
62
  validateProjectRoot,
63
63
  validateSymlinkBoundary
64
- } from "./index-z5ppkn8y.js";
64
+ } from "./index-6eycwm3v.js";
65
65
  import {
66
66
  EvaluationTaskV1Schema,
67
67
  GateAuditManifestV1Schema,
@@ -78,7 +78,7 @@ import {
78
78
  saveGateAuditResult,
79
79
  savePromotionDecision,
80
80
  saveTaskSetSnapshot
81
- } from "./index-zkaz3fhw.js";
81
+ } from "./index-p3k155dv.js";
82
82
  import {
83
83
  loadDatabaseCtor
84
84
  } from "./index-134d35c1.js";
@@ -104,12 +104,12 @@ import {
104
104
  } from "./index-y8552snf.js";
105
105
  import {
106
106
  readRecentEscalations
107
- } from "./index-vmfaafte.js";
107
+ } from "./index-ffqdah8s.js";
108
108
  import {
109
109
  alreadyCuratedThisGeneration,
110
110
  claimNextScanBatch,
111
111
  resolveCohortId
112
- } from "./index-jv9xs6mb.js";
112
+ } from "./index-g2r8nknz.js";
113
113
  import {
114
114
  CURATOR_INIT_PROMPT,
115
115
  CURATOR_PHASE_PROMPT,
@@ -158,7 +158,7 @@ import {
158
158
  listActive,
159
159
  subscribe,
160
160
  unsubscribe
161
- } from "./index-5e5a1y2r.js";
161
+ } from "./index-3p4wgm0d.js";
162
162
  import {
163
163
  BUNDLED_PROJECT_SKILL_ROOT,
164
164
  DEFAULT_SKILL_MIN_CONFIDENCE,
@@ -179,7 +179,7 @@ import {
179
179
  retireSkill,
180
180
  selectCandidateEntries,
181
181
  syncBundledProjectSkillsIfMissingAsync
182
- } from "./index-vj9bba5k.js";
182
+ } from "./index-vdrwj7z0.js";
183
183
  import {
184
184
  appendUnactionable,
185
185
  quarantineEntry,
@@ -190,11 +190,11 @@ import {
190
190
  validateActionableFields,
191
191
  validateLesson,
192
192
  validateSkillPath
193
- } from "./index-n4k0pt5f.js";
193
+ } from "./index-g335vrc7.js";
194
194
  import {
195
195
  authorizeCuration,
196
196
  buildConfigFingerprintInput
197
- } from "./index-e1hjd15c.js";
197
+ } from "./index-tp5ytzzg.js";
198
198
  import {
199
199
  cohortConfigFingerprint
200
200
  } from "./index-rtry5xyf.js";
@@ -208,12 +208,13 @@ import {
208
208
  DEFAULT_STALE_DELEGATION_TIMEOUT_MS,
209
209
  DELEGATION_COMPACTION_HIGH_WATER_BYTES,
210
210
  DELEGATION_COMPACTION_LOW_WATER_BYTES,
211
+ MAX_PR_REVIEW_COLLECTION_RECEIPT_ITEM_IDS,
211
212
  MAX_RECOVERY_LEDGER_BYTES,
212
213
  collectDelegationLedgerHealth,
213
214
  findByBatchId,
214
215
  readDelegations,
215
216
  sweepStaleDelegations
216
- } from "./index-97psh79d.js";
217
+ } from "./index-rpy0bent.js";
217
218
  import {
218
219
  WORKTREE_LIFECYCLE_LOCK_FILE,
219
220
  recordWorktreeProvisioningOwner,
@@ -246,18 +247,18 @@ import {
246
247
  transitionTaskWorkflowEvidence,
247
248
  withTaskEvidenceTransaction,
248
249
  writeWorkflowWalFile
249
- } from "./index-tj861zhd.js";
250
+ } from "./index-96zkay2e.js";
250
251
  import {
251
252
  provisionWorktree,
252
253
  removeWorktree
253
- } from "./index-cx67qa9g.js";
254
+ } from "./index-kjmcp9mf.js";
254
255
  import {
255
256
  MAX_PENDING_SCOPE_BINDINGS,
256
257
  canonicalWorkspaceIdentity,
257
258
  clearAllScopes,
258
259
  clearScopeBindingFromDisk,
259
260
  clearScopeBindings
260
- } from "./index-46cypnz3.js";
261
+ } from "./index-wesj94x0.js";
261
262
  import {
262
263
  appendLedgerEvent,
263
264
  computePlanHash,
@@ -267,11 +268,12 @@ import {
267
268
  getOrAdoptPlanEpochUnderLock,
268
269
  initLedger,
269
270
  ledgerExists,
271
+ normalizeExecutionProfileForHash,
270
272
  readLedgerEvents,
271
273
  readPlanEpochIdentity,
272
274
  replayFromLedgerWithStatus,
273
275
  takeSnapshotEvent
274
- } from "./index-p0m03xa6.js";
276
+ } from "./index-df8xj9hr.js";
275
277
  import {
276
278
  isPathWithinDeclaredScope,
277
279
  sanitizeDiagnosticText
@@ -322,7 +324,7 @@ import {
322
324
  transactFile,
323
325
  transactKnowledge,
324
326
  wordBigrams
325
- } from "./index-42nq97rb.js";
327
+ } from "./index-kv2j4cnq.js";
326
328
  import {
327
329
  MAX_EVENT_LOG_ENTRIES,
328
330
  _internals as _internals2,
@@ -336,10 +338,10 @@ import {
336
338
  recordKnowledgeEvent,
337
339
  recordPhaseCloseIntent,
338
340
  resolveKnowledgeEventsPath
339
- } from "./index-cr90rcg3.js";
341
+ } from "./index-dp5w9s5z.js";
340
342
  import {
341
343
  resolveWorktreeIsolationConfig
342
- } from "./index-y3hmyvt6.js";
344
+ } from "./index-bq4mvwht.js";
343
345
  import {
344
346
  RetrospectiveEvidenceSchema
345
347
  } from "./index-gprxjmm7.js";
@@ -349,7 +351,7 @@ import {
349
351
  init_loader,
350
352
  loadPluginConfig,
351
353
  loadPluginConfigWithMeta
352
- } from "./index-01ybcsa5.js";
354
+ } from "./index-3neh2mxk.js";
353
355
  import {
354
356
  DEFAULT_SKILL_OPT_CONFIG,
355
357
  FALLBACK_MODELS_MAX,
@@ -363,7 +365,7 @@ import {
363
365
  package_default,
364
366
  resolveAutoReviewConfig,
365
367
  stripKnownSwarmPrefix
366
- } from "./index-z9ed68jt.js";
368
+ } from "./index-gr3zfcsh.js";
367
369
  import {
368
370
  AGENT_TOOL_MAP,
369
371
  ALL_AGENT_NAMES,
@@ -414,10 +416,10 @@ import {
414
416
  resolveLinkDir,
415
417
  sanitizeLinkId,
416
418
  writeLinkPointer
417
- } from "./index-w0cj7zyd.js";
419
+ } from "./index-f75qjtn5.js";
418
420
  import {
419
421
  atomicWriteFile
420
- } from "./index-qbpxrw95.js";
422
+ } from "./index-8py21zn6.js";
421
423
  import {
422
424
  KNOWLEDGE_SCHEMA_VERSION,
423
425
  OUTCOME_BLOCK_THRESHOLD,
@@ -429,7 +431,7 @@ import {
429
431
  atomicWriteSwarmFileSync,
430
432
  matchTempGrammar,
431
433
  parseTargetBasename
432
- } from "./index-ycgm9pzg.js";
434
+ } from "./index-hw1yghpg.js";
433
435
  import {
434
436
  assertProjectRoot,
435
437
  hasExplicitProjectBoundary,
@@ -437,12 +439,12 @@ import {
437
439
  listActiveLocks,
438
440
  tryAcquireLock,
439
441
  withEvidenceLock
440
- } from "./index-bghwrr59.js";
442
+ } from "./index-6q35swn2.js";
441
443
  import {
442
444
  emit,
443
445
  getLastHeartbeat,
444
446
  telemetry
445
- } from "./index-qyvjp0bq.js";
447
+ } from "./index-q81s0m8k.js";
446
448
  import {
447
449
  require_proper_lockfile
448
450
  } from "./index-7g4c7s5r.js";
@@ -469,20 +471,107 @@ import {
469
471
 
470
472
  // src/hooks/delegation-gate/worktree-isolation.ts
471
473
  init_constants();
472
- import { createHash as createHash24 } from "crypto";
474
+ import { createHash as createHash25 } from "crypto";
473
475
  import * as fs53 from "fs/promises";
474
476
  import * as path114 from "path";
475
477
  init_executor();
476
478
 
477
479
  // src/state.ts
478
480
  init_constants();
481
+ init_loader();
479
482
  import { randomUUID as randomUUID14 } from "crypto";
480
483
  import * as fs52 from "fs/promises";
481
484
  import * as path113 from "path";
482
485
  init_schema();
483
486
 
484
- // src/db/qa-gate-profile.ts
487
+ // src/council/council-review-identity.ts
488
+ init_schema();
485
489
  import { createHash } from "crypto";
490
+ var COUNCIL_REVIEW_IDENTITY_VERSION = 2;
491
+ function computeCouncilReviewHash(plan) {
492
+ const normalized = {
493
+ schema_version: plan.schema_version,
494
+ title: plan.title,
495
+ swarm: plan.swarm,
496
+ migration_status: plan.migration_status,
497
+ execution_profile: normalizeExecutionProfileForHash(plan.execution_profile),
498
+ phases: plan.phases.map((phase) => ({
499
+ id: phase.id,
500
+ name: phase.name,
501
+ type: phase.type,
502
+ required_agents: phase.required_agents ? [...phase.required_agents].sort() : undefined,
503
+ tasks: phase.tasks.map((task) => ({
504
+ id: task.id,
505
+ phase: task.phase,
506
+ size: task.size,
507
+ description: task.description,
508
+ depends: [...task.depends].sort(),
509
+ acceptance: task.acceptance,
510
+ files_touched: [...task.files_touched].sort(),
511
+ evidence_path: task.evidence_path,
512
+ fr_refs: task.fr_refs ? [...task.fr_refs].sort() : undefined
513
+ }))
514
+ }))
515
+ };
516
+ return createHash("sha256").update(JSON.stringify(normalized), "utf8").digest("hex");
517
+ }
518
+ function computeCouncilPolicyDigest(level, config) {
519
+ const base = {
520
+ maxRounds: config?.maxRounds ?? 3,
521
+ vetoPriority: config?.vetoPriority ?? true,
522
+ freshnessMaxAgeHours: config?.freshnessMaxAgeHours ?? 24
523
+ };
524
+ let normalized;
525
+ if (level === "final") {
526
+ normalized = {
527
+ ...base,
528
+ finalCompletionPolicy: resolveFinalCompletionPolicy(config)
529
+ };
530
+ } else if (level === "phase") {
531
+ normalized = {
532
+ ...base,
533
+ requireAllMembers: config?.requireAllMembers ?? false,
534
+ minimumMembers: config?.minimumMembers ?? 3,
535
+ phaseConcernsAllowComplete: config?.phaseConcernsAllowComplete ?? true
536
+ };
537
+ } else {
538
+ normalized = {
539
+ ...base,
540
+ requireAllMembers: config?.requireAllMembers ?? false,
541
+ minimumMembers: config?.minimumMembers ?? 3
542
+ };
543
+ }
544
+ return createHash("sha256").update(JSON.stringify(normalized), "utf8").digest("hex");
545
+ }
546
+ function resolveFinalCompletionPolicy(config) {
547
+ const policy = config?.finalCompletionPolicy;
548
+ if (!policy || policy.mode !== "quorum") {
549
+ return { mode: "all_required" };
550
+ }
551
+ const minimum = policy.minimumMembers;
552
+ if (typeof minimum === "number" && Number.isInteger(minimum) && minimum >= 3 && minimum <= 5) {
553
+ return { mode: "quorum", minimumMembers: minimum };
554
+ }
555
+ return { mode: "all_required" };
556
+ }
557
+ function computeCouncilReviewIdentity(input) {
558
+ const identity = {
559
+ version: COUNCIL_REVIEW_IDENTITY_VERSION,
560
+ level: input.level,
561
+ scope: input.scope,
562
+ planId: input.plan ? derivePlanId(input.plan) : null,
563
+ planIdentityHash: input.plan ? derivePlanIdentityHash(input.plan) : null,
564
+ reviewHash: input.plan ? computeCouncilReviewHash(input.plan) : null,
565
+ policyDigest: computeCouncilPolicyDigest(input.level, input.config)
566
+ };
567
+ return {
568
+ ...identity,
569
+ identityDigest: createHash("sha256").update(JSON.stringify(identity), "utf8").digest("hex")
570
+ };
571
+ }
572
+
573
+ // src/db/qa-gate-profile.ts
574
+ import { createHash as createHash2 } from "crypto";
486
575
 
487
576
  // src/qa-gate/recovery.ts
488
577
  function formatLegacyQaBindingOnlyCall(identity) {
@@ -928,7 +1017,7 @@ function computeProfileHash(profile) {
928
1017
  identity_hash: profile.identity_hash,
929
1018
  gates: profile.gates
930
1019
  });
931
- return createHash("sha256").update(payload).digest("hex");
1020
+ return createHash2("sha256").update(payload).digest("hex");
932
1021
  }
933
1022
  function getEffectiveGates(profile, sessionOverrides) {
934
1023
  const merged = { ...profile.gates };
@@ -4197,7 +4286,7 @@ async function cleanupRecoveredWorktree(directory, descriptor) {
4197
4286
  awaitingMergeByCallID,
4198
4287
  cleanupStandardWorktreeForCallId,
4199
4288
  standardWorktreeByCallID
4200
- } = await import("./worktree-isolation-87j70zg1.js");
4289
+ } = await import("./worktree-isolation-4d0nc04c.js");
4201
4290
  standardWorktreeByCallID.delete(descriptor.callID);
4202
4291
  if (hasResidue)
4203
4292
  awaitingMergeByCallID.set(descriptor.callID, {
@@ -4299,7 +4388,7 @@ async function recoverCoderSettlement(directory, taskId) {
4299
4388
  awaitingMergeByCallID,
4300
4389
  finishStandardWorktreeDispatch,
4301
4390
  standardWorktreeByCallID
4302
- } = await import("./worktree-isolation-87j70zg1.js");
4391
+ } = await import("./worktree-isolation-4d0nc04c.js");
4303
4392
  const descriptor = wal.worktree;
4304
4393
  const reconstructedDispatch = {
4305
4394
  callID: descriptor.callID,
@@ -4962,7 +5051,7 @@ async function commitTaskTerminalUnderPlanLock(options) {
4962
5051
 
4963
5052
  // src/hooks/pr-workflow-gate.ts
4964
5053
  init_zod();
4965
- import { createHash as createHash4, randomUUID as randomUUID3 } from "crypto";
5054
+ import { createHash as createHash5, randomUUID as randomUUID3 } from "crypto";
4966
5055
  import { readFileSync as readFileSync4 } from "fs";
4967
5056
  import * as fsp2 from "fs/promises";
4968
5057
  import * as path11 from "path";
@@ -4975,6 +5064,7 @@ var CANDIDATE_SEVERITIES = [
4975
5064
  "HIGH",
4976
5065
  "CRITICAL"
4977
5066
  ];
5067
+ var FINDINGS_SEVERITIES = [...CANDIDATE_SEVERITIES, "NONE"];
4978
5068
  var CANDIDATE_CONFIDENCES = ["HIGH", "MEDIUM", "LOW"];
4979
5069
  var CANDIDATE_FIELD_COUNT = 9;
4980
5070
  var CLEAN_FIELD_COUNT = 4;
@@ -5143,6 +5233,38 @@ function repairRedundantCleanConfidence(text, family) {
5143
5233
  `), repaired };
5144
5234
  }
5145
5235
  var NON_CONTRACT_MARKER_LINE = /^\[(?!(?:CANDIDATE|CLEAN)\])[A-Z][A-Z0-9_-]*\]/;
5236
+ function canonicalHeaderShape(line) {
5237
+ const fields = splitPipeFields(line.trim()).map((field) => field.trim());
5238
+ if (fields.length === 0)
5239
+ return null;
5240
+ if (candidateHeaderFamily(fields))
5241
+ return { markerBearing: true };
5242
+ for (const family of ["base_explorer", "micro_lane"]) {
5243
+ const canonical = CANDIDATE_FIELDS[family].map((name) => name === "file_line" ? "file:line" : name);
5244
+ if (fields.length === canonical.length && canonical.every((name, index) => fields[index] === name)) {
5245
+ return { markerBearing: false };
5246
+ }
5247
+ }
5248
+ return null;
5249
+ }
5250
+ function dropDuplicateHeaderRows(text) {
5251
+ const lines = text.split(/\r?\n/);
5252
+ const shapes = lines.map((line) => line.includes("|") ? canonicalHeaderShape(line) : null);
5253
+ const keepIndex = (() => {
5254
+ const markerBearing = shapes.findIndex((shape) => shape?.markerBearing);
5255
+ if (markerBearing !== -1)
5256
+ return markerBearing;
5257
+ return shapes.findIndex((shape) => shape !== null);
5258
+ })();
5259
+ if (keepIndex === -1)
5260
+ return { text, dropped: false };
5261
+ const kept = lines.filter((_line, index) => shapes[index] === null || index === keepIndex);
5262
+ return {
5263
+ text: kept.join(`
5264
+ `),
5265
+ dropped: kept.length !== lines.length
5266
+ };
5267
+ }
5146
5268
  function dropNonContractMarkerRows(text) {
5147
5269
  const lines = text.split(/\r?\n/);
5148
5270
  const kept = lines.filter((line) => {
@@ -5257,7 +5379,11 @@ function normalizeCandidateArtifact(rawText, fallbackFamily) {
5257
5379
  const pipeRepair = repairCleanEvidencePipes(cleanRepair.text);
5258
5380
  if (pipeRepair.repaired)
5259
5381
  repairKinds.push("clean-evidence-pipe-tail-merge");
5260
- const text = pipeRepair.text;
5382
+ const duplicateHeaderDrop = dropDuplicateHeaderRows(pipeRepair.text);
5383
+ if (duplicateHeaderDrop.dropped) {
5384
+ repairKinds.push("duplicate-header-row-dropped");
5385
+ }
5386
+ const text = duplicateHeaderDrop.text;
5261
5387
  const header = selectCandidateHeader(text.split(/\r?\n/));
5262
5388
  if (header?.markerBearing && header.family !== null) {
5263
5389
  return { text, synthesizedHeader: false, repairKinds };
@@ -5835,6 +5961,7 @@ function parseText(input, flags) {
5835
5961
  let pendingClean;
5836
5962
  let cleanErrorCode;
5837
5963
  let cleanErrorMessage;
5964
+ let cleanSalvageReason;
5838
5965
  for (let i = headerIndex + 1;i < lines.length; i++) {
5839
5966
  const rawLine = lines[i];
5840
5967
  const trimmed = rawLine.trim();
@@ -6082,19 +6209,13 @@ ${trimmed}`;
6082
6209
  }
6083
6210
  }
6084
6211
  const pendingCleanLane = pendingClean ? pendingClean.row_format_family === "base_explorer" ? pendingClean.lane : pendingClean.micro_lane : null;
6085
- if (pendingClean && pendingCleanLane !== null) {
6212
+ if (pendingClean && pendingCleanLane !== null && !cleanErrorCode) {
6086
6213
  const conflictingCandidate = candidates.find((candidate) => (candidate.lane ?? candidate.micro_lane) === pendingCleanLane);
6087
6214
  if (conflictingCandidate) {
6088
- cleanErrorCode = "conflicting-clean-attestation";
6089
- cleanErrorMessage = `CLEAN attestation cannot appear with candidate rows for the same lane (${pendingCleanLane})`;
6090
- parseErrorDetails.push({
6091
- row_index: headerIndex,
6092
- field: "clean_attestation",
6093
- message: cleanErrorMessage
6094
- });
6215
+ cleanSalvageReason = `CLEAN attestation discredited: it cannot appear with candidate rows for the same lane (${pendingCleanLane}); the candidate rows were retained`;
6095
6216
  }
6096
6217
  }
6097
- if (pendingClean && !cleanErrorCode && (malformedRows > 0 || parseErrorDetails.length > 0)) {
6218
+ if (pendingClean && !cleanErrorCode && !cleanSalvageReason && (malformedRows > 0 || parseErrorDetails.length > 0)) {
6098
6219
  cleanErrorCode = "untrusted-clean-attestation";
6099
6220
  cleanErrorMessage = "CLEAN attestation requires zero malformed rows and zero parse errors";
6100
6221
  parseErrorDetails.push({
@@ -6103,7 +6224,7 @@ ${trimmed}`;
6103
6224
  message: cleanErrorMessage
6104
6225
  });
6105
6226
  }
6106
- const cleanAttestation = pendingClean && !cleanErrorCode ? pendingClean : undefined;
6227
+ const cleanAttestation = pendingClean && !cleanErrorCode && !cleanSalvageReason ? pendingClean : undefined;
6107
6228
  if (cleanAttestation) {
6108
6229
  formatFamiliesDetected.add(cleanAttestation.row_format_family);
6109
6230
  }
@@ -6133,6 +6254,10 @@ ${trimmed}`;
6133
6254
  error: cleanErrorMessage ?? "Invalid CLEAN attestation",
6134
6255
  error_code: cleanErrorCode
6135
6256
  } : {},
6257
+ ...cleanSalvageReason ? {
6258
+ clean_attestation_salvaged: true,
6259
+ clean_attestation_salvage_reason: cleanSalvageReason
6260
+ } : {},
6136
6261
  candidates: acceptedCandidates,
6137
6262
  ...cleanAttestation ? { clean_attestation: cleanAttestation } : {},
6138
6263
  invocation_envelope: envelope,
@@ -6142,7 +6267,7 @@ ${trimmed}`;
6142
6267
 
6143
6268
  // src/background/lane-output-store.ts
6144
6269
  init_zod();
6145
- import { createHash as createHash3 } from "crypto";
6270
+ import { createHash as createHash4 } from "crypto";
6146
6271
  import {
6147
6272
  existsSync as existsSync6,
6148
6273
  mkdirSync as mkdirSync3,
@@ -6217,7 +6342,7 @@ function hasValidArtifactIntegrity(artifact, expectedRef) {
6217
6342
  return artifact.ref === expectedRef && artifact.ref === expectedArtifactRef;
6218
6343
  }
6219
6344
  function digestText(text) {
6220
- return createHash3("sha256").update(text).digest("hex");
6345
+ return createHash4("sha256").update(text).digest("hex");
6221
6346
  }
6222
6347
 
6223
6348
  // src/background/pr-review-trigger-contract.ts
@@ -6969,13 +7094,14 @@ var PrReviewValidationBatchRecordSchema = exports_external.object({
6969
7094
  lanes: exports_external.array(exports_external.object({
6970
7095
  laneId: exports_external.string().min(1),
6971
7096
  workflowLane: exports_external.string().min(1),
6972
- reviewItemIds: exports_external.array(exports_external.string().min(1)).min(1).optional()
7097
+ reviewItemIds: exports_external.array(exports_external.string().min(1)).min(1).max(MAX_PR_REVIEW_COLLECTION_RECEIPT_ITEM_IDS).optional()
6973
7098
  }).strict()).min(1),
6974
7099
  validatedAt: exports_external.string().min(1)
6975
7100
  }).strict();
6976
7101
  var PrReviewBatchCoherenceRecordSchema = exports_external.object({
6977
7102
  validatedInventory: exports_external.array(exports_external.string().min(1)),
6978
- reviewerItemBindings: exports_external.record(exports_external.string().min(1), exports_external.string().regex(/^[0-9a-f]{64}$/)).optional()
7103
+ reviewerItemBindings: exports_external.record(exports_external.string().min(1), exports_external.string().regex(/^[0-9a-f]{64}$/)).optional(),
7104
+ reviewerItemBindingKeyEncoding: exports_external.literal("prefixed-v1").optional()
6979
7105
  }).passthrough();
6980
7106
  var PrFeedbackScopeDeclarationRecordSchema = exports_external.object({
6981
7107
  taskId: exports_external.string().regex(/^\d+\.\d+(?:\.\d+)*$/),
@@ -7778,7 +7904,7 @@ async function readPrReviewFeedbackHandoffArtifact(directory, relativePath) {
7778
7904
  }
7779
7905
  return {
7780
7906
  artifact: parsed.data,
7781
- digest: createHash4("sha256").update(raw, "utf8").digest("hex")
7907
+ digest: createHash5("sha256").update(raw, "utf8").digest("hex")
7782
7908
  };
7783
7909
  }
7784
7910
  var PrReviewFindingProjectionSchema = exports_external.object({
@@ -7834,7 +7960,7 @@ function canonicalGitHubPrUrl(value) {
7834
7960
  }
7835
7961
  }
7836
7962
  function workflowIdentity(state) {
7837
- return state.workflowInstanceId ?? `legacy-${createHash4("sha256").update(`${state.sessionID}\x00${state.mode}\x00${state.activatedAt}`).digest("hex").slice(0, 32)}`;
7963
+ return state.workflowInstanceId ?? `legacy-${createHash5("sha256").update(`${state.sessionID}\x00${state.mode}\x00${state.activatedAt}`).digest("hex").slice(0, 32)}`;
7838
7964
  }
7839
7965
  function sameHandoffIds(left, right) {
7840
7966
  const normalizedLeft = [...new Set(left)].sort();
@@ -8067,6 +8193,8 @@ var _test_exports = {
8067
8193
  resolveRemoteRefsContainingHead,
8068
8194
  resolveRemoteRefsContainingHeadAsync,
8069
8195
  parseCriticVerdict,
8196
+ analyzePrReviewVerdictRowContract,
8197
+ parseLaneItemVerdicts,
8070
8198
  composePrReviewPhaseVerdicts: async (directory, sessionID, phase) => {
8071
8199
  const state = await requireBoundState(directory, sessionID, "PR_REVIEW");
8072
8200
  const ctx = await createPrReviewGateContext(directory, state);
@@ -8343,6 +8471,7 @@ function sameStringSet(left, right) {
8343
8471
  const rightSet = new Set(right);
8344
8472
  return leftSet.size === rightSet.size && [...leftSet].every((v) => rightSet.has(v));
8345
8473
  }
8474
+ var PR_REVIEW_CLEAN_SENTINEL_ID = "CLEAN-REVIEW";
8346
8475
  function derivePrReviewCandidateInventory(directory, state, ctx) {
8347
8476
  if (ctx.candidateInventory)
8348
8477
  return ctx.candidateInventory;
@@ -8445,6 +8574,7 @@ function derivePrReviewCandidateInventory(directory, state, ctx) {
8445
8574
  }
8446
8575
  }
8447
8576
  const candidateIds = [];
8577
+ const candidateSeverities = new Map;
8448
8578
  const extractedLaneKeys = new Set;
8449
8579
  for (const source of sources) {
8450
8580
  let resolvedArtifact = false;
@@ -8464,7 +8594,13 @@ function derivePrReviewCandidateInventory(directory, state, ctx) {
8464
8594
  const laneKey = `${source.batchId}\x00${source.laneId}`;
8465
8595
  if (!extractedLaneKeys.has(laneKey)) {
8466
8596
  extractedLaneKeys.add(laneKey);
8467
- candidateIds.push(...extractCandidateIds(artifact.text, resolvePrReviewRowFamily(source.workflowLane, source.mode), source.creditedLanes));
8597
+ const extracted = extractCandidateRows(artifact.text, resolvePrReviewRowFamily(source.workflowLane, source.mode), source.creditedLanes);
8598
+ for (const row of extracted) {
8599
+ candidateIds.push(row.candidateId);
8600
+ if (row.severity && !candidateSeverities.has(row.candidateId)) {
8601
+ candidateSeverities.set(row.candidateId, row.severity);
8602
+ }
8603
+ }
8468
8604
  }
8469
8605
  }
8470
8606
  if (source.mode === "swarm-pr-review:micro" && !resolvedArtifact) {
@@ -8475,7 +8611,8 @@ function derivePrReviewCandidateInventory(directory, state, ctx) {
8475
8611
  }
8476
8612
  }
8477
8613
  assertNoDuplicates(candidateIds, "PR_REVIEW discovery candidate ids");
8478
- ctx.candidateInventory = candidateIds.length > 0 ? candidateIds.sort() : ["CLEAN-REVIEW"];
8614
+ ctx.candidateSeverities = candidateSeverities;
8615
+ ctx.candidateInventory = candidateIds.length > 0 ? candidateIds.sort() : [PR_REVIEW_CLEAN_SENTINEL_ID];
8479
8616
  return ctx.candidateInventory;
8480
8617
  }
8481
8618
  function appendBoundedCandidateIssue(issues, message) {
@@ -8528,15 +8665,19 @@ function parseCanonicalCandidateRows(text, fallbackFamily) {
8528
8665
  rows.push({
8529
8666
  candidateId: analysis.candidateId,
8530
8667
  workflowLane: analysis.workflowLane,
8668
+ severity: isCandidateSeverity(analysis.values.severity) ? analysis.values.severity : null,
8531
8669
  evidence: candidateFields.slice(2).join("\x00"),
8532
8670
  lineNumber: index + 1
8533
8671
  });
8534
8672
  }
8535
8673
  return { rows, issues };
8536
8674
  }
8537
- function extractCandidateIds(text, fallbackFamily, scopeToLanes) {
8675
+ function extractCandidateRows(text, fallbackFamily, scopeToLanes) {
8538
8676
  const inScope = (lane) => !scopeToLanes || lane !== undefined && scopeToLanes.includes(lane);
8539
- return parseCanonicalCandidateRows(text, fallbackFamily).rows.filter((row) => inScope(row.workflowLane)).map((row) => row.candidateId);
8677
+ return parseCanonicalCandidateRows(text, fallbackFamily).rows.filter((row) => inScope(row.workflowLane));
8678
+ }
8679
+ function extractCandidateIds(text, fallbackFamily, scopeToLanes) {
8680
+ return extractCandidateRows(text, fallbackFamily, scopeToLanes).map((row) => row.candidateId);
8540
8681
  }
8541
8682
  var MAX_COMPOSITION_DIAGNOSTICS = 16;
8542
8683
  var MAX_UNCLAIMED_ITEMS_IN_MESSAGE = 50;
@@ -8609,7 +8750,11 @@ function composePrReviewPhaseVerdicts(directory, state, phase, ctx, exhaustive =
8609
8750
  if (!artifact)
8610
8751
  continue;
8611
8752
  const declaredItems = qualified.expectedLane.reviewItemIds ?? [];
8612
- const parsed = parseLaneItemVerdicts(artifact.text, declaredItems, phase, reviewerClaims);
8753
+ const { markerRows, parsed } = parsePrReviewVerdictRows(artifact.text, declaredItems, phase, reviewerClaims);
8754
+ if (!verdictRowsContainOnlyAssignedIds(markerRows, declaredItems)) {
8755
+ appendCompositionDiagnostic(diagnostics, `${phase} lane "${qualified.expectedLane.laneId}" contains an unassigned verdict row; it contributes no claims`);
8756
+ continue;
8757
+ }
8613
8758
  if (declaredItems.length > 0 && parsed.size === declaredItems.length) {
8614
8759
  satisfiedObligations.add(qualified.expectedWorkflowLane);
8615
8760
  }
@@ -8657,10 +8802,16 @@ function composePrReviewPhaseVerdicts(directory, state, phase, ctx, exhaustive =
8657
8802
  return composition;
8658
8803
  }
8659
8804
  function criticClaimIsBoundToCurrentReviewerRow(coherence, itemId, reviewerClaims) {
8660
- const bound = coherence.reviewerItemBindings?.[itemId];
8805
+ const bindings = coherence.reviewerItemBindings;
8806
+ const bindingKey = coherence.reviewerItemBindingKeyEncoding === "prefixed-v1" ? reviewerItemBindingKey(itemId) : itemId;
8807
+ const bound = bindings && Object.hasOwn(bindings, bindingKey) ? bindings[bindingKey] : undefined;
8661
8808
  const current = reviewerClaims?.get(itemId)?.rowDigest;
8662
8809
  return Boolean(bound && current && bound === current);
8663
8810
  }
8811
+ var REVIEWER_ITEM_BINDING_KEY_PREFIX = "item:";
8812
+ function reviewerItemBindingKey(itemId) {
8813
+ return `${REVIEWER_ITEM_BINDING_KEY_PREFIX}${itemId}`;
8814
+ }
8664
8815
  function authoritativeReviewerClaims(directory, state, ctx) {
8665
8816
  const composed = composePrReviewPhaseVerdicts(directory, state, "reviewer", ctx);
8666
8817
  return composed.unclaimed.length === 0 ? composed.claims : new Map;
@@ -8986,8 +9137,7 @@ function workflowArtifactHasContractMarker(directory, state, record, expectedMod
8986
9137
  return false;
8987
9138
  if (expectedMode === "swarm-pr-review:reviewer" || expectedMode === "swarm-pr-review:critic") {
8988
9139
  const phase = expectedMode === "swarm-pr-review:reviewer" ? "reviewer" : "critic";
8989
- const parsed = parseLaneItemVerdicts(artifact.text, reviewItemIds ?? [], phase, reviewerClaims);
8990
- return Boolean(reviewItemIds?.length && reviewItemIds.every((itemId) => parsed.has(itemId)));
9140
+ return analyzePrReviewVerdictRowContract(artifact.text, reviewItemIds ?? [], phase, reviewerClaims).ok;
8991
9141
  }
8992
9142
  if (expectedMode === "swarm-pr-feedback:verification") {
8993
9143
  return /^\[FEEDBACK-VERIFIED\]\s*\|/m.test(artifact.text);
@@ -9061,7 +9211,8 @@ function analyzePrReviewDiscoveryArtifact(text, expectedWorkflowLane, ownedWorkf
9061
9211
  const normalized = normalizeCandidateArtifact(text, fallbackFamily);
9062
9212
  const canonicalText = normalized.text;
9063
9213
  const repairKinds = normalized.repairKinds;
9064
- const salvaged = repairKinds.length > 0;
9214
+ let salvaged = repairKinds.length > 0;
9215
+ let cleanAttestationSalvaged = false;
9065
9216
  const header = selectCandidateHeader(canonicalText.split(/\r?\n/));
9066
9217
  if (header === null || !header.markerBearing || header.family !== fallbackFamily) {
9067
9218
  appendBoundedCandidateIssue(issues, `field header: expected one exact canonical ${fallbackFamily} [CANDIDATE] header before discovery rows`);
@@ -9072,6 +9223,7 @@ function analyzePrReviewDiscoveryArtifact(text, expectedWorkflowLane, ownedWorkf
9072
9223
  coverageKind: null,
9073
9224
  salvaged,
9074
9225
  repairKinds,
9226
+ cleanAttestationSalvaged,
9075
9227
  failurePredicate: "discovery.header"
9076
9228
  };
9077
9229
  }
@@ -9103,10 +9255,15 @@ function analyzePrReviewDiscoveryArtifact(text, expectedWorkflowLane, ownedWorkf
9103
9255
  });
9104
9256
  if (parsed.error)
9105
9257
  appendBoundedCandidateIssue(issues, parsed.error);
9258
+ if (parsed.clean_attestation_salvaged) {
9259
+ cleanAttestationSalvaged = true;
9260
+ salvaged = true;
9261
+ appendBoundedCandidateIssue(issues, parsed.clean_attestation_salvage_reason ?? "CLEAN attestation discredited; candidate rows retained");
9262
+ }
9106
9263
  for (const detail of parsed.diagnostics.parse_error_details) {
9107
9264
  appendBoundedCandidateIssue(issues, `row ${detail.row_index + 1} field ${detail.field}: ${detail.message}`);
9108
9265
  }
9109
- const hasParseFailure = Boolean(parsed.error) || parsed.diagnostics.parse_error_details.length > 0;
9266
+ const hasParseFailure = Boolean(parsed.error) || Boolean(parsed.clean_attestation_salvaged) || parsed.diagnostics.parse_error_details.length > 0;
9110
9267
  const extractedCandidateIds = parseCanonicalCandidateRows(canonicalText, fallbackFamily).rows.map((row) => row.candidateId);
9111
9268
  const hasDuplicateCandidateId = new Set(extractedCandidateIds).size !== extractedCandidateIds.length;
9112
9269
  if (hasDuplicateCandidateId) {
@@ -9117,6 +9274,7 @@ function analyzePrReviewDiscoveryArtifact(text, expectedWorkflowLane, ownedWorkf
9117
9274
  coverageKind: null,
9118
9275
  salvaged,
9119
9276
  repairKinds,
9277
+ cleanAttestationSalvaged,
9120
9278
  failurePredicate: "discovery.row"
9121
9279
  };
9122
9280
  }
@@ -9136,7 +9294,8 @@ function analyzePrReviewDiscoveryArtifact(text, expectedWorkflowLane, ownedWorkf
9136
9294
  issues,
9137
9295
  coverageKind: "candidate",
9138
9296
  salvaged,
9139
- repairKinds
9297
+ repairKinds,
9298
+ cleanAttestationSalvaged
9140
9299
  };
9141
9300
  }
9142
9301
  const clean = parsed.clean_attestation;
@@ -9147,7 +9306,8 @@ function analyzePrReviewDiscoveryArtifact(text, expectedWorkflowLane, ownedWorkf
9147
9306
  issues,
9148
9307
  coverageKind: "clean",
9149
9308
  salvaged,
9150
- repairKinds
9309
+ repairKinds,
9310
+ cleanAttestationSalvaged
9151
9311
  };
9152
9312
  }
9153
9313
  return {
@@ -9157,6 +9317,7 @@ function analyzePrReviewDiscoveryArtifact(text, expectedWorkflowLane, ownedWorkf
9157
9317
  coverageKind: null,
9158
9318
  salvaged,
9159
9319
  repairKinds,
9320
+ cleanAttestationSalvaged,
9160
9321
  failurePredicate: hasParseFailure ? "discovery.row" : "discovery.coverage"
9161
9322
  };
9162
9323
  }
@@ -9235,6 +9396,13 @@ function validatePrReviewDiscoveryLaneCompletion(input) {
9235
9396
  reason: `structural repairs applied: ${analysis.repairKinds.join(", ")}`
9236
9397
  });
9237
9398
  }
9399
+ if (analysis.cleanAttestationSalvaged) {
9400
+ laneRecoveries.push({
9401
+ workflowLane,
9402
+ kind: "clean-attestation-salvaged",
9403
+ reason: "a conflicting [CLEAN] attestation was discredited while the independently validated candidate rows were retained"
9404
+ });
9405
+ }
9238
9406
  if (analysis.issues.length > 0) {
9239
9407
  laneRecoveries.push({
9240
9408
  workflowLane,
@@ -9290,6 +9458,14 @@ var REVIEW_SEVERITIES = new Set([
9290
9458
  "INFO",
9291
9459
  "NONE"
9292
9460
  ]);
9461
+ var REVIEW_SEVERITY_RANK = new Map([
9462
+ ["NONE", 0],
9463
+ ["INFO", 1],
9464
+ ["LOW", 2],
9465
+ ["MEDIUM", 3],
9466
+ ["HIGH", 4],
9467
+ ["CRITICAL", 5]
9468
+ ]);
9293
9469
  var CRITIC_STATUSES = new Set([
9294
9470
  "UPHELD",
9295
9471
  "DOWNGRADED",
@@ -9310,28 +9486,49 @@ var FEEDBACK_NO_CHANGE_CLASSIFICATIONS = new Set([
9310
9486
  "NEEDS_MORE_EVIDENCE",
9311
9487
  "NEEDS_USER_DECISION"
9312
9488
  ]);
9313
- function parseReviewerVerdictFields(text, itemId) {
9314
- const rows = text.split(/\r?\n/).map((line) => pipeFieldsCapped(line, 10)).filter((fields2) => fields2[0] === "[REVIEWED]" && fields2[1] === itemId);
9315
- if (rows.length !== 1)
9316
- return null;
9317
- const fields = rows[0];
9489
+ function indexVerdictRows(text, marker, fieldCount) {
9490
+ const markerRows = [];
9491
+ const rowsByItemId = new Map;
9492
+ for (const line of text.split(/\r?\n/)) {
9493
+ const fields = pipeFieldsCapped(line, fieldCount);
9494
+ if (fields[0] !== marker)
9495
+ continue;
9496
+ markerRows.push(fields);
9497
+ const itemId = fields[1] ?? "";
9498
+ const rows = rowsByItemId.get(itemId);
9499
+ if (rows)
9500
+ rows.push(fields);
9501
+ else
9502
+ rowsByItemId.set(itemId, [fields]);
9503
+ }
9504
+ return { markerRows, rowsByItemId };
9505
+ }
9506
+ function validateReviewerVerdictFields(fields) {
9318
9507
  if (fields.length !== 10 || !fields.slice(1).every(Boolean))
9319
9508
  return null;
9320
9509
  const introduced = fields[5].replace(/^introduced_by_pr\s*:\s*/i, "").toUpperCase();
9321
9510
  if (!REVIEWER_CLASSIFICATIONS.has(fields[2]) || !REVIEWER_EVIDENCE_TYPES.has(fields[3]) || !REVIEW_SEVERITIES.has(fields[4]) || !["YES", "NO", "UNKNOWN"].includes(introduced))
9322
9511
  return null;
9512
+ if (fields[2] === "DISPROVED" && fields[4] !== "NONE")
9513
+ return null;
9323
9514
  if (fields[7].length < 8 || fields[8].length < 5 || fields[9].length < 3)
9324
9515
  return null;
9325
9516
  return fields;
9326
9517
  }
9327
9518
  function reviewerVerdictRowDigest(fields) {
9328
- return createHash4("sha256").update(fields.join("\x00")).digest("hex");
9519
+ return createHash5("sha256").update(fields.join("\x00")).digest("hex");
9329
9520
  }
9330
9521
  function parseLaneItemVerdicts(text, itemIds, phase, reviewerClaims) {
9522
+ return parsePrReviewVerdictRows(text, itemIds, phase, reviewerClaims).parsed;
9523
+ }
9524
+ function parsePrReviewVerdictRows(text, itemIds, phase, reviewerClaims) {
9331
9525
  const parsed = new Map;
9526
+ const marker = phase === "reviewer" ? "[REVIEWED]" : "[CRITIC]";
9527
+ const { markerRows, rowsByItemId } = indexVerdictRows(text, marker, phase === "reviewer" ? 10 : 6);
9332
9528
  for (const itemId of itemIds) {
9333
9529
  if (phase === "reviewer") {
9334
- const fields = parseReviewerVerdictFields(text, itemId);
9530
+ const rows2 = rowsByItemId.get(itemId);
9531
+ const fields = rows2?.length === 1 ? validateReviewerVerdictFields(rows2[0]) : null;
9335
9532
  if (!fields)
9336
9533
  continue;
9337
9534
  parsed.set(itemId, {
@@ -9341,7 +9538,8 @@ function parseLaneItemVerdicts(text, itemIds, phase, reviewerClaims) {
9341
9538
  });
9342
9539
  continue;
9343
9540
  }
9344
- const verdict = parseCriticVerdict(text, itemId, reviewerClaims?.get(itemId)?.severity);
9541
+ const rows = rowsByItemId.get(itemId);
9542
+ const verdict = rows?.length === 1 ? validateCriticVerdictFields(rows[0], reviewerClaims?.get(itemId)?.severity) : null;
9345
9543
  if (!verdict)
9346
9544
  continue;
9347
9545
  parsed.set(itemId, {
@@ -9349,13 +9547,56 @@ function parseLaneItemVerdicts(text, itemIds, phase, reviewerClaims) {
9349
9547
  severity: verdict.severity
9350
9548
  });
9351
9549
  }
9352
- return parsed;
9550
+ return { markerRows, parsed };
9551
+ }
9552
+ function analyzePrReviewVerdictRowContract(text, itemIds, phase, reviewerClaims) {
9553
+ const marker = phase === "reviewer" ? "[REVIEWED]" : "[CRITIC]";
9554
+ const assigned = new Set(itemIds);
9555
+ const { markerRows, parsed } = parsePrReviewVerdictRows(text, itemIds, phase, reviewerClaims);
9556
+ const observedIds = markerRows.map((fields) => fields[1] || "(missing)");
9557
+ const unexpectedIds = [
9558
+ ...new Set(observedIds.filter((itemId) => !assigned.has(itemId)))
9559
+ ];
9560
+ const invalidOrMissingIds = itemIds.filter((itemId) => !parsed.has(itemId));
9561
+ return {
9562
+ ok: verdictRowIdsMatchExactly(markerRows, itemIds) && invalidOrMissingIds.length === 0,
9563
+ expected: `exactly one parseable ${marker} row for assigned IDs ${JSON.stringify(itemIds)} and no other ${marker} IDs`,
9564
+ actual: JSON.stringify({
9565
+ rowCount: markerRows.length,
9566
+ observedIds,
9567
+ invalidOrMissingIds,
9568
+ unexpectedIds
9569
+ })
9570
+ };
9571
+ }
9572
+ function verdictRowIdsMatchExactly(markerRows, itemIds) {
9573
+ if (itemIds.length === 0 || markerRows.length !== itemIds.length)
9574
+ return false;
9575
+ const assigned = new Set(itemIds);
9576
+ if (assigned.size !== itemIds.length)
9577
+ return false;
9578
+ const observed = new Set;
9579
+ for (const fields of markerRows) {
9580
+ const itemId = fields[1] ?? "";
9581
+ if (!assigned.has(itemId) || observed.has(itemId))
9582
+ return false;
9583
+ observed.add(itemId);
9584
+ }
9585
+ return observed.size === assigned.size;
9586
+ }
9587
+ function verdictRowsContainOnlyAssignedIds(markerRows, itemIds) {
9588
+ if (itemIds.length === 0)
9589
+ return false;
9590
+ const assigned = new Set(itemIds);
9591
+ return markerRows.every((fields) => assigned.has(fields[1] ?? ""));
9353
9592
  }
9354
9593
  function parseCriticVerdict(text, itemId, reviewerSeverity) {
9355
- const rows = text.split(/\r?\n/).map((line) => pipeFieldsCapped(line, 6)).filter((fields2) => fields2[0] === "[CRITIC]" && fields2[1] === itemId);
9356
- if (rows.length !== 1)
9594
+ const rows = indexVerdictRows(text, "[CRITIC]", 6).rowsByItemId.get(itemId);
9595
+ if (!rows || rows.length !== 1)
9357
9596
  return null;
9358
- const fields = rows[0];
9597
+ return validateCriticVerdictFields(rows[0], reviewerSeverity);
9598
+ }
9599
+ function validateCriticVerdictFields(fields, reviewerSeverity) {
9359
9600
  if (fields.length !== 6 || !fields.slice(1).every(Boolean) || !CRITIC_STATUSES.has(fields[2]) || !REVIEW_SEVERITIES.has(fields[3]))
9360
9601
  return null;
9361
9602
  if (fields[2] === "NEEDS_MORE_EVIDENCE")
@@ -9367,16 +9608,8 @@ function parseCriticVerdict(text, itemId, reviewerSeverity) {
9367
9608
  if (fields[2] === "DOWNGRADED" && fields[3] === "CRITICAL")
9368
9609
  return null;
9369
9610
  if (reviewerSeverity) {
9370
- const severityRank = new Map([
9371
- ["NONE", 0],
9372
- ["INFO", 1],
9373
- ["LOW", 2],
9374
- ["MEDIUM", 3],
9375
- ["HIGH", 4],
9376
- ["CRITICAL", 5]
9377
- ]);
9378
- const reviewerRank = severityRank.get(reviewerSeverity);
9379
- const criticRank = severityRank.get(fields[3]);
9611
+ const reviewerRank = REVIEW_SEVERITY_RANK.get(reviewerSeverity);
9612
+ const criticRank = REVIEW_SEVERITY_RANK.get(fields[3]);
9380
9613
  if (reviewerRank === undefined || criticRank === undefined)
9381
9614
  return null;
9382
9615
  if (fields[2] === "UPHELD" && criticRank !== reviewerRank)
@@ -9931,7 +10164,7 @@ function workflowGateStateRelativePath(sessionID) {
9931
10164
  function prWorkflowSessionFileStem(sessionID) {
9932
10165
  const normalized = normalizeSessionID(sessionID);
9933
10166
  const slug = normalized.replace(/[^A-Za-z0-9_.-]/g, "_").slice(0, 80) || "session";
9934
- const digest = createHash4("sha256").update(normalized).digest("hex").slice(0, 12);
10167
+ const digest = createHash5("sha256").update(normalized).digest("hex").slice(0, 12);
9935
10168
  return `${slug}-${digest}`;
9936
10169
  }
9937
10170
  function normalizeSessionID(sessionID) {
@@ -10153,7 +10386,7 @@ ${USAGE}`;
10153
10386
  }
10154
10387
 
10155
10388
  // src/services/spec-drift-recovery.ts
10156
- import { createHash as createHash5 } from "crypto";
10389
+ import { createHash as createHash6 } from "crypto";
10157
10390
  import { appendFile as appendFile5, mkdir as mkdir5, readFile as readFile6, unlink as unlink2 } from "fs/promises";
10158
10391
  import { dirname as dirname9 } from "path";
10159
10392
  var SPEC_DRIFT_RECOVERY_AGENT = "spec-drift-recovery";
@@ -10182,7 +10415,7 @@ function now() {
10182
10415
  return new Date().toISOString();
10183
10416
  }
10184
10417
  function sha2562(text) {
10185
- return createHash5("sha256").update(text, "utf-8").digest("hex");
10418
+ return createHash6("sha256").update(text, "utf-8").digest("hex");
10186
10419
  }
10187
10420
  function parseMarker(raw) {
10188
10421
  try {
@@ -13490,8 +13723,8 @@ async function handleClarifyCommand(_directory, args) {
13490
13723
 
13491
13724
  // src/commands/close.ts
13492
13725
  import * as fsSync2 from "fs";
13493
- import { promises as fs15 } from "fs";
13494
- import path44 from "path";
13726
+ import { promises as fs16 } from "fs";
13727
+ import path45 from "path";
13495
13728
  init_schema();
13496
13729
 
13497
13730
  // src/full-auto/state.ts
@@ -15598,7 +15831,7 @@ function planMerges(active, threshold, maxComparisons, maxMerges) {
15598
15831
  };
15599
15832
  }
15600
15833
  async function sweepActiveNearDuplicates(directory, options = {}) {
15601
- const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-4vwn66wk.js");
15834
+ const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-5cbbtbvf.js");
15602
15835
  const { config } = loadPluginConfigWithMeta2(directory);
15603
15836
  const sweepConfig = config.learning?.dedup_sweep;
15604
15837
  if (sweepConfig?.enabled === false)
@@ -16682,7 +16915,7 @@ async function runCuratorPhase(directory, phase, agentsDispatched, config, knowl
16682
16915
  }
16683
16916
  if (config.skill_generation_enabled === true && skillCandidates.length > 0) {
16684
16917
  try {
16685
- const skillModule = await import("./skill-generator-fwvmcv8m.js");
16918
+ const skillModule = await import("./skill-generator-980zjk9q.js");
16686
16919
  for (const cand of skillCandidates) {
16687
16920
  if (cand.confidence < (config.min_skill_confidence ?? DEFAULT_SKILL_MIN_CONFIDENCE)) {
16688
16921
  continue;
@@ -17142,7 +17375,7 @@ async function applyCuratorKnowledgeUpdates(directory, recommendations, knowledg
17142
17375
  } catch {}
17143
17376
  }
17144
17377
  if (contradictedEntries.length > 0 && knowledgeConfig.contradiction_threshold_action === "quarantine") {
17145
- const { maybeQuarantineOnContradiction } = await import("./knowledge-escalator-mn4sx4qd.js");
17378
+ const { maybeQuarantineOnContradiction } = await import("./knowledge-escalator-jbazxmk5.js");
17146
17379
  for (const { id } of contradictedEntries) {
17147
17380
  try {
17148
17381
  await maybeQuarantineOnContradiction(directory, id, knowledgeConfig.contradiction_quarantine_threshold, knowledgeConfig.contradiction_quarantine_window_days);
@@ -17961,7 +18194,7 @@ async function runCuratorPostMortem(directory, options = {}) {
17961
18194
  warnings.push("Failed to collect knowledge summary.");
17962
18195
  }
17963
18196
  try {
17964
- const { getScanStatus } = await import("./scan-cursor-p7t5mb4x.js");
18197
+ const { getScanStatus } = await import("./scan-cursor-snx85enn.js");
17965
18198
  const scanStatus = await getScanStatus(directory);
17966
18199
  if (scanStatus.remaining_estimate > 0) {
17967
18200
  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.`);
@@ -18133,9 +18366,9 @@ var _internals24 = {
18133
18366
  verifyPostMortemKnowledgeActions,
18134
18367
  repairPostMortemActions,
18135
18368
  loadDefaultKnowledgeConfig: async (directory) => {
18136
- const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-t8bmshhj.js");
18369
+ const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-6rmxzg6g.js");
18137
18370
  try {
18138
- const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-4vwn66wk.js");
18371
+ const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-5cbbtbvf.js");
18139
18372
  const loaded = loadPluginConfigWithMeta2(directory);
18140
18373
  return KnowledgeConfigSchema2.parse(loaded.config.knowledge ?? {});
18141
18374
  } catch {
@@ -18143,11 +18376,11 @@ var _internals24 = {
18143
18376
  }
18144
18377
  },
18145
18378
  applyCuratorKnowledgeUpdates: async (directory, recommendations, knowledgeConfig, generation) => {
18146
- const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-cvy1s7wd.js");
18379
+ const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-w52frg17.js");
18147
18380
  return applyCuratorKnowledgeUpdates2(directory, recommendations, knowledgeConfig, generation);
18148
18381
  },
18149
18382
  checkHivePromotions: async (entries, knowledgeConfig, directory) => {
18150
- const { checkHivePromotions } = await import("./hive-promoter-3tex870c.js");
18383
+ const { checkHivePromotions } = await import("./hive-promoter-pbm9kee1.js");
18151
18384
  return checkHivePromotions(entries, knowledgeConfig, directory);
18152
18385
  },
18153
18386
  applyProposalTriage: async (directory, triage) => {
@@ -18156,7 +18389,7 @@ var _internals24 = {
18156
18389
  activateProposal,
18157
18390
  listSkills: listSkills2,
18158
18391
  sanitizeSlug
18159
- } = await import("./skill-generator-fwvmcv8m.js");
18392
+ } = await import("./skill-generator-980zjk9q.js");
18160
18393
  const result = {
18161
18394
  approved: [],
18162
18395
  rejected: [],
@@ -18246,7 +18479,7 @@ function extractCurrentPhaseFromPlan(plan) {
18246
18479
 
18247
18480
  // src/hooks/hive-promoter.ts
18248
18481
  init_schema();
18249
- import { createHash as createHash6 } from "crypto";
18482
+ import { createHash as createHash7 } from "crypto";
18250
18483
  import path25 from "path";
18251
18484
 
18252
18485
  // src/hooks/hive-policy.ts
@@ -18662,7 +18895,7 @@ function buildLineage(args) {
18662
18895
  return lineage;
18663
18896
  }
18664
18897
  function lessonRevision(lesson) {
18665
- return createHash6("sha256").update(lesson).digest("hex").slice(0, 12);
18898
+ return createHash7("sha256").update(lesson).digest("hex").slice(0, 12);
18666
18899
  }
18667
18900
  async function checkHivePromotions(swarmEntries, config, directory) {
18668
18901
  const empty = {
@@ -19251,7 +19484,7 @@ async function promoteFromSwarm(directory, lessonId, options, config) {
19251
19484
  }
19252
19485
 
19253
19486
  // src/hooks/knowledge-curator.ts
19254
- import { createHash as createHash7 } from "crypto";
19487
+ import { createHash as createHash8 } from "crypto";
19255
19488
  import { existsSync as existsSync14 } from "fs";
19256
19489
  import {
19257
19490
  appendFile as appendFile7,
@@ -19489,12 +19722,12 @@ function recordSeenRetroSection(key, value, timestamp) {
19489
19722
  capSeenRetroSections();
19490
19723
  }
19491
19724
  function hashContent(content) {
19492
- return createHash7("sha1").update(content).digest("hex");
19725
+ return createHash8("sha1").update(content).digest("hex");
19493
19726
  }
19494
19727
  async function loadConfigForPolicyCurator(directory) {
19495
- const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-t8bmshhj.js");
19728
+ const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-6rmxzg6g.js");
19496
19729
  try {
19497
- const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-4vwn66wk.js");
19730
+ const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-5cbbtbvf.js");
19498
19731
  const { config: loadedConfig } = loadPluginConfigWithMeta2(directory);
19499
19732
  return KnowledgeConfigSchema2.parse(loadedConfig.knowledge ?? {});
19500
19733
  } catch {
@@ -20512,6 +20745,599 @@ var _internals28 = {
20512
20745
  realpath: realpath3
20513
20746
  };
20514
20747
 
20748
+ // src/context-map/telemetry.ts
20749
+ import * as fs13 from "fs";
20750
+ import * as path28 from "path";
20751
+ init_logger();
20752
+ var CONTEXT_TELEMETRY_LIMITS = {
20753
+ activeMaxBytes: 256 * 1024,
20754
+ activeMaxEntries: 1e4,
20755
+ ageMaxMs: 30 * 24 * 60 * 60 * 1000,
20756
+ compactMaxBytes: 64 * 1024,
20757
+ readMaxBytes: 280 * 1024,
20758
+ checkInterval: 50,
20759
+ warnCooldownMs: 60000,
20760
+ headerMaxBytes: 8 * 1024
20761
+ };
20762
+ function isValidTelemetryEntry(value) {
20763
+ if (typeof value !== "object" || value === null) {
20764
+ return false;
20765
+ }
20766
+ const obj = value;
20767
+ const nonNegFinite = (v) => typeof v === "number" && Number.isFinite(v) && v >= 0;
20768
+ return typeof obj.timestamp === "string" && typeof obj.task_id === "string" && typeof obj.agent_role === "string" && typeof obj.delegation_reason === "string" && nonNegFinite(obj.token_estimate) && nonNegFinite(obj.cache_hits) && nonNegFinite(obj.cache_misses) && nonNegFinite(obj.stale_entries) && nonNegFinite(obj.recommended_reads) && nonNegFinite(obj.skipped_reads) && typeof obj.success === "boolean";
20769
+ }
20770
+ var _internals29 = {
20771
+ appendFileSync: fs13.appendFileSync,
20772
+ readFileSync: fs13.readFileSync,
20773
+ existsSync: fs13.existsSync,
20774
+ mkdirSync: fs13.mkdirSync,
20775
+ statSync: fs13.statSync,
20776
+ renameSync: fs13.renameSync,
20777
+ writeFileSync: fs13.writeFileSync,
20778
+ unlinkSync: fs13.unlinkSync,
20779
+ openSync: fs13.openSync,
20780
+ closeSync: fs13.closeSync,
20781
+ readSync: fs13.readSync,
20782
+ limits: CONTEXT_TELEMETRY_LIMITS,
20783
+ emitHealth: emitContextTelemetryHealth,
20784
+ withStoreLock
20785
+ };
20786
+ function telemetryFilePath(directory) {
20787
+ return path28.join(directory, ".swarm", "context-telemetry.jsonl");
20788
+ }
20789
+ function lockFilePath(directory) {
20790
+ return path28.join(directory, ".swarm", "context-telemetry.lock");
20791
+ }
20792
+ function tmpFilePath(directory) {
20793
+ return path28.join(directory, ".swarm", `.context-telemetry.jsonl.${process.pid}.tmp`);
20794
+ }
20795
+ var MANIFEST_TYPE = "ctx-telemetry-manifest";
20796
+ var MANIFEST_SCHEMA = 2;
20797
+ function emptyFolded() {
20798
+ return {
20799
+ delegations: 0,
20800
+ successCount: 0,
20801
+ cacheHits: 0,
20802
+ cacheMisses: 0,
20803
+ staleEntries: 0,
20804
+ tokenSum: 0,
20805
+ recommendedReads: 0,
20806
+ skippedReads: 0,
20807
+ corrupt: 0,
20808
+ dropped: 0,
20809
+ oldestTimestamp: null,
20810
+ newestTimestamp: null
20811
+ };
20812
+ }
20813
+ function emptyManifest() {
20814
+ return {
20815
+ v: 2,
20816
+ type: MANIFEST_TYPE,
20817
+ schemaVersion: MANIFEST_SCHEMA,
20818
+ folded: emptyFolded(),
20819
+ updatedAt: new Date().toISOString()
20820
+ };
20821
+ }
20822
+ function parseManifestLine(line) {
20823
+ const trimmed = line.trim();
20824
+ if (!trimmed)
20825
+ return null;
20826
+ try {
20827
+ const obj = JSON.parse(trimmed);
20828
+ if (typeof obj !== "object" || obj === null)
20829
+ return null;
20830
+ const rec = obj;
20831
+ if (rec.type !== MANIFEST_TYPE || rec.v !== 2 || rec.schemaVersion !== MANIFEST_SCHEMA || typeof rec.folded !== "object" || rec.folded === null) {
20832
+ return null;
20833
+ }
20834
+ const f = rec.folded;
20835
+ const manifest = emptyManifest();
20836
+ const num = (v) => typeof v === "number" && Number.isFinite(v) && v >= 0 ? v : 0;
20837
+ manifest.folded.delegations = num(f.delegations);
20838
+ manifest.folded.successCount = num(f.successCount);
20839
+ manifest.folded.cacheHits = num(f.cacheHits);
20840
+ manifest.folded.cacheMisses = num(f.cacheMisses);
20841
+ manifest.folded.staleEntries = num(f.staleEntries);
20842
+ manifest.folded.tokenSum = num(f.tokenSum);
20843
+ manifest.folded.recommendedReads = num(f.recommendedReads);
20844
+ manifest.folded.skippedReads = num(f.skippedReads);
20845
+ manifest.folded.corrupt = num(f.corrupt);
20846
+ manifest.folded.dropped = num(f.dropped);
20847
+ if (typeof f.oldestTimestamp === "string") {
20848
+ manifest.folded.oldestTimestamp = f.oldestTimestamp;
20849
+ }
20850
+ if (typeof f.newestTimestamp === "string") {
20851
+ manifest.folded.newestTimestamp = f.newestTimestamp;
20852
+ }
20853
+ manifest.updatedAt = typeof rec.updatedAt === "string" ? rec.updatedAt : new Date().toISOString();
20854
+ return manifest;
20855
+ } catch {
20856
+ return null;
20857
+ }
20858
+ }
20859
+ function readBoundedChunk(filePath, maxBytes) {
20860
+ try {
20861
+ if (!_internals29.existsSync(filePath)) {
20862
+ return { text: "", truncated: false };
20863
+ }
20864
+ const fd = _internals29.openSync(filePath, "r");
20865
+ try {
20866
+ const size = _internals29.statSync(filePath).size;
20867
+ const truncated = size > maxBytes;
20868
+ const len = Math.min(size, maxBytes);
20869
+ const buf = Buffer.alloc(len);
20870
+ let read = 0;
20871
+ while (read < len) {
20872
+ const n = _internals29.readSync(fd, buf, read, len - read, read);
20873
+ if (n <= 0)
20874
+ break;
20875
+ read += n;
20876
+ }
20877
+ return { text: buf.toString("utf-8", 0, read), truncated };
20878
+ } finally {
20879
+ _internals29.closeSync(fd);
20880
+ }
20881
+ } catch {
20882
+ warnThrottled("bounded read failed (transient I/O)");
20883
+ return { text: "", truncated: false };
20884
+ }
20885
+ }
20886
+ function fileSizeOrZero(filePath) {
20887
+ try {
20888
+ if (!_internals29.existsSync(filePath))
20889
+ return 0;
20890
+ return _internals29.statSync(filePath).size;
20891
+ } catch {
20892
+ return 0;
20893
+ }
20894
+ }
20895
+ function foldEntryInto(agg, entry) {
20896
+ agg.delegations += 1;
20897
+ if (entry.success)
20898
+ agg.successCount += 1;
20899
+ agg.cacheHits += entry.cache_hits;
20900
+ agg.cacheMisses += entry.cache_misses;
20901
+ agg.staleEntries += entry.stale_entries;
20902
+ agg.tokenSum += entry.token_estimate;
20903
+ agg.recommendedReads += entry.recommended_reads;
20904
+ agg.skippedReads += entry.skipped_reads;
20905
+ if (agg.oldestTimestamp === null || entry.timestamp < agg.oldestTimestamp) {
20906
+ agg.oldestTimestamp = entry.timestamp;
20907
+ }
20908
+ if (agg.newestTimestamp === null || entry.timestamp > agg.newestTimestamp) {
20909
+ agg.newestTimestamp = entry.timestamp;
20910
+ }
20911
+ }
20912
+ function cloneFolded(agg) {
20913
+ return {
20914
+ delegations: agg.delegations,
20915
+ successCount: agg.successCount,
20916
+ cacheHits: agg.cacheHits,
20917
+ cacheMisses: agg.cacheMisses,
20918
+ staleEntries: agg.staleEntries,
20919
+ tokenSum: agg.tokenSum,
20920
+ recommendedReads: agg.recommendedReads,
20921
+ skippedReads: agg.skippedReads,
20922
+ corrupt: agg.corrupt,
20923
+ dropped: agg.dropped,
20924
+ oldestTimestamp: agg.oldestTimestamp,
20925
+ newestTimestamp: agg.newestTimestamp
20926
+ };
20927
+ }
20928
+ function atomicReplace(directory, content) {
20929
+ const finalPath = telemetryFilePath(directory);
20930
+ const tmpPath = tmpFilePath(directory);
20931
+ try {
20932
+ if (_internals29.existsSync(tmpPath)) {
20933
+ try {
20934
+ _internals29.unlinkSync(tmpPath);
20935
+ } catch {}
20936
+ }
20937
+ _internals29.writeFileSync(tmpPath, content, "utf-8");
20938
+ _internals29.renameSync(tmpPath, finalPath);
20939
+ } catch {
20940
+ try {
20941
+ if (_internals29.existsSync(tmpPath)) {
20942
+ _internals29.unlinkSync(tmpPath);
20943
+ }
20944
+ } catch {}
20945
+ throw new Error("context-telemetry atomic replace failed");
20946
+ }
20947
+ }
20948
+ function withStoreLock(directory, fn) {
20949
+ const lockPath = lockFilePath(directory);
20950
+ let acquired = false;
20951
+ try {
20952
+ _internals29.mkdirSync(path28.dirname(lockPath), { recursive: true });
20953
+ const fd = _internals29.openSync(lockPath, "wx");
20954
+ _internals29.closeSync(fd);
20955
+ acquired = true;
20956
+ } catch {
20957
+ try {
20958
+ const age = Date.now() - _internals29.statSync(lockPath).mtimeMs;
20959
+ if (age > 5 * 60000) {
20960
+ try {
20961
+ _internals29.unlinkSync(lockPath);
20962
+ } catch {}
20963
+ try {
20964
+ const fd = _internals29.openSync(lockPath, "wx");
20965
+ _internals29.closeSync(fd);
20966
+ acquired = true;
20967
+ } catch {
20968
+ acquired = false;
20969
+ }
20970
+ }
20971
+ } catch {
20972
+ acquired = false;
20973
+ }
20974
+ }
20975
+ if (!acquired)
20976
+ return null;
20977
+ try {
20978
+ return fn();
20979
+ } finally {
20980
+ try {
20981
+ _internals29.unlinkSync(lockPath);
20982
+ } catch {}
20983
+ }
20984
+ }
20985
+ var _lastWarnAt = 0;
20986
+ function warnThrottled(message) {
20987
+ const now2 = Date.now();
20988
+ if (now2 - _lastWarnAt < _internals29.limits.warnCooldownMs)
20989
+ return;
20990
+ _lastWarnAt = now2;
20991
+ warn(`context-telemetry: ${message}`);
20992
+ }
20993
+ function readStore(directory, bounded) {
20994
+ const filePath = telemetryFilePath(directory);
20995
+ if (!_internals29.existsSync(filePath)) {
20996
+ return { manifest: null, records: [], corruptLines: 0, truncated: false };
20997
+ }
20998
+ let text;
20999
+ let truncated = false;
21000
+ if (bounded) {
21001
+ const chunk = readBoundedChunk(filePath, _internals29.limits.readMaxBytes);
21002
+ text = chunk.text;
21003
+ truncated = chunk.truncated;
21004
+ } else {
21005
+ try {
21006
+ text = _internals29.readFileSync(filePath, "utf-8");
21007
+ } catch {
21008
+ return { manifest: null, records: [], corruptLines: 0, truncated: false };
21009
+ }
21010
+ }
21011
+ const lines = text.split(`
21012
+ `);
21013
+ const records = [];
21014
+ let corruptLines = 0;
21015
+ let manifest = null;
21016
+ for (let i = 0;i < lines.length; i += 1) {
21017
+ const line = lines[i];
21018
+ if (line.trim() === "")
21019
+ continue;
21020
+ if (i === 0) {
21021
+ manifest = parseManifestLine(line);
21022
+ if (manifest)
21023
+ continue;
21024
+ }
21025
+ try {
21026
+ const parsed = JSON.parse(line);
21027
+ if (isValidTelemetryEntry(parsed)) {
21028
+ records.push(parsed);
21029
+ } else {
21030
+ corruptLines += 1;
21031
+ }
21032
+ } catch {
21033
+ corruptLines += 1;
21034
+ }
21035
+ }
21036
+ return { manifest, records, corruptLines, truncated };
21037
+ }
21038
+ function getTelemetrySummary(directory) {
21039
+ const filePath = telemetryFilePath(directory);
21040
+ const zero = () => ({
21041
+ total_delegations: 0,
21042
+ total_cache_hits: 0,
21043
+ total_cache_misses: 0,
21044
+ total_stale_entries: 0,
21045
+ avg_token_estimate: 0,
21046
+ total_recommended_reads: 0,
21047
+ total_skipped_reads: 0,
21048
+ success_rate: 0,
21049
+ coverage: "empty",
21050
+ tracked_period_ms: null,
21051
+ retained_entries: 0,
21052
+ folded_entries: 0,
21053
+ corrupt_entries: 0,
21054
+ dropped_entries: 0,
21055
+ on_disk_bytes: 0
21056
+ });
21057
+ const view = readStore(directory, true);
21058
+ const onDiskBytes = fileSizeOrZero(filePath);
21059
+ const corrupt = view.corruptLines;
21060
+ if (view.manifest === null) {
21061
+ const folded = emptyFolded();
21062
+ for (const rec of view.records)
21063
+ foldEntryInto(folded, rec);
21064
+ const total2 = folded.delegations;
21065
+ if (total2 === 0 && corrupt === 0 && view.records.length === 0) {
21066
+ return zero();
21067
+ }
21068
+ const coverage2 = view.truncated ? "partial-unmigrated" : "complete";
21069
+ return {
21070
+ total_delegations: total2,
21071
+ total_cache_hits: folded.cacheHits,
21072
+ total_cache_misses: folded.cacheMisses,
21073
+ total_stale_entries: folded.staleEntries,
21074
+ avg_token_estimate: total2 > 0 ? Math.round(folded.tokenSum / total2) : 0,
21075
+ total_recommended_reads: folded.recommendedReads,
21076
+ total_skipped_reads: folded.skippedReads,
21077
+ success_rate: total2 > 0 ? Math.round(folded.successCount / total2 * 100) : 0,
21078
+ coverage: coverage2,
21079
+ tracked_period_ms: periodMs(folded.oldestTimestamp, folded.newestTimestamp),
21080
+ retained_entries: view.records.length,
21081
+ folded_entries: 0,
21082
+ corrupt_entries: corrupt,
21083
+ dropped_entries: 0,
21084
+ on_disk_bytes: onDiskBytes
21085
+ };
21086
+ }
21087
+ const agg = cloneFolded(view.manifest.folded);
21088
+ for (const rec of view.records)
21089
+ foldEntryInto(agg, rec);
21090
+ const total = agg.delegations;
21091
+ if (total === 0 && view.records.length === 0 && corrupt === 0) {
21092
+ return zero();
21093
+ }
21094
+ const coverage = view.truncated ? "partial-unmigrated" : "complete";
21095
+ return {
21096
+ total_delegations: total,
21097
+ total_cache_hits: agg.cacheHits,
21098
+ total_cache_misses: agg.cacheMisses,
21099
+ total_stale_entries: agg.staleEntries,
21100
+ avg_token_estimate: total > 0 ? Math.round(agg.tokenSum / total) : 0,
21101
+ total_recommended_reads: agg.recommendedReads,
21102
+ total_skipped_reads: agg.skippedReads,
21103
+ success_rate: total > 0 ? Math.round(agg.successCount / total * 100) : 0,
21104
+ coverage,
21105
+ tracked_period_ms: periodMs(agg.oldestTimestamp, agg.newestTimestamp),
21106
+ retained_entries: view.records.length,
21107
+ folded_entries: view.manifest.folded.delegations,
21108
+ corrupt_entries: corrupt + view.manifest.folded.corrupt,
21109
+ dropped_entries: view.manifest.folded.dropped,
21110
+ on_disk_bytes: onDiskBytes
21111
+ };
21112
+ }
21113
+ function periodMs(oldest, newest) {
21114
+ if (oldest === null || newest === null)
21115
+ return null;
21116
+ const o = Date.parse(oldest);
21117
+ const n = Date.parse(newest);
21118
+ if (Number.isNaN(o) || Number.isNaN(n))
21119
+ return null;
21120
+ return Math.max(0, n - o);
21121
+ }
21122
+ function compactStore(directory, trigger = "compaction", alreadyLocked = false) {
21123
+ const filePath = telemetryFilePath(directory);
21124
+ if (!_internals29.existsSync(filePath))
21125
+ return;
21126
+ const run = () => {
21127
+ const view = readStore(directory, false);
21128
+ if (view.manifest === null)
21129
+ return;
21130
+ const folded = cloneFolded(view.manifest.folded);
21131
+ const now2 = Date.now();
21132
+ const agePruned = [];
21133
+ const kept = [];
21134
+ for (const rec of view.records) {
21135
+ const ts = Date.parse(rec.timestamp);
21136
+ if (!Number.isNaN(ts) && now2 - ts > _internals29.limits.ageMaxMs) {
21137
+ agePruned.push(rec);
21138
+ } else {
21139
+ kept.push(rec);
21140
+ }
21141
+ }
21142
+ const retained = [];
21143
+ let bytes = 0;
21144
+ for (let i = kept.length - 1;i >= 0; i -= 1) {
21145
+ const rec = kept[i];
21146
+ const lineBytes = Buffer.byteLength(JSON.stringify(rec)) + 1;
21147
+ if (retained.length >= _internals29.limits.activeMaxEntries || bytes + lineBytes > _internals29.limits.activeMaxBytes) {
21148
+ break;
21149
+ }
21150
+ retained.push(rec);
21151
+ bytes += lineBytes;
21152
+ }
21153
+ retained.reverse();
21154
+ for (const rec of agePruned)
21155
+ foldEntryInto(folded, rec);
21156
+ folded.dropped += agePruned.length;
21157
+ const retainedSet = new Set(retained);
21158
+ const compacted = [];
21159
+ const keptSet = new Set(kept);
21160
+ for (const rec of view.records) {
21161
+ if (keptSet.has(rec) && !retainedSet.has(rec)) {
21162
+ compacted.push(rec);
21163
+ }
21164
+ }
21165
+ for (const rec of compacted)
21166
+ foldEntryInto(folded, rec);
21167
+ folded.corrupt += view.corruptLines;
21168
+ const manifest = {
21169
+ ...emptyManifest(),
21170
+ folded,
21171
+ updatedAt: new Date().toISOString()
21172
+ };
21173
+ const lines = [`${JSON.stringify(manifest)}`];
21174
+ for (const rec of retained)
21175
+ lines.push(JSON.stringify(rec));
21176
+ atomicReplace(directory, lines.length > 1 ? `${lines.join(`
21177
+ `)}
21178
+ ` : `${lines[0]}
21179
+ `);
21180
+ emitHealth(directory, {
21181
+ trigger,
21182
+ accepted: folded.delegations + retained.length,
21183
+ compacted: compacted.length,
21184
+ retained: retained.length,
21185
+ dropped: agePruned.length,
21186
+ corrupt: folded.corrupt,
21187
+ oldest: folded.oldestTimestamp,
21188
+ newest: folded.newestTimestamp,
21189
+ bytes: fileSizeOrZero(filePath),
21190
+ limitBytes: _internals29.limits.activeMaxBytes
21191
+ });
21192
+ };
21193
+ if (alreadyLocked) {
21194
+ run();
21195
+ return;
21196
+ }
21197
+ withStoreLock(directory, run);
21198
+ }
21199
+ function migrateCutover(directory, trigger = "compaction", alreadyLocked = false) {
21200
+ const filePath = telemetryFilePath(directory);
21201
+ if (!_internals29.existsSync(filePath))
21202
+ return;
21203
+ const run = () => {
21204
+ if (!_internals29.existsSync(filePath))
21205
+ return;
21206
+ const view = readStore(directory, false);
21207
+ if (view.manifest === null && view.records.length === 0)
21208
+ return;
21209
+ const folded = view.manifest ? cloneFolded(view.manifest.folded) : emptyFolded();
21210
+ const now2 = Date.now();
21211
+ const agePruned = [];
21212
+ const kept = [];
21213
+ for (const rec of view.records) {
21214
+ const ts = Date.parse(rec.timestamp);
21215
+ if (!Number.isNaN(ts) && now2 - ts > _internals29.limits.ageMaxMs) {
21216
+ agePruned.push(rec);
21217
+ } else {
21218
+ kept.push(rec);
21219
+ }
21220
+ }
21221
+ const retained = [];
21222
+ let bytes = 0;
21223
+ for (let i = kept.length - 1;i >= 0; i -= 1) {
21224
+ const rec = kept[i];
21225
+ const lb = Buffer.byteLength(JSON.stringify(rec)) + 1;
21226
+ if (retained.length >= _internals29.limits.activeMaxEntries || bytes + lb > _internals29.limits.activeMaxBytes) {
21227
+ break;
21228
+ }
21229
+ retained.push(rec);
21230
+ bytes += lb;
21231
+ }
21232
+ retained.reverse();
21233
+ const retainedSet = new Set(retained);
21234
+ const keptSet = new Set(kept);
21235
+ const budgetPruned = [];
21236
+ for (const rec of view.records) {
21237
+ if (keptSet.has(rec) && !retainedSet.has(rec))
21238
+ budgetPruned.push(rec);
21239
+ }
21240
+ const candidates = [...agePruned, ...budgetPruned];
21241
+ const toFold = new Set;
21242
+ let foldedBytes = 0;
21243
+ for (const cand of candidates) {
21244
+ const cb = Buffer.byteLength(JSON.stringify(cand)) + 1;
21245
+ if (foldedBytes + cb > _internals29.limits.compactMaxBytes && toFold.size > 0) {
21246
+ break;
21247
+ }
21248
+ toFold.add(cand);
21249
+ foldedBytes += cb;
21250
+ }
21251
+ const finalRetained = [];
21252
+ const agePrunedSet = new Set(agePruned);
21253
+ let dropped = 0;
21254
+ for (const rec of view.records) {
21255
+ if (toFold.has(rec)) {
21256
+ foldEntryInto(folded, rec);
21257
+ if (agePrunedSet.has(rec))
21258
+ dropped += 1;
21259
+ } else {
21260
+ finalRetained.push(rec);
21261
+ }
21262
+ }
21263
+ if (dropped > 0)
21264
+ folded.dropped += dropped;
21265
+ folded.corrupt += view.corruptLines;
21266
+ const manifest = {
21267
+ ...emptyManifest(),
21268
+ folded,
21269
+ updatedAt: new Date().toISOString()
21270
+ };
21271
+ const lines = [`${JSON.stringify(manifest)}`];
21272
+ for (const rec of finalRetained)
21273
+ lines.push(JSON.stringify(rec));
21274
+ atomicReplace(directory, lines.length > 1 ? `${lines.join(`
21275
+ `)}
21276
+ ` : `${lines[0]}
21277
+ `);
21278
+ emitHealth(directory, {
21279
+ trigger,
21280
+ accepted: folded.delegations + finalRetained.length,
21281
+ compacted: toFold.size - dropped,
21282
+ retained: finalRetained.length,
21283
+ dropped,
21284
+ corrupt: folded.corrupt,
21285
+ oldest: folded.oldestTimestamp,
21286
+ newest: folded.newestTimestamp,
21287
+ bytes: fileSizeOrZero(filePath),
21288
+ limitBytes: _internals29.limits.activeMaxBytes
21289
+ });
21290
+ };
21291
+ if (alreadyLocked) {
21292
+ run();
21293
+ return;
21294
+ }
21295
+ withStoreLock(directory, run);
21296
+ }
21297
+ function finalizeContextTelemetry(directory) {
21298
+ try {
21299
+ const filePath = telemetryFilePath(directory);
21300
+ if (!_internals29.existsSync(filePath))
21301
+ return;
21302
+ withStoreLock(directory, () => {
21303
+ let prev = Number.POSITIVE_INFINITY;
21304
+ for (let pass = 0;pass < 1e4; pass += 1) {
21305
+ const view = readStore(directory, false);
21306
+ if (view.manifest !== null)
21307
+ break;
21308
+ if (view.records.length === 0)
21309
+ break;
21310
+ if (view.records.length >= prev)
21311
+ break;
21312
+ prev = view.records.length;
21313
+ migrateCutover(directory, "close", true);
21314
+ }
21315
+ compactStore(directory, "close", true);
21316
+ });
21317
+ } catch {
21318
+ warnThrottled("finalize failed");
21319
+ }
21320
+ }
21321
+ function emitContextTelemetryHealth(_directory, payload) {
21322
+ try {
21323
+ telemetry.contextTelemetryHealth({
21324
+ trigger: payload.trigger,
21325
+ accepted_count: payload.accepted,
21326
+ compacted_count: payload.compacted,
21327
+ retained_count: payload.retained,
21328
+ dropped_count: payload.dropped,
21329
+ corrupt_count: payload.corrupt,
21330
+ oldest_timestamp: payload.oldest,
21331
+ newest_timestamp: payload.newest,
21332
+ bytes: payload.bytes,
21333
+ limit_bytes: payload.limitBytes
21334
+ });
21335
+ } catch {}
21336
+ }
21337
+ function emitHealth(directory, payload) {
21338
+ _internals29.emitHealth(directory, payload);
21339
+ }
21340
+
20515
21341
  // src/memory/finalize-reward-sweep.ts
20516
21342
  init_logger();
20517
21343
 
@@ -20745,11 +21571,11 @@ class MemoryValidationError extends Error {
20745
21571
 
20746
21572
  // src/memory/schema.ts
20747
21573
  init_zod();
20748
- import { createHash as createHash9 } from "crypto";
21574
+ import { createHash as createHash10 } from "crypto";
20749
21575
 
20750
21576
  // src/memory/pii.ts
20751
21577
  import * as os3 from "os";
20752
- import * as path28 from "path";
21578
+ import * as path29 from "path";
20753
21579
  function computePiiScore(findings) {
20754
21580
  return findings.reduce((max, f) => Math.max(max, f.confidence), 0);
20755
21581
  }
@@ -20760,10 +21586,10 @@ function summarizePiiFindings(findings) {
20760
21586
  }
20761
21587
  return { score: computePiiScore(findings), countsByType };
20762
21588
  }
20763
- var NER_MODEL_CACHE_DIR = path28.join(os3.homedir(), ".cache", "opencode-swarm", "models");
21589
+ var NER_MODEL_CACHE_DIR = path29.join(os3.homedir(), ".cache", "opencode-swarm", "models");
20764
21590
 
20765
21591
  // src/memory/redaction.ts
20766
- import { createHash as createHash8 } from "crypto";
21592
+ import { createHash as createHash9 } from "crypto";
20767
21593
  var SECRET_PATTERNS = [
20768
21594
  { type: "openai_api_key", pattern: /\bsk-[A-Za-z0-9_-]{20,}\b/g },
20769
21595
  {
@@ -20813,10 +21639,10 @@ function computeRedactionPolicyVersion(policy) {
20813
21639
  }
20814
21640
  var FINGERPRINT_ALGORITHM_VERSION = 2;
20815
21641
  var LEGACY_FINGERPRINT_ALGORITHM_VERSION = 1;
20816
- var _internals29 = {
21642
+ var _internals30 = {
20817
21643
  currentAlgorithmVersion: FINGERPRINT_ALGORITHM_VERSION
20818
21644
  };
20819
- function classifyStoredFingerprintAlgorithmVersion(rawStoredVersion, currentVersion = _internals29.currentAlgorithmVersion) {
21645
+ function classifyStoredFingerprintAlgorithmVersion(rawStoredVersion, currentVersion = _internals30.currentAlgorithmVersion) {
20820
21646
  const storedVersion = rawStoredVersion === undefined ? LEGACY_FINGERPRINT_ALGORITHM_VERSION : rawStoredVersion;
20821
21647
  if (typeof storedVersion !== "number" || !Number.isFinite(storedVersion)) {
20822
21648
  return { status: "unknown" };
@@ -20825,7 +21651,7 @@ function classifyStoredFingerprintAlgorithmVersion(rawStoredVersion, currentVers
20825
21651
  }
20826
21652
  function computeMemoryCohortFingerprint(input) {
20827
21653
  const canonical = stableCanonicalStringify(input);
20828
- return createHash8("sha256").update(canonical).digest("hex").slice(0, 12);
21654
+ return createHash9("sha256").update(canonical).digest("hex").slice(0, 12);
20829
21655
  }
20830
21656
  function buildMemoryCohortFingerprintInput(config) {
20831
21657
  return {
@@ -21123,7 +21949,7 @@ function stableScopeKey(scope) {
21123
21949
  }
21124
21950
  function computeMemoryContentHash(recordLike) {
21125
21951
  const normalized = normalizeMemoryText(recordLike.text).toLowerCase();
21126
- return createHash9("sha256").update(`${stableScopeKey(recordLike.scope)}
21952
+ return createHash10("sha256").update(`${stableScopeKey(recordLike.scope)}
21127
21953
  ${recordLike.kind}
21128
21954
  ${normalized}`).digest("hex");
21129
21955
  }
@@ -21278,7 +22104,7 @@ function normalizeTags(tags) {
21278
22104
  // src/memory/local-jsonl-provider.ts
21279
22105
  var import_proper_lockfile6 = __toESM(require_proper_lockfile(), 1);
21280
22106
  import { randomUUID as randomUUID6 } from "crypto";
21281
- import { existsSync as existsSync15, readFileSync as readFileSync12, writeFileSync as writeFileSync6 } from "fs";
22107
+ import { existsSync as existsSync16, readFileSync as readFileSync13, writeFileSync as writeFileSync7 } from "fs";
21282
22108
  import {
21283
22109
  appendFile as appendFile8,
21284
22110
  mkdir as mkdir11,
@@ -21287,7 +22113,7 @@ import {
21287
22113
  truncate,
21288
22114
  writeFile as writeFile7
21289
22115
  } from "fs/promises";
21290
- import * as path29 from "path";
22116
+ import * as path30 from "path";
21291
22117
 
21292
22118
  // src/memory/q-learning.ts
21293
22119
  function clamp01(value) {
@@ -21865,7 +22691,7 @@ function proposalSort(a, b) {
21865
22691
  }
21866
22692
 
21867
22693
  // src/memory/outcome-events.ts
21868
- import { createHash as createHash10, randomUUID as randomUUID5 } from "crypto";
22694
+ import { createHash as createHash11, randomUUID as randomUUID5 } from "crypto";
21869
22695
  function newOutcomeGeneration() {
21870
22696
  return randomUUID5();
21871
22697
  }
@@ -21998,7 +22824,7 @@ function dedupeAnchors(anchors) {
21998
22824
  return [...byKey.values()].sort((a, b) => compareText(a.file, b.file) || compareText(a.symbol ?? "", b.symbol ?? ""));
21999
22825
  }
22000
22826
  function hash(value) {
22001
- return createHash10("sha256").update(value).digest("hex").slice(0, 32);
22827
+ return createHash11("sha256").update(value).digest("hex").slice(0, 32);
22002
22828
  }
22003
22829
  function compareText(a, b) {
22004
22830
  return a < b ? -1 : a > b ? 1 : 0;
@@ -22023,10 +22849,10 @@ class LocalJsonlMemoryProvider {
22023
22849
  pathFor(file) {
22024
22850
  const filename = file === "memories" ? "memories.jsonl" : file === "proposals" ? "proposals.jsonl" : file === "audit" ? "audit.jsonl" : file === "reward-events" ? "reward-events.jsonl" : "outcome-events.jsonl";
22025
22851
  if (this.cohortRoot) {
22026
- return path29.join(this.cohortRoot, filename);
22852
+ return path30.join(this.cohortRoot, filename);
22027
22853
  }
22028
22854
  const storageDir = this.config.storageDir.replace(/^\.swarm[/\\]?/, "");
22029
- return validateSwarmPath(this.rootDirectory, path29.join(storageDir, filename));
22855
+ return validateSwarmPath(this.rootDirectory, path30.join(storageDir, filename));
22030
22856
  }
22031
22857
  async initialize() {
22032
22858
  if (this.initialized)
@@ -22448,7 +23274,7 @@ class LocalJsonlMemoryProvider {
22448
23274
  await appendJsonl(this.pathFor("audit"), event);
22449
23275
  }
22450
23276
  async withOutcomeStoreLock(fn) {
22451
- const storageDirectory = path29.dirname(this.pathFor("memories"));
23277
+ const storageDirectory = path30.dirname(this.pathFor("memories"));
22452
23278
  await mkdir11(storageDirectory, { recursive: true });
22453
23279
  const release = await lockfile6.lock(storageDirectory, {
22454
23280
  realpath: false,
@@ -22478,9 +23304,9 @@ class LocalJsonlMemoryProvider {
22478
23304
  }
22479
23305
  readOutcomeEventsSync() {
22480
23306
  const filePath = this.pathFor("outcome-events");
22481
- if (!existsSync15(filePath))
23307
+ if (!existsSync16(filePath))
22482
23308
  return [];
22483
- const content = readFileSync12(filePath, "utf-8");
23309
+ const content = readFileSync13(filePath, "utf-8");
22484
23310
  const completeContent = content.endsWith(`
22485
23311
  `) ? content : content.slice(0, Math.max(0, content.lastIndexOf(`
22486
23312
  `) + 1));
@@ -22526,18 +23352,18 @@ class LocalJsonlMemoryProvider {
22526
23352
  if (!this.cohortRoot)
22527
23353
  return;
22528
23354
  try {
22529
- const markerPath = path29.join(this.cohortRoot, "memory.gen");
22530
- writeFileSync6(markerPath, String(Date.now()), "utf-8");
23355
+ const markerPath = path30.join(this.cohortRoot, "memory.gen");
23356
+ writeFileSync7(markerPath, String(Date.now()), "utf-8");
22531
23357
  } catch {}
22532
23358
  }
22533
23359
  assertCohortConfigFingerprint() {
22534
23360
  if (!this.cohortRoot)
22535
23361
  return;
22536
- const configPath = path29.join(this.cohortRoot, "memory-cohort-config.json");
22537
- if (!existsSync15(configPath))
23362
+ const configPath = path30.join(this.cohortRoot, "memory-cohort-config.json");
23363
+ if (!existsSync16(configPath))
22538
23364
  return;
22539
23365
  try {
22540
- const stored = JSON.parse(readFileSync12(configPath, "utf-8"));
23366
+ const stored = JSON.parse(readFileSync13(configPath, "utf-8"));
22541
23367
  const versionCheck = classifyStoredFingerprintAlgorithmVersion(stored.algorithm_version);
22542
23368
  if (versionCheck.status === "unknown") {
22543
23369
  warn("[memory-cohort] cohort config has a present but non-numeric `algorithm_version`, so its fingerprint cannot be attributed to a known algorithm and the config-coherence check was skipped. Run `/swarm memory link` to rewrite the cohort fingerprint.", {
@@ -22650,7 +23476,7 @@ function validateLoadedProposals(values, config) {
22650
23476
  return { records, invalidCount };
22651
23477
  }
22652
23478
  async function readJsonl(filePath) {
22653
- if (!existsSync15(filePath))
23479
+ if (!existsSync16(filePath))
22654
23480
  return [];
22655
23481
  const content = await readFile12(filePath, "utf-8");
22656
23482
  const records = [];
@@ -22727,12 +23553,12 @@ function parseRewardEvent(value) {
22727
23553
  };
22728
23554
  }
22729
23555
  async function appendJsonl(filePath, value) {
22730
- await mkdir11(path29.dirname(filePath), { recursive: true });
23556
+ await mkdir11(path30.dirname(filePath), { recursive: true });
22731
23557
  await appendFile8(filePath, `${JSON.stringify(value)}
22732
23558
  `, "utf-8");
22733
23559
  }
22734
23560
  async function writeJsonlAtomic(filePath, values) {
22735
- await mkdir11(path29.dirname(filePath), { recursive: true });
23561
+ await mkdir11(path30.dirname(filePath), { recursive: true });
22736
23562
  const tmp = `${filePath}.tmp.${randomUUID6()}`;
22737
23563
  const content = values.map((value) => JSON.stringify(value)).join(`
22738
23564
  `) + (values.length > 0 ? `
@@ -22741,7 +23567,7 @@ async function writeJsonlAtomic(filePath, values) {
22741
23567
  await rename5(tmp, filePath);
22742
23568
  }
22743
23569
  async function repairIncompleteJsonlTail(filePath) {
22744
- if (!existsSync15(filePath))
23570
+ if (!existsSync16(filePath))
22745
23571
  return;
22746
23572
  const content = await readFile12(filePath, "utf-8");
22747
23573
  if (content.length === 0 || content.endsWith(`
@@ -22754,19 +23580,19 @@ async function repairIncompleteJsonlTail(filePath) {
22754
23580
 
22755
23581
  // src/memory/provider-pool.ts
22756
23582
  import { realpathSync as realpathSync3 } from "fs";
22757
- import * as path34 from "path";
23583
+ import * as path35 from "path";
22758
23584
 
22759
23585
  // src/memory/sqlite-provider.ts
22760
- import { createHash as createHash11, randomUUID as randomUUID7 } from "crypto";
23586
+ import { createHash as createHash12, randomUUID as randomUUID7 } from "crypto";
22761
23587
  import {
22762
- existsSync as existsSync17,
22763
- mkdirSync as mkdirSync9,
22764
- readFileSync as readFileSync13,
22765
- statSync as statSync7,
22766
- writeFileSync as writeFileSync7
23588
+ existsSync as existsSync18,
23589
+ mkdirSync as mkdirSync10,
23590
+ readFileSync as readFileSync14,
23591
+ statSync as statSync8,
23592
+ writeFileSync as writeFileSync8
22767
23593
  } from "fs";
22768
23594
  import { createRequire as createRequire3 } from "module";
22769
- import * as path33 from "path";
23595
+ import * as path34 from "path";
22770
23596
 
22771
23597
  // src/memory/embeddings/cache.ts
22772
23598
  var DEFAULT_CACHE_SIZE = 256;
@@ -22882,10 +23708,10 @@ function minMaxNormalise(candidates) {
22882
23708
  }
22883
23709
 
22884
23710
  // src/memory/embeddings/local-provider.ts
22885
- import { mkdirSync as mkdirSync7 } from "fs";
23711
+ import { mkdirSync as mkdirSync8 } from "fs";
22886
23712
  import { createRequire } from "module";
22887
23713
  import * as os4 from "os";
22888
- import * as path30 from "path";
23714
+ import * as path31 from "path";
22889
23715
 
22890
23716
  // src/memory/embeddings/types.ts
22891
23717
  class EmbeddingUnavailableError extends Error {
@@ -22907,20 +23733,20 @@ class EmbeddingVersionMismatchError extends Error {
22907
23733
  }
22908
23734
 
22909
23735
  // src/memory/embeddings/local-provider.ts
22910
- var _internals30 = {
23736
+ var _internals31 = {
22911
23737
  resolveEmbeddingCacheDir() {
22912
23738
  let base;
22913
23739
  if (process.platform === "win32") {
22914
- base = process.env.LOCALAPPDATA || path30.join(os4.homedir(), "AppData", "Local");
23740
+ base = process.env.LOCALAPPDATA || path31.join(os4.homedir(), "AppData", "Local");
22915
23741
  } else if (process.platform === "darwin") {
22916
- base = path30.join(os4.homedir(), "Library", "Caches");
23742
+ base = path31.join(os4.homedir(), "Library", "Caches");
22917
23743
  } else {
22918
- base = process.env.XDG_CACHE_HOME || path30.join(os4.homedir(), ".cache");
23744
+ base = process.env.XDG_CACHE_HOME || path31.join(os4.homedir(), ".cache");
22919
23745
  }
22920
- const resolved = path30.join(base, "opencode", "embeddings");
22921
- const segments = resolved.split(path30.sep);
23746
+ const resolved = path31.join(base, "opencode", "embeddings");
23747
+ const segments = resolved.split(path31.sep);
22922
23748
  if (segments.includes(".swarm")) {
22923
- const safeDefault = process.platform === "win32" ? path30.join(os4.homedir(), "AppData", "Local", "opencode", "embeddings") : process.platform === "darwin" ? path30.join(os4.homedir(), "Library", "Caches", "opencode", "embeddings") : path30.join(os4.homedir(), ".cache", "opencode", "embeddings");
23749
+ const safeDefault = process.platform === "win32" ? path31.join(os4.homedir(), "AppData", "Local", "opencode", "embeddings") : process.platform === "darwin" ? path31.join(os4.homedir(), "Library", "Caches", "opencode", "embeddings") : path31.join(os4.homedir(), ".cache", "opencode", "embeddings");
22924
23750
  warn("Embedding cache dir resolved under .swarm/ \u2014 falling back to safe default");
22925
23751
  return safeDefault;
22926
23752
  }
@@ -22928,7 +23754,7 @@ var _internals30 = {
22928
23754
  }
22929
23755
  };
22930
23756
  function resolveEmbeddingCacheDir() {
22931
- return _internals30.resolveEmbeddingCacheDir();
23757
+ return _internals31.resolveEmbeddingCacheDir();
22932
23758
  }
22933
23759
 
22934
23760
  class LocalEmbeddingProvider {
@@ -22961,7 +23787,7 @@ class LocalEmbeddingProvider {
22961
23787
  console.log(`[opencode-swarm] Downloading embedding model "${this.modelName}" (~25 MB) \u2014 this happens once per process.`);
22962
23788
  }
22963
23789
  const cacheDir = resolveEmbeddingCacheDir();
22964
- mkdirSync7(cacheDir, { recursive: true });
23790
+ mkdirSync8(cacheDir, { recursive: true });
22965
23791
  this.pipeline = await transformers.pipeline("feature-extraction", this.modelName, { cache_dir: cacheDir });
22966
23792
  this._available = true;
22967
23793
  return this.pipeline;
@@ -23035,10 +23861,10 @@ class LocalEmbeddingProvider {
23035
23861
  }
23036
23862
 
23037
23863
  // src/memory/embeddings/reranker.ts
23038
- import { mkdirSync as mkdirSync8 } from "fs";
23864
+ import { mkdirSync as mkdirSync9 } from "fs";
23039
23865
  import { createRequire as createRequire2 } from "module";
23040
23866
  import * as os5 from "os";
23041
- import * as path31 from "path";
23867
+ import * as path32 from "path";
23042
23868
  function shouldRerank(previousRecallElapsedMs, latencyBudgetMs) {
23043
23869
  return previousRecallElapsedMs <= latencyBudgetMs;
23044
23870
  }
@@ -23064,7 +23890,7 @@ class CrossEncoderReranker {
23064
23890
  const transformers = req("@xenova/transformers");
23065
23891
  const modelName = this.options.model ?? "Xenova/ms-marco-MiniLM-L-6-v2";
23066
23892
  const cacheDir = resolveRerankerCacheDir();
23067
- mkdirSync8(cacheDir, { recursive: true });
23893
+ mkdirSync9(cacheDir, { recursive: true });
23068
23894
  this.pipeline = await transformers.pipeline("text-classification", modelName, { cache_dir: cacheDir });
23069
23895
  this._available = true;
23070
23896
  return this.pipeline;
@@ -23106,16 +23932,16 @@ class CrossEncoderReranker {
23106
23932
  function resolveRerankerCacheDir() {
23107
23933
  let base;
23108
23934
  if (process.platform === "win32") {
23109
- base = process.env.LOCALAPPDATA || path31.join(os5.homedir(), "AppData", "Local");
23935
+ base = process.env.LOCALAPPDATA || path32.join(os5.homedir(), "AppData", "Local");
23110
23936
  } else if (process.platform === "darwin") {
23111
- base = path31.join(os5.homedir(), "Library", "Caches");
23937
+ base = path32.join(os5.homedir(), "Library", "Caches");
23112
23938
  } else {
23113
- base = process.env.XDG_CACHE_HOME || path31.join(os5.homedir(), ".cache");
23939
+ base = process.env.XDG_CACHE_HOME || path32.join(os5.homedir(), ".cache");
23114
23940
  }
23115
- const resolved = path31.join(base, "opencode", "embeddings");
23116
- const segments = resolved.split(path31.sep);
23941
+ const resolved = path32.join(base, "opencode", "embeddings");
23942
+ const segments = resolved.split(path32.sep);
23117
23943
  if (segments.includes(".swarm")) {
23118
- const safeDefault = process.platform === "win32" ? path31.join(os5.homedir(), "AppData", "Local", "opencode", "embeddings") : process.platform === "darwin" ? path31.join(os5.homedir(), "Library", "Caches", "opencode", "embeddings") : path31.join(os5.homedir(), ".cache", "opencode", "embeddings");
23944
+ const safeDefault = process.platform === "win32" ? path32.join(os5.homedir(), "AppData", "Local", "opencode", "embeddings") : process.platform === "darwin" ? path32.join(os5.homedir(), "Library", "Caches", "opencode", "embeddings") : path32.join(os5.homedir(), ".cache", "opencode", "embeddings");
23119
23945
  warn("Reranker cache dir resolved under .swarm/ \u2014 falling back to safe default");
23120
23946
  return safeDefault;
23121
23947
  }
@@ -23123,9 +23949,9 @@ function resolveRerankerCacheDir() {
23123
23949
  }
23124
23950
 
23125
23951
  // src/memory/jsonl-migration.ts
23126
- import { existsSync as existsSync16, renameSync as renameSync5, unlinkSync as unlinkSync3 } from "fs";
23952
+ import { existsSync as existsSync17, renameSync as renameSync6, unlinkSync as unlinkSync4 } from "fs";
23127
23953
  import { copyFile, mkdir as mkdir12, readFile as readFile13, stat as stat4, writeFile as writeFile8 } from "fs/promises";
23128
- import * as path32 from "path";
23954
+ import * as path33 from "path";
23129
23955
  var LEGACY_JSONL_MIGRATION_VERSION = 2;
23130
23956
  var LEGACY_JSONL_MIGRATION_NAME = "legacy_jsonl_import_complete";
23131
23957
  var LEGACY_JSONL_OUTCOME_META_KEY = "legacy_jsonl_outcomes_import_complete";
@@ -23142,9 +23968,9 @@ function resolveSqliteDatabasePath(rootDirectory, config = {}) {
23142
23968
  async function readLegacyJsonl(rootDirectory, config = {}) {
23143
23969
  const resolved = resolveConfig(config);
23144
23970
  const storageDir = resolveMemoryStorageDir(rootDirectory, resolved);
23145
- const memoryLoad = await readMemoryJsonl(path32.join(storageDir, "memories.jsonl"), resolved);
23146
- const proposalLoad = await readProposalJsonl(path32.join(storageDir, "proposals.jsonl"), resolved);
23147
- const outcomeLoad = await readOutcomeJsonl(path32.join(storageDir, "outcome-events.jsonl"));
23971
+ const memoryLoad = await readMemoryJsonl(path33.join(storageDir, "memories.jsonl"), resolved);
23972
+ const proposalLoad = await readProposalJsonl(path33.join(storageDir, "proposals.jsonl"), resolved);
23973
+ const outcomeLoad = await readOutcomeJsonl(path33.join(storageDir, "outcome-events.jsonl"));
23148
23974
  return {
23149
23975
  memories: memoryLoad.records,
23150
23976
  memoryRows: memoryLoad.rows,
@@ -23161,7 +23987,7 @@ async function readLegacyJsonl(rootDirectory, config = {}) {
23161
23987
  }
23162
23988
  async function backupLegacyJsonl(rootDirectory, config = {}) {
23163
23989
  const storageDir = resolveMemoryStorageDir(rootDirectory, config);
23164
- const backupDir = path32.join(storageDir, "backups");
23990
+ const backupDir = path33.join(storageDir, "backups");
23165
23991
  await mkdir12(backupDir, { recursive: true });
23166
23992
  const results = [];
23167
23993
  for (const filename of [
@@ -23169,11 +23995,11 @@ async function backupLegacyJsonl(rootDirectory, config = {}) {
23169
23995
  "proposals.jsonl",
23170
23996
  "outcome-events.jsonl"
23171
23997
  ]) {
23172
- const source = path32.join(storageDir, filename);
23173
- if (!existsSync16(source))
23998
+ const source = path33.join(storageDir, filename);
23999
+ if (!existsSync17(source))
23174
24000
  continue;
23175
- const backup = path32.join(backupDir, `${filename}.pre-sqlite-migration`);
23176
- if (existsSync16(backup)) {
24001
+ const backup = path33.join(backupDir, `${filename}.pre-sqlite-migration`);
24002
+ if (existsSync17(backup)) {
23177
24003
  results.push({ source, backup, created: false });
23178
24004
  continue;
23179
24005
  }
@@ -23183,62 +24009,62 @@ async function backupLegacyJsonl(rootDirectory, config = {}) {
23183
24009
  return results;
23184
24010
  }
23185
24011
  async function writeJsonlExport(rootDirectory, config, memories, proposals, outcomeEvents = []) {
23186
- const exportDir = path32.join(resolveMemoryStorageDir(rootDirectory, config), "export");
24012
+ const exportDir = path33.join(resolveMemoryStorageDir(rootDirectory, config), "export");
23187
24013
  await mkdir12(exportDir, { recursive: true });
23188
- const memoriesPath = path32.join(exportDir, "memories.jsonl");
23189
- const proposalsPath = path32.join(exportDir, "proposals.jsonl");
23190
- const outcomesPath = path32.join(exportDir, "outcome-events.jsonl");
23191
- const memoriesTempPath = path32.join(path32.dirname(memoriesPath), `${path32.basename(memoriesPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
24014
+ const memoriesPath = path33.join(exportDir, "memories.jsonl");
24015
+ const proposalsPath = path33.join(exportDir, "proposals.jsonl");
24016
+ const outcomesPath = path33.join(exportDir, "outcome-events.jsonl");
24017
+ const memoriesTempPath = path33.join(path33.dirname(memoriesPath), `${path33.basename(memoriesPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
23192
24018
  try {
23193
24019
  await writeFile8(memoriesTempPath, toJsonl(memories), "utf-8");
23194
- renameSync5(memoriesTempPath, memoriesPath);
24020
+ renameSync6(memoriesTempPath, memoriesPath);
23195
24021
  } catch (err) {
23196
24022
  try {
23197
- unlinkSync3(memoriesTempPath);
24023
+ unlinkSync4(memoriesTempPath);
23198
24024
  } catch {}
23199
24025
  throw err;
23200
24026
  }
23201
- const proposalsTempPath = path32.join(path32.dirname(proposalsPath), `${path32.basename(proposalsPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
24027
+ const proposalsTempPath = path33.join(path33.dirname(proposalsPath), `${path33.basename(proposalsPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
23202
24028
  try {
23203
24029
  await writeFile8(proposalsTempPath, toJsonl(proposals), "utf-8");
23204
- renameSync5(proposalsTempPath, proposalsPath);
24030
+ renameSync6(proposalsTempPath, proposalsPath);
23205
24031
  } catch (err) {
23206
24032
  try {
23207
- unlinkSync3(proposalsTempPath);
24033
+ unlinkSync4(proposalsTempPath);
23208
24034
  } catch {}
23209
24035
  throw err;
23210
24036
  }
23211
- const outcomesTempPath = path32.join(path32.dirname(outcomesPath), `${path32.basename(outcomesPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
24037
+ const outcomesTempPath = path33.join(path33.dirname(outcomesPath), `${path33.basename(outcomesPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
23212
24038
  try {
23213
24039
  await writeFile8(outcomesTempPath, toJsonl(outcomeEvents), "utf-8");
23214
- renameSync5(outcomesTempPath, outcomesPath);
24040
+ renameSync6(outcomesTempPath, outcomesPath);
23215
24041
  } catch (err) {
23216
24042
  try {
23217
- unlinkSync3(outcomesTempPath);
24043
+ unlinkSync4(outcomesTempPath);
23218
24044
  } catch {}
23219
24045
  throw err;
23220
24046
  }
23221
24047
  return { directory: exportDir, memoriesPath, proposalsPath, outcomesPath };
23222
24048
  }
23223
24049
  async function writeMigrationReport(rootDirectory, report, config = {}) {
23224
- const reportPath = path32.join(resolveMemoryStorageDir(rootDirectory, config), "migration-report.json");
23225
- await mkdir12(path32.dirname(reportPath), { recursive: true });
23226
- const reportTempPath = path32.join(path32.dirname(reportPath), `${path32.basename(reportPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
24050
+ const reportPath = path33.join(resolveMemoryStorageDir(rootDirectory, config), "migration-report.json");
24051
+ await mkdir12(path33.dirname(reportPath), { recursive: true });
24052
+ const reportTempPath = path33.join(path33.dirname(reportPath), `${path33.basename(reportPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
23227
24053
  try {
23228
24054
  await writeFile8(reportTempPath, `${JSON.stringify(report, null, 2)}
23229
24055
  `, "utf-8");
23230
- renameSync5(reportTempPath, reportPath);
24056
+ renameSync6(reportTempPath, reportPath);
23231
24057
  } catch (err) {
23232
24058
  try {
23233
- unlinkSync3(reportTempPath);
24059
+ unlinkSync4(reportTempPath);
23234
24060
  } catch {}
23235
24061
  throw err;
23236
24062
  }
23237
24063
  return reportPath;
23238
24064
  }
23239
24065
  async function readMigrationReport(rootDirectory, config = {}) {
23240
- const reportPath = path32.join(resolveMemoryStorageDir(rootDirectory, config), "migration-report.json");
23241
- if (!existsSync16(reportPath))
24066
+ const reportPath = path33.join(resolveMemoryStorageDir(rootDirectory, config), "migration-report.json");
24067
+ if (!existsSync17(reportPath))
23242
24068
  return null;
23243
24069
  try {
23244
24070
  return JSON.parse(await readFile13(reportPath, "utf-8"));
@@ -23254,23 +24080,23 @@ async function getLegacyJsonlFileStatus(rootDirectory, config = {}) {
23254
24080
  "proposals.jsonl",
23255
24081
  "outcome-events.jsonl"
23256
24082
  ]) {
23257
- const filePath = path32.join(storageDir, file);
24083
+ const filePath = path33.join(storageDir, file);
23258
24084
  let sizeBytes = 0;
23259
- if (existsSync16(filePath)) {
24085
+ if (existsSync17(filePath)) {
23260
24086
  sizeBytes = (await stat4(filePath)).size;
23261
24087
  }
23262
24088
  statuses.push({
23263
24089
  file,
23264
24090
  path: filePath,
23265
- exists: existsSync16(filePath),
24091
+ exists: existsSync17(filePath),
23266
24092
  sizeBytes
23267
24093
  });
23268
24094
  }
23269
24095
  return statuses;
23270
24096
  }
23271
24097
  async function getLegacyOutcomeJsonlSignature(rootDirectory, config = {}) {
23272
- const filePath = path32.join(resolveMemoryStorageDir(rootDirectory, config), "outcome-events.jsonl");
23273
- if (!existsSync16(filePath))
24098
+ const filePath = path33.join(resolveMemoryStorageDir(rootDirectory, config), "outcome-events.jsonl");
24099
+ if (!existsSync17(filePath))
23274
24100
  return "missing";
23275
24101
  const details = await stat4(filePath);
23276
24102
  return `${details.size}:${details.mtimeMs}`;
@@ -23392,7 +24218,7 @@ async function readOutcomeJsonl(filePath) {
23392
24218
  return { records, rows: validRows, invalidRows, totalRows: rows.totalRows };
23393
24219
  }
23394
24220
  async function readJsonlRows(filePath) {
23395
- if (!existsSync16(filePath)) {
24221
+ if (!existsSync17(filePath)) {
23396
24222
  return { rows: [], invalidRows: [], totalRows: 0 };
23397
24223
  }
23398
24224
  const content = await readFile13(filePath, "utf-8");
@@ -23426,7 +24252,7 @@ function toJsonl(values) {
23426
24252
  var EVENT_CHAIN_GENESIS = "GENESIS";
23427
24253
  var MEMORY_EVENTS_CHAIN_HEAD_KEY = "memory_events_chain_head";
23428
24254
  function memoryEventRowHash(row) {
23429
- return createHash11("sha256").update(stableCanonicalStringify({
24255
+ return createHash12("sha256").update(stableCanonicalStringify({
23430
24256
  id: row.id,
23431
24257
  operation: row.operation,
23432
24258
  target_id: row.target_id,
@@ -23771,7 +24597,7 @@ class SQLiteMemoryProvider {
23771
24597
  }
23772
24598
  databasePath() {
23773
24599
  if (this.cohortRoot) {
23774
- return path33.join(this.cohortRoot, "memory.db");
24600
+ return path34.join(this.cohortRoot, "memory.db");
23775
24601
  }
23776
24602
  const relativePath2 = this.config.sqlite.path.replace(/^\.swarm[/\\]?/, "");
23777
24603
  return validateSwarmPath(this.rootDirectory, relativePath2);
@@ -23792,7 +24618,7 @@ class SQLiteMemoryProvider {
23792
24618
  if (this.cohortRoot) {
23793
24619
  this.assertCohortConfigFingerprint();
23794
24620
  }
23795
- mkdirSync9(path33.dirname(dbPath), { recursive: true });
24621
+ mkdirSync10(path34.dirname(dbPath), { recursive: true });
23796
24622
  const Db = loadDatabaseCtor();
23797
24623
  this.db = new Db(dbPath);
23798
24624
  try {
@@ -24446,13 +25272,13 @@ class SQLiteMemoryProvider {
24446
25272
  }
24447
25273
  try {
24448
25274
  const wal = `${dbPath}-wal`;
24449
- const st = statSync7(wal);
25275
+ const st = statSync8(wal);
24450
25276
  if (st.size > 0)
24451
25277
  walPath2 = wal;
24452
25278
  } catch {}
24453
25279
  try {
24454
25280
  const shm = `${dbPath}-shm`;
24455
- const st = statSync7(shm);
25281
+ const st = statSync8(shm);
24456
25282
  if (st.size > 0)
24457
25283
  shmPath = shm;
24458
25284
  } catch {}
@@ -24864,9 +25690,9 @@ class SQLiteMemoryProvider {
24864
25690
  try {
24865
25691
  const dimension = Math.max(1, Math.trunc(this.config.embeddings.dimension ?? 384));
24866
25692
  const req = createRequire3(import.meta.url);
24867
- const pkgDir = path33.dirname(req.resolve("@sqlite/sqlite-vec/package.json"));
25693
+ const pkgDir = path34.dirname(req.resolve("@sqlite/sqlite-vec/package.json"));
24868
25694
  const ext = process.platform === "win32" ? ".dll" : process.platform === "darwin" ? ".dylib" : ".so";
24869
- const vec0Path = path33.join(pkgDir, `vec0${ext}`);
25695
+ const vec0Path = path34.join(pkgDir, `vec0${ext}`);
24870
25696
  db.loadExtension(vec0Path);
24871
25697
  db.run(`CREATE VIRTUAL TABLE IF NOT EXISTS memory_items_vec USING vec0(
24872
25698
  id TEXT PRIMARY KEY, embedding FLOAT[${dimension}]
@@ -25075,20 +25901,20 @@ class SQLiteMemoryProvider {
25075
25901
  if (!this.cohortRoot)
25076
25902
  return;
25077
25903
  try {
25078
- const markerPath = path33.join(this.cohortRoot, "memory.gen");
25079
- writeFileSync7(markerPath, String(Date.now()), "utf-8");
25904
+ const markerPath = path34.join(this.cohortRoot, "memory.gen");
25905
+ writeFileSync8(markerPath, String(Date.now()), "utf-8");
25080
25906
  } catch {}
25081
25907
  }
25082
25908
  assertCohortConfigFingerprint() {
25083
25909
  if (!this.cohortRoot)
25084
25910
  return;
25085
- const configPath = path33.join(this.cohortRoot, "memory-cohort-config.json");
25086
- if (!existsSync17(configPath)) {
25911
+ const configPath = path34.join(this.cohortRoot, "memory-cohort-config.json");
25912
+ if (!existsSync18(configPath)) {
25087
25913
  warn("[memory-cohort] cohort config fingerprint file is absent; config-coherence check skipped. Run `/swarm memory link` to re-establish the fingerprint.", { cohortRoot: this.cohortRoot });
25088
25914
  return;
25089
25915
  }
25090
25916
  try {
25091
- const stored = JSON.parse(readFileSync13(configPath, "utf-8"));
25917
+ const stored = JSON.parse(readFileSync14(configPath, "utf-8"));
25092
25918
  const versionCheck = classifyStoredFingerprintAlgorithmVersion(stored.algorithm_version);
25093
25919
  if (versionCheck.status === "unknown") {
25094
25920
  warn("[memory-cohort] cohort config has a present but non-numeric `algorithm_version`, so its fingerprint cannot be attributed to a known algorithm and the config-coherence check was skipped. Run `/swarm memory link` to rewrite the cohort fingerprint.", {
@@ -25808,7 +26634,7 @@ function resolvePoolKeyForRoot(root) {
25808
26634
  try {
25809
26635
  return `cohort:${realpathSync3(root.cohortRoot)}`;
25810
26636
  } catch {
25811
- return `cohort:${path34.resolve(root.cohortRoot)}`;
26637
+ return `cohort:${path35.resolve(root.cohortRoot)}`;
25812
26638
  }
25813
26639
  }
25814
26640
  return resolvePoolKey(root.directory);
@@ -25887,7 +26713,7 @@ function unlinkEntry(entry) {
25887
26713
  tail = entry.prev;
25888
26714
  }
25889
26715
  function resolvePoolKey(directory) {
25890
- const rawKey = path34.resolve(directory);
26716
+ const rawKey = path35.resolve(directory);
25891
26717
  try {
25892
26718
  const canonical = realpathSync3(directory);
25893
26719
  resolvedKeyCache.delete(rawKey);
@@ -25920,24 +26746,24 @@ function evictAndClose(directory) {
25920
26746
 
25921
26747
  // src/memory/storage-root.ts
25922
26748
  init_logger();
25923
- import * as path36 from "path";
26749
+ import * as path37 from "path";
25924
26750
 
25925
26751
  // src/memory/memory-link.ts
25926
- import { existsSync as existsSync18, mkdirSync as mkdirSync10, readFileSync as readFileSync14, rmSync as rmSync2, statSync as statSync8 } from "fs";
25927
- import * as path35 from "path";
26752
+ import { existsSync as existsSync19, mkdirSync as mkdirSync11, readFileSync as readFileSync15, rmSync as rmSync2, statSync as statSync9 } from "fs";
26753
+ import * as path36 from "path";
25928
26754
  init_logger();
25929
26755
  var MEMORY_LINK_POINTER_FILENAME = "memory-link.json";
25930
26756
  var CACHE_TTL_MS = 2000;
25931
26757
  var MAX_CACHE_ENTRIES = 500;
25932
26758
  function resolveMemoryLinkPointerPath(directory) {
25933
- return path35.join(directory, ".swarm", MEMORY_LINK_POINTER_FILENAME);
26759
+ return path36.join(directory, ".swarm", MEMORY_LINK_POINTER_FILENAME);
25934
26760
  }
25935
26761
  function readMemoryLinkPointer(directory) {
25936
26762
  const pointerPath = resolveMemoryLinkPointerPath(directory);
25937
- if (!existsSync18(pointerPath))
26763
+ if (!existsSync19(pointerPath))
25938
26764
  return null;
25939
26765
  try {
25940
- const raw = JSON.parse(readFileSync14(pointerPath, "utf-8"));
26766
+ const raw = JSON.parse(readFileSync15(pointerPath, "utf-8"));
25941
26767
  if (!raw || typeof raw !== "object")
25942
26768
  return null;
25943
26769
  const obj = raw;
@@ -25965,8 +26791,8 @@ function readMemoryLinkPointer(directory) {
25965
26791
  }
25966
26792
  }
25967
26793
  async function writeMemoryLinkPointer(directory, pointer) {
25968
- const swarmDir = path35.join(directory, ".swarm");
25969
- mkdirSync10(swarmDir, { recursive: true });
26794
+ const swarmDir = path36.join(directory, ".swarm");
26795
+ mkdirSync11(swarmDir, { recursive: true });
25970
26796
  const pointerPath = resolveMemoryLinkPointerPath(directory);
25971
26797
  await atomicWriteFile(pointerPath, JSON.stringify(pointer, null, 2));
25972
26798
  invalidateMemoryStoreDirCache(directory);
@@ -25983,14 +26809,14 @@ var _resolutionCache = new Map;
25983
26809
  function pointerStatFingerprint(directory) {
25984
26810
  const pointerPath = resolveMemoryLinkPointerPath(directory);
25985
26811
  try {
25986
- const st = statSync8(pointerPath);
26812
+ const st = statSync9(pointerPath);
25987
26813
  return `${st.mtimeMs}:${st.ctimeMs}:${st.size}`;
25988
26814
  } catch {
25989
26815
  return null;
25990
26816
  }
25991
26817
  }
25992
26818
  function resolveMemoryStoreDir(directory) {
25993
- const localSwarm = path35.join(directory, ".swarm");
26819
+ const localSwarm = path36.join(directory, ".swarm");
25994
26820
  const now2 = Date.now();
25995
26821
  const cached = _resolutionCache.get(directory);
25996
26822
  const currentStat = pointerStatFingerprint(directory);
@@ -26001,7 +26827,7 @@ function resolveMemoryStoreDir(directory) {
26001
26827
  try {
26002
26828
  const pointer = readMemoryLinkPointer(directory);
26003
26829
  if (pointer) {
26004
- linkDir = path35.resolve(resolveLinkDir(pointer.linkId));
26830
+ linkDir = path36.resolve(resolveLinkDir(pointer.linkId));
26005
26831
  }
26006
26832
  } catch {
26007
26833
  linkDir = null;
@@ -26041,13 +26867,13 @@ function resolveVettedMemoryRoot(directory, config) {
26041
26867
  return wrapLocalRoot(directory);
26042
26868
  }
26043
26869
  const sharedDir = resolveMemoryStoreDir(directory);
26044
- const localSwarm = path36.join(directory, ".swarm");
26870
+ const localSwarm = path37.join(directory, ".swarm");
26045
26871
  if (sharedDir === localSwarm) {
26046
26872
  return wrapLocalRoot(directory);
26047
26873
  }
26048
26874
  return {
26049
26875
  kind: "cohort",
26050
- cohortRoot: path36.join(sharedDir, "memory"),
26876
+ cohortRoot: path37.join(sharedDir, "memory"),
26051
26877
  cohortId: pointer.cohortId ?? pointer.linkId,
26052
26878
  generation: pointer.generation ?? 0,
26053
26879
  linkId: pointer.linkId,
@@ -26058,7 +26884,7 @@ function wrapLocalRoot(directory) {
26058
26884
  log("[memory] wrapping raw directory as local vetted root \u2014 cohort sharing inactive for this caller", { directory });
26059
26885
  return {
26060
26886
  kind: "local",
26061
- root: path36.join(directory, ".swarm"),
26887
+ root: path37.join(directory, ".swarm"),
26062
26888
  directory
26063
26889
  };
26064
26890
  }
@@ -26066,7 +26892,7 @@ function isCohortRoot(root) {
26066
26892
  return root.kind === "cohort";
26067
26893
  }
26068
26894
  function rootStoragePath(root) {
26069
- return root.kind === "cohort" ? root.cohortRoot : path36.join(root.root, "memory");
26895
+ return root.kind === "cohort" ? root.cohortRoot : path37.join(root.root, "memory");
26070
26896
  }
26071
26897
 
26072
26898
  // src/memory/gateway.ts
@@ -26338,7 +27164,7 @@ async function runFinalizeRewardSweep(args) {
26338
27164
  }
26339
27165
  const timestamp = args.timestamp ?? new Date().toISOString();
26340
27166
  const vettedRoot = resolveVettedMemoryRoot(directory, memoryConfig);
26341
- const provider = _internals31.createConfiguredMemoryProviderForRoot(vettedRoot, memoryConfig);
27167
+ const provider = _internals32.createConfiguredMemoryProviderForRoot(vettedRoot, memoryConfig);
26342
27168
  try {
26343
27169
  result.swept = true;
26344
27170
  for (const taskId of taskIds) {
@@ -26358,7 +27184,7 @@ async function runFinalizeRewardSweep(args) {
26358
27184
  }
26359
27185
  let taskRewarded = 0;
26360
27186
  for (const runId of runIds) {
26361
- const { memoriesRewarded } = await _internals31.applyCouncilReward(provider, {
27187
+ const { memoriesRewarded } = await _internals32.applyCouncilReward(provider, {
26362
27188
  runId,
26363
27189
  unitId: taskId,
26364
27190
  reward: FINALIZE_NEGATIVE_TERMINAL_REWARD,
@@ -26384,15 +27210,15 @@ async function runFinalizeRewardSweep(args) {
26384
27210
  }
26385
27211
  return result;
26386
27212
  }
26387
- var _internals31 = {
27213
+ var _internals32 = {
26388
27214
  createConfiguredMemoryProvider,
26389
27215
  createConfiguredMemoryProviderForRoot,
26390
27216
  applyCouncilReward
26391
27217
  };
26392
27218
 
26393
27219
  // src/services/session-reflection.ts
26394
- import { promises as fs13 } from "fs";
26395
- import * as path37 from "path";
27220
+ import { promises as fs14 } from "fs";
27221
+ import * as path38 from "path";
26396
27222
 
26397
27223
  // src/hooks/skill-improver-llm-factory.ts
26398
27224
  init_schema();
@@ -26569,13 +27395,13 @@ async function gatherRetroLessonsAndTaxonomy(directory) {
26569
27395
  const lessons = [];
26570
27396
  const taxonomy = {};
26571
27397
  try {
26572
- const evidenceDir = path37.join(directory, ".swarm", "evidence");
26573
- const entries = await fs13.readdir(evidenceDir);
27398
+ const evidenceDir = path38.join(directory, ".swarm", "evidence");
27399
+ const entries = await fs14.readdir(evidenceDir);
26574
27400
  const retroDirs = entries.filter((e) => e.startsWith("retro-")).sort((a, b) => a.localeCompare(b, undefined, { numeric: true }));
26575
27401
  for (const retroDir of retroDirs) {
26576
- const evidencePath = path37.join(evidenceDir, retroDir, "evidence.json");
27402
+ const evidencePath = path38.join(evidenceDir, retroDir, "evidence.json");
26577
27403
  try {
26578
- const content = await fs13.readFile(evidencePath, "utf-8");
27404
+ const content = await fs14.readFile(evidencePath, "utf-8");
26579
27405
  const parsed = JSON.parse(content);
26580
27406
  const bundleEntries = parsed.entries ?? [parsed];
26581
27407
  for (const entry of bundleEntries) {
@@ -26602,14 +27428,14 @@ async function gatherRetroLessonsAndTaxonomy(directory) {
26602
27428
  async function gatherGateFailures(directory) {
26603
27429
  const failures = new Map;
26604
27430
  try {
26605
- const evidenceDir = path37.join(directory, ".swarm", "evidence");
26606
- const entries = await fs13.readdir(evidenceDir);
27431
+ const evidenceDir = path38.join(directory, ".swarm", "evidence");
27432
+ const entries = await fs14.readdir(evidenceDir);
26607
27433
  for (const entry of entries) {
26608
27434
  if (entry.startsWith("retro-"))
26609
27435
  continue;
26610
- const evidencePath = path37.join(evidenceDir, entry, "evidence.json");
27436
+ const evidencePath = path38.join(evidenceDir, entry, "evidence.json");
26611
27437
  try {
26612
- const content = await fs13.readFile(evidencePath, "utf-8");
27438
+ const content = await fs14.readFile(evidencePath, "utf-8");
26613
27439
  const parsed = JSON.parse(content);
26614
27440
  const bundleEntries = parsed.entries ?? [parsed];
26615
27441
  for (const e of bundleEntries) {
@@ -26642,7 +27468,7 @@ async function gatherLedgerRejections(directory, sessionId) {
26642
27468
  const counts = {};
26643
27469
  const readLedger = async (filePath) => {
26644
27470
  try {
26645
- const handle = await fs13.open(filePath, "r");
27471
+ const handle = await fs14.open(filePath, "r");
26646
27472
  try {
26647
27473
  const stat5 = await handle.stat();
26648
27474
  if (!stat5.isFile())
@@ -26659,23 +27485,23 @@ async function gatherLedgerRejections(directory, sessionId) {
26659
27485
  }
26660
27486
  };
26661
27487
  const readContained = async (root, ...segments) => {
26662
- const target = path37.join(root, ...segments);
27488
+ const target = path38.join(root, ...segments);
26663
27489
  try {
26664
- const realRoot = await fs13.realpath(path37.join(root));
26665
- const realTarget = await fs13.realpath(target);
26666
- const rel = path37.relative(realRoot, realTarget);
26667
- if (rel.startsWith("..") || path37.isAbsolute(rel))
27490
+ const realRoot = await fs14.realpath(path38.join(root));
27491
+ const realTarget = await fs14.realpath(target);
27492
+ const rel = path38.relative(realRoot, realTarget);
27493
+ if (rel.startsWith("..") || path38.isAbsolute(rel))
26668
27494
  return null;
26669
27495
  } catch {
26670
27496
  return null;
26671
27497
  }
26672
27498
  return readLedger(target);
26673
27499
  };
26674
- let content = await readLedger(path37.join(directory, ".swarm", "events.jsonl"));
27500
+ let content = await readLedger(path38.join(directory, ".swarm", "events.jsonl"));
26675
27501
  if (content === null) {
26676
27502
  try {
26677
- const archiveRoot = path37.join(directory, ".swarm", "archive");
26678
- const archiveEntries = await fs13.readdir(archiveRoot);
27503
+ const archiveRoot = path38.join(directory, ".swarm", "archive");
27504
+ const archiveEntries = await fs14.readdir(archiveRoot);
26679
27505
  const archives = archiveEntries.filter((entry) => entry.startsWith("swarm-")).sort();
26680
27506
  for (let index = archives.length - 1;index >= 0 && content === null; index--) {
26681
27507
  content = await readContained(archiveRoot, archives[index], "events.jsonl");
@@ -26718,7 +27544,7 @@ function gatherSkillViolations(directory, sessionId) {
26718
27544
  if (!sessionId)
26719
27545
  return [];
26720
27546
  try {
26721
- const entries = _internals32.readSkillUsageEntriesTail(directory, {
27547
+ const entries = _internals33.readSkillUsageEntriesTail(directory, {
26722
27548
  sessionID: sessionId
26723
27549
  });
26724
27550
  const bySkill = new Map;
@@ -26751,7 +27577,7 @@ async function gatherContradictionCandidates(directory, sessionStart, dedupThres
26751
27577
  if (!Number.isFinite(sessionStartMs))
26752
27578
  return [];
26753
27579
  try {
26754
- const all = await _internals32.readKnowledge(resolveSwarmKnowledgePath(directory));
27580
+ const all = await _internals33.readKnowledge(resolveSwarmKnowledgePath(directory));
26755
27581
  const sessionCreated = all.filter((e) => {
26756
27582
  if (typeof e.created_at !== "string")
26757
27583
  return false;
@@ -26799,7 +27625,7 @@ async function gatherRealtimeAdmissionCounts(directory, sessionStart) {
26799
27625
  if (!Number.isFinite(sessionStartMs))
26800
27626
  return;
26801
27627
  try {
26802
- const entries = await _internals32.readKnowledge(resolveSwarmKnowledgePath(directory));
27628
+ const entries = await _internals33.readKnowledge(resolveSwarmKnowledgePath(directory));
26803
27629
  let admitted = 0;
26804
27630
  let reinforced = 0;
26805
27631
  for (const e of entries) {
@@ -26818,7 +27644,7 @@ async function gatherRealtimeAdmissionCounts(directory, sessionStart) {
26818
27644
  }
26819
27645
  let rejected = 0;
26820
27646
  try {
26821
- const rejectedLessons = await _internals32.readRejectedLessons(directory);
27647
+ const rejectedLessons = await _internals33.readRejectedLessons(directory);
26822
27648
  rejected = rejectedLessons.filter((r) => {
26823
27649
  const ms = Date.parse(r.rejected_at ?? "");
26824
27650
  return Number.isFinite(ms) && ms >= sessionStartMs;
@@ -27132,10 +27958,10 @@ async function runSessionReflection(input) {
27132
27958
  const agentDispatches = gatherAgentDispatches(input.agentSessions);
27133
27959
  const { lessons, taxonomy } = await gatherRetroLessonsAndTaxonomy(input.directory);
27134
27960
  const gateFailures = await gatherGateFailures(input.directory);
27135
- const ledgerRejections = await _internals32.gatherLedgerRejections(input.directory, input.sessionId);
27136
- const skillViolations = _internals32.gatherSkillViolations(input.directory, input.sessionId);
27137
- const contradictionCandidates = await _internals32.gatherContradictionCandidates(input.directory, input.sessionStart, input.dedupThreshold ?? DEFAULT_DEDUP_THRESHOLD2);
27138
- const realtimeCounts = await _internals32.gatherRealtimeAdmissionCounts(input.directory, input.sessionStart);
27961
+ const ledgerRejections = await _internals33.gatherLedgerRejections(input.directory, input.sessionId);
27962
+ const skillViolations = _internals33.gatherSkillViolations(input.directory, input.sessionId);
27963
+ const contradictionCandidates = await _internals33.gatherContradictionCandidates(input.directory, input.sessionStart, input.dedupThreshold ?? DEFAULT_DEDUP_THRESHOLD2);
27964
+ const realtimeCounts = await _internals33.gatherRealtimeAdmissionCounts(input.directory, input.sessionStart);
27139
27965
  const knowledgeDelta = input.knowledgeDelta ? {
27140
27966
  ...input.knowledgeDelta,
27141
27967
  admitted: realtimeCounts?.admitted ?? input.knowledgeDelta.admitted,
@@ -27193,10 +28019,10 @@ async function writeSessionReflection(directory, result) {
27193
28019
  lines.push(result.architectReport);
27194
28020
  const content = lines.join(`
27195
28021
  `);
27196
- await fs13.writeFile(reflectionPath, content, "utf-8");
28022
+ await fs14.writeFile(reflectionPath, content, "utf-8");
27197
28023
  return reflectionPath;
27198
28024
  }
27199
- var _internals32 = {
28025
+ var _internals33 = {
27200
28026
  gatherToolProblems,
27201
28027
  gatherAgentDispatches,
27202
28028
  gatherRetroLessonsAndTaxonomy,
@@ -27216,14 +28042,14 @@ var _internals32 = {
27216
28042
  };
27217
28043
 
27218
28044
  // src/services/skill-improver.ts
27219
- import { existsSync as existsSync20 } from "fs";
28045
+ import { existsSync as existsSync21 } from "fs";
27220
28046
  import { mkdir as mkdir14, readFile as readFile14 } from "fs/promises";
27221
- import * as path39 from "path";
28047
+ import * as path40 from "path";
27222
28048
  init_logger();
27223
28049
 
27224
28050
  // src/services/trajectory-cluster.ts
27225
28051
  import { mkdir as mkdir13, writeFile as writeFile9 } from "fs/promises";
27226
- import * as path38 from "path";
28052
+ import * as path39 from "path";
27227
28053
  init_logger();
27228
28054
  var MACRO_TRAJECTORY_WINDOW = 200;
27229
28055
  var MOTIF_MIN_TASKS = 2;
@@ -27383,14 +28209,14 @@ async function writeMotifProposals(directory, opts = {}) {
27383
28209
  return result;
27384
28210
  const max = opts.maxProposals ?? 10;
27385
28211
  const selected = motifs.slice(0, max);
27386
- const producedAt = _internals33.now().toISOString();
28212
+ const producedAt = _internals34.now().toISOString();
27387
28213
  const candidates = selected.map((motif) => buildMotifCandidate(motif, opts.sessionId));
27388
- const dedupCheck = await _internals33.checkRecommendations(directory, candidates);
28214
+ const dedupCheck = await _internals34.checkRecommendations(directory, candidates);
27389
28215
  const emitted = dedupCheck.decisions.filter((decision) => decision.emit);
27390
28216
  result.duplicatesSuppressed = dedupCheck.decisions.length - emitted.length;
27391
28217
  if (emitted.length === 0)
27392
28218
  return result;
27393
- const proposalsDir = validateSwarmPath(directory, path38.join("skills", "proposals"));
28219
+ const proposalsDir = validateSwarmPath(directory, path39.join("skills", "proposals"));
27394
28220
  await mkdir13(proposalsDir, { recursive: true });
27395
28221
  const written = [];
27396
28222
  for (const decision of emitted) {
@@ -27399,7 +28225,7 @@ async function writeMotifProposals(directory, opts = {}) {
27399
28225
  if (motif === undefined || candidate === undefined)
27400
28226
  continue;
27401
28227
  const slug = `motif-${slugify(motif.signature)}`;
27402
- const filePath = path38.join(proposalsDir, `${slug}.md`);
28228
+ const filePath = path39.join(proposalsDir, `${slug}.md`);
27403
28229
  await writeFile9(filePath, buildMotifProposal(motif, {
27404
28230
  fingerprint: decision.fingerprint,
27405
28231
  producedAt
@@ -27407,7 +28233,7 @@ async function writeMotifProposals(directory, opts = {}) {
27407
28233
  result.proposalsWritten.push(filePath);
27408
28234
  written.push(candidate);
27409
28235
  }
27410
- await _internals33.recordEmittedRecommendations(directory, written, {
28236
+ await _internals34.recordEmittedRecommendations(directory, written, {
27411
28237
  producedAt
27412
28238
  });
27413
28239
  return result;
@@ -27573,14 +28399,14 @@ async function writeSuccessMotifProposals(directory, opts = {}) {
27573
28399
  return result;
27574
28400
  const max = opts.maxProposals ?? 10;
27575
28401
  const selected = motifs.slice(0, max);
27576
- const producedAt = _internals33.now().toISOString();
28402
+ const producedAt = _internals34.now().toISOString();
27577
28403
  const candidates = selected.map((motif) => buildWorkflowCandidate(motif, opts.sessionId));
27578
- const dedupCheck = await _internals33.checkRecommendations(directory, candidates);
28404
+ const dedupCheck = await _internals34.checkRecommendations(directory, candidates);
27579
28405
  const emitted = dedupCheck.decisions.filter((decision) => decision.emit);
27580
28406
  result.duplicatesSuppressed = dedupCheck.decisions.length - emitted.length;
27581
28407
  if (emitted.length === 0)
27582
28408
  return result;
27583
- const proposalsDir = validateSwarmPath(directory, path38.join("skills", "proposals"));
28409
+ const proposalsDir = validateSwarmPath(directory, path39.join("skills", "proposals"));
27584
28410
  await mkdir13(proposalsDir, { recursive: true });
27585
28411
  const written = [];
27586
28412
  for (const decision of emitted) {
@@ -27589,7 +28415,7 @@ async function writeSuccessMotifProposals(directory, opts = {}) {
27589
28415
  if (motif === undefined || candidate === undefined)
27590
28416
  continue;
27591
28417
  const slug = workflowSlug(motif.signature);
27592
- const filePath = path38.join(proposalsDir, `${slug}.md`);
28418
+ const filePath = path39.join(proposalsDir, `${slug}.md`);
27593
28419
  await writeFile9(filePath, buildWorkflowProposal(motif, {
27594
28420
  fingerprint: decision.fingerprint,
27595
28421
  producedAt
@@ -27597,7 +28423,7 @@ async function writeSuccessMotifProposals(directory, opts = {}) {
27597
28423
  result.proposalsWritten.push(filePath);
27598
28424
  written.push(candidate);
27599
28425
  }
27600
- await _internals33.recordEmittedRecommendations(directory, written, {
28426
+ await _internals34.recordEmittedRecommendations(directory, written, {
27601
28427
  producedAt
27602
28428
  });
27603
28429
  return result;
@@ -27606,21 +28432,21 @@ async function writeSuccessMotifProposals(directory, opts = {}) {
27606
28432
  return result;
27607
28433
  }
27608
28434
  }
27609
- var _internals33 = {
28435
+ var _internals34 = {
27610
28436
  now: () => new Date,
27611
28437
  checkRecommendations,
27612
28438
  recordEmittedRecommendations
27613
28439
  };
27614
28440
 
27615
28441
  // src/services/unactionable-hardening.ts
27616
- import { existsSync as existsSync19 } from "fs";
28442
+ import { existsSync as existsSync20 } from "fs";
27617
28443
  init_logger();
27618
28444
  var HARDENING_BATCH_LIMIT = 5;
27619
28445
  async function hardenUnactionableEntries(params) {
27620
28446
  const result = { hardened: 0, retired: 0, remaining: 0 };
27621
28447
  try {
27622
28448
  const queuePath = resolveUnactionablePath(params.directory);
27623
- if (!existsSync19(queuePath))
28449
+ if (!existsSync20(queuePath))
27624
28450
  return result;
27625
28451
  const limit = params.batchLimit ?? HARDENING_BATCH_LIMIT;
27626
28452
  const dedupThreshold = params.dedupThreshold ?? 0.6;
@@ -27724,13 +28550,13 @@ function timestampSlug(d) {
27724
28550
  return d.toISOString().replace(/[:.]/g, "-");
27725
28551
  }
27726
28552
  async function atomicWrite(p, content) {
27727
- await mkdir14(path39.dirname(p), { recursive: true });
28553
+ await mkdir14(path40.dirname(p), { recursive: true });
27728
28554
  await atomicWriteSwarmFile(p, content);
27729
28555
  }
27730
28556
  async function gatherInventory(directory) {
27731
28557
  const swarm = await readKnowledge(resolveSwarmKnowledgePath(directory));
27732
28558
  const hivePath = resolveHiveKnowledgePath2();
27733
- const hive = existsSync20(hivePath) ? await readKnowledge(hivePath) : [];
28559
+ const hive = existsSync21(hivePath) ? await readKnowledge(hivePath) : [];
27734
28560
  const archived = [...swarm, ...hive].filter((e) => e.status === "archived").length;
27735
28561
  const skills = await listSkills(directory);
27736
28562
  const knowledgeById = new Map([...swarm, ...hive].map((entry) => [entry.id, entry]));
@@ -27933,7 +28759,7 @@ async function reconcileStaleActiveSkills(directory, options = {}) {
27933
28759
  continue;
27934
28760
  }
27935
28761
  try {
27936
- const regen = await _internals34.regenerateSkill(directory, skill.slug, {
28762
+ const regen = await _internals35.regenerateSkill(directory, skill.slug, {
27937
28763
  evaluate: false
27938
28764
  });
27939
28765
  if (regen.regenerated) {
@@ -28125,8 +28951,8 @@ async function runSkillImprover(req) {
28125
28951
  }
28126
28952
  throw err;
28127
28953
  }
28128
- const proposalDir = path39.join(req.directory, ".swarm", "skill-improver", "proposals");
28129
- const proposalFile = path39.join(proposalDir, `${timestampSlug(now2)}.md`);
28954
+ const proposalDir = path40.join(req.directory, ".swarm", "skill-improver", "proposals");
28955
+ const proposalFile = path40.join(proposalDir, `${timestampSlug(now2)}.md`);
28130
28956
  const finalBody = source === "llm" ? buildLLMProposalFrame({
28131
28957
  body,
28132
28958
  targets,
@@ -28189,7 +29015,7 @@ async function runSkillImprover(req) {
28189
29015
  autoApply
28190
29016
  };
28191
29017
  }
28192
- var _internals34 = {
29018
+ var _internals35 = {
28193
29019
  runSkillImprover,
28194
29020
  buildDeterministicProposal,
28195
29021
  buildLLMProposalFrame,
@@ -28201,9 +29027,9 @@ var _internals34 = {
28201
29027
  };
28202
29028
 
28203
29029
  // src/services/swarm-residue.ts
28204
- import { createHash as createHash12 } from "crypto";
28205
- import * as fs14 from "fs";
28206
- import * as path40 from "path";
29030
+ import { createHash as createHash13 } from "crypto";
29031
+ import * as fs15 from "fs";
29032
+ import * as path41 from "path";
28207
29033
  var RESIDUE_STALE_AGE_MS = 30 * 60000;
28208
29034
  var MAX_RESIDUE_SCAN_ENTRIES = 20000;
28209
29035
  var RESIDUE_SCAN_DEPTH = 8;
@@ -28213,10 +29039,10 @@ var RESIDUE_SKIP_DIRS = Object.freeze([
28213
29039
  "quarantine",
28214
29040
  "locks"
28215
29041
  ]);
28216
- var _internals35 = {
29042
+ var _internals36 = {
28217
29043
  now: () => Date.now(),
28218
29044
  renameResidueEntry: (from, to) => {
28219
- fs14.renameSync(from, to);
29045
+ fs15.renameSync(from, to);
28220
29046
  },
28221
29047
  queryTracked: (projectRoot, swarmRoot) => {
28222
29048
  const result = bunSpawnSync([
@@ -28225,7 +29051,7 @@ var _internals35 = {
28225
29051
  "core.quotepath=false",
28226
29052
  "ls-files",
28227
29053
  "--",
28228
- swarmRoot.split(path40.sep).join("/")
29054
+ swarmRoot.split(path41.sep).join("/")
28229
29055
  ], {
28230
29056
  cwd: projectRoot,
28231
29057
  stdin: "ignore",
@@ -28243,30 +29069,30 @@ var _internals35 = {
28243
29069
  for (const line of out.split(/\r?\n/)) {
28244
29070
  const t = line.trim();
28245
29071
  if (t)
28246
- tracked.add(path40.normalize(path40.resolve(projectRoot, t)));
29072
+ tracked.add(path41.normalize(path41.resolve(projectRoot, t)));
28247
29073
  }
28248
29074
  return { tracked };
28249
29075
  },
28250
29076
  activeLockTargets: (directory) => {
28251
29077
  const targets = new Set;
28252
29078
  for (const lock of listActiveLocks(directory)) {
28253
- targets.add(path40.normalize(path40.resolve(directory, lock.filePath)));
29079
+ targets.add(path41.normalize(path41.resolve(directory, lock.filePath)));
28254
29080
  }
28255
29081
  return targets;
28256
29082
  },
28257
29083
  sha256File: (absPath) => {
28258
- const hash2 = createHash12("sha256");
28259
- const fd = fs14.openSync(absPath, "r");
29084
+ const hash2 = createHash13("sha256");
29085
+ const fd = fs15.openSync(absPath, "r");
28260
29086
  try {
28261
29087
  const chunk = Buffer.alloc(1024 * 1024);
28262
29088
  for (;; ) {
28263
- const read = fs14.readSync(fd, chunk, 0, chunk.byteLength, null);
29089
+ const read = fs15.readSync(fd, chunk, 0, chunk.byteLength, null);
28264
29090
  if (read === 0)
28265
29091
  break;
28266
29092
  hash2.update(chunk.subarray(0, read));
28267
29093
  }
28268
29094
  } finally {
28269
- fs14.closeSync(fd);
29095
+ fs15.closeSync(fd);
28270
29096
  }
28271
29097
  return hash2.digest("hex");
28272
29098
  }
@@ -28278,10 +29104,10 @@ function collectCandidates(swarmRoot) {
28278
29104
  const walk = (relDir, depth) => {
28279
29105
  if (truncated)
28280
29106
  return;
28281
- const absDir = relDir === "" ? swarmRoot : path40.join(swarmRoot, ...relDir.split("/"));
29107
+ const absDir = relDir === "" ? swarmRoot : path41.join(swarmRoot, ...relDir.split("/"));
28282
29108
  let dirents;
28283
29109
  try {
28284
- dirents = fs14.readdirSync(absDir, { withFileTypes: true });
29110
+ dirents = fs15.readdirSync(absDir, { withFileTypes: true });
28285
29111
  } catch {
28286
29112
  return;
28287
29113
  }
@@ -28305,7 +29131,7 @@ function collectCandidates(swarmRoot) {
28305
29131
  let mtimeMs = 0;
28306
29132
  if (!dirent.isSymbolicLink()) {
28307
29133
  try {
28308
- const st = fs14.lstatSync(path40.join(swarmRoot, ...rel.split("/")));
29134
+ const st = fs15.lstatSync(path41.join(swarmRoot, ...rel.split("/")));
28309
29135
  if (!st.isFile())
28310
29136
  continue;
28311
29137
  bytes = st.size;
@@ -28327,8 +29153,8 @@ function collectCandidates(swarmRoot) {
28327
29153
  return { items, scannedEntries, truncated };
28328
29154
  }
28329
29155
  async function inventorySwarmResidue(directory) {
28330
- const swarmRoot = path40.normalize(path40.resolve(directory, ".swarm"));
28331
- if (!fs14.existsSync(swarmRoot)) {
29156
+ const swarmRoot = path41.normalize(path41.resolve(directory, ".swarm"));
29157
+ if (!fs15.existsSync(swarmRoot)) {
28332
29158
  return {
28333
29159
  swarmRoot,
28334
29160
  scannedEntries: 0,
@@ -28344,15 +29170,15 @@ async function inventorySwarmResidue(directory) {
28344
29170
  gitState: "unknown"
28345
29171
  };
28346
29172
  }
28347
- const rootStat = fs14.lstatSync(swarmRoot);
29173
+ const rootStat = fs15.lstatSync(swarmRoot);
28348
29174
  if (rootStat.isSymbolicLink()) {
28349
29175
  throw new Error(`Refusing to scan a symlinked .swarm root: ${swarmRoot}`);
28350
29176
  }
28351
- const projectRoot = path40.dirname(swarmRoot);
28352
- const { tracked } = _internals35.queryTracked(projectRoot, swarmRoot);
28353
- const lockTargets = _internals35.activeLockTargets(directory);
29177
+ const projectRoot = path41.dirname(swarmRoot);
29178
+ const { tracked } = _internals36.queryTracked(projectRoot, swarmRoot);
29179
+ const lockTargets = _internals36.activeLockTargets(directory);
28354
29180
  const { items, scannedEntries, truncated } = collectCandidates(swarmRoot);
28355
- const now2 = _internals35.now();
29181
+ const now2 = _internals36.now();
28356
29182
  const entries = [];
28357
29183
  for (const item of items) {
28358
29184
  const ageMs = Math.max(0, now2 - item.mtimeMs);
@@ -28360,7 +29186,7 @@ async function inventorySwarmResidue(directory) {
28360
29186
  if (ageMs < RESIDUE_STALE_AGE_MS)
28361
29187
  continue;
28362
29188
  }
28363
- const abs = path40.normalize(path40.join(swarmRoot, ...item.relPath.split("/")));
29189
+ const abs = path41.normalize(path41.join(swarmRoot, ...item.relPath.split("/")));
28364
29190
  const reasons = [];
28365
29191
  if (!item.grammar.quarantineEligible)
28366
29192
  reasons.push("constant-name-grammar");
@@ -28378,7 +29204,7 @@ async function inventorySwarmResidue(directory) {
28378
29204
  }
28379
29205
  if (item.isSymlink)
28380
29206
  reasons.push("symlink");
28381
- const lockHeld = lockTargets.has(abs) || (item.grammar.parsesTarget ? lockTargets.has(path40.normalize(path40.join(path40.dirname(abs), parseTargetBasename(item.relPath.split("/").pop() ?? "") ?? ""))) : false);
29207
+ const lockHeld = lockTargets.has(abs) || (item.grammar.parsesTarget ? lockTargets.has(path41.normalize(path41.join(path41.dirname(abs), parseTargetBasename(item.relPath.split("/").pop() ?? "") ?? ""))) : false);
28382
29208
  if (lockHeld)
28383
29209
  reasons.push("active-lock");
28384
29210
  if (item.bytes > RESIDUE_HASH_MAX_BYTES)
@@ -28386,10 +29212,10 @@ async function inventorySwarmResidue(directory) {
28386
29212
  if (item.grammar.quarantineEligible && item.grammar.parsesTarget) {
28387
29213
  const targetBasename = parseTargetBasename(item.relPath.split("/").pop() ?? "");
28388
29214
  if (targetBasename) {
28389
- const targetAbs = path40.join(path40.dirname(abs), targetBasename);
29215
+ const targetAbs = path41.join(path41.dirname(abs), targetBasename);
28390
29216
  let targetOk = false;
28391
29217
  try {
28392
- targetOk = fs14.lstatSync(targetAbs).isFile();
29218
+ targetOk = fs15.lstatSync(targetAbs).isFile();
28393
29219
  } catch {
28394
29220
  targetOk = false;
28395
29221
  }
@@ -28429,14 +29255,14 @@ async function inventorySwarmResidue(directory) {
28429
29255
  };
28430
29256
  }
28431
29257
  function validateRelPath(rel, what) {
28432
- if (!rel || path40.isAbsolute(rel) || rel.split("/").some((s) => s === ".." || s === "" || /[\0-\x1f]/.test(s))) {
29258
+ if (!rel || path41.isAbsolute(rel) || rel.split("/").some((s) => s === ".." || s === "" || /[\0-\x1f]/.test(s))) {
28433
29259
  throw new Error(`unsafe ${what} in quarantine manifest: ${JSON.stringify(rel)}`);
28434
29260
  }
28435
29261
  return rel;
28436
29262
  }
28437
29263
  function sha256Bounded(absPath) {
28438
29264
  try {
28439
- return _internals35.sha256File(absPath);
29265
+ return _internals36.sha256File(absPath);
28440
29266
  } catch {
28441
29267
  return;
28442
29268
  }
@@ -28454,8 +29280,8 @@ async function quarantineSwarmResidue(directory, options) {
28454
29280
  }
28455
29281
  const swarmRoot = inventory.swarmRoot;
28456
29282
  const batchId = `${new Date().toISOString().replace(/[:.]/g, "-")}-${Math.random().toString(36).slice(2, 10)}`;
28457
- const batchAbs = path40.join(swarmRoot, "quarantine", batchId);
28458
- fs14.mkdirSync(batchAbs, { recursive: true });
29283
+ const batchAbs = path41.join(swarmRoot, "quarantine", batchId);
29284
+ fs15.mkdirSync(batchAbs, { recursive: true });
28459
29285
  const manifest = {
28460
29286
  schema_version: 1,
28461
29287
  batch_id: batchId,
@@ -28465,9 +29291,9 @@ async function quarantineSwarmResidue(directory, options) {
28465
29291
  };
28466
29292
  const moved = [];
28467
29293
  for (const entry of eligible) {
28468
- const abs = path40.join(swarmRoot, ...entry.relPath.split("/"));
29294
+ const abs = path41.join(swarmRoot, ...entry.relPath.split("/"));
28469
29295
  try {
28470
- const st = fs14.lstatSync(abs);
29296
+ const st = fs15.lstatSync(abs);
28471
29297
  if (!st.isFile() || st.size !== entry.bytes || st.mtimeMs !== entry.mtimeMs) {
28472
29298
  preserved.push({
28473
29299
  relPath: entry.relPath,
@@ -28493,10 +29319,10 @@ async function quarantineSwarmResidue(directory, options) {
28493
29319
  });
28494
29320
  continue;
28495
29321
  }
28496
- const storedAbs = path40.join(batchAbs, ...entry.relPath.split("/"));
29322
+ const storedAbs = path41.join(batchAbs, ...entry.relPath.split("/"));
28497
29323
  try {
28498
- fs14.mkdirSync(path40.dirname(storedAbs), { recursive: true });
28499
- _internals35.renameResidueEntry(abs, storedAbs);
29324
+ fs15.mkdirSync(path41.dirname(storedAbs), { recursive: true });
29325
+ _internals36.renameResidueEntry(abs, storedAbs);
28500
29326
  } catch (moveErr) {
28501
29327
  const code = moveErr?.code ?? "unknown";
28502
29328
  preserved.push({
@@ -28508,7 +29334,7 @@ async function quarantineSwarmResidue(directory, options) {
28508
29334
  }
28509
29335
  manifest.entries.push({
28510
29336
  original_rel_path: entry.relPath,
28511
- stored_rel_path: path40.posix.join("quarantine", batchId, entry.relPath),
29337
+ stored_rel_path: path41.posix.join("quarantine", batchId, entry.relPath),
28512
29338
  sha256: sha,
28513
29339
  bytes: entry.bytes,
28514
29340
  mtime_ms: entry.mtimeMs,
@@ -28519,12 +29345,12 @@ async function quarantineSwarmResidue(directory, options) {
28519
29345
  }
28520
29346
  let batchRelDir;
28521
29347
  if (manifest.entries.length > 0) {
28522
- atomicWriteSwarmFileSync(path40.join(batchAbs, "manifest.json"), `${JSON.stringify(manifest, null, 2)}
29348
+ atomicWriteSwarmFileSync(path41.join(batchAbs, "manifest.json"), `${JSON.stringify(manifest, null, 2)}
28523
29349
  `);
28524
- batchRelDir = path40.posix.join("quarantine", batchId);
29350
+ batchRelDir = path41.posix.join("quarantine", batchId);
28525
29351
  } else {
28526
29352
  try {
28527
- fs14.rmSync(batchAbs, { recursive: true, force: true });
29353
+ fs15.rmSync(batchAbs, { recursive: true, force: true });
28528
29354
  } catch {}
28529
29355
  }
28530
29356
  try {
@@ -28552,15 +29378,15 @@ async function quarantineSwarmResidue(directory, options) {
28552
29378
  };
28553
29379
  }
28554
29380
  function listQuarantineBatches(swarmRoot) {
28555
- const quarantineRoot = path40.join(swarmRoot, "quarantine");
29381
+ const quarantineRoot = path41.join(swarmRoot, "quarantine");
28556
29382
  try {
28557
- return fs14.readdirSync(quarantineRoot, { withFileTypes: true }).filter((d) => d.isDirectory() && !d.isSymbolicLink()).map((d) => d.name).sort();
29383
+ return fs15.readdirSync(quarantineRoot, { withFileTypes: true }).filter((d) => d.isDirectory() && !d.isSymbolicLink()).map((d) => d.name).sort();
28558
29384
  } catch {
28559
29385
  return [];
28560
29386
  }
28561
29387
  }
28562
29388
  async function rollbackResidueQuarantine(directory, batchId) {
28563
- const swarmRoot = path40.normalize(path40.resolve(directory, ".swarm"));
29389
+ const swarmRoot = path41.normalize(path41.resolve(directory, ".swarm"));
28564
29390
  const batches = listQuarantineBatches(swarmRoot);
28565
29391
  if (batches.length === 0) {
28566
29392
  throw new Error("No quarantine batches found under .swarm/quarantine/");
@@ -28568,11 +29394,11 @@ async function rollbackResidueQuarantine(directory, batchId) {
28568
29394
  const selected = batchId ? batches.find((b) => b === batchId || b.endsWith(`-${batchId}`)) ?? (() => {
28569
29395
  throw new Error(`Quarantine batch not found: ${batchId}`);
28570
29396
  })() : batches[batches.length - 1];
28571
- const batchAbs = path40.join(swarmRoot, "quarantine", selected);
28572
- const manifestPath = path40.join(batchAbs, "manifest.json");
29397
+ const batchAbs = path41.join(swarmRoot, "quarantine", selected);
29398
+ const manifestPath = path41.join(batchAbs, "manifest.json");
28573
29399
  let manifest;
28574
29400
  try {
28575
- manifest = JSON.parse(fs14.readFileSync(manifestPath, "utf-8"));
29401
+ manifest = JSON.parse(fs15.readFileSync(manifestPath, "utf-8"));
28576
29402
  } catch {
28577
29403
  throw new Error(`Quarantine batch has no readable manifest.json: ${selected}`);
28578
29404
  }
@@ -28584,20 +29410,20 @@ async function rollbackResidueQuarantine(directory, batchId) {
28584
29410
  for (const entry of manifest.entries) {
28585
29411
  const originalRel = validateRelPath(entry.original_rel_path, "original_rel_path");
28586
29412
  const storedRel = validateRelPath(entry.stored_rel_path, "stored_rel_path");
28587
- const originalAbs = path40.join(swarmRoot, ...originalRel.split("/"));
28588
- const storedAbs = path40.join(swarmRoot, ...storedRel.split("/"));
28589
- if (!originalAbs.startsWith(swarmRoot + path40.sep) || !storedAbs.startsWith(batchAbs + path40.sep)) {
29413
+ const originalAbs = path41.join(swarmRoot, ...originalRel.split("/"));
29414
+ const storedAbs = path41.join(swarmRoot, ...storedRel.split("/"));
29415
+ if (!originalAbs.startsWith(swarmRoot + path41.sep) || !storedAbs.startsWith(batchAbs + path41.sep)) {
28590
29416
  throw new Error(`Quarantine manifest path escapes its root: ${selected}`);
28591
29417
  }
28592
- if (!fs14.existsSync(storedAbs)) {
29418
+ if (!fs15.existsSync(storedAbs)) {
28593
29419
  items.push({ relPath: originalRel, status: "missing-copy" });
28594
29420
  allResolved = false;
28595
29421
  continue;
28596
29422
  }
28597
- if (fs14.existsSync(originalAbs)) {
29423
+ if (fs15.existsSync(originalAbs)) {
28598
29424
  const currentSha = sha256Bounded(originalAbs);
28599
29425
  if (currentSha === entry.sha256) {
28600
- fs14.unlinkSync(storedAbs);
29426
+ fs15.unlinkSync(storedAbs);
28601
29427
  items.push({ relPath: originalRel, status: "already-restored" });
28602
29428
  } else {
28603
29429
  items.push({ relPath: originalRel, status: "collision" });
@@ -28605,17 +29431,17 @@ async function rollbackResidueQuarantine(directory, batchId) {
28605
29431
  }
28606
29432
  continue;
28607
29433
  }
28608
- fs14.mkdirSync(path40.dirname(originalAbs), { recursive: true });
28609
- fs14.renameSync(storedAbs, originalAbs);
29434
+ fs15.mkdirSync(path41.dirname(originalAbs), { recursive: true });
29435
+ fs15.renameSync(storedAbs, originalAbs);
28610
29436
  items.push({ relPath: originalRel, status: "restored" });
28611
29437
  }
28612
29438
  if (allResolved) {
28613
29439
  try {
28614
- fs14.rmSync(batchAbs, { recursive: true, force: true });
29440
+ fs15.rmSync(batchAbs, { recursive: true, force: true });
28615
29441
  } catch {}
28616
29442
  }
28617
29443
  return {
28618
- batchRelDir: path40.posix.join("quarantine", selected),
29444
+ batchRelDir: path41.posix.join("quarantine", selected),
28619
29445
  items,
28620
29446
  drained: allResolved
28621
29447
  };
@@ -28668,26 +29494,26 @@ function formatResidueInventoryLines(inv, options) {
28668
29494
  }
28669
29495
 
28670
29496
  // src/session/session-start-store.ts
28671
- import { existsSync as existsSync22, mkdirSync as mkdirSync12, readFileSync as readFileSync16, writeFileSync as writeFileSync8 } from "fs";
28672
- import * as path41 from "path";
29497
+ import { existsSync as existsSync23, mkdirSync as mkdirSync13, readFileSync as readFileSync17, writeFileSync as writeFileSync9 } from "fs";
29498
+ import * as path42 from "path";
28673
29499
  var SESSION_START_FILE = "session-start.jsonl";
28674
29500
  function recordSessionStart(directory, startMs) {
28675
29501
  try {
28676
- const swarmDir = path41.join(directory, ".swarm");
28677
- const sessionDir = path41.join(swarmDir, "session");
28678
- const filePath = path41.join(sessionDir, SESSION_START_FILE);
29502
+ const swarmDir = path42.join(directory, ".swarm");
29503
+ const sessionDir = path42.join(swarmDir, "session");
29504
+ const filePath = path42.join(sessionDir, SESSION_START_FILE);
28679
29505
  const line = JSON.stringify({ startMs, ts: Date.now() });
28680
- mkdirSync12(sessionDir, { recursive: true });
28681
- writeFileSync8(filePath, `${line}
29506
+ mkdirSync13(sessionDir, { recursive: true });
29507
+ writeFileSync9(filePath, `${line}
28682
29508
  `, { flag: "a" });
28683
29509
  } catch {}
28684
29510
  }
28685
29511
  function readEarliestSessionStart(directory) {
28686
29512
  try {
28687
- const filePath = path41.join(directory, ".swarm", "session", SESSION_START_FILE);
28688
- if (!existsSync22(filePath))
29513
+ const filePath = path42.join(directory, ".swarm", "session", SESSION_START_FILE);
29514
+ if (!existsSync23(filePath))
28689
29515
  return null;
28690
- const content = readFileSync16(filePath, "utf-8");
29516
+ const content = readFileSync17(filePath, "utf-8");
28691
29517
  const lines = content.split(`
28692
29518
  `);
28693
29519
  const validStartMs = [];
@@ -28711,8 +29537,8 @@ function readEarliestSessionStart(directory) {
28711
29537
 
28712
29538
  // src/tools/write-retro.ts
28713
29539
  init_zod();
28714
- import { existsSync as existsSync23 } from "fs";
28715
- import path42 from "path";
29540
+ import { existsSync as existsSync24 } from "fs";
29541
+ import path43 from "path";
28716
29542
  async function executeWriteRetro(args, directory) {
28717
29543
  if (/^(CON|PRN|AUX|NUL|COM[0-9]|LPT[0-9])(:|$)/i.test(directory)) {
28718
29544
  return JSON.stringify({
@@ -28720,7 +29546,7 @@ async function executeWriteRetro(args, directory) {
28720
29546
  message: "Invalid directory: reserved device name"
28721
29547
  }, null, 2);
28722
29548
  }
28723
- if (!existsSync23(path42.join(directory, ".swarm"))) {
29549
+ if (!existsSync24(path43.join(directory, ".swarm"))) {
28724
29550
  return JSON.stringify({
28725
29551
  success: false,
28726
29552
  message: `Cannot write evidence in "${directory}" \u2014 no .swarm/ folder was found. Run write_retro from an initialized project root.`
@@ -29071,13 +29897,13 @@ var write_retro = createSwarmTool({
29071
29897
  task_id: args.task_id !== undefined ? String(args.task_id) : undefined,
29072
29898
  metadata: args.metadata
29073
29899
  };
29074
- return await _internals36.executeWriteRetro(writeRetroArgs, directory);
29900
+ return await _internals37.executeWriteRetro(writeRetroArgs, directory);
29075
29901
  } catch {
29076
29902
  return JSON.stringify({ success: false, phase: rawPhase, message: "Invalid arguments" }, null, 2);
29077
29903
  }
29078
29904
  }
29079
29905
  });
29080
- var _internals36 = {
29906
+ var _internals37 = {
29081
29907
  executeWriteRetro,
29082
29908
  write_retro
29083
29909
  };
@@ -29086,9 +29912,9 @@ var _internals36 = {
29086
29912
  init_logger();
29087
29913
 
29088
29914
  // src/workflow/close-terminal.ts
29089
- import { createHash as createHash13 } from "crypto";
29915
+ import { createHash as createHash14 } from "crypto";
29090
29916
  function createCloseTransitionId(planEpoch, taskId, target) {
29091
- const digest = createHash13("sha256").update(JSON.stringify([planEpoch, taskId, target]), "utf8").digest("hex");
29917
+ const digest = createHash14("sha256").update(JSON.stringify([planEpoch, taskId, target]), "utf8").digest("hex");
29092
29918
  return `close-terminal:${digest}`;
29093
29919
  }
29094
29920
  function findTask(plan, taskId) {
@@ -29303,10 +30129,10 @@ async function reconcileCloseTerminalState(directory, targetPlan, options) {
29303
30129
 
29304
30130
  // src/commands/archive-sqlite.ts
29305
30131
  import * as fsSync from "fs";
29306
- import path43 from "path";
30132
+ import path44 from "path";
29307
30133
  var DEFAULT_MAX_SOURCE_BYTES = 2 * 1024 * 1024 * 1024;
29308
30134
  var DEFAULT_BUSY_TIMEOUT_MS = 5000;
29309
- var _internals37 = {
30135
+ var _internals38 = {
29310
30136
  existsSync: fsSync.existsSync,
29311
30137
  statSync: fsSync.statSync,
29312
30138
  renameSync: fsSync.renameSync,
@@ -29316,11 +30142,11 @@ var _internals37 = {
29316
30142
  DatabaseCtor: null
29317
30143
  };
29318
30144
  function resolveDatabaseCtor() {
29319
- return _internals37.DatabaseCtor ?? loadDatabaseCtor();
30145
+ return _internals38.DatabaseCtor ?? loadDatabaseCtor();
29320
30146
  }
29321
30147
  function safeRemoveTemp(tempPath) {
29322
30148
  try {
29323
- _internals37.rmSync(tempPath, {
30149
+ _internals38.rmSync(tempPath, {
29324
30150
  force: true,
29325
30151
  recursive: true,
29326
30152
  maxRetries: 3,
@@ -29376,7 +30202,7 @@ function captureRowCounts(db) {
29376
30202
  async function archiveSqliteSnapshot(opts) {
29377
30203
  const maxSourceBytes = opts.maxSourceBytes ?? DEFAULT_MAX_SOURCE_BYTES;
29378
30204
  const busyTimeoutMs = opts.busyTimeoutMs ?? DEFAULT_BUSY_TIMEOUT_MS;
29379
- if (!_internals37.existsSync(opts.sourcePath)) {
30205
+ if (!_internals38.existsSync(opts.sourcePath)) {
29380
30206
  return {
29381
30207
  requiredness: "required",
29382
30208
  attempt: "not_attempted",
@@ -29389,10 +30215,10 @@ async function archiveSqliteSnapshot(opts) {
29389
30215
  let sourceBytes = 0;
29390
30216
  for (const suffix of ["", "-wal", "-shm"]) {
29391
30217
  const sidecar = opts.sourcePath + suffix;
29392
- if (!_internals37.existsSync(sidecar))
30218
+ if (!_internals38.existsSync(sidecar))
29393
30219
  continue;
29394
30220
  try {
29395
- sourceBytes += _internals37.statSync(sidecar).size;
30221
+ sourceBytes += _internals38.statSync(sidecar).size;
29396
30222
  } catch (err) {
29397
30223
  if (suffix === "") {
29398
30224
  return {
@@ -29418,8 +30244,8 @@ async function archiveSqliteSnapshot(opts) {
29418
30244
  detail: `source bytes ${sourceBytes} > budget ${maxSourceBytes}`
29419
30245
  };
29420
30246
  }
29421
- const destFinal = path43.join(opts.destDir, opts.destName);
29422
- const destTemp = path43.join(opts.destDir, `.${opts.destName}.tmp.${_internals37.now()}.${_internals37.randomSuffix()}`);
30247
+ const destFinal = path44.join(opts.destDir, opts.destName);
30248
+ const destTemp = path44.join(opts.destDir, `.${opts.destName}.tmp.${_internals38.now()}.${_internals38.randomSuffix()}`);
29423
30249
  let Db;
29424
30250
  try {
29425
30251
  Db = resolveDatabaseCtor();
@@ -29518,7 +30344,7 @@ async function archiveSqliteSnapshot(opts) {
29518
30344
  };
29519
30345
  }
29520
30346
  try {
29521
- _internals37.renameSync(destTemp, destFinal);
30347
+ _internals38.renameSync(destTemp, destFinal);
29522
30348
  } catch (err) {
29523
30349
  safeRemoveTemp(destTemp);
29524
30350
  return {
@@ -29618,20 +30444,20 @@ function countSessionKnowledgeEntries(entries, sessionStart, fallbackCount) {
29618
30444
  async function copyDirRecursiveWithFailures(src, dest) {
29619
30445
  let count = 0;
29620
30446
  const failures = [];
29621
- const entries = await fs15.readdir(src);
29622
- await fs15.mkdir(dest, { recursive: true });
30447
+ const entries = await fs16.readdir(src);
30448
+ await fs16.mkdir(dest, { recursive: true });
29623
30449
  for (const entry of entries) {
29624
- const srcEntry = path44.join(src, entry);
29625
- const destEntry = path44.join(dest, entry);
30450
+ const srcEntry = path45.join(src, entry);
30451
+ const destEntry = path45.join(dest, entry);
29626
30452
  try {
29627
- const stat5 = await fs15.stat(srcEntry);
30453
+ const stat5 = await fs16.stat(srcEntry);
29628
30454
  if (stat5.isDirectory()) {
29629
30455
  const subResult = await copyDirRecursiveWithFailures(srcEntry, destEntry);
29630
30456
  count += subResult.copied;
29631
30457
  failures.push(...subResult.failures);
29632
30458
  } else {
29633
30459
  try {
29634
- await fs15.copyFile(srcEntry, destEntry);
30460
+ await fs16.copyFile(srcEntry, destEntry);
29635
30461
  count++;
29636
30462
  } catch (err) {
29637
30463
  const errno = err?.code;
@@ -29684,7 +30510,8 @@ var ARCHIVE_ARTIFACTS = [
29684
30510
  "background-delegations.jsonl",
29685
30511
  "background-delegations.checkpoint.json",
29686
30512
  "background-delegations.manifest.json",
29687
- "background-delegations-health.json"
30513
+ "background-delegations-health.json",
30514
+ "context-telemetry.jsonl"
29688
30515
  ];
29689
30516
  var ACTIVE_STATE_TO_CLEAN = [
29690
30517
  "plan.json",
@@ -29861,20 +30688,20 @@ async function runFinalizeStage(ctx) {
29861
30688
  ctx.warnings.push(`Session retrospective write threw: ${retroError instanceof Error ? retroError.message : String(retroError)}`);
29862
30689
  }
29863
30690
  }
29864
- const lessonsFilePath = path44.join(ctx.swarmDir, "close-lessons.md");
30691
+ const lessonsFilePath = path45.join(ctx.swarmDir, "close-lessons.md");
29865
30692
  try {
29866
- const lessonsText = await fs15.readFile(lessonsFilePath, "utf-8");
30693
+ const lessonsText = await fs16.readFile(lessonsFilePath, "utf-8");
29867
30694
  ctx.explicitLessons = lessonsText.split(`
29868
30695
  `).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#"));
29869
30696
  } catch {}
29870
30697
  try {
29871
- const evidenceDir = path44.join(ctx.swarmDir, "evidence");
29872
- const evidenceEntries = await fs15.readdir(evidenceDir);
30698
+ const evidenceDir = path45.join(ctx.swarmDir, "evidence");
30699
+ const evidenceEntries = await fs16.readdir(evidenceDir);
29873
30700
  const retroDirs = evidenceEntries.filter((e) => e.startsWith("retro-")).sort((a, b) => a.localeCompare(b, undefined, { numeric: true }));
29874
30701
  for (const retroDir of retroDirs) {
29875
- const evidencePath = path44.join(evidenceDir, retroDir, "evidence.json");
30702
+ const evidencePath = path45.join(evidenceDir, retroDir, "evidence.json");
29876
30703
  try {
29877
- const content = await fs15.readFile(evidencePath, "utf-8");
30704
+ const content = await fs16.readFile(evidencePath, "utf-8");
29878
30705
  const parsed = JSON.parse(content);
29879
30706
  const entries = parsed.entries ?? [parsed];
29880
30707
  for (const entry of entries) {
@@ -29908,8 +30735,8 @@ async function runFinalizeStage(ctx) {
29908
30735
  ];
29909
30736
  ctx.curationSucceeded = false;
29910
30737
  try {
29911
- ctx.curationResult = await _internals38.curateAndStoreSwarm(ctx.allLessons, ctx.projectName, { phase_number: 0 }, ctx.directory, ctx.config, {
29912
- llmDelegate: _internals38.createCuratorLLMDelegate(ctx.directory, "phase", ctx.options.sessionID),
30738
+ ctx.curationResult = await _internals39.curateAndStoreSwarm(ctx.allLessons, ctx.projectName, { phase_number: 0 }, ctx.directory, ctx.config, {
30739
+ llmDelegate: _internals39.createCuratorLLMDelegate(ctx.directory, "phase", ctx.options.sessionID),
29913
30740
  enrichmentQuota: {
29914
30741
  maxCalls: ctx.config.enrichment.max_calls_per_day,
29915
30742
  window: ctx.config.enrichment.quota_window
@@ -29922,13 +30749,13 @@ async function runFinalizeStage(ctx) {
29922
30749
  log("[close-command] curateAndStoreSwarm error:", error2);
29923
30750
  }
29924
30751
  if (ctx.curationSucceeded && ctx.allLessons.length > 0) {
29925
- await fs15.unlink(lessonsFilePath).catch(() => {});
30752
+ await fs16.unlink(lessonsFilePath).catch(() => {});
29926
30753
  }
29927
30754
  if (ctx.curationSucceeded) {
29928
30755
  if (ctx.config.hive_enabled === false) {} else {
29929
30756
  try {
29930
30757
  const entries = await readKnowledge(resolveSwarmKnowledgePath(ctx.directory));
29931
- const result = await _internals38.checkHivePromotions(entries, ctx.config, ctx.directory);
30758
+ const result = await _internals39.checkHivePromotions(entries, ctx.config, ctx.directory);
29932
30759
  ctx.hivePromoted = result.new_promotions;
29933
30760
  } catch (hiveErr) {
29934
30761
  const msg = hiveErr instanceof Error ? hiveErr.message : String(hiveErr);
@@ -29949,7 +30776,7 @@ async function runFinalizeStage(ctx) {
29949
30776
  ctx.knowledgeSkillHint = ctx.sessionKnowledgeCreated > 0 ? `${ctx.sessionKnowledgeCreated} knowledge entries created this session. Consider running skill_improve or skill_generate to compile mature entries into skills.` : "";
29950
30777
  if (ctx.runSkillReview) {
29951
30778
  try {
29952
- const { config: loadedConfig } = _internals38.loadPluginConfigWithMeta(ctx.directory);
30779
+ const { config: loadedConfig } = _internals39.loadPluginConfigWithMeta(ctx.directory);
29953
30780
  const skillImproverConfig = SkillImproverConfigSchema.parse(loadedConfig.skill_improver ?? {});
29954
30781
  const skillReviewResult = await runAbortableSkillReview({
29955
30782
  directory: ctx.directory,
@@ -30046,7 +30873,7 @@ async function runFinalizeStage(ctx) {
30046
30873
  let terminalPlanPersisted = !ctx.planExists;
30047
30874
  if (ctx.planExists) {
30048
30875
  try {
30049
- const reconciled = await _internals38.closePlanTerminalState(ctx.directory, ctx.planData, {
30876
+ const reconciled = await _internals39.closePlanTerminalState(ctx.directory, ctx.planData, {
30050
30877
  actor: ctx.options.sessionID ?? "close-command",
30051
30878
  closedPhaseIds: ctx.guaranteeResult.closedPhaseIds,
30052
30879
  requestedClosedTaskIds: ctx.guaranteeResult.closedTaskIds,
@@ -30088,12 +30915,12 @@ async function runFinalizeStage(ctx) {
30088
30915
  }
30089
30916
  }
30090
30917
  try {
30091
- const { CuratorConfigSchema: CCS } = await import("./schema-t8bmshhj.js");
30092
- const { config: pmLoadedConfig } = _internals38.loadPluginConfigWithMeta(ctx.directory);
30918
+ const { CuratorConfigSchema: CCS } = await import("./schema-6rmxzg6g.js");
30919
+ const { config: pmLoadedConfig } = _internals39.loadPluginConfigWithMeta(ctx.directory);
30093
30920
  const curatorCfg = CCS.parse(pmLoadedConfig.curator ?? {});
30094
30921
  if (curatorCfg.enabled && curatorCfg.postmortem_enabled) {
30095
- const pmResult = await _internals38.runCuratorPostMortem(ctx.directory, {
30096
- llmDelegate: _internals38.createCuratorLLMDelegate(ctx.directory, "postmortem", ctx.options.sessionID),
30922
+ const pmResult = await _internals39.runCuratorPostMortem(ctx.directory, {
30923
+ llmDelegate: _internals39.createCuratorLLMDelegate(ctx.directory, "postmortem", ctx.options.sessionID),
30097
30924
  scope: "project",
30098
30925
  sessionID: ctx.options.sessionID
30099
30926
  });
@@ -30112,15 +30939,21 @@ async function runFinalizeStage(ctx) {
30112
30939
  async function runArchiveStage(ctx) {
30113
30940
  ctx.timestamp = new Date().toISOString().replace(/[:.]/g, "-");
30114
30941
  ctx.archiveSuffix = Math.random().toString(36).slice(2, 8);
30115
- ctx.archiveDir = path44.join(ctx.swarmDir, "archive", `swarm-${ctx.timestamp}-${ctx.archiveSuffix}`);
30942
+ ctx.archiveDir = path45.join(ctx.swarmDir, "archive", `swarm-${ctx.timestamp}-${ctx.archiveSuffix}`);
30116
30943
  try {
30117
- await fs15.mkdir(ctx.archiveDir, { recursive: true });
30944
+ await fs16.mkdir(ctx.archiveDir, { recursive: true });
30118
30945
  try {
30119
- await _internals38.flushAndDrainTelemetry();
30946
+ await _internals39.flushAndDrainTelemetry();
30120
30947
  } catch (flushErr) {
30121
30948
  const msg = flushErr instanceof Error ? flushErr.message : String(flushErr);
30122
30949
  ctx.warnings.push(`Telemetry flush before archive failed: ${msg}`);
30123
30950
  }
30951
+ try {
30952
+ _internals39.finalizeContextTelemetry(ctx.directory);
30953
+ } catch (finalizeErr) {
30954
+ const msg = finalizeErr instanceof Error ? finalizeErr.message : String(finalizeErr);
30955
+ ctx.warnings.push(`Context-map telemetry finalize before archive failed: ${msg}`);
30956
+ }
30124
30957
  const linkedKnowledgeShared = isLinked(ctx.directory);
30125
30958
  if (linkedKnowledgeShared) {
30126
30959
  ctx.warnings.push("Worktree is linked: shared knowledge (knowledge.jsonl, knowledge-rejected.jsonl) lives in the link store and is not archived or cleaned by /swarm close. Manage it via the link.");
@@ -30129,8 +30962,8 @@ async function runArchiveStage(ctx) {
30129
30962
  if (linkedKnowledgeShared && KNOWLEDGE_FAMILY_ARTIFACTS.has(artifact)) {
30130
30963
  continue;
30131
30964
  }
30132
- const srcPath = path44.join(ctx.swarmDir, artifact);
30133
- const destPath = path44.join(ctx.archiveDir, artifact);
30965
+ const srcPath = path45.join(ctx.swarmDir, artifact);
30966
+ const destPath = path45.join(ctx.archiveDir, artifact);
30134
30967
  const requiredness = REQUIRED_ARTIFACTS.has(artifact) ? "required" : "optional";
30135
30968
  if (artifact === "swarm.db") {
30136
30969
  const r = await archiveSqliteSnapshot({
@@ -30161,7 +30994,7 @@ async function runArchiveStage(ctx) {
30161
30994
  }
30162
30995
  } else {
30163
30996
  try {
30164
- await fs15.copyFile(srcPath, destPath);
30997
+ await fs16.copyFile(srcPath, destPath);
30165
30998
  ctx.archivedFileCount++;
30166
30999
  if (ACTIVE_STATE_TO_CLEAN.includes(artifact)) {
30167
31000
  ctx.archivedActiveStateFiles.add(artifact);
@@ -30205,12 +31038,12 @@ async function runArchiveStage(ctx) {
30205
31038
  }
30206
31039
  }
30207
31040
  }
30208
- const dynamicArchiveArtifacts = (await fs15.readdir(ctx.swarmDir).catch(() => [])).filter((name) => /^post-mortem-[^/\\]+\.md$/.test(name) || /^drift-report-phase-\d+\.json$/.test(name));
31041
+ const dynamicArchiveArtifacts = (await fs16.readdir(ctx.swarmDir).catch(() => [])).filter((name) => /^post-mortem-[^/\\]+\.md$/.test(name) || /^drift-report-phase-\d+\.json$/.test(name));
30209
31042
  for (const artifact of dynamicArchiveArtifacts) {
30210
- const srcPath = path44.join(ctx.swarmDir, artifact);
30211
- const destPath = path44.join(ctx.archiveDir, artifact);
31043
+ const srcPath = path45.join(ctx.swarmDir, artifact);
31044
+ const destPath = path45.join(ctx.archiveDir, artifact);
30212
31045
  try {
30213
- await fs15.copyFile(srcPath, destPath);
31046
+ await fs16.copyFile(srcPath, destPath);
30214
31047
  ctx.archivedFileCount++;
30215
31048
  ctx.archivedActiveStateFiles.add(artifact);
30216
31049
  ctx.archiveResults.push({
@@ -30252,8 +31085,8 @@ async function runArchiveStage(ctx) {
30252
31085
  }
30253
31086
  }
30254
31087
  for (const dirName of ACTIVE_STATE_DIRS_TO_CLEAN) {
30255
- const srcDir = path44.join(ctx.swarmDir, dirName);
30256
- const destDir = path44.join(ctx.archiveDir, dirName);
31088
+ const srcDir = path45.join(ctx.swarmDir, dirName);
31089
+ const destDir = path45.join(ctx.archiveDir, dirName);
30257
31090
  try {
30258
31091
  const result = await copyDirRecursiveWithFailures(srcDir, destDir);
30259
31092
  ctx.archivedFileCount += result.copied;
@@ -30295,7 +31128,7 @@ async function runArchiveEvidenceRetention(ctx) {
30295
31128
  let cacheMaxBytes;
30296
31129
  let cacheMaxRecords;
30297
31130
  try {
30298
- const { config: evidenceLoadedConfig } = _internals38.loadPluginConfigWithMeta(ctx.directory);
31131
+ const { config: evidenceLoadedConfig } = _internals39.loadPluginConfigWithMeta(ctx.directory);
30299
31132
  const evidenceCfg = evidenceLoadedConfig.evidence ?? {};
30300
31133
  if (typeof evidenceCfg.max_age_days === "number") {
30301
31134
  maxAgeDays = evidenceCfg.max_age_days;
@@ -30311,7 +31144,7 @@ async function runArchiveEvidenceRetention(ctx) {
30311
31144
  }
30312
31145
  } catch {}
30313
31146
  try {
30314
- await _internals38.archiveEvidence(ctx.directory, maxAgeDays, maxBundles, {
31147
+ await _internals39.archiveEvidence(ctx.directory, maxAgeDays, maxBundles, {
30315
31148
  report: true,
30316
31149
  cacheMaxBytes,
30317
31150
  cacheMaxRecords
@@ -30349,14 +31182,14 @@ async function runCleanStage(ctx) {
30349
31182
  }
30350
31183
  continue;
30351
31184
  }
30352
- const filePath = path44.join(ctx.swarmDir, artifact);
31185
+ const filePath = path45.join(ctx.swarmDir, artifact);
30353
31186
  if (artifact === "swarm.db") {
30354
31187
  try {
30355
31188
  closeProjectDb(ctx.directory);
30356
31189
  } catch {}
30357
31190
  }
30358
31191
  try {
30359
- await fs15.unlink(filePath);
31192
+ await fs16.unlink(filePath);
30360
31193
  cleanedFiles.push(artifact);
30361
31194
  } catch (err) {
30362
31195
  const errno = err?.code;
@@ -30374,7 +31207,7 @@ async function runCleanStage(ctx) {
30374
31207
  continue;
30375
31208
  }
30376
31209
  try {
30377
- await fs15.unlink(path44.join(ctx.swarmDir, artifact));
31210
+ await fs16.unlink(path45.join(ctx.swarmDir, artifact));
30378
31211
  cleanedFiles.push(artifact);
30379
31212
  } catch (err) {
30380
31213
  const errno = err?.code;
@@ -30388,18 +31221,18 @@ async function runCleanStage(ctx) {
30388
31221
  if (!ctx.archivedActiveStateDirs.has(dirName)) {
30389
31222
  continue;
30390
31223
  }
30391
- const dirPath = path44.join(ctx.swarmDir, dirName);
31224
+ const dirPath = path45.join(ctx.swarmDir, dirName);
30392
31225
  try {
30393
- await fs15.rm(dirPath, { recursive: true, force: true });
31226
+ await fs16.rm(dirPath, { recursive: true, force: true });
30394
31227
  cleanedFiles.push(`${dirName}/`);
30395
31228
  } catch {}
30396
31229
  }
30397
31230
  try {
30398
- const swarmFiles = await fs15.readdir(ctx.swarmDir);
31231
+ const swarmFiles = await fs16.readdir(ctx.swarmDir);
30399
31232
  const configBackups = swarmFiles.filter((f) => f.startsWith("config-backup-") && f.endsWith(".json"));
30400
31233
  for (const backup of configBackups) {
30401
31234
  try {
30402
- await fs15.unlink(path44.join(ctx.swarmDir, backup));
31235
+ await fs16.unlink(path45.join(ctx.swarmDir, backup));
30403
31236
  configBackupsRemoved++;
30404
31237
  } catch (err) {
30405
31238
  const errno = err?.code;
@@ -30412,7 +31245,7 @@ async function runCleanStage(ctx) {
30412
31245
  const ledgerSiblings = swarmFiles.filter((f) => (f.startsWith("plan-ledger.archived-") || f.startsWith("plan-ledger.backup-")) && f.endsWith(".jsonl"));
30413
31246
  for (const sibling of ledgerSiblings) {
30414
31247
  try {
30415
- await fs15.unlink(path44.join(ctx.swarmDir, sibling));
31248
+ await fs16.unlink(path45.join(ctx.swarmDir, sibling));
30416
31249
  } catch (err) {
30417
31250
  const errno = err?.code;
30418
31251
  if (errno === "ENOENT") {} else {
@@ -30430,16 +31263,16 @@ async function runCleanStage(ctx) {
30430
31263
  }
30431
31264
  let swarmPlanFilesRemoved = 0;
30432
31265
  const candidates = [
30433
- path44.join(ctx.directory, ".swarm", "plan-export", "SWARM_PLAN.json"),
30434
- path44.join(ctx.directory, ".swarm", "plan-export", "SWARM_PLAN.md"),
30435
- path44.join(ctx.directory, ".swarm", "SWARM_PLAN.json"),
30436
- path44.join(ctx.directory, ".swarm", "SWARM_PLAN.md"),
30437
- path44.join(ctx.directory, "SWARM_PLAN.json"),
30438
- path44.join(ctx.directory, "SWARM_PLAN.md")
31266
+ path45.join(ctx.directory, ".swarm", "plan-export", "SWARM_PLAN.json"),
31267
+ path45.join(ctx.directory, ".swarm", "plan-export", "SWARM_PLAN.md"),
31268
+ path45.join(ctx.directory, ".swarm", "SWARM_PLAN.json"),
31269
+ path45.join(ctx.directory, ".swarm", "SWARM_PLAN.md"),
31270
+ path45.join(ctx.directory, "SWARM_PLAN.json"),
31271
+ path45.join(ctx.directory, "SWARM_PLAN.md")
30439
31272
  ];
30440
31273
  for (const candidate of candidates) {
30441
31274
  try {
30442
- await fs15.unlink(candidate);
31275
+ await fs16.unlink(candidate);
30443
31276
  swarmPlanFilesRemoved++;
30444
31277
  } catch (err) {
30445
31278
  if (err?.code !== "ENOENT") {
@@ -30469,7 +31302,7 @@ async function runCleanStage(ctx) {
30469
31302
  }
30470
31303
  for (const terminalFile of TERMINAL_STATE_FILES) {
30471
31304
  try {
30472
- await fs15.unlink(path44.join(ctx.swarmDir, terminalFile));
31305
+ await fs16.unlink(path45.join(ctx.swarmDir, terminalFile));
30473
31306
  if (!cleanedFiles.includes(terminalFile)) {
30474
31307
  cleanedFiles.push(terminalFile);
30475
31308
  }
@@ -30482,7 +31315,7 @@ async function runCleanStage(ctx) {
30482
31315
  }
30483
31316
  }
30484
31317
  clearAllScopes(ctx.directory);
30485
- const contextPath = path44.join(ctx.swarmDir, "context.md");
31318
+ const contextPath = path45.join(ctx.swarmDir, "context.md");
30486
31319
  const contextContent = [
30487
31320
  "# Context",
30488
31321
  "",
@@ -30513,9 +31346,9 @@ async function runAlignStage(ctx) {
30513
31346
  const pruneBranches = ctx.args.includes("--prune-branches");
30514
31347
  let gitAlignResult = "";
30515
31348
  const prunedBranches = [];
30516
- const gitStatus = _internals38.getGitRepositoryStatus(ctx.directory);
31349
+ const gitStatus = _internals39.getGitRepositoryStatus(ctx.directory);
30517
31350
  if (gitStatus.isRepo) {
30518
- const aggressiveResult = await _internals38.resetToMainAfterMerge(ctx.directory, {
31351
+ const aggressiveResult = await _internals39.resetToMainAfterMerge(ctx.directory, {
30519
31352
  pruneBranches
30520
31353
  });
30521
31354
  if (aggressiveResult.success) {
@@ -30527,7 +31360,7 @@ async function runAlignStage(ctx) {
30527
31360
  ctx.warnings.push("Uncommitted changes were discarded during git alignment");
30528
31361
  }
30529
31362
  } else {
30530
- const alignResult = await _internals38.resetToRemoteBranch(ctx.directory, {
31363
+ const alignResult = await _internals39.resetToRemoteBranch(ctx.directory, {
30531
31364
  pruneBranches
30532
31365
  });
30533
31366
  gitAlignResult = alignResult.message;
@@ -30554,16 +31387,16 @@ async function runAlignStage(ctx) {
30554
31387
  return { gitAlignResult, prunedBranches };
30555
31388
  }
30556
31389
  async function runFinalizeDryRun(directory, swarmDir, planData, planExists) {
30557
- const existsInSwarm = (name) => fsSync2.existsSync(path44.join(swarmDir, name));
31390
+ const existsInSwarm = (name) => fsSync2.existsSync(path45.join(swarmDir, name));
30558
31391
  const phases = planData.phases ?? [];
30559
31392
  const nonTerminalPhases = phases.filter((p) => p.status !== "complete" && p.status !== "completed" && p.status !== "blocked" && p.status !== "closed");
30560
31393
  const planAlreadyDone = planExists && phases.length > 0 && nonTerminalPhases.length === 0;
30561
31394
  const wouldArchive = ARCHIVE_ARTIFACTS.filter(existsInSwarm);
30562
- const dynamicArchive = (await fs15.readdir(swarmDir).catch(() => [])).filter((name) => /^post-mortem-[^/\\]+\.md$/.test(name) || /^drift-report-phase-\d+\.json$/.test(name));
31395
+ const dynamicArchive = (await fs16.readdir(swarmDir).catch(() => [])).filter((name) => /^post-mortem-[^/\\]+\.md$/.test(name) || /^drift-report-phase-\d+\.json$/.test(name));
30563
31396
  const wouldArchiveDirs = ACTIVE_STATE_DIRS_TO_CLEAN.filter(existsInSwarm);
30564
31397
  const wouldRemoveTerminal = TERMINAL_STATE_FILES.filter(existsInSwarm);
30565
31398
  const wouldCleanFiles = ACTIVE_STATE_TO_CLEAN.filter((f) => existsInSwarm(f) && !TERMINAL_STATE_FILES.includes(f));
30566
- const gitStatus = _internals38.getGitRepositoryStatus(directory);
31399
+ const gitStatus = _internals39.getGitRepositoryStatus(directory);
30567
31400
  const gitNote = gitStatus.isRepo ? "would align the working tree to main/remote (git reset), pruning merged branches only with --prune-branches" : "would skip git alignment (not a git repository / git unavailable)";
30568
31401
  let residueSection = [];
30569
31402
  try {
@@ -30617,7 +31450,7 @@ async function runFinalizeDryRun(directory, swarmDir, planData, planExists) {
30617
31450
  `);
30618
31451
  }
30619
31452
  async function handleCloseCommand(directory, args, options = {}) {
30620
- const swarmDir = path44.join(directory, ".swarm");
31453
+ const swarmDir = path45.join(directory, ".swarm");
30621
31454
  try {
30622
31455
  const stat5 = fsSync2.lstatSync(swarmDir);
30623
31456
  if (stat5.isSymbolicLink()) {
@@ -30631,43 +31464,43 @@ async function handleCloseCommand(directory, args, options = {}) {
30631
31464
  const planPath = validateSwarmPath(directory, "plan.json");
30632
31465
  let planExists = false;
30633
31466
  let planData = {
30634
- title: path44.basename(directory) || "Ad-hoc session",
31467
+ title: path45.basename(directory) || "Ad-hoc session",
30635
31468
  phases: []
30636
31469
  };
30637
31470
  try {
30638
- const content = await fs15.readFile(planPath, "utf-8");
31471
+ const content = await fs16.readFile(planPath, "utf-8");
30639
31472
  planData = JSON.parse(content);
30640
31473
  planExists = true;
30641
31474
  } catch (error2) {
30642
31475
  if (error2?.code !== "ENOENT") {
30643
31476
  return `\u274C Failed to read plan.json: ${error2 instanceof Error ? error2.message : String(error2)}`;
30644
31477
  }
30645
- const swarmDirExists = await fs15.access(swarmDir).then(() => true).catch(() => false);
31478
+ const swarmDirExists = await fs16.access(swarmDir).then(() => true).catch(() => false);
30646
31479
  if (!swarmDirExists) {
30647
31480
  return `\u274C No .swarm/ directory found in ${directory}. Run /swarm close from the project root, or run /swarm plan first.`;
30648
31481
  }
30649
31482
  }
30650
31483
  if (args.includes("--dry-run")) {
30651
- return _internals38.runFinalizeDryRun(directory, swarmDir, planData, planExists);
31484
+ return _internals39.runFinalizeDryRun(directory, swarmDir, planData, planExists);
30652
31485
  }
30653
31486
  let finalizeLock = {
30654
31487
  acquired: false
30655
31488
  };
30656
- finalizeLock = await _internals38.acquireFinalizeLock(directory);
31489
+ finalizeLock = await _internals39.acquireFinalizeLock(directory);
30657
31490
  if (!finalizeLock.acquired) {
30658
31491
  return `\u274C Another /swarm finalize is already running for this project. If you are certain no other run is active, wait for the lock to expire or remove the stale lock and retry.`;
30659
31492
  }
30660
31493
  try {
30661
31494
  if (!planExists) {
30662
- const archiveDir = path44.join(swarmDir, "archive");
31495
+ const archiveDir = path45.join(swarmDir, "archive");
30663
31496
  try {
30664
- const archiveEntries = await fs15.readdir(archiveDir);
31497
+ const archiveEntries = await fs16.readdir(archiveDir);
30665
31498
  const hasArchiveBundle = archiveEntries.some((entry) => entry.startsWith("swarm-"));
30666
31499
  if (hasArchiveBundle) {
30667
31500
  const hasActiveState = [
30668
31501
  ...ACTIVE_STATE_TO_CLEAN,
30669
31502
  ...ACTIVE_STATE_DIRS_TO_CLEAN
30670
- ].some((entry) => fsSync2.existsSync(path44.join(swarmDir, entry)));
31503
+ ].some((entry) => fsSync2.existsSync(path45.join(swarmDir, entry)));
30671
31504
  if (!hasActiveState) {
30672
31505
  return `\u2705 Already finalized \u2014 nothing to do.
30673
31506
 
@@ -30684,7 +31517,7 @@ This project was already finalized in a previous /swarm close run. The plan has
30684
31517
  if (planExists) {
30685
31518
  planAlreadyDone = phases.length > 0 && phases.every((p) => p.status === "complete" || p.status === "completed" || p.status === "blocked" || p.status === "closed");
30686
31519
  }
30687
- const { config: loadedConfig } = _internals38.loadPluginConfigWithMeta(directory);
31520
+ const { config: loadedConfig } = _internals39.loadPluginConfigWithMeta(directory);
30688
31521
  const config = KnowledgeConfigSchema.parse(loadedConfig.knowledge ?? {});
30689
31522
  const ctx = {
30690
31523
  directory,
@@ -30733,14 +31566,14 @@ This project was already finalized in a previous /swarm close run. The plan has
30733
31566
  archiveSuffix: "",
30734
31567
  args
30735
31568
  };
30736
- ctx.fullAuto = options.sessionID ? _internals38.detectFullAuto(directory, options.sessionID) : false;
31569
+ ctx.fullAuto = options.sessionID ? _internals39.detectFullAuto(directory, options.sessionID) : false;
30737
31570
  await runFinalizeStage(ctx);
30738
31571
  if (ctx.terminalizationError) {
30739
31572
  return `\u274C Close paused before reward, archive, cleanup, teardown, and Git alignment because terminal plan/evidence reconciliation failed: ${ctx.terminalizationError}
30740
31573
 
30741
31574
  No active state was archived or removed. Fix the reported durable-state problem, then retry /swarm close.`;
30742
31575
  }
30743
- await _internals38.runFinalizeRewardSweep({
31576
+ await _internals39.runFinalizeRewardSweep({
30744
31577
  directory,
30745
31578
  closedTaskIds: ctx.guaranteeResult.closedTaskIds,
30746
31579
  memoryConfig: loadedConfig.memory
@@ -30818,9 +31651,9 @@ No active state was archived or removed. Fix the reported durable-state problem,
30818
31651
  try {
30819
31652
  const sessionIdsToEnd = [...swarmState.agentSessions.keys()];
30820
31653
  for (const sessionId of sessionIdsToEnd) {
30821
- _internals38.endAgentSession(sessionId);
31654
+ _internals39.endAgentSession(sessionId);
30822
31655
  }
30823
- _internals38.resetSwarmStatePreservingSingletons();
31656
+ _internals39.resetSwarmStatePreservingSingletons();
30824
31657
  } catch (teardownError) {
30825
31658
  const msg = teardownError instanceof Error ? teardownError.message : String(teardownError);
30826
31659
  ctx.warnings.push(`Session teardown encountered an error after finalization completed (state may not be fully reset): ${msg}`);
@@ -30917,7 +31750,7 @@ function detectFullAuto(directory, sessionID) {
30917
31750
  return false;
30918
31751
  }
30919
31752
  }
30920
- var _internals38 = {
31753
+ var _internals39 = {
30921
31754
  ACTIVE_STATE_DIRS_TO_CLEAN,
30922
31755
  countSessionKnowledgeEntries,
30923
31756
  CLOSE_SKILL_REVIEW_TIMEOUT_MS,
@@ -30946,8 +31779,11 @@ var _internals38 = {
30946
31779
  closePlanTerminalState: reconcileCloseTerminalStateForPlan,
30947
31780
  endAgentSession,
30948
31781
  flushAndDrainTelemetry: async () => {
30949
- const { flushAndDrainTelemetry } = await import("./telemetry-t109dhv7.js");
31782
+ const { flushAndDrainTelemetry } = await import("./telemetry-xzy0qeap.js");
30950
31783
  return flushAndDrainTelemetry();
31784
+ },
31785
+ finalizeContextTelemetry: (directory) => {
31786
+ finalizeContextTelemetry(directory);
30951
31787
  }
30952
31788
  };
30953
31789
 
@@ -31183,14 +32019,14 @@ function buildStatusMessage(session, plan) {
31183
32019
  // src/commands/config.ts
31184
32020
  init_loader();
31185
32021
  import * as os6 from "os";
31186
- import * as path45 from "path";
32022
+ import * as path46 from "path";
31187
32023
  function getUserConfigDir() {
31188
- return process.env.XDG_CONFIG_HOME || path45.join(os6.homedir(), ".config");
32024
+ return process.env.XDG_CONFIG_HOME || path46.join(os6.homedir(), ".config");
31189
32025
  }
31190
32026
  async function handleConfigCommand(directory, _args) {
31191
32027
  const config = loadPluginConfig(directory);
31192
- const userConfigPath = path45.join(getUserConfigDir(), "opencode", "opencode-swarm.json");
31193
- const projectConfigPath = path45.join(directory, ".opencode", "opencode-swarm.json");
32028
+ const userConfigPath = path46.join(getUserConfigDir(), "opencode", "opencode-swarm.json");
32029
+ const projectConfigPath = path46.join(directory, ".opencode", "opencode-swarm.json");
31194
32030
  const lines = [
31195
32031
  "## Swarm Configuration",
31196
32032
  "",
@@ -31211,19 +32047,19 @@ async function handleConfigCommand(directory, _args) {
31211
32047
  init_schema();
31212
32048
 
31213
32049
  // src/services/skill-consolidation.ts
31214
- import { existsSync as existsSync26 } from "fs";
32050
+ import { existsSync as existsSync27 } from "fs";
31215
32051
  import { mkdir as mkdir15, readFile as readFile15 } from "fs/promises";
31216
- import * as path46 from "path";
32052
+ import * as path47 from "path";
31217
32053
  var DEFAULT_CONSOLIDATION_INTERVAL_HOURS = 24;
31218
32054
  var DEFAULT_CONSOLIDATION_MAX_CALLS_PER_RUN = 1;
31219
32055
  var CONSOLIDATION_RUN_TIMEOUT_MS = 5 * 60 * 1000;
31220
32056
  var runningByDirectory = new Map;
31221
32057
  function consolidationStatePath(directory) {
31222
- return path46.join(directory, ".swarm", "skill-improver", "consolidation-state.json");
32058
+ return path47.join(directory, ".swarm", "skill-improver", "consolidation-state.json");
31223
32059
  }
31224
32060
  async function readState2(directory) {
31225
32061
  const filePath = consolidationStatePath(directory);
31226
- if (!existsSync26(filePath))
32062
+ if (!existsSync27(filePath))
31227
32063
  return {};
31228
32064
  try {
31229
32065
  const parsed = JSON.parse(await readFile15(filePath, "utf-8"));
@@ -31235,7 +32071,7 @@ async function readState2(directory) {
31235
32071
  }
31236
32072
  }
31237
32073
  async function atomicWrite2(filePath, content) {
31238
- await mkdir15(path46.dirname(filePath), { recursive: true });
32074
+ await mkdir15(path47.dirname(filePath), { recursive: true });
31239
32075
  await atomicWriteSwarmFile(filePath, content);
31240
32076
  }
31241
32077
  async function writeState2(directory, state) {
@@ -31313,7 +32149,7 @@ async function runSkillConsolidationInner(req) {
31313
32149
  };
31314
32150
  }
31315
32151
  async function runSkillConsolidation(req) {
31316
- const key = path46.resolve(req.directory);
32152
+ const key = path47.resolve(req.directory);
31317
32153
  const existing = runningByDirectory.get(key);
31318
32154
  if (existing) {
31319
32155
  return {
@@ -31401,99 +32237,10 @@ async function handleConsolidateCommand(directory, args, options = {}) {
31401
32237
  }
31402
32238
  }
31403
32239
 
31404
- // src/context-map/telemetry.ts
31405
- import * as fs16 from "fs";
31406
- import * as path47 from "path";
31407
- function isValidTelemetryEntry(value) {
31408
- if (typeof value !== "object" || value === null) {
31409
- return false;
31410
- }
31411
- const obj = value;
31412
- return typeof obj.timestamp === "string" && typeof obj.task_id === "string" && typeof obj.agent_role === "string" && typeof obj.delegation_reason === "string" && typeof obj.token_estimate === "number" && typeof obj.cache_hits === "number" && typeof obj.cache_misses === "number" && typeof obj.stale_entries === "number" && typeof obj.recommended_reads === "number" && typeof obj.skipped_reads === "number" && typeof obj.success === "boolean";
31413
- }
31414
- var _internals39 = {
31415
- appendFileSync: fs16.appendFileSync,
31416
- readFileSync: fs16.readFileSync,
31417
- existsSync: fs16.existsSync,
31418
- mkdirSync: fs16.mkdirSync
31419
- };
31420
- function telemetryFilePath(directory) {
31421
- return path47.join(directory, ".swarm", "context-telemetry.jsonl");
31422
- }
31423
- function readTelemetry(directory) {
31424
- const filePath = telemetryFilePath(directory);
31425
- const entries = [];
31426
- try {
31427
- if (!_internals39.existsSync(filePath)) {
31428
- return entries;
31429
- }
31430
- const raw = _internals39.readFileSync(filePath, "utf-8");
31431
- const lines = raw.split(`
31432
- `);
31433
- for (const line of lines) {
31434
- if (line.trim() === "") {
31435
- continue;
31436
- }
31437
- try {
31438
- const parsed = JSON.parse(line);
31439
- if (isValidTelemetryEntry(parsed)) {
31440
- entries.push(parsed);
31441
- }
31442
- } catch {}
31443
- }
31444
- return entries;
31445
- } catch {
31446
- return entries;
31447
- }
31448
- }
31449
- function getTelemetrySummary(directory) {
31450
- const entries = readTelemetry(directory);
31451
- if (entries.length === 0) {
31452
- return {
31453
- total_delegations: 0,
31454
- total_cache_hits: 0,
31455
- total_cache_misses: 0,
31456
- total_stale_entries: 0,
31457
- avg_token_estimate: 0,
31458
- total_recommended_reads: 0,
31459
- total_skipped_reads: 0,
31460
- success_rate: 0
31461
- };
31462
- }
31463
- let totalCacheHits = 0;
31464
- let totalCacheMisses = 0;
31465
- let totalStaleEntries = 0;
31466
- let totalTokenEstimate = 0;
31467
- let totalRecommendedReads = 0;
31468
- let totalSkippedReads = 0;
31469
- let totalSuccess = 0;
31470
- for (const entry of entries) {
31471
- totalCacheHits += entry.cache_hits;
31472
- totalCacheMisses += entry.cache_misses;
31473
- totalStaleEntries += entry.stale_entries;
31474
- totalTokenEstimate += entry.token_estimate;
31475
- totalRecommendedReads += entry.recommended_reads;
31476
- totalSkippedReads += entry.skipped_reads;
31477
- if (entry.success) {
31478
- totalSuccess++;
31479
- }
31480
- }
31481
- return {
31482
- total_delegations: entries.length,
31483
- total_cache_hits: totalCacheHits,
31484
- total_cache_misses: totalCacheMisses,
31485
- total_stale_entries: totalStaleEntries,
31486
- avg_token_estimate: Math.round(totalTokenEstimate / entries.length),
31487
- total_recommended_reads: totalRecommendedReads,
31488
- total_skipped_reads: totalSkippedReads,
31489
- success_rate: Math.round(totalSuccess / entries.length * 100)
31490
- };
31491
- }
31492
-
31493
32240
  // src/commands/context-map-stats.ts
31494
32241
  async function handleContextMapStatsCommand(directory) {
31495
32242
  const summary = getTelemetrySummary(directory);
31496
- if (summary.total_delegations === 0) {
32243
+ if (summary.total_delegations === 0 && summary.corrupt_entries === 0) {
31497
32244
  return "No capsule telemetry recorded.";
31498
32245
  }
31499
32246
  const pct = (n, d) => d === 0 ? "N/A" : `${(n / d * 100).toFixed(1)}%`;
@@ -31509,6 +32256,15 @@ async function handleContextMapStatsCommand(directory) {
31509
32256
  `**Recommended reads:** ${summary.total_recommended_reads}`,
31510
32257
  `**Skipped reads:** ${summary.total_skipped_reads}`
31511
32258
  ];
32259
+ if (summary.coverage === "partial-unmigrated") {
32260
+ lines.push("", "> Historical context telemetry spans more than the documented read bound and is being migrated in bounded passes; totals above cover only the part already accounted. Run `/swarm context-map stats` again after the store settles for the full lifetime figure.");
32261
+ }
32262
+ if (summary.dropped_entries > 0) {
32263
+ lines.push(`**Dropped (age-pruned raw records, totals unaffected):** ${summary.dropped_entries}`);
32264
+ }
32265
+ if (summary.corrupt_entries > 0) {
32266
+ lines.push(`**Corrupt/partial lines skipped (diagnostics only):** ${summary.corrupt_entries}`);
32267
+ }
31512
32268
  return lines.join(`
31513
32269
  `);
31514
32270
  }
@@ -32352,9 +33108,9 @@ var _internals43 = {
32352
33108
  loadPluginConfigWithMeta,
32353
33109
  loadCuratorDeps: async () => {
32354
33110
  const [{ CuratorConfigSchema }, curator, { createCuratorLLMDelegate: createCuratorLLMDelegate2 }] = await Promise.all([
32355
- import("./schema-t8bmshhj.js"),
32356
- import("./curator-cvy1s7wd.js"),
32357
- import("./curator-llm-factory-6bra0bfd.js")
33111
+ import("./schema-6rmxzg6g.js"),
33112
+ import("./curator-w52frg17.js"),
33113
+ import("./curator-llm-factory-6hgn7p6n.js")
32358
33114
  ]);
32359
33115
  return { CuratorConfigSchema, curator, createCuratorLLMDelegate: createCuratorLLMDelegate2 };
32360
33116
  }
@@ -32854,7 +33610,7 @@ ${USAGE8}`;
32854
33610
  // src/services/diagnose-service.ts
32855
33611
  init_package();
32856
33612
  import * as child_process5 from "child_process";
32857
- import { existsSync as existsSync31, readdirSync as readdirSync6, readFileSync as readFileSync21, statSync as statSync10 } from "fs";
33613
+ import { existsSync as existsSync31, readdirSync as readdirSync6, readFileSync as readFileSync21, statSync as statSync11 } from "fs";
32858
33614
  import * as path52 from "path";
32859
33615
  import { fileURLToPath } from "url";
32860
33616
 
@@ -32963,7 +33719,7 @@ import { readFile as readFile17 } from "fs/promises";
32963
33719
  import { join as join40 } from "path";
32964
33720
 
32965
33721
  // src/services/version-check.ts
32966
- import { existsSync as existsSync29, mkdirSync as mkdirSync15, readFileSync as readFileSync19, writeFileSync as writeFileSync9 } from "fs";
33722
+ import { existsSync as existsSync29, mkdirSync as mkdirSync15, readFileSync as readFileSync19, writeFileSync as writeFileSync10 } from "fs";
32967
33723
  import { homedir as homedir6 } from "os";
32968
33724
  import { join as join39 } from "path";
32969
33725
  var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
@@ -33308,7 +34064,7 @@ async function computeCurationDiagnostics(directory, entries) {
33308
34064
  let scanCompleted = false;
33309
34065
  let scanRemaining = 0;
33310
34066
  try {
33311
- const { getScanStatus } = await import("./scan-cursor-p7t5mb4x.js");
34067
+ const { getScanStatus } = await import("./scan-cursor-snx85enn.js");
33312
34068
  const status = await getScanStatus(directory);
33313
34069
  scanGeneration = status.generation;
33314
34070
  scanCompleted = status.completed;
@@ -33316,19 +34072,19 @@ async function computeCurationDiagnostics(directory, entries) {
33316
34072
  } catch {}
33317
34073
  let configMatch = null;
33318
34074
  try {
33319
- const { isLinked: isLinked2 } = await import("./knowledge-link-8pr02pza.js");
34075
+ const { isLinked: isLinked2 } = await import("./knowledge-link-jkx8xjxp.js");
33320
34076
  if (isLinked2(directory)) {
33321
- const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-t8bmshhj.js");
34077
+ const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-6rmxzg6g.js");
33322
34078
  let config;
33323
34079
  try {
33324
- const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-4vwn66wk.js");
34080
+ const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-5cbbtbvf.js");
33325
34081
  const loaded = loadPluginConfigWithMeta2(directory);
33326
34082
  config = KnowledgeConfigSchema2.parse(loaded.config.knowledge ?? {});
33327
34083
  } catch {
33328
34084
  config = KnowledgeConfigSchema2.parse({});
33329
34085
  }
33330
34086
  const { cohortConfigFingerprint: cohortConfigFingerprint2 } = await import("./config-fingerprint-v22xh5a2.js");
33331
- const { buildConfigFingerprintInput: buildConfigFingerprintInput2, readCohortConfigFingerprint } = await import("./curation-policy-x19e8bqc.js");
34087
+ const { buildConfigFingerprintInput: buildConfigFingerprintInput2, readCohortConfigFingerprint } = await import("./curation-policy-g353f457.js");
33332
34088
  const currentFp = cohortConfigFingerprint2(buildConfigFingerprintInput2(config));
33333
34089
  const cohortFp = await readCohortConfigFingerprint(directory);
33334
34090
  configMatch = cohortFp === null ? null : currentFp === cohortFp;
@@ -33735,7 +34491,7 @@ async function checkConfigBackups(directory) {
33735
34491
  }
33736
34492
  async function checkGitRepository(directory) {
33737
34493
  try {
33738
- if (!existsSync31(directory) || !statSync10(directory).isDirectory()) {
34494
+ if (!existsSync31(directory) || !statSync11(directory).isDirectory()) {
33739
34495
  return {
33740
34496
  name: "Git Repository",
33741
34497
  status: "\u274C",
@@ -34604,7 +35360,7 @@ async function handleDoctorCommand(directory, args) {
34604
35360
  const result = runConfigDoctor(config, directory);
34605
35361
  let output;
34606
35362
  if (enableAutoFix && result.hasAutoFixableIssues) {
34607
- const { runConfigDoctorWithFixes } = await import("./config-doctor-vstrprja.js");
35363
+ const { runConfigDoctorWithFixes } = await import("./config-doctor-578ebqhn.js");
34608
35364
  const fixResult = await runConfigDoctorWithFixes(directory, config, true, {
34609
35365
  applyLossy: true
34610
35366
  });
@@ -35544,7 +36300,7 @@ async function handleEvidenceCommand(directory, args) {
35544
36300
  return formatTaskEvidenceMarkdown(evidenceData);
35545
36301
  }
35546
36302
  async function handleEvidenceSummaryCommand(directory) {
35547
- const { buildEvidenceSummary } = await import("./evidence-summary-service-yhap2xph.js");
36303
+ const { buildEvidenceSummary } = await import("./evidence-summary-service-nj4p6a0d.js");
35548
36304
  const artifact = await buildEvidenceSummary(directory);
35549
36305
  if (!artifact) {
35550
36306
  return "No plan found. Run `/swarm plan` to check plan status.";
@@ -35828,7 +36584,7 @@ init_zod();
35828
36584
 
35829
36585
  // src/mutation/engine.ts
35830
36586
  import { spawnSync as spawnSync4 } from "child_process";
35831
- import { unlinkSync as unlinkSync6, writeFileSync as writeFileSync11 } from "fs";
36587
+ import { unlinkSync as unlinkSync7, writeFileSync as writeFileSync12 } from "fs";
35832
36588
  import * as path57 from "path";
35833
36589
  init_git_executable();
35834
36590
 
@@ -36098,7 +36854,7 @@ async function executeMutation(patch, testCommand, testFiles, workingDir, option
36098
36854
  const safeId = patch.id.replace(/[^a-zA-Z0-9_-]/g, "_");
36099
36855
  patchFile = path57.join(workingDir, `.mutation_patch_${safeId}.diff`);
36100
36856
  try {
36101
- writeFileSync11(patchFile, patch.patch);
36857
+ writeFileSync12(patchFile, patch.patch);
36102
36858
  } catch (writeErr) {
36103
36859
  error2 = `Failed to write patch file: ${writeErr}`;
36104
36860
  outcome = "error";
@@ -36200,7 +36956,7 @@ async function executeMutation(patch, testCommand, testFiles, workingDir, option
36200
36956
  revertError = new Error(`Failed to revert mutation ${patch.id}: ${revertErr}. Working tree may be dirty.`);
36201
36957
  }
36202
36958
  try {
36203
- unlinkSync6(patchFile);
36959
+ unlinkSync7(patchFile);
36204
36960
  } catch (_unlinkErr) {}
36205
36961
  }
36206
36962
  }
@@ -40479,12 +41235,12 @@ var _internals54 = {
40479
41235
 
40480
41236
  // src/session/snapshot-writer.ts
40481
41237
  import {
40482
- closeSync as closeSync8,
41238
+ closeSync as closeSync9,
40483
41239
  existsSync as existsSync38,
40484
41240
  fsyncSync as fsyncSync2,
40485
41241
  mkdirSync as mkdirSync20,
40486
- openSync as openSync8,
40487
- unlinkSync as unlinkSync8
41242
+ openSync as openSync9,
41243
+ unlinkSync as unlinkSync9
40488
41244
  } from "fs";
40489
41245
  import { rename as fsRename } from "fs/promises";
40490
41246
  import * as path64 from "path";
@@ -40648,18 +41404,18 @@ async function writeSnapshot(directory, state) {
40648
41404
  const tempPath = `${resolvedPath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;
40649
41405
  await bunWrite(tempPath, content);
40650
41406
  try {
40651
- const fd = openSync8(tempPath, "r+");
41407
+ const fd = openSync9(tempPath, "r+");
40652
41408
  try {
40653
41409
  fsyncSync2(fd);
40654
41410
  } finally {
40655
- closeSync8(fd);
41411
+ closeSync9(fd);
40656
41412
  }
40657
41413
  } catch {}
40658
41414
  try {
40659
41415
  await renameWithTransientRetry(tempPath, resolvedPath);
40660
41416
  } finally {
40661
41417
  try {
40662
- unlinkSync8(tempPath);
41418
+ unlinkSync9(tempPath);
40663
41419
  } catch {}
40664
41420
  }
40665
41421
  invalidateCachedArtifact(resolvedPath);
@@ -40861,7 +41617,7 @@ async function handleHistoryCommand(directory, _args) {
40861
41617
  }
40862
41618
  // src/knowledge/hive-quarantine.ts
40863
41619
  init_package();
40864
- import { createHash as createHash16, createHmac, randomBytes, randomUUID as randomUUID9 } from "crypto";
41620
+ import { createHash as createHash17, createHmac, randomBytes, randomUUID as randomUUID9 } from "crypto";
40865
41621
  import {
40866
41622
  chmod,
40867
41623
  copyFile as copyFile2,
@@ -40894,7 +41650,7 @@ function serializeCanonical(value) {
40894
41650
  return `{${entries.map(([k, v]) => `${JSON.stringify(k)}:${serializeCanonical(v)}`).join(",")}}`;
40895
41651
  }
40896
41652
  function sha256Hex(content) {
40897
- return createHash16("sha256").update(content, "utf-8").digest("hex");
41653
+ return createHash17("sha256").update(content, "utf-8").digest("hex");
40898
41654
  }
40899
41655
  var QUARANTINE_SECRET_FILE = "hive-quarantine.key";
40900
41656
  async function readQuarantineSecret() {
@@ -43354,7 +44110,7 @@ var MIN_MAX_CYCLES = 1;
43354
44110
  var MAX_MAX_CYCLES = 5;
43355
44111
  async function readLatestLoopState(directory) {
43356
44112
  try {
43357
- const { readdirSync: readdirSync9, statSync: statSync14, readFileSync: readFileSync33 } = await import("fs");
44113
+ const { readdirSync: readdirSync9, statSync: statSync15, readFileSync: readFileSync33 } = await import("fs");
43358
44114
  const loopDir = `${directory}/.swarm/loop`;
43359
44115
  let latestMtime = 0;
43360
44116
  let latestPath = null;
@@ -43365,7 +44121,7 @@ async function readLatestLoopState(directory) {
43365
44121
  continue;
43366
44122
  const statePath = `${loopDir}/${entry.name}/state.json`;
43367
44123
  try {
43368
- const mtime = statSync14(statePath).mtimeMs;
44124
+ const mtime = statSync15(statePath).mtimeMs;
43369
44125
  if (mtime > latestMtime) {
43370
44126
  latestMtime = mtime;
43371
44127
  latestPath = statePath;
@@ -43988,13 +44744,13 @@ function parseJsonObject(candidate) {
43988
44744
  init_schema();
43989
44745
  // src/memory/reflection-service.ts
43990
44746
  import {
43991
- closeSync as closeSync9,
44747
+ closeSync as closeSync10,
43992
44748
  existsSync as existsSync42,
43993
44749
  fstatSync,
43994
- openSync as openSync9,
43995
- readSync as readSync6,
44750
+ openSync as openSync10,
44751
+ readSync as readSync7,
43996
44752
  realpathSync as realpathSync8,
43997
- statSync as statSync15
44753
+ statSync as statSync16
43998
44754
  } from "fs";
43999
44755
  var import_proper_lockfile8 = __toESM(require_proper_lockfile(), 1);
44000
44756
 
@@ -47215,12 +47971,12 @@ var workspaceCache = new Map;
47215
47971
 
47216
47972
  // src/tools/repo-graph/freshness.ts
47217
47973
  init_package();
47218
- import { createHash as createHash17 } from "crypto";
47974
+ import { createHash as createHash18 } from "crypto";
47219
47975
  import * as fsPromises3 from "fs/promises";
47220
47976
  import * as path74 from "path";
47221
47977
  var REPO_GRAPH_FINGERPRINT_FILENAME = "repo-graph.fingerprint.json";
47222
47978
  var FINGERPRINT_SCHEMA_VERSION = 1;
47223
- var EXTRACTOR_STAMP = createHash17("sha256").update(`${package_default.version}\x00${GRAPH_SCHEMA_VERSION}`).digest("hex");
47979
+ var EXTRACTOR_STAMP = createHash18("sha256").update(`${package_default.version}\x00${GRAPH_SCHEMA_VERSION}`).digest("hex");
47224
47980
  var MAX_FINGERPRINT_BYTES = 24 * 1024 * 1024;
47225
47981
  var MAX_FINGERPRINT_ENTRIES = 100256;
47226
47982
  var MAX_RELATIVE_PATH_LENGTH = 4096;
@@ -47244,7 +48000,7 @@ function normalizedExcludes(options) {
47244
48000
  return [...new Set((options?.excludeDirs ?? []).filter(Boolean))].sort((a, b) => a.localeCompare(b));
47245
48001
  }
47246
48002
  function exclusionStamp(options) {
47247
- return createHash17("sha256").update(JSON.stringify({
48003
+ return createHash18("sha256").update(JSON.stringify({
47248
48004
  excludeDirs: normalizedExcludes(options),
47249
48005
  followSymlinks: options?.followSymlinks ?? false
47250
48006
  })).digest("hex");
@@ -47461,12 +48217,12 @@ function readReflectionDigest(directory) {
47461
48217
  return null;
47462
48218
  let fd;
47463
48219
  try {
47464
- fd = openSync9(filePath, "r");
48220
+ fd = openSync10(filePath, "r");
47465
48221
  const size = fstatSync(fd).size;
47466
48222
  if (size <= 0 || size > MAX_INJECTION_READ_BYTES)
47467
48223
  return null;
47468
48224
  const bytes = Buffer.alloc(size);
47469
- const read = readSync6(fd, bytes, 0, size, 0);
48225
+ const read = readSync7(fd, bytes, 0, size, 0);
47470
48226
  if (read !== size)
47471
48227
  return null;
47472
48228
  return JSON.parse(bytes.toString("utf-8"));
@@ -47474,7 +48230,7 @@ function readReflectionDigest(directory) {
47474
48230
  return null;
47475
48231
  } finally {
47476
48232
  if (fd !== undefined)
47477
- closeSync9(fd);
48233
+ closeSync10(fd);
47478
48234
  }
47479
48235
  }
47480
48236
  function readDeadAnchorMemoryIds(directory) {
@@ -48152,7 +48908,7 @@ init_schema();
48152
48908
 
48153
48909
  // src/memory/memory-family-migration.ts
48154
48910
  var import_proper_lockfile9 = __toESM(require_proper_lockfile(), 1);
48155
- import { copyFileSync as copyFileSync4, existsSync as existsSync44, readFileSync as readFileSync34, unlinkSync as unlinkSync10 } from "fs";
48911
+ import { copyFileSync as copyFileSync4, existsSync as existsSync44, readFileSync as readFileSync34, unlinkSync as unlinkSync11 } from "fs";
48156
48912
  import { mkdir as mkdir22, rename as rename8 } from "fs/promises";
48157
48913
  import * as path77 from "path";
48158
48914
  init_logger();
@@ -48415,10 +49171,10 @@ async function mergeStagedSqlite(destStoragePath, stagedPath) {
48415
49171
  }
48416
49172
  db.close();
48417
49173
  try {
48418
- unlinkSync10(stagedPath);
49174
+ unlinkSync11(stagedPath);
48419
49175
  for (const suffix of ["-wal", "-shm"]) {
48420
49176
  try {
48421
- unlinkSync10(`${stagedPath}${suffix}`);
49177
+ unlinkSync11(`${stagedPath}${suffix}`);
48422
49178
  } catch {}
48423
49179
  }
48424
49180
  } catch {}
@@ -53169,7 +53925,7 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
53169
53925
  const absoluteFile = resolveWorkspacePath(file, workingDir);
53170
53926
  const relativeFile = path84.relative(workingDir, absoluteFile);
53171
53927
  const basename20 = path84.basename(absoluteFile);
53172
- const dirname36 = path84.dirname(absoluteFile);
53928
+ const dirname37 = path84.dirname(absoluteFile);
53173
53929
  const preferRelativeOutput = !path84.isAbsolute(file);
53174
53930
  if (isConventionTestFilePath(relativeFile) || isConventionTestFilePath(file)) {
53175
53931
  dedupePush(testFiles, toWorkspaceOutputPath(absoluteFile, workingDir, preferRelativeOutput));
@@ -53185,7 +53941,7 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
53185
53941
  const colocatedCandidates = [
53186
53942
  ...genericTestNames,
53187
53943
  ...languageSpecificTestNames
53188
- ].map((candidateName) => path84.join(dirname36, candidateName));
53944
+ ].map((candidateName) => path84.join(dirname37, candidateName));
53189
53945
  const testDirectoryNames = [
53190
53946
  basename20,
53191
53947
  ...genericTestNames,
@@ -53194,7 +53950,7 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
53194
53950
  const repoLevelDirectories = getRepoLevelCandidateDirectories(workingDir, relativeFile, ext);
53195
53951
  const possibleTestFiles = [
53196
53952
  ...colocatedCandidates,
53197
- ...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) => path84.join(dirname36, dirName, candidateName))),
53953
+ ...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) => path84.join(dirname37, dirName, candidateName))),
53198
53954
  ...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) => path84.join(candidateDir, candidateName)))
53199
53955
  ];
53200
53956
  for (const testFile of possibleTestFiles) {
@@ -55772,7 +56528,7 @@ async function handleQaGatesCommand(directory, args, sessionID) {
55772
56528
 
55773
56529
  // src/workflow/stage-a-repair.ts
55774
56530
  import { appendFile as appendFile10, mkdir as mkdir24, readdir as readdir7 } from "fs/promises";
55775
- import { dirname as dirname36 } from "path";
56531
+ import { dirname as dirname37 } from "path";
55776
56532
  init_logger();
55777
56533
  var MAX_STAGE_A_REPAIR_SCAN = 200;
55778
56534
  var RETRYABLE_EVENT_CODES = new Set(["EBUSY", "EPERM"]);
@@ -55785,7 +56541,7 @@ async function appendStageARepairEvent(directory, payload) {
55785
56541
  `;
55786
56542
  try {
55787
56543
  const eventsPath = validateSwarmPath(directory, "events.jsonl");
55788
- await mkdir24(dirname36(eventsPath), { recursive: true });
56544
+ await mkdir24(dirname37(eventsPath), { recursive: true });
55789
56545
  await appendFile10(eventsPath, line, "utf-8");
55790
56546
  } catch (error2) {
55791
56547
  const code = error2.code;
@@ -57197,7 +57953,7 @@ import * as fs46 from "fs";
57197
57953
  import * as path96 from "path";
57198
57954
 
57199
57955
  // src/review/diff-source.ts
57200
- import { createHash as createHash18 } from "crypto";
57956
+ import { createHash as createHash19 } from "crypto";
57201
57957
  import * as fs40 from "fs";
57202
57958
  import * as path90 from "path";
57203
57959
  init_git_executable();
@@ -57609,7 +58365,7 @@ function uniqueSkipCodes(skipReasons) {
57609
58365
  return [...new Set(skipReasons.map((item) => item.code))].sort();
57610
58366
  }
57611
58367
  function hashManifestPayload(payload) {
57612
- return createHash18("sha256").update(JSON.stringify(payload), "utf8").digest("hex");
58368
+ return createHash19("sha256").update(JSON.stringify(payload), "utf8").digest("hex");
57613
58369
  }
57614
58370
  function parseObjectFormat(stdout) {
57615
58371
  const objectFormat = stdout.trim();
@@ -57697,7 +58453,7 @@ function hashWorkingTreeIdentity(root, rawPath, budget) {
57697
58453
  if (fileBytes > budget.remainingBytes) {
57698
58454
  return deadlineExceeded(`working-tree content identity exceeded the ${WORKTREE_IDENTITY_TOTAL_BYTES}-byte aggregate cap`);
57699
58455
  }
57700
- const hash2 = createHash18("sha256");
58456
+ const hash2 = createHash19("sha256");
57701
58457
  const buffer = Buffer.alloc(64 * 1024);
57702
58458
  let offset = 0;
57703
58459
  while (offset < fileBytes) {
@@ -58277,8 +59033,8 @@ async function collectReviewDiff(options) {
58277
59033
  canonicalText,
58278
59034
  fileListFallback: fileListFallback ?? null
58279
59035
  });
58280
- const scopeHash = createHash18("sha256").update(hashPayload, "utf8").digest("hex");
58281
- const reviewContentHash = createHash18("sha256").update(JSON.stringify({
59036
+ const scopeHash = createHash19("sha256").update(hashPayload, "utf8").digest("hex");
59037
+ const reviewContentHash = createHash19("sha256").update(JSON.stringify({
58282
59038
  selector,
58283
59039
  canonicalText,
58284
59040
  fileListFallback: fileListFallback ?? null
@@ -58791,7 +59547,7 @@ function buildApprovedReceipt(opts) {
58791
59547
  init_schema();
58792
59548
 
58793
59549
  // src/review/finding-validator.ts
58794
- import { createHash as createHash20 } from "crypto";
59550
+ import { createHash as createHash21 } from "crypto";
58795
59551
  init_schema();
58796
59552
  var MAX_VALIDATOR_FALLBACK_MODELS = FALLBACK_MODELS_MAX;
58797
59553
  function canonicalFindingPayload(finding) {
@@ -58817,7 +59573,7 @@ function canonicalizeValidationCandidates(findings) {
58817
59573
  line_start: finding.line_start,
58818
59574
  line_end: finding.line_end
58819
59575
  };
58820
- const findingId = createHash20("sha256").update(canonicalFindingPayload(normalized), "utf8").digest("hex");
59576
+ const findingId = createHash21("sha256").update(canonicalFindingPayload(normalized), "utf8").digest("hex");
58821
59577
  const existing = candidates.get(findingId);
58822
59578
  if (existing) {
58823
59579
  existing.duplicate_count += "duplicate_count" in finding && finding.duplicate_count > 1 ? finding.duplicate_count : 1;
@@ -59098,7 +59854,7 @@ import * as path93 from "path";
59098
59854
  init_git_executable();
59099
59855
 
59100
59856
  // src/hooks/reviewer-scope-file-fingerprint.ts
59101
- import { createHash as createHash21 } from "crypto";
59857
+ import { createHash as createHash22 } from "crypto";
59102
59858
  import * as fs42 from "fs";
59103
59859
  import * as path92 from "path";
59104
59860
  var RETRYABLE_CAPTURE_FAILURE_CODES = new Set([
@@ -59384,7 +60140,7 @@ function captureReviewerScopeFileFingerprint(directory, file, options = {}) {
59384
60140
  retryable: true
59385
60141
  };
59386
60142
  }
59387
- const hash2 = createHash21("sha256");
60143
+ const hash2 = createHash22("sha256");
59388
60144
  const chunk = Buffer.alloc(REVIEWER_SCOPE_CAPTURE_CHUNK_BYTES);
59389
60145
  let totalBytes = 0;
59390
60146
  for (;; ) {
@@ -59904,11 +60660,11 @@ var _internals82 = {
59904
60660
  };
59905
60661
 
59906
60662
  // src/review/evidence.ts
59907
- import { createHash as createHash22 } from "crypto";
60663
+ import { createHash as createHash23 } from "crypto";
59908
60664
  import * as fs44 from "fs";
59909
60665
  import * as path94 from "path";
59910
60666
  function computeAutoReviewManifestHash(manifest) {
59911
- return createHash22("sha256").update(JSON.stringify({
60667
+ return createHash23("sha256").update(JSON.stringify({
59912
60668
  schema_version: manifest.schema_version,
59913
60669
  content_hash: manifest.content_hash,
59914
60670
  plan_requirements_hash: manifest.plan_requirements_hash,
@@ -59995,7 +60751,7 @@ async function computePlanRequirementsHash(directory) {
59995
60751
  return plan ? computeReviewPlanRequirementsHash(plan) : "plan:none";
59996
60752
  }
59997
60753
  function computeAutoReviewPolicyDigest(config) {
59998
- return createHash22("sha256").update(JSON.stringify({
60754
+ return createHash23("sha256").update(JSON.stringify({
59999
60755
  mode: config.final_review.mode,
60000
60756
  min_confidence: config.min_confidence,
60001
60757
  structured_findings: config.structured_findings,
@@ -60041,7 +60797,7 @@ async function loadReviewRequirementsPlan(directory) {
60041
60797
  return replayed.plan;
60042
60798
  }
60043
60799
  function computeReviewPlanRequirementsHash(plan) {
60044
- return createHash22("sha256").update(JSON.stringify({
60800
+ return createHash23("sha256").update(JSON.stringify({
60045
60801
  schema_version: plan.schema_version,
60046
60802
  title: plan.title,
60047
60803
  swarm: plan.swarm,
@@ -62042,25 +62798,25 @@ import {
62042
62798
  existsSync as existsSync56,
62043
62799
  mkdirSync as mkdirSync27,
62044
62800
  readFileSync as readFileSync42,
62045
- renameSync as renameSync14,
62046
- unlinkSync as unlinkSync18,
62047
- writeFileSync as writeFileSync16
62801
+ renameSync as renameSync15,
62802
+ unlinkSync as unlinkSync19,
62803
+ writeFileSync as writeFileSync17
62048
62804
  } from "fs";
62049
62805
  import * as path100 from "path";
62050
62806
 
62051
62807
  // src/services/skill-optimizer/store.ts
62052
- import { createHash as createHash23, randomUUID as randomUUID12 } from "crypto";
62808
+ import { createHash as createHash24, randomUUID as randomUUID12 } from "crypto";
62053
62809
  import {
62054
- closeSync as closeSync16,
62810
+ closeSync as closeSync17,
62055
62811
  existsSync as existsSync55,
62056
62812
  fsyncSync as fsyncSync3,
62057
62813
  mkdirSync as mkdirSync26,
62058
- openSync as openSync16,
62814
+ openSync as openSync17,
62059
62815
  readFileSync as readFileSync41,
62060
- renameSync as renameSync13,
62061
- statSync as statSync19,
62062
- unlinkSync as unlinkSync17,
62063
- writeFileSync as writeFileSync15,
62816
+ renameSync as renameSync14,
62817
+ statSync as statSync20,
62818
+ unlinkSync as unlinkSync18,
62819
+ writeFileSync as writeFileSync16,
62064
62820
  writeFileSync as writeFileSyncAsync
62065
62821
  } from "fs";
62066
62822
  import * as path99 from "path";
@@ -62074,10 +62830,10 @@ function canonicalJson3(value) {
62074
62830
  return `{${entries.map(([k, v]) => `${JSON.stringify(k)}:${canonicalJson3(v)}`).join(",")}}`;
62075
62831
  }
62076
62832
  function computeStateHash(value) {
62077
- return createHash23("sha256").update(canonicalJson3(value), "utf8").digest("hex");
62833
+ return createHash24("sha256").update(canonicalJson3(value), "utf8").digest("hex");
62078
62834
  }
62079
62835
  function computeContentHash2(content) {
62080
- return createHash23("sha256").update(content, "utf8").digest("hex");
62836
+ return createHash24("sha256").update(content, "utf8").digest("hex");
62081
62837
  }
62082
62838
  function computeEventHash(event) {
62083
62839
  return computeStateHash({
@@ -62124,18 +62880,18 @@ function ensureCandidateDir(directory, skillSlug, candidateId2) {
62124
62880
  return dir;
62125
62881
  }
62126
62882
  function writeFileFsyncedThenRename(tempPath, targetPath, data) {
62127
- const fd = openSync16(tempPath, "w");
62883
+ const fd = openSync17(tempPath, "w");
62128
62884
  try {
62129
- writeFileSync15(fd, data, "utf8");
62885
+ writeFileSync16(fd, data, "utf8");
62130
62886
  fsyncSync3(fd);
62131
62887
  } finally {
62132
- closeSync16(fd);
62888
+ closeSync17(fd);
62133
62889
  }
62134
62890
  try {
62135
- renameSync13(tempPath, targetPath);
62891
+ renameSync14(tempPath, targetPath);
62136
62892
  } catch (err) {
62137
62893
  try {
62138
- unlinkSync17(tempPath);
62894
+ unlinkSync18(tempPath);
62139
62895
  } catch {}
62140
62896
  throw err;
62141
62897
  }
@@ -62145,10 +62901,10 @@ var _internals86 = {
62145
62901
  writeFileFsyncedThenRename,
62146
62902
  writeFileSync: writeFileSyncAsync,
62147
62903
  readFileSync: readFileSync41,
62148
- renameSync: renameSync13,
62149
- unlinkSync: unlinkSync17,
62904
+ renameSync: renameSync14,
62905
+ unlinkSync: unlinkSync18,
62150
62906
  existsSync: existsSync55,
62151
- statSync: statSync19
62907
+ statSync: statSync20
62152
62908
  };
62153
62909
  async function appendEvent2(directory, eventInput) {
62154
62910
  assertProjectRoot(directory);
@@ -62407,9 +63163,9 @@ function writeSkillFileAtomic(targetPath, content) {
62407
63163
  }
62408
63164
  }
62409
63165
  var _internals87 = {
62410
- writeFileSync: writeFileSync16,
62411
- renameSync: renameSync14,
62412
- unlinkSync: unlinkSync18
63166
+ writeFileSync: writeFileSync17,
63167
+ renameSync: renameSync15,
63168
+ unlinkSync: unlinkSync19
62413
63169
  };
62414
63170
  async function activateCandidate(input) {
62415
63171
  const skillPath = path100.join(input.directory, ".opencode", "skills", "generated", input.skillSlug, "SKILL.md");
@@ -62498,7 +63254,7 @@ async function rollbackCandidate(input) {
62498
63254
 
62499
63255
  // src/services/skill-optimizer/controller.ts
62500
63256
  import { randomUUID as randomUUID13 } from "crypto";
62501
- import { existsSync as existsSync58, mkdirSync as mkdirSync28, readFileSync as readFileSync44, writeFileSync as writeFileSync17 } from "fs";
63257
+ import { existsSync as existsSync58, mkdirSync as mkdirSync28, readFileSync as readFileSync44, writeFileSync as writeFileSync18 } from "fs";
62502
63258
  import * as path103 from "path";
62503
63259
 
62504
63260
  // src/evaluation/pr-review-recovery.ts
@@ -63183,8 +63939,8 @@ async function prepareCandidatePayloads(inputRoot, candidateId2, skillSlug, base
63183
63939
  mkdirSync28(payloadSubdir, { recursive: true });
63184
63940
  const baselinePayloadRel = path103.join("candidates", candidateId2, "baseline.md");
63185
63941
  const candidatePayloadRel = path103.join("candidates", candidateId2, "candidate.md");
63186
- writeFileSync17(path103.join(payloadSubdir, "baseline.md"), baselineContent, "utf8");
63187
- writeFileSync17(path103.join(payloadSubdir, "candidate.md"), candidateContent, "utf8");
63942
+ writeFileSync18(path103.join(payloadSubdir, "baseline.md"), baselineContent, "utf8");
63943
+ writeFileSync18(path103.join(payloadSubdir, "candidate.md"), candidateContent, "utf8");
63188
63944
  const { computeCandidateInputContentHash: computeCandidateInputContentHash2 } = await import("./hashing-mjwn6j4y.js");
63189
63945
  const baseline = {
63190
63946
  v: 1,
@@ -63429,7 +64185,7 @@ async function runValidationWithTransientRetry(input, candidateContent, baseline
63429
64185
  if (!input.dispatcher) {
63430
64186
  throw new Error("no evaluation dispatcher available (cannot run validation)");
63431
64187
  }
63432
- const { createModelEvaluationExecutor: createModelEvaluationExecutor2 } = await import("./runner-e7z9cf5y.js");
64188
+ const { createModelEvaluationExecutor: createModelEvaluationExecutor2 } = await import("./runner-q7d22d1w.js");
63433
64189
  const executor = createModelEvaluationExecutor2(input.dispatcher, input.sessionId);
63434
64190
  const result = await _internals91.evaluateCandidateV1({
63435
64191
  projectRoot: input.directory,
@@ -63518,7 +64274,7 @@ function writeConvergenceState(directory, nonImprovements) {
63518
64274
  const dir = path103.dirname(path103.join(directory, CONVERGENCE_FILE));
63519
64275
  if (!existsSync58(dir))
63520
64276
  mkdirSync28(dir, { recursive: true });
63521
- writeFileSync17(path103.join(directory, CONVERGENCE_FILE), JSON.stringify({ nonImprovements }), "utf8");
64277
+ writeFileSync18(path103.join(directory, CONVERGENCE_FILE), JSON.stringify({ nonImprovements }), "utf8");
63522
64278
  }
63523
64279
  async function runOptimizationLoop(input) {
63524
64280
  const rounds = [];
@@ -63573,7 +64329,7 @@ async function runOptimizationLoop(input) {
63573
64329
  }
63574
64330
 
63575
64331
  // src/services/skill-optimizer/skill-eval-tasks.ts
63576
- import { existsSync as existsSync59, mkdirSync as mkdirSync29, writeFileSync as writeFileSync18 } from "fs";
64332
+ import { existsSync as existsSync59, mkdirSync as mkdirSync29, writeFileSync as writeFileSync19 } from "fs";
63577
64333
  import * as path104 from "path";
63578
64334
  var DEFAULT_SKILL_EVAL_TASKS = [
63579
64335
  {
@@ -63618,12 +64374,12 @@ function buildSkillEvalTasks(args) {
63618
64374
  if (!existsSync59(taskDir))
63619
64375
  mkdirSync29(taskDir, { recursive: true });
63620
64376
  const instructionPath = path104.join("skill-eval", spec.id, "instruction.md");
63621
- writeFileSync18(path104.join(args.inputRoot, instructionPath), `${spec.instruction}
64377
+ writeFileSync19(path104.join(args.inputRoot, instructionPath), `${spec.instruction}
63622
64378
  `, "utf8");
63623
64379
  const envRelPath = path104.join("skill-eval", spec.id, "environment.md");
63624
- writeFileSync18(path104.join(args.inputRoot, envRelPath), spec.environmentBody, "utf8");
64380
+ writeFileSync19(path104.join(args.inputRoot, envRelPath), spec.environmentBody, "utf8");
63625
64381
  const phraseSpecPath = path104.join("skill-eval", spec.id, "phrase-spec.json");
63626
- writeFileSync18(path104.join(args.inputRoot, phraseSpecPath), JSON.stringify({
64382
+ writeFileSync19(path104.join(args.inputRoot, phraseSpecPath), JSON.stringify({
63627
64383
  required_phrases: spec.requiredPhrases,
63628
64384
  forbidden_phrases: spec.forbiddenPhrases
63629
64385
  }), "utf8");
@@ -65335,7 +66091,7 @@ function buildDetailedHelp(commandName, entry) {
65335
66091
  async function handleHelpCommand(ctx) {
65336
66092
  const targetCommand = ctx.args.join(" ");
65337
66093
  if (!targetCommand) {
65338
- const { buildHelpText } = await import("./index-r46q6996.js");
66094
+ const { buildHelpText } = await import("./index-t798v5pq.js");
65339
66095
  return buildHelpText();
65340
66096
  }
65341
66097
  const tokens = targetCommand.split(/\s+/);
@@ -65344,7 +66100,7 @@ async function handleHelpCommand(ctx) {
65344
66100
  return _internals94.buildDetailedHelp(resolved.key, resolved.entry);
65345
66101
  }
65346
66102
  const similar = _internals94.findSimilarCommands(targetCommand);
65347
- const { buildHelpText: fullHelp } = await import("./index-r46q6996.js");
66103
+ const { buildHelpText: fullHelp } = await import("./index-t798v5pq.js");
65348
66104
  if (similar.length > 0) {
65349
66105
  return `Command '/swarm ${targetCommand}' not found.
65350
66106
 
@@ -65521,7 +66277,7 @@ var COMMAND_REGISTRY = {
65521
66277
  },
65522
66278
  "guardrail explain": {
65523
66279
  handler: async (ctx) => {
65524
- const { handleGuardrailExplain } = await import("./guardrail-explain-h8cnwa02.js");
66280
+ const { handleGuardrailExplain } = await import("./guardrail-explain-rq01z1yz.js");
65525
66281
  return handleGuardrailExplain(ctx.directory, ctx.args);
65526
66282
  },
65527
66283
  description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
@@ -65531,7 +66287,7 @@ var COMMAND_REGISTRY = {
65531
66287
  },
65532
66288
  "guardrail-explain": {
65533
66289
  handler: async (ctx) => {
65534
- const { handleGuardrailExplain } = await import("./guardrail-explain-h8cnwa02.js");
66290
+ const { handleGuardrailExplain } = await import("./guardrail-explain-rq01z1yz.js");
65535
66291
  return handleGuardrailExplain(ctx.directory, ctx.args);
65536
66292
  },
65537
66293
  description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
@@ -65541,7 +66297,7 @@ var COMMAND_REGISTRY = {
65541
66297
  },
65542
66298
  "guardrail-log": {
65543
66299
  handler: async (ctx) => {
65544
- const { handleGuardrailLog } = await import("./guardrail-log-syb7tz2w.js");
66300
+ const { handleGuardrailLog } = await import("./guardrail-log-ratb651f.js");
65545
66301
  return handleGuardrailLog(ctx.directory, ctx.args);
65546
66302
  },
65547
66303
  description: "Read the guardrail decision log (use --blocks-only for blocks)",
@@ -67740,6 +68496,15 @@ Reply with a single fenced JSON block. No prose outside the block.
67740
68496
  "areasOfUncertainty": [
67741
68497
  "What I'm not sure about, in plain language."
67742
68498
  ],
68499
+ "claims": [
68500
+ {
68501
+ "subject": "The specific question or decision this claim is about",
68502
+ "statement": "Your position on that subject, in one or two sentences",
68503
+ "stance": "support",
68504
+ "confidence": 0.8,
68505
+ "evidence": ["URL or source reference, if any"]
68506
+ }
68507
+ ],
67743
68508
  "disagreementTopics": []
67744
68509
  }
67745
68510
  \`\`\`
@@ -67747,6 +68512,7 @@ Reply with a single fenced JSON block. No prose outside the block.
67747
68512
  Notes:
67748
68513
  - \`searchQueries\` is optional \u2014 list queries you would have run if you had web access (the architect uses these for audit), or omit / leave empty if none.
67749
68514
  - \`sources\` MUST come from the RESEARCH CONTEXT only. Copy title/url/snippet/query verbatim. Never invent sources.
68515
+ - \`claims\` is optional but strongly encouraged (max 8): list your key positions as bounded structured claims. Use one of these \`stance\` values exactly: "support" (the position holds), "oppose" (the position is wrong \u2014 a contrary position), "alternative" (a different option is better \u2014 a contrary position), "concern" (risk flagged without taking a side), "neutral" (no position). Claims make contrary positions detectable even without explicit disagreement phrasing.
67750
68516
  - For Round 1: leave \`disagreementTopics\` as []. For Round 2: list the specific disagreement topics this response addresses.`;
67751
68517
  var HARD_RULES = `================================================================
67752
68518
  HARD RULES
@@ -72390,7 +73156,17 @@ async function buildRehydrationCache(directory) {
72390
73156
  }
72391
73157
  }
72392
73158
  const evidenceMap = await readGateEvidenceFromDisk(directory);
72393
- _rehydrationCache = { planTaskStates, evidenceMap };
73159
+ let councilConfig;
73160
+ try {
73161
+ councilConfig = loadPluginConfig(directory).council;
73162
+ } catch {
73163
+ councilConfig = undefined;
73164
+ }
73165
+ _rehydrationCache = {
73166
+ planTaskStates,
73167
+ evidenceMap,
73168
+ taskIdentityContext: { plan, councilConfig }
73169
+ };
72394
73170
  }
72395
73171
  function applyRehydrationCache(session) {
72396
73172
  if (!_rehydrationCache) {
@@ -72405,7 +73181,7 @@ function applyRehydrationCache(session) {
72405
73181
  if (!session.taskCouncilApproved) {
72406
73182
  session.taskCouncilApproved = new Map;
72407
73183
  }
72408
- const { planTaskStates, evidenceMap } = _rehydrationCache;
73184
+ const { planTaskStates, evidenceMap, taskIdentityContext } = _rehydrationCache;
72409
73185
  for (const [taskId, planState] of planTaskStates) {
72410
73186
  const existingState = session.taskWorkflowStates.get(taskId);
72411
73187
  const existingCache = ensureTaskWorkflowCache(session).get(taskId);
@@ -72444,6 +73220,21 @@ function applyRehydrationCache(session) {
72444
73220
  session.taskCouncilApproved.delete(taskId);
72445
73221
  continue;
72446
73222
  }
73223
+ const rawIdentityDigest = council.identity_digest;
73224
+ if (typeof rawIdentityDigest !== "string" || !/^[a-f0-9]{64}$/.test(rawIdentityDigest)) {
73225
+ session.taskCouncilApproved.delete(taskId);
73226
+ continue;
73227
+ }
73228
+ const expectedIdentity = computeCouncilReviewIdentity({
73229
+ level: "task",
73230
+ scope: { kind: "task", taskId },
73231
+ plan: taskIdentityContext.plan,
73232
+ config: taskIdentityContext.councilConfig
73233
+ });
73234
+ if (rawIdentityDigest !== expectedIdentity.identityDigest) {
73235
+ session.taskCouncilApproved.delete(taskId);
73236
+ continue;
73237
+ }
72447
73238
  const councilWorkflow = getTaskWorkflowSnapshot(evidence2);
72448
73239
  if (!councilWorkflow.authoritative || council.workflowGeneration !== councilWorkflow.generation || councilWorkflow.state !== "pre_check_passed") {
72449
73240
  session.taskCouncilApproved.delete(taskId);
@@ -72548,7 +73339,7 @@ function getDisplayBudget() {
72548
73339
  async function rehydratePrSubscriptions(sessionID, directory) {
72549
73340
  const map = new Map;
72550
73341
  try {
72551
- const { listActive: listActive2 } = await import("./pr-subscriptions-2xn238xt.js");
73342
+ const { listActive: listActive2 } = await import("./pr-subscriptions-js5v2xr6.js");
72552
73343
  const records = await listActive2(directory);
72553
73344
  for (const record of records) {
72554
73345
  if (record.sessionID !== sessionID)
@@ -72964,7 +73755,7 @@ function isLaneOwnedByCurrentSession(branchName, expectedSessionId) {
72964
73755
  return extracted === expectedSessionId;
72965
73756
  }
72966
73757
  async function inspectStandardWorktreeCollisionOwnership(identity) {
72967
- const collisionOwnership = await import("./worktree-collision-ownership-2jtg2my1.js");
73758
+ const collisionOwnership = await import("./worktree-collision-ownership-xj0bsg92.js");
72968
73759
  return collisionOwnership.inspectStandardWorktreeCollisionOwnership(identity);
72969
73760
  }
72970
73761
  async function precreateStandardWorktreeSession(args) {
@@ -73112,7 +73903,7 @@ async function precreateStandardWorktreeSession(args) {
73112
73903
  const laneProfile = computeLaneRuntimeProfile(worktreeConfig.runtime_isolation, laneIndex, provisionResult.worktreePath);
73113
73904
  if (laneProfile) {
73114
73905
  try {
73115
- const { writeLaneProfileToDiskReal } = await import("./core-3wzpwe5z.js");
73906
+ const { writeLaneProfileToDiskReal } = await import("./core-2ne03a43.js");
73116
73907
  await writeLaneProfileToDiskReal(provisionResult.worktreePath, laneProfile.laneIndex, laneProfile.envOverrides);
73117
73908
  } catch {}
73118
73909
  }
@@ -73208,7 +73999,7 @@ async function preserveBackgroundWorktreeOwnershipForCallId(callID) {
73208
73999
  }
73209
74000
  const session = Buffer.from(dispatch.handle.sessionId, "utf8").toString("base64url");
73210
74001
  const lane = Buffer.from(dispatch.handle.id, "utf8").toString("base64url");
73211
- const callDigest = createHash24("sha256").update(callID).digest("hex").slice(0, 12);
74002
+ const callDigest = createHash25("sha256").update(callID).digest("hex").slice(0, 12);
73212
74003
  const tag = `swarm-preserved-owner/${session}/${lane}/${callDigest}`;
73213
74004
  let tagProc;
73214
74005
  try {
@@ -73770,7 +74561,7 @@ async function finishStandardWorktreeDispatch(directory, dispatch, config, callI
73770
74561
  }
73771
74562
  clearWorktreeMergeStatus(statusKey);
73772
74563
  try {
73773
- const { removeLaneProfileFromDiskReal } = await import("./core-3wzpwe5z.js");
74564
+ const { removeLaneProfileFromDiskReal } = await import("./core-2ne03a43.js");
73774
74565
  await removeLaneProfileFromDiskReal(dispatch.handle.worktreePath, dispatch.laneIndex);
73775
74566
  } catch {}
73776
74567
  const state = serializationStateBySessionID.get(dispatch.parentSessionID);