tests/integration/retrieval-correctness.test.ts
Rama main · réplica de lectura del repositorio original.
import { test } from "bun:test";
import assert from "node:assert/strict";
import type { Principal } from "../../src/core/auth";
import type { Db, Param } from "../../src/core/db";
import { loadAuthorizedEvidenceIds, supportingDepth } from "../../src/core/evidence";
import { packUnderBudget } from "../../src/core/rank";
import { planFtsQuery, retrieveClaimCandidates } from "../../src/core/retrieval";
import { createSqliteDb, openDatabase } from "../../src/runtime/bun/sqlite";
import { assertPopulatedV10RetrievalMigration } from "../contract/retrieval-migration";
import { estimateTokens } from "../../src/core/tokens";
test("portable budget units count UTF-8 bytes across scripts", () => {
assert.equal(estimateTokens("abc"), 1);
assert.equal(estimateTokens("abcdef"), 2);
assert.equal(estimateTokens("界"), 1);
assert.equal(estimateTokens("😀"), 2);
assert.equal(estimateTokens(""), 0);
});
test("lexical planning normalizes Unicode and drops only bounded function words", () => {
assert.equal(planFtsQuery("q\u200du\u200da\u200dr\u200dt\u200dz").match, '"quartz"');
assert.equal(planFtsQuery("İstanbul").match, '"i̇stanbul"');
assert.equal(
planFtsQuery("ship to prod safely").match,
'"ship" OR "prod" OR "safely"',
);
assert.equal(planFtsQuery("to the").match, '"to" OR "the"');
const long = planFtsQuery(
"Could you please remind me what our team decided about whether we should keep using the old formatter or move to a new one for all of the frontend repositories",
);
assert.match(long.match!, /"old"/);
assert.match(long.match!, /"new"/);
assert.ok(long.termsUsed <= 16);
assert.ok(long.termsDropped > 0);
});
test("packing preserves full-fit rank, then uses diversity under pressure", () => {
const packed = packUnderBudget([
{ value: "a1", kind: "a", tokens: 2 },
{ value: "a2", kind: "a", tokens: 2 },
{ value: "a3", kind: "a", tokens: 2 },
{ value: "a4", kind: "a", tokens: 2 },
{ value: "b1", kind: "b", tokens: 2 },
], 10);
assert.deepEqual(packed, {
selected: ["a1", "a2", "a3", "a4", "b1"],
usedTokens: 10,
omittedCount: 0,
deduplicatedCount: 0,
budgetExhausted: false,
smallestOmittedTokens: null,
omissions: [],
});
assert.deepEqual(packUnderBudget([
{ value: "a1", kind: "a", tokens: 2 },
{ value: "a2", kind: "a", tokens: 2 },
{ value: "a3", kind: "a", tokens: 2 },
{ value: "a4", kind: "a", tokens: 2 },
{ value: "b1", kind: "b", tokens: 2 },
], 8), {
selected: ["a1", "b1", "a2", "a3"],
usedTokens: 8,
omittedCount: 1,
deduplicatedCount: 0,
budgetExhausted: true,
smallestOmittedTokens: 2,
omissions: [{ value: "a4", tokens: 2, reason: "budget_exhausted" }],
});
assert.deepEqual(packUnderBudget([
{ value: "top", kind: "a", tokens: 1, dedupeKey: "same bytes" },
{ value: "duplicate", kind: "b", tokens: 1, dedupeKey: "same bytes" },
{ value: "other", kind: "b", tokens: 1, dedupeKey: "other bytes" },
], 3), {
selected: ["top", "other"],
usedTokens: 2,
omittedCount: 0,
deduplicatedCount: 1,
budgetExhausted: false,
smallestOmittedTokens: null,
omissions: [],
});
assert.deepEqual(packUnderBudget([
{ value: "too-large", kind: "a", tokens: 9 },
], 8), {
selected: [],
usedTokens: 0,
omittedCount: 1,
deduplicatedCount: 0,
budgetExhausted: true,
smallestOmittedTokens: 9,
omissions: [{ value: "too-large", tokens: 9, reason: "result_too_large" }],
});
});
test("partial fit keeps every item that fits and names the ones that do not", () => {
const packed = packUnderBudget([
{ value: "first", kind: "fact", tokens: 100 },
{ value: "second", kind: "fact", tokens: 80 },
{ value: "third", kind: "fact", tokens: 50 },
{ value: "remainder", kind: "fact", tokens: 90 },
{ value: "huge", kind: "fact", tokens: 400 },
], 300);
assert.deepEqual(packed.selected, ["first", "second", "third"]);
assert.equal(packed.usedTokens, 230);
assert.equal(packed.budgetExhausted, true);
assert.equal(packed.omittedCount, packed.omissions.length);
assert.deepEqual(packed.omissions, [
{ value: "remainder", tokens: 90, reason: "budget_exhausted" },
{ value: "huge", tokens: 400, reason: "result_too_large" },
]);
const remaining = 300 - packed.usedTokens;
for (const omission of packed.omissions)
assert.ok(omission.tokens > remaining, "a result that fits the remainder must be included");
// The rank-order pass stops at the first item that does not fit. The fill
// pass must still admit a later item that does.
const later = packUnderBudget([
{ value: "huge", kind: "fact", tokens: 250 },
{ value: "small", kind: "fact", tokens: 40 },
], 200);
assert.deepEqual(later.selected, ["small"]);
assert.equal(later.usedTokens, 40);
assert.deepEqual(later.omissions, [
{ value: "huge", tokens: 250, reason: "result_too_large" },
]);
});
test("hot retrieval SQL bounds candidates and drives evidence from claim sources", async () => {
let capturedSql = "";
let capturedParams: Param[] = [];
const db: Db = {
async all<Row>(sql: string, params: Param[] = []): Promise<Row[]> {
capturedSql = sql;
capturedParams = params;
return [];
},
async batch() {
throw new Error("not used");
},
async exec() {
throw new Error("not used");
},
};
const principal: Principal = {
keyId: "key_test",
orgId: "org_test",
principalId: "agent_test",
principalKind: "agent",
scopes: ["context:compile"],
maxTrust: "verified",
};
await retrieveClaimCandidates(db, principal, '"marker"', {
subjectId: "subject_test",
projectId: null,
crossProject: false,
at: "2026-07-31T00:00:00.000Z",
});
assert.match(capturedSql, /claims_fts MATCH \([\s\S]*org_scope[\s\S]*subject_scope[\s\S]*statement/);
assert.ok(capturedSql.indexOf("subject_scope") < capturedSql.indexOf("ORDER BY bm25"));
assert.ok(capturedSql.indexOf("LIMIT ?") < capturedSql.indexOf("FROM claim_sources s"));
assert.ok(capturedSql.indexOf("LIMIT ?") < capturedSql.indexOf("context_feedback"));
assert.deepEqual(capturedParams.slice(0, 5), [
"org_test",
"subject_test",
'"marker"',
"org_test",
"subject_test",
]);
await loadAuthorizedEvidenceIds(db, principal, ["claim_late", "claim_early"]);
// The relation travels with the source so ranking can tell corroboration from
// contradiction. Counting rows instead would make the most disputed claim in a
// store look like the best supported one.
assert.match(capturedSql, /SELECT s\.claim_id, s\.observation_id, s\.relation/);
assert.equal(supportingDepth(undefined), 0);
assert.equal(
supportingDepth([
{ observationId: "obs_a", relation: "supports" },
{ observationId: "obs_b", relation: "supports" },
{ observationId: "obs_c", relation: "contradicts" },
{ observationId: "obs_d", relation: "qualifies" },
]),
2,
);
assert.match(capturedSql, /FROM claim_sources s/);
assert.doesNotMatch(capturedSql, /JOIN observations/);
assert.match(capturedSql, /EXISTS \([\s\S]*FROM observations o/);
assert.match(capturedSql, /o\.id = s\.observation_id/);
assert.match(capturedSql, /o\.org_id = \?/);
assert.match(capturedSql, /o\.visibility/);
assert.deepEqual(capturedParams, [
"claim_late",
"claim_early",
"org_test",
"agent_test",
"agent_test",
"agent_test",
"agent_test",
"key_test",
"key_test",
"key_test",
"key_test",
"key_test",
"key_test",
"key_test",
]);
});
test("schema v10 migrates by rebuilding and backfilling scoped Porter FTS", async () => {
const handle = openDatabase(":memory:");
try {
await assertPopulatedV10RetrievalMigration(createSqliteDb(handle));
} finally {
handle.close();
}
});