Prove Flow Choice predicate disjointness - #89
Merged
Merged
Conversation
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.
Based on main at
14c572a3. Closes #71.This replaces Flow Choice target-uniqueness theatre with a bounded, versioned proof that predicates cannot overlap, then binds planning to the immutable snapshot that made the choice.
The gap
Choice admission previously treated distinct target node IDs as if they proved distinct predicates. They do not: two arms can both be true and point at different targets. Planning also did not select a Choice target from the actual snapshot, so the verifier and planner did not share a complete semantic contract.
The fix
Disjoint,Overlap(counterexample), and typedUnknownresults.otherwisewhen none prove, and defer the entire Choice if any arm is unknown.The rejected alternative was an unbounded SAT/SMT dependency or a first-match rule. The former adds a second operational dependency and non-portable proof surface; the latter silently turns ambiguous graphs into order-dependent behavior. This bounded fragment is deterministic,
no_std + alloc, and refuses what it cannot prove.The real user path
These are the public verifier/planner paths, not private helper-only tests:
The refusal cases are asserted through the public library APIs: an overlapping or unknown Choice is rejected by
verify, while an unknown runtime predicate defersplan. A shell exit 1 would test a wrapper rather than the contract this repository exposes.Regressions
Unknown.otherwise, unknown deferral, snapshot binding, and stale planner-version refusal.Proof of teeth
mutation_removing_pair_checks_cannot_hide_identical_predicatesUnknowntoDisjointmutation_treating_unknown_as_disjoint_cannot_admitmutation_removing_snapshot_binding_changes_choice_plan_cidaggregate_pair_work_budget_blocks_large_choicesunknown_choice_arm_defers_instead_of_falling_throughPlan identity had to move to version 1
Choice planning now changes Plan CID bytes by including the full next-step node, kind, capsule CID, and selected Choice target. Keeping planner version 0 would silently reinterpret old identities.
PLANNER_VERSIONis therefore 1; version 0 caller contexts are rejected and must recompute rather than alias the new scheme.Debt-on-touch
Cargo.lockcrates/braid-flow-plan/src/lib.rscrates/braid-flow-plan/src/plan.rscrates/braid-flow-plan/tests/plan_invariants.rscrates/braid-flow-verify/Cargo.tomlproptestcrates/braid-flow-verify/src/disjoint.rscrates/braid-flow-verify/src/error.rscrates/braid-flow-verify/src/lib.rscrates/braid-flow-verify/src/verify.rscrates/braid-flow-verify/tests/disjointness.rsdocs/CRATE-OWNERSHIP.mdbraid-flow-verifydocs/STRATEGIC-VISION.mddocs/adr-099-braid-frontier-flow.mddocs/adr-101-root-admission-triad-and-token-plan.mdspec/braid/DECISIONS.mdFull CI, run locally at
ae01e77b739dbash .wwfd/local-ci.shcompleted all 27 lanes and wrote/Users/srinji/wwfd/state/local-ci-receipt.jsonfor this exact Jujutsu subject.lgwks-stdfeature matrixReceipt:
{"repo_root":"/Users/srinji/Braid","branch":"fix/flow-choice-predicate-disjointness","head_sha":"ae01e77b739d","attested_at":1788066777,"ci_script":"bash .wwfd/local-ci.sh"}GitHub Actions
Braid CI run 33294327212 completed successfully at
ae01e77b739d729a8140ce65fc77e8d019290163: 14/14 checks passed, including Stack, Scope, Build, Tier 0 test, Tier 0 clippy, and Cleanup.What is still not done
Unknown; this patch does not add an SMT backend.