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.
| Design | |
|---|---|
![]() |
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 — Simple dimensional-accuracy test print; also serves as the repo's starter design demonstrating the parameter conventions. |
![]() |
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 — 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 — 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 — Battleship played with real sushi. |
| ↳ 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 |
-
Open the design's folder above — its
README.mdis the product page: what it is, print settings, and the parameters worth tuning for your printer.NOTES.mdholds the engineering log and measurements. -
Render the STL:
./scripts/render.sh <name> # produces build/<name>.stl and build/<name>.png
-
Slice
build/<name>.stlwith 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.05renders one labeled strip of test coupons across the range instead of five sequential guess-prints.
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.
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.
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.
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/.
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-cijob 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-issueroutine'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 committedenabled: truein 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_dispatchforms 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 adry_runoption 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.
designs/<name>/— one directory per design: the parametric.scadsource (entry point matches the directory name), theREADME.mdproduct page, theNOTES.mdengineering log, and committedpreviews/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.scadregression render, plus vendored BOSL2build/— 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 indesigns/<name>/team.confand the interim recent-work manifest inpeople/work.conf; read by the product-site build, which fails on any unresolvable handle, mandate, or work referenceprinter.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.mdscripts/— the toolchain:render.sh— STL + 4-view preview sheet;--previewsre-renders a design's frozen review shots,--sweeprenders tolerance-test stripscheck.sh— fast syntax/geometry validation of every.scadfile, plus theguard-check.sh,mate-check.sh,lineage.shanddocs-check.shchecks belowguard-check.sh— negative tests for library guards: every case in alib/*-guards.confmust still be refused, which a demo cannot test because a firing assert would abort the demo's own rendermate-check.sh— positive tests for library fits: every case in alib/*-mates.confmust 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 itselfprinter-conf-check.sh— proves theprinter.confmechanism 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 vendoredlib/NopSCADlib/tree resolves throughOPENSCADPATHand 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 sharedlib/*.scadmayincludea copyleft-vendored library and noscripts//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-designassembly.confmanifest, 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 viasettingSources=projectgate.sh— render printable parts and gate the STLs with printcheck;--sliceadds a PrusaSlicer test-slice (this is what CI enforces)gate-summary.py— turns a gate log into the CI results tableci-classify.sh— the single source of truth for which gates CI runs and over which designs;ci.yml'schangesjob pipes its diff to it and/preflightruns it--local, so the local mirror can't driftdocs-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 byci-classify.shwhen a change touchesdocs/, the page's source, this gate script, or the CI workflow (its own lightdocs-standardsCI job, with a--selftest)lineage.sh— who derives from whom: validates thederives.confrecords, 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 READMEanimate.sh— animated GIF previews fromanimations.confproduct-shot.sh— real-world-looking studio product shots fromshots.conf, path-traced from the design's own STL exportlifestyle-shot.sh— tier-2 AI lifestyle shots fromlifestyle.confvia the Z.AI GLM-Image API (cosmetic, geometry-approximate, disclosed)shot-spec.sh— authorsshots.conf/lifestyle.conffrom a PM's art-direction brief (named views/colors, freeze and disclosure enforced); the mechanics behind the/art-directionskilllifestyle-clip.sh— tier-2 AI motion clips frommotion.confvia 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 whenreadme-gate.shrejects the one in the tree, and reverts its own draft if the gate rejects that toogallery.sh— regenerates the design gallery abovesite.sh— builds the static product site intobuild/sitestyle-lift.sh— lift a design style out of a reference mesh intostyles/<name>/style-check.sh— gate the style packs and any design that declares onelint-scad.sh— report-only sca2d static analysispreview-budget.sh— sourced helper defining the GIF and product-shot size budgetsregen-stamp.sh— a design's regeneration input fingerprint; CI skips re-rendering previews/GIFs/product shots when it matches the committed stampfield-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):captureturns one gate run into one JSON record (scores, per-design gate wall time, preview budget headroom, what was skipped);reportrenders the committed log intotelemetry/REPORT.mdrelease-bundle.sh— builds a versioned, self-describing release bundle per design (the gated STLs + amanifest.jsonof 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" workflowgh-project.sh— emits the repeatableghrecipe 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 READMEstyles/— design languages lifted from reference models: the spec, the tokens a design builds from, and the rules CI checks parts againsttemplates/— starting points for a new design and its product pagetelemetry/— 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-editeddocs/— repo-level research and reference notestools/printcheck/— STL printability analyzer; scores rendered models for watertightness, overhangs, thin walls, and bed adhesion before slicing — see its READMEtools/photoshot/— STL → Blender/Cycles studio renderer behindproduct-shot.sh, which turns a design's own STL export into the photographed-looking hero image on its product page — see its READMEtools/lineage/— the lineage resolver: reads each design'sderives.confand its include lines, and answers who derives from whom — see its READMEtools/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-issuerun — see its READMEtools/telemetry/— the capture/report engine behindtelemetry.sh: parses a gate log into a telemetry record and renders the committed log into the report — see its READMEtools/stylelift/— measures how a model is shaped (edge treatment, rounding vocabulary, proportion) and turns it into a checkable style spec — see its READMEtools/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 READMEaudits/— preserved before/after render comparisons from design reviews (review history — don't delete)





