From 2a5d82b2500040c54862332f1132bbe49279bf33 Mon Sep 17 00:00:00 2001
From: JSONbored <49853598+JSONbored@users.noreply.github.com>
Date: Fri, 10 Jul 2026 15:20:32 -0700
Subject: [PATCH] chore(review): deprecate gateCheckMode as a computed
read-back value (#4618)
gateCheckMode was a legacy shadow of reviewCheckMode (the actual check-run
publish authority) kept alive only by dual-write sync code scattered across
the DB layer, both settings-write API schemas, and the yml gate-config
resolver. Reduce redundant config surface by making gateCheckMode a
derived, read-only field everywhere: dropped from every write schema
(maintainer dashboard PUT, internal full-replace POST), no longer an
accepted upsertRepositorySettings input, and always recomputed from
reviewCheckMode on read (DB row mapping, yml gate: block resolution, and
the settings.gateCheckMode legacy yml key, which still parses for
back-compat but now derives reviewCheckMode rather than the reverse).
Also fixes a related latent bug: the yml gate: block only re-derived
gateCheckMode when gate.enabled was set, so a manifest setting ONLY
gate.checkMode could leave the back-compat display field silently stale.
Updates the maintainer dashboard's "Review agent check" toggle to write
reviewCheckMode directly instead of the deprecated field, and refreshes
docs/README/CONTRIBUTING references accordingly.
---
CONTRIBUTING.md | 2 +-
README.md | 2 +-
.../site/app-panels/maintainer-settings.tsx | 19 +-
.../src/routes/docs.github-app.tsx | 17 +-
.../src/routes/docs.how-reviews-work.tsx | 5 +-
.../gittensory-engine/src/focus-manifest.ts | 5 +
src/api/routes.ts | 27 +-
src/db/repositories.ts | 22 +-
src/services/maintainer-activation.ts | 3 +-
src/signals/focus-manifest.ts | 11 +-
src/types.ts | 7 +-
test/integration/api.test.ts | 41 +-
test/unit/focus-manifest.test.ts | 35 ++
.../linked-issue-satisfaction-run.test.ts | 3 +
test/unit/maintainer-activation.test.ts | 1 -
test/unit/parity-wire.test.ts | 1 +
test/unit/queue.test.ts | 474 +++++++++---------
test/unit/repo-profile.test.ts | 2 +-
...ository-settings-review-check-mode.test.ts | 29 +-
test/unit/routes-ai-byok.test.ts | 8 +-
test/unit/safety.test.ts | 1 +
21 files changed, 373 insertions(+), 342 deletions(-)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 1b817c4de6..3c9a0eead0 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -279,7 +279,7 @@ Config as code (`.gittensory.yml`) — every repository setting is controllable
- **`settings:`** is a partial of the repository settings: any behaviour a maintainer can toggle in the
dashboard can be set here as code — `commentMode`, `publicAudienceMode`, `publicSurface`, `checkRunMode`,
- `gateCheckMode`, the gate-blocker modes, `autoLabelEnabled`, `gittensorLabel`, `requireLinkedIssue`,
+ `reviewCheckMode`, the gate-blocker modes, `autoLabelEnabled`, `gittensorLabel`, `requireLinkedIssue`,
`backfillEnabled`, etc.
- **`gate:`** is a friendly typed alias for the gate subset — `enabled` (on/off), `linkedIssue`,
`duplicates`, `readiness: { mode, minScore }` (each `off | advisory | block`).
diff --git a/README.md b/README.md
index 8351f581f8..a22e3eabf7 100644
--- a/README.md
+++ b/README.md
@@ -40,7 +40,7 @@ Gittensory CI and gittensory review score, gate, and comment on pull requests. T
**Check-run and comment surfaces, disambiguated** (a common point of confusion — these are three independent, separately-configured things, not layers of the same feature):
-- **`Gittensory Orb Review Agent`** (`gate.*` / `settings.gateCheckMode` / `settings.reviewCheckMode`, off by default) — the authoritative GitHub Check Run carrying the gate's pass/fail verdict. This is the one worth making a required status check.
+- **`Gittensory Orb Review Agent`** (`gate.*` / `settings.reviewCheckMode`, off by default) — the authoritative GitHub Check Run carrying the gate's pass/fail verdict. This is the one worth making a required status check.
- **`Gittensory Context`** (`settings.checkRunMode` / `settings.checkRunDetailLevel`, off by default) — a separate, purely advisory Check Run. At its default `checkRunDetailLevel: minimal` it publishes no findings at all; even at `standard`/`deep` it only re-renders content already shown elsewhere. Never make this one required.
- **Inline review comments** (`GITTENSORY_REVIEW_INLINE_COMMENTS` + `.gittensory.yml`'s `review.inline_comments`, off by both by default) — real, reply-able line-anchored PR review comment threads (CodeRabbit-style). This is the ONLY one of the three that posts an interactive per-line thread; the two check runs above never do. With `.gittensory.yml`'s `review.suggestions` also on, a precise line-anchored fix is additionally rendered as a one-click, committable GitHub suggested-change block. With `review.finding_categories` also on (off by default), each finding is additionally tagged with a category — security/correctness/performance/maintainability/tests/style — in both the inline comment label and the unified comment's "Finding categories" collapsible; a deterministic path/keyword fallback covers whatever the model omits.
diff --git a/apps/gittensory-ui/src/components/site/app-panels/maintainer-settings.tsx b/apps/gittensory-ui/src/components/site/app-panels/maintainer-settings.tsx
index 1fadbd9fed..0ec52cfa6f 100644
--- a/apps/gittensory-ui/src/components/site/app-panels/maintainer-settings.tsx
+++ b/apps/gittensory-ui/src/components/site/app-panels/maintainer-settings.tsx
@@ -21,7 +21,9 @@ type MaintainerSettings = {
publicSurface: "off" | "comment_and_label" | "comment_only" | "label_only";
checkRunMode: "off" | "enabled";
checkRunDetailLevel: "minimal" | "standard" | "deep";
- gateCheckMode: "off" | "enabled";
+ // #4618: gateCheckMode is deprecated (a computed read-back value only) -- reviewCheckMode is the real,
+ // writable authority for whether the review-agent check-run publishes.
+ reviewCheckMode: "required" | "visible" | "disabled";
gatePack: "gittensor" | "oss-anti-slop";
linkedIssueGateMode: GateMode;
duplicatePrGateMode: GateMode;
@@ -90,7 +92,7 @@ const EDITABLE_KEYS: Array = [
"publicSurface",
"checkRunMode",
"checkRunDetailLevel",
- "gateCheckMode",
+ "reviewCheckMode",
"gatePack",
"linkedIssueGateMode",
"duplicatePrGateMode",
@@ -138,12 +140,15 @@ type FieldDef = SelectFieldDef | ToggleFieldDef | NumberFieldDef;
const GATE_FIELDS: FieldDef[] = [
{
- key: "gateCheckMode",
+ key: "reviewCheckMode",
label: "Review agent check",
kind: "select",
+ // "visible" (publishes but never required in branch protection) is deliberately not offered here --
+ // this toggle keeps its historical off/enabled shape; set .gittensory.yml gate.checkMode: visible directly
+ // for that finer-grained mode.
options: [
- ["off", "off"],
- ["enabled", "enabled"],
+ ["disabled", "off"],
+ ["required", "enabled"],
],
},
{
@@ -373,8 +378,8 @@ export function MaintainerSettings({ reviewability }: { reviewability: Array<{ p
{settings ? (
-
- gate {settings.gateCheckMode}
+
+ gate {settings.reviewCheckMode === "disabled" ? "off" : "enabled"}
) : null}
diff --git a/apps/gittensory-ui/src/routes/docs.github-app.tsx b/apps/gittensory-ui/src/routes/docs.github-app.tsx
index 004ac0c161..76f4a43eef 100644
--- a/apps/gittensory-ui/src/routes/docs.github-app.tsx
+++ b/apps/gittensory-ui/src/routes/docs.github-app.tsx
@@ -166,13 +166,14 @@ GET /v1/installations/:id/repair`}
Gate modes
The deterministic gate is the heart of the gittensory review. Its master switch is{" "}
- gateCheckMode (off / enabled); each dimension then
- refines an already-enabled gate with a tri-state mode — off (not evaluated),{" "}
- advisory (surfaced, never blocks), or block (can become a hard{" "}
- Gittensory Orb Review Agent blocker). A configured blocker fails the gate
- for any author identically — confirmed-Gittensor-contributor status does not change{" "}
- who can be blocked; it's carried through only for on-chain scoring, a separate
- concern from the gate's own merge/close decision.
+ reviewCheckMode (required / visible /{" "}
+ disabled); each dimension then refines an already-enabled gate with a tri-state
+ mode — off (not evaluated), advisory (surfaced, never blocks), or{" "}
+ block (can become a hard Gittensory Orb Review Agent blocker).
+ A configured blocker fails the gate for any author identically —
+ confirmed-Gittensor-contributor status does not change who can be blocked; it's
+ carried through only for on-chain scoring, a separate concern from the gate's own
+ merge/close decision.
-
@@ -259,7 +260,7 @@ GET /v1/installations/:id/repair`}
lang="yaml"
code={`# Repository settings as code — any dashboard toggle:
settings:
- gateCheckMode: enabled # review-agent check on/off
+ reviewCheckMode: required # review-agent check on/off (required|visible|disabled)
checkRunMode: enabled # the advisory Context check on/off
commentMode: detected_contributors_only
publicSurface: comment_only
diff --git a/apps/gittensory-ui/src/routes/docs.how-reviews-work.tsx b/apps/gittensory-ui/src/routes/docs.how-reviews-work.tsx
index 70ee0a360a..962686d7df 100644
--- a/apps/gittensory-ui/src/routes/docs.how-reviews-work.tsx
+++ b/apps/gittensory-ui/src/routes/docs.how-reviews-work.tsx
@@ -63,8 +63,9 @@ function HowReviewsWork() {
1. The gate: advisory vs. block
The gate is deterministic — same inputs, same verdict, no model in the loop. Its master
- switch is gateCheckMode (off / enabled). Once
- enabled, each dimension is independently set to one of three modes:
+ switch is reviewCheckMode (required / visible /{" "}
+ disabled). Once enabled, each dimension is independently set to one of
+ three modes:
-
diff --git a/packages/gittensory-engine/src/focus-manifest.ts b/packages/gittensory-engine/src/focus-manifest.ts
index ab3f264e61..7dfc4bc9b8 100644
--- a/packages/gittensory-engine/src/focus-manifest.ts
+++ b/packages/gittensory-engine/src/focus-manifest.ts
@@ -1714,6 +1714,10 @@ function parseSettingsOverride(value: JsonValue | undefined, warnings: string[],
if (checkRunMode !== null) out.checkRunMode = checkRunMode;
const checkRunDetailLevel = normalizeOptionalEnum(r.checkRunDetailLevel, "settings.checkRunDetailLevel", ["minimal", "standard", "deep"] as const, warnings);
if (checkRunDetailLevel !== null) out.checkRunDetailLevel = checkRunDetailLevel;
+ // #4618: gateCheckMode is deprecated (a computed read-back value everywhere else) but this yml key still
+ // parses for back-compat with existing `.gittensory.yml` files. A manifest setting ONLY gateCheckMode
+ // (never the more expressive reviewCheckMode) must keep its historical effect on the actual publish
+ // authority -- derive reviewCheckMode from it below when reviewCheckMode itself is unset.
const gateCheckMode = normalizeOptionalEnum(r.gateCheckMode, "settings.gateCheckMode", ["off", "enabled"] as const, warnings);
if (gateCheckMode !== null) out.gateCheckMode = gateCheckMode;
const regateSweepOrderMode = normalizeOptionalEnum(r.regateSweepOrderMode, "settings.regateSweepOrderMode", ["staleness", "oldest-first"] as const, warnings);
@@ -1722,6 +1726,7 @@ function parseSettingsOverride(value: JsonValue | undefined, warnings: string[],
// resolveEffectiveSettings, and wins when both are set).
const reviewCheckMode = normalizeOptionalEnum(r.reviewCheckMode, "settings.reviewCheckMode", ["required", "visible", "disabled"] as const, warnings);
if (reviewCheckMode !== null) out.reviewCheckMode = reviewCheckMode;
+ else if (gateCheckMode !== null) out.reviewCheckMode = gateCheckMode === "enabled" ? "required" : "disabled";
const autoProjectMilestoneMatch = normalizeOptionalEnum(r.autoProjectMilestoneMatch, "settings.autoProjectMilestoneMatch", ["off", "suggest", "auto"] as const, warnings);
if (autoProjectMilestoneMatch !== null) out.autoProjectMilestoneMatch = autoProjectMilestoneMatch;
const autoProjectMilestoneMatchBackend = normalizeOptionalEnum(r.autoProjectMilestoneMatchBackend, "settings.autoProjectMilestoneMatchBackend", ["github", "linear"] as const, warnings);
diff --git a/src/api/routes.ts b/src/api/routes.ts
index 28afde4c4b..a076a56d62 100644
--- a/src/api/routes.ts
+++ b/src/api/routes.ts
@@ -668,15 +668,10 @@ const repositorySettingsSchema = z.object({
// public output is intentionally minimal by design (see formatCheckRunOutput's doc comment), so a caller of
// this full-replace route that omits this field must land on the same safe default as a never-configured row.
checkRunDetailLevel: z.enum(["minimal", "standard", "deep"]).default("minimal"),
- gateCheckMode: z.enum(["off", "enabled"]).default("off"),
regateSweepOrderMode: z.enum(["staleness", "oldest-first"]).default("staleness"),
- // #2852: deliberately NO `.default()` here (unlike every sibling field above) -- this is a non-partial,
- // full-replace schema (see upsertRepositorySettings call below, which passes every parsed field straight
- // through with no read-merge of the current row), so an eager default would mask a legacy caller that only
- // sends gateCheckMode: the value would already be "defined" (the default) by the time it reaches
- // upsertRepositorySettings, and its own `settings.reviewCheckMode ?? (gateCheckMode==="enabled" ? ...)`
- // fallback only fires on `undefined`. Leaving this genuinely optional lets that fallback do its job.
- reviewCheckMode: z.enum(["required", "visible", "disabled"]).optional(),
+ // #4618: gateCheckMode dropped from this write schema -- it is a computed read-back value only (see its
+ // doc comment on RepositorySettings). Set reviewCheckMode directly.
+ reviewCheckMode: z.enum(["required", "visible", "disabled"]).default("disabled"),
gatePack: z.enum(["gittensor", "oss-anti-slop"]).default("gittensor"),
linkedIssueGateMode: z.enum(["off", "advisory", "block"]).default("advisory"),
duplicatePrGateMode: z.enum(["off", "advisory", "block"]).default("block"),
@@ -726,7 +721,6 @@ const maintainerSettingsSchema = z
publicSurface: z.enum(["off", "comment_and_label", "comment_only", "label_only"]),
checkRunMode: z.enum(["off", "enabled"]),
checkRunDetailLevel: z.enum(["minimal", "standard", "deep"]),
- gateCheckMode: z.enum(["off", "enabled"]),
regateSweepOrderMode: z.enum(["staleness", "oldest-first"]),
reviewCheckMode: z.enum(["required", "visible", "disabled"]),
gatePack: z.enum(["gittensor", "oss-anti-slop"]),
@@ -2389,14 +2383,6 @@ export function createApp() {
const current = await getRepositorySettings(c.env, fullName);
const changes = Object.fromEntries(Object.entries(parsed.data).filter(([, value]) => value !== undefined)) as Partial;
if (changes.qualityGateMode !== undefined) changes.qualityGateMode = downgradeQualityGateMode(changes.qualityGateMode);
- // #2852: a legacy client (the maintainer dashboard's "Review agent check" toggle) only ever sends
- // gateCheckMode, never the newer reviewCheckMode -- which must keep its historical effect on the ACTUAL
- // publish authority. Derive it here, before merging onto `current` (which always has a DEFINED
- // reviewCheckMode already), because upsertRepositorySettings's own legacy-fallback only fires on
- // `undefined` and would never see this change as unset once merged with the current row.
- if (changes.gateCheckMode !== undefined && changes.reviewCheckMode === undefined) {
- changes.reviewCheckMode = changes.gateCheckMode === "enabled" ? "required" : "disabled";
- }
const updated = await upsertRepositorySettings(c.env, { ...current, ...changes, repoFullName: fullName });
await recordAuditEvent(c.env, {
eventType: "repo.settings_updated",
@@ -3898,13 +3884,8 @@ export function createApp() {
publicSignalLevel: parsed.data.publicSignalLevel,
checkRunMode: parsed.data.checkRunMode,
checkRunDetailLevel: parsed.data.checkRunDetailLevel,
- gateCheckMode: parsed.data.gateCheckMode,
regateSweepOrderMode: parsed.data.regateSweepOrderMode,
- // #2852: this route is a full-replace, non-partial schema (every sibling field has a `.default()`),
- // so a caller that only ever sends gateCheckMode must still get its historical effect on the actual
- // publish authority -- derive it explicitly here rather than relying on a passthrough `undefined`
- // (which `exactOptionalPropertyTypes` disallows assigning to RepositorySettings anyway).
- reviewCheckMode: parsed.data.reviewCheckMode ?? (parsed.data.gateCheckMode === "enabled" ? "required" : "disabled"),
+ reviewCheckMode: parsed.data.reviewCheckMode,
gatePack: parsed.data.gatePack,
linkedIssueGateMode: parsed.data.linkedIssueGateMode,
duplicatePrGateMode: parsed.data.duplicatePrGateMode,
diff --git a/src/db/repositories.ts b/src/db/repositories.ts
index a5310573aa..2dcf58f482 100644
--- a/src/db/repositories.ts
+++ b/src/db/repositories.ts
@@ -589,7 +589,10 @@ export async function getRepositorySettings(env: Env, fullName: string): Promise
publicSignalLevel: row.publicSignalLevel === "minimal" ? "minimal" : "standard",
checkRunMode: parseCheckRunMode(row.checkRunMode),
checkRunDetailLevel: parseCheckRunDetailLevel(row.checkRunDetailLevel),
- gateCheckMode: parseGateCheckMode(row.gateCheckMode),
+ // #4618: gateCheckMode is a computed read-back value, never its own stored source of truth -- derive it
+ // from the real authority (reviewCheckMode) on every read instead of trusting the DB column, so a row
+ // whose gate_check_mode column has drifted (e.g. pre-#4618 data) self-heals on the very next read.
+ gateCheckMode: parseReviewCheckMode(row.reviewCheckMode) === "disabled" ? "off" : "enabled",
regateSweepOrderMode: parseRegateSweepOrderMode(row.regateSweepOrderMode),
reviewCheckMode: parseReviewCheckMode(row.reviewCheckMode),
autoProjectMilestoneMatch: parseProjectMilestoneMatchMode(row.projectMilestoneMatchMode),
@@ -706,16 +709,11 @@ export async function upsertRepositorySettings(env: Env, settings: Partial {
return {
- gateCheckMode: "enabled",
reviewCheckMode: "required",
checkRunMode: "enabled",
linkedIssueGateMode: "advisory",
diff --git a/src/signals/focus-manifest.ts b/src/signals/focus-manifest.ts
index ad91b57f7c..30b6e94685 100644
--- a/src/signals/focus-manifest.ts
+++ b/src/signals/focus-manifest.ts
@@ -440,14 +440,17 @@ export function filterReviewFilesForAi(
* repo with no `gate:` block resolves byte-identically to before this was split out.
*/
function applyGateConfigOverrides(effective: RepositorySettings, gate: FocusManifestGateConfig): void {
- if (gate.enabled !== null) effective.gateCheckMode = gate.enabled ? "enabled" : "off";
// reviewCheckMode (#2852) resolution: explicit `gate.checkMode` is the most-specific signal and always wins
// when set. Otherwise fall back to the legacy `gate.enabled` boolean alias, mapped symmetrically so it keeps
- // its historical effect (true -> the check publishes and may be required; false -> it never publishes) even
- // though it no longer drives `gateCheckMode` alone. When NEITHER is set, `effective.reviewCheckMode` already
- // holds `settings.reviewCheckMode` (yml `settings:` override, else the DB value) from the caller's spread.
+ // its historical effect (true -> the check publishes and may be required; false -> it never publishes). When
+ // NEITHER is set, `effective.reviewCheckMode` already holds `settings.reviewCheckMode` (yml `settings:`
+ // override, else the DB value) from the caller's spread.
if (gate.checkMode !== null) effective.reviewCheckMode = gate.checkMode;
else if (gate.enabled !== null) effective.reviewCheckMode = gate.enabled ? "required" : "disabled";
+ // #4618: gateCheckMode is a computed read-back value only -- always re-derive it from the reviewCheckMode
+ // just resolved above (not from gate.enabled alone), so it stays correct even when only gate.checkMode was
+ // the field actually set in the manifest.
+ effective.gateCheckMode = effective.reviewCheckMode === "disabled" ? "off" : "enabled";
if (gate.pack !== null) effective.gatePack = gate.pack;
if (gate.linkedIssue !== null) effective.linkedIssueGateMode = gate.linkedIssue;
if (gate.duplicates !== null) effective.duplicatePrGateMode = gate.duplicates;
diff --git a/src/types.ts b/src/types.ts
index 215caa9d05..f1cf7a05d6 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -705,6 +705,10 @@ export type RepositorySettings = {
publicSignalLevel: "minimal" | "standard";
checkRunMode: "off" | "enabled";
checkRunDetailLevel: "minimal" | "standard" | "deep";
+ /** Legacy shadow of {@link reviewCheckMode} (#2852), deprecated (#4618): a computed read-back value only,
+ * for API/dashboard back-compat display. `"enabled"` when `reviewCheckMode !== "disabled"`, else `"off"`
+ * -- see getRepositorySettings/upsertRepositorySettings in db/repositories.ts. No write path accepts this
+ * field anymore; set {@link reviewCheckMode} directly instead. */
gateCheckMode: "off" | "enabled";
/** Scheduled re-gate sweep candidate ordering (#3815). `staleness` (default) picks whichever open PR the
* sweep has gone longest WITHOUT re-gating (see selectRegateCandidates), which is what gives the sweep its
@@ -715,8 +719,7 @@ export type RepositorySettings = {
* any time regardless of the chosen order. */
regateSweepOrderMode: "staleness" | "oldest-first";
/** The actual runtime authority for whether the "Gittensory Orb Review Agent" check-run publishes (#2852).
- * See {@link ReviewCheckMode}. `gateCheckMode` above stays wired for API/back-compat display but no longer
- * drives the publish decision on its own. */
+ * See {@link ReviewCheckMode}. */
reviewCheckMode: ReviewCheckMode;
/** Auto-project/milestone matching (#3183). See {@link ProjectMilestoneMatchMode}. Always populated by the DB
* layer (default `"off"`); optional so existing settings fixtures/callers need not be touched. */
diff --git a/test/integration/api.test.ts b/test/integration/api.test.ts
index 181af6e6dd..7433921b96 100644
--- a/test/integration/api.test.ts
+++ b/test/integration/api.test.ts
@@ -412,10 +412,11 @@ describe("api routes", () => {
await expect(response.json()).resolves.toMatchObject({ repoFullName: "acme/readiness-block", qualityGateMode: "advisory" });
});
- it("derives reviewCheckMode from a legacy gateCheckMode-only body through the internal settings write endpoint (#2852)", async () => {
- // The internal full-replace route is a non-partial schema (every field defaults independently) -- a
- // caller that only ever knows about gateCheckMode must still get its historical effect on reviewCheckMode,
- // the actual check-run publish authority, not silently leave it at the schema's own "disabled" default.
+ it("ignores a gateCheckMode-only body through the internal settings write endpoint -- it is not a write field (#4618)", async () => {
+ // gateCheckMode is deprecated (#4618): a computed read-back value only, derived from reviewCheckMode.
+ // The internal full-replace route's schema no longer accepts it as input, so a caller sending ONLY
+ // gateCheckMode gets the schema's plain reviewCheckMode default ("disabled"), not the old legacy-write
+ // derivation. gateCheckMode in the response reflects that default, not the caller's (ignored) input.
const app = createApp();
const env = createTestEnv();
const enabled = await app.request(
@@ -424,24 +425,16 @@ describe("api routes", () => {
env,
);
expect(enabled.status).toBe(200);
- await expect(enabled.json()).resolves.toMatchObject({ gateCheckMode: "enabled", reviewCheckMode: "required" });
+ await expect(enabled.json()).resolves.toMatchObject({ gateCheckMode: "off", reviewCheckMode: "disabled" });
- const disabled = await app.request(
- "/v1/internal/repos/acme/legacy-gate-disable/settings",
- { method: "POST", headers: { authorization: `Bearer ${env.INTERNAL_JOB_TOKEN}`, "content-type": "application/json" }, body: JSON.stringify({ gateCheckMode: "off" }) },
- env,
- );
- expect(disabled.status).toBe(200);
- await expect(disabled.json()).resolves.toMatchObject({ gateCheckMode: "off", reviewCheckMode: "disabled" });
-
- // An explicit reviewCheckMode still wins over the gateCheckMode-derived value in the same request.
+ // reviewCheckMode set directly is the real, honored write path.
const explicit = await app.request(
"/v1/internal/repos/acme/legacy-gate-explicit/settings",
{ method: "POST", headers: { authorization: `Bearer ${env.INTERNAL_JOB_TOKEN}`, "content-type": "application/json" }, body: JSON.stringify({ gateCheckMode: "off", reviewCheckMode: "visible" }) },
env,
);
expect(explicit.status).toBe(200);
- await expect(explicit.json()).resolves.toMatchObject({ gateCheckMode: "off", reviewCheckMode: "visible" });
+ await expect(explicit.json()).resolves.toMatchObject({ gateCheckMode: "enabled", reviewCheckMode: "visible" });
});
it("rejects invalid public GitHub repo stats paths before calling GitHub", async () => {
@@ -2527,16 +2520,15 @@ describe("api routes", () => {
// #2267: qualityGateMode: "block" is downgraded to "advisory" on write — readiness/quality can never
// hard-block a PR, so the dashboard/API save path can't persist a value implying enforcement it doesn't
// have. slopGateMode: "block" is a DIFFERENT, legitimately-blockable dimension and is left untouched.
- body: JSON.stringify({ gateCheckMode: "enabled", slopGateMode: "block", slopGateMinScore: 55, qualityGateMode: "block", mergeTrainMode: "enforce", autonomy: { merge: "auto_with_approval", deploy: "auto" }, autoMaintain: { requireApprovals: 2, mergeMethod: "rebase" }, agentPaused: true, agentDryRun: true }),
+ // #4618: gateCheckMode is a legacy key with no effect here (dropped from the write schema) -- included
+ // to confirm it is silently ignored, not to drive reviewCheckMode.
+ body: JSON.stringify({ gateCheckMode: "enabled", reviewCheckMode: "required", slopGateMode: "block", slopGateMinScore: 55, qualityGateMode: "block", mergeTrainMode: "enforce", autonomy: { merge: "auto_with_approval", deploy: "auto" }, autoMaintain: { requireApprovals: 2, mergeMethod: "rebase" }, agentPaused: true, agentDryRun: true }),
},
ownerEnv,
);
expect(settingsUpdate.status).toBe(200);
await expect(settingsUpdate.json()).resolves.toMatchObject({
- gateCheckMode: "enabled",
- // #2852: a legacy client sending ONLY gateCheckMode (never reviewCheckMode, matching the current
- // untouched dashboard) must still get the check-run actually publishing -- reviewCheckMode is derived
- // from this same request's gateCheckMode, not silently left at its "disabled" default.
+ gateCheckMode: "enabled", // #4618: derived read-back from reviewCheckMode below, not the request's own gateCheckMode key
reviewCheckMode: "required",
slopGateMode: "block",
slopGateMinScore: 55,
@@ -2547,16 +2539,15 @@ describe("api routes", () => {
agentPaused: true, // #776 kill-switch
agentDryRun: true,
});
- // #2852: the other direction of the same legacy-write derivation — gateCheckMode: "off" alone (still no
- // reviewCheckMode sent) must derive reviewCheckMode: "disabled", not silently leave it at whatever the
- // prior save left it (still "required" from the write immediately above).
+ // #4618: gateCheckMode alone has NO effect -- it is dropped from the write schema, so reviewCheckMode
+ // stays whatever it already was (still "required" from the write immediately above), not derived "disabled".
const settingsUpdateOff = await app.request(
"/v1/repos/repo-owner/owned-repo/settings",
{ method: "PUT", headers: ownerHeaders, body: JSON.stringify({ gateCheckMode: "off" }) },
ownerEnv,
);
expect(settingsUpdateOff.status).toBe(200);
- await expect(settingsUpdateOff.json()).resolves.toMatchObject({ gateCheckMode: "off", reviewCheckMode: "disabled" });
+ await expect(settingsUpdateOff.json()).resolves.toMatchObject({ gateCheckMode: "enabled", reviewCheckMode: "required" });
// requireApprovals is bounded at the API boundary — an out-of-range value is rejected, not silently clamped.
const settingsBadApprovals = await app.request(
"/v1/repos/repo-owner/owned-repo/settings",
@@ -2566,7 +2557,7 @@ describe("api routes", () => {
expect(settingsBadApprovals.status).toBe(400);
const settingsInvalid = await app.request(
"/v1/repos/repo-owner/owned-repo/settings",
- { method: "PUT", headers: ownerHeaders, body: JSON.stringify({ gateCheckMode: "nonsense" }) },
+ { method: "PUT", headers: ownerHeaders, body: JSON.stringify({ reviewCheckMode: "nonsense" }) },
ownerEnv,
);
expect(settingsInvalid.status).toBe(400);
diff --git a/test/unit/focus-manifest.test.ts b/test/unit/focus-manifest.test.ts
index eb5d0bba5b..daef0de5ce 100644
--- a/test/unit/focus-manifest.test.ts
+++ b/test/unit/focus-manifest.test.ts
@@ -1957,6 +1957,9 @@ describe("parseFocusManifest settings override + resolveEffectiveSettings", () =
checkRunMode: "enabled",
checkRunDetailLevel: "deep",
gateCheckMode: "enabled",
+ // #4618: gateCheckMode is deprecated -- setting it alone (no explicit reviewCheckMode) still derives
+ // reviewCheckMode, so its historical effect on the actual publish authority is preserved.
+ reviewCheckMode: "required",
linkedIssueGateMode: "block",
duplicatePrGateMode: "off",
qualityGateMode: "advisory",
@@ -2451,6 +2454,38 @@ describe("parseFocusManifest settings override + resolveEffectiveSettings", () =
const eff = resolveEffectiveSettings({ reviewCheckMode: "visible" } as unknown as RepositorySettings, parseFocusManifest({ gate: { duplicates: "block" } }));
expect(eff.reviewCheckMode).toBe("visible");
});
+
+ // #4618: gateCheckMode is deprecated -- a computed read-back value only. It is no longer independently
+ // settable via any DB/API write path, but the yml settings.gateCheckMode key still parses (back-compat)
+ // and effective.gateCheckMode is always re-derived from the resolved reviewCheckMode, never trusted as
+ // its own source of truth.
+ describe("gateCheckMode deprecation (#4618)", () => {
+ it("settings.gateCheckMode alone (no reviewCheckMode) derives reviewCheckMode, keeping its historical effect", () => {
+ const enabled = parseFocusManifest({ settings: { gateCheckMode: "enabled" } });
+ expect(enabled.settings.reviewCheckMode).toBe("required");
+ const off = parseFocusManifest({ settings: { gateCheckMode: "off" } });
+ expect(off.settings.reviewCheckMode).toBe("disabled");
+ });
+
+ it("an explicit settings.reviewCheckMode wins over settings.gateCheckMode when both are set", () => {
+ const m = parseFocusManifest({ settings: { gateCheckMode: "off", reviewCheckMode: "visible" } });
+ expect(m.settings.reviewCheckMode).toBe("visible");
+ });
+
+ it("resolveEffectiveSettings re-derives gateCheckMode from gate.checkMode alone, not just gate.enabled (regression)", () => {
+ // Before #4618, gateCheckMode was only mutated in the gate.enabled branch, so a manifest setting ONLY
+ // gate.checkMode left effective.gateCheckMode stale (still the DB's, potentially "off" while the check
+ // actually publishes) -- a latent lie in the back-compat display field.
+ const eff = resolveEffectiveSettings({ reviewCheckMode: "disabled", gateCheckMode: "off" } as unknown as RepositorySettings, parseFocusManifest({ gate: { checkMode: "visible" } }));
+ expect(eff.reviewCheckMode).toBe("visible");
+ expect(eff.gateCheckMode).toBe("enabled");
+ });
+
+ it("resolveEffectiveSettings re-derives gateCheckMode to off when reviewCheckMode resolves to disabled", () => {
+ const eff = resolveEffectiveSettings({ reviewCheckMode: "required", gateCheckMode: "enabled" } as unknown as RepositorySettings, parseFocusManifest({ gate: { checkMode: "disabled" } }));
+ expect(eff.gateCheckMode).toBe("off");
+ });
+ });
});
describe("autoProjectMilestoneMatch precedence (#3183)", () => {
diff --git a/test/unit/linked-issue-satisfaction-run.test.ts b/test/unit/linked-issue-satisfaction-run.test.ts
index ce364d316b..b0d51847a9 100644
--- a/test/unit/linked-issue-satisfaction-run.test.ts
+++ b/test/unit/linked-issue-satisfaction-run.test.ts
@@ -767,6 +767,7 @@ describe("linked-issue satisfaction wired end-to-end through the real webhook pi
autoLabelEnabled: false,
checkRunMode: "off",
gateCheckMode: "enabled",
+ reviewCheckMode: "required",
gatePack: "oss-anti-slop",
linkedIssueGateMode: "off",
// The gate under test: off by default, opted into "block" here so an above-floor "unaddressed" verdict
@@ -858,6 +859,7 @@ describe("linked-issue satisfaction wired end-to-end through the real webhook pi
autoLabelEnabled: false,
checkRunMode: "off",
gateCheckMode: "enabled",
+ reviewCheckMode: "required",
gatePack: "oss-anti-slop",
linkedIssueGateMode: "off",
// No override -- linkedIssueSatisfactionGateMode is omitted, so upsertRepositorySettings persists its
@@ -924,6 +926,7 @@ describe("linked-issue satisfaction wired end-to-end through the real webhook pi
autoLabelEnabled: false,
checkRunMode: "off",
gateCheckMode: "enabled",
+ reviewCheckMode: "required",
linkedIssueGateMode: "off",
linkedIssueSatisfactionGateMode: "advisory",
});
diff --git a/test/unit/maintainer-activation.test.ts b/test/unit/maintainer-activation.test.ts
index 072b5e8bf0..0100dca0f9 100644
--- a/test/unit/maintainer-activation.test.ts
+++ b/test/unit/maintainer-activation.test.ts
@@ -239,7 +239,6 @@ describe("buildMaintainerActivationPreview", () => {
describe("recommendedAdvisoryActivationSettings", () => {
it("enables the gate + deterministic rules in advisory (non-blocking) mode", () => {
expect(recommendedAdvisoryActivationSettings()).toEqual({
- gateCheckMode: "enabled",
reviewCheckMode: "required",
checkRunMode: "enabled",
linkedIssueGateMode: "advisory",
diff --git a/test/unit/parity-wire.test.ts b/test/unit/parity-wire.test.ts
index a02304abf9..2750dd44f1 100644
--- a/test/unit/parity-wire.test.ts
+++ b/test/unit/parity-wire.test.ts
@@ -361,6 +361,7 @@ async function seedGateEnabledRepo(env: Env): Promise {
autoLabelEnabled: false,
checkRunMode: "off",
gateCheckMode: "enabled",
+ reviewCheckMode: "required",
linkedIssueGateMode: "block",
requireLinkedIssue: true,
});
diff --git a/test/unit/queue.test.ts b/test/unit/queue.test.ts
index d8e0087de1..f5654cae01 100644
--- a/test/unit/queue.test.ts
+++ b/test/unit/queue.test.ts
@@ -978,7 +978,7 @@ describe("queue processors", () => {
autonomy: { merge: "auto" },
aiReviewMode: "advisory",
gatePack: "oss-anti-slop",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
checkRunMode: "off",
commentMode: "off",
publicSurface: "off",
@@ -1026,7 +1026,7 @@ describe("queue processors", () => {
autonomy: { merge: "auto" },
aiReviewMode: "block",
gatePack: "oss-anti-slop",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
checkRunMode: "off",
commentMode: "off",
publicSurface: "off",
@@ -1070,7 +1070,7 @@ describe("queue processors", () => {
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem() });
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: {}, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
// STORED head is the stale a7; GitHub's LIVE head is b8 (a push the lost synchronize never delivered).
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 7, title: "Drifted PR", state: "open", user: { login: "contributor" }, head: { sha: "a7" }, labels: [], body: "Closes #1" });
let liveFilesFetched = false;
@@ -1100,7 +1100,7 @@ describe("queue processors", () => {
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem() });
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: {}, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 7, title: "Current PR", state: "open", user: { login: "contributor" }, head: { sha: "a7" }, labels: [], body: "Closes #1" });
const resyncUpsertSpy = vi.spyOn(repositoriesModule, "upsertPullRequestFromGitHub");
vi.stubGlobal("fetch", async (input: RequestInfo | URL) => {
@@ -1130,7 +1130,7 @@ describe("queue processors", () => {
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem() });
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: {}, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
// STORED row still reads open — the `closed` webhook was dropped (relay down); GitHub's LIVE state is closed.
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 7, title: "Closed PR", state: "open", user: { login: "contributor" }, head: { sha: "a7" }, labels: [], body: "Closes #1" });
let filesFetched = false;
@@ -1159,7 +1159,7 @@ describe("queue processors", () => {
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem() });
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: {}, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
vi.setSystemTime(new Date("2026-05-28T02:00:00.000Z"));
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 7, title: "Open PR", state: "open", user: { login: "contributor" }, head: { sha: "a7" }, labels: [], body: "Closes #1" });
let webhookReplayApplied = false;
@@ -1190,7 +1190,7 @@ describe("queue processors", () => {
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem() });
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: { pull_requests: "write" }, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto", update_branch: "auto" }, autoMaintain: { requireApprovals: 0, mergeMethod: "squash" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto", update_branch: "auto" }, autoMaintain: { requireApprovals: 0, mergeMethod: "squash" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 7, title: "Clean PR", state: "open", user: { login: "contributor" }, head: { sha: "a7" }, base: { ref: "main" }, labels: [], body: "Closes #1" });
// Seed an UP-TO-DATE reviews-cache marker so this dedup-focused call-count test stays isolated from the
// reviews-staleness self-heal (#2537 follow-up) — that behavior has its own dedicated coverage below.
@@ -1270,7 +1270,7 @@ describe("queue processors", () => {
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem() });
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: { pull_requests: "write" }, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto", update_branch: "auto" }, autoMaintain: { requireApprovals: 0, mergeMethod: "squash" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto", update_branch: "auto" }, autoMaintain: { requireApprovals: 0, mergeMethod: "squash" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 7, title: "Clean PR", state: "open", user: { login: "contributor" }, head: { sha: "a7" }, base: { ref: "main" }, labels: [], body: "Closes #1" });
// A sync that predates an invalidation (STALE) and no other refresh trigger in play (slop evidence off,
// manifest gate off, no pre-merge check paths configured) — proves the sweep's own visit, not some unrelated
@@ -1316,7 +1316,7 @@ describe("queue processors", () => {
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem() });
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: { pull_requests: "write" }, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto", update_branch: "auto" }, autoMaintain: { requireApprovals: 0, mergeMethod: "squash" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto", update_branch: "auto" }, autoMaintain: { requireApprovals: 0, mergeMethod: "squash" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 8, title: "Clean PR", state: "open", user: { login: "contributor" }, head: { sha: "a8" }, base: { ref: "main" }, labels: [], body: "Closes #1" });
// No reviewsInvalidatedAt at all -- the marker comparison alone would read this as permanently up to date.
await upsertPullRequestDetailSyncState(env, {
@@ -1356,7 +1356,7 @@ describe("queue processors", () => {
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem() });
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: { pull_requests: "write" }, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto", update_branch: "auto" }, autoMaintain: { requireApprovals: 0, mergeMethod: "squash" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto", update_branch: "auto" }, autoMaintain: { requireApprovals: 0, mergeMethod: "squash" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 7, title: "Clean PR", state: "open", user: { login: "contributor" }, head: { sha: "a7" }, base: { ref: "main" }, labels: [], body: "Closes #1" });
await upsertPullRequestDetailSyncState(env, { repoFullName: "owner/agent-repo", pullNumber: 7, status: "complete", reviewsSyncedAt: new Date().toISOString() });
// mockRejectedValue (not -Once): an earlier getPullRequestDetailSyncState read inside the resync/readiness
@@ -1395,7 +1395,7 @@ describe("queue processors", () => {
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem(), GITHUB_PUBLIC_TOKEN: "public-token" });
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: { pull_requests: "write", checks: "write" }, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto", approve: "auto", update_branch: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto", approve: "auto", update_branch: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 7, title: "Clean PR", state: "open", user: { login: "contributor" }, head: { sha: "a7" }, base: { ref: "main" }, labels: [], body: "Closes #1" });
let gateFinalized = false;
let failedMaintenanceMint = false;
@@ -1449,7 +1449,7 @@ describe("queue processors", () => {
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem() });
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: { pull_requests: "write", checks: "write" }, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto", update_branch: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto", update_branch: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 7, title: "Pending CI", state: "open", user: { login: "contributor" }, head: { sha: "a7" }, base: { ref: "main" }, labels: [], body: "Closes #1" });
const requiredContextsSpy = vi
.spyOn(backfillModule, "fetchRequiredStatusContexts")
@@ -1494,7 +1494,7 @@ describe("queue processors", () => {
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem() });
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: { pull_requests: "write", checks: "write" }, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto", update_branch: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto", update_branch: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 7, title: "Still running CI", state: "open", user: { login: "contributor" }, head: { sha: "a7" }, base: { ref: "main" }, labels: [], body: "Closes #1" });
vi.setSystemTime(new Date("2026-05-28T02:00:00.000Z"));
await env.SELFHOST_TRANSIENT_CACHE?.set(
@@ -1542,7 +1542,7 @@ describe("queue processors", () => {
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem() });
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: { pull_requests: "write", checks: "write" }, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto", update_branch: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto", update_branch: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 7, title: "Missing aggregate CI", state: "open", user: { login: "contributor" }, head: { sha: "a7" }, base: { ref: "main" }, labels: [], body: "Closes #1" });
const requiredContextsSpy = vi.spyOn(backfillModule, "fetchRequiredStatusContexts").mockResolvedValue(null);
const liveCiSpy = vi.spyOn(backfillModule, "fetchLiveCiAggregatePreferGraphQl").mockResolvedValue({
@@ -1586,7 +1586,7 @@ describe("queue processors", () => {
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem() });
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: { pull_requests: "write", checks: "write" }, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto", update_branch: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto", update_branch: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 7, title: "Stale optional CI", state: "open", user: { login: "contributor" }, head: { sha: "a7" }, base: { ref: "main" }, labels: [], body: "Closes #1" });
vi.setSystemTime(new Date("2026-05-28T02:00:00.000Z"));
await env.SELFHOST_TRANSIENT_CACHE?.set(
@@ -1645,7 +1645,7 @@ describe("queue processors", () => {
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem() });
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: { pull_requests: "write", checks: "write" }, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto", update_branch: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto", update_branch: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 7, title: "Permanently stuck CI", state: "open", user: { login: "contributor" }, head: { sha: "a7" }, base: { ref: "main" }, labels: [], body: "Closes #1" });
vi.setSystemTime(new Date("2026-05-28T02:00:00.000Z"));
await env.SELFHOST_TRANSIENT_CACHE?.set(
@@ -1721,7 +1721,7 @@ describe("queue processors", () => {
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem() });
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: { pull_requests: "write", checks: "write" }, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto", update_branch: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto", update_branch: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 8, title: "Permanently stuck CI, audit write fails", state: "open", user: { login: "contributor" }, head: { sha: "b8" }, base: { ref: "main" }, labels: [], body: "Closes #1" });
vi.setSystemTime(new Date("2026-05-28T02:00:00.000Z"));
await env.SELFHOST_TRANSIENT_CACHE?.set(
@@ -1775,7 +1775,7 @@ describe("queue processors", () => {
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem() });
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: { pull_requests: "write", checks: "write" }, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto", update_branch: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto", update_branch: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 9, title: "Permanently stuck CI, repeat defer audit write fails", state: "open", user: { login: "contributor" }, head: { sha: "c9" }, base: { ref: "main" }, labels: [], body: "Closes #1" });
vi.setSystemTime(new Date("2026-05-28T02:00:00.000Z"));
await env.SELFHOST_TRANSIENT_CACHE?.set(
@@ -1837,7 +1837,7 @@ describe("queue processors", () => {
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem() });
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: { pull_requests: "write", checks: "write" }, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto", update_branch: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto", update_branch: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 7, title: "Stale missing aggregate CI", state: "open", user: { login: "contributor" }, head: { sha: "a7" }, base: { ref: "main" }, labels: [], body: "Closes #1" });
vi.setSystemTime(new Date("2026-05-28T02:00:00.000Z"));
await env.SELFHOST_TRANSIENT_CACHE?.set(
@@ -1888,7 +1888,7 @@ describe("queue processors", () => {
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem() });
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: { pull_requests: "write", checks: "write" }, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto", update_branch: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto", update_branch: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 7, title: "Missing required context, within cap", state: "open", user: { login: "contributor" }, head: { sha: "a7" }, base: { ref: "main" }, labels: [], body: "Closes #1" });
vi.setSystemTime(new Date("2026-05-28T02:00:00.000Z"));
// 1 minute elapsed: under the new 2-minute missing-required-context cap AND under the old 30-minute cap —
@@ -1944,7 +1944,7 @@ describe("queue processors", () => {
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem() });
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: { pull_requests: "write", checks: "write" }, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto", update_branch: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto", update_branch: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 7, title: "Missing required context, past short cap", state: "open", user: { login: "contributor" }, head: { sha: "a7" }, base: { ref: "main" }, labels: [], body: "Closes #1" });
vi.setSystemTime(new Date("2026-05-28T02:00:00.000Z"));
// 3 minutes elapsed: past the 2-minute missing-required-context surfacing cap, but nowhere near the old
@@ -2002,7 +2002,7 @@ describe("queue processors", () => {
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem() });
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: { pull_requests: "write", checks: "write" }, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto", update_branch: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto", update_branch: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 7, title: "CI completeness unverified", state: "open", user: { login: "contributor" }, head: { sha: "a7" }, base: { ref: "main" }, labels: [], body: "Closes #1" });
const requiredContextsSpy = vi.spyOn(backfillModule, "fetchRequiredStatusContexts").mockResolvedValue(null);
const liveCiSpy = vi.spyOn(backfillModule, "fetchLiveCiAggregatePreferGraphQl").mockResolvedValue({
@@ -2044,7 +2044,7 @@ describe("queue processors", () => {
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem() });
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: { pull_requests: "write", checks: "write" }, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto", update_branch: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto", update_branch: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 7, title: "CI fully verified", state: "open", user: { login: "contributor" }, head: { sha: "a7" }, base: { ref: "main" }, labels: [], body: "Closes #1" });
const requiredContextsSpy = vi.spyOn(backfillModule, "fetchRequiredStatusContexts").mockResolvedValue(new Set(["trusted-required-ci"]));
const liveCiSpy = vi.spyOn(backfillModule, "fetchLiveCiAggregatePreferGraphQl").mockResolvedValue({
@@ -2098,7 +2098,7 @@ describe("queue processors", () => {
autonomy: { close: "auto", review_state_label: "auto" },
aiReviewMode: "off",
gatePack: "oss-anti-slop",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
checkRunMode: "off",
commentMode: "off",
publicSurface: "off",
@@ -2258,7 +2258,7 @@ describe("queue processors", () => {
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem() });
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: { pull_requests: "write", issues: "write", checks: "write" }, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { close: "auto", review_state_label: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { close: "auto", review_state_label: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 7, title: "No hard rule enabled", state: "open", user: { login: "contributor" }, head: { sha: "a7" }, base: { ref: "main" }, labels: [], body: "Closes #9" });
const requiredContextsSpy = requiredContextsMock();
const liveCiSpy = liveCiMock();
@@ -2292,7 +2292,7 @@ describe("queue processors", () => {
// keeps both passes comparable: it satisfies isAgentConfigured, but the action executor STAGES the merge
// for approval instead of ever calling the GitHub merge endpoint, so the PR stays open with the same
// head_sha across both passes.
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto_with_approval", update_branch: "auto_with_approval" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto_with_approval", update_branch: "auto_with_approval" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 7, title: "Cross-job CI cache", state: "open", user: { login: "contributor" }, head: { sha: headSha }, base: { ref: "main" }, labels: [], body: "Closes #1" });
return { env };
}
@@ -2665,7 +2665,7 @@ describe("queue processors", () => {
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem() });
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: { pull_requests: "write", checks: "write" }, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto", update_branch: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto", update_branch: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 7, title: "Fold-all vs configured", state: "open", user: { login: "contributor" }, head: { sha: "a7" }, base: { ref: "main" }, labels: [], body: "Closes #1" });
let branchProtectionGets = 0;
vi.stubGlobal("fetch", async (input: RequestInfo | URL, init?: RequestInit) => {
@@ -2724,7 +2724,7 @@ describe("queue processors", () => {
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem() });
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: { pull_requests: "write", checks: "write" }, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto", update_branch: "auto" }, autoMaintain: { requireApprovals: 0, mergeMethod: "squash" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto", update_branch: "auto" }, autoMaintain: { requireApprovals: 0, mergeMethod: "squash" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 7, title: "Configured + clean", state: "open", user: { login: "contributor" }, head: { sha: "a7" }, base: { ref: "main" }, labels: [], body: "Closes #1" });
await upsertPullRequestDetailSyncState(env, { repoFullName: "owner/agent-repo", pullNumber: 7, status: "complete", reviewsSyncedAt: new Date().toISOString() });
// gate.expectedCiContexts is satisfied by a real, passing check-run — so CI resolves cleanly and the pass
@@ -2771,7 +2771,7 @@ describe("queue processors", () => {
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem() });
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: { pull_requests: "write", checks: "write" }, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto", update_branch: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto", update_branch: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 7, title: "Branch protection drift", state: "open", user: { login: "contributor" }, head: { sha: "a7" }, base: { ref: "main" }, labels: [], body: "Closes #1" });
// expectedCiContexts is configured ONCE and never changes across the two calls below -- only branch protection
// (the OTHER input to mergeRequiredCiContexts) drifts between them.
@@ -2820,7 +2820,7 @@ describe("queue processors", () => {
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem() });
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: { pull_requests: "write", checks: "write" }, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto", update_branch: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto", update_branch: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 7, title: "Spaced context drift", state: "open", user: { login: "contributor" }, head: { sha: "a7" }, base: { ref: "main" }, labels: [], body: "Closes #1" });
await upsertRepoFocusManifest(env, "owner/agent-repo", { gate: { expectedCiContexts: ["lint"] } });
let requiredContextsFromBranchProtection: Array = [];
@@ -2865,7 +2865,7 @@ describe("queue processors", () => {
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem() });
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: {}, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 7, title: "Drifted PR", state: "open", user: { login: "contributor" }, head: { sha: "a7" }, labels: [], body: "Closes #1" });
// The live head drifted (b8 ≠ a7), so the resync upsert fires — but it REJECTS. The `.catch(() => undefined)`
// must swallow it so the sweep proceeds on the stored `pr` rather than stalling (#sweep-resync fail-open).
@@ -2895,7 +2895,7 @@ describe("queue processors", () => {
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem() });
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: {}, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 7, title: "Current PR", state: "open", user: { login: "contributor" }, head: { sha: "a7" }, labels: [], body: "Closes #1" });
await repositoriesModule.markPullRequestSurfacePublished(env, "owner/agent-repo", 7, "a7"); // marker says current, but GitHub may still show a stale/partial panel
let checkRunsFetched = false;
@@ -2920,7 +2920,7 @@ describe("queue processors", () => {
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem(), GITTENSORY_REVIEW_REPOS: "owner/agent-repo" });
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: {}, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 7, title: "Current PR", state: "open", user: { login: "contributor" }, head: { sha: "a7" }, labels: [], body: "Closes #1" });
await repositoriesModule.markPullRequestSurfacePublished(env, "owner/agent-repo", 7, "a7");
let checkRunsFetched = false;
@@ -2998,7 +2998,7 @@ describe("queue processors", () => {
});
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: {}, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
// Links issue #1 — the issue the "labeled" event below fires on.
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 7, title: "Linking PR", state: "open", user: { login: "contributor" }, head: { sha: "a7" }, labels: [], body: "Closes #1", created_at: "2026-07-03T10:00:00.000Z" });
let fetchCount = 0;
@@ -3041,7 +3041,7 @@ describe("queue processors", () => {
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem(), GITTENSORY_REVIEW_REPOS: "owner/agent-repo" });
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: {}, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
// Links issue #99 — the "labeled" event below fires on issue #1, which this PR does NOT link.
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 7, title: "Unrelated PR", state: "open", user: { login: "contributor" }, head: { sha: "a7" }, labels: [], body: "Closes #99" });
let checkRunsFetched = false;
@@ -3072,7 +3072,7 @@ describe("queue processors", () => {
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem(), GITTENSORY_REVIEW_REPOS: "" });
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: {}, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 7, title: "Linking PR", state: "open", user: { login: "contributor" }, head: { sha: "a7" }, labels: [], body: "Closes #1", created_at: "2026-07-03T10:00:00.000Z" });
let checkRunsFetched = false;
vi.stubGlobal("fetch", async (input: RequestInfo | URL) => {
@@ -3142,7 +3142,7 @@ describe("queue processors", () => {
});
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: {}, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 7, title: "Linking PR", state: "open", user: { login: "contributor" }, head: { sha: "a7" }, labels: [], body: "Closes #1", created_at: "2026-07-03T10:00:00.000Z" });
// A CI completion for this exact PR claimed the CI-completion window moments earlier — a wholly separate
// trigger from the issue-side label change below.
@@ -3194,7 +3194,7 @@ describe("queue processors", () => {
});
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: {}, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 7, title: "Linking PR", state: "open", user: { login: "contributor" }, head: { sha: "a7" }, labels: [], body: "Closes #1", created_at: "2026-07-03T10:00:00.000Z" });
let fetchCallCount = 0;
vi.stubGlobal("fetch", async (input: RequestInfo | URL) => {
@@ -3254,7 +3254,7 @@ describe("queue processors", () => {
});
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: {}, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
for (let number = 1; number <= SWEEP_MAX_PRS + 2; number += 1) {
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number, title: `Linking PR ${number}`, state: "open", user: { login: "contributor" }, head: { sha: `a${number}` }, labels: [], body: "Closes #1" });
}
@@ -3306,7 +3306,7 @@ describe("queue processors", () => {
});
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: {}, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
for (let number = 1; number <= ISSUE_WAKE_MAX_PRS + 2; number += 1) {
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number, title: `Linking PR ${number}`, state: "open", user: { login: "contributor" }, head: { sha: `a${number}` }, labels: [], body: "Closes #1" });
}
@@ -3347,7 +3347,7 @@ describe("queue processors", () => {
});
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: {}, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
for (const number of [10, 11, 12]) {
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number, title: `Sibling PR ${number}`, state: "open", user: { login: "contributor" }, head: { sha: `sib${number}` }, labels: [], body: "No linked issue.", created_at: `2026-07-0${number - 9}T00:00:00.000Z` });
}
@@ -3395,7 +3395,7 @@ describe("queue processors", () => {
});
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: {}, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
for (const number of [10, 11, 12]) {
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number, title: `Sibling PR ${number}`, state: "open", user: { login: "contributor" }, head: { sha: `sib${number}` }, labels: [], body: "No linked issue." });
}
@@ -3438,7 +3438,7 @@ describe("queue processors", () => {
});
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: {}, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
for (let number = 1; number <= MERGE_WAKE_MAX_PRS + 2; number += 1) {
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number, title: `Sibling PR ${number}`, state: "open", user: { login: "contributor" }, head: { sha: `sib${number}` }, labels: [], body: "No linked issue." });
}
@@ -3491,7 +3491,7 @@ describe("queue processors", () => {
});
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: {}, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 7, title: "Linking PR", state: "open", user: { login: "contributor" }, head: { sha: "a7" }, labels: [], body: "Closes #1" });
vi.stubGlobal("fetch", async (input: RequestInfo | URL) => {
const url = input.toString();
@@ -3553,7 +3553,7 @@ describe("queue processors", () => {
});
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: {}, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 7, title: "Linking PR", state: "open", user: { login: "contributor" }, head: { sha: "a7" }, labels: [], body: "Closes #1" });
vi.stubGlobal("fetch", async (input: RequestInfo | URL) => {
const url = input.toString();
@@ -3604,7 +3604,7 @@ describe("queue processors", () => {
});
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: {}, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 7, title: "Linking PR", state: "open", user: { login: "contributor" }, head: { sha: "a7" }, labels: [], body: "Closes #1" });
vi.stubGlobal("fetch", async (input: RequestInfo | URL) => {
const url = input.toString();
@@ -3651,7 +3651,7 @@ describe("queue processors", () => {
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem() });
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: {}, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 7, title: "Rebased PR", state: "open", user: { login: "contributor" }, head: { sha: "a7" }, labels: [], body: "Closes #1" });
await repositoriesModule.markPullRequestSurfacePublished(env, "owner/agent-repo", 7, "a7"); // published at the OLD head a7
let checkRunsFetchedAtNewHead = false;
@@ -3681,7 +3681,7 @@ describe("queue processors", () => {
it("#4 over-publish dedup: a failing surface-published stamp is swallowed (fail-open) — the publish still completes", async () => {
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem() });
await upsertRepositoryFromGitHub(env, { name: "gittensory", full_name: "JSONbored/gittensory", private: false, owner: { login: "JSONbored" } }, 123);
- await upsertRepositorySettings(env, { repoFullName: "JSONbored/gittensory", commentMode: "all_prs", publicSurface: "comment_only", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", aiReviewMode: "off", gatePack: "oss-anti-slop" });
+ await upsertRepositorySettings(env, { repoFullName: "JSONbored/gittensory", commentMode: "all_prs", publicSurface: "comment_only", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", reviewCheckMode: "required", aiReviewMode: "off", gatePack: "oss-anti-slop" });
const stampSpy = vi.spyOn(repositoriesModule, "markPullRequestSurfacePublished").mockRejectedValueOnce(new Error("D1 stamp failed"));
let commentPosted = false;
vi.stubGlobal("fetch", async (input: RequestInfo | URL, init?: RequestInit) => {
@@ -3721,7 +3721,7 @@ describe("queue processors", () => {
it("REGRESSION (registry-never-synced lane fix): a contributor PR panel does not show the lane-unavailable hold when no registry snapshot has ever synced", async () => {
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem() });
await upsertRepositoryFromGitHub(env, { name: "gittensory", full_name: "JSONbored/gittensory", private: false, owner: { login: "JSONbored" } }, 123);
- await upsertRepositorySettings(env, { repoFullName: "JSONbored/gittensory", commentMode: "all_prs", publicSurface: "comment_only", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", aiReviewMode: "off", gatePack: "oss-anti-slop" });
+ await upsertRepositorySettings(env, { repoFullName: "JSONbored/gittensory", commentMode: "all_prs", publicSurface: "comment_only", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", reviewCheckMode: "required", aiReviewMode: "off", gatePack: "oss-anti-slop" });
let commentBody = "";
vi.stubGlobal("fetch", async (input: RequestInfo | URL, init?: RequestInit) => {
const url = input.toString();
@@ -3784,7 +3784,7 @@ describe("queue processors", () => {
),
);
await upsertRepositoryFromGitHub(env, { name: "gittensory", full_name: "JSONbored/gittensory", private: false, owner: { login: "JSONbored" } }, 123);
- await upsertRepositorySettings(env, { repoFullName: "JSONbored/gittensory", commentMode: "all_prs", publicSurface: "comment_only", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", aiReviewMode: "off", gatePack: "oss-anti-slop" });
+ await upsertRepositorySettings(env, { repoFullName: "JSONbored/gittensory", commentMode: "all_prs", publicSurface: "comment_only", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", reviewCheckMode: "required", aiReviewMode: "off", gatePack: "oss-anti-slop" });
let commentBody = "";
vi.stubGlobal("fetch", async (input: RequestInfo | URL, init?: RequestInit) => {
const url = input.toString();
@@ -3836,7 +3836,7 @@ describe("queue processors", () => {
it("#regate-churn: a failing markAiReviewPublished stamp is swallowed (fail-open) — the publish still completes", async () => {
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem() });
await upsertRepositoryFromGitHub(env, { name: "gittensory", full_name: "JSONbored/gittensory", private: false, owner: { login: "JSONbored" } }, 123);
- await upsertRepositorySettings(env, { repoFullName: "JSONbored/gittensory", commentMode: "all_prs", publicSurface: "comment_only", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", aiReviewMode: "off", gatePack: "oss-anti-slop" });
+ await upsertRepositorySettings(env, { repoFullName: "JSONbored/gittensory", commentMode: "all_prs", publicSurface: "comment_only", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", reviewCheckMode: "required", aiReviewMode: "off", gatePack: "oss-anti-slop" });
const markSpy = vi.spyOn(repositoriesModule, "markAiReviewPublished").mockRejectedValueOnce(new Error("D1 stamp failed"));
let commentPosted = false;
vi.stubGlobal("fetch", async (input: RequestInfo | URL, init?: RequestInit) => {
@@ -3891,7 +3891,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
aiReviewMode: "block",
gatePack: "oss-anti-slop",
...overrides,
@@ -4385,7 +4385,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "enabled",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "block",
requireLinkedIssue: true,
autonomy: { merge: "observe", request_changes: "observe" },
@@ -4646,7 +4646,7 @@ describe("queue processors", () => {
publicSurface: "comment_only",
autoLabelEnabled: false,
checkRunMode: "enabled",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
aiReviewMode: "block",
gatePack: "oss-anti-slop",
});
@@ -6662,7 +6662,7 @@ describe("queue processors", () => {
});
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: {}, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "block", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "block", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 7, title: "Stale PR", state: "open", user: { login: "contributor" }, head: { sha: "a7" }, labels: [], body: "Closes #1" });
await upsertPullRequestFile(env, { repoFullName: "owner/agent-repo", pullNumber: 7, path: "src/a.ts", status: "modified", additions: 1, deletions: 0, changes: 1, payload: { patch: "@@\n+export const ok = value.length;" } });
// Pre-seed the AI review for this exact head SHA + mode → the sweep's block-mode review must reuse it, not re-run.
@@ -6775,7 +6775,7 @@ describe("queue processors", () => {
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: {}, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
// aiReviewLowConfidenceDisposition left UNSET — the shipped default (hold_for_review) is what's under test.
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { close: "auto" }, aiReviewMode: "block", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { close: "auto" }, aiReviewMode: "block", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 8, title: "Sub-floor defect PR", state: "open", user: { login: "contributor" }, head: { sha: "b8" }, labels: [], body: "Closes #1" });
await upsertPullRequestFile(env, { repoFullName: "owner/agent-repo", pullNumber: 8, path: "src/a.ts", status: "modified", additions: 1, deletions: 0, changes: 1, payload: { patch: "@@\n+export const ok = value.length;" } });
const inputFingerprint = await cachedSubFloorDefectFingerprint("Sub-floor defect PR");
@@ -6826,7 +6826,7 @@ describe("queue processors", () => {
});
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: { pull_requests: "write" }, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { close: "auto" }, aiReviewMode: "block", aiReviewLowConfidenceDisposition: "one_shot", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { close: "auto" }, aiReviewMode: "block", aiReviewLowConfidenceDisposition: "one_shot", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 9, title: "Sub-floor defect PR (one_shot)", state: "open", user: { login: "contributor" }, head: { sha: "c9" }, labels: [], body: "Closes #1" });
await upsertPullRequestFile(env, { repoFullName: "owner/agent-repo", pullNumber: 9, path: "src/a.ts", status: "modified", additions: 1, deletions: 0, changes: 1, payload: { patch: "@@\n+export const ok = value.length;" } });
const inputFingerprint = await cachedSubFloorDefectFingerprint("Sub-floor defect PR (one_shot)");
@@ -6891,7 +6891,7 @@ describe("queue processors", () => {
publicSurface: "comment_only",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
aiReviewMode: "block",
gatePack: "oss-anti-slop",
});
@@ -7126,7 +7126,7 @@ describe("queue processors", () => {
publicSurface: "comment_only",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
aiReviewMode: "block",
gatePack: "oss-anti-slop",
});
@@ -7201,7 +7201,7 @@ describe("queue processors", () => {
publicSurface: "comment_only",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
aiReviewMode: "block",
gatePack: "oss-anti-slop",
});
@@ -7276,7 +7276,7 @@ describe("queue processors", () => {
publicSurface: "comment_only",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
aiReviewMode: "block",
gatePack: "oss-anti-slop",
});
@@ -7362,7 +7362,7 @@ describe("queue processors", () => {
publicSurface: "comment_only",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
aiReviewMode: "block",
gatePack: "oss-anti-slop",
});
@@ -7445,7 +7445,7 @@ describe("queue processors", () => {
publicSurface: "comment_only",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
aiReviewMode: "block",
gatePack: "oss-anti-slop",
});
@@ -7504,7 +7504,7 @@ describe("queue processors", () => {
});
await persistRegistrySnapshot(env, normalizeRegistryPayload({ "JSONbored/gittensory": { emission_share: 0.01, issue_discovery_share: 0 } }, { kind: "raw-github", url: "https://example.test" }, "2026-05-23T00:00:00.000Z"));
await upsertRepositoryFromGitHub(env, { name: "gittensory", full_name: "JSONbored/gittensory", private: false, owner: { login: "JSONbored" } }, 123);
- await upsertRepositorySettings(env, { repoFullName: "JSONbored/gittensory", commentMode: "all_prs", publicSurface: "comment_only", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", aiReviewMode: "advisory" });
+ await upsertRepositorySettings(env, { repoFullName: "JSONbored/gittensory", commentMode: "all_prs", publicSurface: "comment_only", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", reviewCheckMode: "required", aiReviewMode: "advisory" });
const stickyComment: { current: { id: number; body: string } | null } = { current: null };
let postCount = 0;
let patchCount = 0;
@@ -7664,7 +7664,7 @@ describe("queue processors", () => {
publicSurface: "comment_only",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
aiReviewMode: "block",
gatePack: "oss-anti-slop",
});
@@ -7755,7 +7755,7 @@ describe("queue processors", () => {
publicSurface: "comment_only",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
aiReviewMode: "block",
gatePack: "oss-anti-slop",
});
@@ -7849,7 +7849,7 @@ describe("queue processors", () => {
publicSurface: "comment_only",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
aiReviewMode: "block",
gatePack: "oss-anti-slop",
});
@@ -7927,7 +7927,7 @@ describe("queue processors", () => {
publicSurface: "comment_only",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
aiReviewMode: "block",
gatePack: "oss-anti-slop",
});
@@ -8047,7 +8047,7 @@ describe("queue processors", () => {
const env = createTestEnv({ JOBS: { async send(m: import("../../src/types").JobMessage) { sent.push(m); } } as unknown as Queue });
await upsertInstallation(env, { action: "created", installation: { id: 9400, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: {}, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9400);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
for (const number of [1, 2, 3, 4]) {
const headSha = `a${number}`;
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number, title: `PR${number}`, state: "open", user: { login: "c" }, head: { sha: headSha }, labels: [], body: "" });
@@ -8152,7 +8152,7 @@ describe("queue processors", () => {
});
await upsertInstallation(env, { action: "created", installation: { id: 9402, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: {}, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9402);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
for (const number of [1, 2, 3, 4, 5]) {
const headSha = `repair-${number}`;
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number, title: `Repair ${number}`, state: "open", user: { login: "c" }, head: { sha: headSha }, labels: [], body: "" });
@@ -8192,7 +8192,7 @@ describe("queue processors", () => {
});
await upsertInstallation(env, { action: "created", installation: { id: 9403, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: {}, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9403);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
// PR 1: missing its current Gate check -- the one priority repair. Make it newer-by-regate than the
// ordinary stale PRs below, reproducing the backlog bug where a max=1 staleness slice could drop the repair.
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 1, title: "Repair 1", state: "open", user: { login: "c" }, head: { sha: "repair-1" }, labels: [], body: "" });
@@ -8233,7 +8233,7 @@ describe("queue processors", () => {
const env = createTestEnv({ JOBS: { async send(m: import("../../src/types").JobMessage) { sent.push(m); } } as unknown as Queue });
await upsertInstallation(env, { action: "created", installation: { id: 9404, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: {}, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9404);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
// PR 1: missing its current Gate check for its current head -- surfaceRepairPriorityPullNumbers flags this as
// outage-repair priority (no completed Gittensory Gate check run at the live head SHA).
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 1, title: "Repair 1", state: "open", user: { login: "c" }, head: { sha: "repair-1" }, labels: [], body: "" });
@@ -8280,7 +8280,7 @@ describe("queue processors", () => {
const env = createTestEnv({ JOBS: { async send(m: import("../../src/types").JobMessage) { sent.push(m); } } as unknown as Queue });
await upsertInstallation(env, { action: "created", installation: { id: 9407, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: {}, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9407);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
// PR 1: missing its current Gate check for its current head -- would ordinarily be flagged outage-repair
// priority on every tick. Pre-seed REGATE_REPAIR_MAX_ATTEMPTS_PER_SHA=5 (#3998) prior repair-attempt audit
// events for this EXACT head SHA to simulate a review that keeps failing (e.g. a timeout) and never
@@ -8332,7 +8332,7 @@ describe("queue processors", () => {
const env = createTestEnv({ JOBS: { async send(m: import("../../src/types").JobMessage) { sent.push(m); } } as unknown as Queue });
await upsertInstallation(env, { action: "created", installation: { id: 9408, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: {}, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9408);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 2, title: "Fresh repair", state: "open", user: { login: "c" }, head: { sha: "fresh-sha" }, labels: [], body: "" });
await repositoriesModule.markPullRequestSurfacePublished(env, "owner/agent-repo", 2, "fresh-sha");
const targetKey = "owner/agent-repo#2#fresh-sha";
@@ -8377,7 +8377,7 @@ describe("queue processors", () => {
const env = createTestEnv({ JOBS: { async send(m: import("../../src/types").JobMessage) { sent.push(m); } } as unknown as Queue });
await upsertInstallation(env, { action: "created", installation: { id: 9401, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: {}, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9401);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 7, title: "Repair me", state: "open", user: { login: "c" }, head: { sha: "a7" }, labels: [], body: "" });
await repositoriesModule.markPullRequestSurfacePublished(env, "owner/agent-repo", 7, "a7");
vi.setSystemTime(new Date("2026-05-28T02:00:00.000Z"));
@@ -9122,7 +9122,7 @@ describe("queue processors", () => {
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem() });
await upsertInstallation(env, { action: "created", installation: { id: 9001, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: {}, events: [] } });
await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9001);
- await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
await upsertPullRequestFromGitHub(env, "owner/agent-repo", { number: 7, title: "Clean PR", state: "open", user: { login: "contributor" }, head: { sha: "a7" }, labels: [], body: "Closes #1" });
let mergeCalls = 0;
vi.stubGlobal("fetch", async (input: RequestInfo | URL, init?: RequestInit) => {
@@ -9670,7 +9670,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "block",
requireLinkedIssue: true,
});
@@ -9750,7 +9750,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "block",
requireLinkedIssue: true,
});
@@ -9804,7 +9804,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "block",
requireLinkedIssue: true,
});
@@ -9869,7 +9869,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
manifestPolicyGateMode: "block",
requireLinkedIssue: false,
@@ -9957,7 +9957,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
manifestPolicyGateMode: "block",
requireLinkedIssue: false,
@@ -10047,7 +10047,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
manifestPolicyGateMode: "block",
requireLinkedIssue: false,
@@ -10143,7 +10143,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
manifestPolicyGateMode: "block",
requireLinkedIssue: false,
@@ -10232,7 +10232,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
manifestPolicyGateMode: "block",
requireLinkedIssue: false,
@@ -10326,7 +10326,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
manifestPolicyGateMode: "block",
requireLinkedIssue: false,
@@ -10404,7 +10404,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
aiReviewMode: "off",
});
@@ -10460,7 +10460,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
aiReviewMode: "off",
});
@@ -10524,7 +10524,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
aiReviewMode: "off",
});
@@ -10927,7 +10927,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
aiReviewMode: "off",
});
@@ -11022,7 +11022,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
aiReviewMode: "off",
});
@@ -11097,7 +11097,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "block",
requireLinkedIssue: true,
autonomy: { review_state_label: "auto", request_changes: "auto" },
@@ -11160,7 +11160,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
manifestPolicyGateMode: "block",
autonomy: { merge: "auto", request_changes: "auto" },
agentDryRun: true,
@@ -11318,7 +11318,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "enabled",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
autonomy: { merge: "observe", request_changes: "observe" }, // evaluate + post the gate, take no merge/close action
agentDryRun: false, // so the gate check-run is actually POSTed (dry-run suppresses the write) and capturable
});
@@ -11397,7 +11397,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "enabled",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
autonomy: { merge: "observe", request_changes: "observe" },
agentDryRun: false,
});
@@ -11475,7 +11475,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "enabled",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
autonomy: { merge: "observe", request_changes: "observe" },
agentDryRun: false,
});
@@ -11547,7 +11547,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "enabled",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
autonomy: { merge: "observe", request_changes: "observe" },
agentDryRun: false,
// No gate.claMode manifest override — claGateMode stays undefined (the safe default).
@@ -11624,7 +11624,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "enabled",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
autonomy: { merge: "observe", request_changes: "observe" },
agentDryRun: false,
});
@@ -11700,7 +11700,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "enabled",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
autonomy: { merge: "observe", request_changes: "observe" },
agentDryRun: false,
});
@@ -11780,7 +11780,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "enabled",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
autonomy: { merge: "observe", request_changes: "observe" },
agentDryRun: false,
});
@@ -12701,7 +12701,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
autonomy: { merge: "auto", approve: "auto", close: "auto" },
});
vi.stubGlobal("fetch", async (input: RequestInfo | URL) => {
@@ -12760,7 +12760,7 @@ describe("queue processors", () => {
commentMode: "all_prs",
publicSurface: "comment_only",
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
aiReviewMode: "advisory",
autonomy: { close: "auto", label: "auto" },
// The banned login is per-repo DB config; the label is the configurable `.gittensory.yml` value below —
@@ -12833,7 +12833,7 @@ describe("queue processors", () => {
commentMode: "all_prs",
publicSurface: "comment_only",
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
aiReviewMode: "advisory",
autonomy: { close: "auto", label: "auto" },
});
@@ -12896,7 +12896,7 @@ describe("queue processors", () => {
commentMode: "all_prs",
publicSurface: "comment_only",
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
autonomy: { close: "auto", merge: "auto" },
});
await upsertRepoFocusManifest(env, "JSONbored/gittensory", { settings: { screenshotTableGate: { enabled: true, whenLabels: ["visual"] } } }, "repo_file");
@@ -12980,7 +12980,7 @@ describe("queue processors", () => {
commentMode: "all_prs",
publicSurface: "comment_only",
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
autonomy: { close: "auto", label: "auto" },
});
await upsertRepoFocusManifest(env, "JSONbored/gittensory", { settings: { screenshotTableGate: { enabled: true, whenLabels: ["visual"] } } }, "repo_file");
@@ -13086,7 +13086,7 @@ describe("queue processors", () => {
commentMode: "all_prs",
publicSurface: "comment_only",
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
autonomy: { close: "auto", label: "auto" },
});
await upsertRepoFocusManifest(env, "JSONbored/gittensory", { settings: { screenshotTableGate: { enabled: true, whenLabels: ["visual"] } } }, "repo_file");
@@ -13204,7 +13204,7 @@ describe("queue processors", () => {
installation: { id: 123, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: { contents: "write", pull_requests: "write", issues: "write" }, events: [] },
});
await upsertRepositoryFromGitHub(env, { name: "repo", full_name: "owner/repo", private: false, owner: { login: "owner" } }, 123);
- await upsertRepositorySettings(env, { repoFullName: "owner/repo", autonomy: { merge: "auto", review_state_label: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/repo", autonomy: { merge: "auto", review_state_label: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
if (opts.premergeContentRecheck !== undefined) {
await upsertRepoFocusManifest(env, "owner/repo", { gate: { premergeContentRecheck: opts.premergeContentRecheck } });
}
@@ -13283,7 +13283,7 @@ describe("queue processors", () => {
});
// No default_branch on the repo record AND no base.ref on the PR record — baseRef resolves to undefined.
await upsertRepositoryFromGitHub(env, { name: "repo", full_name: "owner/repo", private: false, owner: { login: "owner" } }, 123);
- await upsertRepositorySettings(env, { repoFullName: "owner/repo", autonomy: { merge: "auto", review_state_label: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/repo", autonomy: { merge: "auto", review_state_label: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
await upsertRepoFocusManifest(env, "owner/repo", { gate: { premergeContentRecheck: true } });
await upsertPullRequestFromGitHub(env, "owner/repo", { number: 65, title: "No base ref", state: "open", user: { login: "contributor" }, head: { sha: "sha1" }, labels: [], body: "" });
const seen = { closed: false, merged: false, labels: [] as string[], comments: [] as string[], treeCalls: 0 };
@@ -13655,7 +13655,7 @@ describe("queue processors", () => {
installation: { id: 123, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: { contents: "write", pull_requests: "write", issues: "write" }, events: [] },
});
await upsertRepositoryFromGitHub(env, { name: "repo", full_name: "owner/repo", private: false, owner: { login: "owner" } }, 123);
- await upsertRepositorySettings(env, { repoFullName: "owner/repo", autonomy: opts.autonomy ?? { merge: "auto", review_state_label: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
+ await upsertRepositorySettings(env, { repoFullName: "owner/repo", autonomy: opts.autonomy ?? { merge: "auto", review_state_label: "auto" }, aiReviewMode: "off", gatePack: "oss-anti-slop", gateCheckMode: "enabled", reviewCheckMode: "required", checkRunMode: "off", commentMode: "off", publicSurface: "off" });
if (opts.guardrailMode !== undefined) {
await upsertRepoFocusManifest(env, "owner/repo", { settings: { unlinkedIssueGuardrail: { mode: opts.guardrailMode } } });
}
@@ -13781,7 +13781,7 @@ describe("queue processors", () => {
autoMaintain: { requireApprovals: 0, mergeMethod: "squash" },
aiReviewMode: "off",
gatePack: "oss-anti-slop",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
checkRunMode: "off",
commentMode: "off",
publicSurface: "off",
@@ -13940,7 +13940,7 @@ describe("queue processors", () => {
commentMode: "all_prs",
publicSurface: "comment_only",
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
aiReviewMode: "advisory",
autonomy: { close: "auto", label: "auto" },
contributorOpenPrCap: 2,
@@ -14008,7 +14008,7 @@ describe("queue processors", () => {
commentMode: "all_prs",
publicSurface: "comment_only",
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
aiReviewMode: "advisory",
autonomy: { close: "auto", label: "auto" },
contributorOpenPrCap: 2,
@@ -14094,7 +14094,7 @@ describe("queue processors", () => {
commentMode: "all_prs",
publicSurface: "comment_only",
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
aiReviewMode: "advisory",
autonomy: { close: "auto", label: "auto" },
contributorOpenPrCap: 2,
@@ -14135,7 +14135,7 @@ describe("queue processors", () => {
commentMode: "all_prs",
publicSurface: "comment_only",
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
aiReviewMode: "advisory",
autonomy: { close: "auto", label: "auto" },
contributorOpenPrCap: 2,
@@ -14179,7 +14179,7 @@ describe("queue processors", () => {
commentMode: "all_prs",
publicSurface: "comment_only",
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
aiReviewMode: "advisory",
autonomy: { close: "auto", label: "auto" },
contributorOpenPrCap: 2,
@@ -14226,7 +14226,7 @@ describe("queue processors", () => {
commentMode: "all_prs",
publicSurface: "comment_only",
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
aiReviewMode: "advisory",
autonomy: { close: "auto", label: "auto" },
contributorOpenPrCap: 2,
@@ -14265,7 +14265,7 @@ describe("queue processors", () => {
commentMode: "all_prs",
publicSurface: "comment_only",
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
aiReviewMode: "advisory",
autonomy: { close: "auto", label: "auto" },
contributorOpenPrCap: 2,
@@ -14313,7 +14313,7 @@ describe("queue processors", () => {
commentMode: "all_prs",
publicSurface: "comment_only",
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
aiReviewMode: "advisory",
autonomy: { close: "auto", label: "auto" },
contributorOpenPrCap: 2,
@@ -14357,7 +14357,7 @@ describe("queue processors", () => {
commentMode: "all_prs",
publicSurface: "comment_only",
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
aiReviewMode: "advisory",
autonomy: { close: "auto", label: "auto" },
contributorOpenPrCap: 2,
@@ -14395,7 +14395,7 @@ describe("queue processors", () => {
commentMode: "all_prs",
publicSurface: "comment_only",
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
aiReviewMode: "advisory",
autonomy: { close: "auto", label: "auto" },
contributorOpenPrCap: 2,
@@ -14436,7 +14436,7 @@ describe("queue processors", () => {
commentMode: "all_prs",
publicSurface: "comment_only",
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
aiReviewMode: "advisory",
autonomy: { close: "auto", label: "auto" },
contributorOpenPrCap: 1,
@@ -14494,7 +14494,7 @@ describe("queue processors", () => {
commentMode: "off",
publicSurface: "off",
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
autonomy: { close: "auto", label: "auto" },
contributorOpenPrCap: 100, // above SIBLING_COUNT + 1 — this test only cares about concurrency, not closing.
});
@@ -14556,7 +14556,7 @@ describe("queue processors", () => {
commentMode: "all_prs",
publicSurface: "comment_only",
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
aiReviewMode: "advisory",
autonomy: { close: "auto", label: "auto" },
});
@@ -14611,7 +14611,7 @@ describe("queue processors", () => {
commentMode: "all_prs",
publicSurface: "comment_only",
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
aiReviewMode: "advisory",
autonomy: { close: "auto", label: "auto" },
contributorOpenPrCap: 2,
@@ -14679,7 +14679,7 @@ describe("queue processors", () => {
commentMode: "all_prs",
publicSurface: "comment_only",
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
aiReviewMode: "advisory",
autonomy: { close: "auto", label: "auto" },
// Deliberately NO contributorOpenPrCap here — only the install-wide env cap should catch this.
@@ -14744,7 +14744,7 @@ describe("queue processors", () => {
commentMode: "all_prs",
publicSurface: "comment_only",
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
aiReviewMode: "advisory",
autonomy: { close: "auto", label: "auto" },
});
@@ -14803,7 +14803,7 @@ describe("queue processors", () => {
commentMode: "all_prs",
publicSurface: "comment_only",
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
aiReviewMode: "advisory",
autonomy: { close: "auto", label: "auto" },
});
@@ -14861,7 +14861,7 @@ describe("queue processors", () => {
commentMode: "all_prs",
publicSurface: "comment_only",
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
aiReviewMode: "advisory",
autonomy: { close: "auto", label: "auto" },
autoCloseExemptLogins: ["farmer99"],
@@ -14922,7 +14922,7 @@ describe("queue processors", () => {
commentMode: "all_prs",
publicSurface: "comment_only",
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
aiReviewMode: "advisory",
autonomy: { close: "auto", label: "auto" },
});
@@ -14984,7 +14984,7 @@ describe("queue processors", () => {
commentMode: "all_prs",
publicSurface: "comment_only",
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
aiReviewMode: "advisory",
autonomy: { close: "auto", label: "auto" },
});
@@ -15042,7 +15042,7 @@ describe("queue processors", () => {
commentMode: "all_prs",
publicSurface: "comment_only",
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
aiReviewMode: "advisory",
autonomy: { close: "auto", label: "auto" },
contributorOpenPrCap: 2,
@@ -15098,7 +15098,7 @@ describe("queue processors", () => {
commentMode: "all_prs",
publicSurface: "comment_only",
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
aiReviewMode: "advisory",
autonomy: { close: "auto", label: "auto" },
contributorOpenPrCap: 2,
@@ -15179,7 +15179,7 @@ describe("queue processors", () => {
await upsertRepositorySettings(env, {
repoFullName: "JSONbored/gittensory",
commentMode: "all_prs",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
// #label-scoping: the cap label/close rides on `close`; the new-account label rides on `review_state_label`.
autonomy: { close: "auto", review_state_label: "auto" },
contributorOpenPrCap: 4,
@@ -15216,7 +15216,7 @@ describe("queue processors", () => {
await upsertRepositorySettings(env, {
repoFullName: "JSONbored/gittensory",
commentMode: "all_prs",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
autonomy: { close: "auto", review_state_label: "auto" },
contributorOpenPrCap: 2,
accountAgeThresholdDays: 30,
@@ -15270,7 +15270,7 @@ describe("queue processors", () => {
await upsertRepositorySettings(env, {
repoFullName: "JSONbored/gittensory",
commentMode: "all_prs",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
autonomy: { close: "auto", label: "auto" },
contributorOpenPrCap: 4,
accountAgeThresholdDays: 30,
@@ -15305,7 +15305,7 @@ describe("queue processors", () => {
await upsertRepositorySettings(env, {
repoFullName: "JSONbored/gittensory",
commentMode: "all_prs",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
accountAgeThresholdDays: 30,
});
const seen = { labels: [] as string[], closed: false };
@@ -15351,7 +15351,7 @@ describe("queue processors", () => {
await upsertRepositorySettings(env, {
repoFullName: "JSONbored/gittensory",
commentMode: "all_prs",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
autonomy: { close: "auto", label: "auto" },
// accountAgeThresholdDays intentionally omitted — off by default.
});
@@ -15406,7 +15406,7 @@ describe("queue processors", () => {
await upsertRepositorySettings(env, {
repoFullName: "JSONbored/gittensory",
commentMode: "all_prs",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
autonomy: { close: "auto", review_state_label: "auto" },
accountAgeThresholdDays: 30,
newAccountLabel: "custom-new-account-label",
@@ -15439,7 +15439,7 @@ describe("queue processors", () => {
await upsertRepositorySettings(env, {
repoFullName: "JSONbored/gittensory",
commentMode: "all_prs",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
// autonomy intentionally omitted — deny-by-default ("observe" for every action class, including "review_state_label").
accountAgeThresholdDays: 30,
});
@@ -15835,7 +15835,7 @@ describe("queue processors", () => {
commentMode: "all_prs",
publicSurface: "comment_only",
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
aiReviewMode: "advisory",
autonomy: { close: "auto", label: "auto" },
contributorOpenPrCap: 2,
@@ -15920,7 +15920,7 @@ describe("queue processors", () => {
commentMode: "all_prs",
publicSurface: "comment_only",
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
aiReviewMode: "advisory",
autonomy: { close: "auto", label: "auto" },
contributorOpenPrCap: 2,
@@ -15977,7 +15977,7 @@ describe("queue processors", () => {
commentMode: "all_prs",
publicSurface: "comment_only",
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
aiReviewMode: "advisory",
autonomy: { close: "auto", label: "auto" },
contributorOpenPrCap: 2,
@@ -16781,7 +16781,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
autonomy: over.autonomy ?? { merge: "auto", update_branch: "auto" },
agentPaused: over.agentPaused ?? false,
});
@@ -16919,7 +16919,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "block",
requireLinkedIssue: true,
autonomy: { label: "observe" }, // not acting → agent never runs
@@ -16963,7 +16963,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
autonomy: { review_state_label: "auto", request_changes: "auto" },
});
// No confirmed-miner seed → author is unconfirmed; the manifest's linkedIssue:block + no issue fires a
@@ -17013,7 +17013,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
autonomy: { label: "auto" },
});
vi.stubGlobal("fetch", async (input: RequestInfo | URL) => {
@@ -17055,7 +17055,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
autonomy: { review_state_label: "auto" },
agentDryRun: true,
});
@@ -17104,7 +17104,7 @@ describe("queue processors", () => {
publicSurface: "comment_only",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "block",
});
const calls = { gateChecks: 0, comments: 0, minerList: 0 };
@@ -17175,7 +17175,7 @@ describe("queue processors", () => {
publicSurface: "comment_only",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "block",
});
const calls = { gateChecks: 0, comments: 0, minerList: 0 };
@@ -17354,7 +17354,7 @@ describe("queue processors", () => {
publicSurface: "comment_only",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "block",
});
const calls = { minerList: 0, gateChecks: 0, comments: 0 };
@@ -17426,7 +17426,7 @@ describe("queue processors", () => {
publicSurface: "comment_only",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "block",
});
@@ -17493,7 +17493,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "block",
});
const calls = { minerList: 0, gateChecks: 0 };
@@ -17577,7 +17577,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
aiReviewMode: "block",
// Also exercise the opt-in slop advisory in the same surface pass: it persists a per-PR assessment
@@ -17660,7 +17660,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
});
const patchBodies: Array<{ status?: string; conclusion?: string; output?: { title?: string } }> = [];
@@ -17732,7 +17732,7 @@ describe("queue processors", () => {
publicSurface: "comment_only",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
aiReviewMode: "off",
});
@@ -17803,7 +17803,7 @@ describe("queue processors", () => {
autoLabelEnabled: true,
createMissingLabel: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
aiReviewMode: "off",
});
@@ -17877,7 +17877,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
aiReviewMode: "off",
});
@@ -17936,7 +17936,7 @@ describe("queue processors", () => {
publicSurface: "comment_only",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
aiReviewMode: "off",
});
@@ -17990,7 +17990,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
});
const patchBodies: Array<{ status?: string; conclusion?: string; output?: { title?: string } }> = [];
@@ -18042,7 +18042,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "block",
requireLinkedIssue: true,
});
@@ -18092,7 +18092,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
requireLinkedIssue: true,
});
vi.stubGlobal("fetch", async (input: RequestInfo | URL) => {
@@ -18145,7 +18145,7 @@ describe("queue processors", () => {
publicSurface: "comment_only",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
});
const calls = { gateWrites: 0, commentGets: 0, commentPosts: 0 };
vi.stubGlobal("fetch", async (input: RequestInfo | URL, init?: RequestInit) => {
@@ -18205,7 +18205,7 @@ describe("queue processors", () => {
publicSurface: "comment_only",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
});
let commentGets = 0;
vi.stubGlobal("fetch", async (input: RequestInfo | URL) => {
@@ -18362,7 +18362,7 @@ describe("queue processors", () => {
publicSurface: "comment_only",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
includeMaintainerAuthors: true,
autonomy: { merge: "auto" },
commandAuthorization: { default: ["maintainer"], commands: { "review-now": ["maintainer"] } },
@@ -18924,7 +18924,7 @@ describe("queue processors", () => {
publicSurface: "comment_and_label",
autoLabelEnabled: true,
checkRunMode: "enabled",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
});
let publicCalls = 0;
vi.stubGlobal("fetch", async () => {
@@ -19215,7 +19215,7 @@ describe("queue processors", () => {
autoLabelEnabled: false,
checkRunMode: "off",
checkRunDetailLevel: "minimal",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
backfillEnabled: true,
autonomy: { update_branch: "auto" },
});
@@ -19390,7 +19390,7 @@ describe("queue processors", () => {
autoLabelEnabled: false,
checkRunMode: "off",
checkRunDetailLevel: "minimal",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
backfillEnabled: true,
autonomy: { update_branch: "auto" },
});
@@ -19513,7 +19513,7 @@ describe("queue processors", () => {
autoLabelEnabled: false,
checkRunMode: "off",
checkRunDetailLevel: "minimal",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
backfillEnabled: true,
autonomy: { update_branch: "auto" },
});
@@ -19660,7 +19660,7 @@ describe("queue processors", () => {
autoLabelEnabled: false,
checkRunMode: "off",
checkRunDetailLevel: "minimal",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
backfillEnabled: true,
autonomy: { update_branch: "auto" },
});
@@ -19801,7 +19801,7 @@ describe("queue processors", () => {
autoLabelEnabled: false,
checkRunMode: "off",
checkRunDetailLevel: "minimal",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
backfillEnabled: true,
autonomy: { update_branch: "auto" },
});
@@ -19973,7 +19973,7 @@ describe("queue processors", () => {
autoLabelEnabled: false,
checkRunMode: "off",
checkRunDetailLevel: "minimal",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
backfillEnabled: true,
autonomy: { update_branch: "auto" },
});
@@ -20165,7 +20165,7 @@ describe("queue processors", () => {
publicSurface: "comment_only",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
aiReviewMode: "block",
gatePack: "oss-anti-slop",
});
@@ -20243,7 +20243,7 @@ describe("queue processors", () => {
publicSurface: "comment_only",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
// advisory (NOT block): block mode always reviews the full diff, ignoring exclude_paths/path_filters, so
// only advisory mode exercises the filterReviewFilesForAi branch (src/queue/processors.ts).
aiReviewMode: "advisory",
@@ -20318,7 +20318,7 @@ describe("queue processors", () => {
autoLabelEnabled: false,
checkRunMode: "off",
checkRunDetailLevel: "minimal",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
backfillEnabled: true,
autonomy: { update_branch: "auto" },
linkedIssueGateMode: "block",
@@ -20482,7 +20482,7 @@ describe("queue processors", () => {
autoLabelEnabled: false,
checkRunMode: "off",
checkRunDetailLevel: "minimal",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
backfillEnabled: true,
autonomy: { update_branch: "auto" },
qualityGateMode: "advisory",
@@ -20718,7 +20718,7 @@ describe("queue processors", () => {
it("swallows an estimateReviewEffort failure when persisting the public-stats minutes — the publish still completes", async () => {
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem() });
await upsertRepositoryFromGitHub(env, { name: "gittensory", full_name: "JSONbored/gittensory", private: false, owner: { login: "JSONbored" } }, 123);
- await upsertRepositorySettings(env, { repoFullName: "JSONbored/gittensory", commentMode: "all_prs", publicSurface: "comment_only", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", aiReviewMode: "off", gatePack: "oss-anti-slop" });
+ await upsertRepositorySettings(env, { repoFullName: "JSONbored/gittensory", commentMode: "all_prs", publicSurface: "comment_only", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", reviewCheckMode: "required", aiReviewMode: "off", gatePack: "oss-anti-slop" });
const estimateSpy = vi.spyOn(reviewEffortModule, "estimateReviewEffort").mockImplementationOnce(() => {
throw new Error("estimator blew up");
});
@@ -20806,7 +20806,7 @@ describe("queue processors", () => {
publicSurface: "comment_only",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
aiReviewMode: "block",
gatePack: "oss-anti-slop",
});
@@ -20875,7 +20875,7 @@ describe("queue processors", () => {
});
await persistRegistrySnapshot(env, normalizeRegistryPayload({ "JSONbored/gittensory": { emission_share: 0.01, issue_discovery_share: 0 } }, { kind: "raw-github", url: "https://example.test" }, "2026-05-23T00:00:00.000Z"));
await upsertRepositoryFromGitHub(env, { name: "gittensory", full_name: "JSONbored/gittensory", private: false, owner: { login: "JSONbored" } }, 123);
- await upsertRepositorySettings(env, { repoFullName: "JSONbored/gittensory", commentMode: "all_prs", publicSurface: "comment_only", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", aiReviewMode: "block", gatePack: "oss-anti-slop" });
+ await upsertRepositorySettings(env, { repoFullName: "JSONbored/gittensory", commentMode: "all_prs", publicSurface: "comment_only", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", reviewCheckMode: "required", aiReviewMode: "block", gatePack: "oss-anti-slop" });
await upsertPullRequestFromGitHub(env, "JSONbored/gittensory", { number: 77, title: "Held PR", state: "open", user: { login: "contributor" }, head: { sha: "a77" }, labels: [{ name: "manual-review" }], body: "Closes #1" });
await upsertPullRequestDetailSyncState(env, { repoFullName: "JSONbored/gittensory", pullNumber: 77, status: "complete", reviewsSyncedAt: new Date().toISOString() });
// A prior PUBLISHED review for this exact head — the freeze path reuses it (aiReview = frozenReview) instead of
@@ -20935,7 +20935,7 @@ describe("queue processors", () => {
AI_DAILY_NEURON_BUDGET: "100000",
});
await upsertRepositoryFromGitHub(env, { name: "gittensory", full_name: "JSONbored/gittensory", private: false, owner: { login: "JSONbored" } }, 123);
- await upsertRepositorySettings(env, { repoFullName: "JSONbored/gittensory", commentMode: "all_prs", publicSurface: "comment_only", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", aiReviewMode: "block", gatePack: "oss-anti-slop" });
+ await upsertRepositorySettings(env, { repoFullName: "JSONbored/gittensory", commentMode: "all_prs", publicSurface: "comment_only", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", reviewCheckMode: "required", aiReviewMode: "block", gatePack: "oss-anti-slop" });
let unifiedCommentBody = "";
vi.stubGlobal("fetch", async (input: RequestInfo | URL, init?: RequestInit) => {
const url = input.toString();
@@ -21002,7 +21002,7 @@ describe("queue processors", () => {
autoLabelEnabled: false,
checkRunMode: "off",
checkRunDetailLevel: "minimal",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
backfillEnabled: true,
});
// Seed a FAILED check summary with a per-check WHY (codecov-style) so listCheckSummaries returns it and the
@@ -21159,7 +21159,7 @@ describe("queue processors", () => {
autoLabelEnabled: false,
checkRunMode: "off",
checkRunDetailLevel: "minimal",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
backfillEnabled: true,
});
await upsertPullRequestFromGitHub(env, "JSONbored/gittensory", {
@@ -21307,7 +21307,7 @@ describe("queue processors", () => {
autoLabelEnabled: false,
checkRunMode: "off",
checkRunDetailLevel: "minimal",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
backfillEnabled: true,
});
await upsertPullRequestFromGitHub(env, "JSONbored/gittensory", {
@@ -24931,7 +24931,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
slopGateMode: "off", // dashboard slop disabled…
mergeReadinessGateMode: "advisory", // …but readiness keeps the live score in play
@@ -25010,7 +25010,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
duplicatePrGateMode: "block",
slopGateMode: "advisory",
@@ -25074,7 +25074,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
duplicatePrGateMode: "block",
slopGateMode: "advisory",
@@ -25137,7 +25137,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
duplicatePrGateMode: "block",
slopGateMode: "advisory",
@@ -25201,7 +25201,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
});
await upsertPullRequestFromGitHub(env, "JSONbored/gittensory", {
@@ -25296,7 +25296,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
});
await upsertPullRequestFromGitHub(env, "JSONbored/gittensory", {
@@ -25356,7 +25356,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
agentPaused: true,
});
@@ -25427,7 +25427,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
agentDryRun: true,
});
@@ -25498,7 +25498,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
});
// The stored row still carries the OLD head; a new commit ("live-sha") landed between the comment and now.
@@ -25579,7 +25579,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
});
// A cached row with no head SHA (never detail-synced); the live fetch also yields no head.
@@ -25637,7 +25637,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
});
await upsertPullRequestFromGitHub(env, "JSONbored/gittensory", {
@@ -25704,7 +25704,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
});
await upsertPullRequestFromGitHub(env, "JSONbored/gittensory", {
@@ -25781,7 +25781,7 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
requireLinkedIssue: true,
linkedIssueGateMode: "advisory",
aiReviewMode: "advisory",
@@ -26223,7 +26223,7 @@ describe("queue processors", () => {
const repoFullName = "JSONbored/resolve-1970-dry-run";
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem(), GITTENSORY_REVIEW_MEMORY: "true" });
await seedResolvePr(env, repoFullName, 1970, "resolve-1970-dry-run");
- await upsertRepositorySettings(env, { repoFullName, commentMode: "off", publicSurface: "off", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", requireLinkedIssue: true, linkedIssueGateMode: "advisory", agentDryRun: true });
+ await upsertRepositorySettings(env, { repoFullName, commentMode: "off", publicSurface: "off", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", reviewCheckMode: "required", requireLinkedIssue: true, linkedIssueGateMode: "advisory", agentDryRun: true });
await upsertRepoFocusManifest(env, repoFullName, { review: { memory: true } });
vi.stubGlobal("fetch", async (input: RequestInfo | URL) => {
const url = input.toString();
@@ -26254,7 +26254,7 @@ describe("queue processors", () => {
const repoFullName = "JSONbored/resolve-1971-paused";
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem(), GITTENSORY_REVIEW_MEMORY: "true" });
await seedResolvePr(env, repoFullName, 1971, "resolve-1971-paused");
- await upsertRepositorySettings(env, { repoFullName, commentMode: "off", publicSurface: "off", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", requireLinkedIssue: true, linkedIssueGateMode: "advisory", agentPaused: true });
+ await upsertRepositorySettings(env, { repoFullName, commentMode: "off", publicSurface: "off", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", reviewCheckMode: "required", requireLinkedIssue: true, linkedIssueGateMode: "advisory", agentPaused: true });
await upsertRepoFocusManifest(env, repoFullName, { review: { memory: true } });
vi.stubGlobal("fetch", async (input: RequestInfo | URL) => {
const url = input.toString();
@@ -26288,7 +26288,7 @@ describe("queue processors", () => {
const owner = repoFullName.slice(0, slash);
const name = repoFullName.slice(slash + 1);
await upsertRepositoryFromGitHub(env, { name, full_name: repoFullName, private: false, owner: { login: owner } }, 123);
- await upsertRepositorySettings(env, { repoFullName, commentMode: "off", publicSurface: "off", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", requireLinkedIssue: true, linkedIssueGateMode: "advisory", aiReviewMode: "advisory" });
+ await upsertRepositorySettings(env, { repoFullName, commentMode: "off", publicSurface: "off", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", reviewCheckMode: "required", requireLinkedIssue: true, linkedIssueGateMode: "advisory", aiReviewMode: "advisory" });
await upsertPullRequestFromGitHub(env, repoFullName, { number: prNumber, title: "Explain me", state: "open", user: { login: "contributor" }, author_association: "CONTRIBUTOR", head: { sha: headSha }, labels: [], body: "No linked issue on purpose" });
}
const explainWebhook = (repoFullName: string, prNumber: number, body: string, actor: string, opts: { association?: string; bot?: boolean; action?: string } = {}) => ({
@@ -26455,7 +26455,7 @@ describe("queue processors", () => {
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem() });
// Register the repo + settings but NOT the PR row, so getPullRequest returns null.
await upsertRepositoryFromGitHub(env, { name: "explain-2169-nopr", full_name: repoFullName, private: false, owner: { login: "JSONbored" } }, 123);
- await upsertRepositorySettings(env, { repoFullName, gateCheckMode: "enabled", aiReviewMode: "advisory" });
+ await upsertRepositorySettings(env, { repoFullName, gateCheckMode: "enabled", reviewCheckMode: "required", aiReviewMode: "advisory" });
let posted = false;
vi.stubGlobal("fetch", async (input: RequestInfo | URL) => {
if (input.toString().includes("/comments")) posted = true;
@@ -26507,7 +26507,7 @@ describe("queue processors", () => {
const owner = repoFullName.slice(0, slash);
const name = repoFullName.slice(slash + 1);
await upsertRepositoryFromGitHub(env, { name, full_name: repoFullName, private: false, owner: { login: owner } }, 123);
- await upsertRepositorySettings(env, { repoFullName, commentMode: "off", publicSurface: "off", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", requireLinkedIssue: false, linkedIssueGateMode: "advisory", aiReviewMode: "advisory" });
+ await upsertRepositorySettings(env, { repoFullName, commentMode: "off", publicSurface: "off", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", reviewCheckMode: "required", requireLinkedIssue: false, linkedIssueGateMode: "advisory", aiReviewMode: "advisory" });
await upsertPullRequestFromGitHub(env, repoFullName, { number: prNumber, title: "Add retry to checkout", state: "open", user: { login: authorLogin }, author_association: "CONTRIBUTOR", head: { sha: headSha, ref: opts.headRef ?? "feature/checkout-retry" }, labels: [], body: "Retries the payment call once on a 5xx." });
await upsertPullRequestFile(env, { repoFullName, pullNumber: prNumber, path: "src/checkout.ts", status: "modified", additions: 3, deletions: 0, changes: 3, payload: { patch: "+function retryPayment() {\n+ return true;\n+}" } });
// A renamed-with-no-patch file (GitHub omits `patch` for pure renames) -- exercises the
@@ -26657,7 +26657,7 @@ describe("queue processors", () => {
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem(), AI: { run } as unknown as Ai, GITTENSORY_REVIEW_E2E_TESTS: "true", AI_SUMMARIES_ENABLED: "true", AI_PUBLIC_COMMENTS_ENABLED: "true" });
const slash = repoFullName.indexOf("/");
await upsertRepositoryFromGitHub(env, { name: repoFullName.slice(slash + 1), full_name: repoFullName, private: false, owner: { login: repoFullName.slice(0, slash) } }, 123);
- await upsertRepositorySettings(env, { repoFullName, commentMode: "off", publicSurface: "off", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", requireLinkedIssue: false, linkedIssueGateMode: "advisory", aiReviewMode: "advisory" });
+ await upsertRepositorySettings(env, { repoFullName, commentMode: "off", publicSurface: "off", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", reviewCheckMode: "required", requireLinkedIssue: false, linkedIssueGateMode: "advisory", aiReviewMode: "advisory" });
await upsertPullRequestFromGitHub(env, repoFullName, { number: 4198, title: "x", state: "open", user: { login: "contributor" }, author_association: "CONTRIBUTOR", head: { sha: "gen-tests-4195-disabled" }, labels: [], body: "x" });
// Deliberately no upsertRepoFocusManifest features.e2eTests override -- stays off (no allowlist either).
let postedBody = "";
@@ -26776,7 +26776,7 @@ describe("queue processors", () => {
// aiReviewProvider set AND matching the stored key's provider -- exercises the "explicit provider
// pin agrees with the stored key" arm, distinct from the (also-tested-elsewhere) "no pin configured"
// default arm.
- await upsertRepositorySettings(env, { repoFullName, commentMode: "off", publicSurface: "off", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", requireLinkedIssue: false, linkedIssueGateMode: "advisory", aiReviewMode: "advisory", aiReviewByok: true, aiReviewProvider: "anthropic" });
+ await upsertRepositorySettings(env, { repoFullName, commentMode: "off", publicSurface: "off", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", reviewCheckMode: "required", requireLinkedIssue: false, linkedIssueGateMode: "advisory", aiReviewMode: "advisory", aiReviewByok: true, aiReviewProvider: "anthropic" });
await upsertRepositoryAiKey(env, { repoFullName, provider: "anthropic", key: "sk-ant-byok-gen-tests-9999", model: null });
let postedBody = "";
const fetchMock = vi.fn(async (input: RequestInfo | URL, init?: RequestInit) => {
@@ -26835,7 +26835,7 @@ describe("queue processors", () => {
});
const slash = repoFullName.indexOf("/");
await upsertRepositoryFromGitHub(env, { name: repoFullName.slice(slash + 1), full_name: repoFullName, private: false, owner: { login: repoFullName.slice(0, slash) } }, 123);
- await upsertRepositorySettings(env, { repoFullName, commentMode: "off", publicSurface: "off", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", requireLinkedIssue: false, linkedIssueGateMode: "advisory", aiReviewMode: "advisory" });
+ await upsertRepositorySettings(env, { repoFullName, commentMode: "off", publicSurface: "off", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", reviewCheckMode: "required", requireLinkedIssue: false, linkedIssueGateMode: "advisory", aiReviewMode: "advisory" });
await upsertPullRequestFromGitHub(env, repoFullName, { number: 4205, title: "Add retry to checkout", state: "open", user: { login: "contributor" }, author_association: "CONTRIBUTOR", head: { sha: "gen-tests-4195-allowlist" }, labels: [], body: "x" });
await upsertPullRequestFile(env, { repoFullName, pullNumber: 4205, path: "src/checkout.ts", status: "modified", additions: 3, deletions: 0, changes: 3, payload: { patch: "+function retryPayment() {\n+ return true;\n+}" } });
let postedBody = "";
@@ -26983,7 +26983,7 @@ describe("queue processors", () => {
});
const slash = repoFullName.indexOf("/");
await upsertRepositoryFromGitHub(env, { name: repoFullName.slice(slash + 1), full_name: repoFullName, private: false, owner: { login: repoFullName.slice(0, slash) } }, 123);
- await upsertRepositorySettings(env, { repoFullName, commentMode: "off", publicSurface: "off", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", requireLinkedIssue: false, linkedIssueGateMode: "advisory", aiReviewMode: "advisory" });
+ await upsertRepositorySettings(env, { repoFullName, commentMode: "off", publicSurface: "off", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", reviewCheckMode: "required", requireLinkedIssue: false, linkedIssueGateMode: "advisory", aiReviewMode: "advisory" });
// No head sha/ref cached at all on this PR record.
await upsertPullRequestFromGitHub(env, repoFullName, { number: 4210, title: "Add retry to checkout", state: "open", user: { login: "contributor" }, author_association: "CONTRIBUTOR", labels: [], body: "x" });
await upsertPullRequestFile(env, { repoFullName, pullNumber: 4210, path: "src/checkout.ts", status: "modified", additions: 3, deletions: 0, changes: 3, payload: { patch: "+function retryPayment() {\n+ return true;\n+}" } });
@@ -27049,7 +27049,7 @@ describe("queue processors", () => {
});
const slash = repoFullName.indexOf("/");
await upsertRepositoryFromGitHub(env, { name: repoFullName.slice(slash + 1), full_name: repoFullName, private: false, owner: { login: repoFullName.slice(0, slash) } }, 123);
- await upsertRepositorySettings(env, { repoFullName, commentMode: "off", publicSurface: "off", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", requireLinkedIssue: false, linkedIssueGateMode: "advisory", aiReviewMode: "advisory" });
+ await upsertRepositorySettings(env, { repoFullName, commentMode: "off", publicSurface: "off", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", reviewCheckMode: "required", requireLinkedIssue: false, linkedIssueGateMode: "advisory", aiReviewMode: "advisory" });
// Deliberately no `user` field at all -- the cached PR's authorLogin resolves to null, exercising the
// ternary's not-found arm (`pr.authorLogin ? ... : { status: "not_found" }`) instead of ever calling
// getCachedOfficialMinerDetection.
@@ -27084,7 +27084,7 @@ describe("queue processors", () => {
const run = vi.fn();
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem(), AI: { run } as unknown as Ai, GITTENSORY_REVIEW_E2E_TESTS: "true", AI_SUMMARIES_ENABLED: "true", AI_PUBLIC_COMMENTS_ENABLED: "true" });
await seedGenerateTestsPr(env, repoFullName, 4211, "dryrun-head-sha", "contributor", { headRef: "feature/checkout-retry", e2eTestDelivery: "commit" });
- await upsertRepositorySettings(env, { repoFullName, commentMode: "off", publicSurface: "off", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", requireLinkedIssue: false, linkedIssueGateMode: "advisory", aiReviewMode: "advisory", agentDryRun: true });
+ await upsertRepositorySettings(env, { repoFullName, commentMode: "off", publicSurface: "off", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", reviewCheckMode: "required", requireLinkedIssue: false, linkedIssueGateMode: "advisory", aiReviewMode: "advisory", agentDryRun: true });
vi.stubGlobal("fetch", async (input: RequestInfo | URL) => {
const url = input.toString();
if (url.includes("/access_tokens")) return Response.json({ token: "installation-token" });
@@ -27106,7 +27106,7 @@ describe("queue processors", () => {
const run = vi.fn();
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem(), AI: { run } as unknown as Ai, GITTENSORY_REVIEW_E2E_TESTS: "true", AI_SUMMARIES_ENABLED: "true", AI_PUBLIC_COMMENTS_ENABLED: "true" });
await seedGenerateTestsPr(env, repoFullName, 4212, "paused-head-sha", "contributor", { headRef: "feature/checkout-retry", e2eTestDelivery: "commit" });
- await upsertRepositorySettings(env, { repoFullName, commentMode: "off", publicSurface: "off", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", requireLinkedIssue: false, linkedIssueGateMode: "advisory", aiReviewMode: "advisory", agentPaused: true });
+ await upsertRepositorySettings(env, { repoFullName, commentMode: "off", publicSurface: "off", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", reviewCheckMode: "required", requireLinkedIssue: false, linkedIssueGateMode: "advisory", aiReviewMode: "advisory", agentPaused: true });
vi.stubGlobal("fetch", async (input: RequestInfo | URL) => {
const url = input.toString();
if (url.includes("/access_tokens")) return Response.json({ token: "installation-token" });
@@ -27147,11 +27147,11 @@ describe("queue processors", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- // "enabled" (not "off") -- resolveRepositorySettings derives reviewCheckMode: "required" from this
- // when reviewCheckMode itself is unset, and gateEnabled (which the whole manifestPolicyGateMode block
- // this auto-trigger lives inside is downstream of) requires a truthy reviewCheckMode + a headSha. With
- // gateCheckMode: "off" the function bails out via its own early-return before ever reaching guidance.
- gateCheckMode: "enabled",
+ // reviewCheckMode: "required" (not "disabled") -- gateEnabled (which the whole manifestPolicyGateMode
+ // block this auto-trigger lives inside is downstream of) requires a truthy reviewCheckMode + a headSha.
+ // With reviewCheckMode: "disabled" the function bails out via its own early-return before ever reaching
+ // guidance.
+ gateCheckMode: "enabled", reviewCheckMode: "required",
requireLinkedIssue: false,
linkedIssueGateMode: "off",
manifestPolicyGateMode: opts.manifestPolicyGateMode ?? "advisory",
@@ -27442,7 +27442,7 @@ describe("queue processors", () => {
const run = vi.fn();
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem(), AI: { run } as unknown as Ai, GITTENSORY_REVIEW_E2E_TESTS: "true", AI_SUMMARIES_ENABLED: "true", AI_PUBLIC_COMMENTS_ENABLED: "true" });
await seedAutoTriggerPr(env, repoFullName, 5008, "auto-4196-paused-sha");
- await upsertRepositorySettings(env, { repoFullName, commentMode: "off", publicSurface: "off", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", requireLinkedIssue: false, linkedIssueGateMode: "off", manifestPolicyGateMode: "advisory", aiReviewMode: "off", agentPaused: true });
+ await upsertRepositorySettings(env, { repoFullName, commentMode: "off", publicSurface: "off", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", reviewCheckMode: "required", requireLinkedIssue: false, linkedIssueGateMode: "off", manifestPolicyGateMode: "advisory", aiReviewMode: "off", agentPaused: true });
const posted = { count: 0, body: "" };
stubAutoTriggerFetch(5008, posted);
@@ -27459,7 +27459,7 @@ describe("queue processors", () => {
const run = vi.fn();
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem(), AI: { run } as unknown as Ai, GITTENSORY_REVIEW_E2E_TESTS: "true", AI_SUMMARIES_ENABLED: "true", AI_PUBLIC_COMMENTS_ENABLED: "true" });
await seedAutoTriggerPr(env, repoFullName, 5009, "auto-4196-dryrun-sha");
- await upsertRepositorySettings(env, { repoFullName, commentMode: "off", publicSurface: "off", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", requireLinkedIssue: false, linkedIssueGateMode: "off", manifestPolicyGateMode: "advisory", aiReviewMode: "off", agentDryRun: true });
+ await upsertRepositorySettings(env, { repoFullName, commentMode: "off", publicSurface: "off", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", reviewCheckMode: "required", requireLinkedIssue: false, linkedIssueGateMode: "off", manifestPolicyGateMode: "advisory", aiReviewMode: "off", agentDryRun: true });
const posted = { count: 0, body: "" };
stubAutoTriggerFetch(5009, posted);
@@ -27482,7 +27482,7 @@ describe("queue processors", () => {
});
const slash = repoFullName.indexOf("/");
await upsertRepositoryFromGitHub(env, { name: repoFullName.slice(slash + 1), full_name: repoFullName, private: false, owner: { login: repoFullName.slice(0, slash) } }, 123);
- await upsertRepositorySettings(env, { repoFullName, commentMode: "off", publicSurface: "off", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", requireLinkedIssue: false, linkedIssueGateMode: "off", manifestPolicyGateMode: "advisory", aiReviewMode: "off" });
+ await upsertRepositorySettings(env, { repoFullName, commentMode: "off", publicSurface: "off", autoLabelEnabled: false, checkRunMode: "off", gateCheckMode: "enabled", reviewCheckMode: "required", requireLinkedIssue: false, linkedIssueGateMode: "off", manifestPolicyGateMode: "advisory", aiReviewMode: "off" });
// Deliberately no `user` field at all -- authorLogin resolves to null, exercising the `author ?? "the PR
// author"` fallback arm (the explicit command's own `actor` is always a real commenter login, so this
// branch is reachable only from the auto-trigger, which has no comment-invoker to fall back on).
@@ -27891,7 +27891,7 @@ describe("queue processors", () => {
// never computed at all when the gate is off, silently falling back to the legacy panel (which has
// neither the Test coverage collapsible nor the generate-tests checkbox). Mirrors the settings shape
// of the pre-existing "renders the unified PR-review comment..." test above.
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
requireLinkedIssue: false,
linkedIssueGateMode: "off",
manifestPolicyGateMode: "advisory",
@@ -28153,7 +28153,7 @@ describe("queue processors", () => {
autoLabelEnabled: true,
createMissingLabel: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
aiReviewMode: "off",
});
@@ -28188,7 +28188,7 @@ describe("queue processors", () => {
autoLabelEnabled: false,
createMissingLabel: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
aiReviewMode: "off",
});
@@ -28253,7 +28253,7 @@ describe("queue processors", () => {
// (which has the gate off, so it returns before ever reaching the type-label decision): with the
// gate ENABLED, the function does NOT bail out early, so this is the only path that actually
// exercises `decision.skipReason === "not_official_gittensor_miner"` at the type-label gate.
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
aiReviewMode: "off",
});
@@ -28289,7 +28289,7 @@ describe("queue processors", () => {
typeLabelsEnabled: false,
createMissingLabel: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
aiReviewMode: "off",
});
@@ -28324,7 +28324,7 @@ describe("queue processors", () => {
includeMaintainerAuthors: false,
createMissingLabel: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
aiReviewMode: "off",
});
@@ -28357,7 +28357,7 @@ describe("queue processors", () => {
autoLabelEnabled: true,
createMissingLabel: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
aiReviewMode: "off",
});
@@ -28390,7 +28390,7 @@ describe("queue processors", () => {
autoLabelEnabled: true,
createMissingLabel: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
aiReviewMode: "off",
// A self-host taxonomy well beyond the built-in bug/feature/priority triad (#label-modularity):
@@ -28428,7 +28428,7 @@ describe("queue processors", () => {
autoLabelEnabled: true,
createMissingLabel: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
aiReviewMode: "off",
});
@@ -28461,7 +28461,7 @@ describe("queue processors", () => {
typeLabelsEnabled: false,
createMissingLabel: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
aiReviewMode: "off",
});
@@ -28562,7 +28562,7 @@ describe("queue processors", () => {
autoLabelEnabled: true,
createMissingLabel: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
aiReviewMode: "off",
linkedIssueLabelPropagation: {
@@ -28678,7 +28678,7 @@ describe("queue processors", () => {
autoLabelEnabled: true,
createMissingLabel: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
aiReviewMode: "off",
linkedIssueLabelPropagation: {
@@ -28724,7 +28724,7 @@ describe("queue processors", () => {
autoLabelEnabled: true,
createMissingLabel: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
aiReviewMode: "off",
// linkedIssueLabelPropagation intentionally omitted -- defaults to disabled.
@@ -28759,7 +28759,7 @@ describe("queue processors", () => {
autoLabelEnabled: true,
createMissingLabel: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
aiReviewMode: "off",
});
@@ -28796,7 +28796,7 @@ describe("queue processors", () => {
autoLabelEnabled: true,
createMissingLabel: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
aiReviewMode: "off",
});
@@ -28831,7 +28831,7 @@ describe("queue processors", () => {
typeLabelsEnabled: false,
createMissingLabel: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "off",
aiReviewMode: "off",
});
@@ -29012,7 +29012,7 @@ describe("agentMaintenanceHeadMatchesGate", () => {
publicSurface: "off",
autoLabelEnabled: false,
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
autonomy: { merge: "auto", approve: "auto", close: "auto" },
});
vi.stubGlobal("fetch", async (input: RequestInfo | URL) => {
@@ -29784,7 +29784,7 @@ describe("converted_to_draft gate-close (draft-dodge prevention)", () => {
});
await upsertRepositorySettings(env, {
repoFullName: "JSONbored/gittensory",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
autonomy: { close: "auto" },
agentPaused: false,
...overrides,
@@ -29912,7 +29912,7 @@ describe("converted_to_draft gate-close (draft-dodge prevention)", () => {
},
repositories: [{ name: "gittensory", full_name: "JSONbored/gittensory", private: false, owner: { login: "JSONbored" } }],
});
- await upsertRepositorySettings(env, { repoFullName: "JSONbored/gittensory", gateCheckMode: "enabled", autonomy: { close: "auto" }, agentPaused: false });
+ await upsertRepositorySettings(env, { repoFullName: "JSONbored/gittensory", gateCheckMode: "enabled", reviewCheckMode: "required", autonomy: { close: "auto" }, agentPaused: false });
await recordGateBlockOutcome(env, { repoFullName: "JSONbored/gittensory", pullNumber: 42, headSha: "abc123", blockerCodes: ["missing_linked_issue"] });
await processJob(env, { type: "github-webhook", deliveryId: "draft-dodge-no-write", eventName: "pull_request", payload: draftPayload("contributor") });
@@ -29942,7 +29942,7 @@ describe("converted_to_draft gate-close (draft-dodge prevention)", () => {
// No installations row pre-seeded. processGitHubWebhook auto-upserts one from the payload's bare
// `installation: { id: 123 }` (no permissions field, as a real pull_request payload carries), so the
// resulting row has no explicit pull_requests:write grant — the permission check must fail CLOSED (deny).
- await upsertRepositorySettings(env, { repoFullName: "JSONbored/gittensory", gateCheckMode: "enabled", autonomy: { close: "auto" }, agentPaused: false });
+ await upsertRepositorySettings(env, { repoFullName: "JSONbored/gittensory", gateCheckMode: "enabled", reviewCheckMode: "required", autonomy: { close: "auto" }, agentPaused: false });
await recordGateBlockOutcome(env, { repoFullName: "JSONbored/gittensory", pullNumber: 42, headSha: "abc123", blockerCodes: ["missing_linked_issue"] });
await processJob(env, { type: "github-webhook", deliveryId: "draft-dodge-no-install-row", eventName: "pull_request", payload: draftPayload("contributor") });
@@ -29976,7 +29976,7 @@ describe("converted_to_draft gate-close (draft-dodge prevention)", () => {
},
repositories: [{ name: "gittensory", full_name: "JSONbored/gittensory", private: false, owner: { login: "JSONbored" } }],
});
- await upsertRepositorySettings(env, { repoFullName: "JSONbored/gittensory", gateCheckMode: "enabled", autonomy: { close: "auto" }, agentPaused: false });
+ await upsertRepositorySettings(env, { repoFullName: "JSONbored/gittensory", gateCheckMode: "enabled", reviewCheckMode: "required", autonomy: { close: "auto" }, agentPaused: false });
await recordGateBlockOutcome(env, { repoFullName: "JSONbored/gittensory", pullNumber: 42, headSha: "abc123", blockerCodes: ["missing_linked_issue"] });
// First getInstallation call in processGitHubWebhook (installationActor derivation, unrelated to this fix)
// resolves normally; the SECOND call is the draft-dodge readiness check itself -- that one is a genuine D1
@@ -30362,7 +30362,7 @@ describe("converted_to_draft gate-close (draft-dodge prevention)", () => {
});
await upsertRepositorySettings(env, {
repoFullName: "noslash",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
autonomy: { close: "auto" },
agentPaused: false,
});
@@ -32876,7 +32876,7 @@ describe("auto-action convergence: end-to-end plan+execute for the general heuri
commentMode: "off",
publicSurface: "off",
checkRunMode: "off",
- gateCheckMode: "enabled",
+ gateCheckMode: "enabled", reviewCheckMode: "required",
linkedIssueGateMode: "block", // the default blocker mechanism for these tests: missing linked issue -> gate failure
...settingsOverrides,
});
diff --git a/test/unit/repo-profile.test.ts b/test/unit/repo-profile.test.ts
index 52aa4d1438..eb1cb63786 100644
--- a/test/unit/repo-profile.test.ts
+++ b/test/unit/repo-profile.test.ts
@@ -42,7 +42,7 @@ describe("extractRepoProfile (#2999)", () => {
scripts: { test: "vitest run", "test:coverage": "vitest run --coverage", lint: "eslint .", build: "tsc" },
}),
);
- await upsertRepositorySettings(env, { repoFullName: REPO, gateCheckMode: "enabled", requireLinkedIssue: true });
+ await upsertRepositorySettings(env, { repoFullName: REPO, reviewCheckMode: "required", requireLinkedIssue: true });
await upsertRepoFocusManifest(env, REPO, { linkedIssuePolicy: "required" });
const profile = await extractRepoProfile(env, REPO, { now: "2026-07-05T00:00:00.000Z" });
diff --git a/test/unit/repository-settings-review-check-mode.test.ts b/test/unit/repository-settings-review-check-mode.test.ts
index f3fd54147e..434c537c62 100644
--- a/test/unit/repository-settings-review-check-mode.test.ts
+++ b/test/unit/repository-settings-review-check-mode.test.ts
@@ -2,12 +2,12 @@ import { describe, expect, it } from "vitest";
import { getRepositorySettings, upsertRepositorySettings } from "../../src/db/repositories";
import { createTestEnv } from "../helpers/d1";
-// #2852: reviewCheckMode is the new, more expressive axis for the "Gittensory Orb Review Agent" check-run
-// publish decision (required/visible/disabled), replacing gateCheckMode (off/enabled) as the runtime authority
-// while gateCheckMode itself stays wired for API/back-compat display. These tests pin the default + the
-// same-call legacy-write derivation that lets a caller who only ever sets gateCheckMode keep its historical
-// effect without touching reviewCheckMode at all.
-describe("repository_settings: reviewCheckMode default + legacy gateCheckMode derivation (#2852)", () => {
+// #2852/#4618: reviewCheckMode is the sole runtime authority for the "Gittensory Orb Review Agent" check-run
+// publish decision (required/visible/disabled). gateCheckMode (off/enabled) is deprecated: a computed
+// read-back value only, derived from reviewCheckMode on every read, and it has NO effect as a write input to
+// upsertRepositorySettings -- the legacy dual-write sync now lives only at the yml settings.gateCheckMode
+// parse step (packages/gittensory-engine/src/focus-manifest.ts), not in the DB/API layer.
+describe("repository_settings: reviewCheckMode default + gateCheckMode read-only derivation (#2852, #4618)", () => {
it("getRepositorySettings returns disabled for a repo with no DB row at all (conservative, opt-in default)", async () => {
const env = createTestEnv();
const settings = await getRepositorySettings(env, "acme/brand-new-repo");
@@ -22,12 +22,12 @@ describe("repository_settings: reviewCheckMode default + legacy gateCheckMode de
expect(settings.reviewCheckMode).toBe("disabled");
});
- it("a caller that sets ONLY gateCheckMode: enabled (never touching reviewCheckMode) still gets the check published (legacy-write compatibility)", async () => {
+ it("a caller that sets ONLY gateCheckMode: enabled (never touching reviewCheckMode) is ignored -- gateCheckMode is not a write input", async () => {
const env = createTestEnv();
await upsertRepositorySettings(env, { repoFullName: "acme/legacy-enable", gateCheckMode: "enabled" });
const settings = await getRepositorySettings(env, "acme/legacy-enable");
- expect(settings.reviewCheckMode).toBe("required");
- expect(settings.gateCheckMode).toBe("enabled");
+ expect(settings.reviewCheckMode).toBe("disabled");
+ expect(settings.gateCheckMode).toBe("off"); // re-derived from reviewCheckMode, not the caller's stale input
});
it("a caller that sets ONLY gateCheckMode: off (never touching reviewCheckMode) stays disabled", async () => {
@@ -37,11 +37,20 @@ describe("repository_settings: reviewCheckMode default + legacy gateCheckMode de
expect(settings.reviewCheckMode).toBe("disabled");
});
- it("an explicit reviewCheckMode wins over gateCheckMode when both are set in the same call", async () => {
+ it("reviewCheckMode is honored regardless of a gateCheckMode also passed in the same call (gateCheckMode is a no-op input)", async () => {
const env = createTestEnv();
await upsertRepositorySettings(env, { repoFullName: "acme/explicit-wins", gateCheckMode: "off", reviewCheckMode: "visible" });
const settings = await getRepositorySettings(env, "acme/explicit-wins");
expect(settings.reviewCheckMode).toBe("visible");
+ expect(settings.gateCheckMode).toBe("enabled"); // derived from reviewCheckMode ("visible" !== "disabled"), not the "off" input
+ });
+
+ it("gateCheckMode self-heals on read even if a pre-#4618 row has a stale/divergent gate_check_mode column", async () => {
+ const env = createTestEnv();
+ await upsertRepositorySettings(env, { repoFullName: "acme/stale-column", reviewCheckMode: "required" });
+ await env.DB.prepare("UPDATE repository_settings SET gate_check_mode = ? WHERE repo_full_name = ?").bind("off", "acme/stale-column").run();
+ const settings = await getRepositorySettings(env, "acme/stale-column");
+ expect(settings.gateCheckMode).toBe("enabled"); // ignores the stale DB column, derives from reviewCheckMode
});
it("an explicit required/visible/disabled opt-in round-trips through a re-upsert that carries it forward explicitly", async () => {
diff --git a/test/unit/routes-ai-byok.test.ts b/test/unit/routes-ai-byok.test.ts
index 35084d2bc9..6bb6f38e6e 100644
--- a/test/unit/routes-ai-byok.test.ts
+++ b/test/unit/routes-ai-byok.test.ts
@@ -32,7 +32,7 @@ describe("maintainer AI-review config route", () => {
it("sets mode/byok/provider/model and preserves unrelated settings", async () => {
const app = createApp();
const env = createTestEnv({ TOKEN_ENCRYPTION_SECRET: SECRET });
- await upsertRepositorySettings(env, { repoFullName: REPO, gateCheckMode: "enabled", gittensorLabel: "custom-label", blacklistLabel: "abuse" });
+ await upsertRepositorySettings(env, { repoFullName: REPO, reviewCheckMode: "required", gittensorLabel: "custom-label", blacklistLabel: "abuse" });
const res = await app.request(
`/v1/repos/${REPO}/ai-review`,
{ method: "PUT", headers: apiHeaders(env), body: JSON.stringify({ mode: "block", byok: true, provider: "anthropic", model: "claude-3-5-sonnet-latest", allAuthors: true, closeOwnerAuthors: true }) },
@@ -96,7 +96,7 @@ describe("maintainer AI-review config route", () => {
it("sets aiReviewLowConfidenceDisposition (#4603) and preserves unrelated settings", async () => {
const app = createApp();
const env = createTestEnv({ TOKEN_ENCRYPTION_SECRET: SECRET });
- await upsertRepositorySettings(env, { repoFullName: REPO, gateCheckMode: "enabled", gittensorLabel: "custom-label" });
+ await upsertRepositorySettings(env, { repoFullName: REPO, reviewCheckMode: "required", gittensorLabel: "custom-label" });
const res = await app.request(
`/v1/repos/${REPO}/ai-review`,
{ method: "PUT", headers: apiHeaders(env), body: JSON.stringify({ mode: "block", byok: false, lowConfidenceDisposition: "advisory_only" }) },
@@ -149,10 +149,10 @@ describe("maintainer AI-review config route", () => {
it("lets maintainer settings set closeOwnerAuthors without resetting unrelated fields", async () => {
const app = createApp();
const env = createTestEnv({ TOKEN_ENCRYPTION_SECRET: SECRET });
- await upsertRepositorySettings(env, { repoFullName: REPO, gateCheckMode: "enabled", gittensorLabel: "custom-label" });
+ await upsertRepositorySettings(env, { repoFullName: REPO, reviewCheckMode: "required", gittensorLabel: "custom-label" });
const res = await app.request(`/v1/repos/${REPO}/settings`, { method: "PUT", headers: apiHeaders(env), body: JSON.stringify({ closeOwnerAuthors: true }) }, env);
expect(res.status).toBe(200);
- expect(await res.json()).toMatchObject({ closeOwnerAuthors: true, gateCheckMode: "enabled", gittensorLabel: "custom-label" });
+ expect(await res.json()).toMatchObject({ closeOwnerAuthors: true, reviewCheckMode: "required", gittensorLabel: "custom-label" });
const settings = await getRepositorySettings(env, REPO);
expect(settings.closeOwnerAuthors).toBe(true);
expect(settings.gateCheckMode).toBe("enabled");
diff --git a/test/unit/safety.test.ts b/test/unit/safety.test.ts
index c869425c9f..759e8eb857 100644
--- a/test/unit/safety.test.ts
+++ b/test/unit/safety.test.ts
@@ -68,6 +68,7 @@ async function seedGateEnabledRepo(env: Env): Promise {
autoLabelEnabled: false,
checkRunMode: "off",
gateCheckMode: "enabled",
+ reviewCheckMode: "required",
slopGateMode: "advisory", // turns the shared gateFiles load on so the reuse branch is hit
});
await upsertOfficialMinerDetection(env, "contributor", { status: "confirmed", snapshot: safetyMinerSnapshot("contributor") }, 60_000);