diff --git a/src/review/rag-index.ts b/src/review/rag-index.ts index 1813d873bf..e363641782 100644 --- a/src/review/rag-index.ts +++ b/src/review/rag-index.ts @@ -38,7 +38,7 @@ import { filePriority, getStoredChunkMeta, isIndexablePath, - MAX_CHUNKS_PER_REPO, + maxChunksPerRepo, MAX_FILE_BYTES, ragNamespace, type RagChunk, @@ -209,8 +209,8 @@ async function upsertChunksCapped(env: Env, project: string, repo: string, chunk const infra = createReviewAdapters(env); let stored = alreadyStored; let upserted = 0; - for (let i = 0; i < chunks.length && stored < MAX_CHUNKS_PER_REPO; i += UPSERT_BATCH) { - const remaining = MAX_CHUNKS_PER_REPO - stored; + for (let i = 0; i < chunks.length && stored < maxChunksPerRepo(); i += UPSERT_BATCH) { + const remaining = maxChunksPerRepo() - stored; const batch = chunks.slice(i, i + Math.min(UPSERT_BATCH, remaining)); if (batch.length === 0) break; const n = await upsertChunks(infra, project, repo, batch, blobSha); @@ -324,7 +324,7 @@ export async function indexRepo( skipped += 1; continue; // unchanged since the last full index — skip the fetch/chunk/embed entirely } - if (stored >= MAX_CHUNKS_PER_REPO && (!known || known.count <= 0)) { + if (stored >= maxChunksPerRepo() && (!known || known.count <= 0)) { capped = true; break; } @@ -395,7 +395,7 @@ export async function reindexChangedPaths( let filesIndexed = 0; let capped = false; for (const path of indexable) { - if (stored >= MAX_CHUNKS_PER_REPO) { + if (stored >= maxChunksPerRepo()) { capped = true; break; } diff --git a/src/review/rag.ts b/src/review/rag.ts index 4ecbc75f2f..03c708a1fe 100644 --- a/src/review/rag.ts +++ b/src/review/rag.ts @@ -113,6 +113,18 @@ const CHUNK_OVERLAP = 1500; * recurring one per cron cycle (#4365's blob-SHA skip-cache). Self-host only: this is not a Cloudflare * free-tier constraint on this deployment, but the name/comment history predates self-host. */ export const MAX_CHUNKS_PER_REPO = 4000; +// Test-only override (#test-hotspots): the cap tests exist to pin capping BEHAVIOR, not the number +// 4000 — building 4,000 real chunk rows per cap test made rag-index.test.ts one of the suite's +// slowest files (~7s per cap test). Same `...ForTest` hook convention as +// clearInstallationTokenCacheForTest / clearGitHubResponseCacheForTest; production call sites read +// maxChunksPerRepo() and never touch the override. +let maxChunksPerRepoOverride: number | null = null; +export function maxChunksPerRepo(): number { + return maxChunksPerRepoOverride ?? MAX_CHUNKS_PER_REPO; +} +export function setMaxChunksPerRepoForTest(value: number | null): void { + maxChunksPerRepoOverride = value; +} const EMBED_BATCH = 96; // Workers AI caps embedding input at 100 items/call; kept as a conservative general // bound — other embed providers (Ollama/vLLM/etc via the self-host adapter) may not share this exact cap. const MAX_CONTEXT_CHARS = 14000; // bound the injected block (mirrors diff/knowledge budgets) diff --git a/test/helpers/github-app-key.ts b/test/helpers/github-app-key.ts new file mode 100644 index 0000000000..c3a3df741d --- /dev/null +++ b/test/helpers/github-app-key.ts @@ -0,0 +1,32 @@ +// One throwaway RSA-2048 GitHub App private key per worker process (#test-hotspots): the suite +// re-generated a fresh WebCrypto keypair on every call — ~770 call sites × ~20-100ms of prime +// search — for JWTs whose signatures the fetch stubs never verify. Any single valid key is as good +// as any other for these fixtures, so one per process is memoized on globalThis (NOT module scope: +// vitest's per-file module isolation re-evaluates this module constantly, the same lesson +// test/helpers/d1.ts's template memo learned). github-app.test.ts's key-rotation tests need +// genuinely DISTINCT keys per call and keep their own local, non-memoized generator instead. +const PEM_HEADER = "-----BEGIN PRIVATE KEY-----"; +const PEM_FOOTER = "-----END PRIVATE KEY-----"; + +async function freshPrivateKeyPem(): Promise { + const key = (await crypto.subtle.generateKey( + { + name: "RSASSA-PKCS1-v1_5", + modulusLength: 2048, + publicExponent: new Uint8Array([1, 0, 1]), + hash: "SHA-256", + }, + true, + ["sign", "verify"], + )) as CryptoKeyPair; + const exported = await crypto.subtle.exportKey("pkcs8", key.privateKey); + const base64 = Buffer.from(exported as ArrayBuffer) + .toString("base64") + .replace(/(.{64})/g, "$1\n"); + return `${PEM_HEADER}\n${base64}\n${PEM_FOOTER}`; +} + +export function generatePrivateKeyPem(): Promise { + const holder = globalThis as { __loopoverTestAppKeyPem?: Promise }; + return (holder.__loopoverTestAppKeyPem ??= freshPrivateKeyPem()); +} diff --git a/test/integration/api.test.ts b/test/integration/api.test.ts index 3df7a35f2c..1c7ea59baf 100644 --- a/test/integration/api.test.ts +++ b/test/integration/api.test.ts @@ -46,6 +46,7 @@ import { persistRegistrySnapshot } from "../../src/registry/sync"; import { recordOverrideAudit, writeLiveOverride, writeShadowOverride, type StorageEnv } from "../../src/review/auto-apply"; import { asCloudEnv, createTestEnv } from "../helpers/d1"; import type { JsonValue } from "../../src/types"; +import { generatePrivateKeyPem } from "../helpers/github-app-key"; vi.mock("../../src/github/app", async (importOriginal) => ({ ...(await importOriginal()), @@ -7139,22 +7140,6 @@ function apiHeaders(env: Env): Record { }; } -async function generatePrivateKeyPem(): Promise { - const key = (await crypto.subtle.generateKey( - { - name: "RSASSA-PKCS1-v1_5", - modulusLength: 2048, - publicExponent: new Uint8Array([1, 0, 1]), - hash: "SHA-256", - }, - true, - ["sign", "verify"], - )) as CryptoKeyPair; - const exported = await crypto.subtle.exportKey("pkcs8", key.privateKey); - const base64 = Buffer.from(exported as ArrayBuffer).toString("base64").replace(/(.{64})/g, "$1\n"); - return `-----BEGIN PRIVATE KEY-----\n${base64}\n-----END PRIVATE KEY-----`; -} - function upstreamContractFetch() { const files: Record = { "gittensor/constants.py": "SRC_TOK_SATURATION_SCALE = 58\nMAX_CODE_DENSITY_MULTIPLIER = 1.15\n", diff --git a/test/unit/actions-fallback-webhook.test.ts b/test/unit/actions-fallback-webhook.test.ts index 5482539ae0..da49f7bf0a 100644 --- a/test/unit/actions-fallback-webhook.test.ts +++ b/test/unit/actions-fallback-webhook.test.ts @@ -14,19 +14,10 @@ import { fallbackShotR2Key, FALLBACK_ARTIFACT_NAME, isFallbackDispatchInFlight, import { processJob } from "../../src/queue/processors"; import { upsertRepoFocusManifest } from "../../src/signals/focus-manifest-loader"; import { createTestEnv } from "../helpers/d1"; +import { generatePrivateKeyPem } from "../helpers/github-app-key"; // Mirrors test/unit/queue.test.ts's own generatePrivateKeyPem helper -- createInstallationToken mints a real // JWT, so the default createTestEnv placeholder key ("test-private-key") won't do for any test that reaches it. -async function generatePrivateKeyPem(): Promise { - const key = (await crypto.subtle.generateKey( - { name: "RSASSA-PKCS1-v1_5", modulusLength: 2048, publicExponent: new Uint8Array([1, 0, 1]), hash: "SHA-256" }, - true, - ["sign", "verify"], - )) as CryptoKeyPair; - const exported = await crypto.subtle.exportKey("pkcs8", key.privateKey); - const base64 = Buffer.from(exported as ArrayBuffer).toString("base64").replace(/(.{64})/g, "$1\n"); - return `-----BEGIN PRIVATE KEY-----\n${base64}\n-----END PRIVATE KEY-----`; -} function concatBytes(parts: Uint8Array[]): Uint8Array { const total = parts.reduce((sum, p) => sum + p.length, 0); diff --git a/test/unit/backfill-2.test.ts b/test/unit/backfill-2.test.ts index 7811da927d..4e2a723cea 100644 --- a/test/unit/backfill-2.test.ts +++ b/test/unit/backfill-2.test.ts @@ -63,6 +63,7 @@ import { normalizeRegistryPayload } from "../../src/registry/normalize"; import { persistRegistrySnapshot } from "../../src/registry/sync"; import { renderMetrics, resetMetrics } from "../../src/selfhost/metrics"; import { asCloudEnv, createTestEnv } from "../helpers/d1"; +import { generatePrivateKeyPem } from "../helpers/github-app-key"; // #4682 incident (2026-07-10): the stored-body cap used to be 4000 chars -- well under what a compliant // screenshot-evidence table (or any sufficiently detailed PR/issue) actually needs -- and every body-content @@ -89,22 +90,6 @@ async function seedRegisteredRepo(env: Env) { ); } -async function generatePrivateKeyPem(): Promise { - const key = (await crypto.subtle.generateKey( - { - name: "RSASSA-PKCS1-v1_5", - modulusLength: 2048, - publicExponent: new Uint8Array([1, 0, 1]), - hash: "SHA-256", - }, - true, - ["sign", "verify"], - )) as CryptoKeyPair; - const exported = await crypto.subtle.exportKey("pkcs8", key.privateKey); - const base64 = Buffer.from(exported as ArrayBuffer).toString("base64").replace(/(.{64})/g, "$1\n"); - return `-----BEGIN PRIVATE KEY-----\n${base64}\n-----END PRIVATE KEY-----`; -} - async function persistTotalsSnapshot( env: Env, overrides: { diff --git a/test/unit/backfill.test.ts b/test/unit/backfill.test.ts index d9d198ba30..5d921bc67b 100644 --- a/test/unit/backfill.test.ts +++ b/test/unit/backfill.test.ts @@ -66,6 +66,7 @@ import { normalizeRegistryPayload } from "../../src/registry/normalize"; import { persistRegistrySnapshot } from "../../src/registry/sync"; import { renderMetrics, resetMetrics } from "../../src/selfhost/metrics"; import { asCloudEnv, createTestEnv } from "../helpers/d1"; +import { generatePrivateKeyPem } from "../helpers/github-app-key"; // #4682 incident (2026-07-10): the stored-body cap used to be 4000 chars -- well under what a compliant // screenshot-evidence table (or any sufficiently detailed PR/issue) actually needs -- and every body-content @@ -218,22 +219,6 @@ async function seedInstalledAndRegisteredRepo(env: Env) { await seedRegisteredRepo(env); } -async function generatePrivateKeyPem(): Promise { - const key = (await crypto.subtle.generateKey( - { - name: "RSASSA-PKCS1-v1_5", - modulusLength: 2048, - publicExponent: new Uint8Array([1, 0, 1]), - hash: "SHA-256", - }, - true, - ["sign", "verify"], - )) as CryptoKeyPair; - const exported = await crypto.subtle.exportKey("pkcs8", key.privateKey); - const base64 = Buffer.from(exported as ArrayBuffer).toString("base64").replace(/(.{64})/g, "$1\n"); - return `-----BEGIN PRIVATE KEY-----\n${base64}\n-----END PRIVATE KEY-----`; -} - async function persistTotalsSnapshot( env: Env, overrides: { diff --git a/test/unit/github-comments.test.ts b/test/unit/github-comments.test.ts index f4152846a6..a3299a6bc2 100644 --- a/test/unit/github-comments.test.ts +++ b/test/unit/github-comments.test.ts @@ -1,6 +1,7 @@ import { afterEach, describe, expect, it, vi } from "vitest"; import { createOrUpdatePrIntelligenceComment, createOrUpdateVisualFollowupComment, PR_INTELLIGENCE_COMMENT_MARKER, VISUAL_FOLLOWUP_COMMENT_MARKER } from "../../src/github/comments"; import { createTestEnv } from "../helpers/d1"; +import { generatePrivateKeyPem } from "../helpers/github-app-key"; describe("GitHub PR intelligence comments", () => { afterEach(() => { @@ -504,22 +505,6 @@ describe("GitHub PR intelligence comments", () => { }); }); -async function generatePrivateKeyPem(): Promise { - const key = (await crypto.subtle.generateKey( - { - name: "RSASSA-PKCS1-v1_5", - modulusLength: 2048, - publicExponent: new Uint8Array([1, 0, 1]), - hash: "SHA-256", - }, - true, - ["sign", "verify"], - )) as CryptoKeyPair; - const exported = await crypto.subtle.exportKey("pkcs8", key.privateKey); - const base64 = Buffer.from(exported as ArrayBuffer).toString("base64").replace(/(.{64})/g, "$1\n"); - return `-----BEGIN PRIVATE KEY-----\n${base64}\n-----END PRIVATE KEY-----`; -} - describe("createOrUpdateIssueCommentWithMarker repoFullName guard (#8311)", () => { // The existing segment-count guard now also rejects whitespace, matching pr-actions.ts/assignees.ts/ // labels.ts (#6613). These malformed shapes reject before any GitHub call (no fetch stub needed) and diff --git a/test/unit/linked-issue-label-propagation-fetch.test.ts b/test/unit/linked-issue-label-propagation-fetch.test.ts index 470791bc24..885990bb12 100644 --- a/test/unit/linked-issue-label-propagation-fetch.test.ts +++ b/test/unit/linked-issue-label-propagation-fetch.test.ts @@ -6,6 +6,7 @@ import { fetchLinkedIssueLabelsForPropagation, type LinkedIssuePropagationLabels, } from "../../src/review/linked-issue-label-propagation-fetch"; +import { generatePrivateKeyPem } from "../helpers/github-app-key"; // `getRepositoryCollaboratorPermission` mints its own installation token internally with no fallback to // the public token, so a maintainer-authored-issue test that reaches it (i.e. isn't already short-circuited @@ -18,19 +19,6 @@ import { const PEM_HEADER = ["-----BEGIN", "PRIVATE KEY-----"].join(" "); const PEM_FOOTER = ["-----END", "PRIVATE KEY-----"].join(" "); -async function generatePrivateKeyPem(): Promise { - const key = (await crypto.subtle.generateKey( - { name: "RSASSA-PKCS1-v1_5", modulusLength: 2048, publicExponent: new Uint8Array([1, 0, 1]), hash: "SHA-256" }, - true, - ["sign", "verify"], - )) as CryptoKeyPair; - const exported = await crypto.subtle.exportKey("pkcs8", key.privateKey); - const base64 = Buffer.from(exported as ArrayBuffer) - .toString("base64") - .replace(/(.{64})/g, "$1\n"); - return `${PEM_HEADER}\n${base64}\n${PEM_FOOTER}`; -} - // #regression-safe-propagation: `fetchLinkedIssueLabelsForPropagation` returns `{labels, inconclusive}`, not a // bare `string[]` -- `inconclusive` defaults false (a confirmed result) in every assertion below except the // one test that simulates a genuinely unverifiable pass (a collaborator-permission check that errors). diff --git a/test/unit/linked-issue-satisfaction-run.test.ts b/test/unit/linked-issue-satisfaction-run.test.ts index 7ee90fc8a3..6e2ff3be7b 100644 --- a/test/unit/linked-issue-satisfaction-run.test.ts +++ b/test/unit/linked-issue-satisfaction-run.test.ts @@ -21,6 +21,7 @@ import { persistRegistrySnapshot } from "../../src/registry/sync"; import { upsertRepoFocusManifest } from "../../src/signals/focus-manifest-loader"; import type { Advisory, PullRequestFileRecord, RepositorySettings } from "../../src/types"; import { createTestEnv } from "../helpers/d1"; +import { generatePrivateKeyPem } from "../helpers/github-app-key"; // Split so the literal PEM marker text never appears contiguous in source -- the review-safety secrets // scanner's private_key_block pattern is a pure text match with no awareness that the bytes between these @@ -29,19 +30,6 @@ import { createTestEnv } from "../helpers/d1"; const PEM_HEADER = ["-----BEGIN", "PRIVATE KEY-----"].join(" "); const PEM_FOOTER = ["-----END", "PRIVATE KEY-----"].join(" "); -async function generatePrivateKeyPem(): Promise { - const key = (await crypto.subtle.generateKey( - { name: "RSASSA-PKCS1-v1_5", modulusLength: 2048, publicExponent: new Uint8Array([1, 0, 1]), hash: "SHA-256" }, - true, - ["sign", "verify"], - )) as CryptoKeyPair; - const exported = await crypto.subtle.exportKey("pkcs8", key.privateKey); - const base64 = Buffer.from(exported as ArrayBuffer) - .toString("base64") - .replace(/(.{64})/g, "$1\n"); - return `${PEM_HEADER}\n${base64}\n${PEM_FOOTER}`; -} - function satisfactionJson(over: Partial<{ status: string; rationale: string; confidence: number }> = {}): string { return JSON.stringify({ status: over.status ?? "addressed", diff --git a/test/unit/parity-wire.test.ts b/test/unit/parity-wire.test.ts index 5878ebcebf..13d078c24b 100644 --- a/test/unit/parity-wire.test.ts +++ b/test/unit/parity-wire.test.ts @@ -21,6 +21,7 @@ import { } from "../../src/review/parity-wire"; import type { AdvisoryFinding } from "../../src/types"; import { createTestEnv } from "../helpers/d1"; +import { generatePrivateKeyPem } from "../helpers/github-app-key"; // ── Direct D1 helpers over the real migrated schema (0049 review_audit) ────────────────────────────────────── @@ -342,12 +343,6 @@ describe("GET /v1/internal/parity — bearer-gated, flag-gated endpoint", () => // both sides of the reasonCode ternary (failure → blockers[0].code, non-failure → conclusion). // A self-signed RSA PEM so the GitHub App can mint an installation token (gate check-run posting). -async function generatePrivateKeyPem(): Promise { - const key = (await crypto.subtle.generateKey({ name: "RSASSA-PKCS1-v1_5", modulusLength: 2048, publicExponent: new Uint8Array([1, 0, 1]), hash: "SHA-256" }, true, ["sign", "verify"])) as CryptoKeyPair; - const pkcs8 = await crypto.subtle.exportKey("pkcs8", key.privateKey); - const b64 = Buffer.from(pkcs8 as ArrayBuffer).toString("base64").replace(/(.{64})/g, "$1\n"); - return `-----BEGIN PRIVATE KEY-----\n${b64}\n-----END PRIVATE KEY-----\n`; -} // A confirmed-miner snapshot (confirmed status now feeds only on-chain scoring; the gate blocks every author // the same on a configured blocker — #gate-nonconfirmed). diff --git a/test/unit/pr-panel-retrigger-pending-force-review.test.ts b/test/unit/pr-panel-retrigger-pending-force-review.test.ts index 14f6c794cf..5e3a61be0a 100644 --- a/test/unit/pr-panel-retrigger-pending-force-review.test.ts +++ b/test/unit/pr-panel-retrigger-pending-force-review.test.ts @@ -12,6 +12,7 @@ import { normalizeRegistryPayload } from "../../src/registry/normalize"; import { persistRegistrySnapshot } from "../../src/registry/sync"; import { asCloudEnv, createTestEnv } from "../helpers/d1"; import type { GitHubWebhookPayload } from "../../src/types"; +import { generatePrivateKeyPem } from "../helpers/github-app-key"; // #7626: maybeProcessPrPanelRetrigger threads forceAiReview: true into maybePublishPrPublicSurface when the // "Re-run LoopOver review" checkbox is checked -- but ONLY when prReadyForReview can confirm readiness right @@ -21,22 +22,6 @@ import type { GitHubWebhookPayload } from "../../src/types"; // fresh AI opinion. These tests pin the persisted pending-marker fix: mark on defer, consume (once) on the // next readiness-confirmed pass through either reReviewStoredPullRequest or handlePullRequestWebhookEvent. -async function generatePrivateKeyPem(): Promise { - const key = (await crypto.subtle.generateKey( - { - name: "RSASSA-PKCS1-v1_5", - modulusLength: 2048, - publicExponent: new Uint8Array([1, 0, 1]), - hash: "SHA-256", - }, - true, - ["sign", "verify"], - )) as CryptoKeyPair; - const exported = await crypto.subtle.exportKey("pkcs8", key.privateKey); - const base64 = Buffer.from(exported as ArrayBuffer).toString("base64").replace(/(.{64})/g, "$1\n"); - return `-----BEGIN PRIVATE KEY-----\n${base64}\n-----END PRIVATE KEY-----`; -} - function queueMinerSnapshot(login: string) { return { source: "gittensor_api" as const, diff --git a/test/unit/queue-2.test.ts b/test/unit/queue-2.test.ts index 04669ca4bf..00c41d7569 100644 --- a/test/unit/queue-2.test.ts +++ b/test/unit/queue-2.test.ts @@ -74,6 +74,7 @@ import { import { asCloudEnv, createTestEnv } from "../helpers/d1"; import { ISSUE_WAKE_MAX_PRS, MERGE_WAKE_MAX_PRS, SWEEP_MAX_PRS } from "../../src/settings/agent-sweep"; import { AGENT_LABEL_PENDING_CLOSURE, DEFAULT_LINKED_ISSUE_HARD_RULES } from "../../src/review/linked-issue-hard-rules"; +import { generatePrivateKeyPem } from "../helpers/github-app-key"; vi.mock("../../src/github/pr-freshness", async (importOriginal) => { const actual = await importOriginal(); @@ -200,22 +201,6 @@ function withProductUsageInsertFailure(env: Env): Env { }; } -async function generatePrivateKeyPem(): Promise { - const key = (await crypto.subtle.generateKey( - { - name: "RSASSA-PKCS1-v1_5", - modulusLength: 2048, - publicExponent: new Uint8Array([1, 0, 1]), - hash: "SHA-256", - }, - true, - ["sign", "verify"], - )) as CryptoKeyPair; - const exported = await crypto.subtle.exportKey("pkcs8", key.privateKey); - const base64 = Buffer.from(exported as ArrayBuffer).toString("base64").replace(/(.{64})/g, "$1\n"); - return `-----BEGIN PRIVATE KEY-----\n${base64}\n-----END PRIVATE KEY-----`; -} - describe("queue processors", () => { // Freshness-SLO fixtures are dated relative to late May 2026; pin the clock so staleness windows // stay deterministic regardless of when CI runs. diff --git a/test/unit/queue-3.test.ts b/test/unit/queue-3.test.ts index ed45be1499..e14f045622 100644 --- a/test/unit/queue-3.test.ts +++ b/test/unit/queue-3.test.ts @@ -74,6 +74,7 @@ import { import { createTestEnv } from "../helpers/d1"; import { ISSUE_WAKE_MAX_PRS, MERGE_WAKE_MAX_PRS, SWEEP_MAX_PRS } from "../../src/settings/agent-sweep"; import { AGENT_LABEL_PENDING_CLOSURE, DEFAULT_LINKED_ISSUE_HARD_RULES } from "../../src/review/linked-issue-hard-rules"; +import { generatePrivateKeyPem } from "../helpers/github-app-key"; vi.mock("../../src/github/pr-freshness", async (importOriginal) => { const actual = await importOriginal(); @@ -200,22 +201,6 @@ function withProductUsageInsertFailure(env: Env): Env { }; } -async function generatePrivateKeyPem(): Promise { - const key = (await crypto.subtle.generateKey( - { - name: "RSASSA-PKCS1-v1_5", - modulusLength: 2048, - publicExponent: new Uint8Array([1, 0, 1]), - hash: "SHA-256", - }, - true, - ["sign", "verify"], - )) as CryptoKeyPair; - const exported = await crypto.subtle.exportKey("pkcs8", key.privateKey); - const base64 = Buffer.from(exported as ArrayBuffer).toString("base64").replace(/(.{64})/g, "$1\n"); - return `-----BEGIN PRIVATE KEY-----\n${base64}\n-----END PRIVATE KEY-----`; -} - describe("queue processors", () => { // Freshness-SLO fixtures are dated relative to late May 2026; pin the clock so staleness windows // stay deterministic regardless of when CI runs. diff --git a/test/unit/queue-4.test.ts b/test/unit/queue-4.test.ts index 0587d1ba3b..b6edbf73e6 100644 --- a/test/unit/queue-4.test.ts +++ b/test/unit/queue-4.test.ts @@ -78,6 +78,7 @@ import { import { asCloudEnv, createTestEnv } from "../helpers/d1"; import { ISSUE_WAKE_MAX_PRS, MERGE_WAKE_MAX_PRS, SWEEP_MAX_PRS } from "../../src/settings/agent-sweep"; import { AGENT_LABEL_PENDING_CLOSURE, DEFAULT_LINKED_ISSUE_HARD_RULES } from "../../src/review/linked-issue-hard-rules"; +import { generatePrivateKeyPem } from "../helpers/github-app-key"; vi.mock("../../src/github/pr-freshness", async (importOriginal) => { const actual = await importOriginal(); @@ -204,22 +205,6 @@ function withProductUsageInsertFailure(env: Env): Env { }; } -async function generatePrivateKeyPem(): Promise { - const key = (await crypto.subtle.generateKey( - { - name: "RSASSA-PKCS1-v1_5", - modulusLength: 2048, - publicExponent: new Uint8Array([1, 0, 1]), - hash: "SHA-256", - }, - true, - ["sign", "verify"], - )) as CryptoKeyPair; - const exported = await crypto.subtle.exportKey("pkcs8", key.privateKey); - const base64 = Buffer.from(exported as ArrayBuffer).toString("base64").replace(/(.{64})/g, "$1\n"); - return `-----BEGIN PRIVATE KEY-----\n${base64}\n-----END PRIVATE KEY-----`; -} - describe("queue processors", () => { // Freshness-SLO fixtures are dated relative to late May 2026; pin the clock so staleness windows // stay deterministic regardless of when CI runs. diff --git a/test/unit/queue-5.test.ts b/test/unit/queue-5.test.ts index 8a3e95118b..1c530f9c65 100644 --- a/test/unit/queue-5.test.ts +++ b/test/unit/queue-5.test.ts @@ -76,6 +76,7 @@ import { import { createTestEnv } from "../helpers/d1"; import { ISSUE_WAKE_MAX_PRS, MERGE_WAKE_MAX_PRS, SWEEP_MAX_PRS } from "../../src/settings/agent-sweep"; import { AGENT_LABEL_PENDING_CLOSURE, DEFAULT_LINKED_ISSUE_HARD_RULES } from "../../src/review/linked-issue-hard-rules"; +import { generatePrivateKeyPem } from "../helpers/github-app-key"; vi.mock("../../src/github/pr-freshness", async (importOriginal) => { const actual = await importOriginal(); @@ -202,22 +203,6 @@ function withProductUsageInsertFailure(env: Env): Env { }; } -async function generatePrivateKeyPem(): Promise { - const key = (await crypto.subtle.generateKey( - { - name: "RSASSA-PKCS1-v1_5", - modulusLength: 2048, - publicExponent: new Uint8Array([1, 0, 1]), - hash: "SHA-256", - }, - true, - ["sign", "verify"], - )) as CryptoKeyPair; - const exported = await crypto.subtle.exportKey("pkcs8", key.privateKey); - const base64 = Buffer.from(exported as ArrayBuffer).toString("base64").replace(/(.{64})/g, "$1\n"); - return `-----BEGIN PRIVATE KEY-----\n${base64}\n-----END PRIVATE KEY-----`; -} - describe("queue processors", () => { // Freshness-SLO fixtures are dated relative to late May 2026; pin the clock so staleness windows // stay deterministic regardless of when CI runs. diff --git a/test/unit/queue-lifecycle-guards.test.ts b/test/unit/queue-lifecycle-guards.test.ts index 351f7872d9..21d316081f 100644 --- a/test/unit/queue-lifecycle-guards.test.ts +++ b/test/unit/queue-lifecycle-guards.test.ts @@ -74,6 +74,7 @@ import { import { createTestEnv } from "../helpers/d1"; import { ISSUE_WAKE_MAX_PRS, MERGE_WAKE_MAX_PRS, SWEEP_MAX_PRS } from "../../src/settings/agent-sweep"; import { AGENT_LABEL_PENDING_CLOSURE, DEFAULT_LINKED_ISSUE_HARD_RULES } from "../../src/review/linked-issue-hard-rules"; +import { generatePrivateKeyPem } from "../helpers/github-app-key"; vi.mock("../../src/github/pr-freshness", async (importOriginal) => { const actual = await importOriginal(); @@ -200,22 +201,6 @@ function withProductUsageInsertFailure(env: Env): Env { }; } -async function generatePrivateKeyPem(): Promise { - const key = (await crypto.subtle.generateKey( - { - name: "RSASSA-PKCS1-v1_5", - modulusLength: 2048, - publicExponent: new Uint8Array([1, 0, 1]), - hash: "SHA-256", - }, - true, - ["sign", "verify"], - )) as CryptoKeyPair; - const exported = await crypto.subtle.exportKey("pkcs8", key.privateKey); - const base64 = Buffer.from(exported as ArrayBuffer).toString("base64").replace(/(.{64})/g, "$1\n"); - return `-----BEGIN PRIVATE KEY-----\n${base64}\n-----END PRIVATE KEY-----`; -} - describe("changedPathsForGuardrail", () => { it("collects current + rename paths and skips empty entries", () => { const files = [ diff --git a/test/unit/queue.test.ts b/test/unit/queue.test.ts index c0f1771790..2e0191b25a 100644 --- a/test/unit/queue.test.ts +++ b/test/unit/queue.test.ts @@ -77,6 +77,7 @@ import { import { asCloudEnv, createTestEnv } from "../helpers/d1"; import { ISSUE_WAKE_MAX_PRS, MERGE_WAKE_MAX_PRS, SWEEP_MAX_PRS } from "../../src/settings/agent-sweep"; import { AGENT_LABEL_PENDING_CLOSURE, DEFAULT_LINKED_ISSUE_HARD_RULES } from "../../src/review/linked-issue-hard-rules"; +import { generatePrivateKeyPem } from "../helpers/github-app-key"; vi.mock("../../src/github/pr-freshness", async (importOriginal) => { const actual = await importOriginal(); @@ -203,22 +204,6 @@ function withProductUsageInsertFailure(env: Env): Env { }; } -async function generatePrivateKeyPem(): Promise { - const key = (await crypto.subtle.generateKey( - { - name: "RSASSA-PKCS1-v1_5", - modulusLength: 2048, - publicExponent: new Uint8Array([1, 0, 1]), - hash: "SHA-256", - }, - true, - ["sign", "verify"], - )) as CryptoKeyPair; - const exported = await crypto.subtle.exportKey("pkcs8", key.privateKey); - const base64 = Buffer.from(exported as ArrayBuffer).toString("base64").replace(/(.{64})/g, "$1\n"); - return `-----BEGIN PRIVATE KEY-----\n${base64}\n-----END PRIVATE KEY-----`; -} - describe("queue processors", () => { // Freshness-SLO fixtures are dated relative to late May 2026; pin the clock so staleness windows // stay deterministic regardless of when CI runs. diff --git a/test/unit/rag-index.test.ts b/test/unit/rag-index.test.ts index 72fee852a9..09e16c774a 100644 --- a/test/unit/rag-index.test.ts +++ b/test/unit/rag-index.test.ts @@ -1,6 +1,15 @@ -import { afterEach, describe, expect, it, vi } from "vitest"; +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { indexRepo, reindexChangedPaths } from "../../src/review/rag-index"; -import { MAX_CHUNKS_PER_REPO, MAX_FILE_BYTES, RAG_DIMENSIONS, ragNamespace } from "../../src/review/rag"; +import { MAX_FILE_BYTES, RAG_DIMENSIONS, maxChunksPerRepo, ragNamespace, setMaxChunksPerRepoForTest } from "../../src/review/rag"; + +// #test-hotspots: the cap tests pin capping BEHAVIOR, not the production constant (4000) — building +// 4,000 real chunk rows per cap test made this file one of the suite's slowest (~7s per cap test). +// The whole file runs with a small cap via setMaxChunksPerRepoForTest: cap tests hit it at 24 rows, +// and no other fixture in this file indexes anywhere near 24 files, so their semantics are unchanged. +// Keeps the production constant's NAME so every existing test body reads exactly as before. +const MAX_CHUNKS_PER_REPO = 24; +beforeEach(() => setMaxChunksPerRepoForTest(MAX_CHUNKS_PER_REPO)); +afterEach(() => setMaxChunksPerRepoForTest(null)); import { processJob, splitRepoForRag } from "../../src/queue/processors"; import { upsertRepositoryFromGitHub } from "../../src/db/repositories"; import { upsertRepoFocusManifest } from "../../src/signals/focus-manifest-loader"; @@ -96,6 +105,13 @@ async function pathsFor(env: Env, project: string, repo: string): Promise r.path))]; } +describe("maxChunksPerRepo test override", () => { + it("falls back to the production cap (4000) when no override is armed", () => { + setMaxChunksPerRepoForTest(null); + expect(maxChunksPerRepo()).toBe(4000); + }); +}); + describe("rag-index migration: repo_chunks exists in the test D1", () => { it("the 0051 migration created repo_chunks (insert + read round-trips)", async () => { const db = new TestD1Database() as unknown as D1Database; diff --git a/test/unit/review-evasion-per-repo-admin.test.ts b/test/unit/review-evasion-per-repo-admin.test.ts index 2ed589bf4d..837bd40996 100644 --- a/test/unit/review-evasion-per-repo-admin.test.ts +++ b/test/unit/review-evasion-per-repo-admin.test.ts @@ -6,6 +6,7 @@ import { } from "../../src/queue/review-evasion"; import { createTestEnv } from "../helpers/d1"; import type { GitHubWebhookPayload, PullRequestRecord, RepositorySettings } from "../../src/types"; +import { generatePrivateKeyPem } from "../helpers/github-app-key"; // #4889: the review-evasion guards' fleet-operator exemptions in per-repo admin mode. Mode OFF (self-host // default) keeps the ADMIN_GITHUB_LOGINS shortcut byte-identical — an allowlisted actor is exempt with NO @@ -16,19 +17,6 @@ import type { GitHubWebhookPayload, PullRequestRecord, RepositorySettings } from const PEM_HEADER = ["-----BEGIN", "PRIVATE KEY-----"].join(" "); const PEM_FOOTER = ["-----END", "PRIVATE KEY-----"].join(" "); -async function generatePrivateKeyPem(): Promise { - const key = (await crypto.subtle.generateKey( - { name: "RSASSA-PKCS1-v1_5", modulusLength: 2048, publicExponent: new Uint8Array([1, 0, 1]), hash: "SHA-256" }, - true, - ["sign", "verify"], - )) as CryptoKeyPair; - const exported = await crypto.subtle.exportKey("pkcs8", key.privateKey); - const base64 = Buffer.from(exported as ArrayBuffer) - .toString("base64") - .replace(/(.{64})/g, "$1\n"); - return `${PEM_HEADER}\n${base64}\n${PEM_FOOTER}`; -} - type StubHandler = (url: string) => Response | undefined; function stubGitHub(handler: StubHandler = () => undefined): string[] { diff --git a/test/unit/safety.test.ts b/test/unit/safety.test.ts index 1f99819c87..c940c6f598 100644 --- a/test/unit/safety.test.ts +++ b/test/unit/safety.test.ts @@ -11,6 +11,7 @@ import { } from "../../src/db/repositories"; import { upsertRepoFocusManifest } from "../../src/signals/focus-manifest-loader"; import { createTestEnv } from "../helpers/d1"; +import { generatePrivateKeyPem } from "../helpers/github-app-key"; // Drives the LOOPOVER_REVIEW_SAFETY secrets-scan WIRING through the live review finalize path // (processGitHubWebhook → maybePublishPrPublicSurface → `await maybeAddSecretLeakFinding(...)` at the gate @@ -21,12 +22,6 @@ import { createTestEnv } from "../helpers/d1"; const LEAKED_TOKEN = "ghp_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; // A self-signed RSA PEM so the GitHub App can mint an installation token (gate check-run posting). -async function generatePrivateKeyPem(): Promise { - const key = (await crypto.subtle.generateKey({ name: "RSASSA-PKCS1-v1_5", modulusLength: 2048, publicExponent: new Uint8Array([1, 0, 1]), hash: "SHA-256" }, true, ["sign", "verify"])) as CryptoKeyPair; - const pkcs8 = await crypto.subtle.exportKey("pkcs8", key.privateKey); - const b64 = Buffer.from(pkcs8 as ArrayBuffer).toString("base64").replace(/(.{64})/g, "$1\n"); - return `-----BEGIN PRIVATE KEY-----\n${b64}\n-----END PRIVATE KEY-----\n`; -} // A confirmed-miner snapshot. The author confirmation no longer changes whether the gate can block // (#gate-nonconfirmed); this just stands up a representative confirmed author so the flag-ON safety blocker's diff --git a/test/unit/screenshot-evidence-summary-wiring.test.ts b/test/unit/screenshot-evidence-summary-wiring.test.ts index 6f03791a0a..270b58e5b8 100644 --- a/test/unit/screenshot-evidence-summary-wiring.test.ts +++ b/test/unit/screenshot-evidence-summary-wiring.test.ts @@ -9,22 +9,7 @@ import { upsertInstallation, upsertRepositorySettings } from "../../src/db/repos import { upsertRepoFocusManifest } from "../../src/signals/focus-manifest-loader"; import { processJob } from "../../src/queue/processors"; import { createTestEnv } from "../helpers/d1"; - -async function generatePrivateKeyPem(): Promise { - const key = (await crypto.subtle.generateKey( - { - name: "RSASSA-PKCS1-v1_5", - modulusLength: 2048, - publicExponent: new Uint8Array([1, 0, 1]), - hash: "SHA-256", - }, - true, - ["sign", "verify"], - )) as CryptoKeyPair; - const exported = await crypto.subtle.exportKey("pkcs8", key.privateKey); - const base64 = Buffer.from(exported as ArrayBuffer).toString("base64").replace(/(.{64})/g, "$1\n"); - return `-----BEGIN PRIVATE KEY-----\n${base64}\n-----END PRIVATE KEY-----\n`; -} +import { generatePrivateKeyPem } from "../helpers/github-app-key"; const REPO_FULL_NAME = "JSONbored/gittensory"; const BEFORE_URL = "https://user-images.githubusercontent.com/vision-before.png";