Skip to content

proofs(T3): gale's side of the supply obligation — the bridge lemma, machine-checked - #292

Merged
avrabe merged 2 commits into
mainfrom
proofs/t3-supply
Aug 26, 2026
Merged

avrabe merged 2 commits into
mainfrom
proofs/t3-supply

Conversation

@avrabe

@avrabe avrabe commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

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 (0 sorry/admit/axiom), which proves the inner response-time analysis sound conditional on

SupplyGuarantee sbf Π Θ  :=  ∀ 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 shape

gust's major frame is static and cyclic — MajorFrame::check proves 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 dominates lsbf, so the discharge needs no reasoning about start offsets at all.

The hypothesis does real work: 2Θ ≤ Π+1 forces the blackout 2(Π−Θ) to be at least Π−1, hence at least the largest possible partial frame t % Π.

The hypothesis is proven necessary, not assumed

A machine-checked counterexample ships with it:

example : ¬ (lsbf 5 4 4 ≤ (4 / 5) * 4) := by decide

At Π=5, Θ=4 (so 2Θ = 8 > Π+1 = 6, and Θ < Π so not the degenerate case) the blackout is 2 and lsbf 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::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 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:

frame Π Θ k first violation, raw Θ with Θ_eff
one window 100 40 1 t = 2 560 none ≤ 6 000
two windows 100 50 2 t = 1 926 none ≤ 6 000
three windows 100 70 3 t = 828 none ≤ 6 000

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:

  • the supply-counting lemma from frame_inv (⌊t/Π⌋·Θ_eff ≤ real supply);
  • the > ½ utilisation regime, which the counterexample above shows needs different reasoning;
  • a side condition Lean cannot discharge: Θ_eff = Θ − k assumes 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 for SupplyGuarantee.

Verified locally bazel test //proofs/lean:all → 8 of 8. Rebased onto the #288 fix, so the Lean Proofs job 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

…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

codecov Bot commented Aug 26, 2026

Copy link
Copy Markdown

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
avrabe merged commit 828b22f into main Aug 26, 2026
65 checks passed
@avrabe
avrabe deleted the proofs/t3-supply branch August 26, 2026 14:40
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant