fix: harden durable runtime DEV gates
This commit is contained in:
@@ -76,6 +76,53 @@ test("live mode requires /v1 durable readiness before M3 writes", async () => {
|
||||
assert.equal(report.blockers.some((blocker) => blocker.scope === "api-v1"), true);
|
||||
});
|
||||
|
||||
test("live mode requires /v1 to expose the controlled M3 IO route before M3 writes", async () => {
|
||||
const report = await buildDevRuntimePostflightReport(
|
||||
parseArgs(["--live", "--confirm-dev", "--confirmed-non-production"]),
|
||||
{
|
||||
httpGetJson: async (url) => {
|
||||
const payload = apiPayload({ ready: true });
|
||||
if (url.endsWith("/v1")) {
|
||||
delete payload.m3IoControl;
|
||||
}
|
||||
return { ok: true, status: 200, json: payload };
|
||||
},
|
||||
m3Runner: async () => {
|
||||
throw new Error("M3 runner should not run when /v1 omits the M3 IO contract");
|
||||
},
|
||||
now: () => "2026-05-23T00:00:00.000Z"
|
||||
}
|
||||
);
|
||||
|
||||
assert.equal(report.conclusion.status, "blocked");
|
||||
assert.equal(report.actions.m3MutationAttempted, false);
|
||||
assert.equal(report.blockers.some((blocker) =>
|
||||
blocker.scope === "api-v1" &&
|
||||
blocker.summary.includes("controlled M3 IO route")
|
||||
), true);
|
||||
});
|
||||
|
||||
test("live mode does not mistake DB live evidence for durable runtime readiness", async () => {
|
||||
const report = await buildDevRuntimePostflightReport(
|
||||
parseArgs(["--live", "--confirm-dev", "--confirmed-non-production"]),
|
||||
{
|
||||
httpGetJson: async () => ({ ok: true, status: 200, json: tcpOnlyPayload() }),
|
||||
m3Runner: async () => {
|
||||
throw new Error("M3 runner should not run when only TCP/SecretRef DB readiness is green");
|
||||
},
|
||||
now: () => "2026-05-23T00:00:00.000Z"
|
||||
}
|
||||
);
|
||||
|
||||
assert.equal(report.conclusion.status, "blocked");
|
||||
assert.equal(report.apiHealth.db.connected, true);
|
||||
assert.equal(report.apiHealth.db.liveDbEvidence, true);
|
||||
assert.equal(report.apiHealth.runtime.durable, false);
|
||||
assert.equal(report.apiHealth.readiness.durabilityReady, false);
|
||||
assert.equal(report.actions.m3MutationAttempted, false);
|
||||
assert.equal(report.blockers.some((blocker) => blocker.scope === "api-health-live"), true);
|
||||
});
|
||||
|
||||
test("live mode records M3 true/false durable green evidence", async () => {
|
||||
const report = await buildDevRuntimePostflightReport(
|
||||
parseArgs(["--live", "--confirm-dev", "--confirmed-non-production"]),
|
||||
@@ -91,6 +138,14 @@ test("live mode records M3 true/false durable green evidence", async () => {
|
||||
assert.equal(report.actions.m3MutationAllowed, true);
|
||||
assert.equal(report.m3.trustedGreen, true);
|
||||
assert.equal(report.m3.operationCount, 4);
|
||||
assert.equal(report.m3.persisted, true);
|
||||
assert.equal(report.m3.persistenceContract.ready, true);
|
||||
assert.deepEqual(report.m3.persistenceContract.sequence.map((item) => [item.id, item.observedValue, item.persisted]), [
|
||||
["write-do1-true", true, true],
|
||||
["read-di1-true", true, true],
|
||||
["write-do1-false", false, true],
|
||||
["read-di1-false", false, true]
|
||||
]);
|
||||
assert.deepEqual(report.m3.operations.map((operation) => operation.resultValue), [true, true, false, false]);
|
||||
assert.equal(report.blockers.length, 0);
|
||||
});
|
||||
@@ -108,7 +163,26 @@ test("live mode blocks when M3 operation evidence is not durable green", async (
|
||||
);
|
||||
|
||||
assert.equal(report.conclusion.status, "blocked");
|
||||
assert.equal(report.blockers.some((blocker) => blocker.scope === "m3-durable-evidence"), true);
|
||||
assert.equal(report.blockers.some((blocker) => blocker.scope === "m3-durable-postflight"), true);
|
||||
assert.equal(report.m3.persistenceContract.ready, false);
|
||||
});
|
||||
|
||||
test("live mode blocks when M3 true/false persisted sequence is incomplete", async () => {
|
||||
const m3 = m3GreenReport();
|
||||
m3.liveOperations = m3.liveOperations.slice(0, 3);
|
||||
const report = await buildDevRuntimePostflightReport(
|
||||
parseArgs(["--live", "--confirm-dev", "--confirmed-non-production"]),
|
||||
{
|
||||
httpGetJson: async () => ({ ok: true, status: 200, json: apiPayload({ ready: true }) }),
|
||||
m3Runner: async () => m3,
|
||||
now: () => "2026-05-23T00:00:00.000Z"
|
||||
}
|
||||
);
|
||||
|
||||
assert.equal(report.conclusion.status, "blocked");
|
||||
assert.equal(report.m3.persistenceContract.ready, false);
|
||||
assert.equal(report.m3.persistenceContract.sequence.at(-1).status, "missing");
|
||||
assert.equal(report.blockers.some((blocker) => blocker.scope === "m3-durable-postflight"), true);
|
||||
});
|
||||
|
||||
function apiPayload({ ready }) {
|
||||
@@ -160,10 +234,38 @@ function apiPayload({ ready }) {
|
||||
}
|
||||
},
|
||||
blockerCodes: ready ? []
|
||||
: ["runtime_durable_adapter_auth_blocked"]
|
||||
: ["runtime_durable_adapter_auth_blocked"],
|
||||
m3IoControl: {
|
||||
route: "/v1/m3/io",
|
||||
status: "available",
|
||||
contractVersion: "m3-io-control-v1",
|
||||
boundaries: {
|
||||
directFrontendGatewayOrBoxAccess: false,
|
||||
genericHardwareRpcExposedToFrontend: false
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function tcpOnlyPayload() {
|
||||
const payload = apiPayload({ ready: false });
|
||||
payload.db.ready = true;
|
||||
payload.db.connected = true;
|
||||
payload.db.liveDbEvidence = true;
|
||||
payload.db.connectionResult = "connected";
|
||||
payload.db.runtimeReadiness.blocker = "runtime_durable_adapter_query_blocked";
|
||||
payload.db.runtimeReadiness.queryResult = "query_blocked";
|
||||
payload.runtime.blocker = "runtime_durable_adapter_query_blocked";
|
||||
payload.runtime.durabilityContract.blockedLayer = "durability_query";
|
||||
payload.runtime.gates.auth = gate(true);
|
||||
payload.runtime.gates.schema = gate(true);
|
||||
payload.runtime.gates.migration = gate(true);
|
||||
payload.runtime.gates.durability = gate(false, "runtime_durable_adapter_query_blocked");
|
||||
payload.readiness.durability.blockedLayer = "durability_query";
|
||||
payload.blockerCodes = ["runtime_durable_adapter_query_blocked"];
|
||||
return payload;
|
||||
}
|
||||
|
||||
function gate(ready, blocker = null) {
|
||||
return {
|
||||
checked: true,
|
||||
@@ -195,7 +297,8 @@ function m3GreenReport() {
|
||||
evidenceState: {
|
||||
status: "green",
|
||||
durable: true,
|
||||
sourceKind: "DEV-LIVE"
|
||||
sourceKind: "DEV-LIVE",
|
||||
writeStatus: "persisted"
|
||||
}
|
||||
}))
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user