1. The Central Idea

Classical proof theory assigns proofs a term structure: a derivation tree whose nodes are inference rules. JuGeo takes a different stance. A proof obligation over a piece of code is not a single term — it is a geometric object living at a coordinate in the program's semantic space. When the program evolves, the obligation transforms. When the program branches, the obligation splits. This is the language of sheaves.

Definition 1.1 — Judgment

A judgment is a 4-tuple

\[ \mathcal{J} \;=\; (\mathbb{S}_{\mathrm{top}},\; \mathbb{P}_{\mathrm{str}},\; \mathbb{C}_{\mathrm{spec}},\; \mathbb{G}_{\mathrm{eval}}) \]

where each component is defined as follows.

Symbol Name Type Description
\(\mathbb{S}_{\mathrm{top}}\) Semantic Topos Site + Grothendieck topology The site, Grothendieck topology, sheaf topos, and internal logic. Subsumes the old coordinate \(c\) and formula \(\varphi\).
\(\mathbb{P}_{\mathrm{str}}\) Proof Structure Contexts, types, terms Contexts, types, terms, and derivation trees. Subsumes the old assumptions \(A\) and evidence \(E\).
\(\mathbb{C}_{\mathrm{spec}}\) Cohomological Spectrum \(H^*(\mathcal{S}_P;\, \mathcal{F}_J)\) Covers, Čech complex, cohomology groups, and obstruction classes. Subsumes the old obstruction class \(O\) and budget \(B\).
\(\mathbb{G}_{\mathrm{eval}}\) Graded Evaluation \(\mathfrak{T}\) + quantale Grade semiring, quantale, evaluation functor, and trust algebra. Subsumes the old trust level \(T\) and proof term \(\Pi\).
Remark

The coordinate \(c\) is the crucial departure from classical proof theory. In standard Hoare logic, a triple \(\{P\}\, S\, \{Q\}\) has no notion of where in a larger codebase it lives or how it relates geometrically to neighboring triples. JuGeo situates every judgment in a site \(\mathcal{S}_P\), making restriction, gluing, and transport into well-defined mathematical operations rather than informal reuse patterns.

The key operations on judgments mirror those on sheaf sections:

  • Restriction \(J|_U\): project a judgment to a sub-coordinate \(U \hookrightarrow c\).
  • Gluing \(\mathrm{glue}(J_1, \ldots, J_n)\): assemble compatible local judgments into a global one.
  • Transport \(f^* J\): pull back a judgment along a morphism \(f : c' \to c\) (inlining, specialization).
  • Challenge \(\partial J\): lower the trust level and require re-verification.
  • Escalate \(\uparrow J\): route to a higher-authority channel for re-evaluation.

2. Semantic Sites

A semantic site is a small category \(\mathcal{S}_P\) equipped with a Grothendieck topology \(J_P\). The objects of \(\mathcal{S}_P\) are the coordinates of program \(P\); the morphisms model how one coordinate relates to another via scope nesting, control flow, or module inclusion. The topology specifies which families of morphisms constitute covers — enough local data to reconstruct global behavior.

Definition 2.1 — Semantic Site

Let \(P\) be a Python program. The semantic site of \(P\) is the pair \(\bigl(\mathcal{S}_P,\, J_P\bigr)\) where:

  • \(\Ob(\mathcal{S}_P)\) is the set of coordinates of \(P\),
  • morphisms are generated by the four primitive relations below, and
  • \(J_P\) is the Grothendieck topology generated by the four covering families below.

Objects — Program Coordinates

A coordinate is any syntactically delimited region of \(P\). The taxonomy is:

Ob(S_P) = { Module(m) | m is a Python module / package } ∪ { Class(cls) | cls is a class body } ∪ { Function(f) | f is a function / method / lambda } ∪ { Branch(f, k) | k-th branch of function f } ∪ { Loop(f, i) | i-th loop body in function f } ∪ { Expr(f, e) | expression site e in function f } ∪ { Scope(f, d) | scope at nesting depth d in f }

Morphisms — Four Primitive Relations

Morphism typeNotationMeaning
Restriction \(\iota : U \hookrightarrow V\) Sub-coordinate inclusion: a branch arm inside a function, a loop body inside a branch, etc.
Scope nesting \(\sigma : \text{Scope}(f,d) \to \text{Scope}(f,d-1)\) Inner scope included in outer scope; assumptions flow outward, obligations inward.
Transport / call \(\tau_g : \text{Function}(f) \to \text{Function}(g)\) A call from \(g\) to \(f\); pulls back the postcondition of \(f\) as a local fact in \(g\).
Refinement \(\rho : c_{\text{refined}} \to c\) A loop unrolling, inline expansion, or specification strengthening that creates a tighter coordinate.

Covering Families — The Grothendieck Topology

A family \(\{f_i : U_i \to U\}_{i \in I}\) is a covering sieve of \(U\) in \(J_P\) when it belongs to one of four standard generating classes:

Cover typeGeneratorSemantics
Control-flow cover \(\{\text{Branch}(f,k)\}_{k}\) The branches of an if/match together cover the function body: every execution path is witnessed.
Scope cover \(\{\text{Scope}(f,d)\}_{d}\) Nested scopes cover the function: a fact valid at every nesting depth holds for the whole function.
Module cover \(\{\text{Class}(cls_i)\}_i\) Classes of a module cover the module: module-level properties are assembled from per-class properties.
Temporal cover \(\{\text{Loop}(f,k,n)\}_{n}\) Unrolled loop iterations cover the loop body: an inductive argument assembles infinitely many local sections into a loop invariant.

The Grothendieck Axioms

The covering sieves must satisfy three axioms to form a Grothendieck topology on \(\mathcal{S}_P\):

Axiom GT-1 (Maximality)
\[ \text{For every } U \in \Ob(\mathcal{S}_P), \quad \Hom(-,\, U) \in J_P(U). \]
Axiom GT-2 (Stability under base change)
\[ S \in J_P(U),\; f : V \to U \quad\Longrightarrow\quad f^* S \in J_P(V). \]
Axiom GT-3 (Local character)
\[ S \in J_P(U),\; R \text{ sieve on } U,\; \forall\, (f : V \to U) \in S :\; f^* R \in J_P(V) \quad\Longrightarrow\quad R \in J_P(U). \]

The Sheaf Condition on Specification Functors

A specification functor \(\mathcal{F} : \mathcal{S}_P^{\mathrm{op}} \to \mathbf{Set}\) assigns to each coordinate a set of local specifications. It is a sheaf (equivalently: local specifications glue to global ones) iff the following equalizer diagram is exact for every covering sieve \(\{U_i \to U\}\):

\[ \mathcal{F}(U) \;\xrightarrow{\;\sim\;} \lim\Bigl[ \prod_{i} \mathcal{F}(U_i) \;\rightrightarrows\; \prod_{i,j} \mathcal{F}(U_i \times_U U_j) \Bigr] \]

In plain terms: a collection of local specifications \(\{s_i \in \mathcal{F}(U_i)\}\) that agree on all pairwise overlaps \(U_i \times_U U_j\) is the restriction of a unique global specification \(s \in \mathcal{F}(U)\). This is exactly what program verification needs: branch-level postconditions that agree on shared state glue into a function-level postcondition.

Python — Creating a semantic site
from jugeo.geometry.site import Coordinate, CoordinateKind, build_site

base = Coordinate(("mypackage",), CoordinateKind.MODULE)
parse_fn = Coordinate(("mypackage", "parse"), CoordinateKind.FUNCTION)
site = build_site([base, parse_fn])

print(site.coordinate_count())
print(site.morphism_count())
print([obj.name for obj in site.objects()])

3. Sheaf Descent

Descent is the process of assembling a global judgment from a compatible family of local judgments. Given a covering family \(\{U_i \to U\}_{i \in I}\) and local judgments \(J_i\) on each \(U_i\), descent asks: do the \(J_i\) agree on all pairwise overlaps, and if so, is there a unique global \(J\) restricting to each \(J_i\)?

Definition 3.1 — Descent Condition

A family \(\{J_i\}_{i \in I}\) of local judgments satisfies the descent condition when

\[ J_i\big|_{U_i \cap U_j} \;=\; J_j\big|_{U_i \cap U_j} \qquad \forall\, i,j \in I. \]

When the descent condition holds, there exists a unique global judgment \(J\) on \(U\) — its gluing} — such that \(J|_{U_i} = J_i\) for every \(i\).

Diagram: Descent for a Branching Function

Function(parse) ←——————————————— Global J on parse ↑ ↑ glue (if descent holds) ┌────────┴────────┐ ┌────────┴────────┐ │ │ │ │ Branch 0 Branch 1 J₀ on B₀ J₁ on B₁ (happy path) (error path) ↓ overlap check J₀|_{B₀∩B₁} = J₁|_{B₀∩B₁}? (shared state variables) ✓ agree → glue ✗ disagree → obstruction

Four Descent Strategies

JuGeo implements four strategies for orchestrating the descent computation, trading off coverage guarantees against resource consumption:

EAGER
Immediately discharge every sub-judgment as it is created. Maximal resource use; minimal latency per judgment. Suitable for interactive mode and small functions.
EXHAUSTIVE
Enumerate all coordinates, collect all local judgments, then attempt global gluing in one pass. Finds all obstructions simultaneously; high memory use for large programs.
ITERATIVE
Interleave local discharge with overlap checking, re-using already proved sub-judgments. Converges incrementally; ideal for CI pipelines with cached results from previous runs.
OPTIMISTIC
Assume descent holds and produce a provisional global judgment annotated COPILOT_SUGGESTED. Escalate to solvers only when a challenge is issued. Best throughput for large codebases with few real obstructions.
Theorem 3.1 — Completeness of Exhaustive Descent
\[ \text{EXHAUSTIVE}(P) \text{ terminates} \;\Longrightarrow\; \forall J \in \mathcal{F}(U):\; J \text{ is discharged} \;\Leftrightarrow\; O(J) = 0 \text{ in } H^0(\mathcal{S}_P;\, \mathcal{F}_J). \]
Python — Descent strategies
from jugeo.geometry.descent import DescentEngine, DescentStrategy

engine = DescentEngine()
print(type(engine).__name__)
print([strategy.name for strategy in DescentStrategy])

4. The Trust Algebra

Not all evidence is equal. A runtime test witnessing a property once is less reliable than a formal proof that holds for all inputs. JuGeo makes this precise with a trust algebra — a partially ordered monoid with operations for combining, promoting, and challenging trust annotations.

Definition 4.1 — Trust Algebra

The trust algebra is the 6-tuple

\[ \mathfrak{T} \;=\; \bigl(\mathcal{E}_{\mathrm{adm}},\; \preceq,\; \oplus,\; \ominus,\; \uparrow_\pi,\; \downarrow_\chi\bigr) \]

where:

  • \(\mathcal{E}_{\mathrm{adm}}\) is the set of admissible trust levels (a 7-element chain, see below),
  • \(\preceq\) is the partial order on trust levels (\(\preceq\,\) is total on \(\mathcal{E}_{\mathrm{adm}}\)),
  • \(\oplus : \mathcal{E}_{\mathrm{adm}} \times \mathcal{E}_{\mathrm{adm}} \to \mathcal{E}_{\mathrm{adm}}\) is the conservative join (trust combination),
  • \(\ominus : \mathcal{E}_{\mathrm{adm}} \times \mathcal{E}_{\mathrm{adm}} \to \mathcal{E}_{\mathrm{adm}}\) is trust subtraction (challenge response),
  • \(\uparrow_\pi\) is promotion along evidence \(\pi\) (trust upgrade with a witness), and
  • \(\downarrow_\chi\) is demotion by challenge \(\chi\) (trust downgrade on counter-evidence).

The Seven Trust Levels

Level Constant Numeric Meaning Channel
CONTRADICTED T_⊥ 0 A counter-example was found; the claim is false. Any
UNVERIFIED T_? 1 No evidence collected yet. Initial state of every judgment.
COPILOT_SUGGESTED T_cs 2 An LLM copilot has proposed a proof sketch; not yet validated. COPILOT
ORACLE_PROPOSED T_op 3 A trusted oracle (external service) asserts the claim. ORACLE
RUNTIME_WITNESSED T_rw 4 Observed to hold across collected runtime traces (probabilistic). RUNTIME
SOLVER_DISCHARGED T_sd 5 SMT/SAT solver returned UNSAT with a checkable certificate. SOLVER
VERIFIED_PROOF T_⊤ 6 Machine-checked proof term accepted by a proof assistant (Lean 4). FORMAL_PROOF

Algebra Operations

Conservative Join \(\oplus\)

Combining two trust levels yields the minimum — trust is only as strong as the weakest link:

\[ T_a \oplus T_b \;=\; \min_{\preceq}(T_a,\, T_b). \]

Promotion \(\uparrow_\pi\)

Promotion upgrades trust when a new evidence object \(\pi\) is provided. Promotion is bounded by the trust ceiling of the channel that produced \(\pi\):

\[ \uparrow_\pi (T) \;=\; \begin{cases} \min\bigl(\mathrm{ceil}(\mathrm{ch}(\pi)),\; T_{\text{new}}\bigr) & \text{if } \pi \text{ validates } \varphi, \\ T & \text{otherwise.} \end{cases} \]

Demotion \(\downarrow_\chi\)

When a challenge \(\chi\) (a counter-example candidate, a failing test, a conflicting oracle report) is issued against a judgment at trust level \(T\):

\[ \downarrow_\chi (T) \;=\; \begin{cases} T_\bot & \text{if } \chi \text{ is a valid counter-example,} \\ T_? & \text{if } \chi \text{ invalidates prior evidence (but no counter-example found),} \\ T & \text{if } \chi \text{ is rebutted.} \end{cases} \]

The Three Laws

Theorem 4.1 — Trust Algebra Laws

The trust algebra \(\mathfrak{T}\) satisfies:

Law 1 — No silent promotion. Trust cannot increase without explicit evidence:

\[ \nexists\, \text{operation } f : \mathcal{E}_{\mathrm{adm}} \to \mathcal{E}_{\mathrm{adm}} \text{ such that } f(T) \succ T \text{ without a witness.} \]

Law 2 — Conservative join. Composition never exceeds the weaker component:

\[ \forall\, T_a, T_b \in \mathcal{E}_{\mathrm{adm}}: \quad T_a \oplus T_b \preceq T_a \;\text{ and }\; T_a \oplus T_b \preceq T_b. \]

Law 3 — Challenge conservativity. A successful rebuttal of a challenge restores at most the original trust level:

\[ T' = \uparrow_\rho (\downarrow_\chi (T)) \preceq T \qquad \text{for all challenges } \chi \text{ and rebuttals } \rho. \]
Python — Trust algebra operations
from jugeo.evidence.trust import TrustLevel, TrustAlgebra

T = TrustAlgebra()
combined = T.join(TrustLevel.RUNTIME_WITNESSED, TrustLevel.SOLVER_DISCHARGED)
print(combined)
print(T.promote(TrustLevel.COPILOT_SUGGESTED, "solver witness"))
print(T.demote(TrustLevel.SOLVER_DISCHARGED, TrustLevel.RUNTIME_WITNESSED))

5. Evidence Channels

An evidence channel is a named source of proof evidence, equipped with a jurisdiction (the class of properties it can handle), a trust ceiling (the maximum trust level it can award), and a cost model. JuGeo ships six built-in channels and supports third-party channel plugins.

Definition 5.1 — Evidence Channel

An evidence channel is a triple \(\mathrm{Ch} = (\mathcal{J}, \tau_\mathrm{ceil}, \mathcal{C})\) where:

  • \(\mathcal{J} \subseteq \text{Formula}\) is the channel's jurisdiction — the set of formulas it is authorised to discharge,
  • \(\tau_\mathrm{ceil} \in \mathcal{E}_{\mathrm{adm}}\) is the trust ceiling, and
  • \(\mathcal{C} : \text{Formula} \to \mathbb{R}_{\ge 0}^3\) is the cost model mapping formulas to expected \((t, \$, q)\) tuples.
SOLVER
Jurisdiction: quantifier-free first-order arithmetic, bitvectors, arrays, uninterpreted functions (SMT-LIB2)
Trust ceiling: SOLVER_DISCHARGED
Cost: exponential in formula size; Z3/cvc5/Bitwuzla backends
Output: UNSAT certificate or model (counter-example)
RUNTIME
Jurisdiction: all decidable Python predicates observable at runtime (no universals)
Trust ceiling: RUNTIME_WITNESSED
Cost: proportional to trace collection overhead (\(\sim\)5–20%)
Output: passing / failing trace with concrete values
ORACLE
Jurisdiction: domain-specific assertions (security policies, compliance rules, cloud invariants)
Trust ceiling: ORACLE_PROPOSED
Cost: API call latency + per-query pricing
Output: signed assertion with provenance metadata
FORMAL_PROOF
Jurisdiction: all propositions expressible in Lean 4 / Mathlib
Trust ceiling: VERIFIED_PROOF
Cost: Lean elaboration time; slow but definitive
Output: Lean 4 term with type ⊢ φ
COMPOSED
Jurisdiction: any formula whose sub-goals are individually dischargeable by other channels
Trust ceiling: \(\min(\tau_\mathrm{ceil}(\mathrm{Ch}_i))\) over component channels
Cost: sum of component costs
Output: composite certificate with channel provenance
COPILOT
Jurisdiction: heuristic — LLM-generated proof sketches, annotations, and repair suggestions
Trust ceiling: COPILOT_SUGGESTED
Cost: LLM token cost; fast but probabilistic
Output: annotated Python with inline @jugeo hints

Channel Routing

JuGeo's router maps each formula \(\varphi\) to the cheapest channel whose jurisdiction contains \(\varphi\) and whose trust ceiling meets the required trust level:

\[ \mathrm{route}(\varphi, T_\mathrm{req}) \;=\; \arg\min_{\mathrm{Ch}} \mathcal{C}_\mathrm{Ch}(\varphi) \;\text{subject to}\; \varphi \in \mathcal{J}_\mathrm{Ch} \;\text{ and }\; T_\mathrm{ceil}(\mathrm{Ch}) \succeq T_\mathrm{req}. \]

6. Cohomological Obstructions

When descent fails — when local judgments do not agree on overlaps — the failure is not discarded. Instead it is captured as a cohomological obstruction: an element of a sheaf cohomology group \(H^n(\mathcal{S}_P;\, \mathcal{F}_J)\). The degree \(n\) encodes the severity of the failure.

Definition 6.1 — Obstruction Classes

Let \(\mathcal{F}_J\) be the judgment sheaf. The obstruction class of a judgment \(J\) is \[ O(J) \;\in\; \bigoplus_{n \ge 0} H^n(\mathcal{S}_P;\, \mathcal{F}_J). \] The degree of \(O(J)\) classifies the discharge status:

\(H^0\)
Fully Discharged
\(O(J) \in H^0 = 0\). The global section exists; descent succeeded; the judgment is verified at its required trust level.
\(H^1\)
Partially Discharged
\(O(J) \in H^1 \ne 0\). Local sections exist but fail to glue — there is a 1-cocycle obstruction. Some overlap is unresolved.
\(H^2\)
Failed
\(O(J) \in H^2\). Local sections themselves are inconsistent; no covering family can resolve the conflict without new evidence.
\(H^\infty\)
Oracle-Deferred
The obstruction exceeds solver capacity and has been escalated to an oracle or formal proof assistant for resolution.

The Obstruction Exact Sequence

For a short exact sequence of sheaves \(0 \to \mathcal{A} \to \mathcal{B} \to \mathcal{C} \to 0\) on \(\mathcal{S}_P\), the long exact cohomology sequence is:

\[ 0 \to H^0(\mathcal{A}) \to H^0(\mathcal{B}) \to H^0(\mathcal{C}) \xrightarrow{\,\delta\,} H^1(\mathcal{A}) \to H^1(\mathcal{B}) \to H^1(\mathcal{C}) \xrightarrow{\,\delta\,} H^2(\mathcal{A}) \to \cdots \]

The connecting homomorphism \(\delta\) is JuGeo's repair operator: it takes a global section of \(\mathcal{C}\) (a verified sub-judgment) and produces the obstruction in \(H^1(\mathcal{A})\) that remains to be repaired.

Obstruction Persistence and the Cohomology Ring

Obstructions are persistent: they are stored with the judgment and survive incremental recompilation. Moreover, the cup product

\[ \smile \;:\; H^m(\mathcal{S}_P;\, \mathcal{F}) \times H^n(\mathcal{S}_P;\, \mathcal{F}) \;\longrightarrow\; H^{m+n}(\mathcal{S}_P;\, \mathcal{F}) \]

gives the set of obstruction classes the structure of a graded ring. This ring can be queried — e.g., to find all judgments whose obstruction is in the same cohomology class (likely sharing a common root cause) — and used to plan repair strategies.

Four Obstruction Operations

OperationFormulaEffect
Query \(\mathrm{obs}(J)\) Return the current obstruction class \(O(J) \in H^*\).
Transport \(f^* O(J)\) Pull back an obstruction along a morphism; useful for propagating known failures to call sites.
Repair \(\mathrm{repair}(J, \pi)\) Provide new evidence \(\pi\) to reduce \(O(J)\): if \(\pi\) resolves the \(H^1\) cocycle, the obstruction descends to \(H^0 = 0\).
Challenge \(\partial J\) Issue a challenge: if successful, promotes the obstruction degree; if rebutted, restores the previous class.
Python — Working with obstructions
from jugeo.geometry.site import Coordinate, CoordinateKind
from jugeo.geometry.covers import Cover
from jugeo.geometry.descent import GluingData

base = Coordinate(("mypackage",), CoordinateKind.MODULE)
left = Coordinate(("mypackage", "validate"), CoordinateKind.FUNCTION)
right = Coordinate(("mypackage", "emit"), CoordinateKind.FUNCTION)

cover = Cover(
    target=base,
    patches=(left, right),
    overlaps=((left.key, right.key),),
    provenance=("docs",),
)

gluing = GluingData.from_cover(
    cover,
    {
        left.key: {"status": "ok", "currency": "USD"},
        right.key: {"status": "ok", "currency": "EUR"},
    },
)

cocycle = gluing.compute_cocycle()
print(cocycle.dimension)
print(cocycle.summary())

7. Semantic Moves

A semantic move is an atomic proof-search operation that transforms one or more judgments. Moves play the role that tactics play in interactive theorem provers, but they operate on the geometric structure of judgments rather than on proof terms. JuGeo defines 16 primitive moves; users may compose them into strategies.

Definition 7.1 — Semantic Move

A semantic move is a partial function \[ m : \mathrm{Judgment}^k \;\rightharpoonup\; \mathrm{Judgment}^l \] together with: (i) a precondition \(\mathrm{pre}(m)\) stating when \(m\) is applicable, (ii) a postcondition} \(\mathrm{post}(m)\) stating what the output judgments satisfy, and (iii) a trust monotonicity guarantee: \(\forall i,\, T(\text{output}_i) \succeq T_{\min}(m)\).

VERIFY
Route \(J\) to its optimal channel and attempt discharge. Core operation.
CONSTRUCT
Synthesize a witness \(w\) such that \(\varphi(w)\) holds, returning it as evidence.
NORMALIZE
Rewrite \(\varphi\) to normal form without changing its truth value. Simplifies downstream solver calls.
WEAKEN
Replace \(\varphi\) with \(\psi \Rightarrow \varphi\) for a sound over-approximation \(\psi\).
CONTRACT
Merge two judgments at the same coordinate whose formulas are logically equivalent.
EXCHANGE
Swap the order of two independent sub-judgments in a proof sequence.
CUT
Introduce a lemma \(\ell\): split \(J\) into \(\text{prove } \ell\) and \(\ell \vdash J\).
RESTRICT
Project \(J\) to a sub-coordinate \(U \hookrightarrow c\), producing \(J|_U\).
TRANSPORT
Pull back \(J\) along a call morphism \(\tau_g\) to a call site judgment.
GLUE
Assemble compatible local judgments \(\{J_i\}\) into a global judgment via sheaf gluing.
REPAIR
Provide new evidence to reduce the obstruction degree of a failed or partial judgment.
NEGOTIATE_TREATY
Establish a bi-directional trust contract between two judgment coordinates (cross-module verification).
REFINE_COVER
Replace a covering family with a finer one (e.g., unroll a loop one more step) to expose more local structure.
PROMOTE_TRUST
Upgrade trust level by presenting evidence; fails if evidence does not satisfy channel requirements.
CHALLENGE
Assert a counter-claim; if validated, demotes trust and raises the obstruction degree.
ESCALATE
Route the judgment to a higher-authority channel (e.g., from SOLVER to FORMAL_PROOF) when current channel is insufficient.

Move Composition and Strategy DSL

Moves compose via a small DSL. The sequential combinator \(m_1 \,;\, m_2\) applies \(m_1\) then \(m_2\) on the output; the parallel combinator \(m_1 \parallel m_2\) applies both to independent sub-judgments simultaneously; and the try combinator \(m_1 \mathbin{||} m_2\) applies \(m_2\) when \(m_1\) fails:

\[ \text{strategy} \;::=\; m \;\mid\; m_1 \,;\, m_2 \;\mid\; m_1 \parallel m_2 \;\mid\; m_1 \mathbin{||} m_2 \;\mid\; \mathrm{repeat}(m) \;\mid\; \mathrm{try}(m) \]
Python — Composing semantic moves
from jugeo.evidence.trust import TrustAlgebra, TrustLevel
from jugeo.moves import MoveKind

algebra = TrustAlgebra()
combined = algebra.meet(TrustLevel.SOLVER_DISCHARGED, TrustLevel.HUMAN_ATTESTED)
print(combined)
print([move.name for move in MoveKind][:6])

8. Python Effects as Sheaf Sections

Python's effect system — exceptions, mutable state, asynchronous suspension, generators, context managers — maps precisely onto the geometric language of sheaves. This correspondence is not merely an analogy; it is the formal bridge that lets JuGeo extract judgments automatically from unannotated Python code.

Principle 8.1 — Effects are Sections

Every Python effect is a sheaf-theoretic operation on the judgment sheaf \(\mathcal{F}_J\) over \(\mathcal{S}_P\). The effect system of the runtime is the transition system of the site; tracking effects equals tracking how sections transform.

Python Effect Sheaf-Theoretic Counterpart Judgment Impact
Exceptions (raise / except) Coordinate forks: a raise creates a new branch coordinate \(\text{Branch}_{\mathrm{exc}}\) disjoint from the normal-exit branch. A control-flow cover splits into \(\{U_{\mathrm{normal}},\, U_{\mathrm{exc}}\}\); the postcondition judgment must be separately discharged on each branch.
Mutable state (=, heap writes) Scope sections: each assignment extends the section at the current \(\text{Scope}(f, d)\) coordinate with a new variable binding. Dataflow-induced assumptions propagate forward through scope morphisms; stale bindings are invalidated by restriction to the updated scope.
Async / Await (async def, await) Suspended morphisms: an await point introduces a morphism \(\text{Scope}(f, d_{\mathrm{pre}}) \to \text{Scope}(f, d_{\mathrm{post}})\) that may be traversed zero or more times non-deterministically. Temporal covers capture interleaved executions; the sheaf condition guarantees that invariants holding at every yield point glue to a global coroutine invariant.
Generators (yield) Fiber restrictions: each yield is a restriction of the function-scope section to a fiber} — the state of the generator at that point in the iteration sequence. A generator body judgment is a family of fiber-level judgments; gluing them produces the loop invariant of the iteration protocol.
Context managers (with) Covering families: __enter__ and __exit__ together form a two-element cover \(\{U_{\mathrm{open}},\, U_{\mathrm{close}}\}\) of the managed scope. Resource invariants are specified on the cover; JuGeo verifies that every exit path (normal and exceptional) satisfies the cleanup postcondition of __exit__.

Example: Exception Branches

Python — Exceptions as coordinate forks
from jugeo.easy import spec

review = spec(
    '''
def sum_positive(items):
    total = 0
    for x in items:
        if x < 0:
            raise ValueError(f"negative item: {x}")
        total += x
    return total
''',
    '''
def spec(result, items):
    return result >= 0
''',
    input_cover=[
        {"args": [[1, 2, 3]], "kwargs": {}},
        {"args": [[]], "kwargs": {}},
    ],
    entrypoint="sum_positive",
)
print(review)
print(review.satisfied, review.witness_count)

Example: Context Manager as Covering Family

Python — Context managers as covering families
from jugeo.easy import bugs

result = bugs('''
def load_text(path):
    fh = open(path, "r")
    return fh.read()
''')

print(result)
for bug in result.items:
    print(bug.message)

The Effect-Sheaf Correspondence

The correspondence can be stated as a theorem relating Python's operational semantics to the sheaf-theoretic model:

Theorem 8.1 — Effect-Sheaf Soundness

Let \(P\) be a Python program and \(\mathcal{F}_J\) the associated judgment sheaf on \(\mathcal{S}_P\). For every effect \(e\) generated by the Python runtime during execution of \(P\):

\[ e \text{ is safe w.r.t. the effect specification} \;\Longleftrightarrow\; J_e|_{U_{\mathrm{pre}}} \in \mathcal{F}_J(U_{\mathrm{pre}}) \;\text{ and }\; J_e|_{U_{\mathrm{post}}} \in \mathcal{F}_J(U_{\mathrm{post}}), \]

where \(U_{\mathrm{pre}}\) and \(U_{\mathrm{post}}\) are the pre- and post-coordinates of \(e\), and safety is preserved by descent: if the local judgments are discharged and satisfy the descent condition, the global effect-safety judgment holds.