SG-Lib

Milestone 2026-07-12 — SG-Lib grammar + XX: `sgtestclaude` as the reference style

Rendered views

Learning case — no printable STL for this milestone.

Type: reference/style milestone. The first sgtestclaude construction that fully follows the relational SG-Lib grammar and is enforced - rated by Tim as “the best SG-Lib code I could imagine, as if I had written it myself”.

Task

A 3x4x5 cuboid is inserted sideways (in -x) into a cylinder (dia 10, height 40) 4 mm deep with a clearance fit. The blind-pocket subtraction body is pulled in via a surface frame; clearance also in the depth.

What makes this milestone (the style is the real achievement)

  1. XX design-task header (multi-line, like a function header): first line XX SGLIB DESIGN TASK: LATERAL CLEARANCE INSERTION OF A CUBOID INTO A CYLINDER, then goal | approach | purpose.
  2. Named givens at the top; no literal dimensions in the body.
  3. Quantitative XX values via $expr$ - the caliper reference after manufacturing: geometry cylinder 10 mm dia x 40 mm high, cuboid 3 x 4 x 5 mm, insertion depth 4 mm; cuboid extent 5 mm ...; pocket depth 4.3 mm from insertion 4 mm plus clearance 0.3 mm ... cuboid protrudes 1 mm.
  4. Sizes measured (never reuse the build number): extent via crosspointVLFL (= 5.00 mm).
  5. Placement only via frame relations (alignT/matchT); the relative offset goes inside the braces ({'TU','TR', TofP([0 0 aC-dins])}), never absolute.
  6. Contour by projection with the returned frame T evaluated (VLtransT(CVL,inv(TU))), no 90-degree rotation.
  7. Real fit slfit('c') + CPLbuffer(...,'miter'); SGwarnfittinguse.
  8. One English comment per line. nmB=0.

Made enforceable

  • SGLIBgrammarcheck (new SG-Lib function): blocks HARD violations (absolute placement SGtransP/SGtransR, SGtransT without inv(frame), offset outside the alignT/matchT cell, literal dimensions); SOFT hints (missing trailing comment, slfit without SGwarnfittinguse, SGbox without 'noframe', ,/; in XX lines).
  • As a gate in the build (sgtestclaude) and in the milestone builder SGlibrunMilestone (before run(), with a report in buildinfo). This milestone’s buildinfo shows grammar: OK (0 msg, SGLIBgrammarcheck).

By-product (SG-Lib improvement)

CPLofSGprojection now projects headless and exactly via Manifold project() (CLAUDE_sg_manifold.project_vlfl) instead of the graphics board, with a graphics fallback. Apache-2.0 notice for Manifold added.

Files

  • ..._build_sgtestclaude.m - milestone build (outputs into this folder, gated by SGlibrunMilestone).
  • ..._reference_sgtestclaude.m - the exact reference sgtestclaude (working copy).
  • ..._SGLIBgrammarcheck.m - the grammar checker at the time of the milestone.
  • ..._views.png - result (3x4x5 inserted laterally with clearance).
  • ..._sgtestclaude_buildinfo.txt - provenance incl. grammar status.
  • Conversation: ..._conversation_de.md / ..._conversation_en.md.

Rules stored durably

CLAUDE_MATLAB_PROGRAMMINGSTYLE.md sec.0 (+ mirror), CLAUDE_SGLIB_LEARN.md sec.0a, CLAUDE_SGLIB_PATH2.md (checklist), CLAUDE_SGLIB_PARAMS.md (XX/$..$), CLAUDE_START.md - scope: only constructions made WITH the SG-Lib, not the development of the SG-Lib itself.

Design conversation (English)

Conversation (essence) — SG-Lib grammar + XX, 2026-07-12

Condensed record (Tim <-> Claude). Order = the flow.

  • Tim (meta): “Now it’s correct, but it took 2-3 hours. Please fix the rules and really adhere to them.” -> Claude creates a pre-flight checklist (CLAUDE_SGLIB_PATH2.md).
  • Tim (question): Is enforceable grammar the way? Should I forbid SGtransT/transp/transR? Claude: forbid SGtransP/SGtransR (absolute); SGtransT only with inv(<frame>); more precise than a ban is a linter as a gate. -> builds CLAUDE_grammarcheck (later SGLIBgrammarcheck).
  • Tim: impressed by the three lines that evaluate the returned frame T (VLtransT(CVL,inv(TU))). Use the checker always (Path 2, snippets, milestones). Note: max(dd)-min(dd) measures the outer extent - beware embedded cavities. Absolute givens as a block at the top with XX (value + prose).
  • Tim: “One English trailing comment per relational line” (dense like Lisp). -> SOFT rule in the linter.
  • XX problem/lesson: Claude guessed $cylD (single $) -> error “missing $”. Tim: “I use XX daily without problems.” -> Claude reads the source XX.m: values via $expr$ (a PAIR!), evaluated in the caller.
  • Tim: output absolute values in XX (caliper check). Numbers as numerals. XX reads the rest as MATLAB code
    • no comma/semicolon/operator/hyphen in the prose, no % (-> vH); separator |.
  • Tim: the first XX may be multi-line - a design-task header (like a function header). Fixed first line: XX SGLIB DESIGN TASK: <ONE-LINER IN CAPITALS>.
  • Tim: rename to SGLIBgrammarcheck with an SG-Lib header (“by Claude for Tim Lueth”). Hook the gate into the milestone builder SGlibrunMilestone (blocks hard, override ,false).
  • Tim: “This is a milestone.” Adapt all md files so that from now on the grammarcheck + XX are always used. Scope: applies only to constructions made WITH the SG-Lib, not to developing the SG-Lib itself (slicer etc.).
  • Result: sgtestclaude as the reference style (XX header + $..$ values + measured sizes + frame relations only + trailing comments), nmB=0; grammar enforced in the build and the milestone builder (grammar: OK). Tim: “the best SG-Lib code I could imagine, as if I had written it myself.”

Core lesson: writing rules down is not enough - they must be enforceable. And: read the correct syntax (XX.m) instead of guessing.