Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions src/review/rag-index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import {
filePriority,
getStoredChunkMeta,
isIndexablePath,
MAX_CHUNKS_PER_REPO,
maxChunksPerRepo,
MAX_FILE_BYTES,
ragNamespace,
type RagChunk,
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down
12 changes: 12 additions & 0 deletions src/review/rag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
32 changes: 32 additions & 0 deletions test/helpers/github-app-key.ts
Original file line number Diff line number Diff line change
@@ -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<string> {
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<string> {
const holder = globalThis as { __loopoverTestAppKeyPem?: Promise<string> };
return (holder.__loopoverTestAppKeyPem ??= freshPrivateKeyPem());
}
17 changes: 1 addition & 16 deletions test/integration/api.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<typeof import("../../src/github/app")>()),
Expand Down Expand Up @@ -7139,22 +7140,6 @@ function apiHeaders(env: Env): Record<string, string> {
};
}

async function generatePrivateKeyPem(): Promise<string> {
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<string, string> = {
"gittensor/constants.py": "SRC_TOK_SATURATION_SCALE = 58\nMAX_CODE_DENSITY_MULTIPLIER = 1.15\n",
Expand Down
11 changes: 1 addition & 10 deletions test/unit/actions-fallback-webhook.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<string> {
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);
Expand Down
17 changes: 1 addition & 16 deletions test/unit/backfill-2.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -89,22 +90,6 @@ async function seedRegisteredRepo(env: Env) {
);
}

async function generatePrivateKeyPem(): Promise<string> {
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: {
Expand Down
17 changes: 1 addition & 16 deletions test/unit/backfill.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -218,22 +219,6 @@ async function seedInstalledAndRegisteredRepo(env: Env) {
await seedRegisteredRepo(env);
}

async function generatePrivateKeyPem(): Promise<string> {
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: {
Expand Down
17 changes: 1 addition & 16 deletions test/unit/github-comments.test.ts
Original file line number Diff line number Diff line change
@@ -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(() => {
Expand Down Expand Up @@ -504,22 +505,6 @@ describe("GitHub PR intelligence comments", () => {
});
});

async function generatePrivateKeyPem(): Promise<string> {
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
Expand Down
14 changes: 1 addition & 13 deletions test/unit/linked-issue-label-propagation-fetch.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -18,19 +19,6 @@ import {
const PEM_HEADER = ["-----BEGIN", "PRIVATE KEY-----"].join(" ");
const PEM_FOOTER = ["-----END", "PRIVATE KEY-----"].join(" ");

async function generatePrivateKeyPem(): Promise<string> {
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).
Expand Down
14 changes: 1 addition & 13 deletions test/unit/linked-issue-satisfaction-run.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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<string> {
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",
Expand Down
7 changes: 1 addition & 6 deletions test/unit/parity-wire.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) ──────────────────────────────────────

Expand Down Expand Up @@ -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<string> {
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).
Expand Down
17 changes: 1 addition & 16 deletions test/unit/pr-panel-retrigger-pending-force-review.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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<string> {
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,
Expand Down
17 changes: 1 addition & 16 deletions test/unit/queue-2.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<typeof import("../../src/github/pr-freshness")>();
Expand Down Expand Up @@ -200,22 +201,6 @@ function withProductUsageInsertFailure(env: Env): Env {
};
}

async function generatePrivateKeyPem(): Promise<string> {
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.
Expand Down
Loading