Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

What panproto verifies

panproto’s correctness rests on a small set of properties that are mechanically checked. Some are verified at compile time (a panic during protocol registration, or an error returned when a migration or theory is compiled); some are verified at runtime when the operation is invoked; some are verified by property-based tests in CI. This page is the catalogue.

If a property is in this list, the implementation enforces it. If you can construct a counterexample, that is a bug.

PropertyWhere checkedFailure modeSource
Protocol registration produces a valid theoryCompile-time (panic at registration)Named intermediate colimit step in panic messagepanproto-protocols/src/theories.rs
Schema validates against its protocolRuntimeschema validate runs structural checks plus theory typechecking and exits non-zero on failure; failing-equation reporting lives in schema verifypanproto-schema
Migration existence conditions holdRuntime, before any data is movedschema check exits non-zero, naming the missing inputpanproto-check
Migration type-checks at the GAT levelRuntime, on demand via --typecheckschema check --typecheck exits non-zero, naming the offending sort or operationpanproto-mig
Migration is a theory morphism on its mapped fragmentCompile time, in mig::compileCompilation fails with NotAMorphism, naming the offending edge or sortpanproto-mig
Migration structure is well-formed (vertex maps reference existing vertices; each mapped edge lands on the images of its own endpoints)VCS stage, commit, and mergeRecorded as a migration error; stage marks the schema invalid, and commit and merge return VcsError::ValidationFailed. CommitOptions.skip_verify is the only bypasspanproto-vcs
Schema satisfies its registered protocol theory’s equationsVCS commit and merge, when the protocol is registered with an equation-bearing theorySet-theoretic model check bounded at 10,000 assignments per equation; a violation blocks with VcsError::ValidationFailed, and an equation whose assignment space exceeds the bound raises ModelCheckLimitExceeded naming it rather than passing silently. An unregistered protocol records an advisory note that no equations were checkedpanproto-vcs, panproto-gat
Lens GetPut law: put(s, get(s), complement(s)) = sCI property tests over generated scenarios (identity and projection families, depth-3 nested trees, vertex and edge remaps, field transforms) with generated put-side views, plus DSL-compiled lenses across the step constructors; sample-based (evidence, not proof), alongside a deterministic runtime check on a given instanceProperty-test failure with shrunk counterexamplepanproto-lens/src/laws.rs, panproto-lens-dsl/tests/step_laws.rs
Lens PutGet law: get(put(s, v, c)) = vCI property tests over generated scenarios (identity and projection families, depth-3 nested trees, vertex and edge remaps, field transforms) with generated put-side views, plus DSL-compiled lenses across the step constructors; sample-based (evidence, not proof), alongside a deterministic runtime check on a given instanceProperty-test failure with shrunk counterexamplepanproto-lens/src/laws.rs, panproto-lens-dsl/tests/step_laws.rs
Lens PutPut law: put(put(s, v₁, c), v₂, c) = put(s, v₂, c)CI property tests over generated scenarios (identity and projection families, depth-3 nested trees, vertex and edge remaps, field transforms) with generated put-side views, plus DSL-compiled lenses across the step constructors; sample-based (evidence, not proof), alongside a deterministic runtime check on a given instanceProperty-test failure with shrunk counterexamplepanproto-lens/src/laws.rs, panproto-lens-dsl/tests/step_laws.rs
Edit-lens TreeEdit monoid-action coherence: apply(compose(e₁, e₂), s) agrees with apply(e₂, apply(e₁, s)), with the identity and associativity lawsCI property tests over generated edit words; sample-based (evidence, not proof)Property-test failure with shrunk counterexamplepanproto-lens/src/edit_laws.rs
Edit-lens get_edit functoriality: get_edit(compose(e₁, e₂)) acts on the view as get_edit(e₁) then get_edit(e₂), and preserves the identity editCI property tests over generated edit words; sample-based (evidence, not proof)Property-test failure with shrunk counterexamplepanproto-lens/src/edit_laws.rs
Edit-lens consistency: a translated source edit applied downstream agrees with the source edit applied and re-viewed, compared over full instance structure (values, extra-fields, arcs, fans, parents) rather than node countsRuntime, on a given edit and instanceEditLawViolation::Consistency, with the diverging detailpanproto-lens/src/edit_laws.rs
Edit-lens complement coherence: the edit-lens complement and the whole-state complement agree over full complement structure (dropped nodes with values, arcs, fans, contraction choices) rather than dropped-node countsRuntime, on a given edit and instanceEditLawViolation::ComplementCoherence, naming the divergent fieldpanproto-lens/src/edit_laws.rs
Declared coercion class round-trips on sampled inputs (a declared Iso or Retraction whose expression fails its round-trip laws is refused)Lens-DSL compile (coerce_sort and each directed_equations entry), the theory-DSL default compile (with compile_unchecked as the documented escape hatch), and the checked construction path (*_coercion_checked constructors); sample-based (evidence, not proof)LensDslError::CoercionNotHonest and TheoryDslError::CoercionLawViolation at compile; CoercionHonestyError at constructionpanproto-lens/src/coercion_laws.rs, panproto-theory-dsl/src/compile.rs
Complement-cost subadditivity: cost(complement(g ∘ f)) ≤ cost(f) + cost(g), over vertical and horizontal composition, chain fusion, and data-level compositionCI property tests (≥256 cases); sample-based (evidence, not proof)Property-test failure with shrunk counterexamplepanproto-lens/src/cost.rs
Source-code emit round-trips its grammar’s full corpus (emit(parse(emit(s))) == emit(s) plus vertex-kind and edge-shape multiset preservation, on every corpus entry, for each of the 248 corpus-gated protocols)CI test (emit_corpus_audit)Test panic naming the protocol and first divergent corpus entrypanproto-parse/tests/emit_corpus_audit.rs
Complement composition compatibilityRuntime, on Complement::composeLensError::ComplementFingerprintMismatchpanproto-lens/src/asymmetric.rs
Complement composition agreementRuntime, on Complement::composeLensError::ComplementConflict (with offending key)panproto-lens/src/asymmetric.rs
Protolens composition: structural equality of the intermediate endofunctorRuntime, on vertical_composeLensError::CompositionMismatchpanproto-lens/src/protolens.rs
Pushout cocone commutativityRuntime, on constructions through colimit() / pushout_by_name (including protocol registration); the raw colimit_by_name union used by the C FFI does not run the cocone checkReturned as part of ColimitResultpanproto-gat/src/colimit.rs
Colimit inclusion morphisms preserve signatures and equationsRuntime, on constructions through colimit() / pushout_by_namecheck_morphism on each inclusion against the pushout theory; a non-injective leg is rejected deterministically with GatError::NonInjectiveIdentification naming the element and its conflicting preimagespanproto-gat/src/colimit.rs
Pushout universal property: every alternative cocone factors uniquely through the pushoutRuntime, on demand via verify_universal; the mediator it builds is validated with check_morphism before the factorization comparisons, so a mediator that factors while violating signature or equation preservation is rejectedEquationNotPreserved, or a GatError from the morphism checkpanproto-gat/src/colimit.rs
Schema merge pushout (cocone level: migration totality and base-vertex commutativity)Runtime, at merge time via vcs::merge::verify_pushoutVcsError::PushoutVerificationpanproto-vcs/src/merge.rs
Schema merge universal property (vertex level)On demand via vcs::merge::verify_pushout_universal; not called by schema mergePushoutError::UniversalFactorizationFailurepanproto-vcs/src/merge.rs
Expression evaluation totality (within step budget)Runtime, on every evaluationExprError::StepLimitExceededpanproto-expr/src/eval.rs
Expression arithmetic overflow checkRuntime, on every arithmetic opExprError::Overflowpanproto-expr/src/builtin.rs
Expression division by zero checkRuntime, on Div/ModExprError::DivisionByZeropanproto-expr/src/builtin.rs
Expression builtin dispatch is total (a misrouted op returns an error rather than panicking)Runtime, on every builtin applicationExprError::InternalDispatch naming the oppanproto-expr/src/builtin.rs

Source-code emit coverage

The source-code emitter (emit_pretty) qualifies 255 of the 261 vendored tree-sitter grammars on the two bases described in Source-code emission. 248 are corpus-gated: every entry in the grammar’s upstream test/corpus/ round-trips under the strict oracle described in the row above. The other 7 (python, stan, bugs, jags, julia, scheme, javascript) are backend-verified: covered by dedicated emit regression tests over the construct surface the quivers transpile backends actually emit, with full corpus pass tracked as follow-on work. The remaining six of the 261 are blocked upstream, not by the emitter:

  • comment, todotxt, wolfram model their content as opaque free-text spans, so the grammar gives the emitter no structure to reconstruct and the captured text is dropped on emit (a corruption the char-multiset detector flags).
  • less is compiled against an older tree-sitter ABI than the 0.26 runtime loads, so its parser yields only error nodes; there is nothing to round-trip until the grammar is re-vendored.
  • move has no let-binding production in the vendored grammar, so real source already parses to an error tree on the way in; this is a parse-layer defect, not an emit one.
  • test parses tree-sitter’s own corpus format, whose === and --- delimiters collide with the corpus reader, so it cannot be exercised inside the harness.

The six are the irreducible residual under the current grammars and runtime; closing any of them needs an upstream grammar fix, an ABI re-vendor, or a harness change rather than emitter work.

What is not verified

The following properties are not mechanically checked and should not be assumed:

  • Performance characteristics. The implementation does not guarantee any particular complexity bound on lens composition, colimit construction, or migration application.
  • Round-trip stability of value-level transforms across data with information loss. A migration that drops a field cannot round-trip the dropped data; the lens laws apply only to the surviving structure.
  • Equivalence of two protocols with isomorphic theories but different parsers. Two protocols whose theories are the same up to isomorphism are still distinct from panproto’s perspective.
  • Application-level invariants not expressible in the schema theory. “Email addresses must contain @” is checked only if the schema actually carries a constraint expressing it.
  • Cocone commutativity on the raw colimit_by_name union. The name-based colimit_by_name path used by the C FFI (pp_gat_colimit) builds no inclusion morphisms and runs no verify_cocone; only constructions through colimit() / pushout_by_name (including protocol registration) are checked.
  • Edge, coverage, and deletion conditions at merge time. The merge-time verify_pushout is vertex level: it checks migration totality and base-vertex commutativity only. Strengthening it with merged-vertex coverage, deletion, and edge-leg checks is planned; until then, restore this note to name those conditions once the strengthening lands.
  • Format-preserving round-trips in the default schema binary. Byte-for-byte round-trips require the tree-sitter feature, which the shipped schema binary does not enable. A format-preserving parse requested from that binary returns canonical output with no layout complement and prints a notice to stderr; enabling the feature in a source build restores preservation. See Round-trip with format preservation.

See also