@effect-agent/pr-review 0.1.0-beta.23 → 0.1.0-beta.25
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/README.md +83 -195
- package/dist/action.d.mts +27 -18
- package/dist/action.mjs +60 -39
- package/dist/action.mjs.map +1 -1
- package/dist/cli.mjs +3 -3
- package/dist/cli.mjs.map +1 -1
- package/dist/{fan-out-BJBTAYuh.d.mts → fan-out-CMEsbFLk.d.mts} +455 -177
- package/dist/{github-BbwYzNrC.mjs → github-NjgxGqwM.mjs} +2163 -1518
- package/dist/github-NjgxGqwM.mjs.map +1 -0
- package/dist/index.d.mts +30 -20
- package/dist/index.mjs +3 -3
- package/dist/{providers-NyP-4rS6.mjs → providers-CODZQCmL.mjs} +202 -80
- package/dist/providers-CODZQCmL.mjs.map +1 -0
- package/dist/testing.d.mts +3 -1
- package/dist/testing.mjs +3 -2
- package/dist/testing.mjs.map +1 -1
- package/package.json +2 -2
- package/src/action.ts +141 -78
- package/src/cli.ts +6 -1
- package/src/index.ts +1 -0
- package/src/internal/adjudication.ts +415 -0
- package/src/internal/coverage.ts +41 -60
- package/src/internal/factory.ts +4 -4
- package/src/internal/fan-out.ts +208 -14
- package/src/internal/fingerprint.ts +16 -10
- package/src/internal/fixtures.ts +6 -0
- package/src/internal/github-env.ts +9 -0
- package/src/internal/github.ts +243 -7
- package/src/internal/progress.ts +1 -1
- package/src/internal/render.ts +186 -42
- package/src/internal/retirement.ts +16 -17
- package/src/internal/review-agent.ts +39 -4
- package/src/internal/review-state.ts +315 -105
- package/src/internal/review-units.ts +10 -9
- package/src/internal/run.ts +197 -63
- package/dist/github-BbwYzNrC.mjs.map +0 -1
- package/dist/providers-NyP-4rS6.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# @effect-agent/pr-review
|
|
2
2
|
|
|
3
|
-
A bounded, fail-closed GitHub pull-request reviewer built on
|
|
4
|
-
|
|
3
|
+
A bounded, fail-closed GitHub pull-request reviewer built on effect-agent's public APIs. Read-only
|
|
4
|
+
Agents review host-partitioned pull-request evidence
|
|
5
5
|
through typed ports; the host validates every finding anchor against the real
|
|
6
6
|
diff and posts one review after the run settles.
|
|
7
7
|
|
|
@@ -15,6 +15,7 @@ truncated run posts nothing.
|
|
|
15
15
|
import { Effect, Layer } from "effect";
|
|
16
16
|
import {
|
|
17
17
|
PrReview,
|
|
18
|
+
fullReviewExecutionContextLayer,
|
|
18
19
|
gitHubReviewLayers,
|
|
19
20
|
resolveReviewTarget,
|
|
20
21
|
makeOpenAiReviewModel,
|
|
@@ -27,13 +28,22 @@ const program = Effect.gen(function* () {
|
|
|
27
28
|
const target = yield* resolveReviewTarget({ repository: "acme/api", number: 123 });
|
|
28
29
|
return yield* reviewer
|
|
29
30
|
.run({ post: true })
|
|
30
|
-
.pipe(
|
|
31
|
+
.pipe(
|
|
32
|
+
Effect.provide(
|
|
33
|
+
fullReviewExecutionContextLayer("explicit direct full review").pipe(
|
|
34
|
+
Layer.provideMerge(Layer.merge(gitHubReviewLayers(target), openAiClientLayer)),
|
|
35
|
+
),
|
|
36
|
+
),
|
|
37
|
+
);
|
|
31
38
|
});
|
|
32
39
|
```
|
|
33
40
|
|
|
34
41
|
The run's requirement channel keeps every real dependency visible: the
|
|
35
|
-
`PullRequestSource
|
|
36
|
-
|
|
42
|
+
`PullRequestSource`, `ReviewPublisher`, `ReviewAdjudicationHost`, and
|
|
43
|
+
`ReviewExecutionContext` ports, the provider client, and the handler Layer of
|
|
44
|
+
any extra tool you add. Direct callers provide an explicit full-review context
|
|
45
|
+
as above; the packaged action supplies its selected incremental or full range.
|
|
46
|
+
Anthropic is equally supported
|
|
37
47
|
(`makeAnthropicReviewModel`, `anthropicClientLayer`), and the factory accepts
|
|
38
48
|
any Effect AI Model.
|
|
39
49
|
|
|
@@ -53,44 +63,20 @@ const reviewer = PrReview.make({
|
|
|
53
63
|
});
|
|
54
64
|
```
|
|
55
65
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
the
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
pass that fails (child fault, malformed or misdirected output) is retried
|
|
71
|
-
once; a pass that stays failed is reported and its unit's paths carry forward
|
|
72
|
-
as retryable scope. Verifiers receive the exact candidate claims and the
|
|
73
|
-
complete bounded unit, including neighboring evidence that can falsify a
|
|
74
|
-
locally plausible claim; they do not receive discovery reasoning.
|
|
75
|
-
The host builds publishable findings and concerns from exact confirmed
|
|
76
|
-
candidate IDs and deduplicates byte-identical cross-pass claims in
|
|
77
|
-
deterministic plan order; a discovery claim anchored outside its assigned
|
|
78
|
-
evidence is discarded and counted, never published and never pass-fatal. The
|
|
79
|
-
summary and verdict are composed deterministically from the confirmed
|
|
80
|
-
severities. Shared `guidance` reaches both discovery and verification;
|
|
81
|
-
`maxFindings` remains a host-enforced publication cap.
|
|
82
|
-
|
|
83
|
-
GitHub may omit the `patch` field for large textual files as well as binary
|
|
84
|
-
files. The GitHub source recovers a missing patch by reading bounded, strict
|
|
85
|
-
UTF-8 base/head content: additions require the head, deletions require the
|
|
86
|
-
base, and other changes require both. Reviewers receive that content through
|
|
87
|
-
the ordinary diff-read tool with non-anchorable `B`/`H` line labels and must
|
|
88
|
-
report defects as review-body concerns. Invalid UTF-8, binary NUL content,
|
|
89
|
-
missing sides, and files beyond the per-side read bound leave a path with no
|
|
90
|
-
reviewable textual evidence. Such paths keep input coverage incomplete and are
|
|
91
|
-
carried for as long as they are part of the pull request — an unreviewable
|
|
92
|
-
change must never authorize a green check; exclude them deliberately with
|
|
93
|
-
ignore globs when that is intended.
|
|
66
|
+
Model output is untrusted. The host revalidates anchors, enforces `maxFindings`, and publishes only
|
|
67
|
+
after the run settles. `PrReview.makeFanOut` partitions bounded evidence and schedules general and
|
|
68
|
+
specialist discovery for every unit, followed by independent candidate verification. Verifiers
|
|
69
|
+
receive the exact claims and enough neighboring evidence to reject a plausible mistake, but no
|
|
70
|
+
discovery reasoning.
|
|
71
|
+
|
|
72
|
+
Each failed pass retries once, then carries its unit forward. The host accepts only confirmed
|
|
73
|
+
candidate IDs, discards anchors outside assigned evidence, deduplicates claims in plan order, and
|
|
74
|
+
derives the verdict from validated severities. Shared `guidance` reaches discovery and verification.
|
|
75
|
+
|
|
76
|
+
When GitHub omits a textual patch, the source reads bounded, strict UTF-8 base/head content and
|
|
77
|
+
labels it with non-anchorable `B`/`H` lines. Invalid UTF-8, binary NUL content, missing sides, and
|
|
78
|
+
oversized files remain unreviewable and keep input coverage incomplete. Exclude them with ignore
|
|
79
|
+
globs only when that is intentional.
|
|
94
80
|
|
|
95
81
|
## Assurance model
|
|
96
82
|
|
|
@@ -117,51 +103,52 @@ favors redundant work, but it cannot recognize every semantically risky
|
|
|
117
103
|
change. The specialist pass is context-independent redundancy, not a claim of
|
|
118
104
|
provider or model diversity. Running it for every unit prevents classifier
|
|
119
105
|
silence from suppressing scrutiny; the category labels still cannot prove
|
|
120
|
-
that every semantic risk was recognized.
|
|
121
|
-
for compatibility; new hosts and UI use `inputCoverage` and `assurance`.
|
|
106
|
+
that every semantic risk was recognized. Hosts and UI use `inputCoverage` and `assurance`.
|
|
122
107
|
The flat reviewer has path-input accounting but no independent verifier, so
|
|
123
108
|
its assurance is `unverified` and the Action check cannot report success from
|
|
124
109
|
that shape.
|
|
125
110
|
|
|
111
|
+
## Maintainer adjudication
|
|
112
|
+
|
|
113
|
+
A maintainer can settle a finding without changing code, from the pull request itself:
|
|
114
|
+
|
|
115
|
+
- On a finding's inline thread, reply `/adjudicate accepted-risk|refuted|obsolete[: reason]`.
|
|
116
|
+
The thread names the target, so the verb alone suffices.
|
|
117
|
+
- For an unanchored concern, comment
|
|
118
|
+
`/adjudicate <disposition> "<exact concern title>"[: reason]` in the PR conversation. The quoted
|
|
119
|
+
title is required and must match exactly.
|
|
120
|
+
|
|
121
|
+
An adjudicated identity leaves active findings, verdict counts, and the check conclusion; it
|
|
122
|
+
renders in a collapsed "Adjudicated" section instead, and the final audit distinguishes fixed,
|
|
123
|
+
adjudicated, and still-open items. The reviewer prompt names each adjudication so the model does
|
|
124
|
+
not re-raise it without materially new evidence. Identity is exact — path, line range, and title
|
|
125
|
+
for findings, title alone for concerns — so a materially different finding at the same location is
|
|
126
|
+
untouched. Adjudications persist in the signed review state, and the skip-unchanged path re-reads
|
|
127
|
+
them, so an adjudication lifts a blocking check without a new commit.
|
|
128
|
+
|
|
129
|
+
**Authorization is fail-closed**: only comments whose `author_association` is OWNER, MEMBER, or
|
|
130
|
+
COLLABORATOR adjudicate. Anything else — third parties, bots, malformed commands — is ignored
|
|
131
|
+
(logged at debug). Later adjudications of the same identity win by comment creation order, bounded
|
|
132
|
+
at 20 stored entries (oldest dropped with a logged notice). If either GitHub listing surface fails,
|
|
133
|
+
or one thread exceeds the bounded authorized-command history, fresh collection is discarded and
|
|
134
|
+
the stored set stands unchanged.
|
|
135
|
+
|
|
136
|
+
**Rejected alternative — parsing free-text rebuttals** ("this is fine because …" replies): only an
|
|
137
|
+
explicit, authorized verb is auditable and fail-closed. Inferring intent from prose would let model
|
|
138
|
+
output or third-party comments silently suppress findings, and nobody could later say which comment
|
|
139
|
+
dismissed what.
|
|
140
|
+
|
|
126
141
|
## What a posted review looks like
|
|
127
142
|
|
|
128
|
-
The
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
never from model prose. Directly under it, one host-derived stats line names
|
|
132
|
-
the changeset size (`N files (+adds / −dels)`), the severity tally, and a
|
|
133
|
-
deterministic 1–5 review-effort estimate computed from the changeset shape
|
|
134
|
-
alone. Fan-out reviews add a second host-derived line naming input assignment,
|
|
135
|
-
discovery/specialist/verification settlement, and candidate dispositions.
|
|
136
|
-
Below the summary, a collapsed **📝 Walkthrough** table carries the
|
|
137
|
-
model's one-sentence per-file change summaries — walkthrough paths are
|
|
138
|
-
validated like finding anchors, so entries naming files outside the changeset
|
|
139
|
-
are dropped. Under fan-out only summaries a
|
|
140
|
-
successfully settled general pass actually reported for its own unit's paths
|
|
141
|
-
survive, so a child cannot smuggle or invent entries. Non-anchored `concerns`
|
|
142
|
-
(deletion plans, rollout sequencing,
|
|
143
|
-
coverage gaps, scope questions — things with no diff line to point at) render
|
|
144
|
-
as severity-tagged sections; demoted findings and findings carried from
|
|
145
|
-
unchanged scope collapse into counted `<details>` sections.
|
|
146
|
-
|
|
147
|
-
Each inline comment is headed by its severity plus an optional model-claimed
|
|
148
|
-
category chip (`**[⚠️ important · security] …**`), carries a committable
|
|
149
|
-
GitHub `suggestion` fence when independent verification settled the model's
|
|
150
|
-
suggestion as committable replacement source, and ends with a
|
|
151
|
-
collapsed **🤖 Prompt for AI agents** — a copy-paste instruction derived
|
|
152
|
-
host-side from the validated finding, opening with a fixed preamble telling
|
|
153
|
-
the receiving agent to treat the finding content as untrusted review data.
|
|
154
|
-
The review body repeats every finding — anchored, demoted, and carried — in
|
|
155
|
-
one consolidated prompt block so nothing needs to be collected by hand. The
|
|
156
|
-
footer names the model binding, the observed token usage, and links to the
|
|
157
|
-
workflow run; an invisible metadata comment pins the reviewed head commit so
|
|
158
|
-
later readers know when line callouts have gone stale.
|
|
143
|
+
The host derives callouts, statistics, walkthroughs, inline comments, and the final prompt from
|
|
144
|
+
validated findings. Model prose cannot choose the verdict or smuggle paths outside the changeset.
|
|
145
|
+
The [Action guide](../../action/README.md) documents the rendered review and workflow outputs.
|
|
159
146
|
|
|
160
147
|
## Swap a port
|
|
161
148
|
|
|
162
149
|
Tools observe the pull request only through `PullRequestSource`; publication
|
|
163
150
|
happens only through `ReviewPublisher`. Provide your own Layers to review
|
|
164
|
-
|
|
151
|
+
any diff-shaped input or publish elsewhere. The GitHub REST adapters are
|
|
165
152
|
one implementation, not the contract.
|
|
166
153
|
|
|
167
154
|
## Test what you adapted
|
|
@@ -176,124 +163,25 @@ import {
|
|
|
176
163
|
```
|
|
177
164
|
|
|
178
165
|
Deterministic in-memory adapters for both ports plus prompt-keyed scripted
|
|
179
|
-
models that
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
##
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
and
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
validates the state and reviews the GitHub comparison from that reviewed head
|
|
192
|
-
to the current head plus the carried unreviewed paths, not the complete
|
|
193
|
-
base...HEAD diff. Unchanged settled scope is not sent back to the model;
|
|
194
|
-
unchanged unresolved findings remain active; changed or reverted paths
|
|
195
|
-
invalidate their prior findings and receive fresh discovery and verification.
|
|
196
|
-
Whole overflow files are reviewed in bounded installments across pushes
|
|
197
|
-
through the same carry; a single file beyond total plan capacity and
|
|
198
|
-
undiffable paths stay explicitly incomplete instead — an unreviewable tail
|
|
199
|
-
never moves behind a green check. Non-anchored concerns are carried conservatively
|
|
200
|
-
until a full audit because they cannot be mapped safely to one path.
|
|
201
|
-
|
|
202
|
-
The state marker must be terminal, signed with the configured stable
|
|
203
|
-
`PR_REVIEW_STATE_SECRET`, authored by the configured review-posting bot, and
|
|
204
|
-
pinned to the reviewed commit. The expected author defaults to
|
|
205
|
-
`github-actions[bot]`; set `PR_REVIEW_AUTHOR_LOGIN` (or the Action's
|
|
206
|
-
`review-author` input) to `<app-slug>[bot]` when posting with a custom GitHub
|
|
207
|
-
App token. State lookup, authentication, schema, identity, ancestry, profile,
|
|
208
|
-
and comparison checks are fail-closed for scope selection: missing, stale,
|
|
209
|
-
incompatible, or truncated state/comparisons produce a visible full-diff
|
|
210
|
-
fallback. An ancestor base advance remains incremental and adds overlapping
|
|
211
|
-
PR paths as affected context; a materially changed base lineage falls back to
|
|
212
|
-
full unless the authenticated settled-scope fingerprint still matches. The
|
|
213
|
-
schema field retains the compatibility name `acceptedScopeFingerprint`. That
|
|
214
|
-
fingerprint hashes the ignore-filtered effective diff, patchless base/head
|
|
215
|
-
evidence, PR framing, and review-shaping profile while excluding commit IDs,
|
|
216
|
-
base ancestry, and unified-diff hunk coordinates. Re-running the same head or a
|
|
217
|
-
patch-equivalent rebase skips model execution by default ONLY when the stored
|
|
218
|
-
state fully settled — a state carrying unreviewed scope is always retried.
|
|
219
|
-
The preserved skip keeps its stored blocking/success conclusion and posts no
|
|
220
|
-
duplicate review comments. Missing/corrupt state and any fingerprint or
|
|
221
|
-
profile mismatch review conservatively.
|
|
222
|
-
|
|
223
|
-
After a new state-bearing Action review posts, prior marker-bearing bot reviews
|
|
224
|
-
are retired by default: their bodies become collapsed, superseded history,
|
|
225
|
-
resolved findings are struck through, and matching inline comments are
|
|
226
|
-
minimized as outdated. Only strictly older reviews from the same GitHub actor
|
|
227
|
-
are eligible, so copied markers and newer concurrent reviews are untouched.
|
|
228
|
-
The machine-state comments remain byte-identical and terminal, so an edited
|
|
229
|
-
body still participates in incremental state recovery.
|
|
230
|
-
This cosmetic pass is fail-open and can be disabled with the Action input
|
|
231
|
-
`retire-stale-reviews: "false"`.
|
|
232
|
-
|
|
233
|
-
Authentication is an explicit Effect service supplied by the Action host;
|
|
234
|
-
WebCrypto import/sign/verify failures stay typed. The terminal marker is
|
|
235
|
-
schema-branded and capped at 24,000 characters. If signing fails or state
|
|
236
|
-
exceeds that bound, the completed review is posted without continuity state
|
|
237
|
-
and with a bounded warning, so the next run safely performs a full review.
|
|
238
|
-
|
|
239
|
-
`review-mode: final` is the explicit bounded merge-readiness audit. It ignores
|
|
240
|
-
prior assurance state, plans fresh discovery over the full current PR
|
|
241
|
-
diff, verifies new candidates, and resets the incremental baseline; normal
|
|
242
|
-
`synchronize` events use `incremental` and do not perform this audit.
|
|
243
|
-
Because equivalence is based on the textual review surface, a base change that
|
|
244
|
-
alters runtime meaning without changing the diff/context is not detectable;
|
|
245
|
-
request `final` mode (or disable unchanged skipping) for that case.
|
|
246
|
-
|
|
247
|
-
## Hosts
|
|
248
|
-
|
|
249
|
-
- **GitHub Actions**: the repository ships a prebuilt node-runtime action
|
|
250
|
-
supporting a committed review-profile document via `guidance-file` (this
|
|
251
|
-
repository's own profile lives at `.github/review-guidance.md`)
|
|
252
|
-
(`action/` at the repo root) — `uses` it with an API-key secret and nothing
|
|
253
|
-
else. Fan-out is the Action default because the flat compatibility shape
|
|
254
|
-
has no independent verifier and cannot settle review assurance. While a run executes it maintains one sticky, fail-open "review in
|
|
255
|
-
progress" comment updated in place with the settled outcome
|
|
256
|
-
(`progress-comment` input, default on; at-least-once with generation-fenced
|
|
257
|
-
writes and best-effort duplicate cleanup — strict single-comment behavior
|
|
258
|
-
comes from a per-PR workflow concurrency group), and its logs render one
|
|
259
|
-
compact line per event (`log-level` input, default `Info`). For custom reviewers in
|
|
260
|
-
CI, `@effect-agent/pr-review/action` exports `runReviewAction` (event
|
|
261
|
-
resolution, typed draft/non-PR skips, bounded range selection, step
|
|
262
|
-
outputs, and conservative check gate) to harness your own `reviewer.run`;
|
|
263
|
-
pass `progressComment: true` to opt a custom harness into the sticky
|
|
264
|
-
progress comment. A custom fingerprint-only harness remains source-compatible
|
|
265
|
-
but cannot skip model work: unchanged skipping requires the profile fingerprint
|
|
266
|
-
and authenticated state that prove the prior configured work settled.
|
|
267
|
-
- **CLI**: `bun src/cli.ts --repo owner/name --pr 123 [--post] [--provider anthropic] [--fan-out]`
|
|
268
|
-
(also exported as the `./cli` entry).
|
|
269
|
-
|
|
270
|
-
Environment: `OPENAI_API_KEY` or `ANTHROPIC_API_KEY` for the model,
|
|
271
|
-
`PR_REVIEW_STATE_SECRET` to authenticate incremental state,
|
|
272
|
-
`PR_REVIEW_AUTHOR_LOGIN` to match a custom review-posting bot (defaults to
|
|
273
|
-
`github-actions[bot]`),
|
|
274
|
-
`GITHUB_TOKEN` to post (optional for public-repository reads), and the
|
|
275
|
-
standard `GITHUB_REPOSITORY` / `GITHUB_EVENT_PATH` / `GITHUB_API_URL`
|
|
276
|
-
variables inside Actions.
|
|
166
|
+
models that call the real Tools. Tests need no network or credentials and exercise every ordinary
|
|
167
|
+
gate.
|
|
168
|
+
|
|
169
|
+
## Action and CLI
|
|
170
|
+
|
|
171
|
+
The prebuilt GitHub Action handles signed incremental state, fail-closed scope selection, sticky
|
|
172
|
+
progress, stale-review retirement, and final audits. See its [setup and behavior guide](../../action/README.md)
|
|
173
|
+
and [input reference](../../action/action.yml). Custom hosts can import `runReviewAction` from
|
|
174
|
+
`@effect-agent/pr-review/action`.
|
|
175
|
+
|
|
176
|
+
Run the CLI with
|
|
177
|
+
`bun src/cli.ts --repo owner/name --pr 123 [--post] [--provider anthropic] [--fan-out]`.
|
|
277
178
|
|
|
278
179
|
## Bounds, spelled out
|
|
279
180
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
Fan-out capacity overflow is reported, never dropped. Every fan-out unit has
|
|
288
|
-
at most 12 files, 12 complete evidence shards, and 240,000 evidence characters;
|
|
289
|
-
one path may span multiple shards or units when necessary. If the eight-unit
|
|
290
|
-
plan capacity is exhausted, every affected path and the exact shard count are
|
|
291
|
-
reported, with a deterministic identifier sample bounded to one plan's capacity;
|
|
292
|
-
at most eight units produce at most 24 attached children (general and
|
|
293
|
-
specialist discovery plus one verification batch per unit), with child
|
|
294
|
-
concurrency capped at four. Any blocking active finding fails the Action
|
|
295
|
-
check. Any input gap—including an unassigned evidence shard—failed or
|
|
296
|
-
exhausted configured pass, mismatched candidate batch, or unsettled
|
|
297
|
-
verification is non-success rather than green. A settled
|
|
298
|
-
clean result is evidence that these bounded passes completed, not proof that
|
|
299
|
-
no defect exists.
|
|
181
|
+
Every definition has a finite `AgentPolicy` and run-level `UsageBudgetLimits`. The reviewer rejects
|
|
182
|
+
file versions beyond 200k bytes or characters and patchless B/H renderings beyond 220k characters.
|
|
183
|
+
It reads at most 300 changed files. Each fan-out unit holds at most 12 files, 12 complete evidence
|
|
184
|
+
shards, and 240,000 evidence characters. At most eight units produce 24 attached children with
|
|
185
|
+
child concurrency capped at four. The result reports every capacity overflow. Any blocking
|
|
186
|
+
finding, input gap, failed pass, exhausted pass, mismatched candidate batch, or unsettled
|
|
187
|
+
verification prevents a green check.
|
package/dist/action.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Br as ChangedFile, Cn as ReviewStateAuthenticator, Fr as PullRequestMetadata, Ir as PullRequestSource, L as PriorReviews, Lr as PullRequestSourceFailure, P as GitHubApiFailure, Q as ReviewRetirementHost, Qt as ReviewAdjudicationHost, gn as ReviewExecutionContext, vn as ReviewMode, z as ReviewPublisher } from "./fan-out-CMEsbFLk.mjs";
|
|
2
2
|
import { EffortPosition, InvalidEffortInput, ReviewProgressReporter, ReviewProvider, ReviewRunOutcome, ReviewTargetUnresolved, RunReviewOptions } from "./index.mjs";
|
|
3
3
|
import { Config, Effect, FileSystem, Schema } from "effect";
|
|
4
4
|
import { BudgetExceeded } from "effect-agent";
|
|
@@ -92,29 +92,38 @@ type ReviewActionResult = {
|
|
|
92
92
|
* The reviewer surface the action harness drives. `PrReview.make` and
|
|
93
93
|
* `PrReview.makeFanOut` provide the state-selection effects. A fingerprint is
|
|
94
94
|
* skip authority only when a profile fingerprint and authenticated review
|
|
95
|
-
* state bind it to settled assurance
|
|
96
|
-
* remains source-compatible but deliberately runs instead of claiming green
|
|
97
|
-
* assurance from unauthenticated prior-review text.
|
|
95
|
+
* state bind it to settled assurance.
|
|
98
96
|
*/
|
|
99
|
-
interface
|
|
100
|
-
|
|
97
|
+
interface HarnessedReviewerBase<E, R> {
|
|
98
|
+
/** The action composition root always supplies the selected run context. */
|
|
99
|
+
readonly run: (runOptions?: RunReviewOptions) => Effect.Effect<ReviewRunOutcome, E, R | ReviewExecutionContext>;
|
|
100
|
+
}
|
|
101
|
+
type HarnessedReviewer<E, R, FingerprintE, FingerprintR> = HarnessedReviewerBase<E, R> & ({
|
|
102
|
+
readonly fingerprint?: undefined;
|
|
103
|
+
readonly profileFingerprint?: undefined;
|
|
104
|
+
readonly snapshot?: undefined;
|
|
105
|
+
readonly filterFiles?: undefined;
|
|
106
|
+
} | {
|
|
101
107
|
/** Current effective changeset fingerprint; not standalone skip authority. */
|
|
102
|
-
readonly fingerprint
|
|
103
|
-
readonly profileFingerprint
|
|
104
|
-
readonly snapshot
|
|
108
|
+
readonly fingerprint: Effect.Effect<string, FingerprintE, FingerprintR>;
|
|
109
|
+
readonly profileFingerprint: Effect.Effect<string, FingerprintE, FingerprintR>;
|
|
110
|
+
readonly snapshot: Effect.Effect<{
|
|
105
111
|
readonly metadata: PullRequestMetadata;
|
|
106
112
|
readonly files: ReadonlyArray<ChangedFile>;
|
|
107
|
-
}, FingerprintE, FingerprintR
|
|
113
|
+
}, FingerprintE, FingerprintR>;
|
|
108
114
|
readonly filterFiles?: ((files: ReadonlyArray<ChangedFile>) => ReadonlyArray<ChangedFile>) | undefined;
|
|
109
|
-
}
|
|
115
|
+
});
|
|
110
116
|
/**
|
|
111
117
|
* Host-derived check conclusion; model verdict prose cannot weaken it.
|
|
112
118
|
*
|
|
113
119
|
* Blocking code findings outrank machinery gaps — they are the actionable
|
|
114
|
-
* signal. A machinery gap (
|
|
115
|
-
* `incomplete` with reasons that explicitly say the failure is
|
|
116
|
-
* uncertainty carried forward for retry, never an invitation to
|
|
117
|
-
*
|
|
120
|
+
* signal. A retryable machinery gap (failed passes, capacity overflow)
|
|
121
|
+
* concludes `incomplete` with reasons that explicitly say the failure is
|
|
122
|
+
* reviewer-side uncertainty carried forward for retry, never an invitation to
|
|
123
|
+
* change code. Undiffable files are the deliberate exception: no retry can
|
|
124
|
+
* settle them, so their reason instructs removal or ignore globs instead of
|
|
125
|
+
* promising an automatic retry. The flat reviewer's constant `unverified`
|
|
126
|
+
* assurance is not a gap.
|
|
118
127
|
*/
|
|
119
128
|
declare const concludeReviewOutcome: (outcome: ReviewRunOutcome) => {
|
|
120
129
|
readonly conclusion: ReviewCheckConclusion;
|
|
@@ -154,7 +163,7 @@ declare const runReviewAction: <E, R, FingerprintE = never, FingerprintR = never
|
|
|
154
163
|
} | {
|
|
155
164
|
_tag: "Completed";
|
|
156
165
|
outcome: ReviewRunOutcome;
|
|
157
|
-
}, E | FingerprintE | Config.ConfigError | import("effect/PlatformError").PlatformError | PullRequestSourceFailure | ReviewGateFailed | ReviewTargetUnresolved, FileSystem.FileSystem | import("effect/unstable/http/HttpClient").HttpClient | ReviewStateAuthenticator | Exclude<FingerprintR, PriorReviews | PullRequestSource | ReviewProgressReporter | ReviewPublisher | ReviewRetirementHost> | Exclude<R, PriorReviews | PullRequestSource | ReviewProgressReporter | ReviewPublisher | ReviewRetirementHost>>;
|
|
166
|
+
}, E | FingerprintE | Config.ConfigError | import("effect/PlatformError").PlatformError | PullRequestSourceFailure | ReviewGateFailed | ReviewTargetUnresolved, FileSystem.FileSystem | import("effect/unstable/http/HttpClient").HttpClient | ReviewStateAuthenticator | Exclude<FingerprintR, PriorReviews | PullRequestSource | ReviewAdjudicationHost | ReviewProgressReporter | ReviewPublisher | ReviewRetirementHost> | Exclude<Exclude<R, PullRequestSource | ReviewExecutionContext>, PriorReviews | PullRequestSource | ReviewAdjudicationHost | ReviewProgressReporter | ReviewPublisher | ReviewRetirementHost>>;
|
|
158
167
|
/**
|
|
159
168
|
* The packaged, environment-driven action program: inputs from PR_REVIEW_*,
|
|
160
169
|
* reviewer built from the packaged factory, provider client from the
|
|
@@ -166,7 +175,7 @@ declare const reviewActionProgram: Effect.Effect<{
|
|
|
166
175
|
} | {
|
|
167
176
|
_tag: "Completed";
|
|
168
177
|
outcome: ReviewRunOutcome;
|
|
169
|
-
}, import("effect-agent").AgentApprovalDenied | import("effect-agent").AgentApprovalPending | import("effect-agent").AgentChildPending | import("effect-agent").AgentInputError | import("effect-agent").AgentOutputError | import("effect-agent").AgentPolicyError | import("effect-agent").AgentToolAuthorizationDenied | import("effect/unstable/ai/AiError").AiError | import("effect-agent").BudgetAdapterError | BudgetExceeded | Config.ConfigError | import("effect-agent").ContextOverflowError | GitHubApiFailure | GuidanceFileUnreadable | InvalidEffortInput | InvalidMaxDurationInput | import("effect-agent").ModelProtocolError | import("effect/PlatformError").PlatformError | PullRequestSourceFailure | ReviewGateFailed | ReviewTargetUnresolved | Schema.SchemaError, FileSystem.FileSystem | import("effect/unstable/http/HttpClient").HttpClient>;
|
|
178
|
+
}, import("effect-agent").AgentApprovalDenied | import("effect-agent").AgentApprovalPending | import("effect-agent").AgentChildPending | import("effect-agent").AgentInputError | import("effect-agent").AgentOutputError | import("effect-agent").AgentPolicyError | import("effect-agent").AgentToolAuthorizationDenied | import("effect/unstable/ai/AiError").AiError | import("effect-agent").BudgetAdapterError | BudgetExceeded | Config.ConfigError | import("effect-agent").ContextOverflowError | GitHubApiFailure | GuidanceFileUnreadable | InvalidEffortInput | InvalidMaxDurationInput | import("effect-agent").ModelProtocolError | import("effect/PlatformError").PlatformError | PullRequestSourceFailure | ReviewGateFailed | ReviewTargetUnresolved | Schema.SchemaError, import("effect/Crypto").Crypto | FileSystem.FileSystem | import("effect/unstable/http/HttpClient").HttpClient>;
|
|
170
179
|
/** Run the packaged action program on Node; the bundled action entrypoint. */
|
|
171
180
|
declare const main: () => void;
|
|
172
181
|
/** The packaged GitHub Actions surface. */
|
|
@@ -195,7 +204,7 @@ declare const PrReviewAction: {
|
|
|
195
204
|
} | {
|
|
196
205
|
_tag: "Completed";
|
|
197
206
|
outcome: ReviewRunOutcome;
|
|
198
|
-
}, import("effect-agent").AgentApprovalDenied | import("effect-agent").AgentApprovalPending | import("effect-agent").AgentChildPending | import("effect-agent").AgentInputError | import("effect-agent").AgentOutputError | import("effect-agent").AgentPolicyError | import("effect-agent").AgentToolAuthorizationDenied | import("effect/unstable/ai/AiError").AiError | import("effect-agent").BudgetAdapterError | BudgetExceeded | Config.ConfigError | import("effect-agent").ContextOverflowError | GitHubApiFailure | GuidanceFileUnreadable | InvalidEffortInput | InvalidMaxDurationInput | import("effect-agent").ModelProtocolError | import("effect/PlatformError").PlatformError | PullRequestSourceFailure | ReviewGateFailed | ReviewTargetUnresolved | Schema.SchemaError, FileSystem.FileSystem | import("effect/unstable/http/HttpClient").HttpClient>;
|
|
207
|
+
}, import("effect-agent").AgentApprovalDenied | import("effect-agent").AgentApprovalPending | import("effect-agent").AgentChildPending | import("effect-agent").AgentInputError | import("effect-agent").AgentOutputError | import("effect-agent").AgentPolicyError | import("effect-agent").AgentToolAuthorizationDenied | import("effect/unstable/ai/AiError").AiError | import("effect-agent").BudgetAdapterError | BudgetExceeded | Config.ConfigError | import("effect-agent").ContextOverflowError | GitHubApiFailure | GuidanceFileUnreadable | InvalidEffortInput | InvalidMaxDurationInput | import("effect-agent").ModelProtocolError | import("effect/PlatformError").PlatformError | PullRequestSourceFailure | ReviewGateFailed | ReviewTargetUnresolved | Schema.SchemaError, import("effect/Crypto").Crypto | FileSystem.FileSystem | import("effect/unstable/http/HttpClient").HttpClient>;
|
|
199
208
|
readonly main: typeof main;
|
|
200
209
|
};
|
|
201
210
|
//#endregion
|