Skip to content

Certify max-flow optimality instead of trusting recorded values - #6

Merged
networmix merged 2 commits into
mainfrom
test/maxflow-optimality-certificates
Aug 24, 2026
Merged

Certify max-flow optimality instead of trusting recorded values#6
networmix merged 2 commits into
mainfrom
test/maxflow-optimality-certificates

Conversation

@networmix

Copy link
Copy Markdown
Owner

Follow-up to the 0.8.0 max-flow fix. That release fixed the defect; this closes the
detection gap that let it survive ~400 tests.

Why the old suite missed it

I measured rather than assumed, and the intuitive answer turned out to be wrong.

It was not weak assertions. None of the shared fixtures expose the bug — not at the
pair each test queries, and not at any other pair. 0 of 78 (fixture, src, dst)
combinations
disagree with an independent oracle under 0.7.2. Strengthening every
assertion in the suite would have caught exactly nothing.

It was input generation. Every test graph had near-uniform costs (mostly all-1,
occasionally 1,1,2,2). The defect needs dispersed costs — randomized sweeps find
0/2000 failures at spread ≤ 1..2. The suite faithfully modeled its intended domain
(uniform-cost Clos fabrics), and that domain is precisely the region where the bug
cannot occur.

Worth noting: the bug lived in thoroughly covered code — the tier loop ran in all 78
passing cases. Line coverage was never going to find this.

What this adds

An optimality certificate instead of an oracle. certify_max_flow checks four
properties: feasibility, conservation, that the reported min-cut genuinely separates
source from sink, and tightness. By weak duality those together prove the flow is
maximum — so there's no external solver and no recorded expected value to drift.

I deliberately did not add networkx as a dev dependency. Measured, it adds zero
detection over the certificate for this defect class, while costing a dependency across
14 CI jobs. The certificate is also faster, and reaches configurations no external solver
models — masked runs and EQUAL_BALANCED, which is exactly where the next defect of this
kind would hide.

Generation in the trigger region. Seeded sweeps over full-duplex graphs with dispersed
costs. Since a fixed seed makes detection deterministic, the corpus has to be shown to
have teeth — the seed was chosen so it trips the 0.7.2 defect within the first few graphs.
An arbitrary seed needed ~5750 graphs to hit the same defect, so this is a cheaper corpus,
not a narrower one.

A guard against decay. test_certificate_rejects_a_non_maximal_flow proves the
certificate rejects a genuinely non-maximal result, reached through the public API. Without
it the certificate could quietly become an assertion that always passes — which is exactly
how the old helper failed.

The vacuous helper. assert_valid_min_cut checked only that edge ids were unique and
in range. An empty list satisfies both trivially, so the one helper positioned to catch this
was guaranteed to pass on the flow=2.0, min_cut=[] output the bug produced. It now
asserts duality when given the total. Honest accounting: this would not have caught the
bug (0/78), and it's included because ~7 max-flow tests currently assert nothing that can
fail — not because it's the fix.

A consistency-vs-correctness fix. The batch/serial parity test generated uniform costs
and compared two paths that both call calc_max_flow — it could only prove they agreed,
never that they were right. Costs are now dispersed and results certified. It now fails
against 0.7.2, which it did not before.

Validation

Every item was run against both versions:

catches 0.7.2 bug passes 0.8.0
Certificate sweeps ✅ graph #0
Batch parity (fixed) ✅ (previously could not)
assert_valid_min_cut ❌ as measured — 0/78

444 Python tests pass, up from 433. Suite 2.4s → 3.8s.

🤖 Generated with Claude Code

The 0.7.2 under-reporting bug (fixed in 0.8.0) survived ~400 tests because the
suite could not reach it, not because it checked too loosely. Measured: none of
the shared fixtures expose it, at any src/dst pair (0 of 78 combinations), so no
amount of assertion strengthening would have caught it. The binding constraint
was input generation - every test graph had near-uniform costs, and the defect
needs dispersed costs to trigger.

Add an oracle-free optimality certificate and generate graphs in the region where
such defects live:

- conftest: certify_max_flow checks feasibility, conservation, that the reported
  min-cut genuinely separates src from dst, and tightness. By weak duality those
  four together *prove* the flow is maximum, so no external solver and no stored
  expected value is needed. Masked runs are supported, and maximal=False covers
  EQUAL_BALANCED and shortest_path=True, where only the first two properties hold.

- test_maxflow_certificate: seeded sweeps over full-duplex graphs with dispersed
  costs, plus certification of every shared fixture across all src/dst pairs. The
  seed was chosen so its corpus trips the 0.7.2 defect within the first few graphs;
  both sweeps were confirmed to fail against 0.7.2 and pass against 0.8.0. Includes
  a guard that the certificate rejects a known non-maximal flow, so it cannot decay
  into an assertion that always passes.

- conftest: assert_valid_min_cut previously checked only that edge ids were unique
  and in range, both of which an empty cut satisfies vacuously - so it was
  guaranteed to pass on exactly the output the bug produced. It now takes an
  optional total_flow and asserts duality. Wired into the four call sites that
  compute a true maximum; the EQUAL_BALANCED and shortest_path sites are annotated
  with why duality does not apply there.

- test_review_regressions: the batch/serial parity test generated uniform costs and
  compared two paths that both call calc_max_flow, so it could only ever prove
  consistency, never correctness. Costs are now dispersed and results certified;
  this makes the test fail against 0.7.2, which it did not before.

444 Python tests pass (from 433), suite 2.4s -> 3.8s.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fd4db563fe

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tests/py/test_maxflow_certificate.py Outdated
The sweep supplied only node_mask, so it never reached calc_max_flow's edge_mask
branches -- including the two inside the 0.8.0 residual completion phase, whose
forward and reverse arc loops consult edge_mask independently (src/max_flow.cpp:190,
:202) and compute_min_cut's own edge-mask path. The certificate helper's edge_mask
handling was likewise unexercised despite the test claiming coverage for masked-out
edges.

Rotate through node-only, edge-only, and combined masking, and assert both branches
were actually reached so the sweep cannot silently degrade into an unmasked one.

This is prospective branch coverage, not retroactive detection: the masked sweep
passes against 0.7.2 either way, since the under-reporting defect is not mask-specific.
Verified separately that the masked-edge assertion does fire on a violating input, so
it is not another check that cannot fail.

Reported by Codex review on #6.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@networmix
networmix merged commit 1cbdfe4 into main Aug 24, 2026
24 checks passed
@networmix
networmix deleted the test/maxflow-optimality-certificates branch August 24, 2026 01:08
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