Skip to content

feat(kidscleancar_knob_cover): friction-fit childproof speed-knob cover (pst-8bj) - #58

Merged
SeanOC merged 11 commits into
mainfrom
gc-pilot/pst-8bj
Jul 29, 2026
Merged

feat(kidscleancar_knob_cover): friction-fit childproof speed-knob cover (pst-8bj)#58
SeanOC merged 11 commits into
mainfrom
gc-pilot/pst-8bj

Conversation

@SeanOC

@SeanOC SeanOC commented Jul 29, 2026

Copy link
Copy Markdown
Owner

What

New original parametric model: a friction-fit childproof cover for the speed-adjust knob on a KidsCleanCar kids' ride-on (bead pst-8bj). Stops a toddler changing the speed; no vehicle modification, fully reversible.

How it works

  • Grips the lower flange only (48.1mm OD, 3.15mm grip band) via rib_count vertical crush ribs standing rib_interference past the flange edge — the short 3mm band can't hold a plain interference bore, but ribs deform predictably and survive re-fits (PETG-friendly). These are the per-printer tuning knobs.
  • Decoupling is the lock: round bore over a round flange, no anti-rotation feature, so twisting the cover just spins it — the motion never reaches the knob. Removal is a straight axial pull, with one adult pry recess at the rim (a coin/fingernail), placed in a between-rib gap so it never eats a rib.
  • Nothing else touches the vehicle: a stepped interior clears the 3 proud screw heads (annulus pocket) and floats the knob in a central cavity, untouched even when the cover is pressed and spun.

Print

Mouth-up, support-free — every interior ceiling becomes an up-facing floor, the only exterior overhang is a self-supporting 45° top chamfer. ~53mm OD × ~13mm tall, wall ~2.4mm.

Params exposed

flange_d, flange_h, knob_d, knob_h, screw_head_h, fit_clearance, knob_clear, knob_vclear, screw_clear, skirt_gap, rib_count, rib_interference, rib_width, wall, top_chamfer, pry_notch (+ width/height) — retunable for any similar ride-on knob.

Gates

  • Export watertight, single solid (CGAL).
  • check-invariants.py green — pins single-body, round OD, knob/screw clearance, rib bite past the flange edge + free-spinning bore between ribs.
  • wasm param sweep 53/53 green (light footprint, ~6s).
  • catalog / scad-params / coverage unit tests green; pre-commit gate passed.

Ships all four new-model artifacts (scad + invariants sidecar + sweep test + catalog entry) plus committed renders. Original design under models/LICENSE (CC BY-NC-SA 4.0); no QuackWorks/openGrid dependency.

🤖 Generated with Claude Code

…er (pst-8bj)

Original parametric cover that grips the KidsCleanCar ride-on's lower
speed-knob flange (48.1mm OD, 3.15mm grip band) via tunable vertical
crush ribs, deliberately decoupled from the knob so twisting the cover
never turns it. Round bore over round flange = free spin (no
anti-rotation); a straight adult pull with a between-rib pry recess
removes it. Stepped interior clears the 3 proud screw heads and floats
the knob untouched. Prints mouth-up, support-free.

Ships the four new-model artifacts: .scad + invariants sidecar (single
body, round OD, knob/screw clearance, rib bite + free-spin bore),
sweep test, catalog entry (toys), and committed renders.

Export watertight (single solid); check-invariants green; wasm sweep
53/53 green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YPcLxyLs693J2H9CYq7Wr2

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 29, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
stuff Ready Ready Preview, Comment Jul 29, 2026 6:58am

Request Review

@SeanOC

SeanOC commented Jul 29, 2026

Copy link
Copy Markdown
Owner Author

Codex gate review — changes requested

Reviewed exact head 1ee8cd184c2cd56d3e36d0e947ac7c52ed496b58. Three PR-introduced correctness defects block the gate:

  1. models/kidscleancar_knob_cover.scad:62 — the accepted knob_d=60 bound destroys the cover. At the other defaults the cavity radius is 31.25mm while the body outer radius is only 26.75mm, so shell_profile crosses outside the body. With pinned OpenSCAD 2025.06.12.ai25773, -D "knob_d=60" logs mesh is not closed and emits only six disconnected rib fragments (49.3 x 43.495 x 3.65mm, 72 triangles), which the native download renderer rejects. Smallest fix: cap the range and assert the supported radius relationship, or grow the body from max(bore_r, knob_cav_r); add a maximum-bound regression.

  2. models/kidscleancar_knob_cover.scad:71skirt_gap=4 removes all retention and also hard-errors natively. Because rib_z0=skirt_gap at lines 113-116, the ribs sit at z=4.0..4.15 while the default flange ends at z=3.15: no rib intersects the grip target. The pinned engine also logs repeated non-closed-mesh errors for this accepted value. Smallest fix: constrain or derive the gap so accepted configurations retain meaningful flange overlap and a valid lead-in, then regress the maximum bound for both engagement and render success.

  3. models/kidscleancar_knob_cover.scad:38-48 — the exported native orientation is opposite the documented support-free orientation. The profile at lines 137-146 puts the open rim at minimum Z and the closed roof at maximum Z; the final assembly at lines 193-199 never flips it. The default STL bounds are z=0.5..13.55, so a slicer using the authored frame places the mouth on the bed and must bridge the wide interior roof, exactly the orientation the source says not to use. Smallest fix: flip and translate the final assembly into the promised roof-on-bed frame and update coordinate-dependent invariant probes, or clearly surface a required 180-degree slicer rotation instead of claiming native mouth-up.

Default geometry is otherwise watertight and single-body; the artifact set, catalog entry, license, and vendored pins are correct. Full evidence is recorded on review bead pst-u2m.

…n documented print orientation (pst-8bj)

Addresses codex gate review (pst-u2m); all three findings reproduced on
the pinned engine (2025.06.12.ai25773) and fixed:

1. knob_d max 60->40 so the knob cavity always fits inside the flange
   bore (a cavity wider than the body made shell_profile self-cross ->
   non-closed mesh). Defensive clamp: knob_cav_r = min(.., bore_r-0.6).

2. skirt_gap max 4->2 so the skirt always reaches past the flange top
   (skirt_gap >= flange_h left the ribs entirely off the flange = zero
   retention). rib_leadin now clamped to the rib's straight height so a
   shallow rib can never invert the profile into a non-closed mesh.

3. Final assembly now flips ROOF-DOWN into the print frame: the exported
   STL matches the documented mouth-up/support-free orientation (dome on
   the bed at z=0, mouth up), instead of the previous mouth-on-bed export
   that would have bridged the ~48mm interior roof. Invariant probes map
   deck-frame -> print-frame accordingly.

Verified: every declared @param min/mid/max exports a closed mesh on the
pinned CGAL engine (53 one-at-a-time cases); wasm sweep 53/53 green;
check-invariants green; STL watertight single body, z=0..13.05.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YPcLxyLs693J2H9CYq7Wr2

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@SeanOC

SeanOC commented Jul 29, 2026

Copy link
Copy Markdown
Owner Author

Review fixes pushed (074a8f9)

All three findings reproduced on the pinned engine (2025.06.12.ai25773) and are fixed — no rebuttals:

  1. knob_d=60 non-closed mesh — capped knob_d max 60→40 (a knob wider than its own flange is unphysical), plus a defensive clamp knob_cav_r = min(knob_d/2 + knob_clear, bore_r - 0.6) so the inner contour can never cross the outer wall for odd combos.
  2. skirt_gap=4 no retention + hard error — capped skirt_gap max 4→2 so the skirt always reaches past the flange top (flange_h) with meaningful rib overlap, and clamped rib_leadin to the rib's straight height so a shallow rib can't invert the profile into a non-closed mesh.
  3. Export orientation opposite the doc — the final assembly now flips roof-down into the print frame, so the exported STL matches the documented mouth-up/support-free orientation (dome on the bed at z=0, mouth up at z=13.05) instead of mouth-on-bed. Invariant probes map deck-frame → print-frame accordingly; renders regenerated.

Verification: every declared @param min/mid/max now exports a closed mesh on the pinned CGAL engine (53 one-at-a-time cases, all ok) — this was the gap the wasm sweep missed. wasm sweep still 53/53 green; check-invariants green; STL watertight single body.

@SeanOC

SeanOC commented Jul 29, 2026

Copy link
Copy Markdown
Owner Author

Codex gate review — changes requested

Reviewed exact assigned head 074a8f94e3eb952a82e604e016a499cd87b69315 (the later d84a654 commit changes thumbnails only). Three PR-introduced defects block the gate:

  1. models/kidscleancar_knob_cover.scad:63,113-117,152-161 — the accepted flange minimum makes the cover collide with the knob. With only flange_d=30, the clamp sets knob_cav_r=14.7mm, below the 14.75mm knob radius and far below the requested 16.0mm radius including knob_clear. Pinned-engine containment probes confirm solid cover material inside the upper knob envelope, so the cover can key to the knob while the mesh sweep remains green. Smallest fix: preserve knob_d/2 + knob_clear by growing the body from the larger required radius, or constrain correlated ranges; regress flange_d=min with an upper-envelope clearance probe.

  2. models/kidscleancar_knob_cover.scad:64,78-82,128-131 — an accepted combination has zero grip-band engagement. At flange_h=1.5, skirt_gap=2, the flange ends at deck z=1.5 while the ribs begin at z=2.0, leaving a 0.5mm axial gap. The STL is still watertight, but the childproof cover has no nominal retention. Smallest fix: derive the skirt/rib start from flange_h with a positive minimum overlap, or cap skirt_gap to at most 1.0mm for the advertised flange minimum; add an engagement regression.

  3. models/kidscleancar_knob_cover.scad:71,77,121-126,152-161 — the screw pocket can overrun the exterior roof and destroy export. top_z ignores annulus_roof_z; screw_head_h=8 alone leaves only 0.4mm roof despite wall=2.4, and screw_head_h=8, screw_clear=6 puts the inner annulus roof at 17.15mm above the 13.55mm exterior. Pinned OpenSCAD logs The given mesh is not closed and emits only 72 triangles in six disconnected rib fragments. Smallest fix: derive top_z = max(knob_roof_z, annulus_roof_z) + wall (and update the invariant transform), or constrain the relationship; regress the max height/clearance pair.

Default geometry is otherwise correctly oriented, watertight, single-body, invariant-clean, and correctly licensed. Full evidence is recorded on review bead pst-xnu.

@SeanOC

SeanOC commented Jul 29, 2026

Copy link
Copy Markdown
Owner Author

Codex gate review — changes requested

Reviewed exact head d84a654940ccedb27d924b7dda15e1c4c453d6ec. Three PR-introduced correctness defects block the gate:

  1. models/kidscleancar_knob_cover.scad:63,113-117flange_d=30 makes the cover contact the knob. The clamp reduces the cavity to 14.7mm radius, below the 14.75mm knob and far below the requested 16.0mm cleared envelope. Pinned-engine probes confirm solid material in the upper knob envelope, so the cover can couple to the knob while remaining watertight. The sidecar probe at models/kidscleancar_knob_cover.invariants.py:77-89 samples only lower mid-height and misses it. Smallest fix: size the shell so the cavity never falls below knob_d/2 + knob_clear, or reject incompatible values; add an upper-envelope regression at the flange minimum.

  2. models/kidscleancar_knob_cover.scad:64,78-82,128-131 — accepted values can remove all retention. At flange_h=1.5, skirt_gap=2, the flange ends at z=1.5mm but the ribs start at z=2.0mm. The STL is valid, yet there is zero grip-band overlap and the childproof cover cannot retain. Smallest fix: enforce positive overlap for all accepted values, such as capping skirt_gap at 1.0mm for the current flange minimum or rejecting the relation; regress the boundary combination.

  3. models/kidscleancar_knob_cover.scad:71,77,121-126,152-161 — the screw pocket can overrun the roof. top_z ignores annulus_roof_z; screw_head_h=8 alone leaves only 0.4mm roof despite wall=2.4, and screw_head_h=8, screw_clear=6 places the inner roof at 17.15mm above the 13.55mm exterior. The exact-head export on pinned OpenSCAD/Manifold is non-watertight with five components. Smallest fix: use top_z = max(knob_roof_z, annulus_roof_z) + wall, update the transform in models/kidscleancar_knob_cover.invariants.py:43-49, and add a max-pair native export regression.

Default geometry is otherwise correctly oriented, watertight, single-body, correctly licensed, and registered in the catalog/sweep. Full evidence is recorded on bead pst-bu9.

…truction (pst-8bj)

Addresses codex gate review round 2 (pst-bu9); all three findings
reproduced on the pinned engine (2025.06.12.ai25773) and fixed by
derivation so no accepted parameter combination misbehaves:

1. Knob contact at flange_d=min: the previous defensive clamp shrank the
   cavity BELOW the knob (14.7 < 14.75mm at flange_d=30), letting the
   cover key to the knob. Now knob_cav_r = knob_d/2 + knob_clear ALWAYS
   (never shrinks) and the bore/body GROWS to hold it:
   bore_r = max(flange_r + fit_clearance, knob_cav_r + annulus_min).

2. Zero retention at flange_h=min + skirt_gap=max: ribs started above the
   flange (z 2.0 vs flange top 1.5). Skirt bottom is now derived —
   skirt_z0 = max(0, min(skirt_gap, flange_h - engage_min)), engage_min
   1.5 > the rib lead-in — so a full-depth rib band always bites the
   flange. rib_z0 and the skirt/pry geometry use skirt_z0.

3. Screw pocket punching the roof at large screw_head_h/screw_clear:
   top_z ignored the annulus roof. Now top_z = max(knob_roof_z,
   annulus_roof_z) + wall, so the roof always caps the higher pocket with
   a full wall (the cover just gets taller). Invariant transform updated
   to match; knob-cavity probe extended to the upper knob envelope.

Default geometry byte-identical (bbox 53.5x53.5x13.05, watertight, single
body, invariants green, renders unchanged). Verified: all 51 one-at-a-time
extremes AND the flagged combinations (screw_head_h=8+screw_clear=6,
flange_d=30, flange_h=1.5+skirt_gap=2, knob_d=40+flange_d=40) export CLOSED
on the pinned CGAL engine; flange_d=30 knob envelope now clear; flange_h=1.5
+skirt_gap=2 ribs engaged. wasm sweep 53/53 green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YPcLxyLs693J2H9CYq7Wr2

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@SeanOC

SeanOC commented Jul 29, 2026

Copy link
Copy Markdown
Owner Author

Review round 2 fixes pushed (14d3ab6)

All three findings (pst-bu9) reproduced on the pinned engine and are fixed by derivation — no accepted parameter combination misbehaves now, and the default geometry is byte-identical:

  1. Knob contact at flange_d=30 — my earlier defensive clamp was the cause (it shrank the cavity to 14.7mm, below the 14.75mm knob). Removed it: knob_cav_r = knob_d/2 + knob_clear always (never shrinks), and the bore/body grows to hold it — bore_r = max(flange_r + fit_clearance, knob_cav_r + annulus_min). At flange_d=30 the knob envelope now probes fully clear.
  2. Zero retention at flange_h=1.5, skirt_gap=2 — skirt bottom is now derived: skirt_z0 = max(0, min(skirt_gap, flange_h - engage_min)) with engage_min=1.5 (> the rib lead-in), so a full-depth rib band always bites the flange. Verified engaged at that combo.
  3. Screw pocket punching the roof at screw_head_h=8, screw_clear=6top_z now = max(knob_roof_z, annulus_roof_z) + wall, so the roof always caps the higher interior pocket with a full wall (the cover just gets taller). Invariant top_z transform updated; knob-cavity probe extended to the upper knob envelope.

Verification: all 51 one-at-a-time extremes and the flagged combinations (screw_head_h=8+screw_clear=6, flange_d=30, flange_h=1.5+skirt_gap=2, knob_d=40+flange_d=40) export CLOSED on the pinned CGAL engine; wasm sweep 53/53; check-invariants green; default STL watertight single-body, bbox unchanged 53.5×53.5×13.05.

SeanOC and others added 2 commits July 28, 2026 22:32
…truction (pst-8bj)

Per mayor steering — stop point-fixing individual reviewer combos and
close the whole class. The domain is now valid by construction:

- Single-param bounds tightened so EVERY min/max excursion from the
  measured defaults renders valid geometry on its own: flange_d min
  30->34 (smallest flange still fits the default knob's cleared cavity +
  screw annulus), knob_d max 40->44 (cleared cavity stays inside the
  default flange bore), skirt_gap max 2->1 (>=2mm rib/flange overlap at
  the default flange_h).
- Cross-parameter preconditions that no single bound can express now
  fail LOUDLY via assert() with a fix-hint message instead of emitting
  broken or silently-wrong geometry: (1) cleared knob cavity + annulus
  must fit the flange bore, (2) the skirt must reach >=1mm past the
  flange top, (3) the rib must have positive height.
- Reverted the round-2 body-growth hack: the cover OD tracks the flange
  again (bore_r = flange_r + fit_clearance); the cavity is never shrunk
  (always clears the knob) and never overruns the bore (the assert
  guarantees it). Kept the derived skirt_z0 (guarantees flange overlap
  at small flange_h) and top_z = max(knob_roof_z, annulus_roof_z) + wall
  (roof always caps the higher interior pocket).

Measured defaults untouched: STL byte-identical (bbox 53.5x53.5x13.05,
roof-on-bed z=0..13.05 support-free orientation, watertight single body,
invariants green). Verified: all 51 single-param min/max excursions build
valid with no assert; genuinely-incompatible combos (e.g. flange_d=34 +
knob_d=44) assert loudly with rc=1; wasm sweep green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YPcLxyLs693J2H9CYq7Wr2

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@SeanOC

SeanOC commented Jul 29, 2026

Copy link
Copy Markdown
Owner Author

Domain made sound by construction (8654605) — per mayor steering

Stopped point-fixing individual combos; closed the whole class instead. The parameter domain is now valid by construction:

1. Single-param bounds tightened so every min/max excursion from the measured defaults renders valid geometry on its own:

  • flange_d min 30→34 (smallest flange still fits the default knob's cleared cavity + screw annulus)
  • knob_d max 40→44 (cleared cavity stays inside the default flange bore)
  • skirt_gap max 2→1 (≥2mm rib/flange overlap at the default flange_h)

2. Cross-param preconditions that no single bound can express now assert() loudly with a fix-hint message (no silent broken/wrong geometry):

  • cleared knob cavity + annulus must fit the flange bore
  • skirt must reach ≥1mm past the flange top
  • rib must have positive height

3. Reverted the round-2 body-growth hack — the cover OD tracks the flange again (bore_r = flange_r + fit_clearance); the cavity is never shrunk (always clears the knob) and never overruns the bore (the assert guarantees it). Kept the derived skirt_z0 and top_z = max(knob_roof_z, annulus_roof_z) + wall.

Orientation (finding 3): still fully addressed — the exported STL is roof-on-bed (z=0..13.05), the documented mouth-up support-free frame.

Verification: measured defaults byte-identical (bbox 53.5×53.5×13.05, watertight single body, invariants green). All 51 single-param excursions build valid with no assert; genuinely-incompatible combos (e.g. flange_d=34 + knob_d=44) assert with rc=1 and a clear message; wasm sweep green.

@SeanOC

SeanOC commented Jul 29, 2026

Copy link
Copy Markdown
Owner Author

Codex gate review — changes requested

Reviewed exact assigned head 14d3ab6a7a6767124660f777eacc2c9fd6e5e0fc. The live PR has since advanced to 8654605d7ef7048124d1d073cf89ac77b5ab496e; this verdict and status apply only to the assigned SHA.

Two PR-introduced correctness defects block the gate:

  1. models/kidscleancar_knob_cover.scad:64,74,86,135-143,187-198 — accepted values can leave the cover with no retention. With flange_h=1.5, fit_clearance=1.5, and rib_interference=0.8, rib_leadin is 2.2mm across only 1.5mm of flange overlap. At the flange top the ramp is still at radius 24.0773mm, outside the 24.05mm flange; pinned-engine containment probes found no rib material inside the flange radius anywhere in the grip band. The STL remains watertight and single-body, so CI misses the functional failure. Smallest fix: reject combinations without a positive full-depth grip band, or clamp/derive rib_leadin to leave one; regress this exact combination with a bite probe.

  2. models/kidscleancar_knob_cover.scad:63,85,95-96,150-152,218-223 — the pry notch can sever ribs and emit orphan bodies. With flange_d=30, rib_count=12, pry_notch_w=24, and pry_notch_h=8, pinned OpenSCAD exits 0 but the STL has three components: the 1,998-triangle cover plus detached 14- and 12-triangle rib fragments. The accepted wide notch no longer fits between the adjacent ribs. Smallest fix: derive or reject notch dimensions against actual between-rib clearance so neither neighboring root can be cut; regress this exact combination expecting one connected body.

Default geometry is otherwise watertight, one body, correctly oriented, correctly licensed, and fully registered. Full evidence is recorded on bead pst-20w.

@SeanOC

SeanOC commented Jul 29, 2026

Copy link
Copy Markdown
Owner Author

Codex gate review — changes requested

Reviewed exact head 8654605d7ef7048124d1d073cf89ac77b5ab496e. Three PR-introduced cross-parameter defects block the gate:

  1. models/kidscleancar_knob_cover.scad:73,91-92,125-133,186-195 — accepted chamfer/roof values self-cross the shell and collapse export. With screw_head_h=8, top_chamfer=3, and wall=1.2, annulus_roof_z=13.15 but the chamfered exterior is only r=23.75 there while the inner contour is bore_r=24.35. Pinned OpenSCAD 2025.06.12.ai25773 logs ERROR: The given mesh is not closed! and emits only 72 triangles in six detached rib fragments. The same class occurs with knob_h=2 or screw_clear=6 alongside the thin-wall/max-chamfer pair. Smallest fix: add a cross-parameter guard ensuring the exterior radius at each inner roof stays strictly outside that inner radius (especially outer_at(annulus_roof_z) > bore_r), or reshape/clamp the chamfer; regress this exact triple natively.

  2. models/kidscleancar_knob_cover.scad:67,76,87,135-148,204-216 — an accepted combination has zero flange bite. At flange_h=1.5, fit_clearance=1.5, rib_interference=0.8, the 2.2mm lead-in is still outside the flange radius when the 1.5mm grip band ends. Exact-head containment testing found zero rib material inside the flange across 5,625 samples of the whole band, even though the STL is watertight and one body. The cover therefore has no nominal retention. Smallest fix: clamp/derive rib_leadin from flange_h-rib_z0 so a positive full-depth bite band remains, or assert the incompatible relation; regress this combination with a bite probe.

  3. models/kidscleancar_knob_cover.scad:66,86,96-97,150-152,229-240 — the accepted wide-notch corner still severs ribs. flange_d=34, rib_count=12, pry_notch_w=24, pry_notch_h=8 exports three components: the 1,990-triangle cover plus two detached 8-triangle rib scraps. This violates the single-body contract and the claim that the recess never eats a rib. Smallest fix: derive/assert notch dimensions against actual between-rib/root clearance (or reshape the cut) and regress this exact combination for one connected component.

The default model is otherwise watertight, one body, correctly oriented, correctly licensed, and fully registered. Full evidence is recorded on review bead pst-oi4.

…easured knob class (pst-8bj)

Per mayor decision after 6 review rounds: converge by SHRINKING scope, not
hardening wider. This model childproofs one knob class; it doesn't need to
render a 30mm flange or a 1.5mm grip band.

- Narrowed every @param to a tight envelope around the measured device:
  flange_d 44-52, flange_h 2.5-4, knob_d 26-33, knob_h 4-8,
  screw_head_h 0-4, fit_clearance 0.2-0.6, knob_clear 0.8-2.5,
  knob_vclear 1-3, screw_clear 1-3.5, rib_count 4-8,
  rib_interference 0.1-0.5, rib_width 1-2.5, wall 2-3.5, top_chamfer 0-2,
  pry_notch_w 8-16, pry_notch_h 2-5, skirt_gap 0-1. Defaults unchanged.
- Kept the derivations that make each corner valid: top_chamfer_eff clamped
  to wall (no roof self-cross), rib_leadin clamped so a full-depth grip_band
  survives, top_z = max(knob_roof_z, annulus_roof_z) + wall, pry width
  clamped to the between-rib gap.
- Explicit domain asserts (fail loudly with fix hints) for the combos the
  ranges still can't exclude: knob cavity + annulus must fit the bore;
  grip_band >= 1.5mm (holds at flange_h-min + fit-max + rib_interference-max);
  chamfered exterior stays outside the bore at the annulus roof; rib height.

Verified on the pinned native OpenSCAD (2025.06.12.ai25773): FULL corner
matrix of 8105 cases — exhaustive 2^12 over the interacting params + 4000
random full-parameter corners + all 9 reviewer-cited combos — every case is
either a valid export (closed mesh, single watertight body) or a loud assert.
8102 valid, 3 asserted (the incompatible knob-vs-flange combos), ZERO defects.
Defaults byte-identical (53.5x53.5x13.05, roof-on-bed, watertight, invariants
green); wasm sweep green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YPcLxyLs693J2H9CYq7Wr2

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@SeanOC

SeanOC commented Jul 29, 2026

Copy link
Copy Markdown
Owner Author

Converged — domain narrowed to the measured knob class (9c9de82)

Per the mayor decision after 6 rounds: converge by shrinking scope, not hardening wider. This cover childproofs one knob class; it doesn't need to render a 30mm flange or a 1.5mm grip band.

Narrowed every @param to a tight envelope around the measured device (defaults unchanged):
flange_d 44–52, flange_h 2.5–4, knob_d 26–33, knob_h 4–8, screw_head_h 0–4, fit_clearance 0.2–0.6, knob_clear 0.8–2.5, knob_vclear 1–3, screw_clear 1–3.5, rib_count 4–8, rib_interference 0.1–0.5, rib_width 1–2.5, wall 2–3.5, top_chamfer 0–2, pry_notch_w 8–16, pry_notch_h 2–5, skirt_gap 0–1.

Kept the derivations that make each corner valid (chamfer clamped to wall; rib lead-in clamped so a full-depth grip band survives; top_z = max(knob_roof_z, annulus_roof_z) + wall; pry width clamped to the between-rib gap) and the explicit domain asserts with fix-hint messages for what the ranges still can't exclude — including the two you called out: thin-wall + max-chamfer roof self-cross, and flange_h-min + fit_clearance-max + rib_interference-max must leave ≥1.5mm rib/flange overlap (asserted explicitly).

Full corner matrix run locally on the pinned native OpenSCAD (2025.06.12.ai25773) before pushing8105 cases: exhaustive 2¹² over the interacting params + 4000 random full-parameter corners + all 9 reviewer-cited combos. Every case is either a valid export (closed mesh, single watertight body) or a loud assert: 8102 valid, 3 asserted (the incompatible knob-vs-flange combos), ZERO defects.

Defaults byte-identical (53.5×53.5×13.05, roof-on-bed support-free orientation, watertight single body, invariants green); wasm sweep green.

@SeanOC

SeanOC commented Jul 29, 2026

Copy link
Copy Markdown
Owner Author

Codex gate review — changes requested

Reviewed exact head 9c9de8283c048ce916ed75e18fa9cfa9a0ecfaaa. One PR-introduced functional geometry defect blocks the gate:

  1. models/kidscleancar_knob_cover.scad:145-157 — an accepted corner eliminates the insertion lead-in. With flange_h=2.5 and skirt_gap=1 (both declared bounds; all other values default), the last bound in rib_leadin is 2.5 - 1 - 1.5 = 0, so the ramp collapses to zero. The full rib tip begins directly on the mouth plane at radius 23.85mm, already 0.2mm inside the 24.05mm flange radius. Pinned-engine containment confirms solid rib material inside the flange envelope immediately at the mouth. The STL is still watertight and one component, so the sweep and topology checks remain green even though the flange meets a square full-interference shoulder that can snag or buckle instead of self-centering and seating. Smallest honest fix: constrain or reject the relation so every accepted combination preserves a useful positive lead-in while retaining the 1.5mm full-depth grip band (for example, guard a minimum lead-in tied to rib_interference and tighten skirt_gap accordingly), then regress flange_h=min, skirt_gap=max for nonzero lead-in plus a valid one-body export.

Default geometry and the focused prior-failure corners are otherwise watertight, single-body, correctly oriented, correctly licensed, and fully registered. Full evidence is recorded on review bead pst-yc4.

…ry corner (pst-8bj)

Addresses codex review pst-yc4: at flange_h=2.5 + skirt_gap=1 the previous
grip-band clamp consumed the whole lead-in (rib_leadin -> 0), leaving a
square full-interference shoulder at the mouth that snags instead of self-
centering.

The rib now must present BOTH a positive insertion ramp AND the full crush
band. The skirt bottom is derived to reserve room for both:
  rib_leadin_min = max(0.4, rib_interference)   (deeper rib -> longer ramp)
  engage_min     = rib_bite(1.5) + rib_leadin_min
  skirt_z0       = clamp(skirt_gap, flange_h - engage_min)
so every accepted corner keeps rib_leadin >= rib_leadin_min AND
grip_band >= 1.5mm. New assert makes a collapsed lead-in fail loudly.

Default unchanged (skirt_z0 still 0.5, rib_leadin still 0.8 -> byte-identical
STL, 53.5x53.5x13.05, watertight, invariants green). Re-verified the FULL
corner matrix on pinned native OpenSCAD (2025.06.12.ai25773): 8105 cases
(exhaustive 2^12 + 4000 random full-parameter corners + 9 reviewer combos) —
8100 valid, 5 asserted, ZERO defects. flange_h=min + skirt_gap=max now exports
one watertight body with a nonzero lead-in ramp and >=1.5mm bite. wasm sweep green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YPcLxyLs693J2H9CYq7Wr2

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@SeanOC

SeanOC commented Jul 29, 2026

Copy link
Copy Markdown
Owner Author

Lead-in guaranteed at every corner (e4aad97)

Fixes the pst-yc4 finding: at flange_h=2.5 + skirt_gap=1 the grip-band clamp had consumed the whole lead-in (rib_leadin → 0), leaving a square full-interference shoulder that snags instead of self-centering.

The rib now reserves room for both a positive insertion ramp and the full crush band:

rib_leadin_min = max(0.4, rib_interference)   // deeper rib → longer ramp
engage_min     = rib_bite(1.5) + rib_leadin_min
skirt_z0       = clamp(skirt_gap, flange_h - engage_min)

so every accepted corner keeps rib_leadin ≥ rib_leadin_min and grip_band ≥ 1.5mm. A new assert makes a collapsed lead-in fail loudly.

Verification: default byte-identical (skirt_z0 still 0.5, rib_leadin still 0.8 → same STL, 53.5×53.5×13.05, watertight, invariants green). Containment probes confirm flange_h=2.5, skirt_gap=1 (interference 0.2 and 0.5) now has an empty ramp region at the mouth plus full-depth bite above it. Re-ran the full corner matrix on pinned native OpenSCAD — 8105 cases (exhaustive 2¹² + 4000 random full-parameter corners + 9 reviewer combos): 8100 valid, 5 asserted, ZERO defects. flange_h=min + skirt_gap=max exports one watertight body with a nonzero lead-in and ≥1.5mm bite. wasm sweep green.

@SeanOC

SeanOC commented Jul 29, 2026

Copy link
Copy Markdown
Owner Author

Codex gate review — changes requested

Reviewed exact head e4aad978c2cac3559c8fbfc8cb97a202ec735c70. One PR-introduced functional-clearance defect blocks the gate:

  1. models/kidscleancar_knob_cover.scad:150-159 (especially line 155) — the ribs intrude into the promised screw-head pocket. rib_top_z = flange_h + 1 leaves each full-depth rib solid for 1mm above the flange. At defaults the nominal screw annulus is r=16.0..24.35mm above z=3.15mm, yet the ribs occupy r=23.85..24.65mm through z=4.15mm; pinned-engine containment confirms solid material at r=23.95, z=3.65 on every rib azimuth. Because the source measurements do not constrain screw radial position or head diameter, a stock head reaching that outer annulus can stop full seating or catch a cover intended to spin freely. The sidecar at models/kidscleancar_knob_cover.invariants.py:101-107 probes only the annulus midpoint and misses this intrusion. Smallest honest fix: end the inward rib at flange_h (or taper it back to the bore by that height) and regress the outer annulus at rib azimuths just above the flange. I verified the one-line rib_top_z=flange_h boundary remains watertight and single-body and clears the failing probes.

The focused accepted-corner native exports, default topology, print orientation, catalog/artifact set, license, vendored pins, and reported CI checks are otherwise clean. Full evidence is on review bead pst-s4l.

…f the screw annulus (pst-8bj)

Addresses codex review pst-s4l: rib_top_z = flange_h + 1 left each rib solid
for 1mm above the flange, intruding into the screw-head annulus (solid at
r=23.95, z=3.65 on every rib azimuth). A stock screw head reaching that outer
annulus could stop full seating or catch the free-spinning cover.

Fix: rib_top_z = flange_h — the rib grips only the flange edge and never rises
into the annulus. Grip is unchanged (grip_band was already measured only up to
flange_h; the removed 1mm sat above the flange and gripped nothing). Sidecar
gains an above-flange annulus probe at rib azimuths (was only sampling the
annulus midpoint).

Verified: rib now clears r=23.95,z=3.65 on all azimuths while the flange-band
bite (z=2.075) stays solid; STL watertight, single body, bbox unchanged
53.5x53.5x13.05, invariants green (incl. the new probe). Full corner matrix on
pinned native OpenSCAD: 8105 cases, 8100 valid + 5 asserted, ZERO defects;
wasm sweep green. Renders updated (ribs 1mm shorter; internal, bbox unchanged).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YPcLxyLs693J2H9CYq7Wr2

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@SeanOC

SeanOC commented Jul 29, 2026

Copy link
Copy Markdown
Owner Author

Ribs ended at the flange top (bcd15c8)

Fixes pst-s4l: rib_top_z = flange_h + 1 left each rib solid for 1mm above the flange, intruding into the screw-head annulus (solid at r=23.95, z=3.65 on every rib azimuth) where a stock head could stop seating or catch the free-spinning cover.

Fix: rib_top_z = flange_h — the rib grips only the flange edge and never rises into the annulus. Grip is unchanged: grip_band was already measured only up to flange_h; the removed 1mm sat above the flange and gripped nothing. The sidecar now also probes the above-flange annulus at rib azimuths (it previously sampled only the annulus midpoint and missed this).

Verified: the rib now clears r=23.95, z=3.65 on all azimuths while the flange-band bite (z=2.075) stays solid; STL watertight, single body, bbox unchanged 53.5×53.5×13.05, invariants green (incl. the new probe). Full corner matrix on pinned native OpenSCAD: 8105 cases → 8100 valid, 5 asserted, ZERO defects; wasm sweep green. Renders updated (ribs 1mm shorter; internal, bbox unchanged).

@SeanOC

SeanOC commented Jul 29, 2026

Copy link
Copy Markdown
Owner Author

Codex gate review — pass

Reviewed exact head 6bf51d9e05ee7707fefea401109567879c78a415. No PR-introduced blocking defects found.

Verified the exact-SHA default export and invariant sidecar on pinned OpenSCAD 2025.06.12.ai25773, plus two high-risk combined parameter corners. All native exports were watertight single bodies; containment probes confirmed flange bite, between-rib free spin, and screw-annulus clearance above the flange. The source, catalog/sweep registration, tracked renders, orientation, and CC BY-NC-SA model licensing are consistent, and all reported CI checks are green.

Gate verdict: pass.

@SeanOC
SeanOC merged commit 30bb60f into main Jul 29, 2026
9 checks passed
@SeanOC
SeanOC deleted the gc-pilot/pst-8bj branch July 29, 2026 07:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant