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
5 changes: 0 additions & 5 deletions packages/gittensory-engine/src/settings/pr-type-label.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,6 @@ export const DEFAULT_TYPE_LABELS: PrTypeLabelSet = {
priority: "gittensor:priority",
};

/** Every label name in the built-in default set, generic over however many categories
* `DEFAULT_TYPE_LABELS` carries (#label-modularity) -- never hardcode `.bug`/`.feature`/`.priority`
* property access here, a configured set can carry more or fewer categories than the default. */
export const ALL_TYPE_LABELS: readonly string[] = Object.values(DEFAULT_TYPE_LABELS);

export const MAX_TYPE_LABEL_CATEGORIES = 32;
export const MAX_TYPE_LABEL_NAME_LENGTH = 50;

Expand Down
64 changes: 3 additions & 61 deletions packages/gittensory-engine/src/signals/test-evidence.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,66 +120,8 @@ export function classifyTestCoverage(changedPaths: string[]): TestCoverageClassi
return "weak";
}

// #2187 (foundational slice of #1972 — boundary-safe test generation): a small, precise framework list, each
// tied to an unambiguous marker file/pattern and an existing isTestPath naming family. Deliberately narrow —
// a longer list of guessable-but-ambiguous frameworks would make detectTestConvention's output less trustworthy
// as a test-gen input than returning null (see the "unknown => null" fail-safe below).
// #2187 (foundational slice of #1972 — boundary-safe test generation): a small, precise framework list.
// Consumed by the MCP test-gen tool's enum (src/mcp/server.ts testGenShape) so a caller cannot request a
// spec for a framework this engine doesn't recognize.
export const TEST_FRAMEWORKS = ["vitest", "jest", "pytest", "go-test", "rspec", "cargo-test"] as const;
export type TestFramework = (typeof TEST_FRAMEWORKS)[number];

/** Deterministic detection result: which framework, where tests live, and the file-naming convention to
* follow when scaffolding a new one. `testDir` is `null` for a co-located convention (e.g. Go/Rust/Dart's
* `_test`/`#[cfg(test)]` siblings), matching how those ecosystems actually lay out tests. */
export type TestConvention = {
framework: TestFramework;
testDir: string | null;
namingPattern: string;
};

// One marker file per framework, checked against the basename of each changed/known path. Ordered by
// specificity where two frameworks could share an ecosystem (vitest before jest: a repo migrating from Jest to
// Vitest keeps `jest.config.js` around far more often than the reverse, so vitest's own config marker — when
// present — must win).
const FRAMEWORK_MARKERS: ReadonlyArray<{ framework: TestFramework; pattern: RegExp; testDir: string | null; namingPattern: string }> = [
{ framework: "vitest", pattern: /(^|\/)vitest\.config\.(ts|mts|cts|js|mjs|cjs)$/i, testDir: "test/", namingPattern: "*.test.ts" },
{ framework: "vitest", pattern: /(^|\/)vitest\.workspace\.(ts|mts|cts|js|mjs|cjs)$/i, testDir: "test/", namingPattern: "*.test.ts" },
{ framework: "jest", pattern: /(^|\/)jest\.config\.(ts|js|mjs|cjs|json)$/i, testDir: "__tests__/", namingPattern: "*.test.js" },
{ framework: "pytest", pattern: /(^|\/)pytest\.ini$/i, testDir: null, namingPattern: "test_*.py" },
{ framework: "pytest", pattern: /(^|\/)pyproject\.toml$/i, testDir: null, namingPattern: "test_*.py" },
{ framework: "go-test", pattern: /(^|\/)go\.mod$/i, testDir: null, namingPattern: "*_test.go" },
{ framework: "rspec", pattern: /(^|\/)\.rspec$/i, testDir: "spec/", namingPattern: "*_spec.rb" },
{ framework: "cargo-test", pattern: /(^|\/)Cargo\.toml$/i, testDir: null, namingPattern: "#[cfg(test)] mod tests" },
];

// Fallback inference from an EXISTING test file's own naming, when no marker is present (e.g. a marker file
// wasn't part of the changed/known set passed in, but the repo already has real test files to imitate).
const CONVENTION_FROM_EXISTING_TEST: ReadonlyArray<{ framework: TestFramework; pattern: RegExp; testDir: string | null; namingPattern: string }> = [
{ framework: "vitest", pattern: /\.(test|spec)\.(ts|tsx|mts|cts)$/i, testDir: "test/", namingPattern: "*.test.ts" },
{ framework: "jest", pattern: /\.(test|spec)\.(js|jsx|mjs|cjs)$/i, testDir: "__tests__/", namingPattern: "*.test.js" },
{ framework: "pytest", pattern: /(^|\/)test_[^/]*\.py$|[^/]+_test\.py$/i, testDir: null, namingPattern: "test_*.py" },
{ framework: "go-test", pattern: /[^/]+_test\.go$/i, testDir: null, namingPattern: "*_test.go" },
{ framework: "rspec", pattern: /[^/]+_spec\.rb$/i, testDir: "spec/", namingPattern: "*_spec.rb" },
];

/**
* Detect a repo's test framework + convention from a bounded set of changed paths and known marker filenames
* (e.g. `package.json`, `pyproject.toml`, `go.mod` — paths the caller already has, never fetched by this
* function). Deterministic and pure: markers win over inferring from existing test-file naming (a config file
* is a stronger, unambiguous signal than a naming guess), and the marker list is checked in a fixed order so a
* repo with more than one marker present always resolves to the same framework. Returns `null` when nothing in
* `paths`/`markers` matches any known convention — an unrecognized layout is left alone (fail-safe) rather than
* guessing, since a wrong framework guess would make the downstream test-gen spec actively misleading.
*/
export function detectTestConvention(paths: string[], markers: string[]): TestConvention | null {
for (const marker of FRAMEWORK_MARKERS) {
if (markers.some((path) => marker.pattern.test(path)) || paths.some((path) => marker.pattern.test(path))) {
return { framework: marker.framework, testDir: marker.testDir, namingPattern: marker.namingPattern };
}
}
for (const convention of CONVENTION_FROM_EXISTING_TEST) {
if (paths.some((path) => isTestPath(path) && convention.pattern.test(path))) {
return { framework: convention.framework, testDir: convention.testDir, namingPattern: convention.namingPattern };
}
}
return null;
}
13 changes: 0 additions & 13 deletions review-enrichment/src/analyzers/dependency-scan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -432,16 +432,3 @@ export async function scanDependencyChanges(
}
return findings;
}

/** Analyzer entrypoint: changed deps → OSV → only the deps that carry vulnerabilities. */
export async function scanDependencies(
req: EnrichRequest,
fetchImpl: typeof fetch = fetch,
options: ScanOptions = {},
): Promise<DependencyFinding[]> {
return scanDependencyChanges(
extractDependencyChanges(req.files ?? [], options.limits),
fetchImpl,
options,
);
}
3 changes: 0 additions & 3 deletions review-enrichment/src/analyzers/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ import type {
AnalyzerDescriptor,
AnalyzerFn,
AnalyzerName,
AnalyzerRegistry,
AnyAnalyzerDescriptor,
} from "./types.js";
import { DEFAULT_MAX_FINDINGS, DEFAULT_MAX_LINE_CHARS } from "./limits.js";
Expand Down Expand Up @@ -1632,8 +1631,6 @@ export const ANALYZERS = Object.fromEntries(
ANALYZER_DESCRIPTORS.map((analyzer) => [analyzer.name, analyzer.run]),
) as Record<AnalyzerName, AnalyzerFn>;

export const ANALYZER_REGISTRY: AnalyzerRegistry = ANALYZERS;

export const ANALYZER_DESCRIPTORS_BY_NAME = Object.fromEntries(
ANALYZER_DESCRIPTORS.map((analyzer) => [analyzer.name, analyzer]),
) as Partial<Record<AnalyzerName, AnyAnalyzerDescriptor>>;
Expand Down
37 changes: 0 additions & 37 deletions review-enrichment/test/enrichment.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import assert from "node:assert/strict";
import {
extractDependencyChanges,
queryOsv,
scanDependencies,
} from "../dist/analyzers/dependency-scan.js";
import {
extractLockfileChanges,
Expand Down Expand Up @@ -193,20 +192,6 @@ test("queryOsv: CVSS numeric score bucketed when no database_specific", async ()
assert.equal(cves[0].severity, "critical");
});

test("scanDependencies: only deps with vulns are returned", async () => {
const findings = await scanDependencies(
{
repoFullName: "o/r",
prNumber: 1,
files: [{ path: "package.json", patch: '+ "lodash": "4.17.20",' }],
},
okBatchFetch([{ id: "GHSA-x", database_specific: { severity: "CRITICAL" } }]),
);
assert.equal(findings.length, 1);
assert.equal(findings[0].direction, "add");
assert.equal(findings[0].cves[0].severity, "critical");
});

test("extractLockfileChanges: package-lock version drift with file line, skipping direct manifest deps", () => {
const changes = extractLockfileChanges([
{
Expand Down Expand Up @@ -1668,28 +1653,6 @@ test("extractDependencyChanges: caps manifest files and patch lines", () => {
);
});

test("scanDependencies: caps OSV queries and forwards abort signals", async () => {
const seenSignals = [];
const files = Array.from({ length: 3 }, (_, index) => ({
path: "package.json",
patch: `+ "pkg-${index}": "1.0.0",`,
}));

const controller = new AbortController();
const findings = await scanDependencies(
{ repoFullName: "o/r", prNumber: 1, files },
async (_url, init) => {
seenSignals.push(init.signal);
return { ok: true, json: async () => ({ results: [{ vulns: [] }, { vulns: [] }] }) };
},
{ signal: controller.signal, limits: { maxDependencyQueries: 2 } },
);

assert.equal(findings.length, 0);
assert.equal(seenSignals.length, 1);
assert.ok(seenSignals.every((signal) => signal instanceof AbortSignal));
});

test("buildBrief: timeout aborts dependency scan so OSV work stops", async () => {
const realFetch = globalThis.fetch;
const signals = [];
Expand Down
13 changes: 0 additions & 13 deletions src/db/repositories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4070,19 +4070,6 @@ export async function listOpenItemsForAuthorAcrossInstall(env: Env, installation
];
}

// Anti-farming (#anti-gaming-flood): how many PRs this author has SUBMITTED to this repo since `sinceIso` (ANY
// state — open/merged/closed), so a flood that merges fast is still caught. createdAt is the row-insert time
// (≈ when gittensory first saw the PR), a good proxy for submission time on live webhook-driven PRs.
export async function countRecentSubmissionsByAuthor(env: Env, fullName: string, authorLogin: string, sinceIso: string): Promise<number> {
const db = getDb(env.DB);
const [row] = await db
.select({ count: sql<number>`count(*)` })
.from(pullRequests)
.where(and(eq(pullRequests.repoFullName, fullName), eq(pullRequests.authorLogin, authorLogin), gte(pullRequests.createdAt, sinceIso)));
/* v8 ignore next -- SQL aggregate count always returns one row; fallback protects D1 driver anomalies. */
return Number(row?.count ?? 0);
}

export async function markUnseenOpenPullRequestsClosed(env: Env, fullName: string, seenOpenAt: string): Promise<number> {
const db = getDb(env.DB);
const result = await db
Expand Down
9 changes: 0 additions & 9 deletions src/review/content-lane/registry-logic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,6 @@ export function isInternalAutomationBranch(ref: string | undefined): boolean {
export const ARTIFACT_PATTERN = /^public\/metagraph\/[a-z0-9/_-]+\.json$/i;
export const DEFAULT_PUBLIC_API_BASE = "https://api.metagraph.sh/api/v1";

export const ISSUE_SUBMISSION_LABELS = new Set([
"interface-submission",
"endpoint-submission",
"provider-submission",
"status-report",
]);

const REVIEWER_CLOSE_REASONS = new Set([
"malformed-json",
"unsafe-url",
Expand Down Expand Up @@ -81,8 +74,6 @@ const REVIEWER_SAFE_KINDS = new Set([
"docs",
"data-artifact",
]);
export const AI_REVIEW_VERDICTS = new Set(["merged", "closed", "manual-review"]);

/** Live verdict vocabulary → core verdict. */
export type MetaVerdict = "merged" | "closed" | "manual-review";
export function toCoreVerdict(v: MetaVerdict): Verdict {
Expand Down
4 changes: 0 additions & 4 deletions src/review/repo-doc-render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@
import type { RepoProfile, RepoProfileCommands, RepoProfileFileNamingStyle, RepoProfileTestFileConvention } from "./repo-profile";
import type { GeneratedDocMarkers } from "./generated-doc-refresh";

/** Bumped whenever the RENDERED CONTENT's structure changes in a way #3004's diff-aware refresh needs to know
* about (new section, reordered section, changed marker) -- not on copy-only wording tweaks. */
export const REPO_DOC_TEMPLATE_VERSION = 2;

/** HTML-comment marker pair bracketing the machine-generated section of every AGENTS.md this engine writes.
* Content outside this pair (added by a maintainer before the start marker or after the end marker) is treated
* as permanently manual and is never touched by a refresh (#3004) -- see generated-doc-refresh.ts. */
Expand Down
7 changes: 0 additions & 7 deletions src/selfhost/cf-workers-shim.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,3 @@ export class DurableObject<E = unknown> {
protected env?: E,
) {}
}
export class WorkerEntrypoint<E = unknown> {
constructor(
protected ctx?: unknown,
protected env?: E,
) {}
}
export class RpcTarget {}
4 changes: 0 additions & 4 deletions src/selfhost/queue-common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -598,10 +598,6 @@ export function githubWebhookRateLimitDelayMs(
return githubObservedRateLimitDelayMs(observation, LOW_REST_RATE_LIMIT_REMAINING, nowMs);
}

export function githubRateLimitAdmissionRemainingFloor(kind: "background" | "webhook"): number {
return kind === "webhook" ? LOW_REST_RATE_LIMIT_REMAINING : MAINTENANCE_RESERVED_HEADROOM;
}

function githubWebhookPriority(payload: string): number {
try {
const message = JSON.parse(payload) as {
Expand Down
2 changes: 0 additions & 2 deletions src/services/linked-issue-satisfaction-run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,5 +177,3 @@ async function record(
metadata: { repoFullName: input.repoFullName, pullNumber: input.prNumber, ...(metadata ?? {}) },
});
}

export const __linkedIssueSatisfactionRunInternals = { runWorkersSatisfactionOpinion };
5 changes: 0 additions & 5 deletions src/settings/pr-type-label.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,6 @@ export const DEFAULT_TYPE_LABELS: PrTypeLabelSet = {
priority: "gittensor:priority",
};

/** Every label name in the built-in default set, generic over however many categories
* `DEFAULT_TYPE_LABELS` carries (#label-modularity) -- never hardcode `.bug`/`.feature`/`.priority`
* property access here, a configured set can carry more or fewer categories than the default. */
export const ALL_TYPE_LABELS: readonly string[] = Object.values(DEFAULT_TYPE_LABELS);

export const MAX_TYPE_LABEL_CATEGORIES = 32;
export const MAX_TYPE_LABEL_NAME_LENGTH = 50;

Expand Down
5 changes: 5 additions & 0 deletions test/stubs/cloudflare-workers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ export class WorkflowEntrypoint {
}
}

// NOT dead despite having no first-party caller: vitest.config.ts aliases the `cloudflare:workers`
// specifier to this file for EVERY module resolved under Node, including node_modules -- the `agents`
// package (a dependency of src/mcp/server.ts's `agents/mcp` import) does `import { RpcTarget } from
// "cloudflare:workers"` and extends it, so removing this breaks that whole dependency graph at test
// runtime (confirmed by `npm run test:changed`, not by static grep -- there is no in-repo caller).
export class RpcTarget {}

export const exports = {};
Expand Down
61 changes: 1 addition & 60 deletions test/unit/test-evidence.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { classifyTestCoverage, detectTestConvention, hasLocalTestEvidence, hasValidationNote, isSourcePath, isTestPath } from "../../src/signals/test-evidence";
import { classifyTestCoverage, hasLocalTestEvidence, hasValidationNote, isSourcePath, isTestPath } from "../../src/signals/test-evidence";

describe("test evidence helpers", () => {
it("detects common test path conventions", () => {
Expand Down Expand Up @@ -240,62 +240,3 @@ describe("classifyTestCoverage", () => {
expect(classifyTestCoverage([...sources, "test/single.test.ts"])).toBe("weak");
});
});

// #2187 (foundational slice of #1972): a bounded, deterministic framework/convention detector feeding the
// boundary-safe test-gen action spec (#2188).
describe("detectTestConvention", () => {
it("detects vitest from its config marker, taking precedence over a stale jest config", () => {
expect(detectTestConvention([], ["vitest.config.ts"])).toEqual({ framework: "vitest", testDir: "test/", namingPattern: "*.test.ts" });
expect(detectTestConvention([], ["vitest.workspace.mts"])).toEqual({ framework: "vitest", testDir: "test/", namingPattern: "*.test.ts" });
// A repo migrating off Jest keeps the old config around; vitest's own marker must still win (checked first).
expect(detectTestConvention([], ["vitest.config.js", "jest.config.js"])).toEqual({ framework: "vitest", testDir: "test/", namingPattern: "*.test.ts" });
});

it("detects jest from its config marker", () => {
expect(detectTestConvention([], ["jest.config.ts"])).toEqual({ framework: "jest", testDir: "__tests__/", namingPattern: "*.test.js" });
expect(detectTestConvention([], ["jest.config.json"])).toEqual({ framework: "jest", testDir: "__tests__/", namingPattern: "*.test.js" });
});

it("detects pytest from pytest.ini or pyproject.toml", () => {
expect(detectTestConvention([], ["pytest.ini"])).toEqual({ framework: "pytest", testDir: null, namingPattern: "test_*.py" });
expect(detectTestConvention([], ["pyproject.toml"])).toEqual({ framework: "pytest", testDir: null, namingPattern: "test_*.py" });
});

it("detects go test from go.mod", () => {
expect(detectTestConvention([], ["go.mod"])).toEqual({ framework: "go-test", testDir: null, namingPattern: "*_test.go" });
});

it("detects rspec from .rspec", () => {
expect(detectTestConvention([], [".rspec"])).toEqual({ framework: "rspec", testDir: "spec/", namingPattern: "*_spec.rb" });
});

it("detects cargo test from Cargo.toml", () => {
expect(detectTestConvention([], ["Cargo.toml"])).toEqual({ framework: "cargo-test", testDir: null, namingPattern: "#[cfg(test)] mod tests" });
});

it("matches a marker found in the changed paths, not only the markers list", () => {
expect(detectTestConvention(["backend/go.mod", "backend/main.go"], [])).toEqual({ framework: "go-test", testDir: null, namingPattern: "*_test.go" });
});

it("falls back to inferring from an existing test file's naming when no marker is present", () => {
expect(detectTestConvention(["test/unit/widget.test.ts"], [])).toEqual({ framework: "vitest", testDir: "test/", namingPattern: "*.test.ts" });
expect(detectTestConvention(["__tests__/widget.test.js"], [])).toEqual({ framework: "jest", testDir: "__tests__/", namingPattern: "*.test.js" });
expect(detectTestConvention(["mypackage/test_utils.py"], [])).toEqual({ framework: "pytest", testDir: null, namingPattern: "test_*.py" });
expect(detectTestConvention(["pkg/foo_test.go"], [])).toEqual({ framework: "go-test", testDir: null, namingPattern: "*_test.go" });
expect(detectTestConvention(["spec/models/widget_spec.rb"], [])).toEqual({ framework: "rspec", testDir: "spec/", namingPattern: "*_spec.rb" });
});

it("prefers a marker over an existing test file's naming when both are present", () => {
// go.mod marker present alongside a Ruby-looking spec path (an unusual but possible polyglot repo) — the
// marker is checked first and wins deterministically.
expect(detectTestConvention(["spec/widget_spec.rb"], ["go.mod"])).toEqual({ framework: "go-test", testDir: null, namingPattern: "*_test.go" });
});

it("returns null for an unknown/empty layout (fail-safe)", () => {
expect(detectTestConvention([], [])).toBeNull();
expect(detectTestConvention(["src/widget.rs"], ["Makefile"])).toBeNull();
// A path that merely LOOKS like a test file per isTestPath's directory rule, but whose extension isn't in
// any known convention pattern (e.g. a bare snapshot), does not resolve to a framework.
expect(detectTestConvention(["components/__snapshots__/Card.tsx.snap"], [])).toBeNull();
});
});
Loading