opencode-swarm 7.73.3 → 7.74.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -69,7 +69,7 @@ var package_default;
69
69
  var init_package = __esm(() => {
70
70
  package_default = {
71
71
  name: "opencode-swarm",
72
- version: "7.73.3",
72
+ version: "7.74.1",
73
73
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
74
74
  main: "dist/index.js",
75
75
  types: "dist/index.d.ts",
@@ -648,7 +648,7 @@ var init_tool_metadata = __esm(() => {
648
648
  agents: ["architect", "coder"]
649
649
  },
650
650
  knowledge_archive: {
651
- description: "archive (default), quarantine, or purge a swarm knowledge entry by ID with an immutable audit tombstone; purge requires an admin flag",
651
+ description: "archive (default), quarantine, or purge a swarm or hive knowledge entry by ID with an immutable audit tombstone; purge requires an admin flag",
652
652
  agents: ["architect"]
653
653
  },
654
654
  swarm_memory_recall: {
@@ -15921,7 +15921,11 @@ var init_schema = __esm(() => {
15921
15921
  cold_start_max_age_phases: exports_external.number().int().min(0).max(100).default(3),
15922
15922
  synonym_min_cooccurrence: exports_external.number().int().min(1).max(100).default(3),
15923
15923
  synonym_map_max_pairs: exports_external.number().int().min(1).max(1e4).default(500)
15924
- }).optional()
15924
+ }).optional(),
15925
+ enrichment: exports_external.object({
15926
+ max_calls_per_day: exports_external.number().int().min(0).max(1000).default(30),
15927
+ quota_window: exports_external.enum(["utc", "local"]).default("utc")
15928
+ }).default({ max_calls_per_day: 30, quota_window: "utc" })
15925
15929
  });
15926
15930
  MemoryConfigSchema = exports_external.object({
15927
15931
  enabled: exports_external.boolean().default(false),
@@ -15988,7 +15992,7 @@ var init_schema = __esm(() => {
15988
15992
  llm_timeout_ms: exports_external.number().int().min(5000).max(600000).default(300000),
15989
15993
  skill_generation_enabled: exports_external.boolean().default(true),
15990
15994
  skill_generation_mode: exports_external.enum(["draft", "active"]).default("draft"),
15991
- min_skill_confidence: exports_external.number().min(0).max(1).default(0.85),
15995
+ min_skill_confidence: exports_external.number().min(0).max(1).default(0.7),
15992
15996
  min_skill_confirmations: exports_external.number().int().min(1).max(50).default(2)
15993
15997
  });
15994
15998
  ArchitecturalSupervisionConfigSchema = exports_external.object({
@@ -16736,7 +16740,7 @@ var init_plan_schema = __esm(() => {
16736
16740
  init_zod();
16737
16741
  ExecutionProfileSchema = exports_external.object({
16738
16742
  parallelization_enabled: exports_external.boolean().default(false),
16739
- max_concurrent_tasks: exports_external.number().int().min(1).max(64).default(1),
16743
+ max_concurrent_tasks: exports_external.number().int().min(1).max(64).default(10),
16740
16744
  council_parallel: exports_external.boolean().default(true),
16741
16745
  locked: exports_external.boolean().default(false),
16742
16746
  auto_proceed: exports_external.boolean().default(false)
@@ -42662,8 +42666,30 @@ async function buildParallelExecutionGuidance(directory, sessionID, session) {
42662
42666
  }
42663
42667
  const profile = plan.execution_profile;
42664
42668
  const enabled = profile?.parallelization_enabled === true;
42665
- const maxConcurrent = profile?.max_concurrent_tasks ?? 1;
42666
- const effectiveMaxConcurrent = session?.maxConcurrencyOverride ?? maxConcurrent;
42669
+ const maxConcurrent = profile?.max_concurrent_tasks ?? 10;
42670
+ let effectiveMaxConcurrent = session?.maxConcurrencyOverride ?? maxConcurrent;
42671
+ const allTasks = plan.phases.flatMap((phase) => phase.tasks);
42672
+ const blockedTasks = allTasks.filter((task) => {
42673
+ if (task.status !== "blocked")
42674
+ return false;
42675
+ const reason = (task.blocked_reason ?? "").toLowerCase();
42676
+ return reason.includes("fail") || reason.includes("error") || reason.includes("exception");
42677
+ });
42678
+ const totalTasks = allTasks.length;
42679
+ let backoffTriggered = false;
42680
+ if (totalTasks > 0 && blockedTasks.length > 0) {
42681
+ const failureRate = blockedTasks.length / totalTasks;
42682
+ const FAILURE_RATE_THRESHOLD = 0.2;
42683
+ const BACKOFF_MULTIPLIER = 0.5;
42684
+ if (failureRate > FAILURE_RATE_THRESHOLD && blockedTasks.length >= 2) {
42685
+ const newConcurrency = Math.max(1, Math.floor(effectiveMaxConcurrent * BACKOFF_MULTIPLIER));
42686
+ if (newConcurrency < effectiveMaxConcurrent) {
42687
+ effectiveMaxConcurrent = newConcurrency;
42688
+ session.maxConcurrencyOverride = newConcurrency;
42689
+ backoffTriggered = true;
42690
+ }
42691
+ }
42692
+ }
42667
42693
  if (!enabled || effectiveMaxConcurrent <= 1)
42668
42694
  return null;
42669
42695
  if (hasActiveLeanTurbo(sessionID)) {
@@ -42675,7 +42701,6 @@ async function buildParallelExecutionGuidance(directory, sessionID, session) {
42675
42701
  const tasks = currentPhase.tasks;
42676
42702
  if (tasks.length === 0)
42677
42703
  return null;
42678
- const allTasks = plan.phases.flatMap((phase) => phase.tasks);
42679
42704
  const completed = new Set;
42680
42705
  for (const task of allTasks) {
42681
42706
  const taskId = task.id;
@@ -42709,7 +42734,8 @@ async function buildParallelExecutionGuidance(directory, sessionID, session) {
42709
42734
  if (eligible.length === 0) {
42710
42735
  return `[PARALLEL EXECUTION PROFILE] parallelization_enabled=true max_concurrent_tasks=${effectiveMaxConcurrent}; no dependency-ready pending tasks are available for a new coder slot. Continue the current task/gate.`;
42711
42736
  }
42712
- return `[PARALLEL EXECUTION PROFILE] parallelization_enabled=true max_concurrent_tasks=${effectiveMaxConcurrent}; ${occupied.size} slot(s) occupied. Eligible now: ${eligible.join(", ")}. [NEXT] dispatch up to ${availableSlots} eligible coder task(s) before waiting; preserve ONE task per coder call and call declare_scope for each task.`;
42737
+ const failureWarning = backoffTriggered ? ` (${blockedTasks.length} blocked task(s) detected concurrency auto-reduced due to failures)` : "";
42738
+ return `[PARALLEL EXECUTION PROFILE] parallelization_enabled=true max_concurrent_tasks=${effectiveMaxConcurrent}; ${occupied.size} slot(s) occupied. Eligible now: ${eligible.join(", ")}. [NEXT] dispatch up to ${availableSlots} eligible coder task(s) before waiting; preserve ONE task per coder call and call declare_scope for each task.${failureWarning}`;
42713
42739
  }
42714
42740
  function isParallelGuidancePhaseComplete(phase) {
42715
42741
  return phase.status === "complete" || phase.status === "completed" || phase.status === "closed";
@@ -42873,7 +42899,7 @@ function createDelegationGateHook(config2, directory) {
42873
42899
  return;
42874
42900
  const profile = plan.execution_profile;
42875
42901
  const parallelEnabled = profile?.parallelization_enabled === true;
42876
- const maxConcurrent = profile?.max_concurrent_tasks ?? 1;
42902
+ const maxConcurrent = profile?.max_concurrent_tasks ?? 10;
42877
42903
  const effectiveMaxConcurrent = session.maxConcurrencyOverride ?? maxConcurrent;
42878
42904
  if (!parallelEnabled || effectiveMaxConcurrent <= 1)
42879
42905
  return;
@@ -59501,7 +59527,7 @@ async function appendKnowledgeWithCapEnforcement(filePath, entry, maxEntries) {
59501
59527
  return transactKnowledge(filePath, (entries) => {
59502
59528
  const updated = [...entries, entry];
59503
59529
  if (updated.length > maxEntries) {
59504
- return updated.slice(updated.length - maxEntries);
59530
+ return selectKnowledgeCapSurvivors(updated, maxEntries);
59505
59531
  }
59506
59532
  return updated;
59507
59533
  });
@@ -59510,8 +59536,45 @@ async function enforceKnowledgeCap(filePath, maxEntries) {
59510
59536
  await transactKnowledge(filePath, (entries) => {
59511
59537
  if (entries.length <= maxEntries)
59512
59538
  return null;
59513
- return entries.slice(entries.length - maxEntries);
59539
+ return selectKnowledgeCapSurvivors(entries, maxEntries);
59540
+ });
59541
+ }
59542
+ function selectKnowledgeCapSurvivors(entries, maxEntries) {
59543
+ if (entries.length <= maxEntries)
59544
+ return entries;
59545
+ if (maxEntries <= 0)
59546
+ return [];
59547
+ const candidates = entries.map((entry, index) => {
59548
+ const maybeKnowledge = entry;
59549
+ return {
59550
+ entry,
59551
+ index,
59552
+ status: maybeKnowledge.status,
59553
+ outcomeSignal: computeOutcomeSignal(maybeKnowledge.retrieval_outcomes)
59554
+ };
59514
59555
  });
59556
+ const allPromoted = candidates.every((c) => c.status === "promoted");
59557
+ const evictable = allPromoted ? candidates : candidates.filter((c) => c.status !== "promoted");
59558
+ const targetDropCount = entries.length - maxEntries;
59559
+ const dropCount = Math.min(targetDropCount, evictable.length);
59560
+ if (dropCount <= 0)
59561
+ return entries;
59562
+ const drop = new Set([...evictable].sort((a, b) => {
59563
+ const inactiveDelta = getKnowledgeCapStatusPriority(a.status) - getKnowledgeCapStatusPriority(b.status);
59564
+ if (inactiveDelta !== 0)
59565
+ return inactiveDelta;
59566
+ const signalDelta = a.outcomeSignal - b.outcomeSignal;
59567
+ if (signalDelta !== 0)
59568
+ return signalDelta;
59569
+ return a.index - b.index;
59570
+ }).slice(0, dropCount).map((c) => c.index));
59571
+ return candidates.filter((c) => !drop.has(c.index)).map((c) => c.entry);
59572
+ }
59573
+ function getKnowledgeCapStatusPriority(status) {
59574
+ if (status === "archived" || status === "quarantined" || status === "quarantined_unactionable") {
59575
+ return 0;
59576
+ }
59577
+ return 1;
59515
59578
  }
59516
59579
  async function sweepAgedEntries(filePath, defaultMaxPhases) {
59517
59580
  const result = {
@@ -59748,6 +59811,7 @@ var init_knowledge_store = __esm(() => {
59748
59811
  findNearDuplicate,
59749
59812
  computeConfidence,
59750
59813
  computeOutcomeSignal,
59814
+ selectKnowledgeCapSurvivors,
59751
59815
  inferTags,
59752
59816
  bumpKnowledgeConfidenceBatch
59753
59817
  };
@@ -59758,6 +59822,7 @@ var exports_knowledge_events = {};
59758
59822
  __export(exports_knowledge_events, {
59759
59823
  resolveLegacyApplicationLogPath: () => resolveLegacyApplicationLogPath,
59760
59824
  resolveKnowledgeEventsPath: () => resolveKnowledgeEventsPath,
59825
+ resolveKnowledgeCounterBaselinePath: () => resolveKnowledgeCounterBaselinePath,
59761
59826
  recordKnowledgeEvent: () => recordKnowledgeEvent,
59762
59827
  recomputeCounters: () => recomputeCounters,
59763
59828
  readLegacyApplicationRecords: () => readLegacyApplicationRecords,
@@ -59778,11 +59843,14 @@ __export(exports_knowledge_events, {
59778
59843
  });
59779
59844
  import { randomUUID as randomUUID2 } from "node:crypto";
59780
59845
  import { existsSync as existsSync15 } from "node:fs";
59781
- import { appendFile as appendFile4, mkdir as mkdir4, readFile as readFile5, writeFile as writeFile3 } from "node:fs/promises";
59846
+ import { appendFile as appendFile4, mkdir as mkdir4, readFile as readFile5, stat as stat3 } from "node:fs/promises";
59782
59847
  import * as path32 from "node:path";
59783
59848
  function resolveKnowledgeEventsPath(directory) {
59784
59849
  return path32.join(directory, ".swarm", "knowledge-events.jsonl");
59785
59850
  }
59851
+ function resolveKnowledgeCounterBaselinePath(directory) {
59852
+ return path32.join(directory, ".swarm", "knowledge-counter-baseline.json");
59853
+ }
59786
59854
  function resolveLegacyApplicationLogPath(directory) {
59787
59855
  return path32.join(directory, ".swarm", "knowledge-application.jsonl");
59788
59856
  }
@@ -59817,10 +59885,12 @@ async function appendKnowledgeEvent(directory, event) {
59817
59885
  const lines = content.split(`
59818
59886
  `).filter((line) => line.trim().length > 0);
59819
59887
  if (lines.length > MAX_EVENT_LOG_ENTRIES) {
59888
+ const evicted = lines.slice(0, lines.length - MAX_EVENT_LOG_ENTRIES);
59820
59889
  const trimmed = lines.slice(lines.length - MAX_EVENT_LOG_ENTRIES);
59821
- await writeFile3(filePath, `${trimmed.join(`
59890
+ await foldEvictedEventsIntoBaseline(directory, evicted, filePath);
59891
+ await atomicWriteFile(filePath, `${trimmed.join(`
59822
59892
  `)}
59823
- `, "utf-8");
59893
+ `);
59824
59894
  }
59825
59895
  } catch (err2) {
59826
59896
  warn(`[knowledge-events] local cap trim failed (non-fatal): ${err2 instanceof Error ? err2.message : String(err2)}`);
@@ -59844,19 +59914,8 @@ async function readKnowledgeEvents(directory) {
59844
59914
  if (!existsSync15(filePath))
59845
59915
  return [];
59846
59916
  const content = await readFile5(filePath, "utf-8");
59847
- const out2 = [];
59848
- for (const line of content.split(`
59849
- `)) {
59850
- const trimmed = line.trim();
59851
- if (!trimmed)
59852
- continue;
59853
- try {
59854
- out2.push(JSON.parse(trimmed));
59855
- } catch {
59856
- warn(`[knowledge-events] Skipping corrupted JSONL line in ${filePath}: ${trimmed.slice(0, 80)}`);
59857
- }
59858
- }
59859
- return out2;
59917
+ return parseEventLines(content.split(`
59918
+ `), filePath);
59860
59919
  }
59861
59920
  async function readLegacyApplicationRecords(directory) {
59862
59921
  const filePath = resolveLegacyApplicationLogPath(directory);
@@ -59892,6 +59951,49 @@ function emptyRollup() {
59892
59951
  violation_timestamps: []
59893
59952
  };
59894
59953
  }
59954
+ function cloneRollup(input) {
59955
+ return {
59956
+ ...emptyRollup(),
59957
+ ...input,
59958
+ violation_timestamps: [...input.violation_timestamps ?? []]
59959
+ };
59960
+ }
59961
+ function cloneRollupMap(input) {
59962
+ const out2 = new Map;
59963
+ for (const [id, rollup] of input) {
59964
+ out2.set(id, cloneRollup(rollup));
59965
+ }
59966
+ return out2;
59967
+ }
59968
+ function normalizeRollupTimestamps(rollup) {
59969
+ if (rollup.violation_timestamps.length > 1) {
59970
+ rollup.violation_timestamps.sort((a, b) => a < b ? 1 : a > b ? -1 : 0);
59971
+ }
59972
+ if (rollup.violation_timestamps.length > MAX_VIOLATION_TIMESTAMPS) {
59973
+ rollup.violation_timestamps = rollup.violation_timestamps.slice(0, MAX_VIOLATION_TIMESTAMPS);
59974
+ }
59975
+ return rollup;
59976
+ }
59977
+ function mergeRollupInto(target, source) {
59978
+ target.shown_count += source.shown_count ?? 0;
59979
+ target.acknowledged_count += source.acknowledged_count ?? 0;
59980
+ target.applied_explicit_count += source.applied_explicit_count ?? 0;
59981
+ target.ignored_count += source.ignored_count ?? 0;
59982
+ target.violated_count += source.violated_count ?? 0;
59983
+ target.contradicted_count += source.contradicted_count ?? 0;
59984
+ target.n_a_count += source.n_a_count ?? 0;
59985
+ target.succeeded_after_shown_count += source.succeeded_after_shown_count ?? 0;
59986
+ target.failed_after_shown_count += source.failed_after_shown_count ?? 0;
59987
+ target.partial_after_shown_count += source.partial_after_shown_count ?? 0;
59988
+ if (source.last_applied_at) {
59989
+ target.last_applied_at = maxIso(target.last_applied_at, source.last_applied_at);
59990
+ }
59991
+ if (source.last_acknowledged_at) {
59992
+ target.last_acknowledged_at = maxIso(target.last_acknowledged_at, source.last_acknowledged_at);
59993
+ }
59994
+ target.violation_timestamps.push(...source.violation_timestamps ?? []);
59995
+ normalizeRollupTimestamps(target);
59996
+ }
59895
59997
  function get(map3, id) {
59896
59998
  let r = map3.get(id);
59897
59999
  if (!r) {
@@ -59905,9 +60007,91 @@ function maxIso(current, candidate) {
59905
60007
  return candidate;
59906
60008
  return candidate > current ? candidate : current;
59907
60009
  }
59908
- function recomputeCounters(events, legacyRecords = []) {
60010
+ async function readCounterBaseline(directory) {
60011
+ const filePath = resolveKnowledgeCounterBaselinePath(directory);
60012
+ if (!existsSync15(filePath))
60013
+ return new Map;
60014
+ const raw = JSON.parse(await readFile5(filePath, "utf-8"));
60015
+ const map3 = new Map;
60016
+ for (const [id, rollup] of Object.entries(raw)) {
60017
+ map3.set(id, normalizeRollupTimestamps(cloneRollup(rollup)));
60018
+ }
60019
+ return map3;
60020
+ }
60021
+ async function writeCounterBaseline(directory, baseline) {
60022
+ const filePath = resolveKnowledgeCounterBaselinePath(directory);
60023
+ const out2 = {};
60024
+ for (const [id, rollup] of [...baseline.entries()].sort(([a], [b]) => a.localeCompare(b))) {
60025
+ out2[id] = normalizeRollupTimestamps(cloneRollup(rollup));
60026
+ }
60027
+ await atomicWriteFile(filePath, `${JSON.stringify(out2, null, 2)}
60028
+ `);
60029
+ }
60030
+ async function statCacheKey(filePath) {
60031
+ try {
60032
+ const fileStat = await stat3(filePath);
60033
+ return `${fileStat.mtimeMs}:${fileStat.ctimeMs}:${fileStat.size}`;
60034
+ } catch (err2) {
60035
+ if (err2?.code === "ENOENT")
60036
+ return "missing";
60037
+ throw err2;
60038
+ }
60039
+ }
60040
+ async function buildCounterRollupCacheKey(directory) {
60041
+ const [eventsKey, legacyKey, baselineKey] = await Promise.all([
60042
+ statCacheKey(resolveKnowledgeEventsPath(directory)),
60043
+ statCacheKey(resolveLegacyApplicationLogPath(directory)),
60044
+ statCacheKey(resolveKnowledgeCounterBaselinePath(directory))
60045
+ ]);
60046
+ return `${eventsKey}|${legacyKey}|${baselineKey}`;
60047
+ }
60048
+ function setCounterRollupCache(directory, key, rollups) {
60049
+ if (counterRollupCache.has(directory)) {
60050
+ counterRollupCache.delete(directory);
60051
+ }
60052
+ counterRollupCache.set(directory, {
60053
+ key,
60054
+ rollups: cloneRollupMap(rollups)
60055
+ });
60056
+ while (counterRollupCache.size > MAX_COUNTER_ROLLUP_CACHE_DIRS) {
60057
+ const oldestKey = counterRollupCache.keys().next().value;
60058
+ if (oldestKey === undefined)
60059
+ break;
60060
+ counterRollupCache.delete(oldestKey);
60061
+ }
60062
+ }
60063
+ function parseEventLines(lines, filePath) {
60064
+ const out2 = [];
60065
+ for (const line of lines) {
60066
+ const trimmed = line.trim();
60067
+ if (!trimmed)
60068
+ continue;
60069
+ try {
60070
+ out2.push(JSON.parse(trimmed));
60071
+ } catch {
60072
+ warn(`[knowledge-events] Skipping corrupted JSONL line in ${filePath}: ${trimmed.slice(0, 80)}`);
60073
+ }
60074
+ }
60075
+ return out2;
60076
+ }
60077
+ async function foldEvictedEventsIntoBaseline(directory, evictedLines, filePath) {
60078
+ const evictedEvents = parseEventLines(evictedLines, filePath);
60079
+ if (evictedEvents.length === 0)
60080
+ return;
60081
+ const baseline = await readCounterBaseline(directory);
60082
+ for (const [id, rollup] of recomputeCounters(evictedEvents)) {
60083
+ mergeRollupInto(get(baseline, id), rollup);
60084
+ }
60085
+ await writeCounterBaseline(directory, baseline);
60086
+ }
60087
+ function recomputeCounters(events, legacyRecords = [], baseline = new Map) {
59909
60088
  const map3 = new Map;
59910
60089
  const retrievedIds = new Set;
60090
+ for (const [id, rollup] of baseline) {
60091
+ map3.set(id, cloneRollup(rollup));
60092
+ if ((rollup.shown_count ?? 0) > 0)
60093
+ retrievedIds.add(id);
60094
+ }
59911
60095
  for (const e of events) {
59912
60096
  switch (e.type) {
59913
60097
  case "retrieved": {
@@ -59983,12 +60167,7 @@ function recomputeCounters(events, legacyRecords = []) {
59983
60167
  }
59984
60168
  }
59985
60169
  for (const r of map3.values()) {
59986
- if (r.violation_timestamps.length > 1) {
59987
- r.violation_timestamps.sort((a, b) => a < b ? 1 : a > b ? -1 : 0);
59988
- }
59989
- if (r.violation_timestamps.length > MAX_VIOLATION_TIMESTAMPS) {
59990
- r.violation_timestamps = r.violation_timestamps.slice(0, MAX_VIOLATION_TIMESTAMPS);
59991
- }
60170
+ normalizeRollupTimestamps(r);
59992
60171
  }
59993
60172
  return map3;
59994
60173
  }
@@ -60031,11 +60210,21 @@ async function countEntryViolationsInWindow(directory, entryId, windowDays, now
60031
60210
  }
60032
60211
  async function readKnowledgeCounterRollups(directory) {
60033
60212
  try {
60034
- const [events, legacyRecords] = await Promise.all([
60213
+ const cacheKey = await buildCounterRollupCacheKey(directory);
60214
+ const cached3 = counterRollupCache.get(directory);
60215
+ if (cached3?.key === cacheKey) {
60216
+ counterRollupCache.delete(directory);
60217
+ counterRollupCache.set(directory, cached3);
60218
+ return cloneRollupMap(cached3.rollups);
60219
+ }
60220
+ const [events, legacyRecords, baseline] = await Promise.all([
60035
60221
  readKnowledgeEvents(directory),
60036
- readLegacyApplicationRecords(directory)
60222
+ readLegacyApplicationRecords(directory),
60223
+ readCounterBaseline(directory)
60037
60224
  ]);
60038
- return recomputeCounters(events, legacyRecords);
60225
+ const rollups = recomputeCounters(events, legacyRecords, baseline);
60226
+ setCounterRollupCache(directory, cacheKey, rollups);
60227
+ return cloneRollupMap(rollups);
60039
60228
  } catch (err2) {
60040
60229
  warn(`[knowledge-events] readKnowledgeCounterRollups failed: ${err2 instanceof Error ? err2.message : String(err2)}`);
60041
60230
  return new Map;
@@ -60102,10 +60291,12 @@ async function applyKnowledgeVerdictFeedback(directory, options) {
60102
60291
  return { processed: 0, bumps: 0 };
60103
60292
  }
60104
60293
  }
60105
- var import_proper_lockfile4, KNOWLEDGE_EVENT_SCHEMA_VERSION = 1, MAX_EVENT_LOG_ENTRIES = 5000, RECEIPT_EVENT_TYPES, MAX_VIOLATION_TIMESTAMPS = 10, VERDICT_CONFIDENCE_BOOST = 0.03, VERDICT_CONFIDENCE_DECAY = 0.05, _internals23;
60294
+ var import_proper_lockfile4, KNOWLEDGE_EVENT_SCHEMA_VERSION = 1, MAX_EVENT_LOG_ENTRIES = 5000, counterRollupCache, MAX_COUNTER_ROLLUP_CACHE_DIRS = 32, RECEIPT_EVENT_TYPES, MAX_VIOLATION_TIMESTAMPS = 10, VERDICT_CONFIDENCE_BOOST = 0.03, VERDICT_CONFIDENCE_DECAY = 0.05, _internals23;
60106
60295
  var init_knowledge_events = __esm(() => {
60296
+ init_task_file();
60107
60297
  init_logger();
60108
60298
  import_proper_lockfile4 = __toESM(require_proper_lockfile(), 1);
60299
+ counterRollupCache = new Map;
60109
60300
  RECEIPT_EVENT_TYPES = new Set([
60110
60301
  "acknowledged",
60111
60302
  "applied",
@@ -60117,9 +60308,11 @@ var init_knowledge_events = __esm(() => {
60117
60308
  ]);
60118
60309
  _internals23 = {
60119
60310
  resolveKnowledgeEventsPath,
60311
+ resolveKnowledgeCounterBaselinePath,
60120
60312
  appendKnowledgeEvent,
60121
60313
  recordKnowledgeEvent,
60122
60314
  readKnowledgeEvents,
60315
+ readCounterBaseline,
60123
60316
  readLegacyApplicationRecords,
60124
60317
  readKnowledgeCounterRollups,
60125
60318
  effectiveRetrievalOutcomes,
@@ -60757,7 +60950,7 @@ function validateLesson(candidate, existingLessons, meta3) {
60757
60950
  };
60758
60951
  }
60759
60952
  const normalizedCandidate = candidate.normalize("NFKC").replace(INVISIBLE_FORMAT_CHARS, " ").replace(/\s+/g, " ").toLowerCase();
60760
- for (const pattern of DANGEROUS_COMMAND_PATTERNS) {
60953
+ for (const pattern of DANGEROUS_COMMAND_ERROR_PATTERNS) {
60761
60954
  if (pattern.test(normalizedCandidate)) {
60762
60955
  return {
60763
60956
  valid: false,
@@ -60767,6 +60960,16 @@ function validateLesson(candidate, existingLessons, meta3) {
60767
60960
  };
60768
60961
  }
60769
60962
  }
60963
+ for (const pattern of DANGEROUS_COMMAND_WARNING_PATTERNS) {
60964
+ if (pattern.test(normalizedCandidate)) {
60965
+ return {
60966
+ valid: true,
60967
+ layer: 2,
60968
+ reason: "potentially dangerous command pattern queued for review",
60969
+ severity: "warning"
60970
+ };
60971
+ }
60972
+ }
60770
60973
  for (const pattern of SECURITY_DEGRADING_PATTERNS) {
60771
60974
  if (pattern.test(normalizedCandidate)) {
60772
60975
  return {
@@ -60789,10 +60992,10 @@ function validateLesson(candidate, existingLessons, meta3) {
60789
60992
  }
60790
60993
  if (detectContradiction(candidate, existingLessons)) {
60791
60994
  return {
60792
- valid: false,
60995
+ valid: true,
60793
60996
  layer: 3,
60794
- reason: "lesson contradicts an existing lesson with shared tags",
60795
- severity: "error"
60997
+ reason: "possible contradiction with an existing lesson with shared tags",
60998
+ severity: "warning"
60796
60999
  };
60797
61000
  }
60798
61001
  if (isVagueLesson(candidate)) {
@@ -60932,31 +61135,22 @@ async function appendUnactionable(directory, entry, reason) {
60932
61135
  const filePath = resolveUnactionablePath(directory);
60933
61136
  const dirPath = path33.dirname(filePath);
60934
61137
  await mkdir5(dirPath, { recursive: true });
60935
- let release = null;
60936
- try {
60937
- release = await import_proper_lockfile5.default.lock(dirPath, {
60938
- retries: { retries: 50, minTimeout: 10, maxTimeout: 100 },
60939
- stale: 5000
60940
- });
61138
+ await transactKnowledge(filePath, (existing) => {
60941
61139
  const record3 = {
60942
61140
  ...entry,
60943
61141
  status: "quarantined_unactionable",
60944
61142
  unactionable_reason: reason,
60945
61143
  quarantined_at: new Date().toISOString()
60946
61144
  };
60947
- await appendFile5(filePath, `${JSON.stringify(record3)}
60948
- `, "utf-8");
60949
- const existing = await readKnowledge(filePath);
60950
- if (existing.length > 200) {
60951
- const trimmed = existing.slice(-200);
60952
- await atomicWriteFile(filePath, `${trimmed.map((e) => JSON.stringify(e)).join(`
60953
- `)}
60954
- `);
61145
+ const duplicate = findNearDuplicate(record3.lesson, existing, 0.6);
61146
+ if (duplicate?.unactionable_reason === reason) {
61147
+ duplicate.quarantined_at = record3.quarantined_at;
61148
+ duplicate.updated_at = record3.updated_at;
61149
+ return existing;
60955
61150
  }
60956
- } finally {
60957
- if (release)
60958
- await release().catch(() => {});
60959
- }
61151
+ const next = [...existing, record3];
61152
+ return next.length > 200 ? next.slice(-200) : next;
61153
+ });
60960
61154
  }
60961
61155
  async function quarantineEntry(directory, entryId, reason, reportedBy) {
60962
61156
  if (!directory || directory.includes("..")) {
@@ -61090,28 +61284,34 @@ async function restoreEntry(directory, entryId) {
61090
61284
  }
61091
61285
  }
61092
61286
  }
61093
- var import_proper_lockfile5, DANGEROUS_COMMAND_PATTERNS, SECURITY_DEGRADING_PATTERNS, INVISIBLE_FORMAT_CHARS, INJECTION_PATTERNS, VALID_CATEGORIES, TECH_REFERENCE_WORDS, ACTION_VERB_WORDS, NEGATION_PAIRS, ACTIONABLE_STRING_MAX = 200, ACTIONABLE_LIST_MAX = 20, NAME_PATTERN, SOURCE_REF_FORBIDDEN, ALLOWED_SKILL_PATH_PREFIXES, VALID_DIRECTIVE_PRIORITIES;
61287
+ var import_proper_lockfile5, DANGEROUS_COMMAND_ERROR_PATTERNS, DANGEROUS_COMMAND_WARNING_PATTERNS, DANGEROUS_COMMAND_PATTERNS, SECURITY_DEGRADING_PATTERNS, INVISIBLE_FORMAT_CHARS, INJECTION_PATTERNS, VALID_CATEGORIES, TECH_REFERENCE_WORDS, ACTION_VERB_WORDS, NEGATION_PAIRS, ACTIONABLE_STRING_MAX = 200, ACTIONABLE_LIST_MAX = 20, NAME_PATTERN, SOURCE_REF_FORBIDDEN, ALLOWED_SKILL_PATH_PREFIXES, VALID_DIRECTIVE_PRIORITIES;
61094
61288
  var init_knowledge_validator = __esm(() => {
61095
61289
  init_task_file();
61096
61290
  init_logger();
61097
61291
  init_knowledge_store();
61098
61292
  import_proper_lockfile5 = __toESM(require_proper_lockfile(), 1);
61099
- DANGEROUS_COMMAND_PATTERNS = [
61293
+ DANGEROUS_COMMAND_ERROR_PATTERNS = [
61100
61294
  /\brm\s+-rf\b/,
61101
61295
  /\bsudo\s+rm\b/,
61102
- /\bformat\b/,
61103
61296
  /\bmkfs\b/,
61104
61297
  /\bdd\s+if=/,
61105
61298
  /:\(\)\s*\{/,
61106
61299
  /\bchmod\s+-R\s+777\b/i,
61107
61300
  /\bdeltree\b/,
61108
- /\brmdir\s+\/s\b/,
61301
+ /\brmdir\s+\/s\b/
61302
+ ];
61303
+ DANGEROUS_COMMAND_WARNING_PATTERNS = [
61304
+ /\bformat\b/,
61109
61305
  /\bkill\s+-9\b/,
61110
61306
  /\bpkill\b/,
61111
61307
  /\bkillall\b/,
61112
61308
  /`[^`]*`/,
61113
61309
  /\$\([^)]*\)/
61114
61310
  ];
61311
+ DANGEROUS_COMMAND_PATTERNS = [
61312
+ ...DANGEROUS_COMMAND_ERROR_PATTERNS,
61313
+ ...DANGEROUS_COMMAND_WARNING_PATTERNS
61314
+ ];
61115
61315
  SECURITY_DEGRADING_PATTERNS = [
61116
61316
  /disable\s+.{0,50}firewall/i,
61117
61317
  /turn\s+off\s+.{0,50}security/i,
@@ -61213,7 +61413,7 @@ var init_knowledge_validator = __esm(() => {
61213
61413
  });
61214
61414
 
61215
61415
  // src/services/skill-changelog.ts
61216
- import { appendFile as appendFile6, mkdir as mkdir6, readFile as readFile6, writeFile as writeFile4 } from "node:fs/promises";
61416
+ import { appendFile as appendFile6, mkdir as mkdir6, readFile as readFile6, writeFile as writeFile3 } from "node:fs/promises";
61217
61417
  import * as path34 from "node:path";
61218
61418
  function resolveSkillChangelogPath(directory, slug) {
61219
61419
  if (slug.includes("..") || slug.includes("/") || slug.includes("\\")) {
@@ -61233,7 +61433,7 @@ async function appendSkillChangelog(directory, slug, entry) {
61233
61433
  `).filter((line) => line.trim().length > 0);
61234
61434
  if (lines.length > MAX_CHANGELOG_ENTRIES_PER_SKILL) {
61235
61435
  const trimmed = lines.slice(lines.length - MAX_CHANGELOG_ENTRIES_PER_SKILL);
61236
- await writeFile4(filePath, `${trimmed.join(`
61436
+ await writeFile3(filePath, `${trimmed.join(`
61237
61437
  `)}
61238
61438
  `, "utf-8");
61239
61439
  }
@@ -61258,6 +61458,7 @@ __export(exports_skill_generator, {
61258
61458
  parseDraftFrontmatter: () => parseDraftFrontmatter,
61259
61459
  listSkills: () => listSkills,
61260
61460
  isValidSlug: () => isValidSlug,
61461
+ isSkillMaturityEligible: () => isSkillMaturityEligible,
61261
61462
  inspectSkill: () => inspectSkill,
61262
61463
  generateSkills: () => generateSkills,
61263
61464
  clusterEntries: () => clusterEntries,
@@ -61265,10 +61466,13 @@ __export(exports_skill_generator, {
61265
61466
  activeRepoRelativePath: () => activeRepoRelativePath,
61266
61467
  activePath: () => activePath,
61267
61468
  activateProposal: () => activateProposal,
61268
- _internals: () => _internals24
61469
+ _internals: () => _internals24,
61470
+ STRONG_SKILL_OUTCOME_COUNT: () => STRONG_SKILL_OUTCOME_COUNT,
61471
+ DEFAULT_SKILL_MIN_CONFIRMATIONS: () => DEFAULT_SKILL_MIN_CONFIRMATIONS,
61472
+ DEFAULT_SKILL_MIN_CONFIDENCE: () => DEFAULT_SKILL_MIN_CONFIDENCE
61269
61473
  });
61270
61474
  import { existsSync as existsSync17, unlinkSync as unlinkSync5 } from "node:fs";
61271
- import { mkdir as mkdir7, readFile as readFile7, rename as rename3, writeFile as writeFile5 } from "node:fs/promises";
61475
+ import { mkdir as mkdir7, readFile as readFile7, rename as rename3, writeFile as writeFile4 } from "node:fs/promises";
61272
61476
  import * as path35 from "node:path";
61273
61477
  function sanitizeSlug(input) {
61274
61478
  const lc = input.toLowerCase().trim();
@@ -61293,18 +61497,35 @@ async function selectCandidateEntries(directory, opts) {
61293
61497
  const hivePath = resolveHiveKnowledgePath();
61294
61498
  const hive = existsSync17(hivePath) ? await readKnowledge(hivePath) : [];
61295
61499
  const all = [...swarm, ...hive];
61296
- return all.filter((e) => {
61500
+ const counterRollups = await readKnowledgeCounterRollups(directory);
61501
+ const selected = [];
61502
+ for (const e of all) {
61297
61503
  if (e.status === "archived")
61298
- return false;
61299
- if (e.confidence < opts.minConfidence)
61300
- return false;
61301
- const confirmations = (e.confirmed_by ?? []).length;
61302
- if (confirmations < opts.minConfirmations)
61303
- return false;
61504
+ continue;
61304
61505
  if (e.generated_skill_slug)
61305
- return false;
61306
- return true;
61307
- });
61506
+ continue;
61507
+ const outcomes = effectiveRetrievalOutcomes(e.retrieval_outcomes, counterRollups.get(e.id));
61508
+ if (!isSkillMaturityEligible(e, opts, outcomes))
61509
+ continue;
61510
+ selected.push({ ...e, retrieval_outcomes: outcomes });
61511
+ }
61512
+ return selected;
61513
+ }
61514
+ function hasStrongSkillOutcomeRecord(outcomes) {
61515
+ return (outcomes?.applied_explicit_count ?? 0) >= STRONG_SKILL_OUTCOME_COUNT || (outcomes?.succeeded_after_shown_count ?? 0) >= STRONG_SKILL_OUTCOME_COUNT;
61516
+ }
61517
+ function isHighPriorityDirective(entry) {
61518
+ return entry.directive_priority === "critical" || entry.directive_priority === "high";
61519
+ }
61520
+ function isSkillMaturityEligible(entry, opts, outcomes = entry.retrieval_outcomes) {
61521
+ const outcomeSignal = computeOutcomeSignal(outcomes);
61522
+ if (outcomeSignal < 0)
61523
+ return false;
61524
+ const strongOutcomes = hasStrongSkillOutcomeRecord(outcomes);
61525
+ if (entry.confidence < opts.minConfidence && !strongOutcomes)
61526
+ return false;
61527
+ const confirmations = (entry.confirmed_by ?? []).length;
61528
+ return confirmations >= opts.minConfirmations || strongOutcomes;
61308
61529
  }
61309
61530
  function jaccardSimilarity(setA, setB) {
61310
61531
  const normA = setA.map((s) => s.toLowerCase());
@@ -61344,8 +61565,9 @@ function clusterEntries(entries) {
61344
61565
  }
61345
61566
  const result = [];
61346
61567
  for (const c of clusters) {
61347
- if (c.members.length < MIN_CLUSTER_SIZE)
61568
+ if (c.members.length < MIN_CLUSTER_SIZE && !isSkillSingletonEligible(c.members[0])) {
61348
61569
  continue;
61570
+ }
61349
61571
  const arr = c.members;
61350
61572
  const triggers = uniqueStrings(arr.flatMap((e) => e.triggers ?? []));
61351
61573
  const required3 = uniqueStrings(arr.flatMap((e) => e.required_actions ?? []));
@@ -61371,6 +61593,11 @@ function clusterEntries(entries) {
61371
61593
  result.sort((a, b) => b.entries.length - a.entries.length || b.avgConfidence - a.avgConfidence || a.slug.localeCompare(b.slug));
61372
61594
  return result;
61373
61595
  }
61596
+ function isSkillSingletonEligible(entry) {
61597
+ if (!entry)
61598
+ return false;
61599
+ return isHighPriorityDirective(entry) || hasStrongSkillOutcomeRecord(entry.retrieval_outcomes);
61600
+ }
61374
61601
  function uniqueStrings(arr) {
61375
61602
  return [...new Set(arr.filter((s) => typeof s === "string" && s.length > 0))];
61376
61603
  }
@@ -61471,12 +61698,12 @@ function escapeMarkdown(s) {
61471
61698
  async function atomicWrite2(p, content) {
61472
61699
  await mkdir7(path35.dirname(p), { recursive: true });
61473
61700
  const tmp = `${p}.tmp-${process.pid}-${Date.now()}`;
61474
- await writeFile5(tmp, content, "utf-8");
61701
+ await writeFile4(tmp, content, "utf-8");
61475
61702
  await rename3(tmp, p);
61476
61703
  }
61477
61704
  async function generateSkills(req) {
61478
- const minConfidence = req.minConfidence ?? 0.85;
61479
- const minConfirmations = req.minConfirmations ?? 2;
61705
+ const minConfidence = req.minConfidence ?? DEFAULT_SKILL_MIN_CONFIDENCE;
61706
+ const minConfirmations = req.minConfirmations ?? DEFAULT_SKILL_MIN_CONFIRMATIONS;
61480
61707
  const candidates = await selectCandidateEntries(req.directory, {
61481
61708
  minConfidence,
61482
61709
  minConfirmations
@@ -61871,7 +62098,7 @@ async function retireSkill(directory, slug, reason) {
61871
62098
  reason: reason ?? "manual_retire"
61872
62099
  });
61873
62100
  await mkdir7(markerDir, { recursive: true });
61874
- await writeFile5(markerPath, markerContent, "utf-8");
62101
+ await writeFile4(markerPath, markerContent, "utf-8");
61875
62102
  return {
61876
62103
  retired: true,
61877
62104
  path: skillPath,
@@ -62034,8 +62261,9 @@ async function regenerateSkill(directory, slug) {
62034
62261
  entryCount: matchedEntries.length
62035
62262
  };
62036
62263
  }
62037
- var SLUG_PATTERN, MIN_CLUSTER_SIZE = 2, JACCARD_THRESHOLD = 0.5, AUTO_APPLY_BATCH_LIMIT = 5, _internals24;
62264
+ var SLUG_PATTERN, DEFAULT_SKILL_MIN_CONFIDENCE = 0.7, DEFAULT_SKILL_MIN_CONFIRMATIONS = 2, STRONG_SKILL_OUTCOME_COUNT = 3, MIN_CLUSTER_SIZE = 2, JACCARD_THRESHOLD = 0.5, AUTO_APPLY_BATCH_LIMIT = 5, _internals24;
62038
62265
  var init_skill_generator = __esm(() => {
62266
+ init_knowledge_events();
62039
62267
  init_knowledge_store();
62040
62268
  init_knowledge_validator();
62041
62269
  init_logger();
@@ -62045,6 +62273,7 @@ var init_skill_generator = __esm(() => {
62045
62273
  sanitizeSlug,
62046
62274
  isValidSlug,
62047
62275
  selectCandidateEntries,
62276
+ isSkillMaturityEligible,
62048
62277
  clusterEntries,
62049
62278
  jaccardSimilarity,
62050
62279
  renderSkillMarkdown,
@@ -62063,7 +62292,7 @@ var init_skill_generator = __esm(() => {
62063
62292
 
62064
62293
  // src/services/skill-improver-quota.ts
62065
62294
  import { existsSync as existsSync18 } from "node:fs";
62066
- import { mkdir as mkdir8, readFile as readFile8, rename as rename4, writeFile as writeFile6 } from "node:fs/promises";
62295
+ import { mkdir as mkdir8, readFile as readFile8, rename as rename4, writeFile as writeFile5 } from "node:fs/promises";
62067
62296
  import * as path36 from "node:path";
62068
62297
  async function acquireLock(dir) {
62069
62298
  const acquire = import_proper_lockfile6.default.lock(dir, LOCK_RETRY_OPTS);
@@ -62081,8 +62310,9 @@ async function acquireLock(dir) {
62081
62310
  clearTimeout(timer);
62082
62311
  }
62083
62312
  }
62084
- function resolveQuotaPath(directory) {
62085
- return path36.join(directory, ".swarm", "skill-improver-quota.json");
62313
+ function resolveQuotaPath(directory, scope = "skill-improver") {
62314
+ const fileName = scope === "knowledge-enrichment" ? "knowledge-enrichment-quota.json" : "skill-improver-quota.json";
62315
+ return path36.join(directory, ".swarm", fileName);
62086
62316
  }
62087
62317
  function todayKey(window2, now = new Date) {
62088
62318
  if (window2 === "utc") {
@@ -62110,11 +62340,11 @@ async function readState(filePath) {
62110
62340
  async function writeState(filePath, state) {
62111
62341
  await mkdir8(path36.dirname(filePath), { recursive: true });
62112
62342
  const tmp = `${filePath}.tmp-${process.pid}`;
62113
- await writeFile6(tmp, JSON.stringify(state, null, 2), "utf-8");
62343
+ await writeFile5(tmp, JSON.stringify(state, null, 2), "utf-8");
62114
62344
  await rename4(tmp, filePath);
62115
62345
  }
62116
62346
  async function getQuotaState(directory, opts) {
62117
- const filePath = resolveQuotaPath(directory);
62347
+ const filePath = resolveQuotaPath(directory, opts.scope);
62118
62348
  const today = todayKey(opts.window, opts.now);
62119
62349
  const existing = await readState(filePath);
62120
62350
  if (!existing || existing.date !== today || existing.window !== opts.window) {
@@ -62130,7 +62360,7 @@ async function getQuotaState(directory, opts) {
62130
62360
  return { ...existing, max_calls: opts.maxCalls };
62131
62361
  }
62132
62362
  async function reserveQuota(directory, opts) {
62133
- const filePath = resolveQuotaPath(directory);
62363
+ const filePath = resolveQuotaPath(directory, opts.scope);
62134
62364
  await mkdir8(path36.dirname(filePath), { recursive: true });
62135
62365
  let release = null;
62136
62366
  try {
@@ -62160,7 +62390,7 @@ async function reserveQuota(directory, opts) {
62160
62390
  }
62161
62391
  }
62162
62392
  async function releaseQuota(directory, opts) {
62163
- const filePath = resolveQuotaPath(directory);
62393
+ const filePath = resolveQuotaPath(directory, opts.scope);
62164
62394
  await mkdir8(path36.dirname(filePath), { recursive: true });
62165
62395
  let release = null;
62166
62396
  try {
@@ -62196,7 +62426,7 @@ var init_skill_improver_quota = __esm(() => {
62196
62426
  });
62197
62427
 
62198
62428
  // src/services/skill-reviser.ts
62199
- import { readFile as readFile9, rename as rename5, writeFile as writeFile7 } from "node:fs/promises";
62429
+ import { readFile as readFile9, rename as rename5, writeFile as writeFile6 } from "node:fs/promises";
62200
62430
  async function getSkillVersion(skillPath) {
62201
62431
  try {
62202
62432
  const content = await readFile9(skillPath, "utf-8");
@@ -62302,7 +62532,7 @@ async function reviseSkill(params) {
62302
62532
  try {
62303
62533
  const revised = _internals25.buildDeterministicRevision(params.currentContent, params.currentVersion, params.violationContexts);
62304
62534
  const tmpPath = `${params.skillPath}.tmp-${process.pid}-${Date.now()}`;
62305
- await writeFile7(tmpPath, revised, "utf-8");
62535
+ await writeFile6(tmpPath, revised, "utf-8");
62306
62536
  await rename5(tmpPath, params.skillPath);
62307
62537
  const newVersion = params.currentVersion + 1;
62308
62538
  const entry = {
@@ -62370,7 +62600,7 @@ async function reviseSkill(params) {
62370
62600
  finalOutput = finalOutput.replace(/^version:\s*\d+\s*$/m, `version: ${expectedVersion}`);
62371
62601
  }
62372
62602
  const tmpPath = `${params.skillPath}.tmp-${process.pid}-${Date.now()}`;
62373
- await writeFile7(tmpPath, `${finalOutput}
62603
+ await writeFile6(tmpPath, `${finalOutput}
62374
62604
  `, "utf-8");
62375
62605
  await rename5(tmpPath, params.skillPath);
62376
62606
  const newVersion = expectedVersion;
@@ -62436,6 +62666,89 @@ function resolveLogPath(directory) {
62436
62666
  function normalizeComplianceVerdict(verdict) {
62437
62667
  return verdict === "violation" ? "violated" : verdict;
62438
62668
  }
62669
+ function normalizeSkillUsageEntry(raw) {
62670
+ const entry = raw;
62671
+ return {
62672
+ ...entry,
62673
+ complianceVerdict: normalizeComplianceVerdict(entry.complianceVerdict)
62674
+ };
62675
+ }
62676
+ function legacySkillUsageId(entry) {
62677
+ const stable = JSON.stringify({
62678
+ skillPath: entry.skillPath,
62679
+ agentName: entry.agentName,
62680
+ taskID: entry.taskID,
62681
+ timestamp: entry.timestamp,
62682
+ complianceVerdict: entry.complianceVerdict,
62683
+ sessionID: entry.sessionID,
62684
+ skillVersion: entry.skillVersion
62685
+ });
62686
+ return `legacy:${crypto4.createHash("sha256").update(stable).digest("hex")}`;
62687
+ }
62688
+ function parseSkillUsageEntry(raw) {
62689
+ const entry = raw;
62690
+ if (entry.type === "feedback_applied")
62691
+ return null;
62692
+ if (typeof entry.skillPath !== "string" || typeof entry.agentName !== "string" || typeof entry.taskID !== "string" || typeof entry.timestamp !== "string" || typeof entry.complianceVerdict !== "string" || typeof entry.sessionID !== "string") {
62693
+ return null;
62694
+ }
62695
+ return normalizeSkillUsageEntry({
62696
+ ...entry,
62697
+ id: typeof entry.id === "string" ? entry.id : legacySkillUsageId(entry)
62698
+ });
62699
+ }
62700
+ function parseFeedbackMarker(raw) {
62701
+ const marker = raw;
62702
+ if (marker.type !== "feedback_applied")
62703
+ return null;
62704
+ if (typeof marker.timestamp !== "string")
62705
+ return null;
62706
+ if (!Array.isArray(marker.processedEntryIds))
62707
+ return null;
62708
+ const processedEntryIds = marker.processedEntryIds.filter((id) => typeof id === "string" && id.length > 0);
62709
+ return {
62710
+ type: "feedback_applied",
62711
+ timestamp: marker.timestamp,
62712
+ processedEntryIds
62713
+ };
62714
+ }
62715
+ function readFeedbackAppliedEntryIds(directory) {
62716
+ const resolved = resolveLogPath(directory);
62717
+ const processed = new Set;
62718
+ if (!_internals26.existsSync(resolved))
62719
+ return processed;
62720
+ const raw = _internals26.readFileSync(resolved, "utf-8");
62721
+ for (const line of raw.split(`
62722
+ `)) {
62723
+ const trimmed = line.trim();
62724
+ if (!trimmed)
62725
+ continue;
62726
+ try {
62727
+ const marker = parseFeedbackMarker(JSON.parse(trimmed));
62728
+ if (!marker)
62729
+ continue;
62730
+ for (const id of marker.processedEntryIds)
62731
+ processed.add(id);
62732
+ } catch {}
62733
+ }
62734
+ return processed;
62735
+ }
62736
+ function appendFeedbackAppliedMarker(directory, processedEntryIds) {
62737
+ if (processedEntryIds.length === 0)
62738
+ return;
62739
+ const resolved = resolveLogPath(directory);
62740
+ const dir = path37.dirname(resolved);
62741
+ if (!_internals26.existsSync(dir)) {
62742
+ _internals26.mkdirSync(dir, { recursive: true });
62743
+ }
62744
+ const marker = {
62745
+ type: "feedback_applied",
62746
+ timestamp: new Date().toISOString(),
62747
+ processedEntryIds: [...new Set(processedEntryIds)]
62748
+ };
62749
+ _internals26.appendFileSync(resolved, `${JSON.stringify(marker)}
62750
+ `, "utf-8");
62751
+ }
62439
62752
  function appendSkillUsageEntry(directory, entry) {
62440
62753
  const {
62441
62754
  skillPath,
@@ -62479,7 +62792,7 @@ function appendSkillUsageEntry(directory, entry) {
62479
62792
  agentName,
62480
62793
  taskID,
62481
62794
  timestamp,
62482
- complianceVerdict,
62795
+ complianceVerdict: normalizeComplianceVerdict(complianceVerdict),
62483
62796
  sessionID,
62484
62797
  ...reviewerNotes !== undefined && { reviewerNotes },
62485
62798
  ...skillVersion !== undefined && { skillVersion }
@@ -62487,8 +62800,8 @@ function appendSkillUsageEntry(directory, entry) {
62487
62800
  _internals26.appendFileSync(resolved, `${JSON.stringify(fullEntry)}
62488
62801
  `, "utf-8");
62489
62802
  try {
62490
- const stat3 = _internals26.statSync(resolved);
62491
- if (stat3.size > SKILL_USAGE_LOG_ROTATE_BYTES) {
62803
+ const stat4 = _internals26.statSync(resolved);
62804
+ if (stat4.size > SKILL_USAGE_LOG_ROTATE_BYTES) {
62492
62805
  _internals26.pruneSkillUsageLog(directory, SKILL_USAGE_LOG_MAX_ENTRIES_PER_SKILL);
62493
62806
  }
62494
62807
  } catch {}
@@ -62506,9 +62819,9 @@ function readSkillUsageEntries(directory, options) {
62506
62819
  if (!trimmed)
62507
62820
  continue;
62508
62821
  try {
62509
- const entry = JSON.parse(trimmed);
62510
- entry.complianceVerdict = normalizeComplianceVerdict(entry.complianceVerdict);
62511
- entries.push(entry);
62822
+ const entry = parseSkillUsageEntry(JSON.parse(trimmed));
62823
+ if (entry)
62824
+ entries.push(entry);
62512
62825
  } catch {}
62513
62826
  }
62514
62827
  if (!options)
@@ -62542,11 +62855,11 @@ function readSkillUsageEntriesTail(directory, filters, maxBytes = TAIL_BYTES_DEF
62542
62855
  try {
62543
62856
  const normalizedMaxBytes = Number.isFinite(maxBytes) ? maxBytes : TAIL_BYTES_DEFAULT;
62544
62857
  const boundedMaxBytes = Math.min(Math.max(1, normalizedMaxBytes), MAX_TAIL_BYTES);
62545
- const stat3 = _internals26.statSync(logPath);
62546
- const start2 = Math.max(0, stat3.size - boundedMaxBytes);
62858
+ const stat4 = _internals26.statSync(logPath);
62859
+ const start2 = Math.max(0, stat4.size - boundedMaxBytes);
62547
62860
  const fd = _internals26.openSync(logPath, "r");
62548
62861
  try {
62549
- const readLen = stat3.size - start2;
62862
+ const readLen = stat4.size - start2;
62550
62863
  if (readLen === 0)
62551
62864
  return [];
62552
62865
  const buf = Buffer.alloc(readLen);
@@ -62566,8 +62879,9 @@ function readSkillUsageEntriesTail(directory, filters, maxBytes = TAIL_BYTES_DEF
62566
62879
  if (!line.trim())
62567
62880
  continue;
62568
62881
  try {
62569
- const entry = JSON.parse(line);
62570
- entry.complianceVerdict = normalizeComplianceVerdict(entry.complianceVerdict);
62882
+ const entry = parseSkillUsageEntry(JSON.parse(line));
62883
+ if (!entry)
62884
+ continue;
62571
62885
  if (filters.sessionID !== undefined && entry.sessionID !== filters.sessionID) {
62572
62886
  continue;
62573
62887
  }
@@ -62602,8 +62916,9 @@ function computeComplianceByVersion(entries, skillPath) {
62602
62916
  stats.total += 1;
62603
62917
  if (e.complianceVerdict === "compliant")
62604
62918
  stats.compliant += 1;
62605
- if (e.complianceVerdict === "violated")
62919
+ if (normalizeComplianceVerdict(e.complianceVerdict) === "violated") {
62606
62920
  stats.violation += 1;
62921
+ }
62607
62922
  }
62608
62923
  for (const stats of map3.values()) {
62609
62924
  stats.rate = stats.total === 0 ? 0 : stats.compliant / stats.total;
@@ -62714,6 +63029,7 @@ async function applySkillUsageFeedback(directory, options) {
62714
63029
  let bumps = 0;
62715
63030
  try {
62716
63031
  const allEntries = readSkillUsageEntries(directory);
63032
+ const alreadyProcessed = readFeedbackAppliedEntryIds(directory);
62717
63033
  const actionable = allEntries.filter((e) => {
62718
63034
  if (e.complianceVerdict !== "compliant" && e.complianceVerdict !== "violated") {
62719
63035
  return false;
@@ -62721,6 +63037,9 @@ async function applySkillUsageFeedback(directory, options) {
62721
63037
  if (options?.sinceTimestamp && e.timestamp <= options.sinceTimestamp) {
62722
63038
  return false;
62723
63039
  }
63040
+ if (alreadyProcessed.has(e.id)) {
63041
+ return false;
63042
+ }
62724
63043
  return true;
62725
63044
  });
62726
63045
  if (actionable.length === 0) {
@@ -62735,6 +63054,7 @@ async function applySkillUsageFeedback(directory, options) {
62735
63054
  groups.set(entry.skillPath, [entry]);
62736
63055
  }
62737
63056
  const allDeltas = [];
63057
+ const processedEntryIds = [];
62738
63058
  for (const [skillPath, entries] of Array.from(groups)) {
62739
63059
  let compliantCount = 0;
62740
63060
  let violationCount = 0;
@@ -62753,6 +63073,7 @@ async function applySkillUsageFeedback(directory, options) {
62753
63073
  for (const id of sourceIds) {
62754
63074
  allDeltas.push({ id, delta });
62755
63075
  }
63076
+ processedEntryIds.push(...entries.map((entry) => entry.id));
62756
63077
  processed++;
62757
63078
  bumps += sourceIds.length;
62758
63079
  }
@@ -62766,6 +63087,7 @@ async function applySkillUsageFeedback(directory, options) {
62766
63087
  }));
62767
63088
  if (clampedDeltas.length > 0) {
62768
63089
  await bumpKnowledgeConfidenceBatch(directory, clampedDeltas);
63090
+ appendFeedbackAppliedMarker(directory, processedEntryIds);
62769
63091
  }
62770
63092
  } catch (err2) {
62771
63093
  console.warn("[skill-usage-log] applySkillUsageFeedback failed (fail-open):", err2 instanceof Error ? err2.message : String(err2));
@@ -62792,7 +63114,10 @@ var init_skill_usage_log = __esm(() => {
62792
63114
  resolveSourceKnowledgeIds,
62793
63115
  applySkillUsageFeedback,
62794
63116
  parseGeneratedFromKnowledge,
62795
- computeComplianceByVersion
63117
+ computeComplianceByVersion,
63118
+ normalizeComplianceVerdict,
63119
+ readFeedbackAppliedEntryIds,
63120
+ appendFeedbackAppliedMarker
62796
63121
  };
62797
63122
  TAIL_BYTES_DEFAULT = 64 * 1024;
62798
63123
  MAX_TAIL_BYTES = TAIL_BYTES_DEFAULT;
@@ -62825,7 +63150,7 @@ async function autoRetireSkills(directory, curatorKnowledgePath, excludeSlugs) {
62825
63150
  return true;
62826
63151
  return false;
62827
63152
  });
62828
- const violations = skillUsage.filter((e) => e.complianceVerdict === "violated").length;
63153
+ const violations = skillUsage.filter((e) => normalizeComplianceVerdict(e.complianceVerdict) === "violated").length;
62829
63154
  const violationRate = skillUsage.length > 0 ? violations / skillUsage.length : 0;
62830
63155
  let allArchived = false;
62831
63156
  try {
@@ -63490,7 +63815,7 @@ ${phaseDigest.summary}`,
63490
63815
  });
63491
63816
  if (skillUsage.length === 0)
63492
63817
  continue;
63493
- const violations = skillUsage.filter((e) => e.complianceVerdict === "violated").length;
63818
+ const violations = skillUsage.filter((e) => normalizeComplianceVerdict(e.complianceVerdict) === "violated").length;
63494
63819
  const violationRate = violations / skillUsage.length;
63495
63820
  if (violationRate > REVISION_VIOLATION_THRESHOLD && violationRate <= 0.3) {
63496
63821
  const content = await _internals27.readFileAsync(active.path, "utf-8");
@@ -63498,7 +63823,7 @@ ${phaseDigest.summary}`,
63498
63823
  if (fm && fm.skillOrigin === "promoted_external")
63499
63824
  continue;
63500
63825
  const currentVersion = fm?.version ?? 1;
63501
- const violationContexts = skillUsage.filter((e) => e.complianceVerdict === "violated").slice(-10).map((e) => ({
63826
+ const violationContexts = skillUsage.filter((e) => normalizeComplianceVerdict(e.complianceVerdict) === "violated").slice(-10).map((e) => ({
63502
63827
  taskId: e.taskID,
63503
63828
  agent: e.agentName,
63504
63829
  verdict: e.complianceVerdict,
@@ -63792,6 +64117,9 @@ function isAlreadyInHive(entry, hiveEntries, threshold) {
63792
64117
  return findNearDuplicate(entry.lesson, hiveEntries, threshold) !== undefined;
63793
64118
  }
63794
64119
  function isHiveEligible(entry, autoPromoteDays) {
64120
+ if (!isActiveForHivePromotion(entry)) {
64121
+ return false;
64122
+ }
63795
64123
  const phaseNumbers = new Set;
63796
64124
  for (const record3 of entry.confirmed_by ?? []) {
63797
64125
  if (record3 && typeof record3.phase_number === "number") {
@@ -63812,6 +64140,9 @@ function isHiveEligible(entry, autoPromoteDays) {
63812
64140
  }
63813
64141
  return false;
63814
64142
  }
64143
+ function isActiveForHivePromotion(entry) {
64144
+ return !["archived", "quarantined", "quarantined_unactionable"].includes(entry.status);
64145
+ }
63815
64146
  function countDistinctProjects(confirmedBy) {
63816
64147
  const projectNames = new Set;
63817
64148
  for (const record3 of confirmedBy) {
@@ -63894,7 +64225,7 @@ async function checkHivePromotions(swarmEntries, config3) {
63894
64225
  }
63895
64226
  let hiveModified = false;
63896
64227
  for (const hiveEntry of hiveEntries) {
63897
- const nearDuplicate = findNearDuplicate(hiveEntry.lesson, swarmEntries, config3.dedup_threshold);
64228
+ const nearDuplicate = findNearDuplicate(hiveEntry.lesson, swarmEntries.filter(isActiveForHivePromotion), config3.dedup_threshold);
63898
64229
  if (!nearDuplicate) {
63899
64230
  continue;
63900
64231
  }
@@ -64052,9 +64383,9 @@ import {
64052
64383
  mkdir as mkdir9,
64053
64384
  readFile as readFile10,
64054
64385
  rename as rename6,
64055
- stat as stat3,
64386
+ stat as stat4,
64056
64387
  unlink as unlink2,
64057
- writeFile as writeFile8
64388
+ writeFile as writeFile7
64058
64389
  } from "node:fs/promises";
64059
64390
  import * as path40 from "node:path";
64060
64391
  function emptySynonymMap() {
@@ -64241,7 +64572,7 @@ async function readSynonymMap(directory, maxPairs = DEFAULT_MAX_PAIRS) {
64241
64572
  }
64242
64573
  try {
64243
64574
  const ceiling = Math.max(MIN_READ_CEILING_BYTES, Math.floor(maxPairs) * APPROX_BYTES_PER_PAIR);
64244
- const st = await stat3(filePath);
64575
+ const st = await stat4(filePath);
64245
64576
  if (st.size > ceiling)
64246
64577
  return emptySynonymMap();
64247
64578
  const raw = await readFile10(filePath, "utf-8");
@@ -64254,7 +64585,7 @@ async function writeSynonymMapAtomic(filePath, map3) {
64254
64585
  await mkdir9(path40.dirname(filePath), { recursive: true });
64255
64586
  const tmp = `${filePath}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`;
64256
64587
  try {
64257
- await writeFile8(tmp, JSON.stringify(map3, null, 2), "utf-8");
64588
+ await writeFile7(tmp, JSON.stringify(map3, null, 2), "utf-8");
64258
64589
  await rename6(tmp, filePath);
64259
64590
  } finally {
64260
64591
  try {
@@ -64463,12 +64794,12 @@ function extractKeywords(text) {
64463
64794
  const words = text.toLowerCase().split(/[^a-z0-9]+/).filter((w) => w.length >= MIN_KEYWORD_LENGTH);
64464
64795
  return new Set(words);
64465
64796
  }
64466
- function computeContextMatchScore(taskDescription, skillPath) {
64797
+ function computeContextMatchScore(taskDescription, skillPath, metadata2) {
64467
64798
  const taskKeywords = extractKeywords(taskDescription);
64468
64799
  if (taskKeywords.size === 0)
64469
64800
  return 0;
64470
64801
  const skillName = extractSkillName(skillPath);
64471
- const skillText = `${skillPath} ${skillName}`;
64802
+ const skillText = `${skillPath} ${skillName} ${metadata2?.name ?? ""} ${metadata2?.description ?? ""}`;
64472
64803
  const skillKeywords = extractKeywords(skillText);
64473
64804
  let matchCount = 0;
64474
64805
  for (const kw of taskKeywords) {
@@ -64479,7 +64810,7 @@ function computeContextMatchScore(taskDescription, skillPath) {
64479
64810
  return matchCount / taskKeywords.size;
64480
64811
  }
64481
64812
  function computeSkillRelevanceScore(skillPath, taskDescription, usageHistory, metadata2) {
64482
- const contextScore = computeContextMatchScore(taskDescription, skillPath) * CONTEXT_WEIGHT;
64813
+ const contextScore = computeContextMatchScore(taskDescription, skillPath, metadata2) * CONTEXT_WEIGHT;
64483
64814
  if (usageHistory.length === 0)
64484
64815
  return Math.min(1, contextScore);
64485
64816
  const usageCount = usageHistory.length;
@@ -64554,8 +64885,8 @@ function formatSkillIndexWithContext(skills, directory) {
64554
64885
  const usageLogPath = path41.join(directory, ".swarm", "skill-usage.jsonl");
64555
64886
  let hasHistory = false;
64556
64887
  try {
64557
- const stat4 = fs21.statSync(usageLogPath);
64558
- hasHistory = stat4.size > 0;
64888
+ const stat5 = fs21.statSync(usageLogPath);
64889
+ hasHistory = stat5.size > 0;
64559
64890
  } catch {}
64560
64891
  if (!hasHistory) {
64561
64892
  return skills.map((sp) => {
@@ -65076,24 +65407,32 @@ async function skillPropagationTransformScan(directory, output, sessionID) {
65076
65407
  if (!text)
65077
65408
  continue;
65078
65409
  const skillPaths = [];
65410
+ let explicitReviewerTaskID;
65079
65411
  for (const line of text.split(`
65080
65412
  `)) {
65081
- const coderMatch = line.trim().match(CODER_SKILLS_PATTERN);
65413
+ const trimmed = line.trim();
65414
+ const taskMatch = trimmed.match(REVIEWER_TASK_PATTERN);
65415
+ if (taskMatch) {
65416
+ explicitReviewerTaskID = taskMatch[1];
65417
+ }
65418
+ const coderMatch = trimmed.match(CODER_SKILLS_PATTERN);
65082
65419
  if (coderMatch) {
65083
65420
  const parsed = _internals29.parseSkillPaths(coderMatch[1]);
65084
65421
  skillPaths.push(...parsed);
65085
65422
  }
65086
65423
  }
65087
- let resolvedTaskID = "unknown";
65424
+ let resolvedTaskID = explicitReviewerTaskID ?? "unknown";
65088
65425
  if (existingEntries.length > 0) {
65089
- const latestDelegation = [...existingEntries].reverse().find((e) => e.agentName !== "reviewer" && e.skillPath !== "__overall__");
65090
- if (latestDelegation) {
65091
- resolvedTaskID = latestDelegation.taskID;
65092
- if (skillPaths.length === 0) {
65093
- const delegatedPaths = existingEntries.filter((e) => e.agentName !== "reviewer" && e.skillPath !== "__overall__" && e.taskID === resolvedTaskID).map((e) => e.skillPath);
65094
- if (delegatedPaths.length > 0) {
65095
- skillPaths.push(...new Set(delegatedPaths));
65096
- }
65426
+ if (!explicitReviewerTaskID) {
65427
+ const latestDelegation = [...existingEntries].reverse().find((e) => e.agentName !== "reviewer" && e.skillPath !== "__overall__");
65428
+ if (latestDelegation) {
65429
+ resolvedTaskID = latestDelegation.taskID;
65430
+ }
65431
+ }
65432
+ if (skillPaths.length === 0 && resolvedTaskID !== "unknown") {
65433
+ const delegatedPaths = existingEntries.filter((e) => e.agentName !== "reviewer" && e.skillPath !== "__overall__" && e.taskID === resolvedTaskID).map((e) => e.skillPath);
65434
+ if (delegatedPaths.length > 0) {
65435
+ skillPaths.push(...new Set(delegatedPaths));
65097
65436
  }
65098
65437
  }
65099
65438
  }
@@ -65183,7 +65522,7 @@ async function skillPropagationTransformScan(directory, output, sessionID) {
65183
65522
  break;
65184
65523
  }
65185
65524
  }
65186
- var SKILL_CAPABLE_AGENTS, SKILL_SEARCH_ROOTS, MAX_SCORING_SESSION_ENTRIES = 500, _internals29, COMPLIANCE_PATTERN, CODER_SKILLS_PATTERN;
65525
+ var SKILL_CAPABLE_AGENTS, SKILL_SEARCH_ROOTS, MAX_SCORING_SESSION_ENTRIES = 500, _internals29, COMPLIANCE_PATTERN, CODER_SKILLS_PATTERN, REVIEWER_TASK_PATTERN;
65187
65526
  var init_skill_propagation_gate = __esm(() => {
65188
65527
  init_schema();
65189
65528
  init_logger();
@@ -65229,6 +65568,7 @@ var init_skill_propagation_gate = __esm(() => {
65229
65568
  };
65230
65569
  COMPLIANCE_PATTERN = /SKILL_COMPLIANCE\s*:\s*(COMPLIANT|PARTIAL|VIOLATED)(?:\s*(?:—|-)\s*(.*))?\s*$/i;
65231
65570
  CODER_SKILLS_PATTERN = /SKILLS_USED_BY_CODER\s*:\s*(.+)/i;
65571
+ REVIEWER_TASK_PATTERN = /TASK\s*:\s*(\S+)/i;
65232
65572
  _internals29.skillPropagationGateBefore = skillPropagationGateBefore;
65233
65573
  _internals29.skillPropagationTransformScan = skillPropagationTransformScan;
65234
65574
  _internals29.writeWarnEvent = writeWarnEvent;
@@ -65243,7 +65583,7 @@ var init_skill_propagation_gate = __esm(() => {
65243
65583
 
65244
65584
  // src/hooks/micro-reflector.ts
65245
65585
  import { existsSync as existsSync22 } from "node:fs";
65246
- import { readFile as readFile11, writeFile as writeFile9 } from "node:fs/promises";
65586
+ import { readFile as readFile11, writeFile as writeFile8 } from "node:fs/promises";
65247
65587
  import * as path43 from "node:path";
65248
65588
  function resolveInsightCandidatesPath(directory) {
65249
65589
  return validateSwarmPath(directory, "insight-candidates.jsonl");
@@ -65312,7 +65652,7 @@ async function appendInsightCandidates(directory, candidates) {
65312
65652
  const body2 = data.length === 0 ? "" : `${data.map((c) => JSON.stringify(c)).join(`
65313
65653
  `)}
65314
65654
  `;
65315
- await writeFile9(p, body2, "utf-8");
65655
+ await writeFile8(p, body2, "utf-8");
65316
65656
  }, (all) => {
65317
65657
  const merged = [...all, ...candidates];
65318
65658
  const capped = merged.length > INSIGHT_CANDIDATES_MAX_ENTRIES ? merged.slice(-INSIGHT_CANDIDATES_MAX_ENTRIES) : merged;
@@ -65433,7 +65773,8 @@ async function runMicroReflection(params) {
65433
65773
  const reservation = await reserveQuota(params.directory, {
65434
65774
  nCalls: 1,
65435
65775
  maxCalls: quota.maxCalls,
65436
- window: quota.window
65776
+ window: quota.window,
65777
+ scope: "knowledge-enrichment"
65437
65778
  });
65438
65779
  if (!reservation.allowed)
65439
65780
  return result;
@@ -65520,7 +65861,7 @@ var init_micro_reflector = __esm(() => {
65520
65861
 
65521
65862
  // src/hooks/knowledge-curator.ts
65522
65863
  import { existsSync as existsSync23 } from "node:fs";
65523
- import { appendFile as appendFile7, mkdir as mkdir10, readFile as readFile12, writeFile as writeFile10 } from "node:fs/promises";
65864
+ import { appendFile as appendFile7, mkdir as mkdir10, readFile as readFile12, writeFile as writeFile9 } from "node:fs/promises";
65524
65865
  import * as path44 from "node:path";
65525
65866
  function pruneSeenRetroSections() {
65526
65867
  const cutoff = Date.now() - 86400000;
@@ -65761,7 +66102,8 @@ async function enrichLessonToV3(params) {
65761
66102
  const reservation = await reserveQuota(params.directory, {
65762
66103
  nCalls: 1,
65763
66104
  maxCalls: quota.maxCalls,
65764
- window: quota.window
66105
+ window: quota.window,
66106
+ scope: "knowledge-enrichment"
65765
66107
  });
65766
66108
  if (!reservation.allowed)
65767
66109
  return null;
@@ -65815,7 +66157,7 @@ async function consumeInsightCandidates(directory, batchLimit = MESO_INSIGHT_BAT
65815
66157
  const body2 = data.length === 0 ? "" : `${data.map((c) => JSON.stringify(c)).join(`
65816
66158
  `)}
65817
66159
  `;
65818
- await writeFile10(p, body2, "utf-8");
66160
+ await writeFile9(p, body2, "utf-8");
65819
66161
  }, (all) => {
65820
66162
  if (all.length === 0)
65821
66163
  return null;
@@ -66106,7 +66448,7 @@ async function runAutoPromotion(directory, config3) {
66106
66448
  await rewriteKnowledge(knowledgePath, entries);
66107
66449
  }
66108
66450
  }
66109
- function createKnowledgeCuratorHook(directory, config3) {
66451
+ function createKnowledgeCuratorHook(directory, config3, options = {}) {
66110
66452
  const handler = async (input, _output) => {
66111
66453
  pruneSeenRetroSections();
66112
66454
  if (!config3.enabled)
@@ -66151,7 +66493,10 @@ function createKnowledgeCuratorHook(directory, config3) {
66151
66493
  recordSeenRetroSection(evidenceKey, evidenceHash, Date.now());
66152
66494
  const projectName2 = evidenceData.project_name ?? "unknown";
66153
66495
  const phaseNumber2 = typeof evidenceData.phase_number === "number" ? evidenceData.phase_number : 1;
66154
- await _internals30.curateAndStoreSwarm(lessons, projectName2, { phase_number: phaseNumber2 }, directory, config3);
66496
+ await _internals30.curateAndStoreSwarm(lessons, projectName2, { phase_number: phaseNumber2 }, directory, config3, {
66497
+ llmDelegate: options.llmDelegateFactory?.(sessionID),
66498
+ enrichmentQuota: options.enrichmentQuota
66499
+ });
66155
66500
  return;
66156
66501
  }
66157
66502
  const planContent = await readSwarmFileAsync(directory, "plan.md");
@@ -66173,7 +66518,10 @@ function createKnowledgeCuratorHook(directory, config3) {
66173
66518
  const projectName = projectNameMatch ? projectNameMatch[1].trim() : "unknown";
66174
66519
  const phaseMatch = /^Phase:\s*(\d+)/m.exec(planContent);
66175
66520
  const phaseNumber = phaseMatch ? parseInt(phaseMatch[1], 10) : 1;
66176
- await _internals30.curateAndStoreSwarm(normalLessons, projectName, { phase_number: phaseNumber }, directory, config3);
66521
+ await _internals30.curateAndStoreSwarm(normalLessons, projectName, { phase_number: phaseNumber }, directory, config3, {
66522
+ llmDelegate: options.llmDelegateFactory?.(sessionID),
66523
+ enrichmentQuota: options.enrichmentQuota
66524
+ });
66177
66525
  };
66178
66526
  return safeHook(handler);
66179
66527
  }
@@ -66332,7 +66680,7 @@ var init_skill_improver_llm_factory = __esm(() => {
66332
66680
  });
66333
66681
 
66334
66682
  // src/services/trajectory-cluster.ts
66335
- import { mkdir as mkdir11, writeFile as writeFile11 } from "node:fs/promises";
66683
+ import { mkdir as mkdir11, writeFile as writeFile10 } from "node:fs/promises";
66336
66684
  import * as path45 from "node:path";
66337
66685
  function failureKind(e) {
66338
66686
  const tool3 = (e.tool ?? "").toLowerCase();
@@ -66467,7 +66815,7 @@ async function writeMotifProposals(directory, opts = {}) {
66467
66815
  for (const motif of motifs.slice(0, max)) {
66468
66816
  const slug = `motif-${slugify2(motif.signature)}`;
66469
66817
  const filePath = path45.join(proposalsDir, `${slug}.md`);
66470
- await writeFile11(filePath, buildMotifProposal(motif), "utf-8");
66818
+ await writeFile10(filePath, buildMotifProposal(motif), "utf-8");
66471
66819
  result.proposalsWritten.push(filePath);
66472
66820
  }
66473
66821
  return result;
@@ -66611,7 +66959,7 @@ async function writeSuccessMotifProposals(directory, opts = {}) {
66611
66959
  for (const motif of motifs.slice(0, max)) {
66612
66960
  const slug = workflowSlug(motif.signature);
66613
66961
  const filePath = path45.join(proposalsDir, `${slug}.md`);
66614
- await writeFile11(filePath, buildWorkflowProposal(motif), "utf-8");
66962
+ await writeFile10(filePath, buildWorkflowProposal(motif), "utf-8");
66615
66963
  result.proposalsWritten.push(filePath);
66616
66964
  }
66617
66965
  return result;
@@ -66742,7 +67090,7 @@ var init_unactionable_hardening = __esm(() => {
66742
67090
 
66743
67091
  // src/services/skill-improver.ts
66744
67092
  import { existsSync as existsSync25 } from "node:fs";
66745
- import { mkdir as mkdir12, readFile as readFile13, rename as rename7, writeFile as writeFile12 } from "node:fs/promises";
67093
+ import { mkdir as mkdir12, readFile as readFile13, rename as rename7, writeFile as writeFile11 } from "node:fs/promises";
66746
67094
  import * as path46 from "node:path";
66747
67095
  function timestampSlug(d) {
66748
67096
  return d.toISOString().replace(/[:.]/g, "-");
@@ -66750,7 +67098,7 @@ function timestampSlug(d) {
66750
67098
  async function atomicWrite3(p, content) {
66751
67099
  await mkdir12(path46.dirname(p), { recursive: true });
66752
67100
  const tmp = `${p}.tmp-${process.pid}-${Date.now()}`;
66753
- await writeFile12(tmp, content, "utf-8");
67101
+ await writeFile11(tmp, content, "utf-8");
66754
67102
  await rename7(tmp, p);
66755
67103
  }
66756
67104
  async function gatherInventory(directory) {
@@ -66804,7 +67152,10 @@ async function gatherInventory(directory) {
66804
67152
  });
66805
67153
  }
66806
67154
  }
66807
- const matureCandidates = swarm.concat(hive).filter((e) => e.status !== "archived" && e.confidence >= 0.85 && !e.generated_skill_slug && (e.confirmed_by ?? []).length >= 2);
67155
+ const matureCandidates = await selectCandidateEntries(directory, {
67156
+ minConfidence: DEFAULT_SKILL_MIN_CONFIDENCE,
67157
+ minConfirmations: DEFAULT_SKILL_MIN_CONFIRMATIONS
67158
+ });
66808
67159
  return {
66809
67160
  knowledge: { swarm: swarm.length, hive: hive.length, archived },
66810
67161
  skills: {
@@ -67070,8 +67421,8 @@ async function runSkillImprover(req) {
67070
67421
  const gen = await generateSkills({
67071
67422
  directory: req.directory,
67072
67423
  mode: "draft",
67073
- minConfidence: 0.85,
67074
- minConfirmations: 2
67424
+ minConfidence: DEFAULT_SKILL_MIN_CONFIDENCE,
67425
+ minConfirmations: DEFAULT_SKILL_MIN_CONFIRMATIONS
67075
67426
  });
67076
67427
  draftSkillsWritten = gen.written.map((w) => ({
67077
67428
  slug: w.slug,
@@ -67107,7 +67458,7 @@ async function runSkillImprover(req) {
67107
67458
  unactionableHardening = await hardenUnactionableEntries({
67108
67459
  directory: req.directory,
67109
67460
  llmDelegate: delegate,
67110
- quota: { maxCalls: cfg.max_calls_per_day, window: cfg.quota_window }
67461
+ quota: req.enrichmentQuota
67111
67462
  });
67112
67463
  }
67113
67464
  const motifResult = await writeMotifProposals(req.directory);
@@ -67933,8 +68284,8 @@ async function copyDirRecursive(src, dest) {
67933
68284
  const srcEntry = path48.join(src, entry);
67934
68285
  const destEntry = path48.join(dest, entry);
67935
68286
  try {
67936
- const stat4 = await fs23.stat(srcEntry);
67937
- if (stat4.isDirectory()) {
68287
+ const stat5 = await fs23.stat(srcEntry);
68288
+ if (stat5.isDirectory()) {
67938
68289
  const subCount = await copyDirRecursive(srcEntry, destEntry).catch(() => 0);
67939
68290
  count += subCount;
67940
68291
  } else {
@@ -67970,8 +68321,8 @@ function guaranteeAllPlansComplete(planData) {
67970
68321
  async function handleCloseCommand(directory, args2, options = {}) {
67971
68322
  const swarmDir = path48.join(directory, ".swarm");
67972
68323
  try {
67973
- const stat4 = fsSync5.lstatSync(swarmDir);
67974
- if (stat4.isSymbolicLink()) {
68324
+ const stat5 = fsSync5.lstatSync(swarmDir);
68325
+ if (stat5.isSymbolicLink()) {
67975
68326
  return `❌ Refused: .swarm/ is a symlink or junction. Refusing to operate on a redirected directory for safety.`;
67976
68327
  }
67977
68328
  } catch (err2) {
@@ -68125,12 +68476,11 @@ async function handleCloseCommand(directory, args2, options = {}) {
68125
68476
  let curationSucceeded = false;
68126
68477
  let curationResult;
68127
68478
  try {
68128
- const skillImproverCfg = SkillImproverConfigSchema.parse(loadedConfig.skill_improver ?? {});
68129
68479
  curationResult = await curateAndStoreSwarm(allLessons, projectName, { phase_number: 0 }, directory, config3, {
68130
68480
  llmDelegate: createCuratorLLMDelegate(directory, "phase", options.sessionID),
68131
68481
  enrichmentQuota: {
68132
- maxCalls: skillImproverCfg.max_calls_per_day,
68133
- window: skillImproverCfg.quota_window
68482
+ maxCalls: config3.enrichment.max_calls_per_day,
68483
+ window: config3.enrichment.quota_window
68134
68484
  }
68135
68485
  });
68136
68486
  curationSucceeded = true;
@@ -68195,7 +68545,11 @@ async function handleCloseCommand(directory, args2, options = {}) {
68195
68545
  config: skillImproverConfig,
68196
68546
  targets: ["skills", "knowledge"],
68197
68547
  mode: "proposal",
68198
- sessionId: options.sessionID
68548
+ sessionId: options.sessionID,
68549
+ enrichmentQuota: {
68550
+ maxCalls: config3.enrichment.max_calls_per_day,
68551
+ window: config3.enrichment.quota_window
68552
+ }
68199
68553
  }, options.skillReviewTimeoutMs ?? CLOSE_SKILL_REVIEW_TIMEOUT_MS);
68200
68554
  if (skillReviewResult.ran) {
68201
68555
  const proposal = skillReviewResult.proposalPath ? ` Proposal: ${skillReviewResult.proposalPath}.` : "";
@@ -68784,7 +69138,7 @@ function buildStatusMessage(session, plan) {
68784
69138
  const overrideActive = session.maxConcurrencyOverride !== undefined;
68785
69139
  const configuredOverride = session.maxConcurrencyOverride ?? "absent";
68786
69140
  const hasPlan = plan !== null && plan !== undefined;
68787
- const planBaseline = hasPlan ? plan.execution_profile?.max_concurrent_tasks ?? 1 : 1;
69141
+ const planBaseline = hasPlan ? plan.execution_profile?.max_concurrent_tasks ?? 10 : 10;
68788
69142
  const parallelizationEnabled = hasPlan ? plan.execution_profile?.parallelization_enabled ?? false : false;
68789
69143
  const operationalEffective = !parallelizationEnabled ? 1 : session.maxConcurrencyOverride ?? planBaseline;
68790
69144
  let description;
@@ -68813,8 +69167,8 @@ var init_concurrency = __esm(() => {
68813
69167
  init_state();
68814
69168
  PRESETS = {
68815
69169
  min: 1,
68816
- medium: 3,
68817
- max: 8
69170
+ medium: 8,
69171
+ max: 16
68818
69172
  };
68819
69173
  });
68820
69174
 
@@ -68964,7 +69318,7 @@ __export(exports_co_change_analyzer, {
68964
69318
  });
68965
69319
  import * as child_process3 from "node:child_process";
68966
69320
  import { randomUUID as randomUUID5 } from "node:crypto";
68967
- import { readdir as readdir2, readFile as readFile14, stat as stat4 } from "node:fs/promises";
69321
+ import { readdir as readdir2, readFile as readFile14, stat as stat5 } from "node:fs/promises";
68968
69322
  import * as path50 from "node:path";
68969
69323
  import { promisify } from "node:util";
68970
69324
  function getExecFileAsync() {
@@ -69115,7 +69469,7 @@ async function getStaticEdges(directory) {
69115
69469
  for (const ext of extensions) {
69116
69470
  const testPath = resolvedPath + ext;
69117
69471
  try {
69118
- const testStat = await stat4(testPath);
69472
+ const testStat = await stat5(testPath);
69119
69473
  if (testStat.isFile()) {
69120
69474
  targetFile = testPath;
69121
69475
  break;
@@ -75495,7 +75849,7 @@ var KNOWLEDGE_SCHEMA_VERSION = 2;
75495
75849
  // src/hooks/knowledge-migrator.ts
75496
75850
  import { randomUUID as randomUUID6 } from "node:crypto";
75497
75851
  import { existsSync as existsSync33, readFileSync as readFileSync18 } from "node:fs";
75498
- import { mkdir as mkdir13, readFile as readFile16, writeFile as writeFile13 } from "node:fs/promises";
75852
+ import { mkdir as mkdir13, readFile as readFile16, writeFile as writeFile12 } from "node:fs/promises";
75499
75853
  import * as os13 from "node:os";
75500
75854
  import * as path58 from "node:path";
75501
75855
  async function migrateKnowledgeToExternal(_directory, _config) {
@@ -75844,7 +76198,7 @@ async function writeSentinel(sentinelPath, migrated, dropped) {
75844
76198
  migration_tool: "knowledge-migrator.ts"
75845
76199
  };
75846
76200
  await mkdir13(path58.dirname(sentinelPath), { recursive: true });
75847
- await writeFile13(sentinelPath, JSON.stringify(sentinel, null, 2), "utf-8");
76201
+ await writeFile12(sentinelPath, JSON.stringify(sentinel, null, 2), "utf-8");
75848
76202
  }
75849
76203
  function resolveLegacyHiveKnowledgePath() {
75850
76204
  const platform = process.platform;
@@ -76275,7 +76629,7 @@ var init_redaction = __esm(() => {
76275
76629
  });
76276
76630
 
76277
76631
  // src/memory/schema.ts
76278
- import { createHash as createHash6 } from "node:crypto";
76632
+ import { createHash as createHash7 } from "node:crypto";
76279
76633
  function normalizeMemoryText(text) {
76280
76634
  return text.replace(/\s+/g, " ").trim();
76281
76635
  }
@@ -76299,7 +76653,7 @@ function stableScopeKey(scope) {
76299
76653
  }
76300
76654
  function computeMemoryContentHash(recordLike) {
76301
76655
  const normalized = normalizeMemoryText(recordLike.text).toLowerCase();
76302
- return createHash6("sha256").update(`${stableScopeKey(recordLike.scope)}
76656
+ return createHash7("sha256").update(`${stableScopeKey(recordLike.scope)}
76303
76657
  ${recordLike.kind}
76304
76658
  ${normalized}`).digest("hex");
76305
76659
  }
@@ -76307,14 +76661,14 @@ function createMemoryId(recordLike) {
76307
76661
  return `mem_${computeMemoryContentHash(recordLike).slice(0, 16)}`;
76308
76662
  }
76309
76663
  function createProposalId(input) {
76310
- const hash4 = createHash6("sha256").update(`${input.createdAt}
76664
+ const hash4 = createHash7("sha256").update(`${input.createdAt}
76311
76665
  ${input.proposer}
76312
76666
  ${normalizeMemoryText(input.text)}`).digest("hex");
76313
76667
  return `prop_${hash4.slice(0, 16)}`;
76314
76668
  }
76315
76669
  function createBundleId(query, generatedAt) {
76316
76670
  const compactTimestamp = generatedAt.replace(/[-:.TZ]/g, "").slice(0, 14);
76317
- const hash4 = createHash6("sha256").update(`${generatedAt}
76671
+ const hash4 = createHash7("sha256").update(`${generatedAt}
76318
76672
  ${query}`).digest("hex").slice(0, 8);
76319
76673
  return `bundle_${compactTimestamp}_${hash4}`;
76320
76674
  }
@@ -77066,7 +77420,7 @@ import {
77066
77420
  mkdir as mkdir14,
77067
77421
  readFile as readFile17,
77068
77422
  rename as rename8,
77069
- writeFile as writeFile14
77423
+ writeFile as writeFile13
77070
77424
  } from "node:fs/promises";
77071
77425
  import * as path59 from "node:path";
77072
77426
 
@@ -77477,7 +77831,7 @@ async function writeJsonlAtomic(filePath, values) {
77477
77831
  const content = values.map((value) => JSON.stringify(value)).join(`
77478
77832
  `) + (values.length > 0 ? `
77479
77833
  ` : "");
77480
- await writeFile14(tmp, content, "utf-8");
77834
+ await writeFile13(tmp, content, "utf-8");
77481
77835
  await rename8(tmp, filePath);
77482
77836
  }
77483
77837
  var init_local_jsonl_provider = __esm(() => {
@@ -77572,7 +77926,7 @@ var init_prompt_block = __esm(() => {
77572
77926
 
77573
77927
  // src/memory/jsonl-migration.ts
77574
77928
  import { existsSync as existsSync35 } from "node:fs";
77575
- import { copyFile, mkdir as mkdir15, readFile as readFile18, stat as stat5, writeFile as writeFile15 } from "node:fs/promises";
77929
+ import { copyFile, mkdir as mkdir15, readFile as readFile18, stat as stat6, writeFile as writeFile14 } from "node:fs/promises";
77576
77930
  import * as path60 from "node:path";
77577
77931
  function resolveMemoryStorageDir(rootDirectory, config3 = {}) {
77578
77932
  const resolved = resolveConfig(config3);
@@ -77620,14 +77974,14 @@ async function writeJsonlExport(rootDirectory, config3, memories, proposals) {
77620
77974
  await mkdir15(exportDir, { recursive: true });
77621
77975
  const memoriesPath = path60.join(exportDir, "memories.jsonl");
77622
77976
  const proposalsPath = path60.join(exportDir, "proposals.jsonl");
77623
- await writeFile15(memoriesPath, toJsonl(memories), "utf-8");
77624
- await writeFile15(proposalsPath, toJsonl(proposals), "utf-8");
77977
+ await writeFile14(memoriesPath, toJsonl(memories), "utf-8");
77978
+ await writeFile14(proposalsPath, toJsonl(proposals), "utf-8");
77625
77979
  return { directory: exportDir, memoriesPath, proposalsPath };
77626
77980
  }
77627
77981
  async function writeMigrationReport(rootDirectory, report, config3 = {}) {
77628
77982
  const reportPath = path60.join(resolveMemoryStorageDir(rootDirectory, config3), "migration-report.json");
77629
77983
  await mkdir15(path60.dirname(reportPath), { recursive: true });
77630
- await writeFile15(reportPath, `${JSON.stringify(report, null, 2)}
77984
+ await writeFile14(reportPath, `${JSON.stringify(report, null, 2)}
77631
77985
  `, "utf-8");
77632
77986
  return reportPath;
77633
77987
  }
@@ -77648,7 +78002,7 @@ async function getLegacyJsonlFileStatus(rootDirectory, config3 = {}) {
77648
78002
  const filePath = path60.join(storageDir, file3);
77649
78003
  let sizeBytes = 0;
77650
78004
  if (existsSync35(filePath)) {
77651
- sizeBytes = (await stat5(filePath)).size;
78005
+ sizeBytes = (await stat6(filePath)).size;
77652
78006
  }
77653
78007
  statuses.push({
77654
78008
  file: file3,
@@ -78697,7 +79051,7 @@ var init_sqlite_provider = __esm(() => {
78697
79051
  });
78698
79052
 
78699
79053
  // src/memory/gateway.ts
78700
- import { createHash as createHash7 } from "node:crypto";
79054
+ import { createHash as createHash8 } from "node:crypto";
78701
79055
  import { existsSync as existsSync36, readFileSync as readFileSync19 } from "node:fs";
78702
79056
  import * as path62 from "node:path";
78703
79057
 
@@ -79017,7 +79371,7 @@ function sourceFromEvidence(evidenceRefs, context) {
79017
79371
  return { type: "manual", ref: first };
79018
79372
  }
79019
79373
  function createStableId(value) {
79020
- return createHash7("sha256").update(value.toLowerCase()).digest("hex").slice(0, 16);
79374
+ return createHash8("sha256").update(value.toLowerCase()).digest("hex").slice(0, 16);
79021
79375
  }
79022
79376
  function readGitRemoteUrl(directory) {
79023
79377
  if (gitRemoteUrlCache.has(directory))
@@ -82170,8 +82524,8 @@ var init_secretscan = __esm(() => {
82170
82524
  break;
82171
82525
  const fileFindings = scanFileForSecrets(filePath);
82172
82526
  try {
82173
- const stat6 = fs30.statSync(filePath);
82174
- if (stat6.size > MAX_FILE_SIZE_BYTES) {
82527
+ const stat7 = fs30.statSync(filePath);
82528
+ if (stat7.size > MAX_FILE_SIZE_BYTES) {
82175
82529
  skippedFiles++;
82176
82530
  continue;
82177
82531
  }
@@ -82981,8 +83335,8 @@ function sharedTrailingSegments(a, b) {
82981
83335
  function isCacheStale(impactMap, generatedAtMs) {
82982
83336
  for (const sourcePath of Object.keys(impactMap)) {
82983
83337
  try {
82984
- const stat6 = fs34.statSync(sourcePath);
82985
- if (stat6.mtimeMs > generatedAtMs) {
83338
+ const stat7 = fs34.statSync(sourcePath);
83339
+ if (stat7.mtimeMs > generatedAtMs) {
82986
83340
  return true;
82987
83341
  }
82988
83342
  } catch {
@@ -84328,8 +84682,8 @@ function manifestHash(dir) {
84328
84682
  if (!entries.has(name2))
84329
84683
  continue;
84330
84684
  try {
84331
- const stat6 = fs39.statSync(path77.join(dir, name2));
84332
- parts2.push(`${name2}:${stat6.size}:${stat6.mtimeMs}:${stat6.ino}`);
84685
+ const stat7 = fs39.statSync(path77.join(dir, name2));
84686
+ parts2.push(`${name2}:${stat7.size}:${stat7.mtimeMs}:${stat7.ino}`);
84333
84687
  } catch {}
84334
84688
  }
84335
84689
  return parts2.join("|");
@@ -94313,6 +94667,7 @@ SKILL COMPLIANCE REVIEW: When SKILLS_USED_BY_CODER is provided and not "none":
94313
94667
  - For each skill rule, verify the coder's changes comply
94314
94668
  - Flag violations at the same severity as logic errors
94315
94669
  - Report the overall compliance verdict in SKILL_COMPLIANCE field of your output
94670
+ - Report TASK: <task id> immediately before SKILL_COMPLIANCE when a task id is available
94316
94671
  - If you cannot load a skill (SKILL_LOAD_FAILED), report SKILL_COMPLIANCE: PARTIAL — [skill path] could not be loaded
94317
94672
 
94318
94673
  PROCESSING: If GATES is provided and includes passing results for lint, SAST, placeholder-scan, or secret-scan: skip the corresponding Tier 2 checks that those gates already cover. Focus Tier 2 time on checks NOT covered by automated gates.
@@ -94324,6 +94679,7 @@ VERDICT: APPROVED | REJECTED
94324
94679
  REUSE_RE_VERIFICATION: [VERIFIED | DUPLICATION_DETECTED | SKIPPED] — DUPLICATION_DETECTED is only valid when VERDICT is REJECTED
94325
94680
  RISK: LOW | MEDIUM | HIGH | CRITICAL
94326
94681
  ISSUES: list with line numbers, grouped by CHECK dimension
94682
+ TASK: [task id being reviewed, or "unknown"]
94327
94683
  SKILL_COMPLIANCE: COMPLIANT | PARTIAL | VIOLATED — [list of violations or "all rules followed"]
94328
94684
  DIRECTIVE_COMPLIANCE: one line per knowledge directive shown during this phase (IDs listed in the DIRECTIVES TO VERIFY block of your prompt, when present). Use exactly one of:
94329
94685
  VERIFIED:<id> evidence=<file:line | predicate_passed>
@@ -94904,7 +95260,7 @@ COVERAGE REPORTING:
94904
95260
  `;
94905
95261
 
94906
95262
  // src/agents/index.ts
94907
- import { mkdir as mkdir17, writeFile as writeFile16 } from "node:fs/promises";
95263
+ import { mkdir as mkdir17, writeFile as writeFile15 } from "node:fs/promises";
94908
95264
  import * as path88 from "node:path";
94909
95265
  function stripSwarmPrefix(agentName, swarmPrefix) {
94910
95266
  if (!swarmPrefix || !agentName)
@@ -95384,7 +95740,7 @@ function getAgentConfigs(config3, directory, sessionId, projectContext) {
95384
95740
  generatedAt: new Date().toISOString(),
95385
95741
  agents: agentToolSnapshot
95386
95742
  }, null, 2);
95387
- mkdir17(evidenceDir, { recursive: true }).then(() => writeFile16(path88.join(evidenceDir, filename), snapshotData)).catch(() => {});
95743
+ mkdir17(evidenceDir, { recursive: true }).then(() => writeFile15(path88.join(evidenceDir, filename), snapshotData)).catch(() => {});
95388
95744
  }
95389
95745
  return result;
95390
95746
  }
@@ -100096,8 +100452,8 @@ import {
100096
100452
  readdir as readdir6,
100097
100453
  readFile as readFile22,
100098
100454
  realpath as realpath3,
100099
- stat as stat8,
100100
- writeFile as writeFile18
100455
+ stat as stat9,
100456
+ writeFile as writeFile17
100101
100457
  } from "node:fs/promises";
100102
100458
  import * as path119 from "node:path";
100103
100459
  function normalizeSeparators(filePath) {
@@ -100179,8 +100535,8 @@ async function scanDocIndex(directory) {
100179
100535
  for (const file3 of existingManifest.files) {
100180
100536
  try {
100181
100537
  const fullPath = path119.join(directory, file3.path);
100182
- const stat9 = fs71.statSync(fullPath);
100183
- if (stat9.mtimeMs > file3.mtime) {
100538
+ const stat10 = fs71.statSync(fullPath);
100539
+ if (stat10.mtimeMs > file3.mtime) {
100184
100540
  cacheValid = false;
100185
100541
  break;
100186
100542
  }
@@ -100218,7 +100574,7 @@ async function scanDocIndex(directory) {
100218
100574
  const rel = path119.relative(resolvedDirectory, resolved);
100219
100575
  if (rel.startsWith("..") || path119.isAbsolute(rel))
100220
100576
  continue;
100221
- const targetStat = await stat8(symlinkPath);
100577
+ const targetStat = await stat9(symlinkPath);
100222
100578
  isFile = targetStat.isFile();
100223
100579
  } catch {
100224
100580
  continue;
@@ -100247,7 +100603,7 @@ async function scanDocIndex(directory) {
100247
100603
  continue;
100248
100604
  let fileStat;
100249
100605
  try {
100250
- fileStat = await stat8(fullPath);
100606
+ fileStat = await stat9(fullPath);
100251
100607
  } catch {
100252
100608
  continue;
100253
100609
  }
@@ -100295,7 +100651,7 @@ async function scanDocIndex(directory) {
100295
100651
  };
100296
100652
  try {
100297
100653
  await mkdir20(path119.dirname(manifestPath), { recursive: true });
100298
- await writeFile18(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
100654
+ await writeFile17(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
100299
100655
  } catch {}
100300
100656
  return { manifest, cached: false };
100301
100657
  }
@@ -100982,7 +101338,7 @@ async function searchKnowledge(params) {
100982
101338
  const confBoost = context && entry.confidence >= minConf && (ds.actionHit || ds.agentHit) ? 0.25 : 0;
100983
101339
  const generatedSkillBoost = entry.generated_skill_path && entry.status !== "archived" ? 0.05 : 0;
100984
101340
  const outcomeBoost = computeOutcomeSignal(retrievalOutcomes) * OUTCOME_RANK_WEIGHT;
100985
- const coldStartBonus = retrievalOutcomes.applied_count === 0 && entryAgePhases(entry) < (config3.retrieval?.cold_start_max_age_phases ?? DEFAULT_COLD_START_MAX_AGE_PHASES) ? config3.retrieval?.cold_start_bonus ?? DEFAULT_COLD_START_BONUS : 0;
101341
+ const coldStartBonus = (retrievalOutcomes.applied_explicit_count ?? 0) === 0 && entryAgePhases(entry) < (config3.retrieval?.cold_start_max_age_phases ?? DEFAULT_COLD_START_MAX_AGE_PHASES) ? config3.retrieval?.cold_start_bonus ?? DEFAULT_COLD_START_BONUS : 0;
100986
101342
  let synonymBoost = 0;
100987
101343
  if (synonymTokens.length > 0) {
100988
101344
  const entryHay = normalize4(entryText(entry));
@@ -101007,6 +101363,7 @@ async function searchKnowledge(params) {
101007
101363
  ...entry,
101008
101364
  retrieval_outcomes: retrievalOutcomes,
101009
101365
  finalScore,
101366
+ coldStartBoost: coldStartBonus,
101010
101367
  __critical: isCritical
101011
101368
  };
101012
101369
  });
@@ -101038,7 +101395,8 @@ async function searchKnowledge(params) {
101038
101395
  }
101039
101396
  }
101040
101397
  results = top.map(({ __critical: _c, ...rest }) => rest);
101041
- } catch {
101398
+ } catch (err2) {
101399
+ warn(`[search-knowledge] retrieval failed: ${err2 instanceof Error ? err2.message : String(err2)}`);
101042
101400
  results = [];
101043
101401
  }
101044
101402
  if (emitEvent) {
@@ -101078,6 +101436,7 @@ var TEXT_WEIGHT = 0.6, META_WEIGHT = 0.4, DIRECTIVE_BOOST_MIN_CONFIDENCE = 0.75,
101078
101436
  var init_search_knowledge = __esm(() => {
101079
101437
  init_schema();
101080
101438
  init_synonym_map();
101439
+ init_logger();
101081
101440
  init_knowledge_events();
101082
101441
  init_knowledge_reader();
101083
101442
  init_knowledge_store();
@@ -101463,8 +101822,8 @@ async function runDesignDocDriftCheck(directory, phase, outDir) {
101463
101822
  const traceabilityAbs = path165.join(outAbs, TRACEABILITY_REL);
101464
101823
  let registry3 = null;
101465
101824
  try {
101466
- const stat10 = await fs112.promises.stat(traceabilityAbs);
101467
- if (stat10.size <= MAX_TRACEABILITY_BYTES) {
101825
+ const stat11 = await fs112.promises.stat(traceabilityAbs);
101826
+ if (stat11.size <= MAX_TRACEABILITY_BYTES) {
101468
101827
  const raw = await fs112.promises.readFile(traceabilityAbs, "utf-8");
101469
101828
  const parsed = JSON.parse(raw);
101470
101829
  registry3 = parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
@@ -102777,8 +103136,8 @@ function writeProjectConfigIfNew(directory, quiet = false) {
102777
103136
  const dest = path92.join(opencodeDir, "opencode-swarm.json");
102778
103137
  const normalizePathForCompare = (p) => process.platform === "win32" ? p.toLowerCase() : p;
102779
103138
  try {
102780
- const stat6 = fs50.lstatSync(opencodeDir);
102781
- if (stat6.isSymbolicLink())
103139
+ const stat7 = fs50.lstatSync(opencodeDir);
103140
+ if (stat7.isSymbolicLink())
102782
103141
  return;
102783
103142
  const resolvedDir = fs50.realpathSync(opencodeDir);
102784
103143
  const canonicalOpencode = path92.join(fs50.realpathSync(directory), ".opencode");
@@ -102951,8 +103310,8 @@ function extractFileSummary(filePath, content, absolutePath, existingEntry) {
102951
103310
  let mtimeMs = 0;
102952
103311
  if (absolutePath) {
102953
103312
  try {
102954
- const stat6 = fs52.statSync(absolutePath);
102955
- mtimeMs = stat6.mtimeMs;
103313
+ const stat7 = fs52.statSync(absolutePath);
103314
+ mtimeMs = stat7.mtimeMs;
102956
103315
  } catch {}
102957
103316
  }
102958
103317
  const base = {
@@ -105902,9 +106261,9 @@ function createPhaseMonitorHook(directory, preflightManager, curatorRunner, dele
105902
106261
  const initResult = await runner(directory, curatorConfig, llmDelegate);
105903
106262
  if (initResult.briefing) {
105904
106263
  const briefingPath = path103.join(directory, ".swarm", "curator-briefing.md");
105905
- const { mkdir: mkdir18, writeFile: writeFile17 } = await import("node:fs/promises");
106264
+ const { mkdir: mkdir18, writeFile: writeFile16 } = await import("node:fs/promises");
105906
106265
  await mkdir18(path103.dirname(briefingPath), { recursive: true });
105907
- await writeFile17(briefingPath, initResult.briefing, "utf-8");
106266
+ await writeFile16(briefingPath, initResult.briefing, "utf-8");
105908
106267
  const { buildApprovedReceipt: buildApprovedReceipt2, persistReviewReceipt: persistReviewReceipt2 } = await Promise.resolve().then(() => (init_review_receipt(), exports_review_receipt));
105909
106268
  const initReceipt = buildApprovedReceipt2({
105910
106269
  agent: "curator",
@@ -108493,16 +108852,16 @@ function tryResolveTSJS(rawModule, sourceFileAbs) {
108493
108852
  for (const ext of RESOLVE_EXTENSION_CANDIDATES) {
108494
108853
  const test = basePath + ext;
108495
108854
  try {
108496
- const stat8 = fs66.statSync(test);
108497
- if (stat8.isFile())
108855
+ const stat9 = fs66.statSync(test);
108856
+ if (stat9.isFile())
108498
108857
  return test;
108499
108858
  } catch {}
108500
108859
  }
108501
108860
  for (const indexFile of RESOLVE_INDEX_CANDIDATES) {
108502
108861
  const test = path113.join(basePath, indexFile);
108503
108862
  try {
108504
- const stat8 = fs66.statSync(test);
108505
- if (stat8.isFile())
108863
+ const stat9 = fs66.statSync(test);
108864
+ if (stat9.isFile())
108506
108865
  return test;
108507
108866
  } catch {}
108508
108867
  }
@@ -108533,8 +108892,8 @@ function tryResolvePython(rawModule, sourceFileAbs, workspaceRoot) {
108533
108892
  const baseAbs = path113.resolve(sourceDir, upDirs + remainder);
108534
108893
  const accept = (test) => {
108535
108894
  try {
108536
- const stat8 = fs66.statSync(test);
108537
- if (stat8.isFile()) {
108895
+ const stat9 = fs66.statSync(test);
108896
+ if (stat9.isFile()) {
108538
108897
  const rel = path113.relative(workspaceRoot, test).replace(/\\/g, "/");
108539
108898
  if (rel.startsWith(".."))
108540
108899
  return null;
@@ -109387,8 +109746,8 @@ function saveGraph2(workspaceRoot, graph) {
109387
109746
  const file3 = getGraphPath2(workspaceRoot);
109388
109747
  const dir = path116.dirname(file3);
109389
109748
  try {
109390
- const stat8 = fs68.lstatSync(dir);
109391
- if (stat8.isSymbolicLink()) {
109749
+ const stat9 = fs68.lstatSync(dir);
109750
+ if (stat9.isSymbolicLink()) {
109392
109751
  throw new Error(`refusing to write graph: ${SWARM_DIR}/ is a symbolic link`);
109393
109752
  }
109394
109753
  } catch (err2) {
@@ -109424,15 +109783,15 @@ function isGraphFresh(graph, maxAgeMs = 5 * 60 * 1000) {
109424
109783
  var cache2 = new Map;
109425
109784
  function getCachedGraph2(directory) {
109426
109785
  const file3 = getGraphPath2(directory);
109427
- let stat8;
109786
+ let stat9;
109428
109787
  try {
109429
- stat8 = fs69.statSync(file3);
109788
+ stat9 = fs69.statSync(file3);
109430
109789
  } catch {
109431
109790
  cache2.delete(directory);
109432
109791
  return null;
109433
109792
  }
109434
109793
  const cached3 = cache2.get(directory);
109435
- if (cached3 && cached3.mtimeMs === stat8.mtimeMs && cached3.size === stat8.size) {
109794
+ if (cached3 && cached3.mtimeMs === stat9.mtimeMs && cached3.size === stat9.size) {
109436
109795
  return cached3.graph;
109437
109796
  }
109438
109797
  const graph = loadGraph2(directory);
@@ -109440,7 +109799,7 @@ function getCachedGraph2(directory) {
109440
109799
  cache2.delete(directory);
109441
109800
  return null;
109442
109801
  }
109443
- cache2.set(directory, { graph, mtimeMs: stat8.mtimeMs, size: stat8.size });
109802
+ cache2.set(directory, { graph, mtimeMs: stat9.mtimeMs, size: stat9.size });
109444
109803
  return graph;
109445
109804
  }
109446
109805
  function buildCoderLocalizationBlock(directory, targetFile) {
@@ -112001,6 +112360,7 @@ import { appendFile as appendFile13, mkdir as mkdir22 } from "node:fs/promises";
112001
112360
  import * as path124 from "node:path";
112002
112361
 
112003
112362
  // src/hooks/knowledge-application.ts
112363
+ init_task_file();
112004
112364
  init_logger();
112005
112365
  init_knowledge_store();
112006
112366
  var import_proper_lockfile9 = __toESM(require_proper_lockfile(), 1);
@@ -112010,6 +112370,7 @@ import * as path122 from "node:path";
112010
112370
  function resolveApplicationLogPath(directory) {
112011
112371
  return path122.join(directory, ".swarm", "knowledge-application.jsonl");
112012
112372
  }
112373
+ var MAX_LEGACY_APPLICATION_LOG_ENTRIES = 5000;
112013
112374
  var ACK_PATTERN = /KNOWLEDGE_(APPLIED|IGNORED|VIOLATED|N_A)\s*:\s*([0-9a-fA-F-]{8,64})(?:\s+reason\s*=\s*([^\n\r]+?))?(?=$|[\n\r]|\s+KNOWLEDGE_)/g;
112014
112375
  function parseAcknowledgments(text) {
112015
112376
  if (!text || typeof text !== "string")
@@ -112026,9 +112387,29 @@ function parseAcknowledgments(text) {
112026
112387
  }
112027
112388
  async function appendAudit(directory, record3) {
112028
112389
  const filePath = resolveApplicationLogPath(directory);
112029
- await mkdir21(path122.dirname(filePath), { recursive: true });
112030
- await appendFile11(filePath, `${JSON.stringify(record3)}
112390
+ const dirPath = path122.dirname(filePath);
112391
+ await mkdir21(dirPath, { recursive: true });
112392
+ let release;
112393
+ try {
112394
+ release = await import_proper_lockfile9.default.lock(dirPath, {
112395
+ retries: { retries: 50, minTimeout: 10, maxTimeout: 100 },
112396
+ stale: 5000
112397
+ });
112398
+ await appendFile11(filePath, `${JSON.stringify(record3)}
112031
112399
  `, "utf-8");
112400
+ const content = await readFile24(filePath, "utf-8");
112401
+ const lines = content.split(`
112402
+ `).filter((line) => line.trim().length > 0);
112403
+ if (lines.length > MAX_LEGACY_APPLICATION_LOG_ENTRIES) {
112404
+ const trimmed = lines.slice(-MAX_LEGACY_APPLICATION_LOG_ENTRIES);
112405
+ await atomicWriteFile(filePath, `${trimmed.join(`
112406
+ `)}
112407
+ `);
112408
+ }
112409
+ } finally {
112410
+ if (release)
112411
+ await release().catch(() => {});
112412
+ }
112032
112413
  }
112033
112414
  async function bumpCountersBatch(directory, bumps) {
112034
112415
  const filteredBumps = bumps.filter((b) => b.ids.length > 0);
@@ -112066,14 +112447,10 @@ async function bumpCountersBatch(directory, bumps) {
112066
112447
  return updated;
112067
112448
  };
112068
112449
  const swarmPath = resolveSwarmKnowledgePath(directory);
112069
- const swarm = await readKnowledge(swarmPath);
112070
- if (applyOne(swarm))
112071
- await rewriteKnowledge(swarmPath, swarm);
112450
+ await transactKnowledge(swarmPath, (swarm) => applyOne(swarm) ? swarm : null);
112072
112451
  const hivePath = resolveHiveKnowledgePath();
112073
112452
  if (existsSync69(hivePath)) {
112074
- const hive = await readKnowledge(hivePath);
112075
- if (applyOne(hive))
112076
- await rewriteKnowledge(hivePath, hive);
112453
+ await transactKnowledge(hivePath, (hive) => applyOne(hive) ? hive : null);
112077
112454
  }
112078
112455
  }
112079
112456
  async function bumpCounters(directory, ids, field) {
@@ -112143,7 +112520,7 @@ init_knowledge_events();
112143
112520
  // src/hooks/knowledge-injector.ts
112144
112521
  init_schema();
112145
112522
  init_manager();
112146
- import { createHash as createHash11 } from "node:crypto";
112523
+ import { createHash as createHash12 } from "node:crypto";
112147
112524
 
112148
112525
  // src/services/run-memory.ts
112149
112526
  import * as crypto11 from "node:crypto";
@@ -112320,6 +112697,7 @@ init_extractors();
112320
112697
  init_knowledge_escalator();
112321
112698
  init_knowledge_events();
112322
112699
  init_knowledge_store();
112700
+ init_model_limits();
112323
112701
  init_search_knowledge();
112324
112702
  init_utils2();
112325
112703
  var INJECTION_SENTINEL = `${String.fromCharCode(8204)}[[KNOWLEDGE-INJECTED]]`;
@@ -112636,7 +113014,7 @@ function injectKnowledgeMessage(output, text) {
112636
113014
  };
112637
113015
  output.messages.splice(insertIdx, 0, knowledgeMessage);
112638
113016
  }
112639
- function createKnowledgeInjectorHook(directory, config3) {
113017
+ function createKnowledgeInjectorHook(directory, config3, modelLimitOverrides = {}) {
112640
113018
  function buildContextCacheKey(phase, ctx) {
112641
113019
  const parts2 = [
112642
113020
  String(phase),
@@ -112646,7 +113024,7 @@ function createKnowledgeInjectorHook(directory, config3) {
112646
113024
  ctx.taskId ?? "",
112647
113025
  (ctx.filePaths ?? []).slice(0, 8).join(",")
112648
113026
  ].join("|");
112649
- return createHash11("sha1").update(parts2).digest("hex").slice(0, 16);
113027
+ return createHash12("sha1").update(parts2).digest("hex").slice(0, 16);
112650
113028
  }
112651
113029
  let lastSeenCacheKey = null;
112652
113030
  let cachedInjectionText = null;
@@ -112657,7 +113035,9 @@ function createKnowledgeInjectorHook(directory, config3) {
112657
113035
  const plan = await loadPlan(directory);
112658
113036
  const currentPhase = plan?.current_phase ?? 1;
112659
113037
  const CHARS_PER_TOKEN = 1 / 0.33;
112660
- const MODEL_LIMIT_CHARS = Math.floor(128000 * CHARS_PER_TOKEN);
113038
+ const { modelID, providerID } = extractModelInfo(output.messages);
113039
+ const modelLimitTokens = resolveModelLimit(modelID, providerID, modelLimitOverrides);
113040
+ const MODEL_LIMIT_CHARS = Math.floor(modelLimitTokens * CHARS_PER_TOKEN);
112661
113041
  const existingChars = output.messages.reduce((sum, msg) => {
112662
113042
  return sum + (msg.parts?.reduce((s, p) => s + (p.text?.length ?? 0), 0) ?? 0);
112663
113043
  }, 0);
@@ -115897,8 +116277,8 @@ async function cleanupOldTrajectoryFiles(directory, maxAgeDays = 7) {
115897
116277
  continue;
115898
116278
  const filePath = path131.join(dirPath, entry.name);
115899
116279
  try {
115900
- const stat10 = await fs81.stat(filePath);
115901
- if (now - stat10.mtimeMs > cutoffMs) {
116280
+ const stat11 = await fs81.stat(filePath);
116281
+ if (now - stat11.mtimeMs > cutoffMs) {
115902
116282
  await fs81.unlink(filePath);
115903
116283
  }
115904
116284
  } catch {}
@@ -118764,8 +119144,8 @@ function estimateCyclomaticComplexity(content) {
118764
119144
  }
118765
119145
  function getComplexityForFile(filePath) {
118766
119146
  try {
118767
- const stat10 = fs87.statSync(filePath);
118768
- if (stat10.size > MAX_FILE_SIZE_BYTES4) {
119147
+ const stat11 = fs87.statSync(filePath);
119148
+ if (stat11.size > MAX_FILE_SIZE_BYTES4) {
118769
119149
  return null;
118770
119150
  }
118771
119151
  const content = fs87.readFileSync(filePath, "utf-8");
@@ -118966,8 +119346,8 @@ async function computeDuplicationRatio(files, workingDir) {
118966
119346
  continue;
118967
119347
  }
118968
119348
  try {
118969
- const stat10 = fs87.statSync(fullPath);
118970
- if (stat10.size > MAX_FILE_SIZE_BYTES4) {
119349
+ const stat11 = fs87.statSync(fullPath);
119350
+ if (stat11.size > MAX_FILE_SIZE_BYTES4) {
118971
119351
  continue;
118972
119352
  }
118973
119353
  const content = fs87.readFileSync(fullPath, "utf-8");
@@ -119427,8 +119807,8 @@ async function getGitChurn(days, directory) {
119427
119807
  }
119428
119808
  function getComplexityForFile2(filePath) {
119429
119809
  try {
119430
- const stat10 = fs88.statSync(filePath);
119431
- if (stat10.size > MAX_FILE_SIZE_BYTES5) {
119810
+ const stat11 = fs88.statSync(filePath);
119811
+ if (stat11.size > MAX_FILE_SIZE_BYTES5) {
119432
119812
  return null;
119433
119813
  }
119434
119814
  const content = fs88.readFileSync(filePath, "utf-8");
@@ -121897,8 +122277,8 @@ function readEvidenceFiles(evidenceDir, _cwd) {
121897
122277
  if (!resolvedPath.startsWith(evidenceDirResolved)) {
121898
122278
  continue;
121899
122279
  }
121900
- const stat10 = fs93.lstatSync(filePath);
121901
- if (!stat10.isFile()) {
122280
+ const stat11 = fs93.lstatSync(filePath);
122281
+ if (!stat11.isFile()) {
121902
122282
  continue;
121903
122283
  }
121904
122284
  } catch {
@@ -122320,11 +122700,11 @@ var external_skill_delete = createSwarmTool({
122320
122700
  // src/tools/external-skill-discover.ts
122321
122701
  init_zod();
122322
122702
  init_loader();
122323
- import { createHash as createHash13, randomUUID as randomUUID13 } from "node:crypto";
122703
+ import { createHash as createHash14, randomUUID as randomUUID13 } from "node:crypto";
122324
122704
 
122325
122705
  // src/services/external-skill-validator.ts
122326
122706
  init_knowledge_validator();
122327
- import { createHash as createHash12 } from "node:crypto";
122707
+ import { createHash as createHash13 } from "node:crypto";
122328
122708
  var PROMPT_INJECTION_PATTERNS = [
122329
122709
  {
122330
122710
  pattern: /system\s*:/i,
@@ -122458,31 +122838,31 @@ var UNSAFE_INSTRUCTION_PATTERNS = [
122458
122838
  pattern: /\bkill\s+-9\b/,
122459
122839
  name: "force_kill",
122460
122840
  description: "Force process termination",
122461
- severity: "error"
122841
+ severity: "warning"
122462
122842
  },
122463
122843
  {
122464
122844
  pattern: /\bpkill\b/,
122465
122845
  name: "process_group_kill",
122466
122846
  description: "Process group kill",
122467
- severity: "error"
122847
+ severity: "warning"
122468
122848
  },
122469
122849
  {
122470
122850
  pattern: /\bkillall\b/,
122471
122851
  name: "kill_all_processes",
122472
122852
  description: "Kill all processes by name",
122473
- severity: "error"
122853
+ severity: "warning"
122474
122854
  },
122475
122855
  {
122476
122856
  pattern: /`[^`]*`/,
122477
122857
  name: "backtick_execution",
122478
122858
  description: "Backtick shell execution",
122479
- severity: "error"
122859
+ severity: "warning"
122480
122860
  },
122481
122861
  {
122482
122862
  pattern: /\$\([^)]*\)/,
122483
122863
  name: "shell_substitution",
122484
122864
  description: "Shell command substitution",
122485
- severity: "error"
122865
+ severity: "warning"
122486
122866
  },
122487
122867
  {
122488
122868
  pattern: /disable\s+.{0,50}firewall/i,
@@ -122617,6 +122997,9 @@ function scanInvisibleFormatChars(text, fieldName) {
122617
122997
  }
122618
122998
  return findings;
122619
122999
  }
123000
+ function stripMarkdownCodeForUnsafeScan(text) {
123001
+ return text.replace(/```[\s\S]*?```/g, " ").replace(/~~~[\s\S]*?~~~/g, " ").replace(/`[^`\n]*`/g, " ");
123002
+ }
122620
123003
  function scanPromptInjection(candidate, trustLevel = "low") {
122621
123004
  const fields = extractCandidateFields(candidate);
122622
123005
  const findings = [];
@@ -122683,8 +123066,9 @@ function scanUnsafeInstructions(candidate, trustLevel = "low") {
122683
123066
  const fieldsScanned = [];
122684
123067
  for (const { field, value } of fields) {
122685
123068
  fieldsScanned.push(field);
123069
+ const scanValue = field === "skill_body" ? stripMarkdownCodeForUnsafeScan(value) : value;
122686
123070
  for (const entry of UNSAFE_INSTRUCTION_PATTERNS) {
122687
- const match = entry.pattern.exec(value);
123071
+ const match = entry.pattern.exec(scanValue);
122688
123072
  if (match !== null) {
122689
123073
  findings.push({
122690
123074
  pattern: entry.name,
@@ -122855,7 +123239,8 @@ function evaluateCandidate(candidate, options) {
122855
123239
  }
122856
123240
  var _internals78 = {
122857
123241
  getTimestamp: () => new Date().toISOString(),
122858
- computeSha256: (content) => createHash12("sha256").update(content).digest("hex")
123242
+ computeSha256: (content) => createHash13("sha256").update(content).digest("hex"),
123243
+ stripMarkdownCodeForUnsafeScan
122859
123244
  };
122860
123245
 
122861
123246
  // src/tools/external-skill-discover.ts
@@ -122876,7 +123261,7 @@ var _internals79 = {
122876
123261
  return { content, finalUrl: response.url };
122877
123262
  },
122878
123263
  getTimestamp: () => new Date().toISOString(),
122879
- computeSha256: (content) => createHash13("sha256").update(content).digest("hex"),
123264
+ computeSha256: (content) => createHash14("sha256").update(content).digest("hex"),
122880
123265
  uuid: () => randomUUID13()
122881
123266
  };
122882
123267
  var SOURCE_TRUST_LEVELS = {
@@ -123262,7 +123647,7 @@ var external_skill_list = createSwarmTool({
123262
123647
  // src/tools/external-skill-promote.ts
123263
123648
  init_zod();
123264
123649
  init_loader();
123265
- import { createHash as createHash14 } from "node:crypto";
123650
+ import { createHash as createHash15 } from "node:crypto";
123266
123651
  import * as fs95 from "node:fs/promises";
123267
123652
  import * as path146 from "node:path";
123268
123653
  init_create_tool();
@@ -123427,7 +123812,7 @@ var external_skill_promote = createSwarmTool({
123427
123812
  }
123428
123813
  throw writeErr;
123429
123814
  }
123430
- const promotedContentHash = createHash14("sha256").update(skillMarkdown).digest("hex");
123815
+ const promotedContentHash = createHash15("sha256").update(skillMarkdown).digest("hex");
123431
123816
  const prePromotionHistory = candidate.evaluation_history;
123432
123817
  const lastPrePromotionEntry = prePromotionHistory.length > 0 ? prePromotionHistory[prePromotionHistory.length - 1] : undefined;
123433
123818
  const originalEvaluation = lastPrePromotionEntry ? {
@@ -124396,8 +124781,8 @@ var git_blame = createSwarmTool({
124396
124781
  lines: []
124397
124782
  });
124398
124783
  }
124399
- const stat10 = fs97.statSync(resolvedPath);
124400
- if (stat10.isDirectory()) {
124784
+ const stat11 = fs97.statSync(resolvedPath);
124785
+ if (stat11.isDirectory()) {
124401
124786
  return JSON.stringify({
124402
124787
  error: "path is a directory, not a file",
124403
124788
  file: file3,
@@ -124784,9 +125169,9 @@ function findSourceFiles3(dir, files = [], stats = { skippedDirs: [], skippedFil
124784
125169
  continue;
124785
125170
  }
124786
125171
  const fullPath = path150.join(dir, entry);
124787
- let stat10;
125172
+ let stat11;
124788
125173
  try {
124789
- stat10 = fs98.statSync(fullPath);
125174
+ stat11 = fs98.statSync(fullPath);
124790
125175
  } catch (e) {
124791
125176
  stats.fileErrors.push({
124792
125177
  path: fullPath,
@@ -124794,9 +125179,9 @@ function findSourceFiles3(dir, files = [], stats = { skippedDirs: [], skippedFil
124794
125179
  });
124795
125180
  continue;
124796
125181
  }
124797
- if (stat10.isDirectory()) {
125182
+ if (stat11.isDirectory()) {
124798
125183
  findSourceFiles3(fullPath, files, stats);
124799
- } else if (stat10.isFile()) {
125184
+ } else if (stat11.isFile()) {
124800
125185
  const ext = path150.extname(fullPath).toLowerCase();
124801
125186
  if (SUPPORTED_EXTENSIONS3.includes(ext)) {
124802
125187
  files.push(fullPath);
@@ -124891,8 +125276,8 @@ var imports = createSwarmTool({
124891
125276
  if (consumers.length >= MAX_CONSUMERS)
124892
125277
  break;
124893
125278
  try {
124894
- const stat10 = fs98.statSync(filePath);
124895
- if (stat10.size > MAX_FILE_SIZE_BYTES7) {
125279
+ const stat11 = fs98.statSync(filePath);
125280
+ if (stat11.size > MAX_FILE_SIZE_BYTES7) {
124896
125281
  skippedFileCount++;
124897
125282
  continue;
124898
125283
  }
@@ -125254,10 +125639,12 @@ init_knowledge_store();
125254
125639
  init_logger();
125255
125640
  init_create_tool();
125256
125641
  var MODES2 = ["archive", "quarantine", "purge"];
125642
+ var TIERS = ["swarm", "hive"];
125257
125643
  var knowledge_archive = createSwarmTool({
125258
- description: "Archive (default), quarantine, or purge a swarm knowledge entry by ID, appending an immutable audit tombstone. 'archive'/'quarantine' set the entry status reversibly and hide it from recall; 'purge' hard-deletes and requires allow_purge:true.",
125644
+ description: "Archive (default), quarantine, or purge a swarm or hive knowledge entry by ID, appending an immutable audit tombstone. 'archive'/'quarantine' set the entry status reversibly and hide it from recall; 'purge' hard-deletes and requires allow_purge:true.",
125259
125645
  args: {
125260
125646
  id: exports_external.string().min(1).describe("UUID of the knowledge entry"),
125647
+ tier: exports_external.enum(TIERS).optional().describe("Knowledge tier to modify; default 'swarm'"),
125261
125648
  reason: exports_external.string().min(1).max(500).describe("Why the entry is being archived/quarantined/purged"),
125262
125649
  evidence: exports_external.string().max(1000).optional().describe('Supporting evidence (e.g. "ignored 8 times, contradicted by tests")'),
125263
125650
  mode: exports_external.enum(MODES2).optional().describe("Default 'archive'"),
@@ -125280,6 +125667,7 @@ var knowledge_archive = createSwarmTool({
125280
125667
  });
125281
125668
  }
125282
125669
  const evidence = typeof a.evidence === "string" ? a.evidence : undefined;
125670
+ const tier = a.tier === "hive" ? "hive" : "swarm";
125283
125671
  const mode = a.mode === "quarantine" || a.mode === "purge" ? a.mode : "archive";
125284
125672
  if (mode === "purge" && a.allow_purge !== true) {
125285
125673
  return JSON.stringify({
@@ -125287,44 +125675,40 @@ var knowledge_archive = createSwarmTool({
125287
125675
  error: "purge requires allow_purge:true (admin flag)"
125288
125676
  });
125289
125677
  }
125290
- const swarmPath = resolveSwarmKnowledgePath(directory);
125291
- let entries;
125292
- try {
125293
- entries = await readKnowledge(swarmPath);
125294
- } catch (err2) {
125295
- return JSON.stringify({
125296
- success: false,
125297
- error: err2 instanceof Error ? err2.message : "Unknown error"
125298
- });
125299
- }
125300
- const target = entries.find((e) => e.id === id);
125301
- if (!target) {
125302
- return JSON.stringify({ success: false, message: "entry not found" });
125303
- }
125304
- const previousStatus = target.status;
125678
+ const knowledgePath = tier === "hive" ? resolveHiveKnowledgePath() : resolveSwarmKnowledgePath(directory);
125679
+ let found = false;
125680
+ let previousStatus;
125305
125681
  const now = new Date().toISOString();
125306
- let nextEntries;
125307
125682
  let resultStatus;
125308
- if (mode === "purge") {
125309
- warn(`[knowledge_archive] PURGE: hard-deleting entry id=${id} actor=${ctx?.agent ?? "unknown"} reason=${reason}`);
125310
- nextEntries = entries.filter((e) => e.id !== id);
125311
- resultStatus = "purged";
125312
- } else {
125313
- const newStatus = mode === "quarantine" ? "quarantined" : "archived";
125314
- nextEntries = entries.map((e) => e.id === id ? { ...e, status: newStatus, updated_at: now } : e);
125315
- resultStatus = newStatus;
125316
- }
125317
125683
  try {
125318
- await rewriteKnowledge(swarmPath, nextEntries);
125684
+ await transactKnowledge(knowledgePath, (entries) => {
125685
+ const target = entries.find((e) => e.id === id);
125686
+ if (!target)
125687
+ return null;
125688
+ found = true;
125689
+ previousStatus = target.status;
125690
+ if (mode === "purge") {
125691
+ warn(`[knowledge_archive] PURGE: hard-deleting ${tier} entry id=${id} actor=${ctx?.agent ?? "unknown"} reason=${reason}`);
125692
+ resultStatus = "purged";
125693
+ return entries.filter((e) => e.id !== id);
125694
+ }
125695
+ const newStatus = mode === "quarantine" ? "quarantined" : "archived";
125696
+ resultStatus = newStatus;
125697
+ return entries.map((e) => e.id === id ? { ...e, status: newStatus, updated_at: now } : e);
125698
+ });
125319
125699
  } catch (err2) {
125320
125700
  return JSON.stringify({
125321
125701
  success: false,
125322
125702
  error: err2 instanceof Error ? err2.message : "Unknown error"
125323
125703
  });
125324
125704
  }
125705
+ if (!found) {
125706
+ return JSON.stringify({ success: false, message: "entry not found" });
125707
+ }
125325
125708
  await recordKnowledgeEvent(directory, {
125326
125709
  type: "archived",
125327
125710
  entry_id: id,
125711
+ tier,
125328
125712
  actor: ctx?.agent ?? "unknown",
125329
125713
  reason,
125330
125714
  mode,
@@ -125334,6 +125718,7 @@ var knowledge_archive = createSwarmTool({
125334
125718
  return JSON.stringify({
125335
125719
  success: true,
125336
125720
  id,
125721
+ tier,
125337
125722
  mode,
125338
125723
  previous_status: previousStatus,
125339
125724
  status: resultStatus
@@ -130304,12 +130689,11 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
130304
130689
  if (retroFound && retroEntry?.lessons_learned && retroEntry.lessons_learned.length > 0) {
130305
130690
  try {
130306
130691
  const projectName = path166.basename(dir);
130307
- const skillImproverCfg = SkillImproverConfigSchema.parse(config3.skill_improver ?? {});
130308
130692
  const curationResult = await curateAndStoreSwarm(retroEntry.lessons_learned, projectName, { phase_number: phase }, dir, knowledgeConfig, {
130309
130693
  llmDelegate: createCuratorLLMDelegate(dir, "phase", sessionID),
130310
130694
  enrichmentQuota: {
130311
- maxCalls: skillImproverCfg.max_calls_per_day,
130312
- window: skillImproverCfg.quota_window
130695
+ maxCalls: knowledgeConfig.enrichment.max_calls_per_day,
130696
+ window: knowledgeConfig.enrichment.quota_window
130313
130697
  }
130314
130698
  });
130315
130699
  if (curationResult) {
@@ -132410,8 +132794,8 @@ async function placeholderScan(input, directory) {
132410
132794
  }
132411
132795
  let content;
132412
132796
  try {
132413
- const stat10 = fs115.statSync(fullPath);
132414
- if (stat10.size > MAX_FILE_SIZE) {
132797
+ const stat11 = fs115.statSync(fullPath);
132798
+ if (stat11.size > MAX_FILE_SIZE) {
132415
132799
  continue;
132416
132800
  }
132417
132801
  content = fs115.readFileSync(fullPath, "utf-8");
@@ -134592,14 +134976,14 @@ async function runSecretscanWithFiles(files, directory) {
134592
134976
  skippedFiles++;
134593
134977
  continue;
134594
134978
  }
134595
- let stat10;
134979
+ let stat11;
134596
134980
  try {
134597
- stat10 = fs119.statSync(file3);
134981
+ stat11 = fs119.statSync(file3);
134598
134982
  } catch {
134599
134983
  skippedFiles++;
134600
134984
  continue;
134601
134985
  }
134602
- if (stat10.size > MAX_FILE_SIZE_BYTES9) {
134986
+ if (stat11.size > MAX_FILE_SIZE_BYTES9) {
134603
134987
  skippedFiles++;
134604
134988
  continue;
134605
134989
  }
@@ -135378,8 +135762,8 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
135378
135762
  for (const entry of entries) {
135379
135763
  const entryPath = path174.join(evidenceDir, entry);
135380
135764
  try {
135381
- const stat10 = fs120.statSync(entryPath);
135382
- if (!stat10.isDirectory()) {
135765
+ const stat11 = fs120.statSync(entryPath);
135766
+ if (!stat11.isDirectory()) {
135383
135767
  continue;
135384
135768
  }
135385
135769
  } catch {
@@ -135399,11 +135783,11 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
135399
135783
  if (!resolvedPath.startsWith(evidenceDirResolved + path174.sep)) {
135400
135784
  continue;
135401
135785
  }
135402
- const stat10 = fs120.lstatSync(evidenceFilePath);
135403
- if (!stat10.isFile()) {
135786
+ const stat11 = fs120.lstatSync(evidenceFilePath);
135787
+ if (!stat11.isFile()) {
135404
135788
  continue;
135405
135789
  }
135406
- if (stat10.size > MAX_FILE_SIZE_BYTES9) {
135790
+ if (stat11.size > MAX_FILE_SIZE_BYTES9) {
135407
135791
  continue;
135408
135792
  }
135409
135793
  } catch {
@@ -138154,6 +138538,11 @@ var skill_improve = createSwarmTool({
138154
138538
  const a = args2 ?? {};
138155
138539
  const { config: config3 } = loadPluginConfigWithMeta(directory);
138156
138540
  const parsed = SkillImproverConfigSchema.parse(config3.skill_improver ?? {});
138541
+ const knowledgeConfig = KnowledgeConfigSchema.parse(config3.knowledge ?? {});
138542
+ const enrichmentConfig = knowledgeConfig.enrichment ?? {
138543
+ max_calls_per_day: 30,
138544
+ quota_window: "utc"
138545
+ };
138157
138546
  if (!parsed.enabled) {
138158
138547
  return JSON.stringify({
138159
138548
  ran: false,
@@ -138166,7 +138555,11 @@ var skill_improve = createSwarmTool({
138166
138555
  targets: a.targets,
138167
138556
  mode: a.mode,
138168
138557
  maxCalls: a.max_calls,
138169
- sessionId: ctx?.sessionID
138558
+ sessionId: ctx?.sessionID,
138559
+ enrichmentQuota: {
138560
+ maxCalls: enrichmentConfig.max_calls_per_day,
138561
+ window: enrichmentConfig.quota_window
138562
+ }
138170
138563
  });
138171
138564
  return JSON.stringify(result, null, 2);
138172
138565
  }
@@ -138248,7 +138641,7 @@ init_zod();
138248
138641
  init_config();
138249
138642
  init_schema();
138250
138643
  init_create_tool();
138251
- import { mkdir as mkdir30, rename as rename12, writeFile as writeFile22 } from "node:fs/promises";
138644
+ import { mkdir as mkdir30, rename as rename12, writeFile as writeFile21 } from "node:fs/promises";
138252
138645
  import * as path179 from "node:path";
138253
138646
  var MAX_SPEC_BYTES2 = 256 * 1024;
138254
138647
  var spec_write = createSwarmTool({
@@ -138310,7 +138703,7 @@ ${content}
138310
138703
  }
138311
138704
  } catch {}
138312
138705
  }
138313
- await writeFile22(tmp, finalContent, "utf-8");
138706
+ await writeFile21(tmp, finalContent, "utf-8");
138314
138707
  await rename12(tmp, target);
138315
138708
  return JSON.stringify({ written: true, path: target, bytes: finalContent.length }, null, 2);
138316
138709
  }
@@ -139529,8 +139922,8 @@ async function syntaxCheck(input, directory, config3) {
139529
139922
  return { result, counted: false, failed: false, skipped: true };
139530
139923
  }
139531
139924
  try {
139532
- const stat10 = fs126.statSync(fullPath);
139533
- if (stat10.size >= MAX_FILE_SIZE2) {
139925
+ const stat11 = fs126.statSync(fullPath);
139926
+ if (stat11.size >= MAX_FILE_SIZE2) {
139534
139927
  result.skipped_reason = "file_too_large";
139535
139928
  return { result, counted: false, failed: false, skipped: true };
139536
139929
  }
@@ -139762,15 +140155,15 @@ function findSourceFiles4(dir, files = []) {
139762
140155
  continue;
139763
140156
  }
139764
140157
  const fullPath = path183.join(dir, entry);
139765
- let stat10;
140158
+ let stat11;
139766
140159
  try {
139767
- stat10 = fs127.statSync(fullPath);
140160
+ stat11 = fs127.statSync(fullPath);
139768
140161
  } catch {
139769
140162
  continue;
139770
140163
  }
139771
- if (stat10.isDirectory()) {
140164
+ if (stat11.isDirectory()) {
139772
140165
  findSourceFiles4(fullPath, files);
139773
- } else if (stat10.isFile()) {
140166
+ } else if (stat11.isFile()) {
139774
140167
  if (isSupportedExtension(fullPath)) {
139775
140168
  files.push(fullPath);
139776
140169
  }
@@ -139867,8 +140260,8 @@ var todo_extract = createSwarmTool({
139867
140260
  return JSON.stringify(errorResult, null, 2);
139868
140261
  }
139869
140262
  const filesToScan = [];
139870
- const stat10 = fs127.statSync(scanPath);
139871
- if (stat10.isFile()) {
140263
+ const stat11 = fs127.statSync(scanPath);
140264
+ if (stat11.isFile()) {
139872
140265
  if (isSupportedExtension(scanPath)) {
139873
140266
  filesToScan.push(scanPath);
139874
140267
  } else {
@@ -140988,7 +141381,7 @@ import * as zlib from "node:zlib";
140988
141381
  // src/evidence/documents.ts
140989
141382
  init_utils2();
140990
141383
  init_redaction();
140991
- import { createHash as createHash16 } from "node:crypto";
141384
+ import { createHash as createHash17 } from "node:crypto";
140992
141385
  import { appendFile as appendFile17, mkdir as mkdir31 } from "node:fs/promises";
140993
141386
  import * as path188 from "node:path";
140994
141387
  var EVIDENCE_CACHE_FILE = "evidence-cache/documents.jsonl";
@@ -141032,7 +141425,7 @@ function createEvidenceDocumentRecord(input, defaultCapturedAt) {
141032
141425
  };
141033
141426
  }
141034
141427
  function createEvidenceDocumentId(input) {
141035
- const hash4 = createHash16("sha256").update([
141428
+ const hash4 = createHash17("sha256").update([
141036
141429
  input.sourceType,
141037
141430
  input.query ?? "",
141038
141431
  input.title ?? "",
@@ -142082,13 +142475,12 @@ var write_architecture_supervisor_evidence = createSwarmTool({
142082
142475
  if (config3.architectural_supervision?.persist_knowledge_recommendations && args2.knowledge_recommendations.length > 0) {
142083
142476
  const knowledgeConfig = KnowledgeConfigSchema.parse(config3.knowledge ?? {});
142084
142477
  const lessons = args2.knowledge_recommendations.map((r) => r.lesson);
142085
- const skillImproverCfg = SkillImproverConfigSchema.parse(config3.skill_improver ?? {});
142086
142478
  const result = await curateAndStoreSwarm(lessons, path189.basename(dirResult.directory), { phase_number: args2.phase }, dirResult.directory, knowledgeConfig, {
142087
142479
  skipAutoPromotion: true,
142088
142480
  llmDelegate: createCuratorLLMDelegate(dirResult.directory, "phase"),
142089
142481
  enrichmentQuota: {
142090
- maxCalls: skillImproverCfg.max_calls_per_day,
142091
- window: skillImproverCfg.quota_window
142482
+ maxCalls: knowledgeConfig.enrichment.max_calls_per_day,
142483
+ window: knowledgeConfig.enrichment.quota_window
142092
142484
  }
142093
142485
  });
142094
142486
  knowledgeProposed = result.stored;
@@ -143105,11 +143497,16 @@ async function initializeOpenCodeSwarm(ctx) {
143105
143497
  const summaryConfig = SummaryConfigSchema.parse(config3.summaries ?? {});
143106
143498
  const toolSummarizerHook = createToolSummarizerHook(summaryConfig, ctx.directory);
143107
143499
  const knowledgeConfig = KnowledgeConfigSchema.parse(config3.knowledge ?? {});
143108
- const skillImproverConfig = SkillImproverConfigSchema.parse(config3.skill_improver ?? {});
143109
143500
  const skillPropagationConfig = SkillPropagationConfigSchema.parse(config3.skillPropagation ?? {});
143110
- const knowledgeCuratorHook = knowledgeConfig.enabled ? createKnowledgeCuratorHook(ctx.directory, knowledgeConfig) : undefined;
143501
+ const knowledgeCuratorHook = knowledgeConfig.enabled ? createKnowledgeCuratorHook(ctx.directory, knowledgeConfig, {
143502
+ llmDelegateFactory: (sessionID) => createCuratorLLMDelegate(ctx.directory, "phase", sessionID),
143503
+ enrichmentQuota: {
143504
+ maxCalls: knowledgeConfig.enrichment.max_calls_per_day,
143505
+ window: knowledgeConfig.enrichment.quota_window
143506
+ }
143507
+ }) : undefined;
143111
143508
  const hivePromoterHook = knowledgeConfig.enabled && knowledgeConfig.hive_enabled ? createHivePromoterHook(ctx.directory, knowledgeConfig) : undefined;
143112
- const knowledgeInjectorHook = knowledgeConfig.enabled ? createKnowledgeInjectorHook(ctx.directory, knowledgeConfig) : undefined;
143509
+ const knowledgeInjectorHook = knowledgeConfig.enabled ? createKnowledgeInjectorHook(ctx.directory, knowledgeConfig, config3.context_budget?.model_limits ?? {}) : undefined;
143113
143510
  const steeringConsumedHook = createSteeringConsumedHook(ctx.directory);
143114
143511
  const coChangeSuggesterHook = createCoChangeSuggesterHook(ctx.directory);
143115
143512
  const darkMatterDetectorHook = createDarkMatterDetectorHook(ctx.directory);
@@ -143836,8 +144233,8 @@ ${usedByCoderLine}`;
143836
144233
  await safeHook(() => collectDelegateAcksAfter(ctx.directory, input, output))(input, output);
143837
144234
  await safeHook(() => collectReviewerVerdictsAfter(ctx.directory, input, output))(input, output);
143838
144235
  await safeHook(() => microReflectorAfter(ctx.directory, input, output, createCuratorLLMDelegate(ctx.directory, "phase", input.sessionID), {
143839
- maxCalls: skillImproverConfig.max_calls_per_day,
143840
- window: skillImproverConfig.quota_window
144236
+ maxCalls: knowledgeConfig.enrichment.max_calls_per_day,
144237
+ window: knowledgeConfig.enrichment.quota_window
143841
144238
  }))(input, output);
143842
144239
  }
143843
144240
  await safeHook(prmHook.toolAfter)(input, output);