STL geometry analysis
When a part is uploaded, the mesh is analyzed for objective facts — bounding box, volume, overhang fraction, watertightness — so advice is grounded in the real geometry, not a fuzzy text description. A tall thin part and a flat wide one get different orientation and support strategy because the numbers differ, not because the model imagined they might.
Local-embedding RAG
A curated corpus of engineering principles is embedded locally with a sentence-transformers model and retrieved by intent — so the model's reasoning is grounded in vetted knowledge instead of forum myths. Running embeddings locally rather than through a hosted API is a deliberate choice: retrieval adds no second model dependency, no extra cost, and no extra latency — the only API call in the loop is to Claude.
Tested & evaluated
130 tests passing: the STL geometry analyzer and the deterministic feasibility gate pinned against the real fact tables, plus a retrieval eval harness that asserts plain-English goals surface the principles they must ("phone case that needs to flex" → use-TPU). The eval caught a missing corpus doc during development and now prevents that class of regression. Retrieval relevance is held to an eval, not to vibes.
GitHub Actions runs the whole suite on the same Python version the container uses, and a skipped test fails the build — the retrieval tests download an embedding checkpoint, and a runner that quietly skipped them would show a green tick over the half most likely to catch a real regression. The demo's spend limits are held to the same standard: each one was verified by breaking it deliberately and confirming a test caught it, because a limit that no test would miss is not a limit anyone should trust.
Hybrid retrieval
Plain semantic search over "goal + material + printer" let the material words drown out the intent — a strength request once surfaced material-selection docs instead of the walls-before-infill principle. So retrieval pins the canonical principle for each stated optimization axis via metadata-filtered search, then fills the remaining slots with use-case reality-checks. The principle the user's goal depends on is always present, not left to chance.
Facts vs. reasoning
Two kinds of knowledge live in two kinds of places. Facts — printer specs, material temperatures — are structured, sourced JSON read through typed repositories: diffable, version-controlled, never invented. Reasoning — why walls beat infill, why PLA dies in a hot car — is curated Markdown compiled into a vector store. Eleven printers across four reasoning archetypes; any unlisted machine maps to its closest archetype and still gets sane advice. Fourteen materials with sourced properties.
The coach
Claude assembles the facts, the feasibility verdict, the geometry, and the retrieved principles into a structured settings table. Repeatability comes from the context being identical every time, not from the sampler — the current model rejects a temperature setting outright, so none is sent. Experience level (novice / intermediate / expert) sets the tone; a verbose toggle controls whether the reasoning is shown. The whole brain is one static system prompt — the engineering rules, persona, depth control, and output structure — kept static so it caches on the API. A dry-run mode assembles the entire prompt without spending a token, so it can be inspected and tuned for free.
Deterministic feasibility gate
Whether PC can print on a stock Ender 3 is physics, not opinion: the hotend caps at 240 °C, PC needs ~260 °C, and PC requires an enclosure the machine doesn't have. A pure-code check compares material requirements against printer limits — hotend and bed temperature, enclosure need, abrasive-versus-hardened-nozzle — and returns a verdict with blockers and warnings before the model is ever called. The impossible is refused in code, with the exact reason. The coach only communicates the verdict in persona; it never has to guess the physics. This is the single most important reliability decision in the system.
A demo that cannot run up a bill
A public demo on my own API key is an open invitation to spend my money, and the deployed one was exactly that for a while: no authentication, no rate limit, no upload cap. The fix was not to lock the door but to make the worst case knowable. Every visitor gets the full answer, settings table included, against a daily ceiling I set — and when that ceiling is spent the demo degrades to the half that costs nothing to serve, the geometry analysis and the feasibility verdict, both pure code. Degrading on exhaustion is a different thing from defaulting to the lesser answer: a slicer coach that leads with measurements has withheld the only part anyone came for.
Three limits, and only one of them actually bounds the bill: an upload cap that abandons an oversized body as it streams in rather than reading it first, a per-IP sliding window (fixed windows hand out two full allowances either side of the boundary), and a global daily ceiling on model calls. A per-IP limit does nothing against many callers, and the forwarded address it trusts is client-supplied and forgeable — so the ceiling is the real bound, and it is claimed immediately before the call so that malformed traffic cannot close the demo for everyone else. It is refunded only when the failure provably preceded billing.