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
@@ -1,6 +1,6 @@
1
1
  import * as fsp from 'node:fs/promises';
2
2
  import { type PrReviewInlineTriggerRow } from '../background/pr-review-trigger-contract.js';
3
- import { resolveCommitCountSince, resolveCommitCountSinceAsync, resolveCurrentGitHead, resolveCurrentGitHeadAsync, resolveCurrentUpstreamPushTarget, resolveCurrentUpstreamPushTargetAsync, resolveCurrentUpstreamRemoteRef, resolveExactRemoteBranchHead, resolveExactRemoteBranchHeadAsync, resolveIsExactSingleChildCommit, resolveIsExactSingleChildCommitAsync, resolveIsWorkingTreeClean, resolveIsWorkingTreeCleanAsync, resolvePrReviewDiffStats, resolvePrReviewDiffStatsAsync, resolvePrWorkflowRevisionDigest, resolveRemoteRefsContainingHead, resolveRemoteRefsContainingHeadAsync } from '../background/workspace-snapshot.js';
3
+ import { type RevisionDigestResult, resolveCommitCountSince, resolveCommitCountSinceAsync, resolveCurrentGitHead, resolveCurrentGitHeadAsync, resolveCurrentUpstreamPushTarget, resolveCurrentUpstreamPushTargetAsync, resolveCurrentUpstreamRemoteRef, resolveExactRemoteBranchHead, resolveExactRemoteBranchHeadAsync, resolveIsExactSingleChildCommit, resolveIsExactSingleChildCommitAsync, resolveIsWorkingTreeClean, resolveIsWorkingTreeCleanAsync, resolvePrReviewDiffStats, resolvePrReviewDiffStatsAsync, resolvePrWorkflowRevisionDigest, resolvePrWorkflowRevisionDigestDetailed, resolveRemoteRefsContainingHead, resolveRemoteRefsContainingHeadAsync } from '../background/workspace-snapshot.js';
4
4
  import { type PrWorkflowGitState } from '../git/pr-workflow-state.js';
5
5
  export declare const PR_REVIEW_BASE_DIMENSION_IDS: readonly ["intent-architecture", "correctness-state", "tests-falsifiability", "security-trust", "reliability-performance", "compatibility-delivery"];
6
6
  export declare const PR_REVIEW_REQUIRED_MICRO_LANE_IDS: ("auth-identity-secrets" | "untrusted-input-boundaries" | "subprocess-platform" | "concurrency-state" | "dependencies-build-release" | "api-schema-migrations" | "test-infrastructure" | "ui-accessibility-i18n" | "privacy-observability" | "generated-provenance" | "unclassified-risk")[];
@@ -41,6 +41,25 @@ export declare const PR_REVIEW_DEPTH_TIER_THRESHOLDS: {
41
41
  * multiple dimensions while every dimension stays mandatory to evaluate.
42
42
  */
43
43
  export declare const PR_REVIEW_BASE_LANE_FLOORS: Record<PrReviewDepthTier, number>;
44
+ /**
45
+ * Cumulative lane floor for a tier-L base wave that used consolidated failure
46
+ * recovery (issue #1968 MUST-FIX 1).
47
+ *
48
+ * `PR_REVIEW_BASE_LANE_FLOORS.L` is the *initial wave* floor and equals the
49
+ * dimension count, so it cannot also serve as the post-consolidation floor: any
50
+ * consolidated lane owns at least two dimensions, so a wave that consolidated
51
+ * even once is backed by at most five lanes. Enforcing six cumulatively would
52
+ * make the tier-L retry exception unreachable — i.e. delete the feature.
53
+ *
54
+ * The bound that *is* enforceable, and is the property worth defending, is that
55
+ * a tier-L wave may never be reduced by consolidation to a lane count a tier-M
56
+ * dispatch would already have satisfied: the depth tier chosen for this PR must
57
+ * not be silently downgraded by failure recovery. Hence "strictly more than the
58
+ * tier-M floor" — four distinct lanes for six dimensions, a bounded loss of at
59
+ * most two lanes of depth, versus the unbounded loss (down to two lanes) a
60
+ * per-batch-only floor permits when a retry is split across batches.
61
+ */
62
+ export declare const PR_REVIEW_TIER_L_CONSOLIDATED_LANE_FLOOR: number;
44
63
  /**
45
64
  * Minimum lane counts for a FULL micro (risk-family) sweep per depth tier. These
46
65
  * mirror the base floors' tier *semantics* — not their numbers — scaled to the
@@ -171,6 +190,35 @@ interface PrReviewValidationBatchRecord {
171
190
  }>;
172
191
  validatedAt: string;
173
192
  }
193
+ /**
194
+ * Per-batch coherence keys for item-keyed reviewer/critic composition.
195
+ *
196
+ * This deliberately lives OUTSIDE `PrReviewValidationBatchRecord`: that record's
197
+ * schema is `.strict()`, and Zod's unknown-key policy is per-schema — the parent
198
+ * state schema's `.passthrough()` does not relax a strict child. Adding fields to
199
+ * the batch record would make a rolled-back plugin fail `safeParse` on every gate
200
+ * state read, including `requireAnyActiveState`, which `abortPrWorkflow` calls
201
+ * *before* the clear escape hatch. Keeping this as one new optional TOP-LEVEL key
202
+ * on the passthrough parent keeps older code at "ignore the field I don't know"
203
+ * instead of "refuse to read the file at all".
204
+ */
205
+ interface PrReviewBatchCoherenceRecord {
206
+ /**
207
+ * The exact candidate/critic inventory this batch's ownership was validated
208
+ * against at record time (the same set `assertExactStringSet` compared the
209
+ * declared lane items to).
210
+ */
211
+ validatedInventory: string[];
212
+ /**
213
+ * Critic batches only: per-item sha256 of the full canonical `[REVIEWED]` row
214
+ * that was authoritative for that item when the critic batch was declared. A
215
+ * critic claim is admitted only while the current winning reviewer row for
216
+ * that item is byte-identical, so a reviewer re-run that changes evidence or
217
+ * root cause — not only classification/severity — drops exactly the critic
218
+ * claims it invalidated and leaves its siblings intact.
219
+ */
220
+ reviewerItemBindings?: Record<string, string>;
221
+ }
174
222
  export interface PrWorkflowGateState {
175
223
  schemaVersion: 1;
176
224
  /** Monotonic durable revision used to reject stale same-session transitions. */
@@ -199,6 +247,29 @@ export interface PrWorkflowGateState {
199
247
  prReviewTriggerLedger?: PrReviewInlineTriggerRow[];
200
248
  prReviewTriggerEvalPath?: string;
201
249
  prReviewValidationBatches?: PrReviewValidationBatchRecord[];
250
+ /** Keyed by validation batch id. See `PrReviewBatchCoherenceRecord`. */
251
+ prReviewBatchCoherence?: Record<string, PrReviewBatchCoherenceRecord>;
252
+ /**
253
+ * Child session ids that produced a reviewer artifact for a validation batch
254
+ * the capacity GC has since dropped (issue #1968 MUST-FIX 3).
255
+ *
256
+ * `reviewerSubagentSessionIds` derives the critic reuse ban by walking the
257
+ * live reviewer batches, so pruning one would silently un-forbid its child
258
+ * sessions and let an agent challenge its own review. This ledger carries
259
+ * that fail-closed set across the prune.
260
+ */
261
+ prReviewRetiredReviewerSessionIds?: string[];
262
+ /**
263
+ * Canonical dimension-set keys of consolidated base lanes whose batch the
264
+ * capacity GC dropped (issue #1968 review round 2, FIX D).
265
+ *
266
+ * `tierLBackingLaneCount` covers the consolidated lanes it can see, and it can
267
+ * only see surviving `prReviewBaseDispatches`. A failed consolidated base
268
+ * batch is prunable, so without this ledger a prune would shrink the cover's
269
+ * universe and monotonically hand the wave back consolidation budget it had
270
+ * already spent.
271
+ */
272
+ prReviewRetiredConsolidatedLanes?: string[];
202
273
  prReviewArtifactRunId?: string;
203
274
  prReviewFindingsPath?: string;
204
275
  prReviewArtifactBoundaries?: PrReviewArtifactBoundary[];
@@ -210,6 +281,16 @@ export interface PrWorkflowGateState {
210
281
  prFeedbackReviewHandoff?: PrFeedbackReviewHandoffRecord;
211
282
  prFeedbackInventory?: string[];
212
283
  prFeedbackVerifications?: PrFeedbackVerificationRecord[];
284
+ /**
285
+ * Item -> lane bindings of verification batches the capacity GC dropped
286
+ * (issue #1968 review round 2, MUST-FIX C).
287
+ *
288
+ * `enforcePrFeedbackVerificationOwnership` rejects a re-claim of an inventory
289
+ * item by a different lane using a ledger rebuilt from every live batch.
290
+ * Pruning a batch would silently un-claim its items; this carries the binding
291
+ * across the prune so the rejection stays cumulative.
292
+ */
293
+ prFeedbackRetiredItemOwnership?: Record<string, string>;
213
294
  /** @deprecated Compatibility projection of the most recent verification dispatch. */
214
295
  prFeedbackVerification?: PrFeedbackVerificationRecord;
215
296
  prFeedbackStageA?: PrFeedbackStageARecord;
@@ -294,16 +375,26 @@ export declare function enforcePrWorkflowDispatchLanesAsync(directory: string, s
294
375
  export declare function enforcePrReviewBaseDimensions(directory: string, sessionID: string, lanes: readonly PrWorkflowLaneSpec[], options: {
295
376
  batchId: string;
296
377
  prHeadSha: string;
378
+ revisionDigest?: string;
297
379
  }): Promise<PrWorkflowGateState>;
380
+ declare function minimumConsolidatedLaneCover(sets: ReadonlyArray<readonly string[]>): number;
298
381
  /** Validate durable exact-six PR review evidence across all base and retry batches. */
299
- export declare function assertPrReviewBaseCoverageSettled(directory: string, sessionID: string): Promise<PrWorkflowGateState>;
382
+ export declare function assertPrReviewBaseCoverageSettled(directory: string, sessionID: string, gateContext?: PrReviewGateContext): Promise<PrWorkflowGateState>;
300
383
  /** Persist a council/reviewer/critic validation batch before launch. */
301
384
  export declare function recordPrReviewValidationBatch(directory: string, sessionID: string, phase: PrReviewValidationPhase, lanes: readonly PrWorkflowLaneSpec[], options: {
302
385
  batchId: string;
303
386
  prHeadSha: string;
304
387
  }): Promise<PrWorkflowGateState>;
305
- /** Validate that every declared council/reviewer/critic obligation has a successful retry. */
306
- export declare function assertPrReviewValidationSettled(directory: string, sessionID: string, phase?: PrReviewValidationPhase): Promise<PrWorkflowGateState>;
388
+ /**
389
+ * Validate that every declared council obligation has a successful retry, and
390
+ * that every reviewer/critic *item* carries an authenticated verdict.
391
+ *
392
+ * Council keeps lane-level accounting (council lanes carry no item ownership).
393
+ * Reviewer and critic settle through `composePrReviewPhaseVerdicts`, so
394
+ * settlement and every verdict derivation are literally the same computation —
395
+ * settlement can never pass while derivation is empty.
396
+ */
397
+ export declare function assertPrReviewValidationSettled(directory: string, sessionID: string, phase?: PrReviewValidationPhase, gateContext?: PrReviewGateContext): Promise<PrWorkflowGateState>;
307
398
  export declare function declarePrFeedbackInventory(directory: string, sessionID: string, inventoryIds: readonly string[], options: {
308
399
  prHeadSha: string;
309
400
  }): Promise<PrWorkflowGateState>;
@@ -368,6 +459,8 @@ export declare function enforcePrWorkflowToolBefore(directory: string, sessionID
368
459
  /** Validate the terminal PR workflow contract before removing its durable gate. */
369
460
  export declare function completePrWorkflow(directory: string, sessionID: string, expectedMode: PrWorkflowMode, prHeadSha: string): Promise<PrWorkflowCompletionStatus>;
370
461
  export declare const _test_exports: {
462
+ minimumConsolidatedLaneCover: typeof minimumConsolidatedLaneCover;
463
+ MAX_COVER_UNIVERSE_BITS: number;
371
464
  workflowGateStateRelativePath: typeof workflowGateStateRelativePath;
372
465
  workflowGateStateLockRelativePath: typeof workflowGateStateLockRelativePath;
373
466
  workflowCheckoutMutationLockRelativePath: typeof workflowCheckoutMutationLockRelativePath;
@@ -403,9 +496,66 @@ export declare const _test_exports: {
403
496
  resolvePrReviewDiffStats: typeof resolvePrReviewDiffStats;
404
497
  resolvePrReviewDiffStatsAsync: typeof resolvePrReviewDiffStatsAsync;
405
498
  resolvePrWorkflowRevisionDigest: typeof resolvePrWorkflowRevisionDigest;
499
+ /**
500
+ * The batch cap the capacity GC reclaims against. Exposed so the GC suite
501
+ * builds its fixture from the real bound instead of a hand-copied literal
502
+ * that would silently drift if the cap ever moved.
503
+ */
504
+ MAX_WORKFLOW_BATCHES: number;
505
+ /**
506
+ * The three ledger ceilings whose overflow makes the capacity GC abandon a
507
+ * prune and keep every batch. Exposed on the same reasoning as
508
+ * `MAX_WORKFLOW_BATCHES`: the overflow suite seeds a ledger to exactly its
509
+ * bound from the real constant, so a hand-copied literal cannot drift away
510
+ * from the branch it is meant to reach.
511
+ */
512
+ MAX_RETIRED_REVIEWER_SESSION_IDS: number;
513
+ MAX_RETIRED_CONSOLIDATED_LANES: number;
514
+ MAX_RETIRED_FEEDBACK_ITEM_OWNERS: number;
515
+ /**
516
+ * Issue #1968 P2.2: lets a focused test drive one specific bounded-snapshot
517
+ * failure reason so the BLOCKED diagnostic can be asserted per bound. The
518
+ * pre-existing `resolvePrWorkflowRevisionDigest` seam above still takes
519
+ * priority-two precedence and is unchanged for every existing fixture.
520
+ */
521
+ resolvePrWorkflowRevisionDigestDetailed: typeof resolvePrWorkflowRevisionDigestDetailed;
406
522
  resolveRemoteRefsContainingHead: typeof resolveRemoteRefsContainingHead;
407
523
  resolveRemoteRefsContainingHeadAsync: typeof resolveRemoteRefsContainingHeadAsync;
408
524
  parseCriticVerdict: typeof parseCriticVerdict;
525
+ /**
526
+ * Read-only view of the item-keyed composition for one session, including
527
+ * the diagnostics that settlement only logs (abandoned declared lanes,
528
+ * batches skipped for inventory incoherence). Production callers reach the
529
+ * same computation through settlement and the verdict derivations.
530
+ */
531
+ composePrReviewPhaseVerdicts: (directory: string, sessionID: string, phase: PrReviewComposablePhase) => Promise<PrReviewPhaseComposition>;
532
+ /**
533
+ * Issue #1968 B1 guardrail, exposed directly.
534
+ *
535
+ * Production reaches it from `assertPrReviewValidationSettled`, both
536
+ * critic-coverage gates and the artifact-record projection check. Item-keyed
537
+ * composition makes a real violation unreachable by construction, so the only
538
+ * way to exercise the assertion's own behaviour (and its cause-naming
539
+ * message) without mutating production code is to hand it the divergent pair
540
+ * a future re-split would produce.
541
+ */
542
+ assertSettledPhaseHasAuthoritativeVerdicts: typeof assertSettledPhaseHasAuthoritativeVerdicts;
543
+ /**
544
+ * The critic-coverage gate's guarded input, exposed for the same reason as
545
+ * the assertion above: production reaches its unsettled-reviewer branch only
546
+ * if a caller stops settling reviewer first, which is precisely the future
547
+ * regression it exists to catch, so the branch is otherwise untestable.
548
+ */
549
+ derivePrReviewCriticInventoryForCoverageGate: (directory: string, sessionID: string, origin?: string) => Promise<string[]>;
550
+ /**
551
+ * Read-only view of the mandatory candidate inventory for one session.
552
+ * Production reaches the same derivation through validation-batch ownership
553
+ * validation, the composition, and the artifact-boundary checks; this seam
554
+ * lets a focused test observe *which* base lane won a dimension (the tier-L
555
+ * singleton-over-consolidated precedence) without standing up the full
556
+ * micro-sweep and trigger-ledger prerequisites those entry points require.
557
+ */
558
+ derivePrReviewCandidateInventory: (directory: string, sessionID: string) => Promise<string[]>;
409
559
  isProcessAlive: typeof isProcessAlive;
410
560
  isSafeStandaloneGitCommit: typeof isSafeStandaloneGitCommit;
411
561
  rename: typeof fsp.rename;
@@ -421,6 +571,113 @@ export declare function normalizePrWorkflowShellCommand(command: string): {
421
571
  strippedCdPrefix: boolean;
422
572
  };
423
573
  declare function isSafeStandaloneGitCommit(command: string): boolean;
574
+ /**
575
+ * The gate's view of a digest failure. Everything the bounded-snapshot resolver
576
+ * can report, plus one test-only case: an injected `string | null` seam returned
577
+ * `null`, which carries no reason at all. Modelled explicitly rather than folded
578
+ * into one of the real reasons so a diagnostic never claims a bound fired when
579
+ * nothing proved it did.
580
+ */
581
+ type GateRevisionDigestResult = RevisionDigestResult | {
582
+ ok: false;
583
+ reason: 'seam-unavailable';
584
+ detail?: string;
585
+ };
586
+ /**
587
+ * Name the exact bound that fired, plus what to do about it.
588
+ *
589
+ * Exported because `dispatch_lanes_async` resolves the same bounded revision
590
+ * digest before any gate entry point runs, and must produce the same
591
+ * bound-naming diagnostic rather than the pre-fix "could not compute" with no
592
+ * indication of which of six limits was hit (issue #1968 P2.2 / criterion 6).
593
+ */
594
+ export declare function describePrWorkflowRevisionDigestFailure(failure: Extract<GateRevisionDigestResult, {
595
+ ok: false;
596
+ }>): string;
597
+ /**
598
+ * One PR_REVIEW gate entry point's memoized derivation context.
599
+ *
600
+ * Two properties, both load-bearing:
601
+ *
602
+ * 1. **One revision digest per gate call.** Every artifact-integrity check below
603
+ * compares the persisted artifact's `revisionDigest` against the current
604
+ * worktree revision. Resolving that per record costs three blocking `git`
605
+ * calls plus a full re-read of every changed file, once per record. Both
606
+ * callers of the marker check already require
607
+ * `record.workspace.prHeadSha === state.prHeadSha` earlier in the same
608
+ * predicate, so every record reaching the comparison shares one head and one
609
+ * resolution is equivalent to N.
610
+ *
611
+ * **Honest equivalence statement:** one digest is equivalent to N per-record
612
+ * resolves *absent concurrent worktree mutation during a gate call*. The
613
+ * resolver reads the live worktree, so this narrows a TOCTOU window rather
614
+ * than being a pure cost change. It adopts the precedent already set by the
615
+ * PR_FEEDBACK verification path, which resolves once and threads.
616
+ *
617
+ * 2. **One composed verdict map per gate call.** Settlement, critic-inventory
618
+ * derivation, the artifact-record projection check and the legacy-eligibility
619
+ * marker check are separate passes over the same state. They must never hold
620
+ * two different notions of "the current reviewer verdict", so the composition
621
+ * is computed once here and the same object is handed to all of them.
622
+ *
623
+ * A context is valid for exactly one gate entry-point call over one state
624
+ * snapshot. Never cache it across calls.
625
+ */
626
+ interface PrReviewGateContext {
627
+ readonly revisionDigest: string;
628
+ reviewer?: PrReviewPhaseComposition;
629
+ critic?: PrReviewPhaseComposition;
630
+ candidateInventory?: string[];
631
+ }
632
+ type PrReviewComposablePhase = 'reviewer' | 'critic';
633
+ /** One item's admitted verdict plus the lane provenance that admitted it. */
634
+ interface PrReviewItemClaim {
635
+ batchId: string;
636
+ laneId: string;
637
+ workflowLane: string;
638
+ /** Reviewer classification, or critic status. */
639
+ classification: string;
640
+ severity: string;
641
+ /**
642
+ * sha256 of the full canonical `[REVIEWED]` row this claim was parsed from.
643
+ * Reviewer claims only — this is what a critic batch binds to per item.
644
+ */
645
+ rowDigest?: string;
646
+ }
647
+ interface PrReviewPhaseComposition {
648
+ /** Item id -> winning claim. Most recent successful lane per item wins. */
649
+ claims: Map<string, PrReviewItemClaim>;
650
+ requiredInventory: string[];
651
+ unclaimed: string[];
652
+ contributingBatchIds: string[];
653
+ diagnostics: string[];
654
+ }
655
+ /**
656
+ * **B1 invariant — the accounting defect class's most dangerous recurrence.**
657
+ *
658
+ * Issue #1968's defect class treats the whole inventory on the current revision
659
+ * as the atomic unit of validity. Its worst recurrence is not a false BLOCK, it
660
+ * is a silent PASS: a phase treated as *settled* while the authoritative verdict
661
+ * map every downstream gate reads is empty or partial. For the reviewer phase
662
+ * that chain is `derivePrReviewCriticInventory` -> `[]` ->
663
+ * `completePrWorkflow`'s `criticInventory.length > 0` is false -> **critic
664
+ * coverage is skipped entirely** and CONFIRMED CRITICAL/HIGH findings ship
665
+ * unchallenged, with the only surface symptom a downstream
666
+ * `no authoritative reviewer verdict` that names a consequence, not the cause.
667
+ *
668
+ * Composition currently makes this unreachable by construction: settlement *is*
669
+ * `unclaimed.length === 0` over the very map derivation projects, and claims are
670
+ * filtered to `requiredInventory`, so `unclaimed === []` implies the map covers
671
+ * every required item. This assertion deliberately does **not** rely on that
672
+ * adjacency. It states the property directly so a future refactor that re-splits
673
+ * settlement from derivation fails loudly at the gate instead of silently
674
+ * skipping the critic phase.
675
+ *
676
+ * Fail-closed and always on; never downgraded to a warning, because the failure
677
+ * it catches is invisible in the passing direction. Pure over values the caller
678
+ * already computed: no digest resolution, no artifact reads, no subprocess work.
679
+ */
680
+ declare function assertSettledPhaseHasAuthoritativeVerdicts(phase: PrReviewComposablePhase, composed: Pick<PrReviewPhaseComposition, 'requiredInventory' | 'unclaimed'>, authoritative: ReadonlyMap<string, unknown>, origin: string): void;
424
681
  /** Require at least one semantically valid discovery row or CLEAN attestation. */
425
682
  export declare function prReviewDiscoveryArtifactCoversLane(text: string, expectedWorkflowLane: string, ownedWorkflowLanes?: readonly string[]): boolean;
426
683
  declare function parseCriticVerdict(text: string, itemId: string, reviewerSeverity?: string): {
@@ -73,12 +73,16 @@ export declare const MAX_FALLBACK_BANNER_INJECTIONS_PER_SESSION = 20;
73
73
  */
74
74
  export declare const DEFAULT_TOTAL_WAKE_CEILINGS: Record<PrReviewDepthTier, number>;
75
75
  /**
76
- * Bounded FIFO map of tracked wake budgets. Invariant 8 (session/global
77
- * state): module-level state must have an explicit eviction strategy. Three
78
- * further per-session maps share this same bound and the same FIFO discipline:
79
- * `bannerStamps` (instant of the last full banner), `banneredMessages` (the
80
- * assistant message already carrying a banner), and `fallbackInjections` (the
81
- * injection count on the messageID-less path).
76
+ * Bound on the tracked wake budgets. Invariant 8 (session/global state):
77
+ * module-level state must have an explicit eviction strategy. `wakeBudgets`
78
+ * evicts LEAST RECENTLY WOKEN see {@link evictIfOverBound}, which also
79
+ * refuses to drop suspended or in-flight entries and therefore treats this
80
+ * bound as best-effort. Three further per-session maps share the same numeric
81
+ * bound but keep the simpler insertion-order FIFO discipline, because they
82
+ * hold no enforcement state that is unsafe to lose: `bannerStamps` (instant of
83
+ * the last full banner), `banneredMessages` (the assistant message already
84
+ * carrying a banner), and `fallbackInjections` (the injection count on the
85
+ * messageID-less path).
82
86
  */
83
87
  export declare const MAX_TRACKED_WAKE_SESSIONS = 200;
84
88
  interface PrWorkflowResponseGateClient {
@@ -89,12 +93,26 @@ interface WakeBudget {
89
93
  lastWakeAt: number;
90
94
  lastSeenRevision?: number;
91
95
  suspended: boolean;
92
- /** Total number of wake attempts across the session lifetime. Never reset by
93
- * revision progress — only the consecutive counter resets on progress. */
96
+ /** Total number of wake attempts recorded for this budget. NEVER reset by
97
+ * revision progress — only the consecutive counter resets on progress; that
98
+ * is the guarantee this counter exists to provide. Its SCOPE is the scope of
99
+ * the enclosing map (see `wakeBudgets` in
100
+ * {@link createPrWorkflowResponseGate}): one PROCESS lifetime, running until
101
+ * the durable gate CLEARS. `resetBudget` drops the entry on a gate clear
102
+ * (complete/abort) and a plugin reload starts fresh totals — so this is not
103
+ * a total across the whole conversation/session lifetime.
104
+ *
105
+ * Deliberately NOT "one workflow activation": `transitionPrReviewToFeedback`
106
+ * (`pr-workflow-gate.ts`) mints a new `workflowInstanceId` WITHOUT clearing
107
+ * the gate, so a budget survives the PR_REVIEW -> PR_FEEDBACK handoff and
108
+ * keeps accumulating across both activations. See the ceiling note at the
109
+ * `totalWakes` increment for why that matters. */
94
110
  totalWakes: number;
95
111
  /** Discriminator for WHY the session was suspended: 'consecutive' means
96
112
  * the consecutive-unproductive budget was exhausted; 'total' means the
97
- * absolute per-session total-wake ceiling was reached. */
113
+ * total-wake ceiling in force for this process, at the tier the gate
114
+ * currently reports, was reached (same scope caveat as
115
+ * {@link WakeBudget.totalWakes}). */
98
116
  suspendedReason: 'consecutive' | 'total';
99
117
  }
100
118
  /**
@@ -10,6 +10,25 @@ export type WriteTargetResolution = {
10
10
  export interface WriteTargetResolverContext {
11
11
  directory: string;
12
12
  }
13
+ /**
14
+ * Field names a patch-family tool (`patch` / `apply_patch` /
15
+ * `swarm_apply_patch`) may use to carry its patch payload. Issue #2059: models
16
+ * and tool wrappers commonly emit `patchText`, `patch_text`, `patchPayload`,
17
+ * `text`, or `content`; recognizing only `patch`/`input`/`diff` made the
18
+ * resolver throw `WRITE TARGET UNVERIFIABLE: No patch payload was provided`
19
+ * for valid diffs.
20
+ *
21
+ * Exported so the guardrail layer (`tool-before.ts`) can reuse the single
22
+ * source of truth instead of drifting its own inline copies (the drift is what
23
+ * hid the original bug — three copies of this list existed).
24
+ *
25
+ * Collision safety: the patch resolver only runs for tools in
26
+ * `WRITE_TOOL_NAMES`, and `extract_code_blocks` (which uses `content`) routes
27
+ * to `extractResolver`, not `patchResolver`. Any future `WRITE_TOOL_NAMES`
28
+ * addition that uses `text` or `content` for a non-patch purpose must be
29
+ * audited against this list.
30
+ */
31
+ export declare const PATCH_PAYLOAD_KEYS: readonly ["patch", "input", "diff", "patchText", "patch_text", "patchPayload", "text", "content"];
13
32
  declare function genericResolver(args: Record<string, unknown>): WriteTargetResolution;
14
33
  declare function extractResolver(args: Record<string, unknown>, context: WriteTargetResolverContext): WriteTargetResolution;
15
34
  /** One authoritative resolver per registered write tool. */