Skip to content

Repository files navigation

print-bench

Co-designed, review-hardened, printable: parametric 3D-printing designs written in OpenSCAD, iterated with an AI co-designer, and gated by automated printability checks before they ship.

The designs

Design
aerochord previews aerochord — A musical wind instrument that (a) prints in place as one piece with no supports, (b) does not correspond to any instrument in the historical record, and (c) is only really designable/printable with an FDM machine and a computed internal geometry. The brief was an explicit stress test of the whole co-design pipeline.
calibration-cube previews calibration-cube — Simple dimensional-accuracy test print; also serves as the repo's starter design demonstrating the parameter conventions.
desiccant-capsule previews desiccant-capsule — Refillable two-part capsule for loose silica gel beads, lived-in filament dry-boxes. Perforated body lets air/moisture reach the beads; screw-on lid with real threads (not press-fit) and a ribbed grip edge so it can be opened with dry-box gloves on. Must print on FDM with no supports on either part.
nuggs previews nuggs — An 80 mm-bore tunnel system for an adult Syrian hamster, built around one genderless quarter-turn port that every module carries at every end. The kit that exists today is the Bin Bridge: two bulkheads and one straight joining two enclosures through their walls, with nothing inside the cage.
nuggs-yard previews nuggs-yard — An open-top run for an adult Syrian hamster's playpen — free-roam time outside the cage. The ask was "loops and twists, turns, branches, all the stuff to keep him busy". It is a floor-standing kit of modules the owner lays out themselves, not a fixed object.
sushi-battleship previews sushi-battleship — Battleship played with real sushi.
sushi-battleship-tracker previews sushi-battleship-tracker — The parent tracks hits structurally (an opened door is an eaten cell) but leaves misses to memory, and "did we already call B3?" is the real failure mode of a leisurely dinner game. The refit adds a shallow spherical miss-marker seat to the top face of every print-in-place shutter door: park any small round marker (dried soybean, 6 mm airsoft BB, peppercorn) on a called cell and nobody re-calls it. The product charter lives in PM.md beside this file.
derived from sushi-battleship

Want to print one?

  1. Open the design's folder above — its README.md is the product page: what it is, print settings, and the parameters worth tuning for your printer. NOTES.md holds the engineering log and measurements.

  2. Render the STL:

    ./scripts/render.sh <name>   # produces build/<name>.stl and build/<name>.png
  3. Slice build/<name>.stl with the settings from the product page. If the design ships a <name>-coupon.scad, print that first — it's a short test print for dialing in the fit parameters before you commit to the full part.

All dimensions are in millimeters. Designs target FDM printing by default and expose printer-tuning parameters (wall thickness, fit tolerances) at the top of each file. To tune a fit without editing files:

./scripts/render.sh <name> --sweep thread_tol=0.15:0.35:0.05

renders one labeled strip of test coupons across the range instead of five sequential guess-prints.

Want it to look a certain way?

Point the toolchain at a model whose look you like and it writes down why it looks that way — the radius reused on its edges, chamfer or fillet, how smooth its curves are, what size holes it drills — as a style you can build new designs to and check them against:

./scripts/style-lift.sh <name> <reference.stl> --source <url> --license <terms>
./scripts/style-check.sh <name>        # does a part actually belong to the family?

Styles live in styles/; pick one from the catalog there and a design can include <styles/<name>/style.scad> to build from its numbers directly. See stylelift for how the measuring works, and the /style-spec skill for lifting a new one.

Want to remix one?

Keep a design's tray and put your own lid on it. In OpenSCAD that is one include of the original plus a redefinition of the parts you want different — the original's own code then calls your version — so a remix here is a design directory of its own that stays tied to what it was built from, not a copy that quietly stops tracking it.

Two things the repo adds to that. Each remix records its parents in a derives.conf, so changing an original automatically re-checks everything built on it. And every replacement it claims to make is proved against the original's own export before it can ship: OpenSCAD says nothing at all when a redefinition misses — misspell the part name and you get a flawless, watertight print of the part you were trying to replace — so the replacements are checked rather than trusted.

Start with docs/derivative-designs.md.

Dependencies

The scripts expect: openscad, xvfb-run (headless rendering — the scripts wrap every OpenSCAD call in xvfb-run -a themselves; you only need the prefix for raw openscad commands you run by hand), ImageMagick (montage, for preview sheets), prusa-slicer (for gate.sh --slice), Python bpy — Blender as an importable module, pip install 'bpy~=4.5.0' (for product-shot.sh; its wheels are built per Python minor version, so this needs Python 3.11) — printcheck (pip install -e tools/printcheck), and stylelift (pip install -e tools/stylelift, for the style scripts).

A bare python3 (3.10 or newer) is also required now, not only for those pip-installed tools: check.sh and gallery.sh both call scripts/lineage.sh, which runs lineage straight out of tools/lineage/src with no install step — deliberately, so CI can resolve the lineage graph before it has installed anything. The consequence for a local checkout is that both scripts need python3 on PATH and that directory present; gallery.sh fails loudly rather than quietly dropping the lineage from the page.

How designs get made

This repo runs a session-per-design co-design loop: a human brings the idea and the measurements, an AI session models it parametrically, previews are reviewed after every change, and reviewer personas (printability, and fitness-for-purpose) challenge the design over pull requests until it merges. The full workflow and conventions live in CLAUDE.md.

For how the system is put together — the generic CI/automation platform separated from the 3D-print design layer, written as the basis for a reusable template — see docs/architecture/.

Operating the automation

Most of this repo's CI drives itself, but a few controls are exposed to maintainers directly — no code change required. Every comment-command below is authorised by your real repository permission (write access needed).

  • Smart CI gates — when a PR touches something no gate covers yet, the smart-ci job proposes one in a sticky PR comment. Cross it by commenting on the PR:
    • /ci-gate approve <id> — wire the gate in for this and every future run
    • /ci-gate decline <id> — turn it off so it stops being proposed
    • /ci-gate list — show the current selection
  • Backlog-burn policy — change the scheduled /ship-issue routine's policy without opening a PR by commenting on any issue or PR:
    • /backlog-burn set enabled true|false
    • /backlog-burn set label <label-name>
    • /backlog-burn set provider anthropic|zai
    • /backlog-burn set cadence 4x|2x|daily|weekly|<cron>
  • Arming the unattended routines — each scheduled agent is armed by a repo variable (Settings → Secrets and variables → Actions → Variables) kept deliberately out of git, so a clone or fork can't inherit it and flipping it off halts the routine in seconds:
    • BACKLOG_BURN_ENABLED, DESIGN_RUN_ENABLED, CHUNKER_ENABLED — the three scheduled agents (backlog burn, idea→PR design run, issue chunker). Each also needs its committed enabled: true in the matching .github/*.conf; both keys must agree before it runs.
    • PRINT_FEEDBACK_ENABLED — the Log a print result form (single switch).
  • Manual workflows — several workflows are workflow_dispatch forms in the repository's Actions tab: Log a print result, Regenerate avatar, Lifestyle shot (tier-2, AI), Lifestyle clip (tier-2, AI motion), Release bundles and Backlog-burn config update. The three scheduled agents can also be dispatched there, each with a dry_run option that selects an issue but takes no action.

The design of these controls (the two-key arming, the committed-vs-live config split, the comment-command authorisation) is documented in full in CLAUDE.md; the accepted security posture toward manually dispatched, write-scoped workflows is in docs/actions-security.md.

Layout

  • designs/<name>/ — one directory per design: the parametric .scad source (entry point matches the directory name), the README.md product page, the NOTES.md engineering log, and committed previews/
  • lib/ — shared modules: printability.scad (FDM fastener/chamfer helpers), threads-fdm.scad (printable trapezoidal threads), nuggs-coupling.scad (the NUGGS genderless quarter-turn bayonet port), print-in-place.scad (print-in-place slide rails, tabs, end-stops, sacrificial membranes and a teardrop-bore hinge, extracted from the archived sushi-battleship), printer-conf.scad (the print-feedback profile a design reads to pre-fill its tuned-fit tolerances), each with a *-demo.scad regression render, plus vendored BOSL2
  • build/ — generated STL/PNG outputs (gitignored)
  • people/ — the team registry: who builds here, humans and agents alike, one profile per handle, with per-design core rosters in designs/<name>/team.conf and the interim recent-work manifest in people/work.conf; read by the product-site build, which fails on any unresolvable handle, mandate, or work reference
  • printer.conf — your printer's measured profile (inert by default); designs opt in to pre-fill tuned-fit tolerances. Part of the print-feedback loop — see docs/print-feedback.md
  • scripts/ — the toolchain:
    • render.sh — STL + 4-view preview sheet; --previews re-renders a design's frozen review shots, --sweep renders tolerance-test strips
    • check.sh — fast syntax/geometry validation of every .scad file, plus the guard-check.sh, mate-check.sh, lineage.sh and docs-check.sh checks below
    • guard-check.sh — negative tests for library guards: every case in a lib/*-guards.conf must still be refused, which a demo cannot test because a firing assert would abort the demo's own render
    • mate-check.sh — positive tests for library fits: every case in a lib/*-mates.conf must still assemble, measured as zero facets of interference on the exported mesh. A demo cannot test this either — a render cannot measure itself, and echoing the clearance formula only proves it equals itself
    • printer-conf-check.sh — proves the printer.conf mechanism reads the generic default when nothing is measured and the profile's value when one is, reaching the exported geometry (issue #101)
    • nopscadlib-check.sh — proves the vendored lib/NopSCADlib/ tree resolves through OPENSCADPATH and builds a real vitamin; no committed file includes NopSCADlib yet, so nothing else would notice if it went missing (issue #155)
    • license-boundary-check.sh — enforces the copyleft/GPL core stance (issue #160): no shared lib/*.scad may include a copyleft-vendored library and no scripts//site/ code may bundle its vendored source; design-layer opt-ins and invoking unshipped GPL tools stay allowed (see docs/licensing.md)
    • assembly.sh — generates assembly instructions (exploded view + BOM) from a per-design assembly.conf manifest, using NopSCADlib's BOM/assembly tooling; no design ships a manifest yet (issue #156, stage 2 of #98)
    • chunker-perms-check.sh — proves the chunker's deny backstop (.claude/chunker-settings.json) still neutralizes every dangerous tool allow it would otherwise inherit from .claude/settings.json, which claude-code-action loads additively via settingSources=project
    • gate.sh — render printable parts and gate the STLs with printcheck; --slice adds a PrusaSlicer test-slice (this is what CI enforces)
    • gate-summary.py — turns a gate log into the CI results table
    • ci-classify.sh — the single source of truth for which gates CI runs and over which designs; ci.yml's changes job pipes its diff to it and /preflight runs it --local, so the local mirror can't drift
    • docs-standards-check.sh — the standards gate for the architecture docs (docs/architecture/) and the How-it-works site page and its diagrams: presence/wiring only, no OpenSCAD, selected by ci-classify.sh when a change touches docs/, the page's source, this gate script, or the CI workflow (its own light docs-standards CI job, with a --selftest)
    • lineage.sh — who derives from whom: validates the derives.conf records, answers what a change has to re-gate, and re-proves the derivative gate can still fire (selftest)
    • readme-gate.sh — every design must ship a product-page README
    • animate.sh — animated GIF previews from animations.conf
    • product-shot.sh — real-world-looking studio product shots from shots.conf, path-traced from the design's own STL export
    • lifestyle-shot.sh — tier-2 AI lifestyle shots from lifestyle.conf via the Z.AI GLM-Image API (cosmetic, geometry-approximate, disclosed)
    • shot-spec.sh — authors shots.conf/lifestyle.conf from a PM's art-direction brief (named views/colors, freeze and disclosure enforced); the mechanics behind the /art-direction skill
    • lifestyle-clip.sh — tier-2 AI motion clips from motion.conf via the Z.AI Vidu 2 image-to-video API, transcoded to a budgeted GIF (cosmetic, geometry-approximate, motion illustrative, disclosed)
    • product-page.sh — drafts a design's product-page README with the Claude API when readme-gate.sh rejects the one in the tree, and reverts its own draft if the gate rejects that too
    • gallery.sh — regenerates the design gallery above
    • site.sh — builds the static product site into build/site
    • style-lift.sh — lift a design style out of a reference mesh into styles/<name>/
    • style-check.sh — gate the style packs and any design that declares one
    • lint-scad.sh — report-only sca2d static analysis
    • preview-budget.sh — sourced helper defining the GIF and product-shot size budgets
    • regen-stamp.sh — a design's regeneration input fingerprint; CI skips re-rendering previews/GIFs/product shots when it matches the committed stamp
    • field-test.sh — appends a FIELD-TEST entry (one real print's result) to a design's NOTES.md; the tested core of the "Log a print result" Action (issue #101)
    • telemetry.sh — the repo measures itself (issue #93): capture turns one gate run into one JSON record (scores, per-design gate wall time, preview budget headroom, what was skipped); report renders the committed log into telemetry/REPORT.md
    • release-bundle.sh — builds a versioned, self-describing release bundle per design (the gated STLs + a manifest.json of per-part SHA-256 checksums and the README's machine-readable print settings + a zip); the build half of the versioned-download UX (issue #102), driven by the "Release bundles" workflow
    • gh-project.sh — emits the repeatable gh recipe that provisions the autonomy roadmap board (GitHub Projects v2); the board schema is a spec at the top of the script and the board is created by running the recipe, since the automation can't create a board here (issue #148, see docs/roadmap-board.md)
  • site/ — the static product site built from the designs, styles and previews already committed here, and deployed on Vercel — see its README
  • styles/ — design languages lifted from reference models: the spec, the tokens a design builds from, and the rules CI checks parts against
  • templates/ — starting points for a new design and its product page
  • telemetry/ — the committed self-measurement log (log.ndjson, one JSON record per default-branch gate run, appended by CI) and the report generated from it (REPORT.md) — never hand-edited
  • docs/ — repo-level research and reference notes
  • tools/printcheck/ — STL printability analyzer; scores rendered models for watertightness, overhangs, thin walls, and bed adhesion before slicing — see its README
  • tools/photoshot/ — STL → Blender/Cycles studio renderer behind product-shot.sh, which turns a design's own STL export into the photographed-looking hero image on its product page — see its README
  • tools/lineage/ — the lineage resolver: reads each design's derives.conf and its include lines, and answers who derives from whom — see its README
  • tools/backlog-burn/ — the selection engine behind the scheduled backlog burn (.github/workflows/backlog-burn.yml): picks one unclaimed, autonomy-ok-labelled issue for a nightly unattended /ship-issue run — see its README
  • tools/telemetry/ — the capture/report engine behind telemetry.sh: parses a gate log into a telemetry record and renders the committed log into the report — see its README
  • tools/stylelift/ — measures how a model is shaped (edge treatment, rounding vocabulary, proportion) and turns it into a checkable style spec — see its README
  • tools/ci-gates/ — Smart CI gate selector: proposes CI gates a PR's changes call for but that don't exist yet, runs the approved ones, and comments the command to cross the rest (registry: .github/ci-gates/registry.conf) — see its README
  • audits/ — preserved before/after render comparisons from design reviews (review history — don't delete)

About

Parametric 3D-printable designs, gated before they ship.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages