Pre-flight closure check for `--require-closed`. Bails unless every typing dependency of every constant the batch will certify is itself either (a) certified somewhere in this batch (any input's work items), or (b) already in the on-disk `store` (a prior proof — re-verified and folded at aggregation). Axioms need no special case: they are themselves work items, so they land in (a) as certified dec
( inputs: &[Option<PathBuf>], store: &std::collections::HashSet<[u8; 32]>, )
| 637 | for w in work { |
| 638 | for t in w.proven_targets() { |
| 639 | certified.insert(*t.as_bytes()); |
| 640 | } |
| 641 | } |
| 642 | } |
| 643 | |
| 644 | // Every non-blob ref of every certified constant must be in `certified`. |
| 645 | let mut missing: Vec<(String, Address)> = Vec::new(); |
| 646 | let mut axioms = 0usize; |
| 647 | let mut checked = 0usize; |
| 648 | for (label, env, work) in parsed { |
| 649 | for w in work { |
| 650 | for t in w.proven_targets() { |
| 651 | let Some(c) = env.get_const(&t) else { continue }; |
| 652 | if matches!(&c.info, ConstantInfo::Axio(_)) { |
| 653 | axioms += 1; |
| 654 | } |
| 655 | checked += 1; |
| 656 | for r in &c.refs { |
| 657 | if env.get_blob(r).is_some() { |
| 658 | continue; |
| 659 | } |
| 660 | if !certified.contains(r.as_bytes()) { |
| 661 | missing.push((label.clone(), r.clone())); |
| 662 | } |
| 663 | } |
| 664 | } |
| 665 | } |
| 666 | } |
| 667 | (missing, checked, axioms) |
| 668 | } |
| 669 | |
| 670 | /// Pre-flight closure check for `--require-closed`. Bails unless every typing |
| 671 | /// dependency of every constant the batch will certify is itself either |
| 672 | /// (a) certified somewhere in this batch (any input's work items), or (b) |
| 673 | /// already in the on-disk `store` (a prior proof — re-verified and folded at |
| 674 | /// aggregation). Axioms need no special case: they are themselves work items, |
| 675 | /// so they land in (a) as certified declarations, and their inhabitation is the |
| 676 | /// irreducible "modulo axioms" residual. Literal blob refs (Nat/Str data) are |
| 677 | /// well-typed by construction and never count. |
| 678 | /// |
| 679 | /// Sound under the store-closure invariant: a constant enters the store only |
| 680 | /// via a run, so if every run uses `--require-closed` the store is itself |
| 681 | /// closed and (b) holds transitively. Store entries' own refs aren't re-checked |
| 682 | /// here (their definitions live in other envs), but aggregation re-verifies the |
| 683 | /// covering proofs that certified them. |
| 684 | fn check_inputs_closed( |
| 685 | inputs: &[Option<PathBuf>], |
| 686 | store: &std::collections::HashSet<[u8; 32]>, |
| 687 | ) -> Result<()> { |
no test coverage detected