Skip to content

RULE-VERIFY has no obligation for control flow or byte-level memory — 48% of a real object is covered by neither half #1057

Description

@avrabe

[fathom (gale)] — with #935 and #933 shipped I can finally compute the union denominator a downstream ASIL-D requirement is written against, and the result is a clean, bounded ask rather than a complaint.

Thank you for both: --emit-verify-report is exactly the machine-readable form that makes this computable, and i32_const_correct going from Admitted to Qed moved 55 rule instances in this measurement alone.

The measurement

Three verified thin drivers (gale's isolation core: health monitor, MPU region programmer, ARINC-653 partition switch), each meldloomsynth compile --target cortex-m3, then synth verify --emit-verify-report:

module         applied  verified  declined
hm-thin            190        13       177
mpu-thin           138         7       131
switch-thin        149         2       147
------------------------------------------
TOTAL              477        22       455       4.6% SMT-verified

Declines split near-evenly: register-operation 227 (explicitly "deferred to per-rule Rocq obligations") and unmodeled-op 228.

Joining against the Rocq obligations

Matching each declined rule kind against the 142 distinct *_correct theorems at v0.57.0:

declined kind instances obligation status
LocalGet 131 local_get_correct Qed
I32Const 55 i32_const_correct Qed
LocalSet 36 local_set_correct Qed
Select 4 select_correct Qed
End 60 none found
BrIf 38 none found
Block 36 none found
Call 31 none found
I32Load8U 15 none found
I32Store8 15 none found
Br 7 none found
Unreachable 6 none found
SMT-verified            22
declined but Rocq-Qed  226
------------------------------
UNION                  248 of 477 = 52%
NEITHER half           229 of 477 = 48%

The ask

The 48% is not arithmetic — it is control flow (178 instances) and byte-level memory access (30). Every arithmetic and comparison rule these objects use is covered by one half or the other. What is missing is an obligation for the constructs that decide whether the arithmetic runs.

That is a bounded list: End, BrIf, Block, Br, Call, Unreachable, I32Load8U, I32Store8. Eight kinds, and br_if / block in particular have a history here — #483, #500, #509 and #930 were all miscompiles in exactly that area, which is an argument that these are the rules most worth an obligation rather than least.

I am not asking for them all at once. If there is a natural first one, BrIf (38 instances, and the subject of three closed miscompiles) looks like the highest ratio of risk to effort.

Caveats — I would rather state these than have you find them

  • "None found" means none found BY NAME. I matched snake_case against *_correct. If a control-flow obligation exists under another naming scheme, my table is wrong and I would like to be told.
  • Terminators were parsed from source, not re-checked. I read Qed / Admitted out of the .v files at v0.57.0; nothing here re-ran the Rocq kernel.
  • Weighted by instance count, so LocalGet at 131 dominates the percentage. By distinct kind it is 4 covered of 12.
  • Three thin drivers only, not the fused OS composite.

Why this matters downstream

REQ-OS-OBJVERIFY-001 (gale, ASIL-D track) requires object-code verification with zero coverage gap over the union. It has sat as proposed with an adjective; it now carries 52% / 48% and a named cause. Recorded on our side in benches/gust/drivers/measurements/t2-union-denominator.md (gale#284), reproducible in three commands from committed inputs — happy to hand over the three verify.json reports if a fixture is useful.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions