opencode-swarm 7.162.0 → 7.163.0
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/dist/background/pr-review-contract.d.ts +1 -24
- package/dist/cli/authorization-vstrh7ra.js +23 -0
- package/dist/cli/{coder-settlement-s8cskxk7.js → coder-settlement-g2g5kkv5.js} +10 -10
- package/dist/cli/{config-doctor-636h188h.js → config-doctor-p16xr78z.js} +2 -2
- package/dist/cli/{core-h3hsczyq.js → core-g088v0zt.js} +1 -1
- package/dist/cli/{curation-policy-ayq5kmnf.js → curation-policy-j12j2gvc.js} +6 -6
- package/dist/cli/{curator-p0dwpn2x.js → curator-3m8a8qsn.js} +33 -31
- package/dist/cli/curator-llm-factory-p00hks4v.js +69 -0
- package/dist/cli/{evidence-summary-service-hvbqyb4g.js → evidence-summary-service-4ghqakhx.js} +13 -13
- package/dist/cli/{gate-evidence-dhgmnsh0.js → gate-evidence-4v8apasx.js} +6 -6
- package/dist/cli/guardrail-explain-smqenqtm.js +70 -0
- package/dist/cli/{guardrail-log-qc7rfhv2.js → guardrail-log-mmh4b4k4.js} +7 -7
- package/dist/cli/{guardrail-reset-cxkf5h0x.js → guardrail-reset-zge5hg4p.js} +33 -31
- package/dist/cli/{hive-promoter-ppbrv8m1.js → hive-promoter-vxez5s7m.js} +33 -31
- package/dist/cli/{index-jw7z3gem.js → index-0103w5pf.js} +2 -2
- package/dist/cli/{index-fx3em0dr.js → index-2zgjcmmc.js} +139 -45
- package/dist/cli/{index-qw893zqp.js → index-3ab9tczn.js} +8 -8
- package/dist/cli/{index-q87ht62k.js → index-3b762978.js} +5 -2
- package/dist/cli/{index-5wq0dd30.js → index-3rjxbe1p.js} +2 -2
- package/dist/cli/{index-z4n60b0a.js → index-453tzvkg.js} +1 -1
- package/dist/cli/{index-pde4zn7j.js → index-4t68xs0p.js} +3 -3
- package/dist/cli/{index-sjkxrf06.js → index-4xggfhge.js} +4 -4
- package/dist/cli/{index-8vwe2qjh.js → index-5hgn302x.js} +9 -9
- package/dist/cli/{index-bdmg6yvj.js → index-7n9jznv0.js} +4 -4
- package/dist/cli/{index-2rhs7j4r.js → index-7wb2v7jg.js} +2152 -2622
- package/dist/cli/{index-kk9yk7an.js → index-8ada7ag7.js} +2 -2
- package/dist/cli/{index-nqbqkx4c.js → index-9crtmnqg.js} +1 -1
- package/dist/cli/{index-3gwkmq53.js → index-axx3t3k7.js} +2 -2
- package/dist/cli/{index-80pmq6q2.js → index-cqgpvx2d.js} +2 -2
- package/dist/cli/{index-vcv9m2q5.js → index-eqkdjfqa.js} +4 -4
- package/dist/cli/{index-77syzssw.js → index-f7t5fn4z.js} +4 -4
- package/dist/cli/{index-9wrmzsnk.js → index-fckfgptr.js} +1 -1
- package/dist/cli/{index-0h63swrc.js → index-g4bvsapf.js} +5 -5
- package/dist/cli/{index-ydbd41sv.js → index-hm239n1p.js} +1 -1
- package/dist/cli/{index-qn4w0gar.js → index-m4nhy4fp.js} +1 -1
- package/dist/cli/{index-2ze7yqm8.js → index-m7yt3xmk.js} +1 -1
- package/dist/cli/index-mmngnxev.js +883 -0
- package/dist/cli/{index-7z9gyts0.js → index-n2mhyect.js} +1 -1
- package/dist/cli/{index-db520vnn.js → index-n67vx5zw.js} +2 -2
- package/dist/cli/{index-25xvw7hq.js → index-nwa7ctyf.js} +35 -33
- package/dist/cli/{index-4wmpv2kn.js → index-ptsmms01.js} +6 -6
- package/dist/cli/{index-mfewnd7j.js → index-pykfqsk0.js} +5 -5
- package/dist/cli/{index-r7rn6e5f.js → index-qy2rm1f6.js} +6 -6
- package/dist/cli/{index-tnj464kq.js → index-rqh25ns3.js} +1 -1
- package/dist/cli/{index-tjaawnws.js → index-s8c6f9rr.js} +6 -4
- package/dist/cli/{index-vkaqrrsc.js → index-t4hs3qk6.js} +15 -644
- package/dist/cli/{index-1wapt173.js → index-w0yn4rmh.js} +3 -3
- package/dist/cli/{index-1mbwgw4p.js → index-w1mc7gcm.js} +2 -2
- package/dist/cli/index-w7ekntej.js +643 -0
- package/dist/cli/{index-acnwj4pc.js → index-xyhmt813.js} +1 -1
- package/dist/cli/{index-6w468bjy.js → index-zgz81a8x.js} +1 -1
- package/dist/cli/index.js +33 -31
- package/dist/cli/{knowledge-escalator-nyeg4ndw.js → knowledge-escalator-91d1n291.js} +12 -12
- package/dist/cli/{knowledge-events-z7smbnff.js → knowledge-events-xrd9es3p.js} +10 -10
- package/dist/cli/{knowledge-link-0byjmj0w.js → knowledge-link-vmdj5e5d.js} +5 -5
- package/dist/cli/{knowledge-store-p14t72y5.js → knowledge-store-2brg88cx.js} +6 -6
- package/dist/cli/{knowledge-validator-jg6zhx9s.js → knowledge-validator-s1v7kry2.js} +8 -8
- package/dist/cli/{pending-delegations-0111ywd2.js → pending-delegations-b341397j.js} +6 -5
- package/dist/cli/{pr-subscriptions-4e64sbwg.js → pr-subscriptions-2mkdt0ak.js} +5 -5
- package/dist/cli/{runner-rddddxmq.js → runner-3gw2njnx.js} +6 -6
- package/dist/cli/{scan-cursor-wjad4yd7.js → scan-cursor-jm7j3w1c.js} +7 -7
- package/dist/cli/{schema-9ebqj7mv.js → schema-6cpgnq4s.js} +1 -1
- package/dist/cli/{scope-persistence-j5hz4mnd.js → scope-persistence-q713ck5n.js} +9 -9
- package/dist/cli/{skill-generator-x6b05jz6.js → skill-generator-z9bs6vdt.js} +14 -14
- package/dist/cli/{telemetry-cmbjv240.js → telemetry-x4zggfd7.js} +1 -1
- package/dist/cli/{worktree-collision-ownership-g5n5xbqy.js → worktree-collision-ownership-drtv7jjp.js} +7 -6
- package/dist/cli/{worktree-isolation-ha70bwes.js → worktree-isolation-534h3c2f.js} +33 -31
- package/dist/council/council-observability.d.ts +42 -0
- package/dist/hooks/pr-workflow-gate.d.ts +20 -245
- package/dist/index.js +374 -374
- package/dist/observability/catalog.d.ts +8 -4
- package/dist/observability/ids.d.ts +1 -1
- package/dist/observability/legacy.d.ts +6 -4
- package/dist/observability/observe.d.ts +1 -1
- package/dist/{hooks/pr-review-reentry-authorization.d.ts → pr-review/authorization.d.ts} +32 -10
- package/dist/{hooks/pr-review-resilience-circuit.d.ts → pr-review/circuit.d.ts} +60 -3
- package/dist/pr-review/completion.d.ts +373 -0
- package/dist/pr-review/critic-routing.d.ts +37 -0
- package/dist/pr-review/guardrails.d.ts +67 -0
- package/dist/pr-review/legacy-transcript-adapter.d.ts +276 -0
- package/dist/pr-review/persistence.d.ts +107 -0
- package/dist/pr-review/reducer.d.ts +54 -0
- package/dist/pr-review/types.d.ts +225 -0
- package/dist/telemetry.d.ts +1 -1
- package/package.json +1 -1
- package/dist/cli/curator-llm-factory-g65xmh8f.js +0 -67
- package/dist/cli/guardrail-explain-s0dzn8c6.js +0 -68
- package/dist/cli/pr-review-reentry-authorization-b7ceja9y.js +0 -301
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PR-review recurrence guardrails (issue #2385).
|
|
3
|
+
*
|
|
4
|
+
* Exported source scanners implementing the mechanical guardrails the issue
|
|
5
|
+
* requires. Each scanner is a PURE function over `{ path, content }` source
|
|
6
|
+
* maps; unit tests prove each scanner flags a synthetic violating snippet
|
|
7
|
+
* (the guardrail "biting") and then apply it over the real `src/` tree.
|
|
8
|
+
*
|
|
9
|
+
* 1. `scanObserverTerminalization` — (a) the historical wait-deadline/no-client
|
|
10
|
+
* terminalizer may never reappear by name; (b) in
|
|
11
|
+
* `src/tools/dispatch-lanes.ts`, durable delegation-transition writes are
|
|
12
|
+
* allowed only inside the sanctioned settlement functions.
|
|
13
|
+
* 2. `scanParallelCircuitRuleConstruction` — circuit-record construction may
|
|
14
|
+
* exist only under `src/pr-review/` (the inline-construction recurrence
|
|
15
|
+
* class G-1).
|
|
16
|
+
*
|
|
17
|
+
* Issue #2385 originally specified a third scanner for transcript-parsing
|
|
18
|
+
* locality (the 13 conversion symbols restricted to the legacy adapter),
|
|
19
|
+
* but its only test consumer was a synthetic-input bite demo with no
|
|
20
|
+
* production caller. The boundary is already enforced structurally
|
|
21
|
+
* (the legacy-transcript-adapter is the sole module that owns those symbols,
|
|
22
|
+
* and the two retained scanners cover the real recurrence classes). A
|
|
23
|
+
* scanner with no caller would create the appearance of a guardrail where
|
|
24
|
+
* there is none — per the issue's "no unwired functionality" bar, it was
|
|
25
|
+
* removed instead.
|
|
26
|
+
*/
|
|
27
|
+
export interface GuardrailSource {
|
|
28
|
+
path: string;
|
|
29
|
+
content: string;
|
|
30
|
+
}
|
|
31
|
+
export interface GuardrailHit {
|
|
32
|
+
path: string;
|
|
33
|
+
line: number;
|
|
34
|
+
rule: string;
|
|
35
|
+
excerpt: string;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* The historical PR-review wait-deadline terminalizer (issue #2381 deleted
|
|
39
|
+
* it). Any reappearance of these names in `src/` is the exact recurrence
|
|
40
|
+
* class the issue forbids: a collection wait budget or an unavailable host
|
|
41
|
+
* messages client must never write a terminal delegation transition.
|
|
42
|
+
*/
|
|
43
|
+
export declare const FORBIDDEN_OBSERVER_TERMINALIZER_SYMBOLS: readonly string[];
|
|
44
|
+
/**
|
|
45
|
+
* Enclosing functions in `src/tools/dispatch-lanes.ts` that are allowed to
|
|
46
|
+
* write delegation transitions. Every entry is child-evidence-driven
|
|
47
|
+
* settlement (typed terminal error, explicit caller cancellation, or the
|
|
48
|
+
* age+liveness presumed-stale backstop) — never observer-deadline evidence:
|
|
49
|
+
* - `startAsyncLanePrompt`: `running` transition after a successful launch.
|
|
50
|
+
* - `appendAsyncLaneLaunchError`: typed `error` for a failed child launch.
|
|
51
|
+
* - `collectOnce`: explicit caller `cancelled` transition.
|
|
52
|
+
* - `settleCollectedLane`: `completed`/`error` settlement from child evidence.
|
|
53
|
+
* - `sweepStaleAsyncLaneRecords`: the presumed-stale `stale` backstop.
|
|
54
|
+
* Additions must document their evidence source here.
|
|
55
|
+
*/
|
|
56
|
+
export declare const DELEGATION_WRITE_ALLOWED_FUNCTIONS: ReadonlySet<string>;
|
|
57
|
+
/**
|
|
58
|
+
* Guardrail 2. (a) flags any forbidden historical-terminalizer symbol;
|
|
59
|
+
* (b) for `src/tools/dispatch-lanes.ts`, flags delegation-transition writes
|
|
60
|
+
* inside any enclosing function outside the sanctioned allowlist. This
|
|
61
|
+
* module itself is exempt from rule (a): it DEFINES the forbidden names
|
|
62
|
+
* (the definition site is not a recurrence, same reasoning as the adapter
|
|
63
|
+
* allowlist in guardrail 1).
|
|
64
|
+
*/
|
|
65
|
+
export declare function scanObserverTerminalization(sources: readonly GuardrailSource[]): GuardrailHit[];
|
|
66
|
+
/** Guardrail 3 (issue #2385 recurrence class G-1). */
|
|
67
|
+
export declare function scanParallelCircuitRuleConstruction(sources: readonly GuardrailSource[]): GuardrailHit[];
|
|
@@ -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;
|