Prove every ext-state write by reading the key back, so no guard is constant-true

SetProjExtState's return describes the whole extname. The persist and the instrument's publish now re-read their key; both refusals can finally fire.
This commit is contained in:
2026-08-02 13:14:49 -04:00
parent 0afb885987
commit 25390d5253
14 changed files with 231 additions and 112 deletions
+20 -13
View File
@@ -130,9 +130,11 @@ private:
// One entry's write-back, and the proof of whether it took. Guarded whole: it encodes into
// a fresh string and readKey grows a buffer toward 16 MB, and a throw escaping here would
// skip the ShowConsoleMsg for EVERY key — the silent console this action exists to make
// impossible. A throw is `Unknown` rather than a failure because the write may well have
// landed before the check did.
// impossible. Which proof a throw yields turns on whether SetProjExtState had run: before
// it, the write is KNOWN not to have been made (`Rejected`); after it, the write may well
// have landed and only the check failed (`Unknown`).
wire::BakeWriteProof writeBackOne(ScannedKey& entry, bool persisted) {
bool issued = false;
try {
std::string value; // empty = clear the key
if (entry.write == ScannedKey::Write::Answer) {
@@ -146,7 +148,8 @@ wire::BakeWriteProof writeBackOne(ScannedKey& entry, bool persisted) {
entry.outcome = refuseBake(
BakeStatus::Failed,
"the bake reached the bank in memory, but this pass's persist did not "
"report success, so this answer cannot promise a reload will find it",
"confirm its bank write, so this answer cannot promise a reload will "
"find it",
entry.outcome.generation);
// `detail` left empty on purpose: describeLanding's Unpersisted clause is
// that sentence's one home on the console side, and the message above is
@@ -158,16 +161,16 @@ wire::BakeWriteProof writeBackOne(ScannedKey& entry, bool persisted) {
value = wire::encodeBakeOutcome(entry.outcome);
}
SetProjExtState(entry.proj, kProjExtNamespace(), entry.key.c_str(), value.c_str());
// SetProjExtState's own return is the size of the whole extname's state, which
// `banks` alone keeps non-zero in every case a bake can reach, so only re-reading
// THIS key can speak for it. An oversized read proves nothing either way — folding
// it into bakeWriteLanded's absent case would report a clear off unread bytes.
issued = true;
// Only re-reading THIS key can speak for it (wire::extStateWriteLanded owns why).
// An oversized read proves nothing either way — folding it into that predicate's
// absent case would report a clear off unread bytes.
const KeyRead back = readKey(entry.proj, entry.key);
if (back.oversized) return wire::BakeWriteProof::Unknown;
return wire::bakeWriteLanded(value, back.value) ? wire::BakeWriteProof::Confirmed
: wire::BakeWriteProof::Rejected;
return wire::extStateWriteLanded(value, back.value) ? wire::BakeWriteProof::Confirmed
: wire::BakeWriteProof::Rejected;
} catch (...) {
return wire::BakeWriteProof::Unknown;
return issued ? wire::BakeWriteProof::Unknown : wire::BakeWriteProof::Rejected;
}
}
@@ -193,8 +196,12 @@ void RunResampleBake(ReaSamplerSession& session) {
std::vector<ScannedKey> scanned;
wire::BakeScanTally tally; // every verdict below is counted, skips included
std::string aborted; // set only when the scan itself threw
bool persisted = false; // the pass's ONE persist reported success
bool persisted = false; // the pass's ONE persist confirmed its bank write
bool bookChanged = false; // some landing added or refreshed an entry
// A local, not a tally field: an entry counted here can still be re-answered as a
// failure by the write-back loop below, so this is a persist GATE and never a count
// anything reports.
bool anyLanded = false;
// The scan allocates outside attemptLanding's own guards too (readKey grows a buffer
// toward 16 MB, every container here allocates), and a throw that escaped would discard
// the answers already buffered — the exact no-answer-with-a-silent-console this action
@@ -253,7 +260,7 @@ void RunResampleBake(ReaSamplerSession& session) {
request->generation);
} else {
LandingAttempt attempt = attemptLanding(session, open.dir, *request);
if (attempt.outcome.status == BakeStatus::Ok) ++tally.landed;
if (attempt.outcome.status == BakeStatus::Ok) anyLanded = true;
if (attempt.changedBook) bookChanged = true;
// Never Banked here, on ANY path: the pass's persist has not run yet,
// and bakeLandingAfterPersist is the one place that word is earned. A
@@ -273,7 +280,7 @@ void RunResampleBake(ReaSamplerSession& session) {
}
}
if (tally.landed > 0) {
if (anyLanded) {
// A dedup hit rides the persist too, because that is the only observation that
// can promote its landing — but it added nothing, so it earns neither the
// refresh every open instance pays for nor an undo point named after a bake