test(04-04): the BA7/BA8 drift gates + the search-tree GEO3 pin + the destination-preload capture leg

- BA7: the shipped JS must carry EVERY committed gazetteer id (the
  web half of bot/web id-set parity, T-04-39) — RED against the
  pre-gazetteer bundle, green after the resolver lands in the build
- BA8: the shipped JS carries NO deep-link crypto (JS assets only —
  the official Telegram SDK is external, D-11/T-04-40)
- no-storage: explicit web/src/search memory-only + no-crypto pin
- capture.mjs: the ARAHARAH-DEST signal race + the 'dest' wait mode
  (state=resolved asserted, then the rendered card's text is waited
  on — the card mounts at live, T-04-42) + the shell-dest-preload
  leg; 8/8 expected captures
This commit is contained in:
araharah-executor
2026-10-24 01:38:24 +08:00
parent c2d78b0c8f
commit 747eeb7b34
3 changed files with 106 additions and 6 deletions
+41
View File
@@ -24,6 +24,17 @@
* BA5 pointed there would invert the gate it exists to enforce.
* BA6 no emitted HTML carries the runner page's /api/session or
* /api/location-fallback fetch stubs (same dead-code-elimination proof)
* BA7 the shipped JS carries EVERY gazetteer id from the committed
* dataset (search/src/data/kl-gazetteer.json) — the WEB half of the
* bot/web id-set parity gate (T-04-39): a stale web bundle ships
* without an id the bot just deep-linked, and the webview could
* never resolve it
* BA8 the shipped JS carries NO deep-link crypto (createHmac,
* crypto.subtle, sha256, HMAC() — the deep link is a plain public id
* (D-11, T-04-40). Scans the JS ASSETS only, never the HTML: the
* OFFICIAL Telegram SDK script is loaded EXTERNALLY from
* telegram.org (not bundled) and may contain crypto internals of
* its own.
*
* If web/dist does not exist, every case fails with a build-first message.
*/
@@ -33,6 +44,7 @@ import { join } from "node:path";
import { fileURLToPath } from "node:url";
import path from "node:path";
import { test } from "./harness.mjs";
import gazetteer from "../../search/src/data/kl-gazetteer.json" with { type: "json" };
const WEB = path.join(fileURLToPath(new URL(import.meta.url)), "..", "..");
const DIST = join(WEB, "dist");
@@ -133,3 +145,32 @@ test("BA6 production HTML carries NO runner-page fetch stub endpoints", () => {
);
}
});
test("BA7 the shipped bundle carries EVERY gazetteer id (the bot/web id-set parity gate, T-04-39)", () => {
assert.ok(existsSync(DIST_ASSETS), claimBuildFirst().message);
const bundle = jsFiles
.filter((f) => f.startsWith(DIST_ASSETS))
.map((f) => readFileSync(f, "utf8"))
.join("");
assert.ok(gazetteer.entries.length >= 30, `scanned a real dataset (found ${gazetteer.entries.length} entries)`);
for (const entry of gazetteer.entries) {
assert.ok(
bundle.includes(entry.id),
`gazetteer id "${entry.id}" is MISSING from the shipped web bundle — a stale bundle the webview cannot resolve against (T-04-39); ids are never renamed, only added`,
);
}
});
test("BA8 the shipped bundle carries NO deep-link crypto (D-11, T-04-40)", () => {
assert.ok(existsSync(DIST_ASSETS), claimBuildFirst().message);
const bundle = jsFiles
.filter((f) => f.startsWith(DIST_ASSETS))
.map((f) => readFileSync(f, "utf8"))
.join("");
for (const token of ["createHmac", "crypto.subtle", "sha256", "HMAC("]) {
assert.ok(
!bundle.includes(token),
`"${token}" found in a web/dist JS asset — the deep link is a PLAIN public id, no crypto anywhere in the path (D-11)`,
);
}
});