opencode-swarm 7.161.1 → 7.162.1

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 (89) hide show
  1. package/dist/background/pr-review-contract.d.ts +1 -24
  2. package/dist/cli/authorization-vstrh7ra.js +23 -0
  3. package/dist/cli/{coder-settlement-2jteb5vy.js → coder-settlement-zrda71k0.js} +9 -9
  4. package/dist/cli/{config-doctor-1yn317qf.js → config-doctor-gjw4hdvt.js} +2 -2
  5. package/dist/cli/{core-k687jrr3.js → core-q5j5a7fh.js} +1 -1
  6. package/dist/cli/{curation-policy-ej9xc0cd.js → curation-policy-nv31cr6t.js} +5 -5
  7. package/dist/cli/{curator-llm-factory-m1ke17eq.js → curator-llm-factory-8d6kqsj1.js} +33 -31
  8. package/dist/cli/{curator-q017rjfk.js → curator-njskp28b.js} +33 -31
  9. package/dist/cli/{evidence-summary-service-6jzfa547.js → evidence-summary-service-5rry81jm.js} +13 -13
  10. package/dist/cli/{gate-evidence-j6nskaka.js → gate-evidence-b6k9wng8.js} +5 -5
  11. package/dist/cli/{guardrail-explain-xw3ma90f.js → guardrail-explain-5yw549sm.js} +34 -32
  12. package/dist/cli/{guardrail-log-etmzhbge.js → guardrail-log-nrnx87ac.js} +7 -7
  13. package/dist/cli/{guardrail-reset-z9fkxksy.js → guardrail-reset-zm5an5bw.js} +33 -31
  14. package/dist/cli/{hive-promoter-dmwjya83.js → hive-promoter-zzgnfhxr.js} +33 -31
  15. package/dist/cli/{index-32avgbyq.js → index-0myjf1y2.js} +2 -2
  16. package/dist/cli/{index-dq41vsf9.js → index-1eqbnwm6.js} +1 -1
  17. package/dist/cli/{index-dh5q6z7y.js → index-3b762978.js} +7 -4
  18. package/dist/cli/{index-qd9mrd7e.js → index-3fs3p6ck.js} +5 -5
  19. package/dist/cli/{index-cbcfpgz9.js → index-3gym3fjj.js} +6 -6
  20. package/dist/cli/{index-c6zyqgpq.js → index-3nsewz46.js} +1 -1
  21. package/dist/cli/{index-nm0cpfrv.js → index-5a8nk165.js} +4 -4
  22. package/dist/cli/{index-d8st72j7.js → index-63s6t3z4.js} +1 -1
  23. package/dist/cli/{index-7d79mj06.js → index-7322jr05.js} +9 -9
  24. package/dist/cli/{index-bn78ywnb.js → index-9cvfa8p8.js} +1 -1
  25. package/dist/cli/{index-k55td019.js → index-9m1ze4z4.js} +1 -1
  26. package/dist/cli/{index-hvfsz7e3.js → index-a1bh2e4f.js} +6 -6
  27. package/dist/cli/{index-c1geyan9.js → index-bgzdwkpe.js} +1 -1
  28. package/dist/cli/{index-epjvntnm.js → index-cjjcey0h.js} +1 -1
  29. package/dist/cli/{index-29f9te70.js → index-f18bqg18.js} +5 -3
  30. package/dist/cli/{index-awjx0wgk.js → index-fckfgptr.js} +1 -1
  31. package/dist/cli/{index-88wb0z9r.js → index-gss86tj3.js} +2 -2
  32. package/dist/cli/{index-za42r41w.js → index-gwbxeh8j.js} +14 -643
  33. package/dist/cli/{index-1j532307.js → index-hq1gdz0g.js} +2 -2
  34. package/dist/cli/{index-zhdfqz89.js → index-j1gq4qm8.js} +5 -5
  35. package/dist/cli/{index-4p6x3xxy.js → index-m24pv3f4.js} +4 -4
  36. package/dist/cli/{index-jm21vbyp.js → index-m516tpxe.js} +2 -2
  37. package/dist/cli/index-mmngnxev.js +883 -0
  38. package/dist/cli/{index-134d35c1.js → index-n249fbw7.js} +9 -0
  39. package/dist/cli/{index-s33ee2w3.js → index-nbfpnb0w.js} +1 -1
  40. package/dist/cli/{index-7619tk9a.js → index-rkr19fdv.js} +1 -1
  41. package/dist/cli/{index-9kp3cp5n.js → index-ttdjphep.js} +3 -3
  42. package/dist/cli/{index-f5axf6vq.js → index-v0t8z5ab.js} +1 -1
  43. package/dist/cli/{index-rracnf2y.js → index-vcen0ne4.js} +1 -1
  44. package/dist/cli/{index-y14mwbk8.js → index-w1sfjffe.js} +2 -2
  45. package/dist/cli/index-w7ekntej.js +643 -0
  46. package/dist/cli/{index-hq57ytm5.js → index-wvfgkms6.js} +1 -1
  47. package/dist/cli/{index-e0re84cx.js → index-xsv6zv7n.js} +35 -33
  48. package/dist/cli/{index-cs9w1hfs.js → index-xtjvg1wx.js} +2691 -2781
  49. package/dist/cli/{index-k4xey4kh.js → index-y3fgbx8g.js} +1 -1
  50. package/dist/cli/{index-yhadrxka.js → index-z74stz9p.js} +4 -4
  51. package/dist/cli/index.js +33 -31
  52. package/dist/cli/{knowledge-escalator-cqyxfjfh.js → knowledge-escalator-8y3adkn0.js} +11 -11
  53. package/dist/cli/{knowledge-events-g707awjf.js → knowledge-events-mnexhwe2.js} +9 -9
  54. package/dist/cli/{knowledge-link-8knefv8x.js → knowledge-link-jr8rqr39.js} +4 -4
  55. package/dist/cli/{knowledge-store-byhv66xq.js → knowledge-store-cp42ccd1.js} +5 -5
  56. package/dist/cli/{knowledge-validator-qfkr8eje.js → knowledge-validator-hwp1t6x3.js} +7 -7
  57. package/dist/cli/{pending-delegations-n3baz9m3.js → pending-delegations-jj5vaq9q.js} +5 -4
  58. package/dist/cli/{pr-subscriptions-3zwthnan.js → pr-subscriptions-mm6kyyv0.js} +4 -4
  59. package/dist/cli/{runner-fzgkd6m1.js → runner-d402vnq3.js} +5 -5
  60. package/dist/cli/{scan-cursor-fbtgyeft.js → scan-cursor-d75dh3hv.js} +6 -6
  61. package/dist/cli/{schema-xb7d31wq.js → schema-djm1bhb8.js} +1 -1
  62. package/dist/cli/{scope-persistence-5npzdfjf.js → scope-persistence-g0yc6dfa.js} +8 -8
  63. package/dist/cli/{skill-generator-k1e7nee3.js → skill-generator-9ppgxz4j.js} +13 -13
  64. package/dist/cli/{sqlite-loader-r1kgt2pq.js → sqlite-loader-c92413n7.js} +1 -1
  65. package/dist/cli/{worktree-collision-ownership-jfam09nj.js → worktree-collision-ownership-061zmyyp.js} +6 -5
  66. package/dist/cli/{worktree-isolation-avp3yxcs.js → worktree-isolation-vk82698z.js} +33 -31
  67. package/dist/db/sqlite-loader.d.ts +1 -0
  68. package/dist/hooks/pr-workflow-gate.d.ts +20 -245
  69. package/dist/index.js +392 -378
  70. package/dist/memory/curator-decision-helpers.d.ts +1 -0
  71. package/dist/memory/index.d.ts +1 -1
  72. package/dist/memory/local-jsonl-provider.d.ts +2 -0
  73. package/dist/memory/proposal-load.d.ts +15 -0
  74. package/dist/memory/relation-constants.d.ts +3 -0
  75. package/dist/memory/relations.d.ts +8 -0
  76. package/dist/memory/schema.d.ts +8 -0
  77. package/dist/memory/sqlite-provider.d.ts +3 -0
  78. package/dist/memory/types.d.ts +21 -0
  79. package/dist/{hooks/pr-review-reentry-authorization.d.ts → pr-review/authorization.d.ts} +32 -10
  80. package/dist/{hooks/pr-review-resilience-circuit.d.ts → pr-review/circuit.d.ts} +60 -3
  81. package/dist/pr-review/completion.d.ts +373 -0
  82. package/dist/pr-review/critic-routing.d.ts +37 -0
  83. package/dist/pr-review/guardrails.d.ts +67 -0
  84. package/dist/pr-review/legacy-transcript-adapter.d.ts +276 -0
  85. package/dist/pr-review/persistence.d.ts +107 -0
  86. package/dist/pr-review/reducer.d.ts +54 -0
  87. package/dist/pr-review/types.d.ts +225 -0
  88. package/package.json +1 -1
  89. package/dist/cli/pr-review-reentry-authorization-ttctn8xv.js +0 -301
@@ -0,0 +1,276 @@
1
+ /**
2
+ * Legacy transcript adapter — the transcript/artifact-text → canonical
3
+ * conversion authority (issue #2385).
4
+ *
5
+ * This is the ONLY module allowed to convert raw transcript / artifact text
6
+ * into canonical PR-review data (verdict rows, per-item verdicts, feedback
7
+ * classifications). The locality contract is enforced mechanically by
8
+ * `scanTranscriptParsingOutsideAdapter` in `src/pr-review/guardrails.ts`:
9
+ * every identifier in `TRANSCRIPT_CONVERSION_SYMBOLS` may appear only in this
10
+ * file across `src/`. The gate therefore consumes this boundary through the
11
+ * `legacy*`-prefixed aliases and the test surface exported below — never
12
+ * through the conversion identifiers themselves.
13
+ *
14
+ * Compat gating: the settlement path that accepts legacy (pre-structured-
15
+ * receipt) transcript text is governed by the delegation record's
16
+ * `pr_review_legacy_transcript_compatibility` flag (default false), read
17
+ * through `prReviewLegacyTranscriptCompatibilityEnabled` from
18
+ * `src/background/pr-review-contract.ts`. That settlement path emits no
19
+ * deprecation diagnostic today and none is added here; this header documents
20
+ * the gate only.
21
+ *
22
+ * Binding contract (same precedent as `bindPrReviewCompletionHelpers` in
23
+ * `completion.ts` and `bindPrReviewReentryBindingReader` in
24
+ * `authorization.ts`): this boundary must never import the orchestration gate
25
+ * back. Gate-owned composition/settlement helpers are supplied by the owning
26
+ * gate through `bindPrReviewTranscriptAdapterHelpers`, bound once at gate
27
+ * module init.
28
+ *
29
+ * State typing: the moved functions read only the PR-review slices of the
30
+ * gate's `PrWorkflowGateState` and `PrReviewGateContext`, expressed as the
31
+ * local structural interfaces below; the gate passes its full state and
32
+ * context, which satisfy the slices structurally without a projection step.
33
+ */
34
+ import { type LaneOutputArtifact } from '../background/lane-output-store.js';
35
+ import { type BackgroundDelegationRecord } from '../background/pending-delegations.js';
36
+ import { type PrReviewRiskImpact, type PrReviewRiskTag } from '../background/pr-review-contract.js';
37
+ export type PrReviewComposablePhase = 'reviewer' | 'critic';
38
+ /** One item's admitted verdict plus the lane provenance that admitted it. */
39
+ export interface PrReviewItemClaim {
40
+ batchId: string;
41
+ laneId: string;
42
+ workflowLane: string;
43
+ /** Reviewer classification, or critic status. */
44
+ classification: string;
45
+ severity: string;
46
+ /**
47
+ * Typed risk metadata from the reviewer row (issue #2383). Reviewer claims
48
+ * only; absent on critic claims, which never re-assess routing risk.
49
+ */
50
+ riskImpact?: PrReviewRiskImpact;
51
+ riskTags?: PrReviewRiskTag[];
52
+ /**
53
+ * sha256 of the full canonical `[REVIEWED]` row this claim was parsed from.
54
+ * Reviewer claims only — this is what a critic batch binds to per item.
55
+ */
56
+ rowDigest?: string;
57
+ }
58
+ export interface PrReviewPhaseComposition {
59
+ /** Item id -> winning claim. Most recent successful lane per item wins. */
60
+ claims: Map<string, PrReviewItemClaim>;
61
+ requiredInventory: string[];
62
+ unclaimed: string[];
63
+ contributingBatchIds: string[];
64
+ diagnostics: string[];
65
+ }
66
+ /** Validation-batch shape, as the transcript composition reads it. */
67
+ export interface PrReviewTranscriptBatch {
68
+ batchId: string;
69
+ lanes: ReadonlyArray<PrReviewTranscriptLane>;
70
+ validatedAt: string;
71
+ }
72
+ /** Declared lane shape, as the transcript composition reads it. */
73
+ export interface PrReviewTranscriptLane {
74
+ laneId: string;
75
+ workflowLane: string;
76
+ reviewItemIds?: string[];
77
+ }
78
+ /**
79
+ * Per-batch coherence keys for item-keyed reviewer/critic composition, as the
80
+ * adapter reads them (structural slice of the gate's record).
81
+ */
82
+ export interface PrReviewTranscriptBatchCoherence {
83
+ /**
84
+ * The exact candidate/critic inventory this batch's ownership was validated
85
+ * against at record time.
86
+ */
87
+ validatedInventory: string[];
88
+ /** Critic batches only: per-item sha256 of the authoritative `[REVIEWED]` row. */
89
+ reviewerItemBindings?: Record<string, string>;
90
+ /** Key encoding for reviewerItemBindings; absent means legacy raw item IDs. */
91
+ reviewerItemBindingKeyEncoding?: 'prefixed-v1';
92
+ }
93
+ /** Settled PR_FEEDBACK verification batch, as the adapter reads it. */
94
+ export interface PrReviewTranscriptFeedbackVerification {
95
+ batchId: string;
96
+ ownership: ReadonlyArray<{
97
+ laneId: string;
98
+ }>;
99
+ }
100
+ /**
101
+ * The PR-review slice of the owning gate's `PrWorkflowGateState`: exactly the
102
+ * fields the moved conversion/composition machinery reads directly. The gate's
103
+ * full state type satisfies this structurally.
104
+ */
105
+ export interface PrReviewTranscriptState {
106
+ sessionID: string;
107
+ prReviewBatchCoherence?: Record<string, PrReviewTranscriptBatchCoherence>;
108
+ prFeedbackVerifications?: PrReviewTranscriptFeedbackVerification[];
109
+ }
110
+ /** The gate-context surface the transcript composition consumes (full ctx is gate-owned). */
111
+ export interface PrReviewTranscriptContext {
112
+ readonly revisionDigest: string;
113
+ reviewer?: PrReviewPhaseComposition;
114
+ critic?: PrReviewPhaseComposition;
115
+ }
116
+ /** A batch-integrity-qualified record, as the transcript composition consumes it. */
117
+ export interface PrReviewTranscriptQualifiedBatchRecord {
118
+ record: BackgroundDelegationRecord;
119
+ expectedLane: PrReviewTranscriptLane;
120
+ expectedWorkflowLane: string;
121
+ }
122
+ /**
123
+ * Gate-owned composition/settlement helpers, bound by the owning gate at
124
+ * module init so this boundary never imports the gate back. Declared with
125
+ * method syntax on purpose: the gate's implementations accept/return its FULL
126
+ * state and context types, which are structural supersets of the slices
127
+ * above, and interface method parameters are checked bivariantly.
128
+ */
129
+ export interface PrReviewTranscriptGateHelpers {
130
+ derivePrReviewCandidateInventory(directory: string, state: PrReviewTranscriptState, ctx: PrReviewTranscriptContext): string[];
131
+ derivePrReviewCriticInventory(directory: string, state: PrReviewTranscriptState, ctx: PrReviewTranscriptContext): string[];
132
+ authoritativeReviewerClaims(directory: string, state: PrReviewTranscriptState, ctx: PrReviewTranscriptContext): ReadonlyMap<string, PrReviewItemClaim>;
133
+ reviewerSubagentSessionIds(directory: string, state: PrReviewTranscriptState): Set<string>;
134
+ prReviewPhaseWindow(state: PrReviewTranscriptState, phase: PrReviewComposablePhase): PrReviewTranscriptBatch[];
135
+ batchMayContributeClaims(directory: string, state: PrReviewTranscriptState, batch: PrReviewTranscriptBatch, phase: PrReviewComposablePhase, requiredInventory: readonly string[], forbiddenSubagentSessionIds: ReadonlySet<string>, reviewerClaims: ReadonlyMap<string, PrReviewItemClaim> | undefined, ctx: PrReviewTranscriptContext): boolean;
136
+ recordsPassingBatchIntegrity(directory: string, state: PrReviewTranscriptState, batchId: string, expectedLanes: ReadonlyArray<PrReviewTranscriptLane>, expectedMode: string, validatedAt: string, checkWorkflowLane?: boolean, forbiddenSubagentSessionIds?: ReadonlySet<string>, diagnostics?: string[]): PrReviewTranscriptQualifiedBatchRecord[];
137
+ loadArtifactPassingLaneIntegrity(directory: string, state: PrReviewTranscriptState, record: BackgroundDelegationRecord, expectedMode: string, expectedWorkflowLane: string, expectedRevisionDigest: string, diagnostics?: string[]): LaneOutputArtifact | null;
138
+ }
139
+ export declare function bindPrReviewTranscriptAdapterHelpers(helpers: PrReviewTranscriptGateHelpers): void;
140
+ /**
141
+ * Prefix item IDs before using them as persisted object keys. In particular,
142
+ * assigning a raw `__proto__` key to an ordinary object invokes JavaScript's
143
+ * prototype setter instead of creating an own property.
144
+ */
145
+ export declare function reviewerItemBindingKey(itemId: string): string;
146
+ /**
147
+ * The single item-keyed computation behind reviewer/critic settlement AND every
148
+ * reviewer/critic verdict derivation.
149
+ *
150
+ * Settlement *is* `unclaimed.length === 0` over this map, so settlement can never
151
+ * pass while derivation returns nothing — the failure mode that would let
152
+ * CONFIRMED CRITICAL/HIGH findings ship without critic coverage.
153
+ *
154
+ * Scanning the window reverse-chronologically and claiming only *unclaimed*
155
+ * items makes first-write-wins equal "most recent successful lane per item wins",
156
+ * which is the explicit conflict rule for the case where two batches both carry a
157
+ * parseable verdict for one item. Memoized per gate context so two passes never
158
+ * hold two different verdict maps.
159
+ *
160
+ * The scan stops as soon as every required item is claimed (issue #1968 FIX 5).
161
+ * `readLaneOutput` is a synchronous `readFileSync` per lane per batch, and the
162
+ * window can hold up to `MAX_WORKFLOW_BATCHES` batches, so scanning past a
163
+ * complete claim set is unbounded blocking I/O for no verdict change — first
164
+ * write wins, and every required item has already been written.
165
+ *
166
+ * `exhaustive` turns the exit off for the batch GC, which prunes a reviewer
167
+ * batch on "it contributed no claim". Being precise about what that buys: with
168
+ * *this* exit condition the two scans yield the same `contributingBatchIds`,
169
+ * because the exit fires only when every required item is claimed and a batch
170
+ * reached after that point could never have claimed anything anyway. The flag is
171
+ * therefore not fixing a live divergence — it decouples a durable-state decision
172
+ * from a performance heuristic, so that weakening the exit condition later
173
+ * cannot silently turn "not examined" into "proven inert". It also keeps the
174
+ * whole-window abandoned-lane diagnostics intact for the GC's scan.
175
+ */
176
+ export declare function composePrReviewPhaseVerdicts(directory: string, state: PrReviewTranscriptState, phase: PrReviewComposablePhase, ctx: PrReviewTranscriptContext, exhaustive?: boolean): PrReviewPhaseComposition;
177
+ export interface IndexedVerdictRows {
178
+ markerRows: string[][];
179
+ rowsByItemId: Map<string, string[][]>;
180
+ recoveries: Array<{
181
+ marker: '[REVIEWED]' | '[CRITIC]';
182
+ itemId: string;
183
+ recovery: 'legacy-fidelity-safe' | 'legacy-lossy';
184
+ }>;
185
+ }
186
+ export declare function indexVerdictRows(text: string, marker: '[REVIEWED]' | '[CRITIC]'): IndexedVerdictRows;
187
+ export declare function validateReviewerVerdictFields(fields: string[]): string[] | null;
188
+ /**
189
+ * Digest of the FULL canonical reviewer row, not the classification/severity
190
+ * pair a reviewer verdict projects to. Only 2 of the 12 required fields survive
191
+ * that projection, so a tuple binding would still match a row whose evidence,
192
+ * file:line and root cause all changed. Fields are joined on NUL, which
193
+ * `pipeFields` can never produce, so no field boundary is forgeable.
194
+ */
195
+ export declare function reviewerVerdictRowDigest(fields: readonly string[]): string;
196
+ /**
197
+ * Per-item verdicts an artifact actually carries, as a map rather than a
198
+ * boolean. This is the granularity the composition needs: one unparseable item
199
+ * must not discard its healthy siblings in the same lane.
200
+ */
201
+ export declare function parseLaneItemVerdicts(text: string, itemIds: readonly string[], phase: PrReviewComposablePhase, reviewerClaims?: ReadonlyMap<string, PrReviewItemClaim>): Map<string, {
202
+ classification: string;
203
+ severity: string;
204
+ riskImpact?: PrReviewRiskImpact;
205
+ riskTags?: PrReviewRiskTag[];
206
+ rowDigest?: string;
207
+ }>;
208
+ export declare function parsePrReviewVerdictRows(text: string, itemIds: readonly string[], phase: PrReviewComposablePhase, reviewerClaims?: ReadonlyMap<string, PrReviewItemClaim>): {
209
+ markerRows: string[][];
210
+ parsed: Map<string, {
211
+ classification: string;
212
+ severity: string;
213
+ riskImpact?: PrReviewRiskImpact;
214
+ riskTags?: PrReviewRiskTag[];
215
+ rowDigest?: string;
216
+ }>;
217
+ recoveries: IndexedVerdictRows['recoveries'];
218
+ };
219
+ /** Exact assigned-row contract used by both normal and recovered collection. */
220
+ export declare function analyzePrReviewVerdictRowContract(text: string, itemIds: readonly string[], phase: PrReviewComposablePhase, reviewerClaims?: ReadonlyMap<string, PrReviewItemClaim>): {
221
+ ok: boolean;
222
+ expected: string;
223
+ actual: string;
224
+ recoveries: IndexedVerdictRows['recoveries'];
225
+ };
226
+ export declare function parseCriticVerdict(text: string, itemId: string, reviewerSeverity?: string): {
227
+ status: string;
228
+ severity: string;
229
+ } | null;
230
+ export declare function validateCriticVerdictFields(fields: string[], reviewerSeverity?: string): {
231
+ status: string;
232
+ severity: string;
233
+ } | null;
234
+ export declare function artifactHasExactPositiveVerdictRow(text: string, marker: string, itemId: string, positiveVerdict: string): boolean;
235
+ export declare function pipeFields(line: string): string[];
236
+ /**
237
+ * `pipeFields` capped at the row's canonical field count: separators beyond the
238
+ * expected count merge back into the trailing (free-text) field. Verdict rows
239
+ * ([REVIEWED], [CRITIC], [FEEDBACK-VERIFIED]) carry prose evidence in their
240
+ * last field, and prose containing literal pipes (regex text, `,;|`, shell
241
+ * snippets) otherwise splits the row past its strict field-count check and the
242
+ * whole verdict becomes unparseable. Deterministic: the enumerated leading
243
+ * fields are never merged.
244
+ */
245
+ export declare function pipeFieldsCapped(line: string, expectedFieldCount: number): string[];
246
+ export declare function feedbackArtifactCoversItems(directory: string, state: PrReviewTranscriptState, batchId: string, laneId: string, itemIds: readonly string[]): boolean;
247
+ export declare function feedbackArtifactTextCoversItems(text: string, itemIds: readonly string[]): boolean;
248
+ /**
249
+ * Read the settled verification classification of every inventory item from the
250
+ * settled verification batches' lane outputs (issue #2131 criterion C1). An
251
+ * item missing from the map has no settled verified classification.
252
+ */
253
+ export declare function readSettledFeedbackClassifications(directory: string, state: PrReviewTranscriptState): Map<string, string>;
254
+ /**
255
+ * Issue #2385 guardrail aliases: the transcript-conversion identifiers may
256
+ * appear only in this module (`scanTranscriptParsingOutsideAdapter` in
257
+ * `src/pr-review/guardrails.ts`), so the owning gate imports these aliases
258
+ * instead of the canonical names.
259
+ */
260
+ export declare const analyzeLegacyVerdictRowContract: typeof analyzePrReviewVerdictRowContract;
261
+ export declare const legacyArtifactHasExactPositiveVerdictRow: typeof artifactHasExactPositiveVerdictRow;
262
+ export declare const legacyFeedbackArtifactCoversItems: typeof feedbackArtifactCoversItems;
263
+ export declare const legacyFeedbackArtifactTextCoversItems: typeof feedbackArtifactTextCoversItems;
264
+ export declare const readLegacySettledFeedbackClassifications: typeof readSettledFeedbackClassifications;
265
+ /**
266
+ * The gate's historical `_test_exports` surface for this cluster: spread onto
267
+ * the gate's `_test_exports` at module init so the existing suites keep seeing
268
+ * the same property names without the gate naming the conversion identifiers.
269
+ */
270
+ export declare const legacyTranscriptAdapterTestSurface: {
271
+ pipeFieldsCapped: typeof pipeFieldsCapped;
272
+ indexVerdictRows: typeof indexVerdictRows;
273
+ reviewerVerdictRowDigest: typeof reviewerVerdictRowDigest;
274
+ analyzePrReviewVerdictRowContract: typeof analyzePrReviewVerdictRowContract;
275
+ parseLaneItemVerdicts: typeof parseLaneItemVerdicts;
276
+ };
@@ -0,0 +1,107 @@
1
+ /**
2
+ * PR-review workflow persistence adapter (issues #2385).
3
+ *
4
+ * The single atomic persistence boundary for PR-review workflow state, moved
5
+ * from `src/hooks/pr-workflow-gate.ts` (region: state locks, CAS write,
6
+ * bounded parsing, atomic JSON writes, safe-parent/identity assertions, path
7
+ * helpers, in-memory caches). Every durable PR-review gate-state write goes
8
+ * through this module; the recurrence sweep (issue #2385) forbids direct
9
+ * writes to the state shape outside this boundary.
10
+ *
11
+ * Binding contract (issue #2385 plan, critic item 1): the owning gate binds
12
+ * (a) its full Zod state codec via `bindPrReviewStateCodec` and (b) its
13
+ * `_test_exports` object via `bindPrReviewPersistenceHooks`. Properties are
14
+ * read at CALL time through the bound reference — never destructured at bind
15
+ * time — so test-time property mutation and `resetTrackedStateCache` remain
16
+ * fully visible. Defaults in `defaultPersistenceHooks` make the module usable
17
+ * standalone and are what the gate resets seams back to.
18
+ *
19
+ * The recovery-salvage reader (`readPrWorkflowGateStateForRecovery`) remains
20
+ * in the gate: it composes PR_FEEDBACK sub-schemas (gate-owned) and is a
21
+ * read-only diagnostic built on these primitives.
22
+ */
23
+ import type { BigIntStats } from 'node:fs';
24
+ import * as fsp from 'node:fs/promises';
25
+ import type { ZodError } from 'zod';
26
+ export declare function normalizeSessionID(sessionID: string): string;
27
+ export declare function prWorkflowSessionFileStem(sessionID: string): string;
28
+ export declare const WORKFLOW_GATE_DIR = "pr-workflow-gates";
29
+ export declare function workflowGateStateRelativePath(sessionID: string): string;
30
+ export declare function workflowGateStateLockRelativePath(sessionID: string): string;
31
+ export declare function workflowCheckoutMutationLockRelativePath(): string;
32
+ export declare function workflowGateStatePath(directory: string, sessionID: string): string;
33
+ export declare const MAX_TRACKED_SESSIONS = 200;
34
+ export declare const CHECKOUT_MUTATION_ACTION_TIMEOUT_MS: number;
35
+ export declare const trackedStatesByProjectSession: Map<string, PrWorkflowPersistedStateBase>;
36
+ export declare function isoNow(): string;
37
+ export declare function delay(ms: number): Promise<void>;
38
+ export declare function sameBigIntFileIdentity(left: Pick<BigIntStats, 'dev' | 'ino'>, right: Pick<BigIntStats, 'dev' | 'ino'>): boolean;
39
+ export declare function normalizeComparableFsPath(value: string): string;
40
+ export declare function stateCacheKey(directory: string, sessionID: string): string;
41
+ export declare function rememberState<S extends PrWorkflowPersistedStateBase>(directory: string, state: S): void;
42
+ /** Drop one session's cached state (gate clear/abort paths). */
43
+ export declare function forgetTrackedPrWorkflowState(directory: string, sessionID: string): void;
44
+ /** Test reset: clear every in-process persistence cache/queue. */
45
+ export declare function resetPrReviewPersistenceCaches(): void;
46
+ export interface PrReviewPersistenceHooks {
47
+ nowMs: () => number;
48
+ isProcessAlive: (pid: number) => boolean;
49
+ openCheckoutLock: (lockPath: string) => ReturnType<typeof fsp.open>;
50
+ removeCheckoutLock: (lockPath: string) => Promise<void>;
51
+ checkoutMutationActionTimeoutMs: number;
52
+ rename: (from: string, to: string) => Promise<void>;
53
+ beforeSessionStateLockWrite?: () => Promise<void>;
54
+ beforeCheckoutLockWrite?: () => Promise<void>;
55
+ beforeSafeDirectoryCreate?: (parentPath: string, nextPath: string) => Promise<void>;
56
+ beforeAtomicTempWrite?: () => Promise<void>;
57
+ beforeAtomicRename?: () => Promise<void>;
58
+ }
59
+ export declare const defaultPersistenceHooks: PrReviewPersistenceHooks;
60
+ /**
61
+ * Bind the persistence seam. The gate passes its `_test_exports` object (same
62
+ * reference) so property mutation by tests is read at call time.
63
+ */
64
+ export declare function bindPrReviewPersistenceHooks(nextHooks: PrReviewPersistenceHooks): void;
65
+ /** Structural minimum the CAS machinery relies on. */
66
+ export interface PrWorkflowPersistedStateBase {
67
+ schemaVersion: number;
68
+ revision: number;
69
+ sessionID: string;
70
+ workflowInstanceId?: string;
71
+ }
72
+ export interface PrReviewStateCodec<S extends PrWorkflowPersistedStateBase> {
73
+ safeParse: (data: unknown) => {
74
+ success: true;
75
+ data: S;
76
+ } | {
77
+ success: false;
78
+ error: ZodError;
79
+ };
80
+ parse: (data: unknown) => S;
81
+ }
82
+ export declare function bindPrReviewStateCodec<S extends PrWorkflowPersistedStateBase>(nextCodec: PrReviewStateCodec<S>): void;
83
+ export declare function ensurePrWorkflowSafeParentDirectory(directory: string, filePath: string): Promise<string>;
84
+ export declare function writeAtomicJson(directory: string, filePath: string, value: unknown): Promise<void>;
85
+ /**
86
+ * Write a PR-workflow artifact with the gate's Windows-safe atomic persistence
87
+ * contract. Checkout-preparation receipts must survive the same transient
88
+ * rename contention as canonical gate state.
89
+ */
90
+ export declare function writePrWorkflowAtomicJson(directory: string, filePath: string, value: unknown): Promise<void>;
91
+ export declare function readPrWorkflowGateStateFromDisk<S extends PrWorkflowPersistedStateBase>(directory: string, sessionID: string): Promise<S | null>;
92
+ export declare function readPrWorkflowGateStateFileFromDisk<S extends PrWorkflowPersistedStateBase>(filePath: string, stateLabel: string): Promise<S | null>;
93
+ /** Persist one CAS-checked state replacement while the session lock is held. */
94
+ export declare function writeStateWhileLocked<S extends PrWorkflowPersistedStateBase>(directory: string, state: S, options?: {
95
+ replaceWorkflowInstanceId?: string;
96
+ }): Promise<S>;
97
+ /** A bounded checkout-mutation refusal that never permits unsafe late overlap. */
98
+ export declare class PrWorkflowCheckoutMutationTimeoutError extends Error {
99
+ readonly phase: 'queue' | 'action';
100
+ readonly code: "PR_WORKFLOW_CHECKOUT_MUTATION_TIMEOUT";
101
+ readonly retryable: false;
102
+ constructor(phase: 'queue' | 'action');
103
+ }
104
+ /** Serialize project-wide checkout mutations before any session state lock. */
105
+ export declare function withPrWorkflowCheckoutMutationLock<T>(directory: string, action: () => Promise<T>): Promise<T>;
106
+ /** Serialize in-process mutations; the durable revision rejects stale callers. */
107
+ export declare function withSessionStateMutation<T>(directory: string, sessionID: string, action: () => Promise<T>): Promise<T>;
@@ -0,0 +1,54 @@
1
+ /**
2
+ * PR-review transition authority (issue #2385).
3
+ *
4
+ * Pure `(state, event) -> { state, effects }` reducer over the closed
5
+ * `PrReviewEvent` union. Rule computation is delegated to the focused
6
+ * boundary modules (`circuit.ts`, `completion.ts` via its settlement inputs,
7
+ * `critic-routing.ts`, `lifecycle.ts`); this module owns transition
8
+ * composition and the explicit rejection of every invalid transition class
9
+ * named by issue #2385:
10
+ *
11
+ * - observer deadline / client absence → terminal child failure
12
+ * - raw transcript / parser failure → provider circuit signal
13
+ * - one lane → multiple circuit samples (delegated to circuit.ts's
14
+ * distinct-`(generation, batch, lane)` scan; asserted by property tests)
15
+ * - unresolved/live lane → terminal coverage report
16
+ * - partial/no coverage → approval
17
+ * - ordinary MEDIUM → critic without typed high-impact/vulnerability evidence
18
+ * (enforced where critic inventory is composed, via critic-routing.ts)
19
+ * - stale/foreign authorization → reviewer or publication access
20
+ * - late old-generation result → current-state mutation
21
+ * - structured receipt → downgrade by later transcript parsing
22
+ *
23
+ * The owning gate and `dispatch-lanes` are orchestration adapters: they build
24
+ * events from real I/O, apply the returned state, and map typed rejections to
25
+ * the operator-facing BLOCKED messages. Effects are the transition's OUTPUT
26
+ * CONTRACT — every effect kind maps to an executor that exists in production
27
+ * (see `PrReviewEffect` in types.ts): the gate executes `persist_state`
28
+ * through the persistence CAS write; `settle_delegation` describes the
29
+ * delegation settlement the dispatch/collect adapters perform through
30
+ * `pending-delegations.ts`; `emit_diagnostic` describes the collect
31
+ * observer's bounded diagnostics channel; `block_dispatch` describes the
32
+ * circuit-open admission refusal. No effect kind is emitted without a real
33
+ * executor (reviewer finding 1, issue #2385 Phase 8b).
34
+ *
35
+ * Probe outcomes other than an admission rollback are processed by the
36
+ * machine on the NEXT staged admission: the gate feeds the recorded probe's
37
+ * observation into `advancePrReviewCircuit` (`probeObservationForCircuit`),
38
+ * which is the design's single advance-per-admission cadence.
39
+ */
40
+ import type { PrReviewEffect, PrReviewEvent, PrReviewTransitionRejection, PrReviewWorkflowState } from './types.js';
41
+ export type PrReviewReduceResult = {
42
+ status: 'applied';
43
+ state: PrReviewWorkflowState;
44
+ effects: PrReviewEffect[];
45
+ } | {
46
+ status: 'rejected';
47
+ state: PrReviewWorkflowState;
48
+ rejection: PrReviewTransitionRejection;
49
+ };
50
+ /**
51
+ * The transition authority. Pure: every I/O input arrives on the event; every
52
+ * write leaves as an effect. The state is never mutated in place.
53
+ */
54
+ export declare function reducePrReviewEvent(state: PrReviewWorkflowState, event: PrReviewEvent): PrReviewReduceResult;
@@ -0,0 +1,225 @@
1
+ /**
2
+ * PR-review typed state boundary (issue #2385).
3
+ *
4
+ * The closed event/effect vocabulary for the PR-review transition authority
5
+ * (`reducer.ts`) plus the PR-review slice of the workflow gate state. The
6
+ * owning gate's full `PrWorkflowGateState` satisfies this slice structurally
7
+ * (a compile-time assertion in the gate enforces it), so there is ONE field
8
+ * definition — the gate adds only non-PR-review fields.
9
+ *
10
+ * Invalid transitions from issue #2385 are rejected with typed codes
11
+ * (`PrReviewTransitionRejectionCode`) rather than made representable-by-type
12
+ * alone: several of them depend on runtime evidence (generations, digests,
13
+ * ledger state), so the reducer is the enforcement point.
14
+ */
15
+ import type { PrReviewBaseDimensionId } from '../background/pr-review-contract.js';
16
+ import type { PrReviewCircuitSignal, PrReviewResiliencePolicyRecord } from './circuit.js';
17
+ /** A declared base-dispatch lane (subset the reducer governs). */
18
+ export interface PrReviewBaseDispatchLane {
19
+ laneId: string;
20
+ workflowLane: PrReviewBaseDimensionId;
21
+ ownedWorkflowLanes?: PrReviewBaseDimensionId[];
22
+ }
23
+ export interface PrReviewBaseDispatchRecordLite {
24
+ batchId: string;
25
+ lanes: PrReviewBaseDispatchLane[];
26
+ validatedAt: string;
27
+ }
28
+ export interface PrReviewDimensionCancellationLite {
29
+ reason: string;
30
+ cancelledAt: string;
31
+ source: 'armed_recovery';
32
+ }
33
+ export interface PrReviewResilienceSlice {
34
+ policy: PrReviewResiliencePolicyRecord;
35
+ /** Attempt bookkeeping is adapter-owned; the reducer carries it opaquely. */
36
+ attempts: readonly unknown[];
37
+ circuit?: import('./circuit.js').PrReviewCircuitRecord | undefined;
38
+ }
39
+ /**
40
+ * The PR-review slice of the workflow gate state. The gate's full state type
41
+ * satisfies this structurally; the reducer may therefore be applied to the
42
+ * live gate state object without a projection step.
43
+ */
44
+ export interface PrReviewWorkflowState {
45
+ sessionID: string;
46
+ workflowInstanceId?: string | undefined;
47
+ revision: number;
48
+ prHeadSha?: string | undefined;
49
+ prReviewBaseSha?: string | undefined;
50
+ prReviewBaseDispatches?: PrReviewBaseDispatchRecordLite[] | undefined;
51
+ prReviewBaseDispatch?: PrReviewBaseDispatchRecordLite | undefined;
52
+ prReviewResilience?: PrReviewResilienceSlice | undefined;
53
+ prReviewContractRetryDimensions?: PrReviewBaseDimensionId[] | undefined;
54
+ prReviewDimensionCancellations?: Partial<Record<PrReviewBaseDimensionId, PrReviewDimensionCancellationLite>> | undefined;
55
+ /** Coverage disclosure fields are carried opaquely (owned by completion.ts). */
56
+ prReviewPartialBaseCoverage?: unknown | undefined;
57
+ }
58
+ export type PrReviewTerminalCoverageKind = 'COMPLETE' | 'PARTIAL' | 'NO_COVERAGE';
59
+ export type PrReviewReportVerdict = 'APPROVE' | 'INCOMPLETE' | 'REQUEST_CHANGES';
60
+ export interface PrReviewCoverageSettlementInput {
61
+ kind: PrReviewTerminalCoverageKind;
62
+ coveredDimensions: PrReviewBaseDimensionId[];
63
+ unresolvedDimensions: Array<{
64
+ dimension: PrReviewBaseDimensionId;
65
+ terminalState: 'FAILED' | 'CANCELLED' | 'NOT_LAUNCHED';
66
+ reasonKind: string;
67
+ }>;
68
+ /** Dimensions with a live (non-terminal) lane — blocks finalization. */
69
+ liveDimensions: PrReviewBaseDimensionId[];
70
+ }
71
+ export type PrReviewEffect = {
72
+ kind: 'persist_state';
73
+ } | {
74
+ kind: 'settle_delegation';
75
+ batchId: string;
76
+ laneId: string;
77
+ status: 'completed' | 'error' | 'cancelled' | 'stale';
78
+ replay?: boolean;
79
+ } | {
80
+ kind: 'emit_diagnostic';
81
+ source: 'collection_observer' | 'legacy_transcript_adapter';
82
+ code: string;
83
+ boundedDetail?: string | undefined;
84
+ } | {
85
+ kind: 'block_dispatch';
86
+ reason: 'circuit_open' | 'probe_in_flight';
87
+ };
88
+ /**
89
+ * Effect kinds map to executors that exist in production (issue #2385
90
+ * Phase 8b review): `persist_state` is executed by the gate through the
91
+ * persistence CAS write; `settle_delegation` describes the settlement the
92
+ * dispatch/collect adapters perform via `pending-delegations.ts`;
93
+ * `emit_diagnostic` describes the collect observer's bounded diagnostics
94
+ * channel; `block_dispatch` describes the circuit-open admission refusal.
95
+ * A kind with no executor is not emitted and not declared.
96
+ */
97
+ export type PrReviewCircuitProbeOutcome = {
98
+ result: 'typed_success';
99
+ } | {
100
+ result: 'provider_failure';
101
+ providerClass: string;
102
+ } | {
103
+ result: 'ignored';
104
+ } | {
105
+ result: 'rolled_back_admission';
106
+ };
107
+ export type PrReviewEvent = {
108
+ type: 'base_admission_requested';
109
+ batchId: string;
110
+ lanes: PrReviewBaseDispatchLane[];
111
+ depthTier: 'S' | 'M' | 'L';
112
+ maxBatches: number;
113
+ validatedAt: string;
114
+ } | {
115
+ type: 'base_admission_rolled_back';
116
+ batchId: string;
117
+ batchDelegationRecordsExist: boolean;
118
+ } | {
119
+ type: 'collection_observed';
120
+ diagnostic: 'busy' | 'retry' | 'idle_unknown' | 'host_unavailable' | 'probe_error' | 'wait_expired';
121
+ pendingLaneIds: readonly string[];
122
+ boundedDetail?: string | undefined;
123
+ } | {
124
+ type: 'lane_structured_result_submitted';
125
+ batchId: string;
126
+ laneId: string;
127
+ generation: number;
128
+ semanticEnvelopeDigest: string;
129
+ outcome: 'CLEAN' | 'FINDINGS' | 'INCOMPLETE';
130
+ existingReceiptDigest?: string | undefined;
131
+ } | {
132
+ type: 'transcript_evidence_presented';
133
+ batchId: string;
134
+ laneId: string;
135
+ laneHasStructuredReceipt: boolean;
136
+ } | {
137
+ type: 'provider_terminal_observed';
138
+ batchId: string;
139
+ laneId: string;
140
+ generation: number;
141
+ evidence: {
142
+ source: 'typed_terminal_error_class';
143
+ category: string;
144
+ kind: string;
145
+ } | {
146
+ source: 'observer_deadline';
147
+ } | {
148
+ source: 'client_unavailable';
149
+ } | {
150
+ source: 'parser_or_transcript';
151
+ } | {
152
+ source: 'stale_observation';
153
+ };
154
+ } | {
155
+ type: 'lane_cancelled';
156
+ batchId: string;
157
+ laneId: string;
158
+ generation: number;
159
+ } | {
160
+ type: 'circuit_advance_requested';
161
+ nowMs: number;
162
+ laneSignals: readonly PrReviewCircuitSignal[];
163
+ probeObservation?: {
164
+ terminalStatus: string;
165
+ signal: PrReviewCircuitSignal | null;
166
+ terminalAtMs: number;
167
+ } | undefined;
168
+ admission?: {
169
+ batchId: string;
170
+ laneId: string;
171
+ } | undefined;
172
+ policy: PrReviewResiliencePolicyRecord;
173
+ } | {
174
+ type: 'circuit_probe_settled';
175
+ outcome: PrReviewCircuitProbeOutcome;
176
+ nowMs: number;
177
+ policy: PrReviewResiliencePolicyRecord;
178
+ } | {
179
+ type: 'resilience_config_changed';
180
+ enabled: boolean;
181
+ policy?: import('../config/schema.js').PrReviewResilienceConfig | undefined;
182
+ nowMs: number;
183
+ } | {
184
+ type: 'coverage_finalization_requested';
185
+ settlement: PrReviewCoverageSettlementInput;
186
+ requestedVerdict?: PrReviewReportVerdict;
187
+ } | {
188
+ type: 'critic_result_recorded';
189
+ criticRequiredFindingIds: readonly string[];
190
+ criticConfirmedFindingIds: readonly string[];
191
+ } | {
192
+ type: 'publication_armed';
193
+ coverageKind: PrReviewTerminalCoverageKind;
194
+ verdict: PrReviewReportVerdict;
195
+ } | {
196
+ type: 'publication_published';
197
+ binding: PrReviewAuthorizationBinding;
198
+ } | {
199
+ type: 'armed_recovery_requested';
200
+ binding: PrReviewAuthorizationBinding;
201
+ dimensionsToCancel: PrReviewBaseDimensionId[];
202
+ nowIso: string;
203
+ } | {
204
+ type: 'reviewer_authorization_consumed';
205
+ binding: PrReviewAuthorizationBinding;
206
+ expectedRole: 'reviewer' | 'test_engineer';
207
+ role: 'reviewer' | 'test_engineer';
208
+ };
209
+ /**
210
+ * The exact-identity binding an armed recovery, publication, or re-entry
211
+ * authorization must carry (issue #2383/#2385). Stale or foreign values are
212
+ * rejected with `stale_foreign_authorization`.
213
+ */
214
+ export interface PrReviewAuthorizationBinding {
215
+ sessionID: string;
216
+ workflowInstanceId?: string | undefined;
217
+ prHeadSha: string;
218
+ revisionDigest?: string;
219
+ generation: number;
220
+ }
221
+ export type PrReviewTransitionRejectionCode = 'observer_deadline_not_terminal_evidence' | 'client_absence_not_terminal_evidence' | 'parser_failure_not_provider_signal' | 'stale_observation_not_provider_signal' | 'live_lane_blocks_coverage' | 'partial_coverage_cannot_approve' | 'no_coverage_cannot_approve' | 'critic_required_unfulfilled' | 'stale_foreign_authorization' | 'stale_generation_result' | 'receipt_cannot_be_downgraded' | 'duplicate_conflicting_result' | 'base_batch_limit_reached' | 'rollback_preconditions_failed' | 'lane_not_stale_eligible' | 'unknown_event';
222
+ export interface PrReviewTransitionRejection {
223
+ code: PrReviewTransitionRejectionCode;
224
+ detail: string;
225
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "7.161.1",
3
+ "version": "7.162.1",
4
4
  "description": "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",