diff --git a/docs/superpowers/issues/2026-08-18-ccx-3d-near-miss-tolerance-tier.md b/docs/superpowers/issues/2026-08-18-ccx-3d-near-miss-tolerance-tier.md index 538ed4cf..d1186e69 100644 --- a/docs/superpowers/issues/2026-08-18-ccx-3d-near-miss-tolerance-tier.md +++ b/docs/superpowers/issues/2026-08-18-ccx-3d-near-miss-tolerance-tier.md @@ -1,7 +1,88 @@ # CCX 3D near-miss contact: `tol` is not an acceptance distance — typed `exact|tolerance` tier for isolated intersections -**Status:** OPEN — measured, bisected, pinned; fix designed below, not started. -**Proposed ledger ID:** L62 *(confirm against the ledger before first use — last known used is L61).* +**Status:** IMPLEMENTED 2026-08-19 on branch `l62-ccx-tolerance-tier` +(engine commit `85a8a06`); the two strict xfails fired and are unpinned +(grid 25/25, dedup == 25); all §5 gates green at the branch head. +**Ledger ID:** L62 (confirmed free before first use). + +**Owner decisions made during the implementation session (2026-08-19), +superseding the corresponding parts of §4 below:** + +1. **No band outcome exists** *(supersedes §4.6(c))*: only an overlap is a + long touch, and an overlap must begin and end at a curve-domain + endpoint (L47 gate, unchanged). Every other case is either ONE + isolated tangent contact — the minimum-distance pair of the compact + sub-`tol` region — or, when the curves cross in and immediately back + out, the k exact crossings, distinguished at high precision. The + pending L47 band-bar / K×median question therefore does not apply to + the isolated tier at all. +2. **The tier applies in 2D**, same predicate (no dimension gate; in 2D + the transversal near-miss configuration does not exist, so the + canonical 2D near-miss is the tangent graze — pinned in + `tests/test_ccx4_tolerance_tier.py`). +3. **The parallel-planes accept-path pins re-scoped** *(owner approved the + analysis)*: their membership form contradicted §1 on 11/15 and 1/3 + parameter combos. Re-pinned in `tests/test_bez_ccx4.py` to (a) + membership tracking the REALIZED gap against `atol` in both directions + at every world position, and (b) a resolvable nonzero gap never + carrying `certification='exact'` — the phantom-root guard now lives on + the tag, where `test_absent_axis_is_checked_not_skipped` pins it at + unit level. +4. **CSX opt-out** *(resolves the §4.5 open question)*: `bez_ccx` gained + `tolerance_tier=True`; the nested CSX boundary-zero call passes + `False` (exact-only, byte-identical legacy) — whether CSX wants its own + isolated-contact tier stays a separate ledger item. + +**Implementation notes beyond the §4 design (measured during the session):** + +- The closed inequality is enforced at measurement resolution: `gap == tol` + measures `atol ± roundoff` off the net, so membership accepts within the + certified envelope `eps_d` of the boundary, and the min-of-net/Lipschitz + prune bars carry the same envelope slack (`gap == tol` was otherwise + lost to a 1-ulp coefficient rounding). +- The measurement envelope's SOURCE term is rational-only: polynomial + `D_ij = P_i − Q_j` is one correctly rounded subtraction of exact inputs + (Sterbenz), so a world translation cannot inflate it; rational + cross-products round at world scale, which is where the typed + cannot-decide tail is genuinely reachable (pinned end-to-end with a + |T|=1e12 unequal-weights fixture). +- Descent cost needed three structural rules, all measured: coarse + terminal stops for zero-free cells (wholly-in-band hull bound; + Hessian-PD unique-minimizer via `_check_uniqueness_2d` one level up) and + anisotropic refinement for curve pieces collapsed under half the dedup + radius. A shallow rational ellipse–spline crossing went 545k → 587 + cells; the 11-curve 3D grid went 46 s → 2.4 s while keeping 25/25. + +**Adversarial review (2026-08-19, 35-agent workflow, 5 lenses × 2-skeptic +verification): 15/15 findings sustained, all reproduced, all fixed** in the +follow-up commits on the branch. The load-bearing corrections: + +- The net measurement envelope is GLOBAL (extent²-scaled) and reached an + accept path: at |ctrl| ≈ 3e3 with atol=1e-3 it certified gaps up to + 1.68·atol as members and armed the cannot-decide tail ~6 orders early. + Membership now uses the sharper of the net and a direct-evaluation + measurement (`_measure_contact`), whose envelopes fail in complementary + regimes (extent² vs world position). +- The tolerance minimizer is basin-clamped to its cell (unbounded GN + jumped super-tol ridges and lost the abandoned basin's contact) — + deliberately unlike the exact tier's unbounded Newton doctrine. +- The tier never stands down call-wide on overlap-class/band evidence + (that deleted members with topology claimed complete); jurisdiction is + enforced in the drain: certified overlap spans, plus band-anchor + connectivity armed only under crossing evidence (= the never-merge + boundary, no wider). +- Component identity is decided by CONNECTIVITY only, and the walk follows + the inversion pairing with an arrival check (straight (u,v) chords + split curved components; a 3D-radius shortcut merged disconnected + ones). Grid-verified: exactly one contact per component at the argmin. +- The endpoint pre-filter bar gained the same envelope slack as every + other level-atol bar (a rotated gap==atol terminus contact was lost + 134/300 times to 1-ulp coefficient rounding). +- Adapter: a per-candidate typed cannot-decide is recorded on + `status['uncertified_contacts']` (global params + curve indices) and the + scan CONTINUES — it no longer aborts unrelated span pairs; the + NURBS-level seam re-verification carries an operand slack so it cannot + reverse closed-boundary decisions. **Pinned at:** `tests/test_nccx4.py` — two `xfail(strict=True)` on `TestNurbsCCXMultiple3D::{test_ground_truth,test_no_span_boundary_duplicates}`. Because they are strict, implementing the fix makes them FIRE — remove the pins as diff --git a/mmcore/numeric/intersection/ccx/_bez_ccx4.py b/mmcore/numeric/intersection/ccx/_bez_ccx4.py index c00fe0ab..0d21f752 100644 --- a/mmcore/numeric/intersection/ccx/_bez_ccx4.py +++ b/mmcore/numeric/intersection/ccx/_bez_ccx4.py @@ -4,6 +4,13 @@ squared-distance net ``||C1(u) - C2(v)||^2`` in Bernstein form to classify cells as NO_INTERSECTION, UNIQUE_ISOLATED, OVERLAP, or INDETERMINATE, avoiding explicit Jacobian-rank analysis. + +L62 (owner contract 2026-08-18): isolated-intersection membership is +``d_min <= atol``, closed, at every ``atol`` — the acceptance-distance +semantics standard in CAD. The strict roundoff machinery introduced by +5d05ddc is re-scoped, not reverted: it grades the ``certification`` tag and +guards sub-``atol`` topology, while membership itself is decided by the +tolerance tier's net-certified minimum measurement (see ``bez_ccx``). """ from __future__ import annotations @@ -253,10 +260,20 @@ def _eval_scalar(values): def _strict_residual_ok(C1, C2, u, v, rational, component_scale=None): """Accept a point equality only inside a floating roundoff envelope. - ``atol`` is a search/resolution tolerance, not membership in the exact - intersection set. The envelope is tied to each coordinate's own control - scale and curve degrees, so every representable nonzero offset in an - otherwise constant coordinate remains nonzero for this predicate. + The envelope is tied to each coordinate's own control scale and curve + degrees, so every representable nonzero offset in an otherwise constant + coordinate remains nonzero for this predicate. + + Post-L62 jurisdiction (owner, 2026-08-18): this strict envelope has NO + membership role. Its three jobs are (a) grading the ``certification`` + tag (``'exact'`` = agreement inside this envelope), (b) the + sub-``atol`` topology guards (distinct crossings inside a band must + never merge — resolution finer than ``atol`` is legitimately + load-bearing there), and (c) backing the typed straddle outcome of the + tolerance tier. Public membership of an isolated contact is + ``d_min <= atol`` (closed), decided by the net-certified measurement in + `_measure_net_distance` — never by this predicate and never by a raw + Newton residual. """ p1 = eval_curve(C1, float(u), rational=rational) p2 = eval_curve(C2, float(v), rational=rational) @@ -317,9 +334,12 @@ def _strict_polish_ccx(C1, C2, u, v, rational, component_scale=None, The Newton calls are intentionally unbounded by the current subdivision cell (they retain only the public [0,1] curve domains). Cell bounds are a search device and must not turn a root just across a cell seam into a - near-root. Neither Newton's step size nor ``atol`` can accept the result; - the component-wise residual certificate above is the sole membership - gate. + near-root. Neither Newton's step size nor ``atol`` can accept the + result; the component-wise residual certificate above is the sole gate + of the EXACT tier — it decides what may carry ``certification='exact'`` + and nothing more. Public membership is the L62 tolerance contract + (``d_min <= atol``, closed); a candidate this polish refuses is not + rejected, it falls through to the net-certified minimum measurement. """ u = float(np.clip(u, 0.0, 1.0)) v = float(np.clip(v, 0.0, 1.0)) @@ -572,14 +592,19 @@ def _tolerance_overlap_certificate(C1, C2, atol, rational, ptol_u, ptol_v, A non-flipping (tangential) touch inside the band is covered by the overlap; root-like dips alone are not crossing evidence. - Returns ``(overlap | None, brackets, band_evidence, span_evidence)``: + Returns ``(overlap | None, brackets, band_evidence, span_evidence, + anchors)``: ``brackets`` is a list of ``(u, v)`` seeds for strict root polishing; ``band_evidence`` is True when some qualifying domain end continues as a within-``atol`` coincidence BAND into the domain interior (inward-probe test) — a mere corner CONTACT (curves within atol at one endpoint but diverging immediately, e.g. consecutive edges of a loop sharing a vertex) is NOT band evidence and must not arm the bounded fallback; - ``span_evidence`` is the widest endpoint-qualified u-extent (or None). + ``span_evidence`` is the widest endpoint-qualified u-extent (or None); + ``anchors`` is the deduped list of endpoint-qualified ``(u, v)`` pairs — + the L62 drain suppresses tolerance candidates connected to an anchor + when the certificate ALSO found crossing structure (never merge), and + leaves corner/terminus contacts alone otherwise. """ ends1 = [np.asarray(eval_curve(C1, t, rational=rational), dtype=np.float64) for t in (0.0, 1.0)] @@ -642,13 +667,16 @@ def _outside(pt, lo, hi): if band_evidence: break - if len(cands) < 2: - return None, [], band_evidence, None + # Deduped endpoint-qualified pairs double as the BAND ANCHORS the L62 + # drain uses: structure connected to a domain-end coincidence anchor is + # this certificate's jurisdiction when crossing evidence exists. uniq = [] for u, v in cands: if not any(abs(u - uu) <= 4.0 * ptol_u and abs(v - vv) <= 4.0 * ptol_v for uu, vv in uniq): uniq.append((float(u), float(v))) + if len(cands) < 2: + return None, [], band_evidence, None, uniq span_evidence = None if len(uniq) >= 2: u_ext = [u for u, _v in uniq] @@ -743,8 +771,8 @@ def _outside(pt, lo, hi): "v_range": (float(va), float(vb)), "certification": "tolerance", "residual_max": float(res.max()), - }, brackets, band_evidence, span_evidence) - return None, brackets, band_evidence, span_evidence + }, brackets, band_evidence, span_evidence, uniq) + return None, brackets, band_evidence, span_evidence, uniq def _vector_residual_hull_excludes_zero(C1, C2, rational, depth): @@ -756,8 +784,14 @@ def _vector_residual_hull_excludes_zero(C1, C2, rational, depth): If every coefficient is strictly on the same side of zero, with a subdivision- and product-roundoff margin, the two curve pieces cannot - intersect. Independent homogeneous scales cancel because each curve is - normalized as a whole before the cross product. + intersect EXACTLY — this is a statement about the zero level set only, + never about distance (L62): a pair at distance ``tol/1e6`` satisfies it + in the offset coordinate while being a member at every practical + ``atol``. Phase 2 therefore uses it to route cells (zero-free cells + skip exact-root work and descend to their certified minimizer), and + prunes on it only when the tolerance tier is off. Independent + homogeneous scales cancel because each curve is normalized as a whole + before the cross product. Envelope (2026-07-25, cluster-4 burn-down). The margin is the house TWO-TERM derived form, not the operator term alone: @@ -833,6 +867,364 @@ def _vector_residual_hull_excludes_zero(C1, C2, rational, depth): return False +# --------------------------------------------------------------------------- +# L62: tolerance tier for isolated contacts +# --------------------------------------------------------------------------- +# Membership is ``d_min <= atol`` (closed) at every ``atol`` — the standard +# CAD semantics (owner contract 2026-08-18). The strict roundoff envelope +# above keeps exactly three jobs and NO membership role: grading the +# ``certification`` tag, the sub-``atol`` topology guards, and the straddle +# tail below. ``d_min`` is measured against the squared-distance net's own +# certified values, never against a raw Newton residual, so acceptance is +# translation-invariant to the same degree the net construction is. + +from mmcore.numeric.bern_sq_dist import bernstein_basis as _bernstein_basis + + +def _ccx_net_measurement_envelope(C1, C2, F, rational): + """Roundoff envelope for values read off the squared-distance net. + + Two-term derived form (house discipline — every factor prices an + operation actually performed, every term has an operand): + + * OPERATOR term ``eps * f_max``: Bernstein evaluation / subdivision of + the degree-(2p, 2q) net accumulates roundings of coefficients bounded + by ``max|F|``. + * SOURCE term ``eps * d_max * src``: each coefficient is a convolution + of Gram products of the cross-difference net ``D``. What ``src`` is + depends on how ``D`` rounds: + - polynomial curves: ``D_ij = P_i - Q_j`` is ONE correctly rounded + subtraction of exact inputs, so its error is result-relative + (``eps * |D|``) — a world translation cancels in the subtraction + itself (Sterbenz for nearby operands) and CANNOT inflate this + term. ``src = d_max``. + - rational curves: ``D_ij = P_i*w2_j - Q_j*w1_i`` rounds its two + PRODUCTS at world scale before the cancelling subtract, so the + operand magnitudes are the honest source — this is where a far + world position genuinely destroys precision, and where the typed + straddle outcome of `_tolerance_membership` becomes reachable. + + Direction of safety (corrected by review 2026-08-19): this envelope + reaches an ACCEPT path — the membership tie window is + ``d_hat <= atol + eps_d`` — so on its own an overpriced net envelope + IS a false-accept window (measured: 0.68·atol at |ctrl| ~ 3e3, where + the global extent² scaling dwarfs the local evaluation error). It is + therefore never used alone: `_measure_contact` pairs it with the + direct-evaluation measurement and the SMALLER certified envelope + governs, which bounds the tie window by the sharper of the two at + every scale. + """ + C1 = np.asarray(C1, dtype=np.float64) + C2 = np.asarray(C2, dtype=np.float64) + if rational: + P, Pw = C1[:, :-1], C1[:, -1] + Q, Qw = C2[:, :-1], C2[:, -1] + D = (P[:, None, :] * Qw[None, :, None] + - Q[None, :, :] * Pw[:, None, None]) + src = float(np.max( + np.abs(P)[:, None, :] * np.abs(Qw)[None, :, None] + + np.abs(Q)[None, :, :] * np.abs(Pw)[:, None, None])) + else: + D = C1[:, None, :] - C2[None, :, :] + src = float(np.max(np.abs(D))) + d_max = float(np.max(np.abs(D))) + f_max = float(np.max(np.abs(F))) + factor = 32.0 * max(1, len(C1) + len(C2)) + return factor * float(np.finfo(np.float64).eps) * (d_max * src + f_max) + + +def _measure_net_distance(F, Pw, Qw, u, v, env_F): + """Certified distance measurement at ``(u, v)`` from the top-level net. + + Returns ``(d_hat, eps_d)`` — the measured curve-curve distance and its + roundoff envelope — or ``None`` when the weight denominator collapses. + """ + p = (F.shape[0] - 1) // 2 + q = (F.shape[1] - 1) // 2 + Bu = _bernstein_basis(2 * p, float(u)) + Bv = _bernstein_basis(2 * q, float(v)) + N = float(Bu @ F @ Bv) + w1 = float(_bernstein_basis(p, float(u)) @ np.asarray(Pw, dtype=np.float64)) + w2 = float(_bernstein_basis(q, float(v)) @ np.asarray(Qw, dtype=np.float64)) + denom = (w1 * w2) ** 2 + if not np.isfinite(denom) or denom <= 0.0: + return None + d2 = N / denom + env_d2 = float(env_F) / denom + d_hat = float(np.sqrt(max(d2, 0.0))) + env_root = float(np.sqrt(max(env_d2, 0.0))) + if d_hat > env_root: + eps_d = env_d2 / d_hat + else: + # Near-zero regime: d^2 is below its own envelope, so the distance + # is only located inside [0, ~sqrt(2*env)]. + eps_d = 2.0 * env_root + return d_hat, float(eps_d) + + +def _measure_direct_distance(C1, C2, u, v, rational): + """Direct-evaluation distance measurement with an operand envelope. + + Two de Casteljau chains, one subtraction, one norm: the error scales + with the curves' own coordinate magnitudes (position + extent, + weight-conditioned for rational inputs) — LINEARLY, where the + squared-distance net's coefficients carry the pair's extent squared. + The two measurements are complementary: the net construction cancels + world position once (exactly, by Sterbenz, for polynomial inputs) but + saturates at sqrt-of-envelope for large extents; this one is sharp at + any ordinary extent but degrades with world position. Membership uses + whichever certified envelope is smaller (`_measure_contact`). + """ + p1 = np.asarray(eval_curve(C1, float(u), rational=rational), + dtype=np.float64) + p2 = np.asarray(eval_curve(C2, float(v), rational=rational), + dtype=np.float64) + if not (np.all(np.isfinite(p1)) and np.all(np.isfinite(p2))): + return None + d = float(np.linalg.norm(p1 - p2)) + pts1 = _cartesian_curve_controls_for_exactness(C1, rational) + pts2 = _cartesian_curve_controls_for_exactness(C2, rational) + if pts1 is None or pts2 is None: + return None + axis_scale = np.maximum(np.max(np.abs(pts1), axis=0), + np.max(np.abs(pts2), axis=0)) + cond = 1.0 + if rational: + C1a = np.asarray(C1, dtype=np.float64) + C2a = np.asarray(C2, dtype=np.float64) + w1 = np.abs(C1a[:, -1]) + w2 = np.abs(C2a[:, -1]) + w1_min, w2_min = float(np.min(w1)), float(np.min(w2)) + if w1_min <= 0.0 or w2_min <= 0.0: + return None + # Rational evaluation conditioning: the dehomogenizing division + # amplifies numerator roundoff by at most the weight RATIO (which + # is invariant under the homogeneous scalings the exactness suite + # pins). + cond = max(float(np.max(w1)) / w1_min, float(np.max(w2)) / w2_min) + eps = float(np.finfo(np.float64).eps) + e_axis = 8.0 * max(1, len(C1) + len(C2)) * eps * cond * axis_scale + eps_d = float(np.linalg.norm(e_axis)) + 4.0 * eps * d + return d, eps_d + + +def _measure_contact(F, Pw, Qw, C1, C2, u, v, env_F, rational): + """Certified d_min measurement: the sharper of net and direct. + + Both measurements are honest certified intervals for the same + quantity, with complementary failure modes (see the two helpers), so + the one with the smaller envelope governs. Review 2026-08-19: the + net envelope alone — global, extent²-scaled — opened a false-accept + window of up to 0.68·atol at ordinary CAD extents (|ctrl| ~ 3e3 with + atol = 1e-3) and armed the cannot-decide tail ~6 orders of magnitude + early; the direct measurement's ~eps·|coords| envelope closes both at + every scale where float64 can represent the geometry at all. + """ + m_net = _measure_net_distance(F, Pw, Qw, u, v, env_F) + m_dir = _measure_direct_distance(C1, C2, u, v, rational) + if m_net is None: + return m_dir + if m_dir is None: + return m_net + return m_dir if m_dir[1] < m_net[1] else m_net + + +def _tolerance_membership(d_hat, eps_d, atol): + """Owner membership contract (L62 §1): closed inequality, typed tail. + + ``'member'`` iff ``d_min <= atol`` with the inequality CLOSED. The + engine holds ``d_min`` only inside the certified envelope + ``[d_hat - eps_d, d_hat + eps_d]``, so the closed inequality is + enforced at measurement resolution: a value within ``eps_d`` of the + boundary IS the boundary, and the tie resolves to membership by + contract (a pair constructed at ``gap == tol`` measures + ``atol ± roundoff`` and must be exactly one intersection). Rejection + is certified: ``d_hat - eps_d > atol``. ``eps_d`` is roundoff-scale, + so the acceptance bias this admits is the measurement's own noise + floor, never a second tolerance. + + The typed ``'undecided'`` outcome arms only when the envelope both + covers the boundary AND is itself at the decision scale + (``eps_d >= atol``) — the measurement cannot resolve tolerance-sized + structure at all. With ``eps_d`` taken from `_measure_contact` (the + sharper of the net and direct envelopes) this is reachable only where + float64 genuinely cannot hold the geometry against ``atol``: + coordinate magnitudes of order ``atol / (deg·eps)`` for the direct + measurement, compounded by weight conditioning for rational inputs + (the pinned |T| = 1e12 unequal-weights fixture). + """ + if eps_d >= atol and abs(d_hat - atol) <= eps_d: + return "undecided" + return "member" if d_hat <= atol + eps_d else "reject" + + +def _polish_min_ccx(C1, C2, u0, v0, rational, max_iter=48, bounds=None): + """Damped Gauss-Newton minimizer of ``||C1(u) - C2(v)||``. + + The result is a SEARCH product only — membership is decided by the + certified measurement, never by this iteration's residual. The + iterate is clamped to ``bounds`` (the originating cell) when given, + else to [0,1]²: unlike the EXACT tier's deliberately unbounded Newton, + the minimizer must respect its cell's basin — a Gauss-Newton step + happily jumps a super-``atol`` ridge into a deeper neighboring basin, + and the abandoned basin's contact is then never emitted (measured on + a triple-dip pair: both mid-region seeds slid to the domain corners + and the interior contact vanished). Cross-cell duplicates of one + minimizer are the drain's job. A minimizer clamped onto a domain + edge is the endpoint-contact configuration. + """ + lo_u, hi_u, lo_v, hi_v = bounds if bounds is not None else ( + 0.0, 1.0, 0.0, 1.0) + lo_u = max(0.0, float(lo_u)); hi_u = min(1.0, float(hi_u)) + lo_v = max(0.0, float(lo_v)); hi_v = min(1.0, float(hi_v)) + u = float(min(hi_u, max(lo_u, float(u0)))) + v = float(min(hi_v, max(lo_v, float(v0)))) + p1, d1 = eval_curve_d1(C1, u, rational=rational) + p2, d2 = eval_curve_d1(C2, v, rational=rational) + r = p1 - p2 + f = float(np.dot(r, r)) + if not np.isfinite(f): + return u, v + for _ in range(max_iter): + a11 = float(np.dot(d1, d1)) + a22 = float(np.dot(d2, d2)) + a12 = -float(np.dot(d1, d2)) + g1 = float(np.dot(d1, r)) + g2 = -float(np.dot(d2, r)) + damp = 1e-12 * max(a11, a22) + det = (a11 + damp) * (a22 + damp) - a12 * a12 + if not np.isfinite(det) or det <= 0.0: + break + su = (-g1 * (a22 + damp) + g2 * a12) / det + sv = (-g2 * (a11 + damp) + g1 * a12) / det + if max(abs(su), abs(sv)) < 4.0 * np.finfo(np.float64).eps: + break + scale = 1.0 + improved = False + for _ls in range(20): + uc = float(min(hi_u, max(lo_u, u + scale * su))) + vc = float(min(hi_v, max(lo_v, v + scale * sv))) + p1c, d1c = eval_curve_d1(C1, uc, rational=rational) + p2c, d2c = eval_curve_d1(C2, vc, rational=rational) + rc = p1c - p2c + fc = float(np.dot(rc, rc)) + if fc < f: + u, v, p1, d1, p2, d2, r, f = uc, vc, p1c, d1c, p2c, d2c, rc, fc + improved = True + break + scale *= 0.5 + if not improved: + break + return u, v + + +def _sublevel_connected(C1, C2, F, Pw, Qw, env_F, ua, va, ub, vb, + atol, ptol_u, ptol_v, rational): + """Valley-following containment of a path in ``{D <= atol}``. + + Used to enforce the component rules: a candidate connected to an exact + root belongs to a component the exact machinery already resolved (no + tolerance contact — the tiers cannot double-count), and two connected + tolerance candidates are ONE contact at the argmin (owner decision + 2026-08-18: a compact region of sub-``atol`` distance is a single + isolated tangent intersection — there are no "band" outcomes). + + The tested path follows the PAIRING, not the straight (u,v) chord: a + sub-``atol`` component is generically curved in parameter space, and + the chord between two of its points leaves the set (review + 2026-08-19: one curved component shipped as several contacts). The + walk samples the dominant parameter axis and inverts each sample onto + the partner curve — the L47 certificate's own pairing device — so the + path tracks the valley floor, and it must ARRIVE: an inversion path + that ends on a different branch is not a connection. Aliasing thinner + than the ptol pitch remains, in the safe direction (not connected + keeps both candidates and never merges topology). + """ + du, dv = ub - ua, vb - va + walk_u = (abs(du) / max(ptol_u, 1e-12) + >= abs(dv) / max(ptol_v, 1e-12)) + span = abs(du) if walk_u else abs(dv) + pitch = max(ptol_u if walk_u else ptol_v, 1e-12) + steps = int(min(64, max(2, np.ceil(span / pitch)))) + src, dst = (C1, C2) if walk_u else (C2, C1) + t_prev = None + t_dst = None + for k in range(steps + 1): + s = k / steps + t_src = (ua + s * du) if walk_u else (va + s * dv) + seed = (va + s * dv) if walk_u else (ua + s * du) + if t_prev is not None: + seed = t_prev + pt = np.asarray(eval_curve(src, float(t_src), rational=rational), + dtype=np.float64) + t_dst, _res = _invert_point_on_curve(dst, pt, seed, rational) + u_s, v_s = (t_src, t_dst) if walk_u else (t_dst, t_src) + m = _measure_contact(F, Pw, Qw, C1, C2, u_s, v_s, env_F, rational) + if m is None or _tolerance_membership(m[0], m[1], atol) != "member": + return False + t_prev = t_dst + target = vb if walk_u else ub + arrive_tol = 4.0 * (ptol_v if walk_u else ptol_u) + return t_dst is not None and abs(t_dst - target) <= arrive_tol + + +# Cap on materialized tolerance-minimum candidates per engine call — a work +# budget in the max_results family, not a classification threshold. +_TOL_POOL_CAP = 4_096 + + + +def _endpoint_contact_candidates(C1, C2, F, Pw, Qw, env_F, atol, rational, + cells): + """Phase-1 boundary analysis lifted from level 0 to level ``atol²``. + + A component of ``{D <= atol}`` touching a domain edge of the parameter + square is a curve-terminus contact. The interior tier cannot reach it: + a boundary minimum has no interior stationary point, so the + derivative-sign prune removes its cells — exactly as Phase 1 owns the + level-0 boundary zeros. Each of the four curve termini whose boundary + net dips under the (weight-corrected) ``atol²`` hull bound is projected + onto the other curve; surviving candidates join the shared tolerance + pool, where the component rules dedup them against exact roots and + interior contacts. Billing: one cell per projection performed (the + L47 arming-scan pricing). + """ + from mmcore.numeric.intersection._sq_dist_classify import ( + _weight_max_product, + ) + cands = [] + w_sc = _weight_max_product(Pw, Qw) + edges = ( + (0, 0.0, F[0, :]), (0, 1.0, F[-1, :]), + (1, 0.0, F[:, 0]), (1, 1.0, F[:, -1]), + ) + for which, t_end, edge_net in edges: + # Sound hull pre-filter: min D² on this edge above atol² → the + # sub-level set cannot touch it. Envelope-slacked like every + # other level-atol bar in this module: the edge coefficients carry + # the net-construction roundoff, and gap == atol must survive the + # closed contract (review 2026-08-19: this was the one unslacked + # bar, and a rotated end-to-end pair at gap == atol lost its + # contact to a 1-ulp coefficient rounding 134/300 times). + if (float(np.min(edge_net)) / (w_sc ** 2) + > atol * atol + env_F / (w_sc ** 2)): + continue + if cells.remaining <= 0: + break + cells.spend(1) + src, dst = (C1, C2) if which == 0 else (C2, C1) + pt = np.asarray(eval_curve(src, t_end, rational=rational), + dtype=np.float64) + s_proj, _res = _project_point_on_curve(dst, pt, rational) + u, v = (t_end, s_proj) if which == 0 else (s_proj, t_end) + m = _measure_contact(F, Pw, Qw, C1, C2, u, v, env_F, rational) + if m is None: + continue + if _tolerance_membership(m[0], m[1], atol) == "reject": + continue + cands.append((m[0], m[1], float(u), float(v))) + return cands + from mmcore.numeric.bern import bernstein_partial_derivative_coeffs @@ -913,11 +1305,24 @@ def _phase2_ccx(F, C1, C2, C1_orig, C2_orig, known_points=None, max_depth=50, max_cells=50_000, max_results=4_096, - initial_stack=None): + initial_stack=None, + F_top=None, Pw_top=None, Qw_top=None, env_F=None, + tol_pool=None): """Phase 2: find isolated intersections via subdivision + Newton + cutout. No boundary analysis, no overlap checks, no classifier. Just: min-of-net → derivative sign → Newton → cutout. + + L62 tolerance tier: when ``tol_pool`` is a list, cells certified + zero-free are no longer pruned — they descend toward the interior + minimizer of the squared distance, and terminal cells that the strict + (exact) tier cannot accept contribute net-certified minimum candidates + ``(d_hat, eps_d, u, v)`` to the pool. The pool is drained ONCE by the + caller (component merge + membership), so this function never decides + tolerance membership on its own. With ``tol_pool=None`` the legacy + exact-only behavior is preserved bit-for-bit (nested engine callers + consume exact boundary zeros; their own tolerance semantics are a + separate contract). """ from mmcore.numeric.intersection._sq_dist_classify import ( _check_min_of_net, _check_lipschitz, _weight_max_product, @@ -954,9 +1359,6 @@ def _phase2_ccx(F, C1, C2, C1_orig, C2_orig, else: pts1 = seg1 pts2 = seg2 - if _vector_residual_hull_excludes_zero( - seg1, seg2, rational, depth): - continue bb1 = np.array(aabb(pts1)); bb1[0] -= atol; bb1[1] += atol bb2 = np.array(aabb(pts2)); bb2[0] -= atol; bb2[1] += atol if not aabb_intersect(bb1, bb2): @@ -964,12 +1366,20 @@ def _phase2_ccx(F, C1, C2, C1_orig, C2_orig, w_sc = _weight_max_product(pw, qw) - # min-of-net prune - if _check_min_of_net(F_cell, atol, w_sc): + # min-of-net / Lipschitz prunes. L62: with the tier armed, a + # certified lower bound must clear atol² by the net measurement + # envelope before the cell may be deleted — at gap == atol the true + # minimum EQUALS the bar and subdivision roundoff on the restricted + # coefficients must not break the closed membership contract. + # Under-pruning is sound (the terminal measurement rejects); the + # tier-off bar is bit-identical to the legacy one. + atol_prune = atol + if tol_pool is not None: + atol_prune = float(np.sqrt( + atol * atol + env_F / (w_sc ** 2))) + if _check_min_of_net(F_cell, atol_prune, w_sc): continue - - # Lipschitz prune - if _check_lipschitz(F_cell, atol, w_sc): + if _check_lipschitz(F_cell, atol_prune, w_sc): continue # Derivative sign pruning @@ -984,13 +1394,77 @@ def _phase2_ccx(F, C1, C2, C1_orig, C2_orig, if not can_have_stationary: continue - # ptol-based early termination - if (u1 - u0) <= ptol_u and (v1 - v0) <= ptol_v: + # L62: the vector-residual hull certifies "no exact zero on this + # cell's closure" — a statement about the ZERO LEVEL SET, not about + # distance. Using it as a cell prune was the near-miss loss site + # (a cell whose distance sits in (0, atol] was deleted with no + # downstream recourse — measured: a z-gap of tol/1e6 erased the + # intersection). With the tolerance tier armed it only ROUTES the + # cell: certified zero-free cells skip the exact-root Newton work + # and descend toward the certified minimizer instead. Tier off + # (``tol_pool is None``): it remains the prune it always was. + zero_free = _vector_residual_hull_excludes_zero( + seg1, seg2, rational, depth) + if zero_free and tol_pool is None: + continue + + # ptol-based early termination. L62 adds two COARSE terminal + # conditions for ZERO-FREE cells — a cell that cannot contain a + # root needs only to locate its minimum candidate, never to + # isolate roots at ptol resolution: + # * wholly-in-band: the hull upper bound of D² sits below atol², + # so membership cannot change by subdividing — only the argmin + # sharpens, and the minimizer polish locates it from this + # cell's seed; the drain's argmin sort + connectivity merge + # select the component argmin across cells; + # * certified-convex: `_check_uniqueness_2d`'s Hessian-PD + # certificate (the level-0 uniqueness doctrine, one level up) + # proves at most ONE interior minimizer in the cell, which the + # Gauss-Newton polish finds from any seed. + # Without these, a thin sub-atol valley (~ptol across, macroscopic + # along) forces isotropic subdivision to cover its whole length at + # ptol pitch — measured 545k cells on one shallow rational + # ellipse-spline crossing, every candidate discarded at the drain. + # Cells that may contain zeros keep the full exact-tier descent. + # + # A third structural rule (L62): an axis whose CURVE PIECE has + # collapsed — Cartesian hull diameter at or under half the dedup + # radius — is RESOLVED: every candidate inside that piece lands in + # one 3D dedup ball, so further splitting of that axis cannot + # produce additional distinct results, only descent cost + # (measured: a curve terminus curling to ~1e-4 from the partner + # kept halving a point-like piece toward ptol pitch, 100k cells on + # one span pair). Such an axis stops subdividing below; a cell + # resolved on both axes is terminal. + collapsed1 = collapsed2 = False + if tol_pool is not None: + collapsed1 = float(np.linalg.norm( + pts1.max(axis=0) - pts1.min(axis=0))) <= 0.5 * atol + collapsed2 = float(np.linalg.norm( + pts2.max(axis=0) - pts2.min(axis=0))) <= 0.5 * atol + at_ptol = (((u1 - u0) <= ptol_u or collapsed1) + and ((v1 - v0) <= ptol_v or collapsed2)) + coarse_stop = False + if tol_pool is not None and zero_free and not at_ptol: + w1_lo = float(np.min(pw)) + w2_lo = float(np.min(qw)) + if w1_lo > 0.0 and w2_lo > 0.0: + coarse_stop = ( + float(np.max(F_cell)) / ((w1_lo * w2_lo) ** 2) + <= atol * atol) + if not coarse_stop: + from mmcore.numeric.intersection._sq_dist_classify import ( + _check_uniqueness_2d, + ) + coarse_stop = _check_uniqueness_2d(F_cell) + if at_ptol or coarse_stop: u_mid = 0.5 * (u0 + u1) v_mid = 0.5 * (v0 + v1) - polished = _strict_polish_ccx( - C1_orig, C2_orig, u_mid, v_mid, rational, - component_scale=component_scale, require_newton=True) + polished = None + if not zero_free: + polished = _strict_polish_ccx( + C1_orig, C2_orig, u_mid, v_mid, rational, + component_scale=component_scale, require_newton=True) if polished is not None: u_sol, v_sol, pt = polished if (u0 - 0.25 * ptol_u <= u_sol <= u1 + 0.25 * ptol_u @@ -999,11 +1473,35 @@ def _phase2_ccx(F, C1, C2, C1_orig, C2_orig, and not _is_duplicate(isolated, pt, atol)): isolated.append({ "u": float(u_sol), "v": float(v_sol), - "point": pt, "_micro": True, + "point": pt, "certification": "exact", + "d_min": 0.0, "_micro": True, }) + elif tol_pool is not None: + # L62 terminal tolerance candidate: polish the MINIMIZER + # (not a root) and measure it against the top-level net. + # Candidates that wander out of this cell's neighborhood + # are dropped — the owning cell contributes them itself. + mu, mv = _polish_min_ccx( + C1_orig, C2_orig, u_mid, v_mid, rational, + bounds=(u0, u1, v0, v1)) + if (u0 - ptol_u <= mu <= u1 + ptol_u + and v0 - ptol_v <= mv <= v1 + ptol_v): + m = _measure_contact( + F_top, Pw_top, Qw_top, C1_orig, C2_orig, + mu, mv, env_F, rational) + if (m is not None + and _tolerance_membership(m[0], m[1], atol) + != "reject"): + if len(tol_pool) < _TOL_POOL_CAP: + tol_pool.append( + (m[0], m[1], float(mu), float(mv))) + else: + exhausted = True continue - # Newton from cell center + # Newton from cell center (exact tier — a zero-free cell cannot + # contain a root on its closure, so the strict attempts are skipped + # there and the cell descends toward its minimizer) u_mid = 0.5 * (u0 + u1) v_mid = 0.5 * (v0 + v1) uv_candidates = [ @@ -1011,28 +1509,33 @@ def _phase2_ccx(F, C1, C2, C1_orig, C2_orig, (u_mid, v_mid), ] root_found = False - for u_mid, v_mid in uv_candidates: - if root_found: - break - polished = _strict_polish_ccx( - C1_orig, C2_orig, u_mid, v_mid, rational, - component_scale=component_scale, require_newton=True) - if polished is not None: - u_sol, v_sol, pt = polished - else: - continue - if u0 < u_sol < u1 and v0 < v_sol < v1: - is_new = not _is_duplicate(isolated, pt, atol) - #print(f"CCX: is_new: {is_new}") - if is_new: - isolated.append({"u": float(u_sol), "v": float(v_sol), "point": pt}) - sub_cells = _cutout_2d( - F_cell, seg1, seg2, pw, qw, u0, u1, v0, v1, depth, - float(u_sol), float(v_sol), ptol_u, ptol_v, rational, - ) - stack.extend(sub_cells) - root_found=True + if not zero_free: + for u_mid, v_mid in uv_candidates: + if root_found: break + polished = _strict_polish_ccx( + C1_orig, C2_orig, u_mid, v_mid, rational, + component_scale=component_scale, require_newton=True) + if polished is not None: + u_sol, v_sol, pt = polished + else: + continue + if u0 < u_sol < u1 and v0 < v_sol < v1: + is_new = not _is_duplicate(isolated, pt, atol) + #print(f"CCX: is_new: {is_new}") + if is_new: + isolated.append({ + "u": float(u_sol), "v": float(v_sol), + "point": pt, "certification": "exact", + "d_min": 0.0, + }) + sub_cells = _cutout_2d( + F_cell, seg1, seg2, pw, qw, u0, u1, v0, v1, depth, + float(u_sol), float(v_sol), ptol_u, ptol_v, rational, + ) + stack.extend(sub_cells) + root_found=True + break if root_found:continue @@ -1051,19 +1554,37 @@ def _phase2_ccx(F, C1, C2, C1_orig, C2_orig, u_mid_split = 0.5 * (u0 + u1) v_mid_split = 0.5 * (v0 + v1) - seg1_L, seg1_R = _subdivide_curve(seg1) - seg2_L, seg2_R = _subdivide_curve(seg2) - F_LL, F_LR, F_RR,F_RL, =_subdivide_sq_dist_net_2d(F_cell,0.5 ,0.5) - - - pw_L = seg1_L[:, -1].copy() if rational else np.ones(seg1_L.shape[0]) - pw_R = seg1_R[:, -1].copy() if rational else np.ones(seg1_R.shape[0]) - qw_L = seg2_L[:, -1].copy() if rational else np.ones(seg2_L.shape[0]) - qw_R = seg2_R[:, -1].copy() if rational else np.ones(seg2_R.shape[0]) - stack.append((seg1_L, seg2_L, F_LL, pw_L, qw_L, u0, u_mid_split, v0, v_mid_split, depth+1)) - stack.append((seg1_L, seg2_R, F_LR, pw_L, qw_R,u0, u_mid_split, v_mid_split, v1, depth+1)) - stack.append((seg1_R, seg2_R, F_RR, pw_R, qw_R,u_mid_split, u1, v_mid_split, v1, depth+1)) - stack.append((seg1_R, seg2_L, F_RL, pw_R, qw_L,u_mid_split, u1, v0, v_mid_split, depth+1)) + split_u = not collapsed1 + split_v = not collapsed2 + if split_u and split_v: + seg1_L, seg1_R = _subdivide_curve(seg1) + seg2_L, seg2_R = _subdivide_curve(seg2) + F_LL, F_LR, F_RR,F_RL, =_subdivide_sq_dist_net_2d(F_cell,0.5 ,0.5) + + pw_L = seg1_L[:, -1].copy() if rational else np.ones(seg1_L.shape[0]) + pw_R = seg1_R[:, -1].copy() if rational else np.ones(seg1_R.shape[0]) + qw_L = seg2_L[:, -1].copy() if rational else np.ones(seg2_L.shape[0]) + qw_R = seg2_R[:, -1].copy() if rational else np.ones(seg2_R.shape[0]) + stack.append((seg1_L, seg2_L, F_LL, pw_L, qw_L, u0, u_mid_split, v0, v_mid_split, depth+1)) + stack.append((seg1_L, seg2_R, F_LR, pw_L, qw_R,u0, u_mid_split, v_mid_split, v1, depth+1)) + stack.append((seg1_R, seg2_R, F_RR, pw_R, qw_R,u_mid_split, u1, v_mid_split, v1, depth+1)) + stack.append((seg1_R, seg2_L, F_RL, pw_R, qw_L,u_mid_split, u1, v0, v_mid_split, depth+1)) + elif split_u: + # v-piece collapsed: refine u only (L62 anisotropic rule above) + seg1_L, seg1_R = _subdivide_curve(seg1) + F_L, F_R = _subdivide_sq_dist_net(F_cell, 0, 0.5) + pw_L = seg1_L[:, -1].copy() if rational else np.ones(seg1_L.shape[0]) + pw_R = seg1_R[:, -1].copy() if rational else np.ones(seg1_R.shape[0]) + stack.append((seg1_L, seg2, F_L, pw_L, qw, u0, u_mid_split, v0, v1, depth+1)) + stack.append((seg1_R, seg2, F_R, pw_R, qw, u_mid_split, u1, v0, v1, depth+1)) + else: + # u-piece collapsed: refine v only + seg2_L, seg2_R = _subdivide_curve(seg2) + F_L, F_R = _subdivide_sq_dist_net(F_cell, 1, 0.5) + qw_L = seg2_L[:, -1].copy() if rational else np.ones(seg2_L.shape[0]) + qw_R = seg2_R[:, -1].copy() if rational else np.ones(seg2_R.shape[0]) + stack.append((seg1, seg2_L, F_L, pw, qw_L, u0, u1, v0, v_mid_split, depth+1)) + stack.append((seg1, seg2_R, F_R, pw, qw_R, u0, u1, v_mid_split, v1, depth+1)) return isolated[n_known:], exhausted, cells @@ -1082,6 +1603,7 @@ def bez_ccx( max_depth=50, max_cells=100_000, max_results=4_096, + tolerance_tier=True, ) -> dict: """Bezier curve-curve intersection via two-phase architecture. @@ -1102,6 +1624,26 @@ def bez_ccx( structure that NEITHER certificate can promote and the bounded fallback cannot discretize returns ``uncertified_overlap_span=(u_lo, u_hi)`` with ``boundary_topology_complete=False`` — typed, not a bare budget flag. + + L62 isolated tolerance tier (owner contract 2026-08-18): membership of + an isolated contact is ``d_min <= atol``, CLOSED, at every ``atol`` — + ``atol`` is the acceptance distance, the standard CAD semantics. Each + ``isolated`` entry carries ``certification`` (``'exact'`` = agreement + inside the strict roundoff envelope; ``'tolerance'`` = a certified + near-miss minimum) and ``d_min`` (the net-certified measured distance; + 0.0 for exact roots). The tag is metadata — membership never depends + on it. Per component of ``{D <= atol}``: certified zeros inside → + exact roots only; zero-free and compact → exactly ONE contact at the + certified argmin (there is no "band" outcome — a long sub-``atol`` + graze is still one tangent contact); touching a domain edge → an + endpoint contact from the lifted Phase-1 boundary analysis; + boundary-anchored both ends → the L47 overlap path, unchanged. A + candidate whose measurement envelope straddles the ``atol`` boundary at + decision scale returns typed ``uncertified_contacts`` (cannot-decide, + never a guess) with ``boundary_topology_complete=False``. + ``tolerance_tier=False`` restores exact-only acceptance for engine + callers that consume level-0 boundary zeros (the nested CSX call; its + own tolerance semantics are a separate ledger item). """ C1 = np.asarray(C1, dtype=np.float64) C2 = np.asarray(C2, dtype=np.float64) @@ -1134,6 +1676,14 @@ def _result(isolated, overlaps, *, topology_complete=True): component_scale = _ccx_exactness_context( C1_orig, C2_orig, rational) + # L62: one measurement envelope per call, derived from the operands the + # net construction actually consumed; the candidate pool collects + # net-certified minima from the endpoint lift and Phase 2 and is + # drained exactly once, in ``_finalize``. + env_F = (_ccx_net_measurement_envelope(C1, C2, F, rational) + if tolerance_tier else None) + tol_pool = [] if tolerance_tier else None + isolated = [] overlaps = [] @@ -1180,7 +1730,25 @@ def _result(isolated, overlaps, *, topology_complete=True): return _result([], [], topology_complete=False) #print(f"CCX: {cls} (phase 1)") if cls.kind == NO_INTERSECTION: - return _result([], []) + # L62: the classifier's lower bounds carry construction roundoff. + # A pair whose true minimum sits within the measurement envelope of + # atol (gap == atol is a member, closed) must not be discarded by a + # bound that cleared the bar by less than that envelope — re-test + # with the envelope-slacked bar and fall through to the tier when + # inconclusive. + certified_out = True + if tolerance_tier: + from mmcore.numeric.intersection._sq_dist_classify import ( + _check_min_of_net, _check_lipschitz, + ) + w_top = float(np.max(np.abs(Pw))) * float(np.max(np.abs(Qw))) + atol_slacked = float(np.sqrt( + atol * atol + env_F / (w_top ** 2))) + certified_out = ( + _check_min_of_net(F, atol_slacked, w_top) + or _check_lipschitz(F, atol_slacked, w_top)) + if certified_out: + return _result([], []) # 1a. Collect validated boundary zeros (don't add to isolated yet) boundary_hits = [] # list of strictly validated (u, v, point) @@ -1274,11 +1842,15 @@ def _result(isolated, overlaps, *, topology_complete=True): residual_band_evidence = False uncertified_span_evidence = None interior_bracket_hits = [] + band_anchors = [] + band_crossing_evidence = False if not overlap_found and cells.remaining > 0: cells.spend(1) tol_overlap, tol_brackets, residual_band_evidence, \ - uncertified_span_evidence = _tolerance_overlap_certificate( + uncertified_span_evidence, band_anchors = \ + _tolerance_overlap_certificate( C1_orig, C2_orig, atol, rational, ptol_u, ptol_v) + band_crossing_evidence = bool(tol_brackets) if tol_overlap is not None: overlaps.append(tol_overlap) overlap_found = True @@ -1311,19 +1883,154 @@ def _result(isolated, overlaps, *, topology_complete=True): if non_affine_overlap_fallback else None ) + # L62: the tier stays armed even when the overlap-class fallback is — + # a call-wide stand-down silently lost members with topology claimed + # complete (review 2026-08-19: band evidence at one terminus deleted + # an unrelated far-end contact; an overlap-class verdict deleted every + # sub-tol member of a triple-dip pair). Jurisdiction is enforced + # STRUCTURALLY in the drain instead: candidates on certified overlap + # spans, on the structural typed span, or connected to a band anchor + # while the certificate holds crossing evidence, are suppressed there + # — which is exactly the never-merge boundary, no wider. + tier_active = bool(tolerance_tier) + + # L62 Phase-1 lift: curve-terminus contacts at level ``atol²`` (the + # boundary-touching components of {D <= atol}). + if tier_active: + tol_pool.extend(_endpoint_contact_candidates( + C1_orig, C2_orig, F, Pw, Qw, env_F, atol, rational, cells)) + + def _drain_tolerance_pool(): + """L62 component rules over the collected minimum candidates. + + Candidates ascend by measured distance, so the accepted contact of + each component is its certified argmin (owner decision 2026-08-18: + one compact sub-``atol`` region = ONE isolated tangent contact — + there is no band outcome). A candidate connected inside + ``{D <= atol}`` to an exact root — or lying on a certified overlap + span — belongs to a component the exact machinery already resolved + and is suppressed: the tiers cannot double-count by construction. + """ + nonlocal budget_exhausted + accepted, undecided = [], [] + if not tol_pool: + return accepted, undecided + # Suppression u-spans: every certified overlap range. The + # structural typed span (when the fallback exhausts unpromoted) is + # deliberately NOT one of them: it names structure the engine + # could not certify, and a certified point contact inside it is a + # refinement, not a contradiction — the never-merge boundary for + # refused bands is the anchor-connectivity rule below, which arms + # exactly when the certificate holds crossing evidence. + spans = [] + for ovl in overlaps: + lo, hi = ovl["u_range"] + spans.append((min(lo, hi), max(lo, hi))) + for d_hat, eps_d, u_c, v_c in sorted(tol_pool): + # A candidate on structure another tier already resolved (or + # typed) is suppressed REGARDLESS of its own verdict: on those + # spans the overlap machinery's outcome IS the answer, and in + # the parameter dedup ball of an accepted root/contact that + # entry is the answer — an unresolvable measurement of an + # already-resolved component is not a typed outcome (measured: + # the exact seam touch of a ray at tol=1e-6, where the net's + # sqrt roundoff floor exceeds atol, spuriously flagged its own + # root's neighborhood). + if any(lo - ptol_u <= u_c <= hi + ptol_u for lo, hi in spans): + continue + suppressed = False + for entry in isolated + accepted: + if (abs(float(entry["u"]) - u_c) <= 4.0 * ptol_u + and abs(float(entry["v"]) - v_c) <= 4.0 * ptol_v): + suppressed = True + break + if suppressed: + continue + verdict = _tolerance_membership(d_hat, eps_d, atol) + if verdict == "reject": + continue + if verdict == "undecided": + # Typed cannot-decide entries dedup by parameter proximity + # only — the connectivity test is a membership predicate + # and has no meaning at a scale the measurement cannot + # resolve. + if not any(abs(e["u"] - u_c) <= 4.0 * ptol_u + and abs(e["v"] - v_c) <= 4.0 * ptol_v + for e in undecided): + undecided.append({ + "u": float(u_c), "v": float(v_c), + "d_min": float(d_hat), "envelope": float(eps_d), + }) + continue + # Component rules, by CONNECTIVITY only (the 3D-point radius + # shortcut merged genuinely disconnected components whose + # witnesses happened to fall within atol in space — review + # 2026-08-19; connectivity is what distinguishes one graze + # from two): + # * connected to an accepted root/contact → same component, + # already represented; + # * connected to a band anchor while the L47 certificate + # holds crossing evidence → refused-band jurisdiction (the + # woven family): a point contact would merge crossing + # topology, so the typed-span path answers instead. + connected = False + for entry in isolated + accepted: + if _sublevel_connected( + C1_orig, C2_orig, F, Pw, Qw, env_F, u_c, v_c, + float(entry["u"]), float(entry["v"]), + atol, ptol_u, ptol_v, rational): + connected = True + break + if not connected and band_crossing_evidence: + for ua, va in band_anchors: + if _sublevel_connected( + C1_orig, C2_orig, F, Pw, Qw, env_F, u_c, v_c, + float(ua), float(va), + atol, ptol_u, ptol_v, rational): + connected = True + break + if connected: + continue + if len(isolated) + len(accepted) >= max_results: + budget_exhausted = True + break + p1 = np.asarray( + eval_curve(C1_orig, float(u_c), rational=rational), + dtype=np.float64) + p2 = np.asarray( + eval_curve(C2_orig, float(v_c), rational=rational), + dtype=np.float64) + accepted.append({ + "u": float(u_c), "v": float(v_c), + "point": 0.5 * (p1 + p2), + "certification": "tolerance", "d_min": float(d_hat), + }) + tol_pool.clear() + return accepted, undecided + def _finalize(topology_complete=True): # Typed L47 outcome, mirroring CSX's L42 export: when the overlap- # class structure could not be certified AND the bounded fallback # could not discretize it, name the span instead of billing the # failure to the budget with topology claimed complete. + tol_accept, tol_undecided = ( + _drain_tolerance_pool() if tier_active else ([], [])) + isolated.extend(tol_accept) structural = (non_affine_overlap_fallback and budget_exhausted and not overlap_found) - res = _result(isolated, overlaps, - topology_complete=topology_complete and not structural) + res = _result( + isolated, overlaps, + topology_complete=(topology_complete and not structural + and not tol_undecided)) if structural: span = uncertified_span_evidence or (0.0, 1.0) res["uncertified_overlap_span"] = ( float(span[0]), float(span[1])) + if tol_undecided: + # L62 typed cannot-decide (the |coords| >~ atol/eps tail): + # membership at these candidates is not measurable at the atol + # scale — named, never guessed (the L47 typed-outcome pattern). + res["uncertified_contacts"] = tol_undecided return res # 1c. Classify boundary hits: overlap endpoints go into the overlap, @@ -1355,14 +2062,16 @@ def _finalize(topology_complete=True): if len(isolated) >= max_results: budget_exhausted = True break - isolated.append({"u": u_bz, "v": v_bz, "point": pt}) + isolated.append({"u": u_bz, "v": v_bz, "point": pt, + "certification": "exact", "d_min": 0.0}) else: for u_bz, v_bz, pt in boundary_hits: if not _is_duplicate(isolated, pt, atol): if len(isolated) >= max_results: budget_exhausted = True break - isolated.append({"u": u_bz, "v": v_bz, "point": pt}) + isolated.append({"u": u_bz, "v": v_bz, "point": pt, + "certification": "exact", "d_min": 0.0}) # Interior crossings certified from the residual tier's rejected # brackets (crossing structure inside a tolerance band is topology, @@ -1372,7 +2081,8 @@ def _finalize(topology_complete=True): if len(isolated) >= max_results: budget_exhausted = True break - isolated.append({"u": u_hit, "v": v_hit, "point": pt}) + isolated.append({"u": u_hit, "v": v_hit, "point": pt, + "certification": "exact", "d_min": 0.0}) if budget_exhausted: return _finalize() @@ -1411,12 +2121,17 @@ def _finalize(topology_complete=True): C1_sub, _ = _subdivide_curve(C1_sub, u_hi_rescaled) pw_sub = C1_sub[:, -1].copy() if rational else np.ones(C1_sub.shape[0]) - # Quick min-of-net check + # Quick min-of-net check (envelope-slacked bar when the tier is + # armed — same closed-contract discipline as the Phase-2 prunes) from mmcore.numeric.intersection._sq_dist_classify import ( _check_min_of_net, _weight_max_product, ) w_sc = _weight_max_product(pw_sub, Qw) - if _check_min_of_net(F_sub, atol, w_sc): + atol_prune = atol + if tier_active: + atol_prune = float(np.sqrt( + atol * atol + env_F / (w_sc ** 2))) + if _check_min_of_net(F_sub, atol_prune, w_sc): continue # Run Phase 2 on this sub-interval × full v @@ -1436,6 +2151,8 @@ def _finalize(topology_complete=True): known_points=isolated, max_depth=max_depth, max_cells=phase2_cell_limit, max_results=max_results - len(isolated), + F_top=F, Pw_top=Pw, Qw_top=Qw, env_F=env_F, + tol_pool=(tol_pool if tier_active else None), ) cells.spend(cells_used) if non_affine_overlap_fallback: diff --git a/mmcore/numeric/intersection/ccx/_nccx4.py b/mmcore/numeric/intersection/ccx/_nccx4.py index 4f581fe4..1ec9933d 100644 --- a/mmcore/numeric/intersection/ccx/_nccx4.py +++ b/mmcore/numeric/intersection/ccx/_nccx4.py @@ -22,8 +22,13 @@ # Dtypes (self-contained, no dependency on _nccx.py) # --------------------------------------------------------------------------- +# L62: isolated entries surface the engine's typed tier — 'certification' +# ('exact' | 'tolerance') is metadata grading the measurement, 'd_min' is +# the net-certified curve-curve distance (0.0 for exact roots). Membership +# is d_min <= tol (closed) and never depends on the tag. _ccx_isolated_dtype = lambda dim: [ ('u', np.float64), ('v', np.float64), ('point', np.float64, (dim,)), + ('d_min', np.float64), ('certification', 'U9'), ] _ccx_overlap_dtype = lambda dim: [ ('u', np.float64, (2,)), ('v', np.float64, (2,)), ('point', np.float64, (2, dim)), @@ -125,10 +130,12 @@ def _dedup_isolated(entries, curves, tol): c1, c2 = int(e['curve1_i']), int(e['curve2_i']) u, v = float(e['u']), float(e['v']) pt = e['point'] + cert = str(e.get('certification', 'exact')) + d_min = float(e.get('d_min', 0.0)) if c1 <= c2: - canonical.append((c1, c2, u, v, pt)) + canonical.append((c1, c2, u, v, pt, cert, d_min)) else: - canonical.append((c2, c1, v, u, pt)) + canonical.append((c2, c1, v, u, pt, cert, d_min)) # Sort by (curve pair, u parameter) canonical.sort(key=lambda x: (x[0], x[1], x[2])) @@ -136,14 +143,18 @@ def _dedup_isolated(entries, curves, tol): # Walk and merge within each curve pair kept = [canonical[0]] for entry in canonical[1:]: - c1, c2, u, v, pt = entry - prev_c1, prev_c2, prev_u, prev_v, prev_pt = kept[-1] + c1, c2, u, v, pt, cert, d_min = entry + prev = kept[-1] - if c1 == prev_c1 and c2 == prev_c2: + if c1 == prev[0] and c2 == prev[1]: ptol_a = ptols[c1] ptol_b = ptols[c2] - if abs(u - prev_u) < ptol_a and abs(v - prev_v) < ptol_b: - # Duplicate — skip (keep the earlier one, which was sorted first) + if abs(u - prev[2]) < ptol_a and abs(v - prev[3]) < ptol_b: + # Duplicate (span-seam) — keep the better-certified side: + # an exact root over a tolerance contact, else the smaller + # measured distance (L62: the contact IS the argmin). + if _isolated_entry_beats(cert, d_min, prev[5], prev[6]): + kept[-1] = entry continue kept.append(entry) @@ -151,14 +162,75 @@ def _dedup_isolated(entries, curves, tol): # Convert back to dict format (un-canonicalize is not needed — # the canonical order is fine for the output) result = [] - for c1, c2, u, v, pt in kept: + for c1, c2, u, v, pt, cert, d_min in kept: result.append({ 'u': u, 'v': v, 'point': pt, 'curve1_i': c1, 'curve2_i': c2, + 'certification': cert, 'd_min': d_min, }) return result +def _isolated_entry_beats(cert, d_min, prev_cert, prev_d_min): + """Span-seam merge preference: exact beats tolerance, then lower d_min.""" + if cert == 'exact' and prev_cert != 'exact': + return True + if cert != 'exact' and prev_cert == 'exact': + return False + return d_min < prev_d_min + + +def _absorb_uncertified_contacts(result, status, context, return_status, + mapper): + """L62 typed cannot-decide is a PER-CANDIDATE outcome, never a span-pair + failure. Record the payload on the status ledger, mark the aggregate + incomplete, and let the candidate scan CONTINUE — escalating it into the + stop-after-span signal discarded certified intersections in span pairs + the loop never reached, under a 'budget exhausted' diagnosis that was + false (review 2026-08-19). ``mapper`` lifts each entry's span-local + parameters to the global NURBS parameterization. With + ``return_status=False`` the fail-fast contract still raises, naming the + typed cause. + """ + uncert = result.get('uncertified_contacts') + if not uncert: + return result + status.setdefault('uncertified_contacts', []).append({ + 'context': context, + 'entries': [mapper(dict(e)) for e in uncert], + }) + status['complete'] = False + status['partial_results'] += 1 + if not return_status: + raise RuntimeError( + f"{context}: typed uncertified contacts (the measurement cannot " + "decide membership at this tolerance); pass return_status=True " + "to receive the typed payload") + if not result.get('budget_exhausted', False): + # Topology-incomplete ONLY through the typed entries: the honest + # aggregate marker is status['complete']=False plus the payload — + # not a scan stop. + result = dict(result) + result['boundary_topology_complete'] = True + return result + + +def _seam_check_slack(curve1, curve2): + """Operand envelope for the adapter's NURBS-level re-verification. + + The engine accepts membership at the closed boundary within its + certified measurement envelope; re-measuring with an UNSLACKED + ``> tol`` at the NURBS level silently reversed those decisions (a + ``gap == tol`` contact evaluates to ``tol ± evaluation roundoff``). + Two de Casteljau chains and a norm, priced on the curves' own + coordinate scale. + """ + scale = max(float(np.max(np.abs(curve1.control_points))), + float(np.max(np.abs(curve2.control_points)))) + return (8.0 * (int(curve1.order) + int(curve2.order)) + * float(np.finfo(np.float64).eps) * scale) + + def _dedup_isolated_pair(entries, curve1, curve2, tol): """Deduplicate isolated intersections for a single curve pair (nurbs_ccx). @@ -178,6 +250,12 @@ def _dedup_isolated_pair(entries, curve1, curve2, tol): for entry in sorted_entries[1:]: prev = kept[-1] if abs(entry['u'] - prev['u']) < ptol_u and abs(entry['v'] - prev['v']) < ptol_v: + if _isolated_entry_beats( + entry.get('certification', 'exact'), + float(entry.get('d_min', 0.0)), + prev.get('certification', 'exact'), + float(prev.get('d_min', 0.0))): + kept[-1] = entry continue kept.append(entry) @@ -276,11 +354,18 @@ def nurbs_ccx( result = bez_ccx_v4( pts1, pts2, atol=tol, rational=rational, **call_kwargs, ) + _u_int, _v_int = _c1.interval(), _c2.interval() + result = _absorb_uncertified_contacts( + result, status, context, return_status, + lambda e, _ui=_u_int, _vi=_v_int: dict( + e, u=_ui[0] + (_ui[1] - _ui[0]) * e['u'], + v=_vi[0] + (_vi[1] - _vi[0]) * e['v'])) result, stop_after_span = _consume_bezier_status( result, status, context, return_status, remaining_cells, remaining_results, ) + seam_slack = _seam_check_slack(curve1, curve2) for inter in result['isolated']: u_glob, v_glob = _map_local_to_global( inter['u'], inter['v'], *_c1.interval(), *_c2.interval(), @@ -290,9 +375,15 @@ def nurbs_ccx( pt1 = evaluate_nurbs_curve(curve1, u_glob, 0)['C'] pt2 = evaluate_nurbs_curve(curve2, v_glob, 0)['C'] - if float(np.linalg.norm(pt1 - pt2)) >= tol: + # L62: closed membership — dist == tol is a member, up to the + # re-evaluation's own operand envelope. + if float(np.linalg.norm(pt1 - pt2)) > tol + seam_slack: continue - raw_isolated.append({'u': u_glob, 'v': v_glob, 'point': inter['point']}) + raw_isolated.append({ + 'u': u_glob, 'v': v_glob, 'point': inter['point'], + 'certification': str(inter.get('certification', 'exact')), + 'd_min': float(inter.get('d_min', 0.0)), + }) for overlap in result['overlaps']: ur = overlap.get('u_range', (0.0, 1.0)) @@ -318,6 +409,9 @@ def nurbs_ccx( isolated['u'] = [e['u'] for e in deduped] isolated['v'] = [e['v'] for e in deduped] isolated['point'] = [e['point'] for e in deduped] + isolated['d_min'] = [e.get('d_min', 0.0) for e in deduped] + isolated['certification'] = [ + e.get('certification', 'exact') for e in deduped] if not raw_overlaps_u: overlaps = None @@ -450,11 +544,19 @@ def nurbs_ccx_multiple( result = bez_ccx_v4( pts1, pts2, atol=tol, rational=rational, **call_kwargs, ) + _u_int, _v_int = segm1.interval(), segm2.interval() + result = _absorb_uncertified_contacts( + result, status, context, return_status, + lambda e, _ui=_u_int, _vi=_v_int, _a=curve1_i, _b=curve2_i: dict( + e, u=_ui[0] + (_ui[1] - _ui[0]) * e['u'], + v=_vi[0] + (_vi[1] - _vi[0]) * e['v'], + curve1_i=_a, curve2_i=_b)) result, stop_after_span = _consume_bezier_status( result, status, context, return_status, remaining_cells, remaining_results, ) + seam_slack = _seam_check_slack(curves[curve1_i], curves[curve2_i]) for inter in result['isolated']: u_glob, v_glob = _map_local_to_global( inter['u'], inter['v'], *segm1.interval(), *segm2.interval(), @@ -463,12 +565,16 @@ def nurbs_ccx_multiple( from mmcore.nurbs._nurbs_eval import evaluate_nurbs_curve pt1 = evaluate_nurbs_curve(curves[curve1_i], u_glob, 0)['C'] pt2 = evaluate_nurbs_curve(curves[curve2_i], v_glob, 0)['C'] - if float(np.linalg.norm(pt1 - pt2)) >= tol: + # L62: closed membership — dist == tol is a member, up to the + # re-evaluation's own operand envelope. + if float(np.linalg.norm(pt1 - pt2)) > tol + seam_slack: continue raw_isolated.append({ 'u': u_glob, 'v': v_glob, 'point': inter['point'], 'curve1_i': curve1_i, 'curve2_i': curve2_i, + 'certification': str(inter.get('certification', 'exact')), + 'd_min': float(inter.get('d_min', 0.0)), }) for overlap in result['overlaps']: @@ -499,6 +605,9 @@ def nurbs_ccx_multiple( isolated['point'] = [e['point'] for e in deduped] isolated['curve1_i'] = [e['curve1_i'] for e in deduped] isolated['curve2_i'] = [e['curve2_i'] for e in deduped] + isolated['d_min'] = [e.get('d_min', 0.0) for e in deduped] + isolated['certification'] = [ + e.get('certification', 'exact') for e in deduped] if not raw_overlaps: overlaps = None diff --git a/mmcore/numeric/intersection/csx/_bez_csx4.py b/mmcore/numeric/intersection/csx/_bez_csx4.py index 19291ffc..36f59eff 100644 --- a/mmcore/numeric/intersection/csx/_bez_csx4.py +++ b/mmcore/numeric/intersection/csx/_bez_csx4.py @@ -962,10 +962,15 @@ def _find_csx_boundary_zeros( if cells.remaining <= 0: exhausted = True break + # L62: exact-only. This nested call consumes level-0 boundary zeros + # for the CSX boundary analysis; CCX's isolated tolerance tier + # (membership at atol) is a different contract, and whether CSX + # wants its own isolated-contact tier is a separate ledger item. ccx_result = bez_ccx_v4( C, iso_curve, atol=atol, rational=rational, max_cells=cells.remaining, max_results=max(0, max_results - len(zeros)), + tolerance_tier=False, ) ccx_cells = int(ccx_result.get("cells_processed", 0)) ccx_cells = min(ccx_cells, cells.remaining) diff --git a/pyproject.toml b/pyproject.toml index ee820372..3aa26744 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,7 +10,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "mmcore" -version = "0.55.0" +version = "0.56.0" description = "mmcore" authors = ["Andrew Astakhov ", ] license = "Apache License Version 2.0" diff --git a/tests/test_bez_ccx4.py b/tests/test_bez_ccx4.py index 36a727b4..56a91764 100644 --- a/tests/test_bez_ccx4.py +++ b/tests/test_bez_ccx4.py @@ -495,56 +495,76 @@ def test_centering_envelope_does_not_swallow_small_real_offsets(offset): # --------------------------------------------------------------------------- -# Cluster-4 follow-up (adversarial review, 2026-07-26): the ACCEPT path needs -# anti-loosening guards too, not just the prune. +# Cluster-4 follow-up (adversarial review, 2026-07-26), re-pinned for L62 +# (owner decision 2026-08-19): the ACCEPT path needs anti-loosening guards +# too, not just the prune. # -# The absent-axis rule must never mean "skip this coordinate". Two segments -# lying in PARALLEL planes x = X0 and x = X0 + d never meet, at any world -# position. If the x axis is declared absent because d sits under the -# centering envelope, and the membership gate then omits x, the engine -# reports a confident phantom root -- the same class of wrong topology the -# prune defect caused, in the opposite direction. +# The original pins asserted `len(isolated) == 0` for every resolvable gap — +# correct while an accepted root and an exactness claim were the same thing, +# and in direct conflict with the L62 membership contract (d_min <= atol, +# CLOSED: a 1e-8 gap at atol=1e-3 IS one tolerance contact). What the +# 2026-07-26 guard bought is kept, aimed at the claims that still exist: +# the phantom-root defect class (an axis silently dropped from a +# certificate) now lives in the TAG, where +# test_absent_axis_is_checked_not_skipped pins it at unit level, and here +# end-to-end as "a resolvable nonzero gap never carries +# certification='exact'". Membership itself gains the anti-loosening +# direction the old form never tested: gap > atol must REJECT at every +# world position. # --------------------------------------------------------------------------- -def _parallel_planes_certify(X0, gap): +def _parallel_planes_case(X0, gap): C1 = np.array([[X0, -1.0, -1.0], [X0, 1.0, 1.0]]) C2 = np.array([[X0 + gap, -1.0, 1.0], [X0 + gap, 1.0, -1.0]]) - return len(bez_ccx(C1, C2, atol=1e-3, rational=False)["isolated"]) > 0 + # X0 + gap rounds: the engine is judged against the geometry it was + # actually given, not against the nominal parameter. + realized = float(C2[0, 0] - C1[0, 0]) + return bez_ccx(C1, C2, atol=1e-3, rational=False), realized -# The common-origin centering computes each coordinate as -# fl(x/scale) - fl(origin*fl(w/scale)); its error is ~4 eps per operand, so -# separations of a few ulps of the WORLD coordinate are genuinely below what -# the centered representation can resolve. Measured acceptance ceiling -# after the 2026-07-26 review fix: 7-16 ulps, i.e. ~1.6e-15 RELATIVE, and -# constant from magnitude 1 to 1e9 (it was 256-1464 ulps and growing with -# degree before). So the contract is stated relatively, and the property -# that matters is that the verdict does not depend on world position. @pytest.mark.parametrize("rel", [1e-12, 1e-10, 1e-8]) @pytest.mark.parametrize("X0", [0.0, 1.0, 1e3, 1e6, 1e9]) -def test_parallel_planes_never_certify_a_resolvable_gap(X0, rel): - gap = rel * max(1.0, abs(X0)) - assert not _parallel_planes_certify(X0, gap), (X0, rel, gap) - +def test_parallel_planes_membership_tracks_atol_never_exact(X0, rel): + """L62 §1 on the old accept-path grid, both directions, tag guarded. -@pytest.mark.parametrize("rel", [1e-14, 1e-12, 1e-8]) -def test_parallel_plane_verdict_is_translation_invariant(rel): - """Whatever the engine decides, it must decide it everywhere. + realized <= atol → exactly ONE isolated contact, tagged 'tolerance' + (never 'exact' — the re-scoped 2026-07-26 guard); realized > atol → + none. At these world positions the polynomial net construction is + translation-invariant, so no typed cannot-decide outcome may appear. + """ + gap = rel * max(1.0, abs(X0)) + r, realized = _parallel_planes_case(X0, gap) + assert "uncertified_contacts" not in r, (X0, rel, r) + iso = r["isolated"] + if realized <= 1e-3: + assert len(iso) == 1, (X0, rel, realized, len(iso)) + assert iso[0]["certification"] == "tolerance", (X0, rel, iso) + assert float(iso[0]["d_min"]) <= 1e-3 + else: + assert len(iso) == 0, (X0, rel, realized, len(iso)) - This is the real invariance contract: a fixed RELATIVE separation is the - same geometry at every world position, so the accept/reject verdict must - not move. Before the review fix the ceiling grew with |X0| in absolute - terms while shrinking in relative terms, so this property failed. - Floor: `rel` must stay above float64 representability, which is ~1.1e-16 - relative. At rel=1e-16 the verdict legitimately differs — an origin- - centred pair has no cancellation at all and resolves the gap, while at - |X0|=1e9 the same relative gap is 0.84 ulp and no method can see it. - That asymmetry is information-theoretic, not an envelope defect. +@pytest.mark.parametrize("gap", [1e-8, 5e-4, 2e-3]) +@pytest.mark.parametrize("X0", [0.0, 1.0, 1e3, 1e6, 1e9]) +def test_parallel_plane_verdict_tracks_realized_gap_at_every_position(X0, gap): + """The invariance object post-L62 is the verdict on a fixed ABSOLUTE + gap: the same realized geometry must get the same membership verdict + at every world position. (The old form held the RELATIVE gap fixed — + the right invariant for an exactness certificate, structurally wrong + for absolute-tolerance membership: rel=1e-8 is 1e-8 at the origin and + 10.0 at X0=1e9 — different geometry, different verdict, correctly.) + Where float construction changes the realized geometry (at X0=1e9 a + nominal 1e-8 gap rounds to exactly 0 — a transversal exact crossing), + the expectation follows the realized gap, and the tag follows the + strict envelope: 'exact' only when the realized gap is exactly zero. """ - verdicts = {X0: _parallel_planes_certify(X0, rel * max(1.0, abs(X0))) - for X0 in (0.0, 1.0, 1e3, 1e6, 1e9)} - assert len(set(verdicts.values())) == 1, verdicts + r, realized = _parallel_planes_case(X0, gap) + iso = r["isolated"] + expected = 1 if realized <= 1e-3 else 0 + assert len(iso) == expected, (X0, gap, realized, len(iso)) + if expected: + want_cert = "exact" if realized == 0.0 else "tolerance" + assert iso[0]["certification"] == want_cert, (X0, gap, realized, iso) def test_absent_axis_is_checked_not_skipped(): diff --git a/tests/test_ccx4_tolerance_tier.py b/tests/test_ccx4_tolerance_tier.py new file mode 100644 index 00000000..fbff647f --- /dev/null +++ b/tests/test_ccx4_tolerance_tier.py @@ -0,0 +1,443 @@ +"""L62 isolated tolerance tier — the owner membership contract (2026-08-18). + +Membership of an isolated curve-curve contact is ``d_min <= tol``, CLOSED, +at every ``tol``: at any ``tol >= d_min`` the pair has exactly one isolated +intersection there; at any ``tol < d_min`` it has none; topology is correct +at every ``tol``. The parameter values used below are instances of the law, +never special constants. ``certification`` ('exact' | 'tolerance') and +``d_min`` are metadata — membership never depends on the tag. + +Owner decisions recorded here (2026-08-18/19 session): +- there is no "band" outcome: a compact zero-free region of sub-``tol`` + distance is ONE isolated tangent contact at the certified argmin; a + dip-through is its k exact crossings, distinguished at high precision; + only a domain-end-anchored overlap is a long touch (L47, unchanged); +- the tier applies in 2D with the same predicate; +- a measurement whose envelope straddles ``tol`` at decision scale is a + typed ``uncertified_contacts`` outcome — never a guess. +""" + +import numpy as np +import pytest + +from mmcore.numeric.intersection.ccx._bez_ccx4 import bez_ccx + + +ATOL = 1e-3 + + +def _line(p0, p1): + return np.array([p0, p1], dtype=np.float64) + + +def _crossing_pair(gap, offset=(0.0, 0.0, 0.0)): + """Two transversal segments, closest approach exactly ``gap`` at + u = v = 0.5 (the minimal repro of the L62 issue doc).""" + off = np.asarray(offset, dtype=np.float64) + C1 = _line([-1.0, 0.0, 0.0], [1.0, 0.0, 0.0]) + off + C2 = _line([0.0, -1.0, gap], [0.0, 1.0, gap]) + off + return C1, C2 + + +# --------------------------------------------------------------------------- +# The (gap, tol) law +# --------------------------------------------------------------------------- + +@pytest.mark.parametrize("gap", [0.0, 1e-9, 1e-7, 2.5e-4, 5e-4, 9e-4, + 1e-3, 2e-3]) +@pytest.mark.parametrize("tol", [1e-5, 1e-4, 2.5e-4, 5e-4, 1e-3, 1e-2]) +def test_membership_tracks_tol_exactly(gap, tol): + """Exactly one intersection iff tol >= gap (closed — the grid includes + the equality instances gap == tol == 2.5e-4 / 5e-4 / 1e-3); the count + never exceeds one.""" + C1, C2 = _crossing_pair(gap) + r = bez_ccx(C1, C2, atol=tol, rational=False) + expected = 1 if gap <= tol else 0 + assert len(r["isolated"]) == expected, (gap, tol, r["isolated"]) + assert r["overlaps"] == [] + assert "uncertified_contacts" not in r + assert r["boundary_topology_complete"] is True + if expected: + iso = r["isolated"][0] + assert iso["certification"] == ("exact" if gap == 0.0 + else "tolerance") + # d_min is the net-certified measurement: equal to the gap down to + # the net's own resolution (a 1e-9 gap measures as ~0 — its squared + # trace sits below coefficient roundoff — while still a member). + assert float(iso["d_min"]) == pytest.approx(gap, abs=1e-7) + assert float(iso["u"]) == pytest.approx(0.5, abs=1e-3) + assert float(iso["v"]) == pytest.approx(0.5, abs=1e-3) + + +# --------------------------------------------------------------------------- +# Translation invariance of tolerance acceptance (the hole 5d05ddc closed +# must stay closed: acceptance comes from the net measurement, which cannot +# decay with world position for polynomial inputs) +# --------------------------------------------------------------------------- + +@pytest.mark.parametrize("offset", [ + (0.0, 0.0, 0.0), + (1.0e4, -3.0e3, 7.0e2), + (-2.0e6, 1.0e6, 5.0e5), +], ids=["origin", "1e4", "1e6"]) +def test_tolerance_contact_is_translation_invariant(offset): + gap = 5e-4 + C1, C2 = _crossing_pair(gap, offset) + r = bez_ccx(C1, C2, atol=ATOL, rational=False) + assert len(r["isolated"]) == 1, (offset, r["isolated"]) + iso = r["isolated"][0] + assert iso["certification"] == "tolerance" + assert float(iso["d_min"]) == pytest.approx(gap, rel=1e-3) + assert float(iso["u"]) == pytest.approx(0.5, abs=1e-3) + assert float(iso["v"]) == pytest.approx(0.5, abs=1e-3) + assert r["boundary_topology_complete"] is True + assert r["budget_exhausted"] is False + + +@pytest.mark.parametrize("offset", [(0.0, 0.0, 0.0), (1.0e4, -3.0e3, 7.0e2)], + ids=["origin", "1e4"]) +def test_rejection_is_translation_invariant(offset): + """The anti-loosening direction: a gap above tol rejects everywhere.""" + C1, C2 = _crossing_pair(2e-3, offset) + r = bez_ccx(C1, C2, atol=ATOL, rational=False) + assert r["isolated"] == [], (offset, r["isolated"]) + assert "uncertified_contacts" not in r + + +# --------------------------------------------------------------------------- +# Endpoint contacts (Phase-1 boundary analysis lifted from level 0 to tol²) +# --------------------------------------------------------------------------- + +def test_endpoint_contact_curve_terminus_vs_interior(): + """A curve STARTING gap-above the other curve's interior: the component + of {D <= tol} touches the v=0 domain edge only — one endpoint contact.""" + gap = 5e-4 + C1 = _line([-1.0, 0.0, 0.0], [1.0, 0.0, 0.0]) + C2 = _line([0.0, 0.0, gap], [0.0, 1.0, gap + 1.0]) + r = bez_ccx(C1, C2, atol=ATOL, rational=False) + assert len(r["isolated"]) == 1, r["isolated"] + iso = r["isolated"][0] + assert iso["certification"] == "tolerance" + assert float(iso["d_min"]) == pytest.approx(gap, rel=1e-3) + assert float(iso["u"]) == pytest.approx(0.5, abs=1e-3) + assert float(iso["v"]) == pytest.approx(0.0, abs=1e-3) + # membership still tracks tol: below the gap, no contact + r2 = bez_ccx(C1, C2, atol=1e-4, rational=False) + assert r2["isolated"] == [] + + +def test_endpoint_contact_corner_to_corner(): + """Both termini within tol of each other: a corner contact, once.""" + gap = 5e-4 + C1 = _line([-1.0, 0.0, 0.0], [0.0, 0.0, 0.0]) + C2 = _line([0.0, gap, 0.0], [1.0, 1.0, 0.0]) + r = bez_ccx(C1, C2, atol=ATOL, rational=False) + assert len(r["isolated"]) == 1, r["isolated"] + iso = r["isolated"][0] + assert iso["certification"] == "tolerance" + assert float(iso["d_min"]) == pytest.approx(gap, rel=1e-3) + assert float(iso["u"]) == pytest.approx(1.0, abs=2e-3) + assert float(iso["v"]) == pytest.approx(0.0, abs=2e-3) + r2 = bez_ccx(C1, C2, atol=1e-4, rational=False) + assert r2["isolated"] == [] + + +# --------------------------------------------------------------------------- +# Component rules: no bands, no double counts (owner decision 2026-08-18) +# --------------------------------------------------------------------------- + +def test_tangent_graze_is_exactly_one_contact(): + """A parabola grazing 5e-5 above a line: the sub-tol region is a long + interior valley (~200x the param tol), and it is ONE isolated tangent + contact at the certified argmin — never several points along the + valley, never a 'band'.""" + a, b = 5e-5, 0.1 + C1 = _line([-1.0, 0.0, 0.0], [1.0, 0.0, 0.0]) + # y(t) = a + b*(t-1/2)^2, apex a at t=1/2; ends at a+b/4 >> tol + C2 = np.array([ + [-1.0, a + b / 4.0, 0.0], + [0.0, a - b / 4.0, 0.0], + [1.0, a + b / 4.0, 0.0], + ]) + r = bez_ccx(C1, C2, atol=ATOL, rational=False) + assert len(r["isolated"]) == 1, r["isolated"] + iso = r["isolated"][0] + assert iso["certification"] == "tolerance" + assert float(iso["d_min"]) == pytest.approx(a, rel=1e-2) + assert float(iso["u"]) == pytest.approx(0.5, abs=5e-3) + assert float(iso["v"]) == pytest.approx(0.5, abs=5e-3) + assert r["overlaps"] == [] + assert r["boundary_topology_complete"] is True + + +def test_dip_through_is_two_exact_roots_no_extra_contact(): + """A curve dipping 5e-5 THROUGH the other and back out inside one + sub-tol region: the two transversal crossings are the topology — two + exact roots, distinguished at high precision, and the tolerance tier + must not add a third contact at the interior saddle (d = 5e-5 there, + a member by distance, but the component contains certified zeros and + is resolved by the exact machinery alone).""" + c = 2e-2 + C1 = _line([-1.0, 0.0, 0.0], [1.0, 0.0, 0.0]) + # y(t) = c*(t-0.45)*(t-0.55): roots at t=0.45/0.55, apex -c*2.5e-3, + # ends c*0.2475 >> tol (the component is compact-interior) + C2 = np.array([ + [-1.0, 0.2475 * c, 0.0], + [0.0, -0.2525 * c, 0.0], + [1.0, 0.2475 * c, 0.0], + ]) + r = bez_ccx(C1, C2, atol=ATOL, rational=False) + us = sorted(float(i["u"]) for i in r["isolated"]) + assert len(us) == 2, r["isolated"] + assert us[0] == pytest.approx(0.45, abs=5e-3) + assert us[1] == pytest.approx(0.55, abs=5e-3) + for iso in r["isolated"]: + assert iso["certification"] == "exact" + assert r["overlaps"] == [] + + +# --------------------------------------------------------------------------- +# 2D: same predicate (owner decision 2026-08-19) +# --------------------------------------------------------------------------- + +@pytest.mark.parametrize("gap,expected", [(5e-4, 1), (2e-3, 0)]) +def test_tier_applies_in_2d(gap, expected): + """In 2D two transversal segments always meet exactly, so the canonical + 2D near-miss is the tangent graze: a parabola whose apex passes ``gap`` + above a line without crossing.""" + C1 = np.array([[-1.0, 0.0], [1.0, 0.0]]) + C2 = np.array([ + [-1.0, gap + 0.25], [0.0, gap - 0.25], [1.0, gap + 0.25], + ]) + r = bez_ccx(C1, C2, atol=ATOL, rational=False) + assert len(r["isolated"]) == expected, (gap, r["isolated"]) + if expected: + iso = r["isolated"][0] + assert iso["certification"] == "tolerance" + assert float(iso["d_min"]) == pytest.approx(gap, rel=1e-2) + + +# --------------------------------------------------------------------------- +# The typed cannot-decide tail (never a guess) +# --------------------------------------------------------------------------- + +def test_far_translated_rational_boundary_is_typed_not_guessed(): + """Rational curves with unequal weights at |T| = 1e12: the homogeneous + cross-products round at world scale and the net measurement genuinely + cannot resolve tolerance-sized structure (eps_d >= atol). The engine + must return the typed ``uncertified_contacts`` outcome with topology + not claimed complete — never a silent accept or reject.""" + X0 = 1.0e12 + gap = 5e-4 + w = np.array([1.0, 2.0]) + C1_xyz = np.array([[X0 - 1.0, 0.0, 0.0], [X0 + 1.0, 0.0, 0.0]]) + C2_xyz = np.array([[X0, -1.0, gap], [X0, 1.0, gap]]) + C1 = np.concatenate([C1_xyz * w[:, None], w[:, None]], axis=1) + C2 = np.concatenate([C2_xyz * w[:, None], w[:, None]], axis=1) + r = bez_ccx(C1, C2, atol=ATOL, rational=True) + assert r["isolated"] == [], r["isolated"] + assert "uncertified_contacts" in r, sorted(r) + assert r["boundary_topology_complete"] is False + entry = r["uncertified_contacts"][0] + assert float(entry["envelope"]) >= ATOL + + +# --------------------------------------------------------------------------- +# Review 2026-08-19 regressions (adversarial verification of the L62 commit; +# every fixture below reproduced a confirmed defect before its fix) +# --------------------------------------------------------------------------- + +def _extent_crossing(gap, L=3000.0): + """Transversal quadratic pair of extent ±L with a pure z-gap — the + configuration where the global (extent²-scaled) net envelope alone + opened a false-accept window of up to 0.68·atol.""" + C1 = np.array([[-L, 0.0, 0.0], [0.0, 0.0, 0.0], [L, 0.0, 0.0]]) + C2 = np.array([[0.0, -L, gap], [0.0, 0.0, gap], [0.0, L, gap]]) + return C1, C2 + + +@pytest.mark.parametrize("gap,expected", [ + (5e-4, 1), (1e-3, 1), # members (closed at the boundary) + (1.2e-3, 0), (1.5e-3, 0), # the reviewed false accepts — must reject +]) +def test_membership_holds_at_large_extent(gap, expected): + """The law must hold at |ctrl| ~ 3e3 with atol=1e-3 (an ordinary part + modelled in mm at micron tolerance): acceptance comes from the sharper + of the net and direct measurements, so the accept window is the + measurement's true noise floor, never the net's extent² envelope.""" + C1, C2 = _extent_crossing(gap) + r = bez_ccx(C1, C2, atol=ATOL, rational=False) + assert len(r["isolated"]) == expected, (gap, r["isolated"]) + assert "uncertified_contacts" not in r, (gap, r) + if expected: + assert float(r["isolated"][0]["d_min"]) <= ATOL + 1e-9 + + +@pytest.mark.parametrize("L", [1.0, 300.0]) +def test_super_tol_ridge_never_merges_two_contacts(L): + """Two 8e-4 endpoint contacts separated by a 1.02e-3 ridge stay TWO + contacts at every extent — the widened connectivity walk used to step + over the ridge at L=300 and silently merge them.""" + z0 = z2 = 8e-4 + z1 = (4 * 1.02e-3 - z0 - z2) / 2.0 + C1 = np.array([[-L, 0.0, 0.0], [L, 0.0, 0.0]]) + C2 = np.array([[-L, 0.0, z0], [0.0, 0.0, z1], [L, 0.0, z2]]) + r = bez_ccx(C1, C2, atol=ATOL, rational=False) + us = sorted(round(float(i["u"]), 3) for i in r["isolated"]) + assert us == [0.0, 1.0], (L, r["isolated"]) + + +def test_band_evidence_does_not_stand_down_the_tier(): + """Band evidence at one terminus (a tangential start) must not disarm + the tier across the whole call: the unrelated far-end contact at + d = 5e-4 is a member and ships alongside the exact tangent root.""" + C1 = np.array([[0.0, 0.0, 0.0], [10.0, 0.0, 0.0]]) + C2 = np.array([[0.0, 0.0, 0.0], [3.0, 0.0, 0.0], + [6.0, -0.5, 0.0], [8.0, -0.0005, 0.0]]) + r = bez_ccx(C1, C2, atol=ATOL, rational=False) + got = sorted((round(float(i["u"]), 2), i["certification"]) + for i in r["isolated"]) + assert (0.0, "exact") in got, got + assert (0.8, "tolerance") in got, got + assert len(got) == 2, got + assert r["boundary_topology_complete"] is True + + +def test_triple_dip_reports_all_three_contacts(): + """h(t) = 5e-4 + A·(t(1-t)(t-1/2))² against a line: two terminus + contacts and one interior tangent contact, all at d = 5e-4, separated + by 5e-3 ridges. The overlap-class stand-down used to return zero of + them with topology claimed complete; the unclamped minimizer used to + slide over the ridges and lose the interior one.""" + from math import comb + + def mono_to_bern(a): + n = len(a) - 1 + return [sum(comb(i, k) / comb(n, k) * a[k] for k in range(i + 1)) + for i in range(n + 1)] + + p = np.array([0.0, 0.5, -1.5, 1.0]) # t(1-t)(t-1/2) monomials + p2 = np.polynomial.polynomial.polymul(p, p) + peak = float(np.max(np.polynomial.polynomial.polyval( + np.linspace(0.0, 1.0, 1001), p2))) + h = np.zeros(7) + h[:len(p2)] = (5e-3 / peak) * p2 + h[0] += 5e-4 + C1 = np.array([[0.0, 0.0, 0.0], [1.0, 0.0, 0.0]]) + C2 = np.column_stack([mono_to_bern([0, 1, 0, 0, 0, 0, 0]), + mono_to_bern(h.tolist()), np.zeros(7)]) + r = bez_ccx(C1, C2, atol=ATOL, rational=False) + us = sorted(round(float(i["u"]), 2) for i in r["isolated"]) + assert us == [0.0, 0.5, 1.0], r["isolated"] + for iso in r["isolated"]: + assert float(iso["d_min"]) == pytest.approx(5e-4, rel=1e-2) + + +def test_curved_component_is_one_contact_at_the_argmin(): + """Grid-verified fixture with exactly three connected components of + {D <= atol}: the engine must report exactly one contact per component, + each at the component argmin — the straight-chord connectivity used to + ship one component twice, and this cubic pair pins the valley-following + walk against that.""" + C1 = np.array([ + [0.18704965, -0.0073058, 0.0], [0.398129, -0.57963249, 0.0], + [-0.25633933, 0.09465561, 0.0], [0.79909922, -0.21653492, 0.0]]) + C2 = np.array([ + [0.01501163, 0.008352, -0.01421305], + [0.8892442, -0.37590185, 0.0064144], + [-0.28783153, -0.04980575, 0.0240725], + [-0.9890063, 0.40801458, 0.02848489]]) + r = bez_ccx(C1, C2, atol=0.05, rational=False) + got = sorted((round(float(i["u"]), 2), round(float(i["v"]), 2)) + for i in r["isolated"]) + # 401x401 grid truth: argmins of the three components + assert got == [(0.05, 0.10), (0.10, 0.41), (0.76, 0.18)], r["isolated"] + + +def test_disconnected_components_close_in_space_stay_two_contacts(): + """A loop whose two termini pass 3e-4/3.5e-4 above nearly the same + point of the line: two disconnected components whose witnesses are + within atol in 3D. The removed space-radius dedup used to absorb the + second one; connectivity is the only component discriminator.""" + C1 = np.array([[-1.0, 0.0, 0.0], [1.0, 0.0, 0.0]]) + C2 = np.array([[0.0, 3e-4, 0.0], [2.0, 1.0, 0.0], + [-2.0, 1.0, 0.0], [0.0, 3.5e-4, 0.0]]) + r = bez_ccx(C1, C2, atol=ATOL, rational=False) + vs = sorted(round(float(i["v"]), 2) for i in r["isolated"]) + assert vs == [0.0, 1.0], r["isolated"] + + +@pytest.mark.parametrize("seed", [0, 1, 2, 3]) +def test_endpoint_prefilter_survives_rotation_at_gap_equals_tol(seed): + """Collinear end-to-end pair at gap == atol, rigidly rotated: the + endpoint pre-filter's bar carries net-construction roundoff and must + be envelope-slacked like every other level-atol bar (unslacked it + dropped the contact for 134/300 rotations by a 1-ulp coefficient + rounding).""" + rng = np.random.default_rng(seed) + q = rng.normal(size=4) + q /= np.linalg.norm(q) + w, x, y, z = q + R = np.array([ + [1 - 2 * (y * y + z * z), 2 * (x * y - w * z), 2 * (x * z + w * y)], + [2 * (x * y + w * z), 1 - 2 * (x * x + z * z), 2 * (y * z - w * x)], + [2 * (x * z - w * y), 2 * (y * z + w * x), 1 - 2 * (x * x + y * y)], + ]) + C1 = np.array([[-1.0, 0.0, 0.0], [-0.5, 0.0, 0.0], [0.0, 0.0, 0.0]]) @ R.T + C2 = np.array([[ATOL, 0.0, 0.0], [ATOL + 0.5, 0.0, 0.0], + [ATOL + 1.0, 0.0, 0.0]]) @ R.T + r = bez_ccx(C1, C2, atol=ATOL, rational=False) + assert len(r["isolated"]) == 1, (seed, r["isolated"]) + assert float(r["isolated"][0]["d_min"]) == pytest.approx(ATOL, rel=1e-6) + + +# --------------------------------------------------------------------------- +# Adapter-level pins (nurbs_ccx / nurbs_ccx_multiple) +# --------------------------------------------------------------------------- + +def _ntuple_line(p0, p1): + from mmcore.nurbs._nurbs_eval import NURBSCurveTuple + return NURBSCurveTuple(order=2, knot=np.array([0.0, 0.0, 1.0, 1.0]), + control_points=np.array([p0, p1], dtype=float), + weights=np.array([1.0, 1.0])) + + +def test_adapter_closed_seam_keeps_gap_equals_tol(): + """Mutation kill for the adapter's re-verification: reverting the + closed seam check (or dropping its operand slack) loses the + gap == tol member the engine certified.""" + from mmcore.numeric.intersection.ccx._nccx4 import nurbs_ccx + c1 = _ntuple_line([-1.0, 0.0, 0.0], [1.0, 0.0, 0.0]) + c2 = _ntuple_line([0.0, -1.0, ATOL], [0.0, 1.0, ATOL]) + iso, _ovl, status = nurbs_ccx(c1, c2, tol=ATOL) + assert iso is not None and len(iso) == 1, (iso, status) + assert str(iso[0]["certification"]) == "tolerance" + assert float(iso[0]["d_min"]) == pytest.approx(ATOL, rel=1e-9) + + +def test_adapter_continues_past_typed_cannot_decide(): + """A per-candidate typed cannot-decide (the |T|=1e12 unequal-weights + pair) must not abort the scan: the unrelated clean crossing ships, the + aggregate is marked incomplete, and the typed payload reaches the + status ledger with global parameters and curve indices.""" + from mmcore.nurbs._nurbs_eval import NURBSCurveTuple + from mmcore.numeric.intersection.ccx._nccx4 import nurbs_ccx_multiple + a = _ntuple_line([-1.0, 0.0, 0.0], [1.0, 0.0, 0.0]) + b = _ntuple_line([0.0, -1.0, 0.0], [0.0, 1.0, 0.0]) + X0 = 1.0e12 + far1 = NURBSCurveTuple( + order=2, knot=np.array([0.0, 0.0, 1.0, 1.0]), + control_points=np.array([[X0 - 1.0, 0.0, 0.0], [X0 + 1.0, 0.0, 0.0]]), + weights=np.array([1.0, 2.0])) + far2 = NURBSCurveTuple( + order=2, knot=np.array([0.0, 0.0, 1.0, 1.0]), + control_points=np.array([[X0, -1.0, 5e-4], [X0, 1.0, 5e-4]]), + weights=np.array([1.0, 2.0])) + iso, _ovl, status = nurbs_ccx_multiple([a, b, far1, far2], tol=ATOL) + assert iso is not None and len(iso) == 1, (iso, status) + assert float(iso[0]["u"]) == pytest.approx(0.5, abs=1e-6) + assert status["complete"] is False + payload = status["uncertified_contacts"] + assert payload and payload[0]["entries"], status + entry = payload[0]["entries"][0] + assert {entry["curve1_i"], entry["curve2_i"]} == {2, 3} diff --git a/tests/test_nccx4.py b/tests/test_nccx4.py index 68de5222..81d29cbd 100644 --- a/tests/test_nccx4.py +++ b/tests/test_nccx4.py @@ -131,18 +131,6 @@ def result(self, curves_3d): # both latent breakages would fire the day that import is repaired). return nurbs_ccx_multiple(curves_3d, tol=0.001) - @pytest.mark.xfail(strict=True, reason= - "3D near-miss acceptance gap, unmasked 2026-08-16 when the setup import " - "was repaired (error-masked since c14fd3e): 20 of the 25 ground-truth " - "grid intersections are near-misses (curve-curve distance 4e-6..5e-4) " - "and nurbs_ccx reports only exact crossings — tol does not act as an " - "acceptance distance (0 found even at tol=1e-2). Origin bisected to " - "5d05ddc (2026-07-10, ssx5 singular hardening): _strict_residual_ok " - "deliberately retyped atol from geometric acceptance into a search " - "tolerance to kill atol-sized false roots at large coordinate scales; " - "the pre-change engine (1d9a511) finds 38 grid hits, current finds 5. " - "Issue + fix plan: " - "docs/superpowers/issues/2026-08-18-ccx-3d-near-miss-tolerance-tier.md") def test_ground_truth(self, result, expected): """All 25 known intersections (excl curve 0) must be found.""" iso, ovl, _status = result @@ -158,10 +146,6 @@ def test_ground_truth(self, result, expected): f"u={exp['u']:.4f} v={exp['v']:.4f} pt={exp['point']}" ) - @pytest.mark.xfail(strict=True, reason= - "Same 3D near-miss acceptance gap as test_ground_truth: the ==25 count " - "pins the OLD algorithm's within-tol acceptance; the v4 engine finds " - "the 5 exact crossings only.") def test_no_span_boundary_duplicates(self, result, expected): """Excluding curve 0, raw count should equal unique count (no duplicates).""" iso, ovl, _status = result