Bug B: profile_extrude has no inlier-coverage gate #48

Closed
opened 2026-06-24 22:25:57 +00:00 by Mark · 1 comment
Owner

Strategy gap: profile_extrude has no inlier-coverage gate

What is missing

derive_profile_operations emits a profile_extrude primitive with a
depth that may be silently wrong. The current depth heuristic (when no
axial cone/cylinder is available) is "10% of the polygon's largest XY
extent" — see the original bug description in pc2cad#24 bug 2 / #39.
That heuristic produced a 0.01 m thick plate on a 1–2 mm slab.

There is no metric anywhere in pc2cad.py that says "this
profile_extrude accounts for ≥95% of the polygon's inlier points
within tolerance". Without that gate, a profile_extrude is emitted
regardless of whether it explains the input points.

This is a strategy gap (no quality metric exists for
profile_extrude), not a function bug (the function works as designed).

Sample

samples/strategy_plate_with_hole.ply (7000 points, σ=0.2 mm)

Parametric ground truth (build123d):

  • Body: 100 × 100 × 10 mm plate
  • Features: Ø20 through-hole, 1 mm chamfer on top edges
  • The plate's profile_extrude depth is exactly 10 mm (matches
    build123d bbox Z extent)
  • See samples/specs/strategy_plate_with_hole_spec.py

What a real fix has to produce

Add inlier_coverage(profile_extrude, polygon_points, tolerance) -> float that returns the fraction of polygon inliers within tolerance of
the extruded surface. Gate the emit of profile_extrude on coverage ≥
0.95 (configurable via FitConfig). Expose the metric through
fit_primitives's return value so callers and tests can inspect it.

Acceptance — agentic / visual verification

python tests/render_compare.py \
    samples/strategy_plate_with_hole.ply /tmp/bug_B_plate.step \
    --spec samples/specs/strategy_plate_with_hole_spec.py \
    --out-dir /tmp/bug_B_plate --tolerance 1.0 --min-coverage 0.85

The command must exit 0 (coverage ≥ 0.85). The closing comment must
include:

  1. /tmp/bug_B_plate/side_by_side.png
  2. The numerical coverage value from metrics.json
  3. A demonstration that a deliberately-wrong depth (e.g. forced to
    0.01 × 10 = 0.1 mm) is now rejected by the coverage gate —
    show the test that asserts coverage drops below 0.95 and the gate
    reverts to the 10%-of-extent fallback (or whatever fallback the
    implementer chose).

A commit that ships a coverage-metric helper but does not wire it into
derive_profile_operations is not a real fix — the metric must
actually be the gate.

Why this is a strategy gap and not a function bug

This bug was filed originally as pc2cad#24 bug 2 and decomposed to
pc2cad#39, but the body described the symptom (depth source wrong)
without naming the missing capability (no inlier-coverage metric).
Closing this bug requires the metric to exist AND be the gate AND be
demonstrably correct on the synthetic plate sample.

  • pc2cad#24 (parent), pc2cad#39 (symptom-level child)
  • Bug A (body+features composition)
  • Bug D (visual harness committed)

How to regenerate the sample

python scripts/gen_strategy_samples.py
## Strategy gap: profile_extrude has no inlier-coverage gate ### What is missing `derive_profile_operations` emits a `profile_extrude` primitive with a depth that may be silently wrong. The current depth heuristic (when no axial cone/cylinder is available) is "10% of the polygon's largest XY extent" — see the original bug description in pc2cad#24 bug 2 / #39. That heuristic produced a 0.01 m thick plate on a 1–2 mm slab. There is no metric anywhere in `pc2cad.py` that says "this profile_extrude accounts for ≥95% of the polygon's inlier points within tolerance". Without that gate, a profile_extrude is emitted regardless of whether it explains the input points. This is a **strategy gap** (no quality metric exists for profile_extrude), not a function bug (the function works as designed). ### Sample `samples/strategy_plate_with_hole.ply` (7000 points, σ=0.2 mm) Parametric ground truth (build123d): - Body: 100 × 100 × 10 mm plate - Features: Ø20 through-hole, 1 mm chamfer on top edges - The plate's profile_extrude depth is **exactly 10 mm** (matches build123d bbox Z extent) - See `samples/specs/strategy_plate_with_hole_spec.py` ### What a real fix has to produce Add `inlier_coverage(profile_extrude, polygon_points, tolerance) -> float` that returns the fraction of polygon inliers within tolerance of the extruded surface. Gate the emit of profile_extrude on coverage ≥ 0.95 (configurable via `FitConfig`). Expose the metric through `fit_primitives`'s return value so callers and tests can inspect it. ### Acceptance — agentic / visual verification ```bash python tests/render_compare.py \ samples/strategy_plate_with_hole.ply /tmp/bug_B_plate.step \ --spec samples/specs/strategy_plate_with_hole_spec.py \ --out-dir /tmp/bug_B_plate --tolerance 1.0 --min-coverage 0.85 ``` The command must exit 0 (coverage ≥ 0.85). The closing comment must include: 1. `/tmp/bug_B_plate/side_by_side.png` 2. The numerical coverage value from `metrics.json` 3. A demonstration that a deliberately-wrong depth (e.g. forced to 0.01 × 10 = 0.1 mm) is now **rejected** by the coverage gate — show the test that asserts coverage drops below 0.95 and the gate reverts to the 10%-of-extent fallback (or whatever fallback the implementer chose). A commit that ships a coverage-metric helper but does not wire it into `derive_profile_operations` is **not** a real fix — the metric must actually be the gate. ### Why this is a strategy gap and not a function bug This bug was filed originally as pc2cad#24 bug 2 and decomposed to pc2cad#39, but the body described the symptom (depth source wrong) without naming the missing capability (no inlier-coverage metric). Closing this bug requires the metric to exist AND be the gate AND be demonstrably correct on the synthetic plate sample. ### Related - pc2cad#24 (parent), pc2cad#39 (symptom-level child) - Bug A (body+features composition) - Bug D (visual harness committed) ### How to regenerate the sample ```bash python scripts/gen_strategy_samples.py ```
Author
Owner

This bug is part of a four-bug batch on the pc2cad reconstruction
strategy gaps. They are designed to be solved together because each
one's verification gate depends on the harness from Bug D and the
synthetic samples from Bug A.

Bug Title Depends on
Bug D (#50) render-compare harness committed —
Bug A (#47) body+features composition Bug D
Bug B (#48) inlier-coverage gate Bug D
Bug C (#49) organic vs mechanical routing Bug A + Bug B

Closing this bug requires running the verification commands in its body
and attaching the resulting side-by-side PNGs to the closing comment.
Closing any of A/B/C without Bug D's harness producing falsifiable
evidence is a workaround, not a fix.

## Cross-references — related strategy bugs This bug is part of a four-bug batch on the pc2cad reconstruction strategy gaps. They are designed to be solved together because each one's verification gate depends on the harness from Bug D and the synthetic samples from Bug A. | Bug | Title | Depends on | |---|---|---| | Bug D (#50) | render-compare harness committed | — | | Bug A (#47) | body+features composition | Bug D | | Bug B (#48) | inlier-coverage gate | Bug D | | Bug C (#49) | organic vs mechanical routing | Bug A + Bug B | Closing this bug requires running the verification commands in its body and attaching the resulting side-by-side PNGs to the closing comment. Closing any of A/B/C without Bug D's harness producing falsifiable evidence is a workaround, not a fix.
Mark 2026-07-05 04:32:24 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Mark/pc2cad#48
No description provided.