fix(MULTIVERSION-0001): eliminate NULL-row contamination in getRules

When a versioned query is made, getRules() now returns only the
version-specific repository_configs row. The NULL (HEAD/repo-wide)
row is no longer merged in, preventing v4 rules from bleeding into
v1/v2/v3 versioned context responses.

Tests updated to assert the isolation: versioned queries return only
their own rules row; a new test verifies that a version with no
config row returns an empty rules array even when a NULL row exists.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Giancarmine Salucci
2026-03-29 11:47:31 +02:00
parent bbc67f8064
commit 09c6f9f7c1
2 changed files with 50 additions and 30 deletions

View File

@@ -69,35 +69,25 @@ function getRules(
repositoryId: string,
versionId?: string
): string[] {
// Repo-wide rules (version_id IS NULL).
const repoRow = db
.prepare<
[string],
RawRepoConfig
>(`SELECT rules FROM repository_configs WHERE repository_id = ? AND version_id IS NULL`)
.get(repositoryId);
if (!versionId) {
// Unversioned query: return repo-wide (HEAD) rules only.
const row = db
.prepare<
[string],
RawRepoConfig
>(`SELECT rules FROM repository_configs WHERE repository_id = ? AND version_id IS NULL`)
.get(repositoryId);
return parseRulesJson(row?.rules);
}
const repoRules = parseRulesJson(repoRow?.rules);
if (!versionId) return repoRules;
// Version-specific rules.
const versionRow = db
// Versioned query: return only version-specific rules (no NULL row merge).
const row = db
.prepare<
[string, string],
RawRepoConfig
>(`SELECT rules FROM repository_configs WHERE repository_id = ? AND version_id = ?`)
.get(repositoryId, versionId);
const versionRules = parseRulesJson(versionRow?.rules);
// Merge: repo-wide first, then version-specific (deduped by content).
const seen = new Set(repoRules);
const merged = [...repoRules];
for (const r of versionRules) {
if (!seen.has(r)) merged.push(r);
}
return merged;
return parseRulesJson(row?.rules);
}
interface RawRepoState {