test(08-03): rollout pins RO1/RO2 — the D-01 locks enforced suite-side (full battery green)
- RO1 upload-format-agnostic: upload-road-graph.mjs keeps KEY 'kl-roadgraph.v1.bin' + BUCKET 'araharah-graphs'; comment-stripped code contains ZERO format tokens (landmark/encodeGraph/decodeGraph/ARG1/ARG2 magics/GRAPH_VERSION) — the migration is byte-shipping of the same key, forever (A8 grep-shape) - RO2 one decode path: worker-router.ts keeps GRAPH_KEY unchanged, exactly ONE decodeGraph call in the loadGraph flow, no version-conditional branch (GRAPH_VERSION / magics / '=== 2' absent) — an undecodable binary flows to the existing null -> router-pending path (D-01 at the consumer) - full battery at this commit — the FIRST where routeAstar consults real landmark tables on the bot suite's ARG2 corridor graphs: routing 79/79 (A1 seal + A9/A10/A11 + RO1/RO2), bot 126/126 (RT trunks + cron), routing+bot typechecks clean; worker-router.ts and upload-road-graph.mjs untouched (git diff --stat empty)
This commit is contained in:
@@ -0,0 +1,97 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
/*
|
||||||
|
* rollout.test.mjs — the D-01 rollout locks as structural pins (RO1–RO2).
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
* Plan 08-03 task 2: the ARG2 migration is "rebuild the binary, re-upload the
|
||||||
|
* SAME key" — nothing else. These pins make the locks MECHANICAL: the upload
|
||||||
|
* script can never grow format awareness and the Worker can never grow a
|
||||||
|
* version branch without failing the suite (T-08-08 — enforced, not
|
||||||
|
* customary). Grep mechanics are A8's exact shape (comment stripping, assert
|
||||||
|
* on stripped code) so a doc-comment mention can never satisfy a pin.
|
||||||
|
*
|
||||||
|
* RO1 upload-format-agnostic — upload-road-graph.mjs keeps the storage
|
||||||
|
* contract (KEY + BUCKET) and its
|
||||||
|
* comment-stripped code contains ZERO format
|
||||||
|
* tokens (no landmark/encode/decode/magic/
|
||||||
|
* GRAPH_VERSION): byte-shipping of the same
|
||||||
|
* key is the whole migration, forever
|
||||||
|
* RO2 one decode path — worker-router.ts keeps GRAPH_KEY unchanged
|
||||||
|
* and exactly ONE decodeGraph call inside the
|
||||||
|
* loadGraph flow, with NO version-conditional
|
||||||
|
* branch (an undecodable binary flows to the
|
||||||
|
* existing null -> router-pending path)
|
||||||
|
*
|
||||||
|
* NOT duplicated here: RP1a (bot/test/route-privacy.test.mjs) already pins
|
||||||
|
* the router's claim-bound identity and never-fetch law — RO2 pins the
|
||||||
|
* FORMAT-agnostic law, RP pins the identity/no-fetch law.
|
||||||
|
*
|
||||||
|
* Run: npm run routing:test (exit 0 = all green)
|
||||||
|
*/
|
||||||
|
import { strict as assert } from "node:assert";
|
||||||
|
import { readFileSync } from "node:fs";
|
||||||
|
import path from "node:path";
|
||||||
|
import { fileURLToPath } from "node:url";
|
||||||
|
import { test } from "./harness.mjs";
|
||||||
|
|
||||||
|
const here = path.dirname(fileURLToPath(import.meta.url)); // routing/test
|
||||||
|
|
||||||
|
/** A8's comment-strip shape: block comments first, then line comments
|
||||||
|
* (the ([^:\\]) guard keeps "://" URLs intact). Assert on STRIPPED code —
|
||||||
|
* a doc-comment mention can never satisfy a pin. */
|
||||||
|
function stripComments(src) {
|
||||||
|
return src
|
||||||
|
.replace(/\/\*[\s\S]*?\*\//g, " ")
|
||||||
|
.replace(/(^|[^:\\])\/\/[^\n]*/g, "$1");
|
||||||
|
}
|
||||||
|
|
||||||
|
test("RO1 upload-format-agnostic — the upload path is byte-shipping, never format-aware", () => {
|
||||||
|
const src = readFileSync(
|
||||||
|
path.join(here, "..", "scripts", "upload-road-graph.mjs"),
|
||||||
|
"utf8",
|
||||||
|
);
|
||||||
|
// The storage contract: must agree with worker-router.ts's GRAPH_KEY and
|
||||||
|
// bot/wrangler.jsonc's ROAD_GRAPH binding bucket_name (the header's fork
|
||||||
|
// contract — your graph, YOUR bucket, same key path).
|
||||||
|
assert.ok(src.includes('KEY = "kl-roadgraph.v1.bin"'), "the R2 object key is pinned (renaming it is prohibited — D-01)");
|
||||||
|
assert.ok(src.includes('BUCKET = "araharah-graphs"'), "the R2 bucket is pinned");
|
||||||
|
// ZERO format awareness in CODE (comment-stripped): the script ships
|
||||||
|
// bytes; the binary's header is the only format authority. A fork's
|
||||||
|
// upload path stays layout-agnostic forever — it can never grow a
|
||||||
|
// landmark/codec/version fork of its own.
|
||||||
|
const code = stripComments(src);
|
||||||
|
for (const token of [
|
||||||
|
"landmark",
|
||||||
|
"encodeGraph",
|
||||||
|
"decodeGraph",
|
||||||
|
"0x41524731", // ARG1 magic
|
||||||
|
"0x41524732", // ARG2 magic
|
||||||
|
"GRAPH_VERSION",
|
||||||
|
]) {
|
||||||
|
assert.ok(!code.includes(token), `upload code must never reference ${token} (the migration is byte-shipping — D-01)`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test("RO2 one decode path at the Worker — the router never branches on format", () => {
|
||||||
|
const src = readFileSync(
|
||||||
|
path.join(here, "..", "..", "bot", "src", "routing", "worker-router.ts"),
|
||||||
|
"utf8",
|
||||||
|
);
|
||||||
|
const code = stripComments(src);
|
||||||
|
// The storage NAME is unchanged ("v1" is a storage name; the binary header
|
||||||
|
// is the format truth — documented law, never "fixed" in this phase).
|
||||||
|
assert.ok(
|
||||||
|
code.includes('GRAPH_KEY = "kl-roadgraph.v1.bin"'),
|
||||||
|
"GRAPH_KEY unchanged (the upload key must keep agreeing)",
|
||||||
|
);
|
||||||
|
// Exactly ONE decodeGraph CALL — the loadGraph flow's single decode path.
|
||||||
|
// An undecodable binary flows to the existing null -> router-pending
|
||||||
|
// 200-null path (D-01's one-path law at the consumer); a second decode
|
||||||
|
// branch (v1 fallback, per-version paths) would fail this pin.
|
||||||
|
const calls = code.match(/decodeGraph\(/g) ?? [];
|
||||||
|
assert.equal(calls.length, 1, "exactly one decodeGraph call site — the ONE decode path");
|
||||||
|
// NO version-conditional branch against the graph bytes: no version
|
||||||
|
// constant import/compare, no magic, no `=== 2` anywhere in the file.
|
||||||
|
for (const token of ["GRAPH_VERSION", "0x41524731", "0x41524732", "=== 2"]) {
|
||||||
|
assert.ok(!code.includes(token), `the router must never branch on format (${token})`);
|
||||||
|
}
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user