Skip to main content

Correct-by-construction generation: one projection bottleneck, content-addressed recipes, and an exhaustive sweep that proves the invariant holds everywhere.

Project description

snapgate

Correct-by-construction generation. Write sloppy generators; get provably-correct output — one projection function makes every artifact valid by construction, one recipe hash makes it reproducible forever, one exhaustive sweep proves the invariant holds across the whole parameter space.

Zero dependencies. Python ≥ 3.10. Apache-2.0.

pip install snapgate

The pattern

Most constrained-generation code tries to make every generator perfect, then samples the output space with tests and hopes. snapgate inverts both moves:

  1. Project, don't perfect. Generators are allowed to be approximate. Every artifact passes through one total projection — project(x, constraint) — at a single emission chokepoint. The domain supplies contains(x) and nearest(x); the framework guarantees totality, idempotence, and that an already-valid artifact is never disturbed. Holding a Projected[T] is the proof the value crossed the chokepoint; nothing else can construct one.

  2. Hash the recipe, not the artifact. An artifact's identity is the content hash of the recipe that produces it. The Ledger stores recipes — never artifacts — and recall(id) re-generates the exact artifact and verifies its content hash. A good result can never be lost, because the description of how it was made is the result.

  3. Sweep, don't sample. sweep(axes, generate, gates) enumerates the full Cartesian product of your parameter space and classifies every case per gate: PASS / LEAK (invariant violated) / SKIP (gate not applicable) / ERROR. Fail-closed exit code, JSON report, per-axis pass-rate breakdown. Not a sample — the whole surface.

This pattern was extracted from a private production generation system where it has held a hard domain invariant over an exhaustive combinatorial sweep of several hundred thousand cases, in CI, at zero leaks. snapgate is the pattern with the domain removed.

Sixty seconds

from snapgate import Gate, project, sweep

# 1. Your domain constraint: membership + your own notion of "nearest valid".
class MultipleOf:
    def __init__(self, k): self.k = k
    def contains(self, x): return x % self.k == 0
    def nearest(self, x):  return round(x / self.k) * self.k

# 2. A sloppy generator, made correct at the chokepoint.
def generate(case):
    raw = case["a"] * 7 + case["b"]           # no attempt to stay valid
    return project(raw, MultipleOf(12)).value  # valid by construction

# 3. Prove it over the WHOLE space, not a sample.
report = sweep(
    axes={"a": range(100), "b": range(100)},   # all 10,000 cases
    generate=generate,
    gates=[Gate("multiple-of-12", lambda case, x: x % 12 == 0)],
)
assert not report.failed
print(report.summary())

And reproducibility:

from snapgate import Ledger, Recipe, rng_for

def generate(recipe):
    rng = rng_for(recipe)                      # ONLY source of randomness
    return [rng.randint(0, 127) for _ in range(recipe.config["n"])]

ledger = Ledger("ledger.jsonl", generate=generate)
entry = ledger.record(Recipe("root", {"n": 8, "mood": "bright"}))
# ...months later, artifact long deleted:
artifact = ledger.recall(entry["id"])          # exact reconstruction, hash-verified

The laws

All normative, all executable (tests/test_laws.py, property-based via Hypothesis):

# Law Statement
1 Totality Projection against a satisfiable constraint always yields a valid value
2 Identity An already-valid candidate is returned unchanged
3 Idempotence Projecting twice equals projecting once
4 Determinism Equal recipes ⇒ equal ids ⇒ equal artifact content hashes
5 Recall integrity A ledger recall reproduces the exact artifact or raises
6 Sensitivity A constraint-violating artifact reaching its gate is LEAK, never PASS

Law 6 matters most: a proof harness you never saw catch anything proves nothing. Both shipped examples include a deliberately-broken generator variant that the sweep must catch, run in CI (tests/test_sensitivity.py).

Examples (two domains, same three primitives)

  • examples/paletteWCAG-contrast-safe color palettes. Constraint: every text/background pair meets its WCAG 2.x contrast ratio (4.5:1 normal, 3:1 large), computed, never eyeballed. nearest walks lightness to the closest compliant color. The sweep enumerates hue × lightness × role combinations and proves 0 violations.

  • examples/budgetconservation-constrained budget allocation. Constraint: channel allocations sum exactly to the total and respect per-channel min/max. nearest is a bounded redistribution. The sweep enumerates budget levels × channel mixes × bound profiles and proves conservation everywhere.

Run either:

snapgate sweep examples/palette/spec.py --json palette-report.json
snapgate sweep examples/budget/spec.py

Exit code is non-zero on any LEAK or ERROR — a sweep drops into CI as-is.

CLI

snapgate sweep <module-or-file> [--json PATH] [--progress N] [--breakdown GATE:AXIS]

A spec module declares AXES (mapping of axis name → values), GATES (list of snapgate.Gate), and generate(case) -> artifact.

When to reach for this

  • Generated output must satisfy a hard validity rule (schema, range, physical constraint, style rule, legal window) with zero tolerance for leaks.
  • You need generated artifacts to be exactly reproducible months later without storing them.
  • Your parameter space is finite and enumerable, and "we tested some of it" isn't good enough.

What this is not

  • Not a solver: nearest comes from your domain knowledge, snapgate just makes its application total, witnessed, and proven.
  • Not property-based testing: Hypothesis samples cleverly; a sweep enumerates exhaustively. Use both (snapgate's own laws are Hypothesis-tested).

Spec

The full normative specification, RFC-2119 style: SPEC.md.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

snapgate-0.1.0.tar.gz (29.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

snapgate-0.1.0-py3-none-any.whl (20.9 kB view details)

Uploaded Python 3

File details

Details for the file snapgate-0.1.0.tar.gz.

File metadata

  • Download URL: snapgate-0.1.0.tar.gz
  • Upload date:
  • Size: 29.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for snapgate-0.1.0.tar.gz
Algorithm Hash digest
SHA256 0445295e9160465c44b49570f81a6f8dc2a44ea1d6cac7b5de9aa809ae6ff265
MD5 4728fd4fe0626a52f31c203ded38e1df
BLAKE2b-256 743d98283d262d6352f1faf430c1f570d1c423ea47b16f104a1270ffe54f2d84

See more details on using hashes here.

File details

Details for the file snapgate-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: snapgate-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 20.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for snapgate-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 bdde91945346db4f9d529f5b5379c96899ffe053ecca67794edce827b3b51139
MD5 f718dd696653beebc632826fa390388f
BLAKE2b-256 4b9ae2268ddbd4f979254a85ff607bc45a839a821f6fba8f59b66840164c87a7

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page