opencode-swarm 7.136.1 → 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 (67) hide show
  1. package/.opencode/skills/swarm-pr-feedback/SKILL.md +41 -1
  2. package/.opencode/skills/swarm-pr-review/SKILL.md +72 -24
  3. package/README.md +18 -0
  4. package/dist/background/workspace-snapshot.d.ts +54 -0
  5. package/dist/cli/{config-doctor-6fphg5xm.js → config-doctor-b67nb84b.js} +2 -2
  6. package/dist/cli/{curation-policy-m24jbyag.js → curation-policy-kvzhfaj1.js} +2 -2
  7. package/dist/cli/{curator-llm-factory-w5arq7tr.js → curator-llm-factory-x7kvry9x.js} +17 -14
  8. package/dist/cli/{curator-zrt5sqj2.js → curator-nrmj8bds.js} +17 -14
  9. package/dist/cli/{evidence-summary-service-w006jnpg.js → evidence-summary-service-cf8sz2bq.js} +3 -1
  10. package/dist/cli/{guardrail-explain-462jwhbh.js → guardrail-explain-5kd44rcj.js} +18 -15
  11. package/dist/cli/{guardrail-log-ax21jd9e.js → guardrail-log-aksrzqdx.js} +3 -3
  12. package/dist/cli/hashing-mjwn6j4y.js +34 -0
  13. package/dist/cli/{hive-promoter-2vacnbws.js → hive-promoter-cy21rhnd.js} +17 -14
  14. package/dist/cli/{index-hzkvbycn.js → index-0755132s.js} +4 -4
  15. package/dist/cli/{index-9gxp450h.js → index-1kn24ja0.js} +1 -1
  16. package/dist/cli/{index-h3bweb88.js → index-21115szq.js} +5 -5
  17. package/dist/cli/{index-g7g4hqh3.js → index-37v2wxqe.js} +1 -1
  18. package/dist/cli/{index-gf7hqbmz.js → index-7ayaq27q.js} +5 -1
  19. package/dist/cli/{index-kzc2ygea.js → index-84nz7bhe.js} +1 -1
  20. package/dist/cli/{index-1sq47n6t.js → index-ad6j0m7k.js} +12 -6
  21. package/dist/cli/{index-zkddc5ye.js → index-azghvnja.js} +2 -2
  22. package/dist/cli/{index-rhgctfn3.js → index-ckybsn6p.js} +19 -16
  23. package/dist/cli/{index-cggqh2dz.js → index-kwwxevne.js} +53 -996
  24. package/dist/cli/{index-tfa40hwb.js → index-m5fw4mer.js} +19 -2
  25. package/dist/cli/{index-jwrydqjp.js → index-rw3f73aq.js} +1 -1
  26. package/dist/cli/{index-dyy3hvk3.js → index-s0rbdp61.js} +2 -2
  27. package/dist/cli/{index-p1pqqwgp.js → index-s0vahtdm.js} +1 -1
  28. package/dist/cli/{index-prnjt2jr.js → index-sr2cynyw.js} +4509 -2306
  29. package/dist/cli/index-wjm896ey.js +1100 -0
  30. package/dist/cli/{index-f4cmtd89.js → index-wnz282j3.js} +2 -2
  31. package/dist/cli/{index-y6a7gjtj.js → index-wsdnttf4.js} +228 -81
  32. package/dist/cli/{index-r9v98d0y.js → index-y0xaq4f3.js} +39 -4
  33. package/dist/cli/index-y8552snf.js +264 -0
  34. package/dist/cli/index-z1tm47nj.js +783 -0
  35. package/dist/cli/index.js +17 -14
  36. package/dist/cli/{knowledge-escalator-1zt8qy1c.js → knowledge-escalator-ta3xjrdj.js} +3 -3
  37. package/dist/cli/{knowledge-events-ej3s9tsm.js → knowledge-events-dk6banmz.js} +1 -1
  38. package/dist/cli/{knowledge-store-ey4cbkp4.js → knowledge-store-h3jz10bv.js} +1 -1
  39. package/dist/cli/{knowledge-validator-zwmq7s2c.js → knowledge-validator-jsz1dxkr.js} +4 -4
  40. package/dist/cli/runner-2v413r74.js +21 -0
  41. package/dist/cli/{scan-cursor-809hf2n1.js → scan-cursor-48gwzh9c.js} +2 -2
  42. package/dist/cli/{schema-mhd7xqwr.js → schema-f937b9cs.js} +5 -1
  43. package/dist/cli/{skill-generator-yyc8zd9j.js → skill-generator-4p10ktw1.js} +5 -5
  44. package/dist/cli/{workspace-snapshot-jmyamqnv.js → workspace-snapshot-h5rzw37b.js} +5 -1
  45. package/dist/commands/registry.d.ts +72 -0
  46. package/dist/commands/skill-opt.d.ts +41 -0
  47. package/dist/config/schema.d.ts +47 -0
  48. package/dist/hooks/guardrails/file-authority.d.ts +11 -2
  49. package/dist/hooks/pr-workflow-gate.d.ts +261 -4
  50. package/dist/hooks/pr-workflow-response-gate.d.ts +27 -9
  51. package/dist/hooks/write-target-resolver.d.ts +19 -0
  52. package/dist/index.js +353 -318
  53. package/dist/services/skill-evaluator.d.ts +17 -0
  54. package/dist/services/skill-optimizer/activation.d.ts +58 -0
  55. package/dist/services/skill-optimizer/candidates.d.ts +88 -0
  56. package/dist/services/skill-optimizer/controller.d.ts +146 -0
  57. package/dist/services/skill-optimizer/deterministic-seed.d.ts +29 -0
  58. package/dist/services/skill-optimizer/lifecycle.d.ts +70 -0
  59. package/dist/services/skill-optimizer/promoted-external-staleness.d.ts +98 -0
  60. package/dist/services/skill-optimizer/retirement.d.ts +54 -0
  61. package/dist/services/skill-optimizer/skill-eval-tasks.d.ts +47 -0
  62. package/dist/services/skill-optimizer/smoke.d.ts +46 -0
  63. package/dist/services/skill-optimizer/store.d.ts +118 -0
  64. package/dist/tools/write-pr-review-trigger-eval.d.ts +2 -1
  65. package/dist/utils/stable-stringify.d.ts +46 -0
  66. package/evaluation-fixtures/skill-eval/scoring/score-skill-eval.cjs +97 -0
  67. package/package.json +1 -1
@@ -608,7 +608,10 @@ Only exact positive verdict fields pass. A sentence containing “not APPROVE,
608
608
  header without item rows, duplicate rows, missing IDs, degraded/truncated
609
609
  artifacts, wrong roles, stale content digests, parallel or out-of-order phases,
610
610
  and reused pre-edit approvals all fail closed. Any content change after Stage A
611
- invalidates Stage A and every later gate; restart at step 1. Publication tools
611
+ invalidates Stage A and every later gate; restart at step 1. See
612
+ "Re-recording Stage A on an unchanged revision" below for the one retention
613
+ exception, which applies only when the revision digest itself did not change.
614
+ Publication tools
612
615
  and `git commit`/`git push` remain blocked until all four ordered lane phases
613
616
  settle on the Stage-A digest. After they settle, only one standalone `git commit`
614
617
  command may create the reviewed commit; push and remote publication remain
@@ -704,6 +707,43 @@ full stdout/stderr is inlined instead so evidence is never lost. A successful
704
707
  run persists nothing — there is no failure evidence to recover, and the
705
708
  per-check summaries are the useful record.
706
709
 
710
+ ### Re-recording Stage A on an unchanged revision
711
+
712
+ Re-recording Stage A always requires a fresh, complete receipt set on the
713
+ current revision digest — that part is unconditional. What happens to the
714
+ already-recorded Stage B and closeout gate batches depends on whether the
715
+ revision digest itself changed. If the digest is unchanged from the prior
716
+ Stage A record **and** the newly declared applicable obligations/categories
717
+ are equal to or a superset of the prior declaration, the already-approved
718
+ independent gate batches are retained: re-recording Stage A to add a
719
+ previously-missed obligation, or to re-attest the same set, does not by
720
+ itself discard Stage B and closeout work that already passed on that
721
+ revision. A narrower obligation set than the prior declaration, or any actual
722
+ digest change, still wipes every recorded gate batch and un-arms publication
723
+ exactly as before — a controller cannot narrow what it declares in order to
724
+ dodge re-verification.
725
+
726
+ ### Why gate evidence is not item-scoped
727
+
728
+ Stage A, Stage B, and closeout evidence invalidate as whole gate batches, not
729
+ per feedback item, and that is a deliberate design decision, not unfinished
730
+ work:
731
+
732
+ - **No trustworthy item-to-file mapping exists to key invalidation on.** The
733
+ file scope a caller declares for a feedback item is caller-asserted and
734
+ only path-sanitized — it is never intersected with the actual changed-file
735
+ set, and it carries no persisted binding back to feedback item IDs. Keying
736
+ invalidation on that declaration would let a controller dodge
737
+ re-verification by under-declaring scope, turning a fail-closed guarantee
738
+ into a fail-open one (AGENTS.md invariant 9) — the same failure class that
739
+ already ruled out keying digest invalidation on `git diff --raw` blob OIDs.
740
+ - **The four gate phases are holistic by contract.** Each recorded batch must
741
+ own every inventory item exactly once and in declared order. Retaining
742
+ evidence for a subset of items per gate would re-partition that
743
+ independent-review contract itself, and would need its own
744
+ collusion/independence analysis before it could be trusted — it is not a
745
+ drop-in extension of the revision-level retention above.
746
+
707
747
  ### Stage B — reviewer + test_engineer (mandatory after Stage A passes)
708
748
 
709
749
  Two independent agents on the Stage-A-green diff, run in order: **reviewer
@@ -757,9 +757,9 @@ never which review dimensions or risk families get evaluated:
757
757
 
758
758
  | Tier | Diff shape | Dispatch shape (Profiles B/C) |
759
759
  |---|---|---|
760
- | S | ≤ ~50 changed lines, ≤ 3 files, no risk triggers | Consolidate: 1–2 explorer lanes covering all six dimensions (B), or one candidate-generation pass (C); Phase 4 risk families fold into the same lanes as an explicit per-family checklist |
761
- | M | ≤ ~500 changed lines, or any risk trigger | Dedicated lanes for the triggered dimensions/families; consolidate the remaining thin dimensions into 1–2 lanes |
762
- | L | > ~500 changed lines, > ~20 files, multi-subsystem, or security-sensitive surface | Full fan-out: one lane per dimension (six) and per-family micro dispatch in Phase 4 |
760
+ | S | ≤ ~100 changed lines, ≤ 5 files, no risk triggers | Consolidate: 1–2 explorer lanes covering all six dimensions (B), or one candidate-generation pass (C); Phase 4 risk families fold into the same lanes as an explicit per-family checklist |
761
+ | M | ≤ ~1500 changed lines, or any risk trigger | Dedicated lanes for the triggered dimensions/families; consolidate the remaining thin dimensions into 1–2 lanes |
762
+ | L | > ~1500 changed lines, > ~50 files, multi-subsystem, or security-sensitive surface | Full fan-out: one lane per dimension (six) and per-family micro dispatch in Phase 4 |
763
763
 
764
764
  Risk triggers (any one escalates to at least tier M, and the triggered
765
765
  dimension/family always gets a dedicated lane at M and above):
@@ -775,14 +775,29 @@ cost, or predicted simplicity — permits fewer lanes than the classified tier,
775
775
  and no tier permits skipping a dimension or family. Under Profile A the
776
776
  controller computes the tier itself from the bound `base_sha...pr_head_sha`
777
777
  diff (`--numstat` totals; an uncomputable diff fails strict to tier L) and
778
- mechanically enforces the matching floors on every base and micro batch
779
- initial waves and retries alike: tier L requires the historical
780
- full fan-out (six singleton base lanes, one micro-lane per family, on every
781
- batch, not only the first), while
782
- tiers S and M accept consolidated lanes that declare their complete
783
- `owned_workflow_lanes` set — every dimension and family still owned exactly
784
- once and attested per family. Risk triggers remain caller-side escalation on
785
- every profile: dispatch MORE than the floor whenever a trigger warrants it.
778
+ mechanically enforces the matching floors on every base and micro batch. The
779
+ initial base wave and every micro batch keep the historical tier-L full
780
+ fan-out (six singleton base lanes on the initial base wave; one micro-lane
781
+ per family on every micro batch, not only the first), while tiers S and M
782
+ accept consolidated lanes that declare their complete `owned_workflow_lanes`
783
+ set — every dimension and family still owned exactly once and attested per
784
+ family. A tier-L base **retry** may consolidate dimensions that each have a
785
+ recorded, terminally-failed prior attempt and currently have no successful
786
+ source, subject to two lane floors: no single lane may own all six
787
+ dimensions, and — counted cumulatively across every recorded base batch, not
788
+ per batch, and including batches the capacity GC has since dropped — the six
789
+ dimensions must stay backed by at least four distinct lanes (each dimension
790
+ no consolidated lane claims counts as one, plus the FEWEST declared
791
+ consolidated lanes that suffice to cover the rest). That permits a small
792
+ consolidation as failure recovery and rejects re-doing the whole wave in two
793
+ or three lanes, whether the attempt is split across several batches or
794
+ disguised as overlapping or duplicate consolidations — declaring more lanes
795
+ than the cover needs buys no budget. A dimension that already has a
796
+ successful source, or whose prior attempt is still in flight, still requires
797
+ its own dedicated retry lane, and
798
+ a full six-lane singleton re-dispatch is always accepted. Risk triggers
799
+ remain caller-side escalation on every profile: dispatch MORE than the floor
800
+ whenever a trigger warrants it.
786
801
 
787
802
  ### Dispatch
788
803
 
@@ -1295,23 +1310,47 @@ machine enforcement cannot safely infer every repository-specific trust
1295
1310
  boundary from prose. Completion is blocked until that exact derived inventory
1296
1311
  has valid critic rows.
1297
1312
 
1298
- Reviewer and critic retries cannot be combined as complementary partial verdict
1299
- sets. Each phase requires at least one fully successful exact batch covering its
1300
- entire mechanically assigned inventory on one revision. A later degraded,
1301
- truncated, stale, wrong-identity, or malformed batch cannot replace an earlier
1302
- valid batch or suppress critic routing.
1303
-
1304
- Any newer reviewer batch invalidates every older critic batch, even when the
1305
- new reviewer rows happen to be identical. Dispatch a fresh critic wave from the
1306
- latest coherent reviewer batch; critic evidence can never predate the reviewer
1307
- evidence it purports to challenge.
1313
+ Reviewer and critic settlement compose across batches, item by item: a phase
1314
+ settles once every review item in the current mechanically assigned inventory
1315
+ holds a successful verdict, whether that coverage comes from one batch or from
1316
+ several complementary partial retries. A later degraded, truncated, stale,
1317
+ wrong-identity, or malformed batch never supplies a verdict for the items it
1318
+ touches, but it does not discard verdicts other batches already supplied for
1319
+ different items.
1320
+
1321
+ When more than one successful batch covers the same item, the most recent
1322
+ successful batch wins that item. This conflict rule is one shared computation,
1323
+ so settlement and every downstream verdict use (candidate inventory, critic
1324
+ routing, final synthesis) never disagree about which claim is authoritative
1325
+ for an item. A batch contributes only when it was validated against the exact
1326
+ candidate inventory current at validation time; a batch recorded before that
1327
+ binding existed contributes only if it is wholly successful and its item set
1328
+ exactly matches the current inventory — the historical all-or-nothing rule,
1329
+ preserved unchanged for state that predates composition.
1330
+
1331
+ A critic claim is bound per item to the exact reviewer row it was validated
1332
+ against, not to the reviewer batch as a whole. A reviewer retry that
1333
+ reproduces a byte-identical row for an item retains that item's critic work;
1334
+ a reviewer row that changed at all — even one field — invalidates only that
1335
+ item's critic claim, not the whole critic wave. Critic batches recorded
1336
+ before per-item binding existed keep the old behavior: any newer reviewer
1337
+ batch invalidates them wholesale. Dispatch a fresh critic wave to cover
1338
+ whatever items composition leaves unclaimed; critic evidence can never
1339
+ predate the reviewer evidence it purports to challenge.
1340
+
1341
+ Settlement is item completeness, not lane completeness: a declared lane that
1342
+ never completes produces a diagnostic naming the abandoned lane, not an
1343
+ automatic block, as long as every item in the inventory already holds a
1344
+ successful verdict from some lane.
1308
1345
 
1309
1346
  Under Profile A, dispatch critic chunks with `dispatch_lanes_async`,
1310
1347
  `mode: "swarm-pr-review:critic"`, a unique non-empty `workflow_lane` per
1311
1348
  chunk, `review_item_ids` containing the exact finding IDs assigned to that
1312
1349
  chunk, critic-role agents only, and the same exact `pr_head_sha`. The runtime
1313
1350
  requires one parseable `[CRITIC]` row for every structurally assigned ID and
1314
- requires one coherent fully successful exact reviewer batch before a critic wave.
1351
+ requires the reviewer phase to have settled every item in the current
1352
+ inventory holding a successful reviewer verdict, composed across batches —
1353
+ before a critic wave.
1315
1354
  Under Profile B, dispatch each critic chunk to a fresh subagent that was
1316
1355
  neither the explorer nor the reviewer for those findings; under Profile C, run
1317
1356
  a separate critic pass. The one-parseable-`[CRITIC]`-row-per-assigned-ID
@@ -1744,8 +1783,17 @@ checkout …` is repeatedly rejected as read-only shell syntax (the runtime
1744
1783
  requires each git intake command to be a single standalone command), when
1745
1784
  the PR ref is missing, or when the working tree is on the wrong branch and
1746
1785
  the merge-base bind can never verify. In that state the response gate
1747
- suspends further auto-resumes after a small number of consecutive
1748
- unproductive wakes, and the only exits are:
1786
+ suspends further auto-resumes for either of two independent reasons: a
1787
+ small number of consecutive unproductive wakes (the durable gate `revision`
1788
+ did not advance), or the total wake ceiling being reached (tier-scaled
1789
+ defaults S=12 / M=54 / L=102, overridable via the `totalWakeCeiling`
1790
+ option, and in-memory/per-process so the count resets on plugin reload and
1791
+ when the durable gate clears — but NOT across the PR_REVIEW → PR_FEEDBACK
1792
+ handoff, which keeps accumulating). Either suspension appends a
1793
+ `pr_workflow_wake_suspended` record to `.swarm/events.jsonl` naming the
1794
+ reason, both counters, the tier, and the ceiling in force — read that first
1795
+ when diagnosing why a review stopped resuming. Either way, the only exits
1796
+ are:
1749
1797
 
1750
1798
  1. **Diagnose and retry the canonical standalone sequence.** Run
1751
1799
  `git fetch origin refs/pull/<N>/head`, verify
package/README.md CHANGED
@@ -37,6 +37,7 @@ Most AI coding tools let one model write code and ask that same model whether th
37
37
  - 🔎 **Independent auto-review engine** — bounded whole-diff review in a fresh read-only model session, structured diff-anchored findings, optional independent validation, advisory-by-default phase review, and an evidence-backed opt-in completion gate. v7 remains opt-in; v8's default is pinned to a committed 30-diff cost burn-in.
38
38
  - 🔍 **DEEP_DIVE Protocol** — High-rigor, on-demand read-only codebase audit via specialized skills
39
39
  - 🔬 **External Skill Curation Pipeline** — Opt-in discovery, quarantine, evaluation, and promotion of external skill candidates from configured sources (disabled by default; enable via `external_skills.curation_enabled: true` in config). Includes 7 tools: `external_skill_discover`, `external_skill_list`, `external_skill_inspect`, `external_skill_promote`, `external_skill_reject`, `external_skill_delete`, `external_skill_revoke`. Candidates pass through a 3-gate validation pipeline before evaluation: **prompt injection scan** (12 regex patterns), **unsafe instruction scan** (25 patterns), and **provenance integrity check** (SHA-256, timestamp, URL, publisher, and hash verification).
40
+ - 🎯 **Governed Skill Optimizer** — Manually-activated, single-skill optimizer (`/swarm skill-opt plan|run|status|diff|approve|reject|rollback|history`) that drives one allowlisted `SKILL.md` candidate at a time through deterministic draft → smoke → evaluation-substrate validation → manual approval → atomic activation/rollback. Bounded, restartable, reversible, and unable to mutate source/harness/security surfaces. Disabled by default (`skill_opt.enabled: false`); see [docs/skill-optimizer.md](docs/skill-optimizer.md).
40
41
  - 🔄 **Phase completion gates** — completion-verify and drift verifier gates enforced before phase completion
41
42
  - 🔁 **Resumable sessions** — all state saved to `.swarm/`; pick up any project any day
42
43
  - 🖥️ **PR Monitor** — GitHub PR subscription and background polling via `gh` CLI; delivers real-time CI, review, and merge status updates via the AutomationEventBus (FR-001, opt-in via `pr_monitor.enabled: true`). Subscribe with `/swarm pr subscribe <pr-url|owner/repo#N|N>`; unsubscribe with `/swarm pr unsubscribe <pr-url|owner/repo#N|N>`; check status with `/swarm pr status`. With `auto_pr_feedback: true`, CI failures and merge conflicts mechanically activate PR_FEEDBACK only when no other workflow owns the session; otherwise they are durably queued for a later round.
@@ -637,6 +638,19 @@ Seven skill-management tools (`skill_generate`, `skill_list`, `skill_apply`, `sk
637
638
 
638
639
  - **Proposal cleanup** — When a draft skill proposal is activated via `skill_apply`, the source proposal file is deleted as part of the activation process (best-effort; permission errors are logged but do not block activation).
639
640
 
641
+ ### Governed Skill Optimizer
642
+
643
+ `/swarm skill-opt` (issue #1822 — SkillOpt 3/7) is a **manually-activated, governed** optimizer that drives ONE allowlisted `SKILL.md` candidate at a time through deterministic draft → static smoke → evaluation-substrate validation (`split:'test'`) → manual approval → atomic activation (or rollback). The loop is bounded, restartable, reversible, and unable to mutate harness/source/security surfaces.
644
+
645
+ Commands: `/swarm skill-opt plan|run|status|diff|approve|reject|rollback|history`.
646
+
647
+ - **Disabled by default.** `/swarm skill-opt run` requires `skill_opt.enabled: true` AND `--confirm`. `plan`/`status`/`diff`/`history` are always available (read-only / proposal-only).
648
+ - **No autonomous mutation.** `approve`/`activate`/`reject`/`rollback` are human-only and require `--expected-content-hash` to refuse a stale base.
649
+ - **Validation reuse.** Uses the existing evaluation substrate (`evaluateCandidateV1`) — no duplicate runner/scorer. Held-out test sets are single-use (`claimHeldOutTest`), so a single `run` performs at most one validation.
650
+ - **Durable lifecycle.** Append-only state machine under `.swarm/evolution/skills/<slug>/<candidateId>/` with hash-chain integrity and corrupt-tail quarantine.
651
+
652
+ See `docs/skill-optimizer.md` for the full architecture and the `skill_opt` config block.
653
+
640
654
  ### External Skill Curation
641
655
 
642
656
  Swarm provides an opt-in, quarantine-first pipeline for discovering, validating, and promoting external skills. Disabled by default — no network calls are made until explicitly enabled.
@@ -711,6 +725,10 @@ Every candidate passes a 3-gate pipeline before entering quarantine:
711
725
  | `context_budget.unified_injection_tokens` | number | `undefined` | Opt-in unified ceiling (tokens) for combined system-enhancer + knowledge-injector injection per turn. When set, both hooks share this budget with proportional split |
712
726
  | `context_budget.tool_output_mask_threshold` | number | `2000` | Threshold for masking tool outputs (chars) |
713
727
  | `skills.enabled` | boolean | `false` | Gates the 7 skill-management tools (`skill_generate`, `skill_list`, `skill_apply`, `skill_inspect`, `skill_regenerate`, `skill_retire`, `skill_improve`) behind an opt-in flag. When `false` (default), these tools are hidden from the architect's tool map. |
728
+ | `skill_opt.enabled` | boolean | `false` | Master opt-in for the governed skill optimizer (`/swarm skill-opt`). `run` also requires `--confirm`; `plan`/`status`/`diff`/`history` are always available. See `docs/skill-optimizer.md`. |
729
+ | `skill_opt.deadband` | number | `0` | Promotion policy deadband forwarded to the evaluation substrate. |
730
+ | `skill_opt.max_rounds` | number | `5` | Hard cap on draft/smoke retries before a validation (held-out test set is single-use). |
731
+ | `skill_opt.max_transient_retries` | number | `5` | Max transient-infra retries before an infra failure becomes inconclusive. |
714
732
  | `context_budget.scoring.enabled` | boolean | `false` | Enable context scoring/ranking |
715
733
  | `context_budget.scoring.max_candidates` | number | `100` | Maximum items to score (10-500) |
716
734
  | `context_budget.scoring.weights` | object | `{ recency: 0.3, ... }` | Scoring weights for priority |
@@ -120,18 +120,49 @@ export declare function resolvePrFeedbackTrackingCandidatesAsync(directory: stri
120
120
  } | null>;
121
121
  /** Run the exact array-form switch selected by the controller. */
122
122
  export declare function switchPrFeedbackTrackingCandidateAsync(directory: string, candidate: PrFeedbackTrackingCandidate): Promise<boolean>;
123
+ /**
124
+ * Discriminated result for the revision-digest twins (issue #1968 P6). A
125
+ * bare `null` on any failure made the digest cap a dead end: a gate consumer
126
+ * could not tell "revision too large" (a bound the operator can act on) from
127
+ * "Git failed" or "output truncated" (an environment problem). `detail` is a
128
+ * best-effort human-readable diagnostic and is not part of the failure
129
+ * contract; only `reason` is.
130
+ */
131
+ export type RevisionDigestFailureReason = 'file-cap' | 'byte-cap' | 'buffer-truncated' | 'timeout' | 'git-failed' | 'containment' | 'read-failed';
132
+ export type RevisionDigestResult = {
133
+ ok: true;
134
+ digest: string;
135
+ } | {
136
+ ok: false;
137
+ reason: RevisionDigestFailureReason;
138
+ detail?: string;
139
+ };
123
140
  /**
124
141
  * Bind a mutable working tree to its actual content, not merely porcelain status.
125
142
  * This lets PR-feedback approvals fail closed when a same-path edit occurs after a
126
143
  * gate. Paths come from Git, are containment-checked, and are hashed without
127
144
  * following symlinks outside the project.
145
+ *
146
+ * This is the one implementation of the sync digest; {@link
147
+ * resolvePrWorkflowRevisionDigest} is a thin `.ok ? digest : null` delegate
148
+ * that preserves the pre-existing signature/behavior for existing callers.
128
149
  */
150
+ export declare function resolvePrWorkflowRevisionDigestDetailed(directory: string, baseHeadSha: string): RevisionDigestResult;
129
151
  export declare function resolvePrWorkflowRevisionDigest(directory: string, baseHeadSha: string): string | null;
130
152
  /**
131
153
  * Asynchronously bind a mutable working tree to its actual content. File
132
154
  * reads are chunked with bounded cooperative yields so a large, permitted
133
155
  * revision cannot stall the synchronous plugin gate path.
156
+ *
157
+ * This is the one implementation of the async digest; {@link
158
+ * resolvePrWorkflowRevisionDigestAsync} is a thin `.ok ? digest : null`
159
+ * delegate that preserves the pre-existing signature/behavior for existing
160
+ * callers. Sequenced after P2 (see issue #1968 05-fix-plan.md P6.4): the sync
161
+ * twin above has no chunking/yield, so enlarging its `readFileSync` loop
162
+ * before P2 threads the digest through a single gate-entry-point resolve
163
+ * would have worsened blocking on the production path.
134
164
  */
165
+ export declare function resolvePrWorkflowRevisionDigestDetailedAsync(directory: string, baseHeadSha: string): Promise<RevisionDigestResult>;
135
166
  export declare function resolvePrWorkflowRevisionDigestAsync(directory: string, baseHeadSha: string): Promise<string | null>;
136
167
  /** Parse `git status --porcelain=v1 -z`, including both sides of renames. */
137
168
  export declare function parsePorcelainPaths(output: string): string[] | null;
@@ -174,5 +205,28 @@ export declare const _internals: {
174
205
  gitTimeoutMs: number;
175
206
  yieldControl: () => Promise<void>;
176
207
  parsePorcelainV2Snapshot: typeof parsePorcelainV2Snapshot;
208
+ /**
209
+ * Revision-digest bound seams (issue #1968 P6). Defaults mirror the
210
+ * top-level constants; tests lower these to deterministically produce
211
+ * `file-cap` / `byte-cap` / `buffer-truncated` against small real temp
212
+ * git repos instead of materializing tens of thousands of real files.
213
+ */
214
+ revisionMaxFiles: number;
215
+ revisionMaxTotalBytes: number;
216
+ gitSnapshotMaxBuffer: number;
217
+ revisionEnumerationTimeoutMs: number;
218
+ /**
219
+ * The synchronous digest's changed-file content read, behind the same kind
220
+ * of seam as `spawnSync` above. The `read-failed` reason it guards has no
221
+ * portable filesystem trigger: Windows normalizes every crafted-path failure
222
+ * (nested-under-a-file, reserved characters, over-length) to `ENOENT`, which
223
+ * this code deliberately treats as "deleted, keep hashing", and `chmod` is a
224
+ * no-op there — so without this seam the sync twin's `read-failed` arm is
225
+ * unreachable from a test while remaining reachable in production (EACCES,
226
+ * EIO, a vanished mount). The async twin needs no equivalent: its chunked
227
+ * reader reaches `read-failed` through the short-read branch, which a test
228
+ * drives via the existing `yieldControl` seam.
229
+ */
230
+ readChangedFileSync: (filePath: string) => Buffer;
177
231
  };
178
232
  export {};
@@ -12,8 +12,8 @@ import {
12
12
  shouldRunOnStartup,
13
13
  writeBackupArtifact,
14
14
  writeDoctorArtifact
15
- } from "./index-gf7hqbmz.js";
16
- import"./index-r9v98d0y.js";
15
+ } from "./index-7ayaq27q.js";
16
+ import"./index-y0xaq4f3.js";
17
17
  import"./index-bk5tah7q.js";
18
18
  import"./index-3jcyn8g6.js";
19
19
  import"./index-bpmtbmy9.js";
@@ -4,9 +4,9 @@ import {
4
4
  authorizeCuration,
5
5
  buildConfigFingerprintInput,
6
6
  readCohortConfigFingerprint
7
- } from "./index-jwrydqjp.js";
7
+ } from "./index-rw3f73aq.js";
8
8
  import"./index-rtry5xyf.js";
9
- import"./index-kzc2ygea.js";
9
+ import"./index-84nz7bhe.js";
10
10
  import"./index-ae75rja9.js";
11
11
  import"./index-dzyjb33e.js";
12
12
  import"./index-ey29aap6.js";
@@ -1,33 +1,36 @@
1
1
  // @bun
2
2
  import {
3
3
  createCuratorLLMDelegate
4
- } from "./index-prnjt2jr.js";
4
+ } from "./index-sr2cynyw.js";
5
5
  import"./index-vm4xw9z3.js";
6
- import"./index-tfa40hwb.js";
7
- import"./index-gf7hqbmz.js";
8
- import"./index-cggqh2dz.js";
6
+ import"./index-wjm896ey.js";
7
+ import"./index-m5fw4mer.js";
8
+ import"./index-7ayaq27q.js";
9
+ import"./index-kwwxevne.js";
10
+ import"./index-z1tm47nj.js";
11
+ import"./index-y8552snf.js";
9
12
  import"./index-4905hd2m.js";
10
13
  import"./index-134d35c1.js";
11
- import"./index-1sq47n6t.js";
12
- import"./index-h3bweb88.js";
13
- import"./index-9gxp450h.js";
14
+ import"./index-ad6j0m7k.js";
15
+ import"./index-21115szq.js";
16
+ import"./index-1kn24ja0.js";
14
17
  import"./index-6mjf4vr1.js";
15
18
  import"./index-c8s9a3zh.js";
16
19
  import"./index-9ss2m4rs.js";
17
- import"./index-y6a7gjtj.js";
20
+ import"./index-wsdnttf4.js";
18
21
  import"./index-mrtms113.js";
19
- import"./index-dyy3hvk3.js";
20
- import"./index-jwrydqjp.js";
22
+ import"./index-s0rbdp61.js";
23
+ import"./index-rw3f73aq.js";
21
24
  import"./index-rtry5xyf.js";
22
- import"./index-hzkvbycn.js";
23
- import"./index-kzc2ygea.js";
25
+ import"./index-0755132s.js";
26
+ import"./index-84nz7bhe.js";
24
27
  import"./index-ae75rja9.js";
25
28
  import"./index-dzyjb33e.js";
26
29
  import"./index-ey29aap6.js";
27
- import"./index-p1pqqwgp.js";
30
+ import"./index-s0vahtdm.js";
28
31
  import"./index-k5jrywpr.js";
29
32
  import"./index-n832052r.js";
30
- import"./index-r9v98d0y.js";
33
+ import"./index-y0xaq4f3.js";
31
34
  import"./index-bk5tah7q.js";
32
35
  import"./index-8fwhhayc.js";
33
36
  import"./index-q1exe2b3.js";
@@ -14,33 +14,36 @@ import {
14
14
  runCuratorInit,
15
15
  runCuratorPhase,
16
16
  writeCuratorSummary
17
- } from "./index-prnjt2jr.js";
17
+ } from "./index-sr2cynyw.js";
18
18
  import"./index-vm4xw9z3.js";
19
- import"./index-tfa40hwb.js";
20
- import"./index-gf7hqbmz.js";
21
- import"./index-cggqh2dz.js";
19
+ import"./index-wjm896ey.js";
20
+ import"./index-m5fw4mer.js";
21
+ import"./index-7ayaq27q.js";
22
+ import"./index-kwwxevne.js";
23
+ import"./index-z1tm47nj.js";
24
+ import"./index-y8552snf.js";
22
25
  import"./index-4905hd2m.js";
23
26
  import"./index-134d35c1.js";
24
- import"./index-1sq47n6t.js";
25
- import"./index-h3bweb88.js";
26
- import"./index-9gxp450h.js";
27
+ import"./index-ad6j0m7k.js";
28
+ import"./index-21115szq.js";
29
+ import"./index-1kn24ja0.js";
27
30
  import"./index-6mjf4vr1.js";
28
31
  import"./index-c8s9a3zh.js";
29
32
  import"./index-9ss2m4rs.js";
30
- import"./index-y6a7gjtj.js";
33
+ import"./index-wsdnttf4.js";
31
34
  import"./index-mrtms113.js";
32
- import"./index-dyy3hvk3.js";
33
- import"./index-jwrydqjp.js";
35
+ import"./index-s0rbdp61.js";
36
+ import"./index-rw3f73aq.js";
34
37
  import"./index-rtry5xyf.js";
35
- import"./index-hzkvbycn.js";
36
- import"./index-kzc2ygea.js";
38
+ import"./index-0755132s.js";
39
+ import"./index-84nz7bhe.js";
37
40
  import"./index-ae75rja9.js";
38
41
  import"./index-dzyjb33e.js";
39
42
  import"./index-ey29aap6.js";
40
- import"./index-p1pqqwgp.js";
43
+ import"./index-s0vahtdm.js";
41
44
  import"./index-k5jrywpr.js";
42
45
  import"./index-n832052r.js";
43
- import"./index-r9v98d0y.js";
46
+ import"./index-y0xaq4f3.js";
44
47
  import"./index-bk5tah7q.js";
45
48
  import"./index-8fwhhayc.js";
46
49
  import"./index-q1exe2b3.js";
@@ -6,7 +6,9 @@ import {
6
6
  loadPlanJsonOnly,
7
7
  mergeDurableGateEntriesFromEvidence,
8
8
  readDurableGateEvidence
9
- } from "./index-cggqh2dz.js";
9
+ } from "./index-kwwxevne.js";
10
+ import"./index-z1tm47nj.js";
11
+ import"./index-y8552snf.js";
10
12
  import"./index-9ss2m4rs.js";
11
13
  import"./index-mrtms113.js";
12
14
  import"./index-ey29aap6.js";
@@ -1,34 +1,37 @@
1
1
  // @bun
2
2
  import {
3
3
  handleGuardrailExplain
4
- } from "./index-zkddc5ye.js";
5
- import"./index-prnjt2jr.js";
4
+ } from "./index-azghvnja.js";
5
+ import"./index-sr2cynyw.js";
6
6
  import"./index-vm4xw9z3.js";
7
- import"./index-tfa40hwb.js";
8
- import"./index-gf7hqbmz.js";
9
- import"./index-cggqh2dz.js";
7
+ import"./index-wjm896ey.js";
8
+ import"./index-m5fw4mer.js";
9
+ import"./index-7ayaq27q.js";
10
+ import"./index-kwwxevne.js";
11
+ import"./index-z1tm47nj.js";
12
+ import"./index-y8552snf.js";
10
13
  import"./index-4905hd2m.js";
11
14
  import"./index-134d35c1.js";
12
- import"./index-1sq47n6t.js";
13
- import"./index-h3bweb88.js";
14
- import"./index-9gxp450h.js";
15
+ import"./index-ad6j0m7k.js";
16
+ import"./index-21115szq.js";
17
+ import"./index-1kn24ja0.js";
15
18
  import"./index-6mjf4vr1.js";
16
19
  import"./index-c8s9a3zh.js";
17
20
  import"./index-9ss2m4rs.js";
18
- import"./index-y6a7gjtj.js";
21
+ import"./index-wsdnttf4.js";
19
22
  import"./index-mrtms113.js";
20
- import"./index-dyy3hvk3.js";
21
- import"./index-jwrydqjp.js";
23
+ import"./index-s0rbdp61.js";
24
+ import"./index-rw3f73aq.js";
22
25
  import"./index-rtry5xyf.js";
23
- import"./index-hzkvbycn.js";
24
- import"./index-kzc2ygea.js";
26
+ import"./index-0755132s.js";
27
+ import"./index-84nz7bhe.js";
25
28
  import"./index-ae75rja9.js";
26
29
  import"./index-dzyjb33e.js";
27
30
  import"./index-ey29aap6.js";
28
- import"./index-p1pqqwgp.js";
31
+ import"./index-s0vahtdm.js";
29
32
  import"./index-k5jrywpr.js";
30
33
  import"./index-n832052r.js";
31
- import"./index-r9v98d0y.js";
34
+ import"./index-y0xaq4f3.js";
32
35
  import"./index-bk5tah7q.js";
33
36
  import"./index-8fwhhayc.js";
34
37
  import"./index-q1exe2b3.js";
@@ -1,9 +1,9 @@
1
1
  // @bun
2
2
  import {
3
3
  handleGuardrailLog
4
- } from "./index-g7g4hqh3.js";
5
- import"./index-tfa40hwb.js";
6
- import"./index-r9v98d0y.js";
4
+ } from "./index-37v2wxqe.js";
5
+ import"./index-m5fw4mer.js";
6
+ import"./index-y0xaq4f3.js";
7
7
  import"./index-bk5tah7q.js";
8
8
  import"./index-3jcyn8g6.js";
9
9
  import"./index-bpmtbmy9.js";
@@ -0,0 +1,34 @@
1
+ // @bun
2
+ import {
3
+ _internals,
4
+ canonicalHash,
5
+ canonicalJson,
6
+ computeCandidateInputContentHash,
7
+ computeManifestContentHash,
8
+ computeRunIntegrityHash,
9
+ computeTaskContentHash,
10
+ computeTaskInputContentHash,
11
+ computeTaskLineageInputHash,
12
+ computeTaskSetContentHash,
13
+ contentHashWithout,
14
+ resolveContainedExistingPath,
15
+ resolveContainedExistingPathAsync,
16
+ sha256
17
+ } from "./index-y8552snf.js";
18
+ import"./index-a76rekgs.js";
19
+ export {
20
+ sha256,
21
+ resolveContainedExistingPathAsync,
22
+ resolveContainedExistingPath,
23
+ contentHashWithout,
24
+ computeTaskSetContentHash,
25
+ computeTaskLineageInputHash,
26
+ computeTaskInputContentHash,
27
+ computeTaskContentHash,
28
+ computeRunIntegrityHash,
29
+ computeManifestContentHash,
30
+ computeCandidateInputContentHash,
31
+ canonicalJson,
32
+ canonicalHash,
33
+ _internals
34
+ };
@@ -7,35 +7,38 @@ import {
7
7
  isHiveEligible,
8
8
  promoteFromSwarm,
9
9
  promoteToHive
10
- } from "./index-prnjt2jr.js";
10
+ } from "./index-sr2cynyw.js";
11
11
  import"./index-vm4xw9z3.js";
12
- import"./index-tfa40hwb.js";
13
- import"./index-gf7hqbmz.js";
14
- import"./index-cggqh2dz.js";
12
+ import"./index-wjm896ey.js";
13
+ import"./index-m5fw4mer.js";
14
+ import"./index-7ayaq27q.js";
15
+ import"./index-kwwxevne.js";
16
+ import"./index-z1tm47nj.js";
17
+ import"./index-y8552snf.js";
15
18
  import"./index-4905hd2m.js";
16
19
  import"./index-134d35c1.js";
17
- import"./index-1sq47n6t.js";
18
- import"./index-h3bweb88.js";
19
- import"./index-9gxp450h.js";
20
+ import"./index-ad6j0m7k.js";
21
+ import"./index-21115szq.js";
22
+ import"./index-1kn24ja0.js";
20
23
  import"./index-6mjf4vr1.js";
21
24
  import"./index-c8s9a3zh.js";
22
25
  import"./index-9ss2m4rs.js";
23
- import"./index-y6a7gjtj.js";
26
+ import"./index-wsdnttf4.js";
24
27
  import"./index-mrtms113.js";
25
- import"./index-dyy3hvk3.js";
26
- import"./index-jwrydqjp.js";
28
+ import"./index-s0rbdp61.js";
29
+ import"./index-rw3f73aq.js";
27
30
  import"./index-rtry5xyf.js";
28
31
  import {
29
32
  resolveHiveKnowledgePath
30
- } from "./index-hzkvbycn.js";
31
- import"./index-kzc2ygea.js";
33
+ } from "./index-0755132s.js";
34
+ import"./index-84nz7bhe.js";
32
35
  import"./index-ae75rja9.js";
33
36
  import"./index-dzyjb33e.js";
34
37
  import"./index-ey29aap6.js";
35
- import"./index-p1pqqwgp.js";
38
+ import"./index-s0vahtdm.js";
36
39
  import"./index-k5jrywpr.js";
37
40
  import"./index-n832052r.js";
38
- import"./index-r9v98d0y.js";
41
+ import"./index-y0xaq4f3.js";
39
42
  import"./index-bk5tah7q.js";
40
43
  import"./index-8fwhhayc.js";
41
44
  import"./index-q1exe2b3.js";
@@ -702,7 +702,7 @@ async function applyConfidenceFloorAction(directory, touched, options) {
702
702
  const recovered = touched.filter((e) => e.confidence > CONFIDENCE_FLOOR + FLOOR_EPSILON && e.confidence_floor_demoted);
703
703
  if (atFloor.length === 0 && recovered.length === 0)
704
704
  return;
705
- const { readKnowledgeCounterRollups, effectiveRetrievalOutcomes } = await import("./knowledge-events-ej3s9tsm.js");
705
+ const { readKnowledgeCounterRollups, effectiveRetrievalOutcomes } = await import("./knowledge-events-dk6banmz.js");
706
706
  const rollups = await readKnowledgeCounterRollups(directory);
707
707
  const flagIds = new Set;
708
708
  for (const e of atFloor) {
@@ -769,11 +769,11 @@ async function applyConfidenceFloorAction(directory, touched, options) {
769
769
  });
770
770
  }
771
771
  if (action === "quarantine" && toQuarantine.length > 0) {
772
- const { quarantineEntry } = await import("./knowledge-validator-zwmq7s2c.js");
773
- const { KnowledgeConfigSchema } = await import("./schema-mhd7xqwr.js");
772
+ const { quarantineEntry } = await import("./knowledge-validator-jsz1dxkr.js");
773
+ const { KnowledgeConfigSchema } = await import("./schema-f937b9cs.js");
774
774
  let config;
775
775
  try {
776
- const { loadPluginConfigWithMeta } = await import("./index-f4cmtd89.js");
776
+ const { loadPluginConfigWithMeta } = await import("./index-wnz282j3.js");
777
777
  const { config: loadedConfig } = loadPluginConfigWithMeta(directory);
778
778
  config = KnowledgeConfigSchema.parse(loadedConfig.knowledge ?? {});
779
779
  } catch {