Validation report — independent tile repair kernel
Date 2026-10-30. Reference runtime: Shapely 2.2.0, GEOS 3.14.1
(3.14.1-CAPI-1.20.5, libgeos sha256 bbe7a60a…912a, libgeos_c 2166c0a8…ec93),
NumPy 2.5.4, Python 3.13 (sandbox), Linux x86-64. Production encoder
reference/tile-encoder sha256 da04be3b…4af. Rust 1.99.0 stable, edition 2024,
MSRV field 1.90. Host CPU for timings: 1 visible core, i7-6700 @ 3.40 GHz;
CARGO_BUILD_JOBS=2, target /build. All commands were run directly inside
the sandbox (per RUN-ENVIRONMENT.md), not through tools/isolate.py.
Summary
| Gate | Command | Result |
|---|---|---|
| Format | cargo fmt --all -- --check |
pass |
| Strict Clippy | cargo clippy --workspace --all-targets --locked --offline -- -D warnings |
pass (0 warnings) |
| Native tests | cargo test --locked --offline |
pass: 4 unit + 20 integration tests |
| Native build | cargo build --locked --offline |
pass |
| WASM library | cargo build --locked --offline --lib --target wasm32-unknown-unknown |
pass |
| Fixture replay, Layer A+B | python3 tools/replay.py |
pass: 51/51 kernel; 50/50 tile-adapter; wide-i32-bowtie kernel pass + encoder-domain exclusion (as specified) |
| Harness self-checks | tools/replay.py --reference-self-check, tools/check_harness.py |
pass |
| Immutable references | python3 tools/verify_package.py |
pass (hashes unchanged) |
| Scaffold prep check | tools/check_scaffold.py |
fails, as intended once implemented |
| Generated differential | candidate/tests/oracle/generated_oracle.py (3 seeds, 4,500 cases) |
0 mismatches, 0 oracle failures, 0 candidate failures; 8 reported candidate-only encoder overflows (below) |
| Stress, direct API | cargo build --release …; /build/release/examples/stress <case> |
completed; numbers below |
| Stress vs oracle (optional) | candidate/tests/oracle/stress_oracle.py |
incomplete — not a pass (stopped by custodian) |
Layer A/B: fixture replay (immutable tools/replay.py)
candidate-acceptance, 51 cases: 50 × pass (validity, emptiness, hole count,
exact equals for integral fixtures, area ratio ≤ 1e-10, boundary Hausdorff ≤
max(1e-10, 8 ulp(M)), then identical encoder presence and exact integer tile
geometry) and 1 × kernel-pass/encoder-domain-excluded (wide-i32-bowtie,
reference encoder overflow as documented in PROTOCOL.md). Failures: none.
Native test fixture_exact_coordinates_for_fractional_crossings additionally
checks that for every invalid fixture each output vertex is bit-identical to a
vertex in the oracle output (including 42/13, 30/13, −0.5 and the near-i32::MAX
crossings).
Layer C: generated differential cases (original generator)
Generator: candidate/tests/oracle/generated_oracle.py, Python random.Random(seed),
families random-rings, rectangles, fractional, near-integer, star, degenerate,
fan, nested, far-offset, dense, wide-i32, collinear, many-parts (weights in the
file). Expected results are computed live from the oracle; nothing is stored.
Each case goes through the immutable replay.check_case comparator.
| Seed | Cases | Invalid inputs | pass | pass-structural (invalid reference tile) | kernel-pass, reference encoder overflow | kernel-pass, candidate-only encoder overflow | mismatch | oracle failure | candidate failure |
|---|---|---|---|---|---|---|---|---|---|
| 20261030 | 2000 | 1873 | 1857 | 71 | 69 | 3 | 0 | 0 | 0 |
| 7 | 1000 | 921 | 923 | 36 | 38 | 3 | 0 | 0 | 0 |
| 99 | 1500 | 1380 | 1407 | 38 | 53 | 2 | 0 | 0 | 0 |
| Total | 4500 | 4174 | 4187 | 145 | 160 | 8 | 0 | 0 | 0 |
Reproduce: python3 candidate/tests/oracle/generated_oracle.py --seed S --count N
(≈ 7–8 ms per case; exit status nonzero on any mismatch/failure).
Explanation of the non-"pass" categories (not hidden as passes)
- pass-structural / invalid reference tile (145). The kernel comparison
passed, but the immutable comparator's final
MultiPolygon.equalson the encoded integer tiles returned false. In every such case the reference's own encoded tile is an invalid geometry (overlapping/retraced slivers produced by truncation), and GEOSequalson it is order-dependent: for 5 of the first 9 analysed cases the reference tile was notequalsto itself with polygon order reversed. Reproducing that would require GEOS's private component/ring enumeration order, which SPEC MV-04 excludes. For these cases only, the harness applies a stricter exact check: identical presence and identical multisets of encoded polygons (each shell and its holes as integer rings, normalised only by start rotation). All 145 are exactly identical. The immutable replay itself is unchanged and all 51 fixtures pass it directly. (During development a harness bug — canonicalising ring starts at the first copy of a repeated vertex — produced 6 false mismatches; fixed by using the lexicographically smallest rotation.) - kernel-pass, reference encoder overflow (160).
wide-i32family inputs whose oracle output already overflows the encoder'si32deltas — the same documented domain limitation aswide-i32-bowtie. Kernel comparison passed. - kernel-pass, candidate-only encoder overflow (8) — a reported difference. Full-range inputs (spans ≈ 2^32) where the oracle's output encodes but the candidate's output makes the encoder overflow. The geometry passed Layer A; the difference is only ring start/component order, which changes the cursor-move delta between rings (candidate rings start at their lexicographically smallest vertex). Inputs (seed, id): 20261030 wide-i32-600/830/1244; 7 wide-i32-25/301/807; 99 wide-i32-646/1313 (full inputs are regenerated by the seeds). Real tile coordinates are far inside this domain, but the candidate does not guarantee encodability whenever GEOS's order happens to encode. Not fixed; for custodian review.
Layer C: native adversarial/property tests (candidate/tests/properties.rs)
Labelled in the file: [O] GEOS-observed, [P] defensive policy, [Inv] invariants.
- [O] fixture polygon/hole counts and areas for all 51; bit-exact vertex sets
for invalid fixtures.
- [P] empty outer/polygon/ring inputs; empty exterior ignores holes (MV-05);
unclosed rings closed logically; 1-point, 2-point, retraced and collinear rings
never fill; consecutive duplicates ignored; full i32 square/bowtie and
nearly-parallel full-range edges; 60-deep nesting (as components and as holes);
900 disconnected parts; 64-triangle point fan and 32-triangle shared-edge fan;
partially coincident segments; near-integer crossing rounded exactly.
- [Inv] determinism (bitwise) and non-mutation (300 random); invariance under
ring rotation, reversal and component permutation (400 random, exact output
equality); idempotence of integral outputs (600 inputs, >50 integral checked);
integer translation moves output within rounding tolerance (200 random).
- Structural checks on every output: closed, finite, ≥3 distinct vertices, no
consecutive duplicates, shells clockwise / holes counter-clockwise.
- Unit tests: 256-bit product comparison, canonical points, correctly rounded
rational → binary64 (incl. ties-to-even and 20,000 cross-checks against IEEE
division).
Stress (release build, direct Rust API, one process per case)
| Case | Input | Arrangement (edges / vertices) | Iterations | Output | Wall time | Peak RSS |
|---|---|---|---|---|---|---|
| sparse-ring: 200k-vertex circle, one twist | 200,003 vertices | 200,004 / 200,003 | 2 | 1 polygon, 1 hole (pinched bay), 200,006 vertices | 0.33 s | 66 MiB |
| many-parts: 50k squares + cover | 250,005 vertices | 200,750 / 200,301 | 3 | 44,375 polygons, 5,476 holes | 0.45 s | 71 MiB |
| dense-random-ring-600 (4096 box) | 601 vertices | 80,852 / 40,726 | 134 | 20,134 polygons | 0.92 s | 23 MiB |
| strip-grid 150×150 overlapping strips | 1,500 vertices | 180,300 / 90,600 | 151 | 22,425 polygons, 1 hole | 1.05 s | 46 MiB |
| onion: 400 crossing squares/diamonds | 2,000 vertices | 406,336 / 203,968 | 401 | 101,136 polygons, 507k vertices | 9.3 s | 101 MiB |
| dense-random-ring: 2,000 vertices (10^4 box) | 2,001 vertices | 903,162 / 452,581 | 467 | 225,194 polygons, 1.13M vertices | 47.6 s | 220 MiB |
Sparse inputs are near-linear (BVH candidate search, no all-pairs work).
Intersection-dense layered inputs hit the O(I·m) regime of the iterative fill
(design.md §4). Failure policy: no cutoffs; invariant violations are returned as
RepairError (transport status: error); OOM is not guarded. No time budget is
proposed beyond these measurements.
Stress vs oracle: incomplete. stress_oracle.py sparse-ring dense-random-ring-600
strip-grid many-parts was stopped by the custodian after several CPU minutes
before printing any result (the time went to the oracle/comparator side). Per
custodian instruction it was not re-run. The stress outputs are therefore
not oracle-verified; only the direct-API completion, structural invariants
and the exact-arithmetic design back them.
Numeric tolerances and precision
- All predicates exact (i128 and 256-bit products); no epsilon anywhere in the kernel. Output coordinates are the nearest binary64 to the exact rational node.
- Acceptance tolerances are the immutable ones (area ratio 1e-10, Hausdorff max(1e-10, 8 ulp)); the grid layer is exact.
- Limitation: two distinct exact nodes within one binary64 ulp would round to the same output point; consecutive duplicates are removed and a ring with <3 distinct rounded vertices is dropped (its area is sub-ulp). Not observed in any test; no proof it cannot create an invalid touch in adversarial full-range input.
- Valid inputs: the oracle returns them unchanged; the candidate re-derives them and may add integral contact nodes (e.g. hole vertex on a shell edge) and uses its own ring direction/start. Integral nodes are unchanged by truncation.
Interface/transport changes in the mutable candidate
try_make_valid(fallible, approved for production by notes/custodian-response.md) andfallible_implementation()added;implementation()returnsSome(make_valid)(compatibility wrapper, panics only on an internal invariant violation; not on any production/transport path).src/main.rsnow calls the fallible API and reportsRepairErroras{"status":"error"}; the request format and all other statuses are unchanged.
Not done / outstanding (for the custodian)
- Layer D production integration, GDAL real-data differential tiles, Python/JS binding tests, MSRV toolchain check (1.90 not available here; built with 1.99).
- The 8 candidate-only encoder overflows above (order-dependent cursor deltas on full-range inputs).
- Whether the
equals-on-invalid-tile limitation of the immutable comparator should be amended (e.g. to the exact structural comparison used here). - Oracle verification of the stress cases (incomplete).
- No additional dependency is needed; no notes/custodian-request.md was filed.
Provenance statement
Kernel: exact.rs, arrangement.rs, topology.rs, lib.rs written in this
session from the design in notes/design.md; only std (serde_json is used by the
transport/tests only). No GEOS, JTS, PostGIS, GDAL or Terrio source was available
or consulted (notes/exposure.md). The fill rule was derived from black-box
oracle probes kept in candidate/tests/oracle/probes/. Functional agreement is
not proof of legal independence; that gate belongs to the maintainer.