FAILURE MAP
← Case archive

FA-88656 / Mesh topology invariants / Open access

Edge flip reads the second apex from the wrong corner · case 01

The second apex is an endpoint of the flipped edge, so valid flips are refused as "edge-exists".

Verified by executionVariant 1 · 7 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

For the b->a triangle the apex is read at corner j+1 instead of j+2.

VERIFIED REPAIR

The apex is the corner after the half-edge end, (j+2) mod 3.

Unsuccessful approach: Reading corner j returns b itself.

Case contract

Input [faces, a, b] for oriented triangles. The flip needs a triangle holding half-edge a->b (apex c) and one holding b->a (apex d), else "boundary"; exactly two faces may contain both a and b, else "non-manifold"; c==d is "degenerate"; an existing undirected edge c-d is "edge-exists". Otherwise replace the first triangle in place by [c,a,d] and the second by [d,b,c] and return the face list.

Why this case matters

Mesh processing pipelines (remeshing, export, simulation, printing) trust these topological counts and adjacency answers; a wrong invariant silently accepts broken meshes or rejects valid ones.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
    faces,a,b=x
    fs=[list(f) for f in faces]
    t1=t2=None
    for i,f in enumerate(fs):
        for j in range(3):
            if f[j]==a and f[(j+1)%3]==b: t1=(i,f[(j+2)%3])
            if f[j]==b and f[(j+1)%3]==a: t2=(i,f[(j+1)%3])
    if t1 is None or t2 is None: return 'boundary'
    cnt=sum(1 for f in fs if a in f and b in f)
    if cnt!=2: return 'non-manifold'
    c,d=t1[1],t2[1]
    if c==d: return 'degenerate'
    for f in fs:
        for j in range(3):
            if {f[j],f[(j+1)%3]}=={c,d}: return 'edge-exists'
    fs[t1[0]]=[c,a,d]
    fs[t2[0]]=[d,b,c]
    return fs
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['square diagonal', [[[[0, 1, 2], [2, 1, 3]], 1, 2]], [[0, 1, 3], [3, 2, 0]]], ['square diagonal reversed', [[[[0, 1, 2], [2, 1, 3]], 2, 1]], [[0, 1, 3], [3, 2, 0]]], ['rim edge', [[[[0, 1, 2], [2, 1, 3]], 0, 1]], 'boundary'], ['disk spoke', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1]], 0, 2]], [[1, 2, 3], [3, 0, 1], [0, 3, 4], [0, 4, 5], [0, 5, 1]]], ['tetrahedron edge', [[[[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]], 0, 1]], 'edge-exists'], ['octahedron edge', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 1], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]], 0, 1]], [[2, 0, 4], [0, 2, 3], [0, 3, 4], [4, 1, 2], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]]], ['book spine', [[[[0, 1, 2], [1, 0, 3], [0, 1, 4], [1, 0, 5]], 0, 1]], 'non-manifold']], [['square diagonal reversed', [[[[0, 1, 2], [2, 1, 3]], 2, 1]], [[0, 1, 3], [3, 2, 0]]], ['tetrahedron edge', [[[[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]], 0, 1]], 'edge-exists'], ['octahedron edge', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 1], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]], 0, 1]], [[2, 0, 4], [0, 2, 3], [0, 3, 4], [4, 1, 2], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]]], ['book spine', [[[[0, 1, 2], [1, 0, 3], [0, 1, 4], [1, 0, 5]], 0, 1]], 'non-manifold'], ['folded pair', [[[[0, 1, 2], [1, 0, 2]], 0, 1]], 'degenerate'], ['grid diagonal', [[[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4]], 0, 4]], [[1, 4, 3], [3, 0, 1], [1, 2, 5], [1, 5, 4]]], ['grid interior edge', [[[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4]], 1, 4]], [[0, 1, 5], [0, 4, 3], [1, 2, 5], [5, 4, 0]]]], [['disk spoke', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1]], 0, 2]], [[1, 2, 3], [3, 0, 1], [0, 3, 4], [0, 4, 5], [0, 5, 1]]], ['folded pair', [[[[0, 1, 2], [1, 0, 2]], 0, 1]], 'degenerate'], ['grid diagonal', [[[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4]], 0, 4]], [[1, 4, 3], [3, 0, 1], [1, 2, 5], [1, 5, 4]]], ['grid interior edge', [[[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4]], 1, 4]], [[0, 1, 5], [0, 4, 3], [1, 2, 5], [5, 4, 0]]], ['fan spoke', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4]], 0, 3]], [[0, 1, 2], [2, 3, 4], [4, 0, 2]]], ['rotated storage', [[[[2, 0, 1], [3, 1, 0], [2, 3, 4]], 0, 1]], 'edge-exists'], ['diagonal closing edge', [[[[0, 1, 2], [1, 0, 3], [3, 4, 2]], 0, 1]], 'edge-exists']], [['square diagonal', [[[[0, 1, 2], [2, 1, 3]], 1, 2]], [[0, 1, 3], [3, 2, 0]]], ['square diagonal reversed', [[[[0, 1, 2], [2, 1, 3]], 2, 1]], [[0, 1, 3], [3, 2, 0]]], ['octahedron edge', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 1], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]], 0, 1]], [[2, 0, 4], [0, 2, 3], [0, 3, 4], [4, 1, 2], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]]], ['fan spoke', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4]], 0, 3]], [[0, 1, 2], [2, 3, 4], [4, 0, 2]]], ['rotated storage', [[[[2, 0, 1], [3, 1, 0], [2, 3, 4]], 0, 1]], 'edge-exists'], ['diagonal closing edge', [[[[0, 1, 2], [1, 0, 3], [3, 4, 2]], 0, 1]], 'edge-exists'], ['diagonal stored reversed', [[[[0, 1, 2], [1, 0, 3], [3, 2, 4]], 0, 1]], 'edge-exists']], [['square diagonal', [[[[0, 1, 2], [2, 1, 3]], 1, 2]], [[0, 1, 3], [3, 2, 0]]], ['square diagonal reversed', [[[[0, 1, 2], [2, 1, 3]], 2, 1]], [[0, 1, 3], [3, 2, 0]]], ['rim edge', [[[[0, 1, 2], [2, 1, 3]], 0, 1]], 'boundary'], ['disk spoke', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1]], 0, 2]], [[1, 2, 3], [3, 0, 1], [0, 3, 4], [0, 4, 5], [0, 5, 1]]], ['tetrahedron edge', [[[[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]], 0, 1]], 'edge-exists'], ['folded pair', [[[[0, 1, 2], [1, 0, 2]], 0, 1]], 'degenerate'], ['diagonal stored reversed', [[[[0, 1, 2], [1, 0, 3], [3, 2, 4]], 0, 1]], 'edge-exists']]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
square diagonaledge-exists[[0, 1, 3], [3, 2, 0]]Failed
square diagonal reversededge-exists[[0, 1, 3], [3, 2, 0]]Failed
rim edgeboundaryboundaryPassed
disk spokeedge-exists[[1, 2, 3], [3, 0, 1], [0, 3, 4], [0, 4, 5], [0, 5, 1]]Failed
tetrahedron edgeedge-existsedge-existsPassed
octahedron edgeedge-exists[[2, 0, 4], [0, 2, 3], [0, 3, 4], [4, 1, 2], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]]Failed
book spinenon-manifoldnon-manifoldPassed

SHA-256 / d786de8a152e74d55ae6d4d868547a39e42d13d2e5857706049c43fd3f30ae15

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
    faces,a,b=x
    fs=[list(f) for f in faces]
    t1=t2=None
    for i,f in enumerate(fs):
        for j in range(3):
            if f[j]==a and f[(j+1)%3]==b: t1=(i,f[(j+2)%3])
            if f[j]==b and f[(j+1)%3]==a: t2=(i,f[j])
    if t1 is None or t2 is None: return 'boundary'
    cnt=sum(1 for f in fs if a in f and b in f)
    if cnt!=2: return 'non-manifold'
    c,d=t1[1],t2[1]
    if c==d: return 'degenerate'
    for f in fs:
        for j in range(3):
            if {f[j],f[(j+1)%3]}=={c,d}: return 'edge-exists'
    fs[t1[0]]=[c,a,d]
    fs[t2[0]]=[d,b,c]
    return fs
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['square diagonal', [[[[0, 1, 2], [2, 1, 3]], 1, 2]], [[0, 1, 3], [3, 2, 0]]], ['square diagonal reversed', [[[[0, 1, 2], [2, 1, 3]], 2, 1]], [[0, 1, 3], [3, 2, 0]]], ['rim edge', [[[[0, 1, 2], [2, 1, 3]], 0, 1]], 'boundary'], ['disk spoke', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1]], 0, 2]], [[1, 2, 3], [3, 0, 1], [0, 3, 4], [0, 4, 5], [0, 5, 1]]], ['tetrahedron edge', [[[[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]], 0, 1]], 'edge-exists'], ['octahedron edge', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 1], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]], 0, 1]], [[2, 0, 4], [0, 2, 3], [0, 3, 4], [4, 1, 2], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]]], ['book spine', [[[[0, 1, 2], [1, 0, 3], [0, 1, 4], [1, 0, 5]], 0, 1]], 'non-manifold']], [['square diagonal reversed', [[[[0, 1, 2], [2, 1, 3]], 2, 1]], [[0, 1, 3], [3, 2, 0]]], ['tetrahedron edge', [[[[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]], 0, 1]], 'edge-exists'], ['octahedron edge', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 1], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]], 0, 1]], [[2, 0, 4], [0, 2, 3], [0, 3, 4], [4, 1, 2], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]]], ['book spine', [[[[0, 1, 2], [1, 0, 3], [0, 1, 4], [1, 0, 5]], 0, 1]], 'non-manifold'], ['folded pair', [[[[0, 1, 2], [1, 0, 2]], 0, 1]], 'degenerate'], ['grid diagonal', [[[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4]], 0, 4]], [[1, 4, 3], [3, 0, 1], [1, 2, 5], [1, 5, 4]]], ['grid interior edge', [[[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4]], 1, 4]], [[0, 1, 5], [0, 4, 3], [1, 2, 5], [5, 4, 0]]]], [['disk spoke', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1]], 0, 2]], [[1, 2, 3], [3, 0, 1], [0, 3, 4], [0, 4, 5], [0, 5, 1]]], ['folded pair', [[[[0, 1, 2], [1, 0, 2]], 0, 1]], 'degenerate'], ['grid diagonal', [[[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4]], 0, 4]], [[1, 4, 3], [3, 0, 1], [1, 2, 5], [1, 5, 4]]], ['grid interior edge', [[[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4]], 1, 4]], [[0, 1, 5], [0, 4, 3], [1, 2, 5], [5, 4, 0]]], ['fan spoke', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4]], 0, 3]], [[0, 1, 2], [2, 3, 4], [4, 0, 2]]], ['rotated storage', [[[[2, 0, 1], [3, 1, 0], [2, 3, 4]], 0, 1]], 'edge-exists'], ['diagonal closing edge', [[[[0, 1, 2], [1, 0, 3], [3, 4, 2]], 0, 1]], 'edge-exists']], [['square diagonal', [[[[0, 1, 2], [2, 1, 3]], 1, 2]], [[0, 1, 3], [3, 2, 0]]], ['square diagonal reversed', [[[[0, 1, 2], [2, 1, 3]], 2, 1]], [[0, 1, 3], [3, 2, 0]]], ['octahedron edge', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 1], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]], 0, 1]], [[2, 0, 4], [0, 2, 3], [0, 3, 4], [4, 1, 2], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]]], ['fan spoke', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4]], 0, 3]], [[0, 1, 2], [2, 3, 4], [4, 0, 2]]], ['rotated storage', [[[[2, 0, 1], [3, 1, 0], [2, 3, 4]], 0, 1]], 'edge-exists'], ['diagonal closing edge', [[[[0, 1, 2], [1, 0, 3], [3, 4, 2]], 0, 1]], 'edge-exists'], ['diagonal stored reversed', [[[[0, 1, 2], [1, 0, 3], [3, 2, 4]], 0, 1]], 'edge-exists']], [['square diagonal', [[[[0, 1, 2], [2, 1, 3]], 1, 2]], [[0, 1, 3], [3, 2, 0]]], ['square diagonal reversed', [[[[0, 1, 2], [2, 1, 3]], 2, 1]], [[0, 1, 3], [3, 2, 0]]], ['rim edge', [[[[0, 1, 2], [2, 1, 3]], 0, 1]], 'boundary'], ['disk spoke', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1]], 0, 2]], [[1, 2, 3], [3, 0, 1], [0, 3, 4], [0, 4, 5], [0, 5, 1]]], ['tetrahedron edge', [[[[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]], 0, 1]], 'edge-exists'], ['folded pair', [[[[0, 1, 2], [1, 0, 2]], 0, 1]], 'degenerate'], ['diagonal stored reversed', [[[[0, 1, 2], [1, 0, 3], [3, 2, 4]], 0, 1]], 'edge-exists']]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
square diagonaledge-exists[[0, 1, 3], [3, 2, 0]]Failed
square diagonal reversededge-exists[[0, 1, 3], [3, 2, 0]]Failed
rim edgeboundaryboundaryPassed
disk spokeedge-exists[[1, 2, 3], [3, 0, 1], [0, 3, 4], [0, 4, 5], [0, 5, 1]]Failed
tetrahedron edgeedge-existsedge-existsPassed
octahedron edgeedge-exists[[2, 0, 4], [0, 2, 3], [0, 3, 4], [4, 1, 2], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]]Failed
book spinenon-manifoldnon-manifoldPassed

SHA-256 / f08076448d4cbeaeac622a158b077b59d5565ef8c7e449b888c509480f43bb55

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
    faces,a,b=x
    fs=[list(f) for f in faces]
    t1=t2=None
    for i,f in enumerate(fs):
        for j in range(3):
            if f[j]==a and f[(j+1)%3]==b: t1=(i,f[(j+2)%3])
            if f[j]==b and f[(j+1)%3]==a: t2=(i,f[(j+2)%3])
    if t1 is None or t2 is None: return 'boundary'
    cnt=sum(1 for f in fs if a in f and b in f)
    if cnt!=2: return 'non-manifold'
    c,d=t1[1],t2[1]
    if c==d: return 'degenerate'
    for f in fs:
        for j in range(3):
            if {f[j],f[(j+1)%3]}=={c,d}: return 'edge-exists'
    fs[t1[0]]=[c,a,d]
    fs[t2[0]]=[d,b,c]
    return fs
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['square diagonal', [[[[0, 1, 2], [2, 1, 3]], 1, 2]], [[0, 1, 3], [3, 2, 0]]], ['square diagonal reversed', [[[[0, 1, 2], [2, 1, 3]], 2, 1]], [[0, 1, 3], [3, 2, 0]]], ['rim edge', [[[[0, 1, 2], [2, 1, 3]], 0, 1]], 'boundary'], ['disk spoke', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1]], 0, 2]], [[1, 2, 3], [3, 0, 1], [0, 3, 4], [0, 4, 5], [0, 5, 1]]], ['tetrahedron edge', [[[[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]], 0, 1]], 'edge-exists'], ['octahedron edge', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 1], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]], 0, 1]], [[2, 0, 4], [0, 2, 3], [0, 3, 4], [4, 1, 2], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]]], ['book spine', [[[[0, 1, 2], [1, 0, 3], [0, 1, 4], [1, 0, 5]], 0, 1]], 'non-manifold']], [['square diagonal reversed', [[[[0, 1, 2], [2, 1, 3]], 2, 1]], [[0, 1, 3], [3, 2, 0]]], ['tetrahedron edge', [[[[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]], 0, 1]], 'edge-exists'], ['octahedron edge', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 1], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]], 0, 1]], [[2, 0, 4], [0, 2, 3], [0, 3, 4], [4, 1, 2], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]]], ['book spine', [[[[0, 1, 2], [1, 0, 3], [0, 1, 4], [1, 0, 5]], 0, 1]], 'non-manifold'], ['folded pair', [[[[0, 1, 2], [1, 0, 2]], 0, 1]], 'degenerate'], ['grid diagonal', [[[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4]], 0, 4]], [[1, 4, 3], [3, 0, 1], [1, 2, 5], [1, 5, 4]]], ['grid interior edge', [[[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4]], 1, 4]], [[0, 1, 5], [0, 4, 3], [1, 2, 5], [5, 4, 0]]]], [['disk spoke', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1]], 0, 2]], [[1, 2, 3], [3, 0, 1], [0, 3, 4], [0, 4, 5], [0, 5, 1]]], ['folded pair', [[[[0, 1, 2], [1, 0, 2]], 0, 1]], 'degenerate'], ['grid diagonal', [[[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4]], 0, 4]], [[1, 4, 3], [3, 0, 1], [1, 2, 5], [1, 5, 4]]], ['grid interior edge', [[[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4]], 1, 4]], [[0, 1, 5], [0, 4, 3], [1, 2, 5], [5, 4, 0]]], ['fan spoke', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4]], 0, 3]], [[0, 1, 2], [2, 3, 4], [4, 0, 2]]], ['rotated storage', [[[[2, 0, 1], [3, 1, 0], [2, 3, 4]], 0, 1]], 'edge-exists'], ['diagonal closing edge', [[[[0, 1, 2], [1, 0, 3], [3, 4, 2]], 0, 1]], 'edge-exists']], [['square diagonal', [[[[0, 1, 2], [2, 1, 3]], 1, 2]], [[0, 1, 3], [3, 2, 0]]], ['square diagonal reversed', [[[[0, 1, 2], [2, 1, 3]], 2, 1]], [[0, 1, 3], [3, 2, 0]]], ['octahedron edge', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 1], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]], 0, 1]], [[2, 0, 4], [0, 2, 3], [0, 3, 4], [4, 1, 2], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]]], ['fan spoke', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4]], 0, 3]], [[0, 1, 2], [2, 3, 4], [4, 0, 2]]], ['rotated storage', [[[[2, 0, 1], [3, 1, 0], [2, 3, 4]], 0, 1]], 'edge-exists'], ['diagonal closing edge', [[[[0, 1, 2], [1, 0, 3], [3, 4, 2]], 0, 1]], 'edge-exists'], ['diagonal stored reversed', [[[[0, 1, 2], [1, 0, 3], [3, 2, 4]], 0, 1]], 'edge-exists']], [['square diagonal', [[[[0, 1, 2], [2, 1, 3]], 1, 2]], [[0, 1, 3], [3, 2, 0]]], ['square diagonal reversed', [[[[0, 1, 2], [2, 1, 3]], 2, 1]], [[0, 1, 3], [3, 2, 0]]], ['rim edge', [[[[0, 1, 2], [2, 1, 3]], 0, 1]], 'boundary'], ['disk spoke', [[[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1]], 0, 2]], [[1, 2, 3], [3, 0, 1], [0, 3, 4], [0, 4, 5], [0, 5, 1]]], ['tetrahedron edge', [[[[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]], 0, 1]], 'edge-exists'], ['folded pair', [[[[0, 1, 2], [1, 0, 2]], 0, 1]], 'degenerate'], ['diagonal stored reversed', [[[[0, 1, 2], [1, 0, 3], [3, 2, 4]], 0, 1]], 'edge-exists']]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
square diagonal[[0, 1, 3], [3, 2, 0]][[0, 1, 3], [3, 2, 0]]Passed
square diagonal reversed[[0, 1, 3], [3, 2, 0]][[0, 1, 3], [3, 2, 0]]Passed
rim edgeboundaryboundaryPassed
disk spoke[[1, 2, 3], [3, 0, 1], [0, 3, 4], [0, 4, 5], [0, 5, 1]][[1, 2, 3], [3, 0, 1], [0, 3, 4], [0, 4, 5], [0, 5, 1]]Passed
tetrahedron edgeedge-existsedge-existsPassed
octahedron edge[[2, 0, 4], [0, 2, 3], [0, 3, 4], [4, 1, 2], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]][[2, 0, 4], [0, 2, 3], [0, 3, 4], [4, 1, 2], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]]Passed
book spinenon-manifoldnon-manifoldPassed

SHA-256 / aa64a4705028691b10d3cacba688947d83c8ab1f3432a898ac2a9dc09153d970

Verification & scope

Pure combinatorial teaching model over integer face lists with a stipulated contract; no geometry kernel or file format is implied. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.

Observations recorded using Python 3.12.14 at 2026-09-29T14:51:10.122250+00:00.

Case digest / 15f9be81313b3f0e4e02d1c25460c6ce0028fecd16997555f58bc3327403d34a