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