#513 was already an explicit census of continuity handling across the kernel and
the bridge, written as prose. This turns it into a committed, executable artifact
that measures the current tree instead of a list in an issue body that goes stale
the next time someone touches this code -- which #490/#480/#398/#619 already have,
since #513 was filed.
Scripts/repro/censuses/ClusterD.swift (dynamic, primary evidence): 31 distinct
entry points measured against real fixtures -- the knot-splitting family's one
contract across five entry points, the three canonical occtGeomAbsFrom* decoders'
saturation behaviour probed at every raw-Int-reachable site, the plate/filling
family's raw pass-through (reproducing #437 directly), the result-side raw-cast
family, and BRepGraph.edgeMaxContinuity's still-live stub (proven, not assumed, by
contrast against Shape.maxContinuity on the same cylinder).
Scripts/repro/cluster-d-continuity/classify_continuity_sites.py (static
cross-check): classifies 42 named bridge functions by which decoder each calls, or
none. 13/13 self-test cases pass, each with a proven guard-removal pair.
Scripts/repro/cluster-d-continuity/README.md: the encodings as measured (three
canonical decoders plus two structurally different raw pass-throughs, not #513's
own "four"), the guard-removal matrix, and the verdict that #437 is an instance of
the shared root while #438 is an independent API-duplication defect -- correcting
#667's framing that both are instances of the same thing.
This is the census only. It does not fix #437, #438, or the edgeMaxContinuity stub.
Verified: clean full-package build (0 errors, 0 new warnings), full swift test
(5356/5356), cluster-a (45 rows) and cluster-b (16 rows) unchanged, all four gate
scripts plus their --self-tests, and this census's own classifier self-test.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
What & why
Cluster D of the v2.0.0 release (#667). #513 already wrote the continuity-handling
census as prose: 38 unaudited bridge functions, four incompatible request
encodings, two live defects. This PR turns that into a committed, executable
artifact that measures the current tree, per #667's own instruction ("#513 is
already an explicit census... Do the census, then the instances fall out").
This PR is the census only. It does not fix #437, #438, or
BRepGraph.edgeMaxContinuity's stub.What's here
Scripts/repro/censuses/ClusterD.swift(dynamic, primary evidence,swift run Censuses cluster-d): 31 distinct entry points measured against real fixtures.Scripts/repro/cluster-d-continuity/classify_continuity_sites.py(staticcross-check): classifies 42 named bridge functions by which of the three
shared
occtGeomAbsFrom*decoders (Consolidate the bridge's ~8 duplicate int→GeomAbs_Shape continuity mappers — divergent numbering already shipped one bug (#433) and still causes bsplineRestriction vs bsplineRestrictionAdvanced to silently disagree #490) each calls, or none. 13/13 self-testcases pass, each with a proven guard-removal pair.
Scripts/repro/cluster-d-continuity/README.md: full write-up.CensusRunner.swiftregisteringcluster-d.Headline findings
Two of its named "live defects" (
FilletBuilder.setContinuity's raw cast,OCCTThruSectionsSetContinuity's old reading) were fixed as part of Consolidate the bridge's ~8 duplicate int→GeomAbs_Shape continuity mappers — divergent numbering already shipped one bug (#433) and still causes bsplineRestriction vs bsplineRestrictionAdvanced to silently disagree #490's ownPR, which cites Continuity handling census across the kernel and the bridge: 38 unaudited functions, four incompatible request encodings, two live defects #513 by number in its source comments. The one still open:
BRepGraph.edgeMaxContinuityis confirmed (not assumed) to be a hardcodedstub always returning 0, contrasted against
Shape.maxContinuity(edge:)reporting the real class on the same cylinder.
encodings." Plus two structurally different raw pass-throughs (the
knot-splitting family's literal derivative order, ruled non-decodable by Surface/LawFunction knot splitting kept the continuity cap of 2 that #398 proved is a no-op #480;
the plate family's literal
GeomPlateorder, undocumented until now).#438-shaped duplicate, found beyond Continuity handling census across the kernel and the bridge: 38 unaudited functions, four incompatible request encodings, two live defects #513's own list:Surface.splitByContinuityandSurface.splitSurfaceByContinuityare twopublic APIs over the same
ShapeUpgrade_SplitSurfaceContinuity-- confirmednow converged (Consolidate the bridge's ~8 duplicate int→GeomAbs_Shape continuity mappers — divergent numbering already shipped one bug (#433) and still causes bsplineRestriction vs bsplineRestrictionAdvanced to silently disagree #490), not diverged.
.g2point constraint failsplateSurface(through:orders:)every time; curve constraints don't have thesame restriction. Confirmed as a raw pass-through into
GeomPlate_PointConstraint's own literal order, not a decode bug.a genuine instance of the shared "four encodings" root (a raw pass-through
hitting a real OCCT domain restriction). divided(at:) and dividedByContinuity(criterion:tolerance:) are two public APIs over one OCCT class #438 is independent: both
divided(at:)/dividedByContinuitycorrectly decode through the samecanonical decoder; they diverge because they set different criteria on the
underlying builder, an API-surface duplication question, not an encoding one.
Shape.continuity(edge:...)(BRep_Tool, unmigrated) disagrees with
continuityClassOfFaces(BRepLib,migrated by Bridge's GeomAbs_Shape ordinal vocabulary for continuity is hand-copied into three divergent C++ conversion helpers (orderToShape/shapeToOrder ×2, continuityFromInt78) and four drifted header comments, never wired to the canonical Surface.Continuity enum #398/PR#436 established #495) on a cylinder's seam edge (0 vs cN). The first hypothesis
tried (a cached-flag vs live-computation gap) was tested directly with
encodingRegularity()and disproved. A narrower, unconfirmed mechanism isrecorded in the README rather than a guess dressed as a finding.
Verdict on #513
Recommend closing once this merges: its own ask (turn the prose into an
executable artifact) is done, its live defects are one fixed / one tracked as a
small follow-up, and its remaining open decision (the null/failure sentinel
policy on the result side) is a design question better tracked on its own than
kept open against a census issue whose job is complete. Full reasoning in the
README's "Should #513 close?" section.
Verify
deliberate ClusterA.swift deprecation warning).
swift test: 5356/5356 passing, run twice for confirmation.swift run Censuses cluster-a: still 45 rows, unchanged logic.swift run Censuses cluster-b: still 16 rows, unchanged logic.check-bridge-index,check-null-handle-guards,check-docs-defaults,count-operations) plus their--self-tests: pass.classify_continuity_sites.py --self-test: 13/13, guard-removal matrix inthe README.
Checklist
--self-testfor thestatic classifier, with every case proven by removing the guard and
watching the classification move, per
okf/policies/prove-the-test-fails.md.Notes for the reviewer
No files in this PR overlap with the two other PRs open against
refactor/381-pass1bat the time of writing (#711, Cluster C'scheck-null-handle-guards.pyupgrade; #712,ClusterB.swift/#633fix) --confirmed by diffing file lists before opening this PR.
Closes #513