fix(07-03): fold the follow-up fixes described in 07-03-SUMMARY
- asset-header probe reads HTTP status BEFORE interpreting headers — a non-2xx is deployment drift (the notRun exit-2 class), never a cache violation; the violations.length count bug fixed - XHTML namespace URI joins the SVG spec-identifier adjudication - probeUnavailable carries the reason only (the CLI prints NOT RUN) - CP2/AU1 suite vectors updated to the corrected contracts Residue note: these edits were on the tree during 07-03/07-04 execution but escaped those plans' commits (07-04-SUMMARY residue caution).
This commit is contained in:
@@ -37,9 +37,10 @@ const WRANGLER_JSONC = path.join(REPO_ROOT, "bot", "wrangler.jsonc");
|
||||
* family is REPORTED, never assumed absent (07-RESEARCH A5). */
|
||||
export const KEY_FAMILIES = ["session:", "chat:", "loc:", "guidance:"];
|
||||
|
||||
/** A missing environment is the exit-2 class: pass:false + notRun:true. */
|
||||
/** A missing environment is the exit-2 class: pass:false + notRun:true. The
|
||||
* evidence carries the REASON only — the CLI prints the NOT RUN status. */
|
||||
export function probeUnavailable(reason) {
|
||||
return { id: "probe", pass: false, notRun: true, evidence: `NOT RUN — ${reason}` };
|
||||
return { id: "probe", pass: false, notRun: true, evidence: reason };
|
||||
}
|
||||
|
||||
function notRun(id, reason) {
|
||||
@@ -178,6 +179,12 @@ function categoryOf(err) {
|
||||
* `cf-cache-status` headers VERBATIM. CF-Cache-Status is probabilistic per
|
||||
* Cloudflare's own footnote — the evidence prints it, it does not interpret
|
||||
* it as a guarantee (07-RESEARCH Pitfall 10).
|
||||
*
|
||||
* Honesty laws: every leg's HTTP status is read BEFORE any header is
|
||||
* interpreted — a non-2xx is deployment/environment drift (the notRun
|
||||
* class), never a cache-header violation. The immutable `/assets/*` policy
|
||||
* itself is `web/public/_headers`' claim (07-04) — this probe quotes, it
|
||||
* does not assert the policy.
|
||||
*/
|
||||
export function runAssetHeaderProbe(opts = {}) {
|
||||
const id = "asset-headers";
|
||||
@@ -193,7 +200,7 @@ export function runAssetHeaderProbe(opts = {}) {
|
||||
}
|
||||
|
||||
const lines = [];
|
||||
let violations = 0;
|
||||
const observed = [];
|
||||
const targets = [["HTML entry /", `${baseUrl}/`]];
|
||||
if (assetPath !== null) targets.push([`hashed asset ${assetPath}`, `${baseUrl}${assetPath}`]);
|
||||
try {
|
||||
@@ -203,23 +210,31 @@ export function runAssetHeaderProbe(opts = {}) {
|
||||
timeout: 30000,
|
||||
stdio: ["ignore", "pipe", "pipe"],
|
||||
});
|
||||
const status = Number(out.match(/^HTTP\/[\d.]+\s+(\d+)/m)?.[1] ?? 0);
|
||||
const cacheControl = out.match(/^cache-control:.*$/im)?.[0]?.trim() ?? null;
|
||||
const cfStatus = out.match(/^cf-cache-status:.*$/im)?.[0]?.trim() ?? null;
|
||||
if (cacheControl === null) {
|
||||
violations += 1;
|
||||
lines.push(`${label}: no cache-control header observed`);
|
||||
} else {
|
||||
lines.push(`${label}: ${cacheControl}${cfStatus !== null ? ` | ${cfStatus}` : " | cf-cache-status: not reported by this response"}`);
|
||||
observed.push(
|
||||
`${label}: HTTP ${status || "unknown"}${cacheControl !== null ? ` | ${cacheControl}` : " | no cache-control"}${cfStatus !== null ? ` | ${cfStatus}` : ""}`,
|
||||
);
|
||||
if (!Number.isInteger(status) || status < 200 || status >= 400) {
|
||||
return notRun(
|
||||
id,
|
||||
`deployment drift — ${label} answered HTTP ${status || "unknown"} ` +
|
||||
`(the deployed origin does not match web/dist); observed: ${observed.join(" || ")}`,
|
||||
);
|
||||
}
|
||||
if (cacheControl === null) lines.push(`${label}: NO cache-control header observed`);
|
||||
else lines.push(`${label}: ${cacheControl} | ${cfStatus ?? "cf-cache-status not reported"}`);
|
||||
}
|
||||
} catch (err) {
|
||||
return notRun(id, `origin unreachable (${categoryOf(err)})`);
|
||||
}
|
||||
|
||||
const violations = lines.filter((l) => l.includes("NO cache-control")).length;
|
||||
const pass = violations === 0;
|
||||
const evidence = pass
|
||||
? `${targets.length} response header(s), VERBATIM (cf-cache-status is probabilistic — reported, not interpreted as a guarantee): ${lines.join(" || ")}`
|
||||
: `${violations.length} violation(s): ${lines.join(" || ")}`;
|
||||
? `${targets.length} response header(s), VERBATIM (cf-cache-status is probabilistic — quoted, never interpreted as a guarantee): ${lines.join(" || ")}`
|
||||
: `${violations} violation(s): ${lines.join(" || ")}`;
|
||||
return { id, pass, evidence, violations };
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user