opencode-swarm 7.136.0 → 7.136.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/.opencode/skills/swarm-pr-feedback/SKILL.md +41 -1
  2. package/.opencode/skills/swarm-pr-review/SKILL.md +83 -24
  3. package/README.md +18 -0
  4. package/dist/background/candidate-contract.d.ts +13 -0
  5. package/dist/background/workspace-snapshot.d.ts +54 -0
  6. package/dist/cli/{config-doctor-q0krbxwv.js → config-doctor-b67nb84b.js} +2 -2
  7. package/dist/cli/{curation-policy-v6ywe8qd.js → curation-policy-kvzhfaj1.js} +2 -2
  8. package/dist/cli/{curator-llm-factory-mhwje8rf.js → curator-llm-factory-x7kvry9x.js} +17 -14
  9. package/dist/cli/{curator-tqedvpy1.js → curator-nrmj8bds.js} +17 -14
  10. package/dist/cli/{evidence-summary-service-w006jnpg.js → evidence-summary-service-cf8sz2bq.js} +3 -1
  11. package/dist/cli/{guardrail-explain-m0m74hvr.js → guardrail-explain-5kd44rcj.js} +18 -15
  12. package/dist/cli/{guardrail-log-5g8x6qc6.js → guardrail-log-aksrzqdx.js} +3 -3
  13. package/dist/cli/hashing-mjwn6j4y.js +34 -0
  14. package/dist/cli/{hive-promoter-s804newd.js → hive-promoter-cy21rhnd.js} +17 -14
  15. package/dist/cli/{index-n8j0cnp1.js → index-0755132s.js} +4 -4
  16. package/dist/cli/{index-1kjg590p.js → index-1kn24ja0.js} +1 -1
  17. package/dist/cli/{index-j08trvny.js → index-21115szq.js} +5 -5
  18. package/dist/cli/{index-2cv1j3rf.js → index-37v2wxqe.js} +1 -1
  19. package/dist/cli/{index-cfz5750k.js → index-7ayaq27q.js} +5 -1
  20. package/dist/cli/{index-9bk16zkv.js → index-84nz7bhe.js} +1 -1
  21. package/dist/cli/{index-bwfzq91q.js → index-ad6j0m7k.js} +12 -6
  22. package/dist/cli/{index-qh9466j3.js → index-azghvnja.js} +2 -2
  23. package/dist/cli/{index-cxq1t7j1.js → index-ckybsn6p.js} +19 -16
  24. package/dist/cli/{index-cggqh2dz.js → index-kwwxevne.js} +53 -996
  25. package/dist/cli/{index-nw9cn84t.js → index-m5fw4mer.js} +19 -2
  26. package/dist/cli/{index-2w4tsmva.js → index-rw3f73aq.js} +1 -1
  27. package/dist/cli/{index-wpqypdge.js → index-s0rbdp61.js} +2 -2
  28. package/dist/cli/{index-bbejqagj.js → index-s0vahtdm.js} +1 -1
  29. package/dist/cli/{index-81dkzncr.js → index-sr2cynyw.js} +4535 -2325
  30. package/dist/cli/index-wjm896ey.js +1100 -0
  31. package/dist/cli/{index-w58bmwyq.js → index-wnz282j3.js} +2 -2
  32. package/dist/cli/{index-y6a7gjtj.js → index-wsdnttf4.js} +228 -81
  33. package/dist/cli/{index-m1hew17b.js → index-y0xaq4f3.js} +39 -4
  34. package/dist/cli/index-y8552snf.js +264 -0
  35. package/dist/cli/index-z1tm47nj.js +783 -0
  36. package/dist/cli/index.js +17 -14
  37. package/dist/cli/{knowledge-escalator-f1m2xp5x.js → knowledge-escalator-ta3xjrdj.js} +3 -3
  38. package/dist/cli/{knowledge-events-rksgem6f.js → knowledge-events-dk6banmz.js} +1 -1
  39. package/dist/cli/{knowledge-store-t6d6fr8b.js → knowledge-store-h3jz10bv.js} +1 -1
  40. package/dist/cli/{knowledge-validator-5ggzb3j1.js → knowledge-validator-jsz1dxkr.js} +4 -4
  41. package/dist/cli/runner-2v413r74.js +21 -0
  42. package/dist/cli/{scan-cursor-18fnwr58.js → scan-cursor-48gwzh9c.js} +2 -2
  43. package/dist/cli/{schema-jw15d8bt.js → schema-f937b9cs.js} +5 -1
  44. package/dist/cli/{skill-generator-3n5y902z.js → skill-generator-4p10ktw1.js} +5 -5
  45. package/dist/cli/{workspace-snapshot-jmyamqnv.js → workspace-snapshot-h5rzw37b.js} +5 -1
  46. package/dist/commands/registry.d.ts +72 -0
  47. package/dist/commands/skill-opt.d.ts +41 -0
  48. package/dist/config/schema.d.ts +47 -0
  49. package/dist/hooks/guardrails/file-authority.d.ts +11 -2
  50. package/dist/hooks/pr-workflow-gate.d.ts +261 -4
  51. package/dist/hooks/pr-workflow-response-gate.d.ts +27 -9
  52. package/dist/hooks/write-target-resolver.d.ts +19 -0
  53. package/dist/index.js +355 -320
  54. package/dist/services/skill-evaluator.d.ts +17 -0
  55. package/dist/services/skill-optimizer/activation.d.ts +58 -0
  56. package/dist/services/skill-optimizer/candidates.d.ts +88 -0
  57. package/dist/services/skill-optimizer/controller.d.ts +146 -0
  58. package/dist/services/skill-optimizer/deterministic-seed.d.ts +29 -0
  59. package/dist/services/skill-optimizer/lifecycle.d.ts +70 -0
  60. package/dist/services/skill-optimizer/promoted-external-staleness.d.ts +98 -0
  61. package/dist/services/skill-optimizer/retirement.d.ts +54 -0
  62. package/dist/services/skill-optimizer/skill-eval-tasks.d.ts +47 -0
  63. package/dist/services/skill-optimizer/smoke.d.ts +46 -0
  64. package/dist/services/skill-optimizer/store.d.ts +118 -0
  65. package/dist/tools/write-pr-review-trigger-eval.d.ts +2 -1
  66. package/dist/utils/stable-stringify.d.ts +46 -0
  67. package/evaluation-fixtures/skill-eval/scoring/score-skill-eval.cjs +97 -0
  68. package/package.json +1 -1
@@ -1,4 +1,9 @@
1
1
  // @bun
2
+ import {
3
+ EvaluationRunV1Schema,
4
+ GateAuditResultV1Schema,
5
+ getProtectedEvaluationRunIds
6
+ } from "./index-z1tm47nj.js";
2
7
  import {
3
8
  readEffectiveSpecSync
4
9
  } from "./index-9ss2m4rs.js";
@@ -8,9 +13,6 @@ import {
8
13
  readTaskEvidenceRaw,
9
14
  sanitizeTaskId
10
15
  } from "./index-mrtms113.js";
11
- import {
12
- atomicWriteFile
13
- } from "./index-ey29aap6.js";
14
16
  import {
15
17
  EVIDENCE_MAX_JSON_BYTES,
16
18
  EvidenceBundleSchema,
@@ -57,7 +59,6 @@ import {
57
59
  } from "./index-09b9zncg.js";
58
60
  import {
59
61
  ZodError,
60
- exports_external,
61
62
  init_zod
62
63
  } from "./index-bpmtbmy9.js";
63
64
  import {
@@ -3382,961 +3383,17 @@ init_zod();
3382
3383
  import {
3383
3384
  mkdirSync as mkdirSync4,
3384
3385
  readdirSync as readdirSync2,
3385
- realpathSync as realpathSync2,
3386
+ realpathSync,
3386
3387
  rmSync,
3387
3388
  statSync as statSync2
3388
3389
  } from "fs";
3389
3390
  import * as fs6 from "fs/promises";
3390
3391
  import * as os4 from "os";
3391
- import * as path12 from "path";
3392
+ import * as path9 from "path";
3392
3393
 
3393
3394
  // src/evaluation/retention.ts
3394
3395
  import * as fs4 from "fs/promises";
3395
- import * as path11 from "path";
3396
-
3397
- // src/evaluation/contracts.ts
3398
- init_zod();
3399
- var IdentifierSchema = exports_external.string().min(1).max(160).regex(/^[A-Za-z0-9][A-Za-z0-9._-]*$/);
3400
- var Sha256Schema = exports_external.string().regex(/^[a-f0-9]{64}$/);
3401
- var IsoDateSchema = exports_external.iso.datetime({ offset: true });
3402
- var RelativePathSchema = exports_external.string().min(1).max(1024).refine((value) => !value.includes("\x00"), "path contains a NUL byte").refine((value) => !/^(?:[A-Za-z]:[\\/]|[\\/]{1,2})/.test(value), {
3403
- message: "path must be project-relative"
3404
- }).refine((value) => !value.replace(/\\/g, "/").split("/").some((segment) => segment === ".."), "path must not traverse outside its root");
3405
- var EvaluationSplitSchema = exports_external.enum(["train", "validation", "test"]);
3406
- var CostRecordSchema = exports_external.object({
3407
- source: exports_external.enum(["reported", "estimated", "unavailable"]),
3408
- usd: exports_external.number().finite().nonnegative().optional()
3409
- }).strict().superRefine((value, ctx) => {
3410
- if (value.source === "unavailable" && value.usd !== undefined) {
3411
- ctx.addIssue({
3412
- code: "custom",
3413
- path: ["usd"],
3414
- message: "unavailable costs cannot declare a USD value"
3415
- });
3416
- }
3417
- if (value.source !== "unavailable" && value.usd === undefined) {
3418
- ctx.addIssue({
3419
- code: "custom",
3420
- path: ["usd"],
3421
- message: "reported and estimated costs require a USD value"
3422
- });
3423
- }
3424
- });
3425
- var HumanReviewReceiptSchema = exports_external.object({
3426
- reviewer: exports_external.string().min(1).max(200),
3427
- reviewedAt: IsoDateSchema,
3428
- instruction: exports_external.literal(true),
3429
- fixture: exports_external.literal(true),
3430
- scorer: exports_external.literal(true),
3431
- secretsPrivacy: exports_external.literal(true),
3432
- license: exports_external.literal(true),
3433
- split: exports_external.literal(true)
3434
- }).strict();
3435
- var EvaluationTaskV1Schema = exports_external.object({
3436
- v: exports_external.literal(1),
3437
- id: IdentifierSchema,
3438
- derivedFromTaskId: IdentifierSchema.optional(),
3439
- source: exports_external.enum(["curated", "trace-proposal"]),
3440
- split: EvaluationSplitSchema,
3441
- category: IdentifierSchema,
3442
- protected: exports_external.boolean().default(false),
3443
- instructionPath: RelativePathSchema,
3444
- environment: exports_external.discriminatedUnion("kind", [
3445
- exports_external.object({ kind: exports_external.literal("fixture"), path: RelativePathSchema }).strict(),
3446
- exports_external.object({ kind: exports_external.literal("container"), path: RelativePathSchema }).strict()
3447
- ]),
3448
- scorer: exports_external.object({
3449
- kind: exports_external.enum(["builtin", "project"]),
3450
- argv: exports_external.array(exports_external.string().min(1).max(4096)).min(1).max(64),
3451
- timeoutMs: exports_external.number().int().min(100).max(600000),
3452
- scoreRange: exports_external.tuple([exports_external.number().finite(), exports_external.number().finite()]).refine(([minimum, maximum]) => maximum > minimum, {
3453
- message: "score range maximum must be greater than minimum"
3454
- })
3455
- }).strict(),
3456
- provenance: exports_external.object({
3457
- origin: exports_external.string().min(1).max(2048),
3458
- license: exports_external.string().min(1).max(200),
3459
- collectedAt: IsoDateSchema.optional(),
3460
- review: HumanReviewReceiptSchema.optional()
3461
- }).strict(),
3462
- contentHash: Sha256Schema
3463
- }).strict().superRefine((task, ctx) => {
3464
- if (task.derivedFromTaskId === task.id) {
3465
- ctx.addIssue({
3466
- code: "custom",
3467
- path: ["derivedFromTaskId"],
3468
- message: "a derived task must reference a different parent task"
3469
- });
3470
- }
3471
- if (task.source === "trace-proposal" && !task.provenance.review) {
3472
- ctx.addIssue({
3473
- code: "custom",
3474
- path: ["provenance", "review"],
3475
- message: "trace-derived tasks require an explicit human review receipt"
3476
- });
3477
- }
3478
- if (task.scorer.kind === "project" && !RelativePathSchema.safeParse(task.scorer.argv[0]).success) {
3479
- ctx.addIssue({
3480
- code: "custom",
3481
- path: ["scorer", "argv", 0],
3482
- message: "project scorer executable must be project-relative"
3483
- });
3484
- }
3485
- });
3486
- var EvaluationCandidateV1Schema = exports_external.object({
3487
- v: exports_external.literal(1),
3488
- id: IdentifierSchema,
3489
- kind: exports_external.enum(["baseline", "skill", "harness"]),
3490
- payloadPath: RelativePathSchema,
3491
- model: exports_external.string().min(1).max(300),
3492
- agent: exports_external.string().min(1).max(160).optional(),
3493
- contentHash: Sha256Schema
3494
- }).strict();
3495
- var EvaluationOutcomeSchema = exports_external.enum([
3496
- "scored",
3497
- "infrastructure_failure",
3498
- "timeout",
3499
- "cancelled",
3500
- "malformed",
3501
- "unsupported",
3502
- "integrity_failure"
3503
- ]);
3504
- var EvaluationResultV1Schema = exports_external.object({
3505
- v: exports_external.literal(1),
3506
- taskId: IdentifierSchema,
3507
- category: IdentifierSchema,
3508
- protected: exports_external.boolean().default(false),
3509
- repetition: exports_external.number().int().nonnegative(),
3510
- candidateId: IdentifierSchema,
3511
- seed: exports_external.string().min(1).max(500),
3512
- outcome: EvaluationOutcomeSchema,
3513
- score: exports_external.number().finite().optional(),
3514
- scoreRange: exports_external.tuple([exports_external.number().finite(), exports_external.number().finite()]),
3515
- cost: CostRecordSchema,
3516
- durationMs: exports_external.number().int().nonnegative(),
3517
- retries: exports_external.number().int().nonnegative().default(0),
3518
- failureCode: exports_external.string().min(1).max(160).optional(),
3519
- metadata: exports_external.record(exports_external.string(), exports_external.unknown()).optional()
3520
- }).strict().superRefine((result, ctx) => {
3521
- const [minimum, maximum] = result.scoreRange;
3522
- if (maximum <= minimum) {
3523
- ctx.addIssue({
3524
- code: "custom",
3525
- path: ["scoreRange"],
3526
- message: "score range maximum must be greater than minimum"
3527
- });
3528
- }
3529
- if (result.outcome === "scored") {
3530
- if (result.score === undefined || result.score < minimum || result.score > maximum) {
3531
- ctx.addIssue({
3532
- code: "custom",
3533
- path: ["score"],
3534
- message: "scored outcomes require an in-range score"
3535
- });
3536
- }
3537
- } else if (result.score !== undefined) {
3538
- ctx.addIssue({
3539
- code: "custom",
3540
- path: ["score"],
3541
- message: "non-score outcomes must not be imputed with a score"
3542
- });
3543
- }
3544
- });
3545
- var EvaluationBudgetsV1Schema = exports_external.object({
3546
- maxTasks: exports_external.number().int().positive(),
3547
- maxRepetitions: exports_external.number().int().positive(),
3548
- maxConcurrency: exports_external.number().int().positive(),
3549
- maxTaskTimeMs: exports_external.number().int().positive(),
3550
- maxRetries: exports_external.number().int().nonnegative(),
3551
- maxOutputBytes: exports_external.number().int().positive(),
3552
- maxSpendUsd: exports_external.number().finite().nonnegative().optional()
3553
- }).strict();
3554
- var EnvironmentFingerprintV1Schema = exports_external.object({
3555
- platform: exports_external.string().min(1),
3556
- arch: exports_external.string().min(1),
3557
- runtime: exports_external.string().min(1),
3558
- baseSha: exports_external.string().regex(/^[a-f0-9]{40,64}$/),
3559
- activeTreeHash: Sha256Schema,
3560
- taskSetHash: Sha256Schema
3561
- }).strict();
3562
- var EvaluationRunV1Schema = exports_external.object({
3563
- v: exports_external.literal(1),
3564
- runId: IdentifierSchema,
3565
- createdAt: IsoDateSchema,
3566
- status: exports_external.enum(["complete", "inconclusive", "cancelled"]),
3567
- baseline: EvaluationCandidateV1Schema,
3568
- candidate: EvaluationCandidateV1Schema,
3569
- taskSet: exports_external.object({
3570
- id: IdentifierSchema,
3571
- contentHash: Sha256Schema,
3572
- taskIds: exports_external.array(IdentifierSchema).min(1)
3573
- }).strict(),
3574
- split: EvaluationSplitSchema,
3575
- seed: exports_external.string().min(1).max(500),
3576
- models: exports_external.array(exports_external.string().min(1).max(300)).min(1),
3577
- environment: EnvironmentFingerprintV1Schema,
3578
- budgets: EvaluationBudgetsV1Schema,
3579
- results: exports_external.array(EvaluationResultV1Schema),
3580
- cost: CostRecordSchema,
3581
- integrityHash: Sha256Schema
3582
- }).strict().superRefine((run, ctx) => {
3583
- if (run.environment.taskSetHash !== run.taskSet.contentHash) {
3584
- ctx.addIssue({
3585
- code: "custom",
3586
- path: ["environment", "taskSetHash"],
3587
- message: "environment and task-set hashes must agree"
3588
- });
3589
- }
3590
- const allowed = new Set([run.baseline.id, run.candidate.id]);
3591
- if (allowed.size !== 2) {
3592
- ctx.addIssue({
3593
- code: "custom",
3594
- path: ["candidate", "id"],
3595
- message: "baseline and candidate ids must differ"
3596
- });
3597
- }
3598
- if (run.results.some((result) => !allowed.has(result.candidateId))) {
3599
- ctx.addIssue({
3600
- code: "custom",
3601
- path: ["results"],
3602
- message: "results may only reference the declared baseline and candidate"
3603
- });
3604
- }
3605
- const taskIds = new Set(run.taskSet.taskIds);
3606
- if (run.results.some((result) => !taskIds.has(result.taskId))) {
3607
- ctx.addIssue({
3608
- code: "custom",
3609
- path: ["results"],
3610
- message: "results may only reference tasks in the frozen task set"
3611
- });
3612
- }
3613
- const resultKeys = run.results.map((result) => `${result.candidateId}\x00${result.taskId}\x00${result.repetition}`);
3614
- if (new Set(resultKeys).size !== resultKeys.length) {
3615
- ctx.addIssue({
3616
- code: "custom",
3617
- path: ["results"],
3618
- message: "run contains duplicate candidate/task/repetition results"
3619
- });
3620
- }
3621
- if (run.results.some((result) => result.repetition >= run.budgets.maxRepetitions)) {
3622
- ctx.addIssue({
3623
- code: "custom",
3624
- path: ["results"],
3625
- message: "result repetition exceeds the declared run budget"
3626
- });
3627
- }
3628
- });
3629
- var PromotionPolicyV1Schema = exports_external.object({
3630
- v: exports_external.literal(1),
3631
- minValidPairs: exports_external.number().int().positive().default(6),
3632
- minCoverage: exports_external.number().min(0).max(1).default(0.8),
3633
- deadband: exports_external.number().min(0).max(1).default(0),
3634
- confidence: exports_external.literal(0.95).default(0.95),
3635
- bootstrapResamples: exports_external.literal(1e4).default(1e4),
3636
- requireAvailableCosts: exports_external.boolean().default(true),
3637
- protectedCategoryTolerances: exports_external.record(exports_external.string(), exports_external.number().min(0).max(1)).default({})
3638
- }).strict();
3639
- var PromotionComparisonSchema = exports_external.object({
3640
- baselineRunId: IdentifierSchema,
3641
- baselineCandidateId: IdentifierSchema,
3642
- baselineMean: exports_external.number().min(0).max(1),
3643
- candidateMean: exports_external.number().min(0).max(1),
3644
- pairedDelta: exports_external.number().min(-1).max(1),
3645
- confidenceInterval: exports_external.tuple([
3646
- exports_external.number().min(-1).max(1),
3647
- exports_external.number().min(-1).max(1)
3648
- ]),
3649
- validPairs: exports_external.number().int().nonnegative(),
3650
- missingPairs: exports_external.number().int().nonnegative(),
3651
- coverage: exports_external.number().min(0).max(1)
3652
- }).strict();
3653
- var PromotionDecisionV1Schema = exports_external.object({
3654
- v: exports_external.literal(1),
3655
- decisionId: IdentifierSchema,
3656
- runId: IdentifierSchema,
3657
- decidedAt: IsoDateSchema,
3658
- status: exports_external.enum(["accept", "reject", "inconclusive"]),
3659
- reasons: exports_external.array(exports_external.string().min(1).max(300)),
3660
- baseline: PromotionComparisonSchema,
3661
- historicalBest: PromotionComparisonSchema,
3662
- deadband: exports_external.number().min(0).max(1),
3663
- bootstrap: exports_external.object({
3664
- resamples: exports_external.literal(1e4),
3665
- confidence: exports_external.literal(0.95),
3666
- seedHash: Sha256Schema
3667
- }).strict(),
3668
- categories: exports_external.array(exports_external.object({
3669
- category: IdentifierSchema,
3670
- protected: exports_external.boolean(),
3671
- tolerance: exports_external.number().min(0).max(1),
3672
- baselineMean: exports_external.number().min(0).max(1),
3673
- candidateMean: exports_external.number().min(0).max(1),
3674
- pairedDelta: exports_external.number().min(-1).max(1),
3675
- regression: exports_external.boolean()
3676
- }).strict()),
3677
- lineage: exports_external.object({
3678
- baselineRunId: IdentifierSchema,
3679
- historicalBestRunId: IdentifierSchema,
3680
- taskSetHash: Sha256Schema,
3681
- baselineHash: Sha256Schema,
3682
- candidateHash: Sha256Schema,
3683
- historicalBestHash: Sha256Schema
3684
- }).strict(),
3685
- policyHash: Sha256Schema,
3686
- unavailableQualityMetrics: exports_external.array(exports_external.enum(["complexity_delta", "public_api_delta"])).default(["complexity_delta", "public_api_delta"])
3687
- }).strict();
3688
- var GateNameSchema = exports_external.enum([
3689
- "reviewer",
3690
- "test-engineer",
3691
- "sast",
3692
- "mutation",
3693
- "quality"
3694
- ]);
3695
- var GateAuditManifestV1Schema = exports_external.object({
3696
- v: exports_external.literal(1),
3697
- id: IdentifierSchema,
3698
- createdAt: IsoDateSchema,
3699
- taskIds: exports_external.array(IdentifierSchema).min(1),
3700
- gates: exports_external.array(GateNameSchema).min(1),
3701
- models: exports_external.array(exports_external.string().min(1).max(300)).min(1),
3702
- preferredSwarm: IdentifierSchema.optional(),
3703
- repetitions: exports_external.number().int().positive().max(100),
3704
- seed: exports_external.string().min(1).max(500),
3705
- maxConcurrency: exports_external.number().int().positive().max(64),
3706
- maxRetries: exports_external.number().int().nonnegative().max(20),
3707
- maxTimeMs: exports_external.number().int().positive(),
3708
- maxCostUsd: exports_external.number().finite().nonnegative().optional(),
3709
- contentHash: Sha256Schema
3710
- }).strict();
3711
- var GateAuditCellV1Schema = exports_external.object({
3712
- v: exports_external.literal(1),
3713
- taskId: IdentifierSchema,
3714
- candidateId: IdentifierSchema.optional(),
3715
- defectType: IdentifierSchema,
3716
- gate: GateNameSchema,
3717
- model: exports_external.string().min(1).max(300),
3718
- repetition: exports_external.number().int().nonnegative(),
3719
- outcome: exports_external.enum([
3720
- "caught",
3721
- "missed",
3722
- "false_rejection",
3723
- "unsupported",
3724
- "infrastructure_failure"
3725
- ]),
3726
- retries: exports_external.number().int().nonnegative(),
3727
- cost: CostRecordSchema,
3728
- durationMs: exports_external.number().int().nonnegative(),
3729
- failureClassification: exports_external.enum([
3730
- "clean",
3731
- "pre_existing_failure",
3732
- "new_regression",
3733
- "flaky_failure",
3734
- "infrastructure_failure",
3735
- "unknown_failure"
3736
- ]).optional(),
3737
- failureCode: exports_external.string().min(1).max(160).optional()
3738
- }).strict();
3739
- var GateAuditResultV1Schema = exports_external.object({
3740
- v: exports_external.literal(1),
3741
- runId: IdentifierSchema,
3742
- manifestHash: Sha256Schema,
3743
- createdAt: IsoDateSchema,
3744
- status: exports_external.enum(["complete", "inconclusive", "cancelled"]),
3745
- cells: exports_external.array(GateAuditCellV1Schema),
3746
- cost: CostRecordSchema,
3747
- qualityMetricAvailability: exports_external.object({
3748
- complexity_delta: exports_external.literal("unavailable"),
3749
- public_api_delta: exports_external.literal("unavailable")
3750
- }).strict()
3751
- }).strict();
3752
- var TestConsumptionClaimV1Schema = exports_external.object({
3753
- v: exports_external.literal(1),
3754
- runId: IdentifierSchema,
3755
- taskSetHash: Sha256Schema,
3756
- baselineHash: Sha256Schema,
3757
- candidateHash: Sha256Schema,
3758
- claimedAt: IsoDateSchema
3759
- }).strict();
3760
- var TaskSetSnapshotV1Schema = exports_external.object({
3761
- v: exports_external.literal(1),
3762
- id: IdentifierSchema,
3763
- split: EvaluationSplitSchema,
3764
- tasks: exports_external.array(EvaluationTaskV1Schema).min(1),
3765
- contentHash: Sha256Schema,
3766
- createdAt: IsoDateSchema
3767
- }).strict();
3768
-
3769
- // src/evaluation/store.ts
3770
- import { mkdir as mkdir2, readdir, readFile as readFile3 } from "fs/promises";
3771
- import * as path10 from "path";
3772
-
3773
- // src/evidence/immutable-store.ts
3774
- import { mkdir, readFile } from "fs/promises";
3775
3396
  import * as path8 from "path";
3776
- async function readOptionalFile(filePath) {
3777
- try {
3778
- return await readFile(filePath, "utf8");
3779
- } catch (error2) {
3780
- if (error2.code === "ENOENT")
3781
- return;
3782
- throw error2;
3783
- }
3784
- }
3785
- async function writeImmutableArtifact(options) {
3786
- await mkdir(path8.dirname(options.filePath), { recursive: true });
3787
- return withEvidenceLock(options.directory, options.relativeLockPath, options.agent, options.taskId, async () => {
3788
- const desired = options.serialize(options.value);
3789
- const existing = await readOptionalFile(options.filePath);
3790
- if (existing !== undefined) {
3791
- let parsed;
3792
- try {
3793
- parsed = options.parse(JSON.parse(existing));
3794
- } catch (error2) {
3795
- throw options.conflictError({
3796
- kind: "corrupt",
3797
- filePath: options.filePath,
3798
- cause: error2
3799
- });
3800
- }
3801
- if (options.serialize(parsed) === desired || options.isEquivalent?.(parsed, options.value)) {
3802
- return parsed;
3803
- }
3804
- throw options.conflictError({
3805
- kind: "divergent",
3806
- filePath: options.filePath
3807
- });
3808
- }
3809
- await atomicWriteFile(options.filePath, desired);
3810
- return options.value;
3811
- });
3812
- }
3813
-
3814
- // src/evaluation/hashing.ts
3815
- import { createHash as createHash2 } from "crypto";
3816
- import { lstatSync, realpathSync } from "fs";
3817
- import { lstat, opendir, readFile as readFile2, realpath } from "fs/promises";
3818
- import * as path9 from "path";
3819
- function canonicalize(value, ancestors) {
3820
- if (value === null || typeof value === "string" || typeof value === "boolean") {
3821
- return value;
3822
- }
3823
- if (typeof value === "number") {
3824
- if (!Number.isFinite(value))
3825
- throw new TypeError("canonical JSON rejects non-finite numbers");
3826
- return Object.is(value, -0) ? 0 : value;
3827
- }
3828
- if (value === undefined)
3829
- return;
3830
- if (typeof value !== "object") {
3831
- throw new TypeError(`canonical JSON cannot encode ${typeof value}`);
3832
- }
3833
- if (ancestors.has(value))
3834
- throw new TypeError("canonical JSON rejects cyclic values");
3835
- ancestors.add(value);
3836
- try {
3837
- if (Array.isArray(value)) {
3838
- return value.map((entry) => {
3839
- const encoded = canonicalize(entry, ancestors);
3840
- return encoded === undefined ? null : encoded;
3841
- });
3842
- }
3843
- const record = value;
3844
- const result = {};
3845
- for (const key of Object.keys(record).sort()) {
3846
- const encoded = canonicalize(record[key], ancestors);
3847
- if (encoded !== undefined)
3848
- result[key] = encoded;
3849
- }
3850
- return result;
3851
- } finally {
3852
- ancestors.delete(value);
3853
- }
3854
- }
3855
- function canonicalJson(value) {
3856
- return JSON.stringify(canonicalize(value, new Set));
3857
- }
3858
- function sha256(value) {
3859
- return createHash2("sha256").update(value).digest("hex");
3860
- }
3861
- function canonicalHash(value) {
3862
- return sha256(canonicalJson(value));
3863
- }
3864
- function contentHashWithout(value, keys) {
3865
- const copy = { ...value };
3866
- for (const key of keys)
3867
- delete copy[key];
3868
- return canonicalHash(copy);
3869
- }
3870
- function createHashBudget(limits) {
3871
- return { entries: 0, bytes: 0, limits };
3872
- }
3873
- function chargeHashEntry(budget) {
3874
- budget.entries++;
3875
- if (budget.entries > budget.limits.maxFiles) {
3876
- throw new Error("evaluation input exceeds the canonical hashing budget");
3877
- }
3878
- }
3879
- async function closeDirectory(directory) {
3880
- try {
3881
- await directory.close();
3882
- } catch (error2) {
3883
- if (typeof error2 !== "object" || error2 === null || !("code" in error2) || error2.code !== "ERR_DIR_CLOSED") {
3884
- throw error2;
3885
- }
3886
- }
3887
- }
3888
- function resolveTaskInputHashLimits(limits) {
3889
- const bounded = {
3890
- maxFiles: limits.maxFiles ?? 5000,
3891
- maxBytes: limits.maxBytes ?? 50 * 1024 * 1024
3892
- };
3893
- if (!Number.isSafeInteger(bounded.maxFiles) || bounded.maxFiles <= 0 || !Number.isSafeInteger(bounded.maxBytes) || bounded.maxBytes <= 0) {
3894
- throw new Error("task input hash limits must be positive safe integers");
3895
- }
3896
- return bounded;
3897
- }
3898
- async function hashTree(projectRoot, relativePath, budget) {
3899
- const target = await resolveContainedExistingPathAsync(projectRoot, relativePath);
3900
- const canonicalRoot = await _internals9.realpath(projectRoot);
3901
- const entries = [];
3902
- const visit = async (absolutePath, entryAlreadyCharged = false) => {
3903
- const stat = await _internals9.lstat(absolutePath);
3904
- if (stat.isSymbolicLink()) {
3905
- throw new Error(`evaluation input contains a symlink or reparse point: ${relativePath}`);
3906
- }
3907
- if (!entryAlreadyCharged)
3908
- chargeHashEntry(budget);
3909
- const relative2 = path9.relative(canonicalRoot, absolutePath).replace(/\\/g, "/");
3910
- if (stat.isDirectory()) {
3911
- entries.push({ path: relative2, type: "directory" });
3912
- const children = [];
3913
- const directory = await _internals9.opendir(absolutePath);
3914
- try {
3915
- while (true) {
3916
- const child = await directory.read();
3917
- if (!child)
3918
- break;
3919
- chargeHashEntry(budget);
3920
- children.push(child.name);
3921
- }
3922
- } finally {
3923
- await closeDirectory(directory);
3924
- }
3925
- for (const child of children.sort()) {
3926
- await visit(path9.join(absolutePath, child), true);
3927
- }
3928
- return;
3929
- }
3930
- if (!stat.isFile()) {
3931
- throw new Error(`evaluation input must contain only regular files: ${relative2}`);
3932
- }
3933
- budget.bytes += stat.size;
3934
- if (budget.bytes > budget.limits.maxBytes) {
3935
- throw new Error("evaluation input exceeds the canonical hashing budget");
3936
- }
3937
- const content = await _internals9.readFile(absolutePath);
3938
- entries.push({
3939
- path: relative2,
3940
- type: "file",
3941
- bytes: content.byteLength,
3942
- sha256: sha256(content)
3943
- });
3944
- };
3945
- await visit(target);
3946
- return entries;
3947
- }
3948
- async function computeTaskInputContentHash(projectRoot, task, limits = {}) {
3949
- const bounded = resolveTaskInputHashLimits(limits);
3950
- const budget = createHashBudget(bounded);
3951
- const inputTrees = [
3952
- ...await hashTree(projectRoot, task.instructionPath, budget),
3953
- ...await hashTree(projectRoot, task.environment.path, budget)
3954
- ];
3955
- if (task.scorer.kind === "project" && task.scorer.argv[0]) {
3956
- inputTrees.push(...await hashTree(projectRoot, task.scorer.argv[0], budget));
3957
- }
3958
- return canonicalHash({
3959
- task: JSON.parse(canonicalJson({ ...task, contentHash: undefined })),
3960
- inputs: inputTrees.sort((left, right) => `${left.path}\x00${left.type}`.localeCompare(`${right.path}\x00${right.type}`))
3961
- });
3962
- }
3963
- async function computeTaskLineageInputHash(projectRoot, task, limits = {}) {
3964
- const bounded = resolveTaskInputHashLimits(limits);
3965
- const budget = createHashBudget(bounded);
3966
- const normalizedTree = async (relativePath) => {
3967
- const canonicalRoot = await _internals9.realpath(projectRoot);
3968
- const target = await resolveContainedExistingPathAsync(projectRoot, relativePath);
3969
- const targetRelative = path9.relative(canonicalRoot, target).replace(/\\/g, "/");
3970
- return (await hashTree(projectRoot, relativePath, budget)).map((entry) => ({
3971
- ...entry,
3972
- path: path9.posix.relative(targetRelative, entry.path) || "."
3973
- }));
3974
- };
3975
- const scorerArgv = [...task.scorer.argv];
3976
- const projectScorer = task.scorer.kind === "project" && scorerArgv[0] ? await normalizedTree(scorerArgv[0]) : undefined;
3977
- if (projectScorer)
3978
- scorerArgv[0] = "<project-scorer>";
3979
- return canonicalHash({
3980
- instruction: await normalizedTree(task.instructionPath),
3981
- environment: {
3982
- kind: task.environment.kind,
3983
- tree: await normalizedTree(task.environment.path)
3984
- },
3985
- scorer: {
3986
- kind: task.scorer.kind,
3987
- argv: scorerArgv,
3988
- timeoutMs: task.scorer.timeoutMs,
3989
- scoreRange: task.scorer.scoreRange,
3990
- projectScorer
3991
- }
3992
- });
3993
- }
3994
- function computeTaskSetContentHash(snapshot) {
3995
- return contentHashWithout(snapshot, ["contentHash", "createdAt"]);
3996
- }
3997
- function computeManifestContentHash(manifest) {
3998
- return contentHashWithout(manifest, ["contentHash"]);
3999
- }
4000
- function isWithin(root, candidate) {
4001
- const relative2 = path9.relative(root, candidate);
4002
- return relative2 === "" || !relative2.startsWith("..") && !path9.isAbsolute(relative2);
4003
- }
4004
- function resolveContainedExistingPath(root, relativePath) {
4005
- if (path9.isAbsolute(relativePath) || /^(?:[A-Za-z]:[\\/]|[\\/]{1,2})/.test(relativePath) || relativePath.includes("\x00")) {
4006
- throw new Error("evaluation path must be a non-NUL relative path");
4007
- }
4008
- const segments = relativePath.replace(/\\/g, "/").split("/").filter(Boolean);
4009
- if (segments.length === 0 || segments.some((segment) => segment === "..")) {
4010
- throw new Error("evaluation path traversal is not allowed");
4011
- }
4012
- const canonicalRoot = realpathSync(root);
4013
- let cursor = canonicalRoot;
4014
- for (const segment of segments) {
4015
- if (segment === ".")
4016
- continue;
4017
- cursor = path9.join(cursor, segment);
4018
- const stat = lstatSync(cursor);
4019
- if (stat.isSymbolicLink()) {
4020
- throw new Error(`evaluation path contains a symlink or reparse point: ${relativePath}`);
4021
- }
4022
- }
4023
- const canonicalCandidate = realpathSync(cursor);
4024
- if (!isWithin(canonicalRoot, canonicalCandidate)) {
4025
- throw new Error("evaluation path escapes its admitted root");
4026
- }
4027
- return canonicalCandidate;
4028
- }
4029
- async function resolveContainedExistingPathAsync(root, relativePath) {
4030
- if (path9.isAbsolute(relativePath) || /^(?:[A-Za-z]:[\\/]|[\\/]{1,2})/.test(relativePath) || relativePath.includes("\x00")) {
4031
- throw new Error("evaluation path must be a non-NUL relative path");
4032
- }
4033
- const segments = relativePath.replace(/\\/g, "/").split("/").filter(Boolean);
4034
- if (segments.length === 0 || segments.some((segment) => segment === "..")) {
4035
- throw new Error("evaluation path traversal is not allowed");
4036
- }
4037
- const canonicalRoot = await _internals9.realpath(root);
4038
- let cursor = canonicalRoot;
4039
- for (const segment of segments) {
4040
- if (segment === ".")
4041
- continue;
4042
- cursor = path9.join(cursor, segment);
4043
- const stat = await _internals9.lstat(cursor);
4044
- if (stat.isSymbolicLink()) {
4045
- throw new Error(`evaluation path contains a symlink or reparse point: ${relativePath}`);
4046
- }
4047
- }
4048
- const canonicalCandidate = await _internals9.realpath(cursor);
4049
- if (!isWithin(canonicalRoot, canonicalCandidate)) {
4050
- throw new Error("evaluation path escapes its admitted root");
4051
- }
4052
- return canonicalCandidate;
4053
- }
4054
- var _internals9 = {
4055
- lstat,
4056
- opendir,
4057
- readFile: readFile2,
4058
- realpath
4059
- };
4060
-
4061
- // src/evaluation/store.ts
4062
- var AGENT = "evaluation-store";
4063
- var TEST_LEDGER_RELATIVE = path10.join("evolution", "test-consumption.jsonl");
4064
- var TASK_SPLIT_REGISTRY_RELATIVE = path10.join("evolution", "tasks", "split-registry.json");
4065
-
4066
- class EvaluationConflictError extends Error {
4067
- constructor(message) {
4068
- super(message);
4069
- this.name = "EvaluationConflictError";
4070
- }
4071
- }
4072
- function swarmPath(directory, ...segments) {
4073
- return path10.join(directory, ".swarm", ...segments);
4074
- }
4075
- function serialized(value) {
4076
- return `${canonicalJson(value)}
4077
- `;
4078
- }
4079
- function parseTaskSplitRegistry(content) {
4080
- if (content === undefined)
4081
- return { v: 1, entries: [] };
4082
- let value;
4083
- try {
4084
- value = JSON.parse(content);
4085
- } catch (error2) {
4086
- throw new EvaluationConflictError(`task split registry is corrupt: ${String(error2)}`);
4087
- }
4088
- if (!value || typeof value !== "object" || Array.isArray(value)) {
4089
- throw new EvaluationConflictError("task split registry is corrupt");
4090
- }
4091
- const record = value;
4092
- if (record.v !== 1 || !Array.isArray(record.entries)) {
4093
- throw new EvaluationConflictError("task split registry is corrupt");
4094
- }
4095
- const entries = record.entries.map((candidate) => {
4096
- if (!candidate || typeof candidate !== "object" || Array.isArray(candidate)) {
4097
- throw new EvaluationConflictError("task split registry is corrupt");
4098
- }
4099
- const entry = candidate;
4100
- if (typeof entry.lineageHash !== "string" || !["train", "validation", "test"].includes(String(entry.split)) || !Array.isArray(entry.taskIds) || !entry.taskIds.every((id) => typeof id === "string") || !Array.isArray(entry.inputHashes) || !entry.inputHashes.every((hash) => typeof hash === "string")) {
4101
- throw new EvaluationConflictError("task split registry is corrupt");
4102
- }
4103
- return {
4104
- lineageHash: entry.lineageHash,
4105
- split: entry.split,
4106
- taskIds: [...new Set(entry.taskIds)].sort(),
4107
- inputHashes: [...new Set(entry.inputHashes)].sort()
4108
- };
4109
- });
4110
- return { v: 1, entries };
4111
- }
4112
- function evaluationConflictError(conflict) {
4113
- return conflict.kind === "corrupt" ? new EvaluationConflictError(`existing evaluation artifact is corrupt: ${conflict.filePath}: ${String(conflict.cause)}`) : new EvaluationConflictError(`immutable evaluation artifact conflicts with existing content: ${conflict.filePath}`);
4114
- }
4115
- function writeImmutable(options) {
4116
- return writeImmutableArtifact({
4117
- ...options,
4118
- agent: AGENT,
4119
- serialize: serialized,
4120
- conflictError: evaluationConflictError
4121
- });
4122
- }
4123
- function validateTaskInputs(directory, task) {
4124
- resolveContainedExistingPath(directory, task.instructionPath);
4125
- const environmentRoot = resolveContainedExistingPath(directory, task.environment.path);
4126
- if (task.scorer.kind === "project") {
4127
- const executable = task.scorer.argv[0];
4128
- if (!executable)
4129
- throw new Error("project scorer requires an executable");
4130
- const scorerPath = resolveContainedExistingPath(directory, executable);
4131
- const relative3 = path10.relative(environmentRoot, scorerPath);
4132
- if (!relative3 || relative3 === ".." || relative3.startsWith(`..${path10.sep}`) || path10.isAbsolute(relative3)) {
4133
- throw new Error("project scorer executable must be inside the admitted task environment");
4134
- }
4135
- }
4136
- }
4137
- async function admitEvaluationTask(directory, input, inputRoot = directory) {
4138
- const task = EvaluationTaskV1Schema.parse(input);
4139
- if (await computeTaskInputContentHash(inputRoot, task) !== task.contentHash) {
4140
- throw new Error(`task ${task.id} content hash does not match its canonical inputs`);
4141
- }
4142
- validateTaskInputs(inputRoot, task);
4143
- const lineageInputHash = await computeTaskLineageInputHash(inputRoot, task);
4144
- const relative3 = path10.join("evolution", "tasks", task.split, `${task.id}.json`);
4145
- const admissionLock = TASK_SPLIT_REGISTRY_RELATIVE;
4146
- const filePath = swarmPath(directory, relative3);
4147
- await mkdir2(path10.dirname(filePath), { recursive: true });
4148
- return withEvidenceLock(directory, admissionLock, AGENT, task.id, async () => {
4149
- const registryPath = swarmPath(directory, TASK_SPLIT_REGISTRY_RELATIVE);
4150
- const registry = parseTaskSplitRegistry(await readOptionalFile(registryPath));
4151
- const existingTaskEntry = registry.entries.find((entry) => entry.taskIds.includes(task.id));
4152
- if (existingTaskEntry && existingTaskEntry.split !== task.split) {
4153
- throw new EvaluationConflictError(`task ${task.id} is already admitted to a different split`);
4154
- }
4155
- const parentEntry = task.derivedFromTaskId ? registry.entries.find((entry) => entry.taskIds.includes(task.derivedFromTaskId)) : undefined;
4156
- if (task.derivedFromTaskId && !parentEntry) {
4157
- throw new EvaluationConflictError(`derived task ${task.id} references an unadmitted parent ${task.derivedFromTaskId}`);
4158
- }
4159
- const lineageEntry = parentEntry ?? registry.entries.find((entry) => entry.lineageHash === lineageInputHash || entry.inputHashes.includes(lineageInputHash));
4160
- if (lineageEntry && lineageEntry.split !== task.split) {
4161
- throw new EvaluationConflictError(`task ${task.id} lineage is already admitted to ${lineageEntry.split}; derived and aliased tasks must inherit that split`);
4162
- }
4163
- for (const split of ["train", "validation", "test"]) {
4164
- if (split === task.split)
4165
- continue;
4166
- if (await readOptionalFile(swarmPath(directory, "evolution", "tasks", split, `${task.id}.json`))) {
4167
- throw new EvaluationConflictError(`task ${task.id} is already admitted to a different split`);
4168
- }
4169
- }
4170
- const desired = serialized(task);
4171
- const existing = await readOptionalFile(filePath);
4172
- if (existing !== undefined) {
4173
- const parsed = EvaluationTaskV1Schema.parse(JSON.parse(existing));
4174
- if (serialized(parsed) === desired) {
4175
- if (lineageEntry) {
4176
- lineageEntry.taskIds = [
4177
- ...new Set([...lineageEntry.taskIds, task.id])
4178
- ].sort();
4179
- lineageEntry.inputHashes = [
4180
- ...new Set([...lineageEntry.inputHashes, lineageInputHash])
4181
- ].sort();
4182
- } else {
4183
- registry.entries.push({
4184
- lineageHash: lineageInputHash,
4185
- split: task.split,
4186
- taskIds: [task.id],
4187
- inputHashes: [lineageInputHash]
4188
- });
4189
- }
4190
- registry.entries.sort((left, right) => left.lineageHash.localeCompare(right.lineageHash));
4191
- await atomicWriteFile(registryPath, serialized(registry));
4192
- return parsed;
4193
- }
4194
- if (task.split !== "train") {
4195
- throw new EvaluationConflictError(`${task.split} task ${task.id} is immutable after admission`);
4196
- }
4197
- }
4198
- await atomicWriteFile(filePath, desired);
4199
- if (lineageEntry) {
4200
- lineageEntry.taskIds = [
4201
- ...new Set([...lineageEntry.taskIds, task.id])
4202
- ].sort();
4203
- lineageEntry.inputHashes = [
4204
- ...new Set([...lineageEntry.inputHashes, lineageInputHash])
4205
- ].sort();
4206
- } else {
4207
- registry.entries.push({
4208
- lineageHash: lineageInputHash,
4209
- split: task.split,
4210
- taskIds: [task.id],
4211
- inputHashes: [lineageInputHash]
4212
- });
4213
- }
4214
- registry.entries.sort((left, right) => left.lineageHash.localeCompare(right.lineageHash));
4215
- await atomicWriteFile(registryPath, serialized(registry));
4216
- return task;
4217
- });
4218
- }
4219
- async function saveTaskSetSnapshot(directory, input, inputRoot = directory) {
4220
- const snapshot = TaskSetSnapshotV1Schema.parse(input);
4221
- const ids = snapshot.tasks.map((task) => task.id);
4222
- if (new Set(ids).size !== ids.length)
4223
- throw new Error("task-set contains duplicate task ids");
4224
- if (snapshot.tasks.some((task) => task.split !== snapshot.split)) {
4225
- throw new Error("task-set tasks must all belong to the declared split");
4226
- }
4227
- for (const task of snapshot.tasks) {
4228
- if (await computeTaskInputContentHash(inputRoot, task) !== task.contentHash) {
4229
- throw new Error(`task ${task.id} content hash is invalid`);
4230
- }
4231
- }
4232
- if (computeTaskSetContentHash(snapshot) !== snapshot.contentHash) {
4233
- throw new Error("task-set content hash does not match its canonical inputs");
4234
- }
4235
- const relative3 = path10.join("evolution", "task-sets", `${snapshot.contentHash}.json`);
4236
- return writeImmutable({
4237
- directory,
4238
- relativeLockPath: relative3,
4239
- filePath: swarmPath(directory, relative3),
4240
- taskId: snapshot.id,
4241
- value: snapshot,
4242
- parse: (value) => TaskSetSnapshotV1Schema.parse(value),
4243
- isEquivalent: (existing, desired) => existing.contentHash === desired.contentHash
4244
- });
4245
- }
4246
- async function saveGateAuditResult(directory, input) {
4247
- const result = GateAuditResultV1Schema.parse(input);
4248
- const relative3 = path10.join("evidence", "gate-audit", result.runId, "results.json");
4249
- return writeImmutable({
4250
- directory,
4251
- relativeLockPath: relative3,
4252
- filePath: swarmPath(directory, relative3),
4253
- taskId: result.runId,
4254
- value: result,
4255
- parse: (value) => GateAuditResultV1Schema.parse(value)
4256
- });
4257
- }
4258
- async function saveGateAuditManifest(directory, input) {
4259
- const manifest = GateAuditManifestV1Schema.parse(input);
4260
- const relative3 = path10.join("evolution", "gate-audit-manifests", `${manifest.id}.json`);
4261
- return writeImmutable({
4262
- directory,
4263
- relativeLockPath: relative3,
4264
- filePath: swarmPath(directory, relative3),
4265
- taskId: manifest.id,
4266
- value: manifest,
4267
- parse: (value) => GateAuditManifestV1Schema.parse(value)
4268
- });
4269
- }
4270
- async function readGateAuditManifest(directory, runId) {
4271
- const content = await readOptionalFile(swarmPath(directory, "evolution", "gate-audit-manifests", `${runId}.json`));
4272
- return content === undefined ? undefined : GateAuditManifestV1Schema.parse(JSON.parse(content));
4273
- }
4274
- async function readGateAuditResult(directory, runId) {
4275
- const content = await readOptionalFile(swarmPath(directory, "evidence", "gate-audit", runId, "results.json"));
4276
- return content === undefined ? undefined : GateAuditResultV1Schema.parse(JSON.parse(content));
4277
- }
4278
- async function listGateAuditResults(directory) {
4279
- const root = swarmPath(directory, "evidence", "gate-audit");
4280
- let entries = [];
4281
- try {
4282
- entries = await readdir(root, { withFileTypes: true });
4283
- } catch (error2) {
4284
- if (error2.code === "ENOENT") {
4285
- return { results: [], corruptRunIds: [] };
4286
- }
4287
- throw error2;
4288
- }
4289
- const results = [];
4290
- const corruptRunIds = [];
4291
- for (const entry of entries.sort((left, right) => left.name.localeCompare(right.name))) {
4292
- if (!entry.isDirectory() || !/^[A-Za-z0-9][A-Za-z0-9._-]{0,159}$/.test(entry.name)) {
4293
- continue;
4294
- }
4295
- try {
4296
- const parsed = GateAuditResultV1Schema.parse(JSON.parse(await readFile3(path10.join(root, entry.name, "results.json"), "utf8")));
4297
- if (parsed.runId !== entry.name)
4298
- throw new Error("run id/path mismatch");
4299
- results.push(parsed);
4300
- } catch {
4301
- corruptRunIds.push(entry.name);
4302
- }
4303
- }
4304
- return { results, corruptRunIds };
4305
- }
4306
- function parseTestLedger(content) {
4307
- return content.split(/\r?\n/).filter((line) => line.trim().length > 0).map((line, index) => {
4308
- try {
4309
- return TestConsumptionClaimV1Schema.parse(JSON.parse(line));
4310
- } catch (error2) {
4311
- throw new EvaluationConflictError(`test-consumption ledger is corrupt at line ${index + 1}: ${String(error2)}`);
4312
- }
4313
- });
4314
- }
4315
- async function getProtectedEvaluationRunIds(directory) {
4316
- const protectedIds = new Set;
4317
- const ledger = await readOptionalFile(swarmPath(directory, TEST_LEDGER_RELATIVE));
4318
- for (const claim of parseTestLedger(ledger ?? ""))
4319
- protectedIds.add(claim.runId);
4320
- const decisionsDirectory = swarmPath(directory, "evolution", "decisions");
4321
- let files = [];
4322
- try {
4323
- files = await readdir(decisionsDirectory);
4324
- } catch (error2) {
4325
- if (error2.code !== "ENOENT")
4326
- throw error2;
4327
- }
4328
- for (const filename of files.filter((value) => value.endsWith(".json")).sort()) {
4329
- const decision = PromotionDecisionV1Schema.parse(JSON.parse(await readFile3(path10.join(decisionsDirectory, filename), "utf8")));
4330
- protectedIds.add(decision.runId);
4331
- protectedIds.add(decision.lineage.baselineRunId);
4332
- if (decision.lineage.historicalBestRunId !== "unavailable") {
4333
- protectedIds.add(decision.lineage.historicalBestRunId);
4334
- }
4335
- }
4336
- return protectedIds;
4337
- }
4338
-
4339
- // src/evaluation/retention.ts
4340
3397
  function artifactKey(artifact) {
4341
3398
  return `${artifact.namespace}/${artifact.id}`;
4342
3399
  }
@@ -4344,7 +3401,7 @@ function validId(value) {
4344
3401
  return /^[A-Za-z0-9][A-Za-z0-9._-]{0,159}$/.test(value);
4345
3402
  }
4346
3403
  async function evaluationRunCandidates(directory) {
4347
- const root = path11.join(directory, ".swarm", "evolution", "runs");
3404
+ const root = path8.join(directory, ".swarm", "evolution", "runs");
4348
3405
  let entries = [];
4349
3406
  try {
4350
3407
  entries = await fs4.readdir(root, { withFileTypes: true });
@@ -4363,7 +3420,7 @@ async function evaluationRunCandidates(directory) {
4363
3420
  if (!validId(id))
4364
3421
  continue;
4365
3422
  const artifact = { namespace: "evaluation-run", id };
4366
- const target = path11.join(root, entry.name);
3423
+ const target = path8.join(root, entry.name);
4367
3424
  try {
4368
3425
  const run = EvaluationRunV1Schema.parse(JSON.parse(await fs4.readFile(target, "utf8")));
4369
3426
  if (run.runId !== id)
@@ -4381,7 +3438,7 @@ async function evaluationRunCandidates(directory) {
4381
3438
  return { candidates, corrupt };
4382
3439
  }
4383
3440
  async function gateAuditCandidates(directory) {
4384
- const root = path11.join(directory, ".swarm", "evidence", "gate-audit");
3441
+ const root = path8.join(directory, ".swarm", "evidence", "gate-audit");
4385
3442
  let entries = [];
4386
3443
  try {
4387
3444
  entries = await fs4.readdir(root, { withFileTypes: true });
@@ -4397,9 +3454,9 @@ async function gateAuditCandidates(directory) {
4397
3454
  if (!entry.isDirectory() || !validId(entry.name))
4398
3455
  continue;
4399
3456
  const artifact = { namespace: "gate-audit", id: entry.name };
4400
- const target = path11.join(root, entry.name);
3457
+ const target = path8.join(root, entry.name);
4401
3458
  try {
4402
- const result = GateAuditResultV1Schema.parse(JSON.parse(await fs4.readFile(path11.join(target, "results.json"), "utf8")));
3459
+ const result = GateAuditResultV1Schema.parse(JSON.parse(await fs4.readFile(path8.join(target, "results.json"), "utf8")));
4403
3460
  if (result.runId !== entry.name)
4404
3461
  throw new Error("run id/path mismatch");
4405
3462
  candidates.push({
@@ -4440,7 +3497,7 @@ var _retentionInternals = {
4440
3497
  removeCandidate
4441
3498
  };
4442
3499
  async function archiveEvaluationArtifacts(args) {
4443
- return withEvidenceLock(args.directory, path11.join("evolution", "retention-index"), "evaluation-retention", "archive", async () => {
3500
+ return withEvidenceLock(args.directory, path8.join("evolution", "retention-index"), "evaluation-retention", "archive", async () => {
4444
3501
  const inventory = await retentionCandidates(args.directory);
4445
3502
  let protectedKeys = await _retentionInternals.protectedArtifacts(args.directory);
4446
3503
  const protectedRefs = inventory.candidates.filter((candidate) => protectedKeys.has(artifactKey(candidate.artifact))).map((candidate) => candidate.artifact);
@@ -4497,7 +3554,7 @@ var MAX_READ_BYTES = 100 * 1024 * 1024;
4497
3554
  var RENAME_MAX_ATTEMPTS = 5;
4498
3555
  var RENAME_BACKOFF_MS = 10;
4499
3556
  var RENAME_RETRY_CODES = new Set(["EPERM", "EBUSY", "ENOTEMPTY", "EACCES"]);
4500
- var _internals10 = {
3557
+ var _internals9 = {
4501
3558
  stat: (p) => fsp.stat(p),
4502
3559
  createReadStream: (p, options) => fs5.createReadStream(p, options),
4503
3560
  openSync: (p, flags) => fs5.openSync(p, flags),
@@ -4539,9 +3596,9 @@ function emptyResult(dryRun) {
4539
3596
  };
4540
3597
  }
4541
3598
  async function readCacheRows(filePath) {
4542
- const stat2 = await _internals10.stat(filePath);
3599
+ const stat2 = await _internals9.stat(filePath);
4543
3600
  const bytesBefore = stat2.size;
4544
- const stream = _internals10.createReadStream(filePath, {
3601
+ const stream = _internals9.createReadStream(filePath, {
4545
3602
  encoding: "utf8",
4546
3603
  highWaterMark: 64 * 1024
4547
3604
  });
@@ -4617,23 +3674,23 @@ async function rewriteAtomic(filePath, survivors) {
4617
3674
  `)}
4618
3675
  ` : "";
4619
3676
  let succeeded = false;
4620
- const fd = _internals10.openSync(tmpPath, "w");
3677
+ const fd = _internals9.openSync(tmpPath, "w");
4621
3678
  try {
4622
- _internals10.writeSync(fd, payload, 0);
4623
- _internals10.fsyncSync(fd);
4624
- _internals10.closeSync(fd);
4625
- await _internals10.renameWithRetry(tmpPath, filePath);
3679
+ _internals9.writeSync(fd, payload, 0);
3680
+ _internals9.fsyncSync(fd);
3681
+ _internals9.closeSync(fd);
3682
+ await _internals9.renameWithRetry(tmpPath, filePath);
4626
3683
  succeeded = true;
4627
3684
  } catch (err) {
4628
3685
  try {
4629
- _internals10.closeSync(fd);
3686
+ _internals9.closeSync(fd);
4630
3687
  } catch {}
4631
3688
  const msg = err instanceof Error ? err.message : String(err);
4632
3689
  throw new Error(`documents-cache rewrite failed: ${msg}`);
4633
3690
  } finally {
4634
3691
  if (!succeeded) {
4635
3692
  try {
4636
- await _internals10.unlink(tmpPath);
3693
+ await _internals9.unlink(tmpPath);
4637
3694
  } catch {}
4638
3695
  }
4639
3696
  }
@@ -4645,7 +3702,7 @@ async function pruneEvidenceDocuments(args) {
4645
3702
  const filePath = validateSwarmPath(args.directory, EVIDENCE_CACHE_FILE);
4646
3703
  let stat2;
4647
3704
  try {
4648
- stat2 = await _internals10.stat(filePath);
3705
+ stat2 = await _internals9.stat(filePath);
4649
3706
  } catch (err) {
4650
3707
  const code = err?.code;
4651
3708
  if (code === "ENOENT")
@@ -4760,11 +3817,11 @@ var PROJECT_INDICATORS = [
4760
3817
  ];
4761
3818
  function isWeakConfigContainerRoot(directory) {
4762
3819
  try {
4763
- const resolved = realpathSync2(directory);
4764
- return resolved === realpathSync2(os4.tmpdir()) || resolved === realpathSync2(os4.homedir());
3820
+ const resolved = realpathSync(directory);
3821
+ return resolved === realpathSync(os4.tmpdir()) || resolved === realpathSync(os4.homedir());
4765
3822
  } catch {
4766
- const resolved = path12.resolve(directory);
4767
- return resolved === path12.resolve(os4.tmpdir()) || resolved === path12.resolve(os4.homedir());
3823
+ const resolved = path9.resolve(directory);
3824
+ return resolved === path9.resolve(os4.tmpdir()) || resolved === path9.resolve(os4.homedir());
4768
3825
  }
4769
3826
  }
4770
3827
  function hasAccessibleProjectIndicator(directory, options = {}) {
@@ -4774,7 +3831,7 @@ function hasAccessibleProjectIndicator(directory, options = {}) {
4774
3831
  continue;
4775
3832
  }
4776
3833
  try {
4777
- const indicatorStat = statSync2(path12.join(directory, indicator));
3834
+ const indicatorStat = statSync2(path9.join(directory, indicator));
4778
3835
  if (indicatorStat.isFile() || indicatorStat.isDirectory()) {
4779
3836
  return true;
4780
3837
  }
@@ -4785,7 +3842,7 @@ function hasAccessibleProjectIndicator(directory, options = {}) {
4785
3842
  function validateProjectRoot(directory) {
4786
3843
  let resolved;
4787
3844
  try {
4788
- resolved = realpathSync2(directory);
3845
+ resolved = realpathSync(directory);
4789
3846
  } catch {
4790
3847
  warn(`[evidence] Cannot canonicalize directory "${directory}" \u2014 failing closed`);
4791
3848
  throw new Error(`Cannot verify project root for "${directory}" \u2014 directory may not exist or is inaccessible`);
@@ -4796,14 +3853,14 @@ function validateProjectRoot(directory) {
4796
3853
  if (depth >= MAX_DEPTH)
4797
3854
  break;
4798
3855
  depth++;
4799
- const parent = path12.dirname(current);
3856
+ const parent = path9.dirname(current);
4800
3857
  if (parent === current)
4801
3858
  break;
4802
- if (path12.dirname(parent) === parent) {
3859
+ if (path9.dirname(parent) === parent) {
4803
3860
  current = parent;
4804
3861
  continue;
4805
3862
  }
4806
- const parentSwarm = path12.join(parent, ".swarm");
3863
+ const parentSwarm = path9.join(parent, ".swarm");
4807
3864
  try {
4808
3865
  if (statSync2(parentSwarm).isDirectory()) {
4809
3866
  if (hasAccessibleProjectIndicator(parent, {
@@ -4822,14 +3879,14 @@ function validateProjectRoot(directory) {
4822
3879
  }
4823
3880
  }
4824
3881
  async function saveEvidence(directory, taskId, evidence) {
4825
- _internals11.validateProjectRoot(directory);
3882
+ _internals10.validateProjectRoot(directory);
4826
3883
  const sanitizedTaskId = sanitizeTaskId2(taskId);
4827
- const relativePath = path12.join("evidence", sanitizedTaskId, "evidence.json");
3884
+ const relativePath = path9.join("evidence", sanitizedTaskId, "evidence.json");
4828
3885
  validateSwarmPath(directory, relativePath);
4829
- _internals11.validateEvidence(evidence);
3886
+ _internals10.validateEvidence(evidence);
4830
3887
  return withEvidenceLock(directory, relativePath, "evidence-manager", sanitizedTaskId, async () => {
4831
3888
  const evidencePath = validateSwarmPath(directory, relativePath);
4832
- const evidenceDir = path12.dirname(evidencePath);
3889
+ const evidenceDir = path9.dirname(evidencePath);
4833
3890
  let bundle;
4834
3891
  const existingContent = await readSwarmFileAsync(directory, relativePath);
4835
3892
  if (existingContent !== null) {
@@ -4872,7 +3929,7 @@ async function saveEvidence(directory, taskId, evidence) {
4872
3929
  throw new Error(`Evidence bundle size (${bundleJson.length} bytes) exceeds maximum (${EVIDENCE_MAX_JSON_BYTES} bytes)`);
4873
3930
  }
4874
3931
  mkdirSync4(evidenceDir, { recursive: true });
4875
- const tempPath = path12.join(evidenceDir, `evidence.json.tmp.${Date.now()}.${process.pid}`);
3932
+ const tempPath = path9.join(evidenceDir, `evidence.json.tmp.${Date.now()}.${process.pid}`);
4876
3933
  try {
4877
3934
  await bunWrite(tempPath, bundleJson);
4878
3935
  await fs6.rename(tempPath, evidencePath);
@@ -4916,7 +3973,7 @@ function wrapFlatRetrospective(flatEntry, taskId) {
4916
3973
  }
4917
3974
  async function loadEvidence(directory, taskId, options) {
4918
3975
  const sanitizedTaskId = sanitizeTaskId2(taskId);
4919
- const relativePath = path12.join("evidence", sanitizedTaskId, "evidence.json");
3976
+ const relativePath = path9.join("evidence", sanitizedTaskId, "evidence.json");
4920
3977
  if (relativePath.length > 4096) {
4921
3978
  return { status: "not_found" };
4922
3979
  }
@@ -4932,7 +3989,7 @@ async function loadEvidence(directory, taskId, options) {
4932
3989
  return { status: "invalid_schema", errors: ["Invalid JSON"] };
4933
3990
  }
4934
3991
  if (isFlatRetrospective(parsed)) {
4935
- const wrappedBundle = _internals11.wrapFlatRetrospective(parsed, sanitizedTaskId);
3992
+ const wrappedBundle = _internals10.wrapFlatRetrospective(parsed, sanitizedTaskId);
4936
3993
  try {
4937
3994
  const validated = EvidenceBundleSchema.parse(wrappedBundle);
4938
3995
  if (options?.migrate === false) {
@@ -4940,9 +3997,9 @@ async function loadEvidence(directory, taskId, options) {
4940
3997
  }
4941
3998
  try {
4942
3999
  await withEvidenceLock(directory, relativePath, "evidence-loader", sanitizedTaskId, async () => {
4943
- const evidenceDir = path12.dirname(evidencePath);
4000
+ const evidenceDir = path9.dirname(evidencePath);
4944
4001
  const bundleJson = JSON.stringify(validated);
4945
- const tempPath = path12.join(evidenceDir, `evidence.json.tmp.${Date.now()}.${process.pid}`);
4002
+ const tempPath = path9.join(evidenceDir, `evidence.json.tmp.${Date.now()}.${process.pid}`);
4946
4003
  try {
4947
4004
  await bunWrite(tempPath, bundleJson);
4948
4005
  await fs6.rename(tempPath, evidencePath);
@@ -4987,7 +4044,7 @@ async function listEvidenceTaskIds(directory) {
4987
4044
  }
4988
4045
  const taskIds = [];
4989
4046
  for (const entry of entries) {
4990
- const entryPath = path12.join(evidenceBasePath, entry);
4047
+ const entryPath = path9.join(evidenceBasePath, entry);
4991
4048
  try {
4992
4049
  const stats = statSync2(entryPath);
4993
4050
  if (!stats.isDirectory()) {
@@ -5005,7 +4062,7 @@ async function listEvidenceTaskIds(directory) {
5005
4062
  }
5006
4063
  async function deleteEvidence(directory, taskId) {
5007
4064
  const sanitizedTaskId = sanitizeTaskId2(taskId);
5008
- const relativePath = path12.join("evidence", sanitizedTaskId);
4065
+ const relativePath = path9.join("evidence", sanitizedTaskId);
5009
4066
  const evidenceDir = validateSwarmPath(directory, relativePath);
5010
4067
  try {
5011
4068
  statSync2(evidenceDir);
@@ -5021,8 +4078,8 @@ async function deleteEvidence(directory, taskId) {
5021
4078
  }
5022
4079
  }
5023
4080
  async function checkRequirementCoverage(phase, directory) {
5024
- const relativePath = path12.join("evidence", `req-coverage-phase-${phase}.json`);
5025
- const absolutePath = path12.resolve(directory, ".swarm", relativePath);
4081
+ const relativePath = path9.join("evidence", `req-coverage-phase-${phase}.json`);
4082
+ const absolutePath = path9.resolve(directory, ".swarm", relativePath);
5026
4083
  try {
5027
4084
  await fs6.access(absolutePath);
5028
4085
  return { exists: true, path: absolutePath };
@@ -5031,8 +4088,8 @@ async function checkRequirementCoverage(phase, directory) {
5031
4088
  }
5032
4089
  }
5033
4090
  async function archiveEvidence(directory, maxAgeDays, maxBundles, options) {
5034
- const taskIds = await _internals11.listEvidenceTaskIds(directory);
5035
- const cutoffDate = options?.now ? new Date(options.now) : _internals11.now();
4091
+ const taskIds = await _internals10.listEvidenceTaskIds(directory);
4092
+ const cutoffDate = options?.now ? new Date(options.now) : _internals10.now();
5036
4093
  cutoffDate.setDate(cutoffDate.getDate() - maxAgeDays);
5037
4094
  const cutoffIso = cutoffDate.toISOString();
5038
4095
  const selected = new Set;
@@ -5044,7 +4101,7 @@ async function archiveEvidence(directory, maxAgeDays, maxBundles, options) {
5044
4101
  for (const taskId of taskIds) {
5045
4102
  let result;
5046
4103
  try {
5047
- result = await _internals11.loadEvidence(directory, taskId);
4104
+ result = await _internals10.loadEvidence(directory, taskId);
5048
4105
  } catch {
5049
4106
  warn("archive: skipping corrupt or unreadable evidence for task", taskId);
5050
4107
  continue;
@@ -5072,7 +4129,7 @@ async function archiveEvidence(directory, maxAgeDays, maxBundles, options) {
5072
4129
  }
5073
4130
  if (!options?.dryRun) {
5074
4131
  for (const taskId of [...selected].sort()) {
5075
- const deleted = await _internals11.deleteEvidence(directory, taskId);
4132
+ const deleted = await _internals10.deleteEvidence(directory, taskId);
5076
4133
  if (deleted)
5077
4134
  archived.push(taskId);
5078
4135
  else
@@ -5098,7 +4155,7 @@ async function archiveEvidence(directory, maxAgeDays, maxBundles, options) {
5098
4155
  };
5099
4156
  if (typeof options?.cacheMaxBytes === "number" && options.cacheMaxBytes > 0 || typeof options?.cacheMaxRecords === "number" && options.cacheMaxRecords > 0) {
5100
4157
  try {
5101
- documentsCache = await _internals11.pruneEvidenceDocuments({
4158
+ documentsCache = await _internals10.pruneEvidenceDocuments({
5102
4159
  directory,
5103
4160
  maxBytes: options?.cacheMaxBytes,
5104
4161
  maxRecords: options?.cacheMaxRecords,
@@ -5126,7 +4183,7 @@ async function archiveEvidence(directory, maxAgeDays, maxBundles, options) {
5126
4183
  function validateEvidence(evidence) {
5127
4184
  return EvidenceSchema.parse(evidence);
5128
4185
  }
5129
- var _internals11 = {
4186
+ var _internals10 = {
5130
4187
  wrapFlatRetrospective,
5131
4188
  loadEvidence,
5132
4189
  listEvidenceTaskIds,
@@ -5248,4 +4305,4 @@ function mergeDurableGateEntriesFromEvidence(taskId, entries, evidence) {
5248
4305
  return merged;
5249
4306
  }
5250
4307
 
5251
- export { getExecutor, init_executor, MAX_TRANSIENT_RETRIES, isTransientSpawnError, transientBackoff, getGitRepositoryStatus, isGitRepo, getDefaultBaseBranch, resetToRemoteBranch, resetToMainAfterMerge, isStateUnreadable, loadEpicSessionState, isEpicModeActive, enableEpicMode, disableEpicMode, normalizePath, pathsConflict, isGlobalFile, isProtectedPath, readTaskScopes, computeSpecHash, loadPlanJsonOnly, loadPlan, savePlan, closePlanTerminalState, derivePlanMarkdown, IdentifierSchema, EvaluationTaskV1Schema, GateNameSchema, GateAuditManifestV1Schema, GateAuditResultV1Schema, canonicalJson, canonicalHash, computeTaskInputContentHash, computeTaskSetContentHash, computeManifestContentHash, resolveContainedExistingPath, admitEvaluationTask, saveTaskSetSnapshot, saveGateAuditResult, saveGateAuditManifest, readGateAuditManifest, readGateAuditResult, listGateAuditResults, isValidEvidenceType, sanitizeTaskId2 as sanitizeTaskId, validateProjectRoot, saveEvidence, loadEvidence, listEvidenceTaskIds, checkRequirementCoverage, archiveEvidence, readDurableGateEvidence, getDurableGateEvidenceStatus, getDurableGateEvidenceStatusForTask, mergeDurableGateEntriesFromEvidence };
4308
+ export { getExecutor, init_executor, MAX_TRANSIENT_RETRIES, isTransientSpawnError, transientBackoff, getGitRepositoryStatus, isGitRepo, getDefaultBaseBranch, resetToRemoteBranch, resetToMainAfterMerge, isStateUnreadable, loadEpicSessionState, isEpicModeActive, enableEpicMode, disableEpicMode, normalizePath, pathsConflict, isGlobalFile, isProtectedPath, readTaskScopes, computeSpecHash, loadPlanJsonOnly, loadPlan, savePlan, closePlanTerminalState, derivePlanMarkdown, isValidEvidenceType, sanitizeTaskId2 as sanitizeTaskId, validateProjectRoot, saveEvidence, loadEvidence, listEvidenceTaskIds, checkRequirementCoverage, archiveEvidence, readDurableGateEvidence, getDurableGateEvidenceStatus, getDurableGateEvidenceStatusForTask, mergeDurableGateEntriesFromEvidence };