Meckie bodies.

Contribute.

A body is one folder. CI enforces the rest, so the fastest way to learn the standard is to run it on your branch.

01

Start from a working body

A pack is ten-odd files that have to agree with each other. Rather than start from nothing, copy one that already works — then change it a part at a time and watch what breaks.

npm install
npm run new-body -- my-body "My Body"      # copies Scout: 1 board, 19 parts, no serial servos
npm run sync && npm run emit && npm run site-data
npm run check

That gives you a complete, valid pack that already shows up in the catalog, and exactly one failing check:

my-body: still an unmodified copy of scout — its Print Parts geometry is scout's with the names changed.

That is the whole job, stated as a test. Pass --from to start from a body closer to what you are building — --from biped-mini for legs, --from lamp for an arm.

02

The shape of a pack

bodies/<slug>/
  <Name> Design Brief.dc.html     the full brief, sections 01-06
  <Name> Viewer.html              three.js viewer
  <Name> Print Parts.html         live CSG generator — the geometric source of truth
  stl/<slug>-<part>-x<qty>.stl    print files, quantity in the name
  parts-list.csv                  part,qty,where,link,notes
  firmware/hangar_bay_<slug>.yaml the body manifest — the one authored copy
  hangar-bay/<slug>.template.yaml generated from it
  generated/manifest.json         generated — what Meckie OS consumes
  generated/build.json            generated
  README.txt                      maker instructions
  LICENSE.txt                     CERN-OHL-S-2.0 + MIT
Three of those are generated. Edit the manifest, then npm run sync && npm run emit, and commit the result. CI fails if the committed output does not match a fresh run.
03

The rules CI enforces

1. No glue, ever

Everything screws into heat-set inserts or snaps together. Press-fits only where a screw or clamp retains them. CI reads the 05c assembly table: every joint's method must come from a mechanical vocabulary, and an adhesive word may appear in a joint description only in a sentence that rules it out.

2. Anything that drives senses ahead and below

A body with drives: true declares a peripheral with role: obstacle and at least two with role: drop_off, and every drop-off sensor must be wired into the edge reflex. A fixed base says why the rule does not apply rather than leaving the exemption implicit. Enforced by role, not by name — the names varied between packs and the rule silently passed bodies that only looked compliant.

3. The safety reflex

On heartbeat loss (~500 ms), low battery or servo over-temperature the body stops, brakes, waits about 2 s, moves slowly to a safe rest pose, lowers torque and shows a lost-connection face. It resumes only on a fresh command. And the calibration wizard ends in a required safety_test — the one check that proves it parks itself when Central goes away.

4. Pins are unique per host MCU

Partitioned by host, because a two-board body has two independent GPIO spaces and merging them invents collisions that do not exist. One pin may carry two signals only where shared_pins declares it, names every signal on it, and says how it is shared.

5. Fabrication

Fits a 220 × 220 mm bed. PLA shells and structure, TPU bumpers and tyres. Bearings at every pivot, metal servo horns, hidden fasteners. Insert bores: M2 Ø3.2 · M2.5 Ø3.6 · M3 Ø4.0 · M4 Ø5.6 · M5 Ø6.4. Supplier links stay plain — no affiliate tags, and prefer a search URL to a specific listing, because listings rot and searches do not.

3b

Why those two materials

The constraint that decided this was not strength. It was that a stock printer with no modifications should be able to make every rigid part. PLA needs no hardened nozzle, no dry box, no enclosure and no 260 °C hotend, which is the difference between a pack most people can print and a pack most people can only read. Contributed packs are held to the same rule.

PLA

everything rigid

Shells, structure, brackets, bezels. Stiff, dimensionally accurate, prints unsupported on more surfaces than anything else, and stocked in every colour the briefs name.

TPU 95A

only where flex is the function

Tyres, tracks, soles, feet, bumpers, grommets, straps. Parts a rigid version would not perform at all. Nothing is TPU for toughness alone — if a rigid part would do, it is PLA.

What PLA costs you

Snap hooks are the weak point. The snap features in these packs were drawn to stay under 2.5% strain, which suits PETG. PLA's safe cantilever strain is nearer 1.5%, so the hooks work harder than the geometry assumed. Print them with the layer lines running across the hook rather than along it, and treat a hook as a part you may have to reprint. Nothing in this catalogue has been test-printed, so this is the first place to look for trouble, and a report that a hook snapped is worth more to us than a report that one held.

Heat is a storage rule, not a running problem. PLA's glass transition is about 55 to 60 °C and the serial-servo bodies do not warn until 65 °C. Indoors that gap never opens: the shell sits near room temperature and the servos are the only thing that gets hot. Left in a closed car in summer, or on a sill in direct sun, a shell can soften while the electronics still consider themselves fine.

Heat-set inserts want a cooler iron. Every screw lands in a brass insert, and PLA's window is narrower than PETG's: run the iron around 180 to 200 °C, go in slowly, and let the boss cool before loading it. Rushing one slumps the wall around it.

If you want the margin back: the geometry does not change. Print the shells in PETG and the load-bearing structure in CF-nylon and every part still fits, because that was the original specification and the only thing that changed is which spool is on the shelf. The cost is a hardened nozzle, a dry box and a printer that holds 260 °C. Each body's brief carries this argument with that body's own numbers, in section 06b.

04

Submitting

git checkout -b my-body
npm run new-body -- my-body "My Body"
# design it: geometry, manifest, brief, buy list
npm run sync && npm run emit && npm run site-data
npm run check     # validate + generators current + the gates still fail on bad input
# drop "scaffolded_from" from your bodies.json entry, then open a PR

Hardware must be CERN-OHL-S-2.0 and code MIT, and the pack must include a Hangar Bay template. A community body gets a known template — pick it by name in Hangar Bay, flash, go — once it is accepted into the catalog. Until then it uses Hangar Bay's builder, which can already build whatever you design.

05

The catalog, for machines

The catalog is readable as JSON, which is how Hangar Bay fills its body picker: it reads the feed to list the official bodies, then fetches one template to get that body's manifest, pin map and calibration wizard. If you are writing something that needs the catalog, read these rather than scraping the pages.

GET /bodies.json
    every body: slug, class, servos, brains, mass_g, bom_usd,
    total_prints, materials, status, plus template_url and page_url

GET /api/bodies/<slug>/template
    the Hangar Bay template, pre-rendered by this repo. Served
    byte-for-byte as published, so the `hardware` text you hash
    is the text the pack signed.

GET /api/bodies/<slug>/stl.zip
    every STL for one body, in one zip.

The feed sends Access-Control-Allow-Origin: * on purpose — another app on your own machine reading it is the point — and no-cache, so a body you scaffold shows up the moment it exists. While the catalog is in private preview it also accepts the access token as ?t= or an X-Meckie-Bodies-Token header, because Hangar Bay has no browser session to carry a cookie.