Distinguish main matches from related suggestions and ship 0.1.9

This commit is contained in:
karl committed 2026-10-14 12:45:32 +02:00
1 parent a8ba594d0e
commit b0bdfc7816
40 files changed
+2463 -185

No files matched your search

+64 -8
View File
@@ -25,6 +25,12 @@ const out = resolve(
repository,
process.env.SEARCHI_CAPTURE_OUTPUT ?? "docs/screenshots",
);
const frontendVersion = JSON.parse(await readFile(
resolve(repository, "apps/desktop/package.json"), "utf8")).version;
if (process.env.SEARCHI_CAPTURE_EXPECTED_VERSION) {
assert.equal(frontendVersion, process.env.SEARCHI_CAPTURE_EXPECTED_VERSION,
"Frontend metadata must match the version intended for this capture");
}
const infoResponse = await fetch(new URL("/capture-info", target), {
signal: AbortSignal.timeout(15000),
});
@@ -35,6 +41,10 @@ assert(
"Requires an initialized real-engine capture backend",
);
await mkdir(out, { recursive: true });
assert(process.env.SEARCHI_CAPTURE_BACKEND_EXE,
"Set SEARCHI_CAPTURE_BACKEND_EXE to the actual owned backend executable for provenance");
const captureBackendSha256 = createHash("sha256")
.update(await readFile(process.env.SEARCHI_CAPTURE_BACKEND_EXE)).digest("hex");
const browser = await chromium.launch({
headless: true,
args: [
@@ -47,6 +57,7 @@ const failures = [];
const evidence = [];
const measured = [];
let latestMeasured;
const isRelated = (result) => result.match_kind?.endsWith("_related") === true;
const source = {
base_commit: execFileSync("git", ["rev-parse", "HEAD"], {
cwd: repository,
@@ -58,6 +69,17 @@ const source = {
encoding: "utf8",
}).trim().length > 0,
};
source.source_sha256 = {};
for (const name of [
"crates/searchi-service/src/lib.rs", "crates/searchi-service/src/relevance.rs",
"apps/desktop/src/main.ts", "apps/desktop/src/style.css",
"tools/desktop-capture/backend/src/main.rs", "tools/desktop-capture/capture.mjs",
"tools/relevance-eval/policies/evidence-v1.json",
]) {
source.source_sha256[name] = createHash("sha256")
.update(await readFile(resolve(repository, name))).digest("hex");
}
source.capture_backend_sha256 = captureBackendSha256;
try {
const context = await browser.newContext({
viewport: { width: 1440, height: 1000 },
@@ -139,6 +161,8 @@ try {
query: text,
mode: debug ? "debug" : "basic",
result_count: body.results.length,
main_result_count: body.results.filter((result) => !isRelated(result)).length,
related_result_count: body.results.filter(isRelated).length,
metrics: body.metrics,
first_filename: body.results[0]?.filename,
first_source: body.results[0]?.source,
@@ -160,7 +184,7 @@ try {
{
query: text,
filename: latestMeasured.first_filename,
count: latestMeasured.result_count,
count: latestMeasured.main_result_count,
},
{ timeout: 60000 },
);
@@ -168,15 +192,22 @@ try {
(await page.locator("#results .result").count()) > 0,
`Real query returned no matches: ${text}`,
);
assert.equal(await page.locator("#related-results .result").count(), 0,
"Collapsed related neighbors must stay out of keyboard/focusable result rows");
assert.equal(await page.locator("#related-suggestions").evaluate((element) => element.open),
false, "Related suggestions must be collapsed for a new query");
await page.locator("#results .result").first().click();
await page.waitForFunction(
() => !document.querySelector("#preview")?.hidden,
);
if (text === "cancel the supplier partnership") {
assert(
!body.results.some((result) => ["Mountain Lake.jpg", "Night Pier.jpg"].includes(result.filename)),
"Contract results must not contain the unrelated fixture photos",
body.results.filter((result) => ["Mountain Lake.jpg", "Night Pier.jpg"].includes(result.filename))
.every(isRelated),
"Contract photos must remain related suggestions rather than primary results",
);
assert(body.results.some((result) => result.filename === "Mountain Lake.jpg"),
"Eligible mountain photo must remain accessible as a related suggestion");
assert.equal(
latestMeasured.first_filename,
"Supplier Agreement.pdf",
@@ -251,12 +282,13 @@ try {
literal_query_marks: true,
actual_page_explanation: true,
why_disclosure_collapsed_by_default: true,
unrelated_photos_removed: true,
unrelated_photos_in_collapsed_related_group: true,
};
}
if (text === "mountains reflected in calm water") {
assert(body.results.every((result) => result.match_kind === "semantic_image"),
"Visual search shortlist must not contain the unrelated fixture documents");
assert(body.results.filter((result) => !isRelated(result))
.every((result) => result.match_kind === "semantic_image"),
"Visual search primary results must not contain unrelated fixture documents");
assert.equal(
latestMeasured.first_filename,
"Mountain Lake.jpg",
@@ -267,7 +299,7 @@ try {
0,
"Meaning-only photo result must not invent word-level alignment",
);
latestMeasured.ui_checks = { meaning_only_image_has_no_text_marks: true, unrelated_documents_removed: true };
latestMeasured.ui_checks = { meaning_only_image_has_no_text_marks: true, related_sources_retained: true };
}
await page.evaluate(
() =>
@@ -298,6 +330,9 @@ try {
query: queryText,
mode: latestMeasured.mode,
result_count: latestMeasured.result_count,
main_result_count: latestMeasured.main_result_count,
related_result_count: latestMeasured.related_result_count,
related_expanded: await page.locator("#related-suggestions").evaluate((element) => element.open),
selected_filename: selected,
first_source_kind: latestMeasured.first_source?.kind,
first_source_number: latestMeasured.first_source?.number,
@@ -322,7 +357,28 @@ try {
}
const documentQuery = "cancel the supplier partnership";
await query(documentQuery);
await page.locator("#query").press("ArrowDown");
assert.equal(await page.locator("#preview-title").innerText(), "Supplier Agreement.pdf",
"Collapsed related suggestions must not enter arrow-key selection");
latestMeasured.ui_checks.collapsed_related_skipped_by_keyboard = true;
await screenshot("search-light", documentQuery);
await page.locator("#related-suggestions > summary").focus();
await page.locator("#related-suggestions > summary").press("ArrowDown");
await page.locator("#related-results .result").first().waitFor({ state: "visible" });
assert.equal(await page.locator("#related-results .result").count(),
latestMeasured.related_result_count, "Expanding must restore every actual related neighbor");
assert.equal(await page.locator("#preview-title").innerText(),
await page.locator("#related-results .result strong").first().innerText(),
"ArrowDown on related disclosure must select its first actual candidate");
await page.locator("#results .result").first().click();
assert(await page.locator("#related-results .result").filter({ hasText: "Mountain Lake.jpg" }).count(),
"Expanded related suggestions must expose the actual mountain candidate");
await screenshot("related-suggestions", documentQuery);
await page.locator("#related-results .result").first().click();
await page.locator("#related-suggestions > summary").click();
await page.waitForFunction(() => document.querySelector("#preview-title")?.textContent === "Supplier Agreement.pdf");
assert.equal(await page.locator("#preview-title").innerText(), "Supplier Agreement.pdf",
"Collapsing related suggestions must restore visible primary selection");
await page.emulateMedia({ colorScheme: "dark" });
await screenshot("search-dark", documentQuery);
await page.emulateMedia({ colorScheme: "light" });
@@ -402,7 +458,7 @@ try {
kind: "browser-rendered-production-ui-real-cpu-engine",
source,
frontend_build: {
version: JSON.parse(await readFile(resolve(repository, "apps/desktop/package.json"), "utf8")).version,
version: frontendVersion,
index_sha256: createHash("sha256").update(await readFile(resolve(repository, "apps/desktop/dist/index.html"))).digest("hex"),
},
viewport: { width: 1440, height: 1000 },