opencode-swarm 7.136.1 → 7.136.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.opencode/skills/brainstorm/SKILL.md +1 -1
- package/.opencode/skills/clarify/SKILL.md +3 -3
- package/.opencode/skills/clarify-spec/SKILL.md +2 -2
- package/.opencode/skills/consult/SKILL.md +1 -1
- package/.opencode/skills/council/SKILL.md +1 -1
- package/.opencode/skills/critic-gate/SKILL.md +8 -3
- package/.opencode/skills/discover/SKILL.md +1 -1
- package/.opencode/skills/execute/SKILL.md +1 -1
- package/.opencode/skills/gate-attribution/SKILL.md +1 -1
- package/.opencode/skills/issue-ingest/SKILL.md +3 -3
- package/.opencode/skills/phase-wrap/SKILL.md +1 -1
- package/.opencode/skills/plan/SKILL.md +3 -3
- package/.opencode/skills/pre-phase-briefing/SKILL.md +1 -1
- package/.opencode/skills/resume/SKILL.md +1 -1
- package/.opencode/skills/specify/SKILL.md +1 -1
- package/.opencode/skills/swarm-pr-feedback/SKILL.md +41 -1
- package/.opencode/skills/swarm-pr-review/SKILL.md +72 -24
- package/README.md +18 -0
- package/dist/background/workspace-snapshot.d.ts +54 -0
- package/dist/cli/{config-doctor-6fphg5xm.js → config-doctor-g71mz50j.js} +2 -2
- package/dist/cli/{core-4z1s2ak1.js → core-jpjk2qvt.js} +1 -1
- package/dist/cli/{curation-policy-m24jbyag.js → curation-policy-zhyttjpa.js} +6 -6
- package/dist/cli/{curator-zrt5sqj2.js → curator-36dxw38r.js} +27 -24
- package/dist/cli/{curator-llm-factory-w5arq7tr.js → curator-llm-factory-k2a7cv41.js} +27 -24
- package/dist/cli/{evidence-summary-service-w006jnpg.js → evidence-summary-service-nse06dqr.js} +8 -6
- package/dist/cli/{gate-evidence-aenyz6vt.js → gate-evidence-kdygjr56.js} +4 -4
- package/dist/cli/{guardrail-explain-462jwhbh.js → guardrail-explain-1k337z5d.js} +28 -25
- package/dist/cli/{guardrail-log-ax21jd9e.js → guardrail-log-xbc9bvdt.js} +3 -3
- package/dist/cli/hashing-mjwn6j4y.js +34 -0
- package/dist/cli/{hive-promoter-2vacnbws.js → hive-promoter-daxrn62p.js} +27 -24
- package/dist/cli/{index-r9v98d0y.js → index-0vq9gnqd.js} +46 -5
- package/dist/cli/{index-jwrydqjp.js → index-176zwqcq.js} +2 -2
- package/dist/cli/{index-cggqh2dz.js → index-45y0y3xh.js} +57 -1000
- package/dist/cli/{index-gf7hqbmz.js → index-68tjkaqk.js} +5 -1
- package/dist/cli/{index-dyy3hvk3.js → index-79pgzj9a.js} +4 -4
- package/dist/cli/{index-45t7w06b.js → index-7t3vjw5e.js} +1 -1
- package/dist/cli/{index-ey29aap6.js → index-b3jfcptk.js} +1 -1
- package/dist/cli/{index-prnjt2jr.js → index-brtg922w.js} +4576 -2316
- package/dist/cli/{index-7a2hm51h.js → index-cze4bq1x.js} +41 -0
- package/dist/cli/{index-mrtms113.js → index-d2sf9an1.js} +2 -2
- package/dist/cli/{index-wxyxf0bd.js → index-d61h3f3h.js} +2 -2
- package/dist/cli/{index-rhgctfn3.js → index-g2kpqpvh.js} +29 -26
- package/dist/cli/{index-g7g4hqh3.js → index-g5rtcb1n.js} +1 -1
- package/dist/cli/{index-1sq47n6t.js → index-gj5jerzz.js} +12 -6
- package/dist/cli/{index-c9ddxv4k.js → index-hh34tyv7.js} +1 -1
- package/dist/cli/{index-h3bweb88.js → index-kp5h245k.js} +5 -5
- package/dist/cli/{index-tcn457d5.js → index-kym0cctr.js} +1 -1
- package/dist/cli/{index-kzc2ygea.js → index-mgbpbs1f.js} +3 -3
- package/dist/cli/{index-tfa40hwb.js → index-n89fdxwg.js} +19 -2
- package/dist/cli/index-ne28wyyc.js +783 -0
- package/dist/cli/index-nfm9f10v.js +1100 -0
- package/dist/cli/{index-zkddc5ye.js → index-pff46kfv.js} +2 -2
- package/dist/cli/{index-f4cmtd89.js → index-rtgqy0yg.js} +2 -2
- package/dist/cli/{index-09b9zncg.js → index-tncy55bp.js} +1 -1
- package/dist/cli/{index-vg3yx648.js → index-w6j1n5az.js} +1 -1
- package/dist/cli/{index-hzkvbycn.js → index-wbdxmf1a.js} +6 -6
- package/dist/cli/{index-y6a7gjtj.js → index-wsdnttf4.js} +228 -81
- package/dist/cli/index-y8552snf.js +264 -0
- package/dist/cli/{index-9gxp450h.js → index-zcrvn579.js} +2 -2
- package/dist/cli/{index-p1pqqwgp.js → index-zwh5dewz.js} +1 -1
- package/dist/cli/{index-dzyjb33e.js → index-zzhyws9g.js} +1 -1
- package/dist/cli/index.js +27 -24
- package/dist/cli/{knowledge-escalator-1zt8qy1c.js → knowledge-escalator-h7fspgph.js} +7 -7
- package/dist/cli/{knowledge-events-ej3s9tsm.js → knowledge-events-vkf7an5n.js} +5 -5
- package/dist/cli/{knowledge-link-mm1w967j.js → knowledge-link-zr40rnwr.js} +4 -4
- package/dist/cli/{knowledge-store-ey4cbkp4.js → knowledge-store-s4976v9c.js} +5 -5
- package/dist/cli/{knowledge-validator-zwmq7s2c.js → knowledge-validator-64ppqy4y.js} +8 -8
- package/dist/cli/{pending-delegations-qajsxct0.js → pending-delegations-0h5b18p7.js} +3 -3
- package/dist/cli/{pr-subscriptions-qhr41epq.js → pr-subscriptions-jn0h047q.js} +3 -3
- package/dist/cli/runner-deeswadt.js +21 -0
- package/dist/cli/{scan-cursor-809hf2n1.js → scan-cursor-xbkae12h.js} +6 -6
- package/dist/cli/{schema-mhd7xqwr.js → schema-7jm70cab.js} +5 -1
- package/dist/cli/{scope-persistence-h2fpgxww.js → scope-persistence-5xc9ntdh.js} +4 -4
- package/dist/cli/{skill-generator-yyc8zd9j.js → skill-generator-8gtq1ajr.js} +9 -9
- package/dist/cli/{telemetry-859khp82.js → telemetry-6678gya0.js} +1 -1
- package/dist/cli/{workspace-snapshot-jmyamqnv.js → workspace-snapshot-h5rzw37b.js} +5 -1
- package/dist/cli/{worktree-collision-ownership-13btcj9g.js → worktree-collision-ownership-wt7cc850.js} +3 -3
- package/dist/commands/registry.d.ts +72 -0
- package/dist/commands/skill-opt.d.ts +41 -0
- package/dist/config/schema.d.ts +57 -0
- package/dist/hooks/delegation-gate.d.ts +12 -1
- package/dist/hooks/gate-denial-tracker.d.ts +175 -0
- package/dist/hooks/guardrails/execution-episode.d.ts +41 -0
- package/dist/hooks/guardrails/execution-stall.d.ts +285 -0
- package/dist/hooks/guardrails/file-authority.d.ts +11 -2
- package/dist/hooks/guardrails/internals-guard.d.ts +117 -0
- package/dist/hooks/guardrails/messages-transform.d.ts +85 -0
- package/dist/hooks/pr-workflow-gate.d.ts +261 -4
- package/dist/hooks/pr-workflow-response-gate.d.ts +27 -9
- package/dist/hooks/trajectory-logger.d.ts +76 -0
- package/dist/hooks/write-target-resolver.d.ts +19 -0
- package/dist/index.js +511 -462
- package/dist/memory/schema.d.ts +3 -3
- package/dist/prm/index.d.ts +2 -0
- package/dist/services/skill-evaluator.d.ts +17 -0
- package/dist/services/skill-optimizer/activation.d.ts +58 -0
- package/dist/services/skill-optimizer/candidates.d.ts +88 -0
- package/dist/services/skill-optimizer/controller.d.ts +146 -0
- package/dist/services/skill-optimizer/deterministic-seed.d.ts +29 -0
- package/dist/services/skill-optimizer/lifecycle.d.ts +70 -0
- package/dist/services/skill-optimizer/promoted-external-staleness.d.ts +98 -0
- package/dist/services/skill-optimizer/retirement.d.ts +54 -0
- package/dist/services/skill-optimizer/skill-eval-tasks.d.ts +47 -0
- package/dist/services/skill-optimizer/smoke.d.ts +46 -0
- package/dist/services/skill-optimizer/store.d.ts +118 -0
- package/dist/state.d.ts +32 -0
- package/dist/telemetry.d.ts +66 -1
- package/dist/tools/write-pr-review-trigger-eval.d.ts +2 -1
- package/dist/types/events.d.ts +14 -1
- package/dist/utils/stable-stringify.d.ts +46 -0
- package/evaluation-fixtures/skill-eval/scoring/score-skill-eval.cjs +97 -0
- package/package.json +2 -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
|
-
/**
|
|
306
|
-
|
|
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
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
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
|
|
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
|
-
*
|
|
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
|
/**
|
|
@@ -23,6 +23,13 @@ export interface TrajectoryEntry {
|
|
|
23
23
|
args_summary: string;
|
|
24
24
|
verdict: string;
|
|
25
25
|
elapsed_ms: number;
|
|
26
|
+
/**
|
|
27
|
+
* Host tool-call id. Written only by {@link recordDeniedToolCall} (issue
|
|
28
|
+
* #2063 D1) so a `tool.execute.after` that unexpectedly fires for a call
|
|
29
|
+
* whose before-hook already threw can be recognised and skipped instead of
|
|
30
|
+
* double-recording the same call.
|
|
31
|
+
*/
|
|
32
|
+
callID?: string;
|
|
26
33
|
}
|
|
27
34
|
/**
|
|
28
35
|
* Truncates a trajectory file to the newest half when maxLines is exceeded.
|
|
@@ -32,6 +39,28 @@ export interface TrajectoryEntry {
|
|
|
32
39
|
* @param maxLines - Maximum number of lines to retain
|
|
33
40
|
*/
|
|
34
41
|
export declare function truncateTrajectoryFile(filePath: string, maxLines: number): Promise<void>;
|
|
42
|
+
/**
|
|
43
|
+
* Derives the action type from the tool name.
|
|
44
|
+
*
|
|
45
|
+
* Issue #2063 D2: the name is normalized via `normalizeToolNameLowerCase`
|
|
46
|
+
* first, so host-namespaced names (`opencode:bash`, `opencode.read`) bucket
|
|
47
|
+
* identically to their bare forms. Previously they all fell through to
|
|
48
|
+
* `tool_use`, which flattened the taxonomy PRM pattern detection reads. `grep`
|
|
49
|
+
* was likewise missing from the read bucket despite being one of the most
|
|
50
|
+
* frequent read-only calls.
|
|
51
|
+
*
|
|
52
|
+
* @param tool - Tool name (may carry a host namespace prefix)
|
|
53
|
+
* @returns Action type string
|
|
54
|
+
*/
|
|
55
|
+
declare function deriveAction(tool: string): string;
|
|
56
|
+
/**
|
|
57
|
+
* Extracts the target from tool arguments.
|
|
58
|
+
*
|
|
59
|
+
* @param tool - Tool name
|
|
60
|
+
* @param args - Tool arguments object
|
|
61
|
+
* @returns Target string
|
|
62
|
+
*/
|
|
63
|
+
declare function extractTarget(tool: string, args?: Record<string, unknown>): string;
|
|
35
64
|
/**
|
|
36
65
|
* Creates the trajectory logger hook pair.
|
|
37
66
|
*
|
|
@@ -51,6 +80,41 @@ export declare function createTrajectoryLoggerHook(config: Partial<TrajectoryCon
|
|
|
51
80
|
metadata: unknown;
|
|
52
81
|
}) => Promise<void>;
|
|
53
82
|
};
|
|
83
|
+
/**
|
|
84
|
+
* Records a tool call that a fail-closed `tool.execute.before` hook DENIED.
|
|
85
|
+
*
|
|
86
|
+
* Before this existed the trajectory only contained calls that ran, so a
|
|
87
|
+
* session that spent fifty turns re-issuing a dispatch the delegation gate kept
|
|
88
|
+
* rejecting looked, to PRM and to any post-hoc reader, like a session that made
|
|
89
|
+
* no tool calls at all — the exact loop shape #2063 is about was invisible in
|
|
90
|
+
* the record of it.
|
|
91
|
+
*
|
|
92
|
+
* Contract:
|
|
93
|
+
* - The step is minted with the SHARED `nextTrajectoryStep(sessionId)`. Any
|
|
94
|
+
* private counter would desynchronise the `prmTrajectoryStep` window and
|
|
95
|
+
* silently break PRM's step-range filtering.
|
|
96
|
+
* - `session.delegationActive` gates recording at all (the architect session
|
|
97
|
+
* is deliberately out of scope); the task-evidence copy additionally
|
|
98
|
+
* requires `session.currentTaskId`, so a subagent running without a task id
|
|
99
|
+
* still lands in the PRM store.
|
|
100
|
+
* - EVERY failure is swallowed. This runs inside the `catch` that is about to
|
|
101
|
+
* rethrow a policy denial; it must never change which error propagates.
|
|
102
|
+
*
|
|
103
|
+
* @param sessionID - Session whose chain denied the call
|
|
104
|
+
* @param input - The host `tool.execute.before` input (tool / callID / args)
|
|
105
|
+
* @param errorMessage - The ORIGINAL denial message, before any B1 decoration
|
|
106
|
+
* @param directory - Workspace root (evidence + PRM store live under `.swarm/`)
|
|
107
|
+
* @param options - `maxLines` mirrors the hook's `max_lines` config
|
|
108
|
+
*/
|
|
109
|
+
export declare function recordDeniedToolCall(sessionID: string, input: {
|
|
110
|
+
tool: string;
|
|
111
|
+
callID?: string;
|
|
112
|
+
args?: Record<string, unknown>;
|
|
113
|
+
}, errorMessage: string, directory: string, options?: {
|
|
114
|
+
maxLines?: number;
|
|
115
|
+
}): Promise<void>;
|
|
116
|
+
/** Test helper: drop all denied-call dedupe markers. */
|
|
117
|
+
export declare function clearDeniedCallMarkers(): void;
|
|
54
118
|
/**
|
|
55
119
|
* Resets the step counter for a session. Called when a new session starts
|
|
56
120
|
* or when trajectory tracking should restart from step 1.
|
|
@@ -73,3 +137,15 @@ export declare function clearTrajectoryStep(sessionId?: string): void;
|
|
|
73
137
|
* @param startTime - Start timestamp in milliseconds
|
|
74
138
|
*/
|
|
75
139
|
export declare function recordToolCallStart(sessionId: string, callID: string, startTime: number): void;
|
|
140
|
+
/**
|
|
141
|
+
* Tier-0 pure-function test seam (writing-tests skill). These helpers take no
|
|
142
|
+
* external dependencies, so testing them directly needs no mocks at all.
|
|
143
|
+
*/
|
|
144
|
+
export declare const _test_exports: {
|
|
145
|
+
readonly deriveAction: typeof deriveAction;
|
|
146
|
+
readonly extractTarget: typeof extractTarget;
|
|
147
|
+
readonly MAX_DENIED_CALL_MARKERS: 500;
|
|
148
|
+
readonly DENIED_CALL_TTL_MS: number;
|
|
149
|
+
readonly deniedCallMarkerCount: () => number;
|
|
150
|
+
};
|
|
151
|
+
export {};
|
|
@@ -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. */
|