Repository navigation
proofs(T3): gale's side of the supply obligation — the bridge lemma, machine-checked - #292
Merged
Merged
Conversation
…machine-checked
spar#331 delivered ArincSupply.lean, which proves the inner response-time
analysis sound CONDITIONAL on `SupplyGuarantee (∀ t, lsbf Π Θ t ≤ sbf t)` — and
states plainly that spar does NOT prove it. It is the partition scheduler's
obligation, i.e. gale's. This is the arithmetic core of that discharge.
theorem lsbf_le_full_frames (Pi Theta t) (hPi : 0 < Pi) (hU : 2*Theta ≤ Pi+1) :
lsbf Pi Theta t ≤ (t / Pi) * Theta
Why this is the useful shape: gust's major frame is STATIC and cyclic —
MajorFrame::check proves the windows tile [0, frame_len) with no gap, no overlap
and every budget > 0 — so over any Π consecutive ticks a partition receives
exactly its useful budget, and ⌊t/Π⌋·Θ is a sound floor on supply over ANY
interval regardless of where it starts. This lemma shows that floor already
dominates lsbf, so the discharge needs no reasoning about start offsets.
The hypothesis is doing real work: 2Θ ≤ Π+1 forces the blackout 2(Π−Θ) to be at
least Π−1, hence at least the largest possible partial frame t % Π, so the
partial frame never has to be counted.
THE HYPOTHESIS IS PROVEN NECESSARY, NOT ASSUMED. A machine-checked counterexample
is included: at Π=5, Θ=4 (2Θ=8 > Π+1=6, and Θ < Π so not the degenerate case) the
blackout is 2 and lsbf 5 4 4 = 1 > (4/5)·4 = 0. Above one-half utilisation the
partial frame carries supply that must be counted; that regime needs a different
argument and this is not an artefact of how the proof was written.
Θ IS Θ_eff, NEVER THE RAW BUDGET. Switcher::tick fires at t == offset+budget-1,
so each owned window loses its final tick to ctx-save/region-swap/ctx-resume. A
partition owning k windows gets Θ_eff = Θ − k. Instantiating with the raw budget
is UNSOUND — lsbf's leading rate Θ/Π against a real rate (Θ−k)/Π — and it passes
short tests: measured first violation at t=2560 for Π=100/Θ=40/k=1, and t=828
for k=3. The file records this so the next instantiation cannot get it wrong.
Verified locally: bazel test //proofs/lean:all -> 8 of 8 pass.
NOT the whole obligation. This is the arithmetic bridge only. Still owed: the
supply-counting lemma from frame_inv (⌊t/Π⌋·Θ_eff ≤ real supply), the >1/2
utilisation regime, and the side condition Lean cannot discharge — that the
three-atom switch sequence completes within one tick, a WCET obligation on
trusted native code outside both BIN-VERIFY and MC/DC.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011QG86sovTbfnPNY9SfhSmo
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
… PR's own proof
Caught on this PR: `Lean Proofs (7 files)` went GREEN while the branch defines
EIGHT lean_proof_test targets. PartitionSupply.lean was not in the workflow's
hand-written list, so CI never elaborated the proof this PR exists to add, and it
would have merged with a green tick that meant nothing about its content.
That is exactly gale#286's shape — a gate that exists but does not run — one
level down, and it appeared the very first time a proof was added after the gate
landed. An enumerated list is a gate that silently narrows every time someone
forgets to widen it.
bazel test --lockfile_mode=off //proofs/lean:all --test_output=errors
`:all` gates a new lean_proof_test by construction. Verified locally: 8 of 8.
Also dropped the hardcoded count from the job name ("Lean Proofs (7 files)" ->
"Lean Proofs") so the name cannot go stale the same way. Safe to rename: main has
no required status checks (see below), so no protection rule references it.
NOTE, unrelated to this PR and filed separately: main's branch protection has
required_status_checks.contexts == [] — reviews are required and admins are
enforced, but NO check is required to pass. CI is advisory; "CLEAN/MERGEABLE"
means no conflicts, not that anything went green.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011QG86sovTbfnPNY9SfhSmo
avrabe
added a commit
that referenced
this pull request
Aug 27, 2026
…d it — status stays proposed (#297) * docs(T3): record the supply-half discharge on REQ-OS-SCHED-001 — status stays proposed PR #292 + #295 landed proofs/lean/PartitionSupply.lean: 14 theorems, 0 sorry / 0 admit / 0 axiom / 0 native_decide, CI-gated via //proofs/lean:all. supplyGuarantee_of_half_utilisation : lsbf Pi (thetaEff Pi u) t <= supply Pi u s t which IS the hypothesis spar's ArincSupply.lean carries and explicitly declines to prove — the partition scheduler's obligation, i.e. gale's. Recorded on the artifact so the next pass does not re-derive it, and so the gap is not mistaken for closure. STATUS DELIBERATELY UNCHANGED at `proposed`: VER-OS-SCHED-001 demands the WCRT recurrence instantiated against the SHIPPED executor, which this is not. The demand half is untouched and still needs T4's C_i, which is blocked on scry#144 / synth#1063. The description now carries what is owed as precisely as what is done: - the final theorem is conditioned on 2*Theta <= Pi + 1. The SUPPLY side is already unconditional (supply_floor_strong); the missing piece is the purely arithmetic lsbf Pi Th t <= floor(t/Pi)*Th + (t%Pi - (Pi-Th)). A numeric sweep found no counterexample in either regime — recorded as a SWEEP, explicitly not as a proof, because it is not one. - lsbf_le_full_frames is genuinely FALSE above one half, with a machine-checked counterexample in the file. It kills the ROUTE, not the conclusion. - Theta_eff = Theta - k assumes the three-atom switch completes within one tick — a WCET obligation on trusted native code, outside BIN-VERIFY and MC/DC, which Lean cannot discharge. - u is an abstract residue predicate; deriving it from a concrete MajorFrame table is not done. rivet validate: PASS (333 warnings, unchanged). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011QG86sovTbfnPNY9SfhSmo * proofs(T3): SupplyGuarantee is now UNCONDITIONAL — the ≤1/2 bound is gone theorem supplyGuarantee (Pi) (u) (s t) (hPi : 0 < Pi) : lsbf Pi (thetaEff Pi u) t ≤ supply Pi u s t No utilisation hypothesis. This is the obligation spar's ArincSupply.lean carries and explicitly declines to prove — the partition scheduler's duty, i.e. gale's — discharged from the frame's periodic structure alone, for every Theta ≤ Pi. The missing piece was one arithmetic lemma, now proved: lsbf_le_strong_floor : Th ≤ Pi -> lsbf Pi Th t ≤ (t/Pi)*Th + (t%Pi - (Pi - Th)) by case analysis on whether the remainder outruns the blackout: inside it, all supply comes from complete frames; outside, the partial frame carries the rest and Th*(r - 2g) ≤ Pi*(r - g) follows from Th ≤ Pi with both factors monotone. I had recorded this step as supported by an exhaustive numeric sweep and explicitly NOT as a proof. It is now a proof, and the sweep note is removed rather than left standing as a weaker claim beside a stronger one. WHAT THE COUNTEREXAMPLE ACTUALLY KILLED. lsbf_le_full_frames remains FALSE above one half and its machine-checked witness (Pi=5, Th=4, t=4) stays in the file. It kills the ROUTE — complete-frames-only — not the conclusion. That distinction is now demonstrated rather than argued: supplyGuarantee_of_half_utilisation is kept beside the unconditional result precisely to record it. Trust audit: 0 sorry / 0 admit / 0 axiom / 0 native_decide. 17 theorems. bazel test //proofs/lean:all -> 8 of 8. STILL OWED, unchanged by this: - the side condition Lean cannot discharge: Theta_eff = Theta - k assumes the three-atom switch completes within one tick — a WCET obligation on trusted native code, outside BIN-VERIFY and MC/DC. - u is an abstract residue predicate; deriving it from a concrete MajorFrame table (partition_id/offset/budget) is not done. - the DEMAND half of T3, which needs T4's C_i. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011QG86sovTbfnPNY9SfhSmo * docs(T3): record the UNCONDITIONAL discharge, not the ≤1/2 one The artifact text written earlier in this branch described the conditional result. The unconditional theorem landed in the same branch a commit later, so the description would have merged already stale. supplyGuarantee (Pi) (u) (s t) (hPi : 0 < Pi) : lsbf Pi (thetaEff Pi u) t <= supply Pi u s t -- no utilisation bound Also removes the 'exhaustive numeric sweep, explicitly not a proof' note for lsbf_le_strong_floor, which is now proved. Leaving a hedge standing beside a proof is how a burn-down drifts out of date. Kept, because it is the useful part: lsbf_le_full_frames really is FALSE above one half, its machine-checked counterexample stays, and the two theorems sit side by side to record that the counterexample killed the ROUTE and not the conclusion. rivet validate: PASS (333 warnings, unchanged). --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
First step on T3 (
REQ-OS-SCHED-001), and the first gale Lean to land now that #288 made the proofs actually CI-checked.What spar left to us
spar#331 delivered
ArincSupply.lean(0sorry/admit/axiom), which proves the inner response-time analysis sound conditional onand states plainly that spar does not prove it — it is the partition scheduler's obligation, i.e. gale's. This is the arithmetic core of that discharge:
Why this shape
gust's major frame is static and cyclic —
MajorFrame::checkproves the windows tile[0, frame_len)with no gap, no overlap, every budget > 0 — so over any Π consecutive ticks a partition receives exactly its useful budget, and⌊t/Π⌋·Θis a sound floor on supply over any interval regardless of where it starts. This lemma shows that floor already dominateslsbf, so the discharge needs no reasoning about start offsets at all.The hypothesis does real work:
2Θ ≤ Π+1forces the blackout2(Π−Θ)to be at leastΠ−1, hence at least the largest possible partial framet % Π.The hypothesis is proven necessary, not assumed
A machine-checked counterexample ships with it:
At Π=5, Θ=4 (so
2Θ = 8 > Π+1 = 6, and Θ < Π so not the degenerate case) the blackout is 2 andlsbf 5 4 4 = 1 > 0. Above one-half utilisation the conclusion is genuinely false — that regime needs a different argument, and it is not an artefact of how this proof was written. Same discipline as the CI gate: a hypothesis that has never been shown to bite is worth as little as a gate that has never failed.Θ is Θ_eff, never the raw budget
Recorded in the file because it is the way to get this wrong.
Switcher::tickfires att == offset + budget - 1, so each owned window loses its final tick toctx-save/region-swap/ctx-resume. A partition owningkwindows receivesΘ_eff = Θ − k.Instantiating with the raw budget is unsound —
lsbf's leading rateΘ/Πagainst a real rate(Θ−k)/Π— and it passes short tests. Exhaustive simulation over all worst-case start offsets:More windows fails sooner, so splitting a budget to reduce blackout — the natural design move — makes the wrong instantiation fail faster.
Not the whole obligation
Stated in the file rather than glossed. Still owed:
frame_inv(⌊t/Π⌋·Θ_eff ≤real supply);Θ_eff = Θ − kassumes the three-atom switch sequence completes within one tick — a WCET obligation on trusted native code, outside both BIN-VERIFY and MC/DC. It must be carried as an explicit hypothesis, in the same shape spar chose forSupplyGuarantee.Verified locally
bazel test //proofs/lean:all→ 8 of 8. Rebased onto the #288 fix, so theLean Proofsjob here will actually check it — this is the first gale proof to land as gated evidence rather than locally-green.🤖 Generated with Claude Code
https://claude.ai/code/session_011QG86sovTbfnPNY9SfhSmo