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
40 changes: 40 additions & 0 deletions scripts/check-engine-parity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,45 @@ export const SECRET_DETECTION_MARKERS = Object.freeze([
'"generic_secret_assignment"',
] as const);

/** `scripts/forbidden-content.ts`'s FORBIDDEN_CONTENT is a THIRD hand-copy (#7433) of the HARD_SECRET_KINDS
* regex bodies in `src/review/secret-patterns.ts` — the four package-manifest checkers (check-mcp/miner/
* engine/ui-kit-package.ts) use it to reject a packed tarball embedding a provider secret. Unlike the REES
* pair it was never drift-checked, so a tightened or added HARD_SECRET_KINDS pattern would silently leave
* packaged MCP/miner/engine/ui-kit scanning with a stale body, with no CI signal (#8674). Registered here so
* a divergence in any of the shared regex bodies fails CI. */
export const FORBIDDEN_CONTENT_TWIN_PAIR: NamedTwinPair = Object.freeze({
area: "forbidden-content-secret-patterns",
hostRelative: "src/review/secret-patterns.ts",
engineRelative: "scripts/forbidden-content.ts",
hostFileName: "secret-patterns.ts",
engineFileName: "forbidden-content.ts",
});

// The distinctive core of each HARD_SECRET_KINDS regex body that forbidden-content.ts hand-copied EXACTLY
// (#7433/#8396). Anchored on the backslash-free inner body, NOT the `\b`/`\.` escapes (which necessarily differ
// between secret-patterns.ts's regex literals — single `\` — and forbidden-content.ts's string bodies — double
// `\\`), so a merely-reformatted boundary never false-fails while a change to the actual character class /
// length / watermark of any shared pattern does. `github_token`/`github_pat`/`private_key_block` are
// DELIBERATELY EXCLUDED: forbidden-content.ts keeps its own looser pre-#7433 bodies for those three (e.g.
// `gh[pousr]_[A-Za-z0-9_]+` vs secret-patterns.ts's `gh[pousr]_[A-Za-z0-9]{20,}`), a pre-existing intentional
// divergence — including them would false-fail this check on the very PR that introduces it, exactly as
// SECRET_DETECTION_MARKERS excludes its own two naming-divergent kinds.
export const FORBIDDEN_CONTENT_MARKERS = Object.freeze([
"AKIA[0-9A-Z]{16}", // aws_access_key
"xox[baprs]-[A-Za-z0-9-]{10,}", // slack_token
"AIza[0-9A-Za-z_-]{35}", // google_api_key
"glpat-[0-9A-Za-z_-]{20}(?![0-9A-Za-z_-])", // gitlab_token
"npm_[A-Za-z0-9]{36}", // npm_token
"(?:sk|rk)_live_[0-9A-Za-z]{24,}", // stripe_secret_key
"[A-Za-z0-9_-]{43}(?![A-Za-z0-9_-])", // sendgrid_key (the distinctive 43-char secret half)
"hf_[A-Za-z0-9]{34}", // huggingface_token
"(?:pa|al)-[A-Za-z0-9]{20,}(?![A-Za-z0-9_-])", // voyage_api_key
"fc-[A-Za-z0-9]{16,}(?![A-Za-z0-9_-])", // firecrawl_api_key
"sk-(?:proj-|svcacct-|admin-)?[A-Za-z0-9_-]{20,}T3BlbkFJ[A-Za-z0-9_-]{20,}", // openai_api_key
"sk-ant-api03-[A-Za-z0-9_-]{93}AA", // anthropic_api_key
"eyJ[A-Za-z0-9_-]{10,}", // jwt (#8396)
] as const);

/** Every explicitly named twin pair, checked for core-marker presence in `runEngineParityChecks` — the
* same escape hatch #4518 built for `GATE_DECISION_TWIN_PAIR`, generalized (#4605) so a function-level or
* nested-directory duplicate can be added here without inventing a new mechanism. `GATE_DECISION_TWIN_PAIR`
Expand All @@ -163,6 +202,7 @@ export const NAMED_TWIN_PAIRS: ReadonlyArray<{ pair: NamedTwinPair; markers: rea
{ pair: DIFF_FILE_PRIORITY_GROUNDING_TWIN_PAIR, markers: DIFF_FILE_PRIORITY_MARKERS },
{ pair: SHARES_MEANINGFUL_FILE_TWIN_PAIR, markers: SHARES_MEANINGFUL_FILE_MARKERS },
{ pair: SECRET_DETECTION_TWIN_PAIR, markers: SECRET_DETECTION_MARKERS },
{ pair: FORBIDDEN_CONTENT_TWIN_PAIR, markers: FORBIDDEN_CONTENT_MARKERS },
]);
const ENGINE_SRC_ROOT = "packages/loopover-engine/src";
const HOST_SRC_ROOT = "src";
Expand Down
44 changes: 43 additions & 1 deletion test/unit/check-engine-parity-script.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import {
discoverGateDecisionTwinPair,
enginePackageVersionIncreased,
extractForbiddenTermsRegex,
FORBIDDEN_CONTENT_MARKERS,
FORBIDDEN_CONTENT_TWIN_PAIR,
GATE_DECISION_TWIN_PAIR,
type EngineParityPair,
isEngineStubPair,
Expand Down Expand Up @@ -456,7 +458,7 @@ const CHECK_RUN_FORBIDDEN_TERMS =
});

describe("named twin-pair coverage (#4605)", () => {
it("registers the gate-decision, content-lane, diff-file-priority twins, shares-meaningful-file, and secret-detection pairs", () => {
it("registers the gate-decision, content-lane, diff-file-priority, diff-file-priority-grounding, shares-meaningful-file, secret-detection, and forbidden-content pairs", () => {
const areas = NAMED_TWIN_PAIRS.map(({ pair }) => pair.area);
expect(areas).toEqual([
"gate-decision",
Expand All @@ -465,6 +467,7 @@ const CHECK_RUN_FORBIDDEN_TERMS =
"diff-file-priority-grounding",
"shares-meaningful-file",
"secret-detection",
"forbidden-content-secret-patterns",
]);
});

Expand Down Expand Up @@ -635,6 +638,45 @@ const CHECK_RUN_FORBIDDEN_TERMS =
});
});

describe("forbidden-content twin coverage (#8674)", () => {
it("registers scripts/forbidden-content.ts against src/review/secret-patterns.ts", () => {
expect(FORBIDDEN_CONTENT_TWIN_PAIR.hostRelative).toBe("src/review/secret-patterns.ts");
expect(FORBIDDEN_CONTENT_TWIN_PAIR.engineRelative).toBe("scripts/forbidden-content.ts");
});

it("excludes the three kinds whose forbidden-content bodies deliberately diverge (github_token/github_pat/private_key_block)", () => {
// Those three keep looser pre-#7433 bodies in forbidden-content.ts (e.g. `gh[pousr]_[A-Za-z0-9_]+`);
// asserting their absence documents the deliberate omission and guards against someone "completing the
// set" and reintroducing a false-fail, exactly as the secret-detection pair does for its own divergences.
const joined = FORBIDDEN_CONTENT_MARKERS.join("\n");
expect(joined).not.toContain("gh[pousr]_");
expect(joined).not.toContain("github_pat_");
expect(joined).not.toContain("PRIVATE KEY");
});

it("fails presence when a shared HARD_SECRET_KINDS regex body drifts between the two copies", () => {
// Reproduces the drift class this pair exists to catch (#8674): a HARD_SECRET_KINDS body is tightened in
// secret-patterns.ts while forbidden-content.ts's hand-copy is left stale, silently packaging tarballs
// with an outdated scanner. Both bodies start from the FULL marker set so only the dropped line fails.
const droppedMarker = "sk-ant-api03-[A-Za-z0-9_-]{93}AA";
const hostBody = FORBIDDEN_CONTENT_MARKERS.join("\n");
const driftedTwinBody = FORBIDDEN_CONTENT_MARKERS.filter((marker) => marker !== droppedMarker).join("\n");
const result = checkGateDecisionTwinPresence({
root: "/fake",
readFile: (_root, relativePath) => {
if (relativePath === FORBIDDEN_CONTENT_TWIN_PAIR.hostRelative) return hostBody;
if (relativePath === FORBIDDEN_CONTENT_TWIN_PAIR.engineRelative) return driftedTwinBody;
throw new Error(`unexpected read: ${relativePath}`);
},
pair: FORBIDDEN_CONTENT_TWIN_PAIR,
markers: FORBIDDEN_CONTENT_MARKERS,
});
expect(result.failures).toHaveLength(1);
expect(result.failures[0]).toContain(FORBIDDEN_CONTENT_TWIN_PAIR.engineRelative);
expect(result.failures[0]).toContain(JSON.stringify(droppedMarker));
});
});

describe("engine version skew", () => {
it("classifies equal, behind, and ahead boundary cases", () => {
expect(compareSemver("0.2.0", "0.2.0")).toBe(0);
Expand Down