Relationships
#4010 judgeRunRecord lets a forged record settle a waiting approval gate to skipped without an approve
Opened by skunk-ape · 10/27/2026
Found by verify-build on swamp-club#3970's branch (base df3636764, main at the time). The failing property test is unrelated to that change and was added by swamp-club#3922 (#3396).
Failure
src/domain/datastore_v3/run_record_model_property_test.ts, test "judgeRunRecord (model): no forged record a run-only caller can land breaks the run's guarantees", fails after 635 runs:
Got AssertionError: Values are not equal: settle-gate: waiting gate main/s0 settled to skipped without approveIt reproduces every time with fast-check's replay parameters on that fc.assert (numRuns 5000):
seed: -879038343
path: "[IP-1]"
endOnFailure: trueShrunk counterexample:
[[{"job":"main","name":"s0","kind":"guarded"}],
[{"legit":834205783},{"legit":0},{"legit":537057781},
{"forge":{"kind":"settle-gate","pick":0,"status":"waiting_approval","abort":false,"retypeTo":"other","field":0,"keepStatus":false}},
{"forge":{"kind":"settle-gate","pick":0,"status":"skipped","abort":false,"retypeTo":"other","field":0,"keepStatus":false}}]]What it means
A run-only caller can land two forged settle-gate records: one moving the guarded step main/s0 to waiting_approval, then one moving it to skipped. judgeRunRecord (src/domain/datastore_v3/content_bindings.ts) accepts both, so a gate that waits for approval settles without one. Either the model's invariant is too strict or judgeRunRecord misses the waiting-to-skipped transition for a forged record; either way main's suite fails on some seeds.
Expected
A waiting approval gate settles to skipped only through an approve or reject decision; or, if that transition is legitimate here, the model says so and the property passes for every seed.
Open
No activity in this phase yet.
Sign in to post a ripple.