diff --git a/apps/loopover-ui/content/docs/self-hosting-github-app.mdx b/apps/loopover-ui/content/docs/self-hosting-github-app.mdx index 0a04dc949c..5888624e17 100644 --- a/apps/loopover-ui/content/docs/self-hosting-github-app.mdx +++ b/apps/loopover-ui/content/docs/self-hosting-github-app.mdx @@ -86,7 +86,8 @@ the URL. behavior change — the cancellation attempt is skipped and logged, never blocking the close itself. -Events: pull request, pull request review, push, issues, check suite, check run, and status. +Events: pull request, pull request review, pull request review thread, push, issues, issue comment, +repository, check suite, check run, status, workflow run, and deployment status. ## Re-approving a permission bump on an existing App diff --git a/src/review/predicted-gate-agreement.ts b/src/review/predicted-gate-agreement.ts index 4214e49373..726ef4dfc6 100644 --- a/src/review/predicted-gate-agreement.ts +++ b/src/review/predicted-gate-agreement.ts @@ -1,6 +1,6 @@ // Predicted-vs-live gate agreement (#predicted-live-gate-agreement, maintainer review-stack x AMS integration // audit 2026-07-09) -- a SIBLING to computeGateEval/computeGateParity (src/review/parity.ts), answering a -// DIFFERENT question than either: not "does gittensory match reviewbot" (computeGateParity) and not "does one +// DIFFERENT question than either: not "does loopover match reviewbot" (computeGateParity) and not "does one // system's prediction match the human's realized merge/close" (computeGateEval), but "does the MCP predict_gate // tool's pre-submission verdict for a contributor match the REAL gate decision their eventual PR receives." // diff --git a/test/integration/api.test.ts b/test/integration/api.test.ts index 4dd61c511e..c7149b19e6 100644 --- a/test/integration/api.test.ts +++ b/test/integration/api.test.ts @@ -2354,7 +2354,9 @@ describe("api routes", () => { account: { login: "JSONbored", id: 1, type: "User" }, repository_selection: "selected", permissions: { metadata: "read", pull_requests: "write", issues: "write", checks: "write" }, - events: ["issues", "issue_comment", "pull_request", "repository", "installation_repositories"], + // #9169 promoted pull_request_review/check_run/check_suite to REQUIRED_INSTALLATION_EVENTS, so a + // "healthy" refresh now needs all of them subscribed, not just the pre-#9169 required set. + events: ["issues", "issue_comment", "pull_request", "pull_request_review", "repository", "check_run", "check_suite", "installation_repositories"], }); } return new Response("not found", { status: 404 }); diff --git a/test/unit/backfill.test.ts b/test/unit/backfill.test.ts index dfbe182504..a524c66ad0 100644 --- a/test/unit/backfill.test.ts +++ b/test/unit/backfill.test.ts @@ -676,7 +676,8 @@ describe("GitHub backfill", () => { account: { login: "JSONbored", id: 1, type: "User" }, repository_selection: "selected", permissions: { checks: "write", metadata: "read", pull_requests: "write", issues: "write" }, - events: ["issues", "issue_comment", "pull_request", "repository", "installation_repositories"], + // #9169 promoted pull_request_review/check_run/check_suite to REQUIRED_INSTALLATION_EVENTS. + events: ["issues", "issue_comment", "pull_request", "pull_request_review", "repository", "check_run", "check_suite", "installation_repositories"], }); } return new Response("not found", { status: 404 }); @@ -686,7 +687,7 @@ describe("GitHub backfill", () => { expect(result.installations[0]).toMatchObject({ status: "needs_attention", missingPermissions: ["pull_requests", "issues"], - missingEvents: ["issues", "issue_comment", "repository"], + missingEvents: ["issues", "issue_comment", "pull_request_review", "repository", "check_run", "check_suite"], repairSteps: expect.arrayContaining(["Update the GitHub App permissions and subscribed events."]), }); @@ -696,7 +697,7 @@ describe("GitHub backfill", () => { account: { login: "JSONbored", id: 1, type: "User" }, repository_selection: "selected", permissions: { checks: "write", metadata: "read", pull_requests: "write", issues: "write" }, - events: ["issues", "issue_comment", "pull_request", "repository", "installation_repositories"], + events: ["issues", "issue_comment", "pull_request", "pull_request_review", "repository", "check_run", "check_suite", "installation_repositories"], }, }); const refreshed = await refreshInstallationHealth(env); @@ -1358,7 +1359,8 @@ describe("GitHub backfill", () => { target_type: "User", repository_selection: "selected", permissions: { checks: "write", metadata: "read", pull_requests: "write", issues: "write" }, - events: ["issues", "issue_comment", "pull_request", "repository", "installation_repositories"], + // #9169 promoted pull_request_review/check_run/check_suite to REQUIRED_INSTALLATION_EVENTS. + events: ["issues", "issue_comment", "pull_request", "pull_request_review", "repository", "check_run", "check_suite", "installation_repositories"], }); } return new Response("not found", { status: 404 }); @@ -1386,7 +1388,7 @@ describe("GitHub backfill", () => { account: { login: "JSONbored", id: 1, type: "User" }, repository_selection: "selected", permissions: { metadata: "read", pull_requests: "write", issues: "write" }, - events: ["issues", "issue_comment", "pull_request", "repository", "installation_repositories"], + events: ["issues", "issue_comment", "pull_request", "pull_request_review", "repository", "check_run", "check_suite", "installation_repositories"], }); } return new Response("not found", { status: 404 }); @@ -4731,7 +4733,8 @@ describe("GitHub backfill", () => { permissions: {}, events: [], missingPermissions: ["metadata", "pull_requests", "issues"], - missingEvents: ["issues", "issue_comment", "pull_request", "repository"], + // #9169 promoted pull_request_review/check_run/check_suite to REQUIRED_INSTALLATION_EVENTS. + missingEvents: ["issues", "issue_comment", "pull_request", "pull_request_review", "repository", "check_run", "check_suite"], }), ]), );