Build: raw materials to a demonstrable exocortex (one milestone)
The whole build is a single milestone, M1. It ends with a wearable, photographed helmet and the fabrication footage. Two gates inside M1 decide whether to carry on; neither is a separate milestone.
Done means: - 1,024 contacts placed, logged at ≥ 99.5 % first-pass yield; - 16 tiles keyed into the shell; - wear mode and photo mode both work; - the shot list below has been captured.
Regenerate
uv sync --python 3.12
uv run python -m exo.layout # out/layout.json (tile frames, 1,024 contact positions, pads, vents)
uv run python -m exo.layout --study # out/tile_study.json (10/12/16/20 tiles)
uv run python -m exo.build # out/step, out/stl, out/dxf, out/bom.csv, out/report.json, out/viewer
uv run python -m exo.gcode # out/gcode/T01.nc ... T16.nc + summary.json
uv run python -m exo.stream --mock place T01 # dry run of the QA streamer
exo.build exits non-zero if any check in out/report.json fails. If the coupon gate changes cup_lip (or anything
else) in exo/spec.py, rebuild the tiles before printing them.
Tracks and critical path
| track | content | machine | elapsed |
|---|---|---|---|
| T0 ordering | BOM, woven label (10–14 day lead), brass balls (2 × 1,000 or 3 × 400) | — | day 0 |
| T1 SLA | coupons EXO-300/301 → gate 1 → 16 tiles EXO-201…216 (2 per plate) + EXO-311 pins | resin printer | days 1–6 |
| T2 FDM | PNP-100…102, PNP-200, PNP-211 → shell EXO-100 (band), EXO-101 (crown) | Ender-3 V3 SE × n | days 1–4 |
| T3 laser | PNP-210 ball tray from out/dxf/PNP-210.dxf, 3 mm black cast acrylic |
diode laser | day 2 |
| T4 placer | build the head, GRBL settings, zeroing, coupon run → gate 2 | 3018 | days 3–5 |
| T5 placement | 16 tiles × 64 balls, wick, cure, tug check | 3018 + UV | days 5–8 |
| T6 forming study | EXO-310/311 on EXO-320, A vs B (v1 data, does not gate v0) | oven, 3018 (MDF) | days 3–7 |
| T7 integration | inserts, shell bond, tiles, liner, dial, beanie, label | bench | days 8–9 |
| T8 presentation | finishing, photos, video | — | days 9–10 |
Critical path: order (day 0) → coupons → gate 1 → tile prints → placement → integration → label sewn on → photos.
The tile prints are the long pole: 8 plates at about 1.5–2.5 h each, plus washing and curing. Start them the moment gate 1 passes. The label arrives on day 10–14. If it's late, photograph everything except the cuff close-up first.
Day by day
| day | work |
|---|---|
| 0 | Order the BOM and the woven label. Measure the wearer (circumference, length, breadth, vertex height), set head_a/b/c in exo/spec.py, regenerate. Measure the 3018's spindle clamp bore and set clamp_bore. |
| 1 | SLA: EXO-300 flat and EXO-301 curved coupons. FDM: PNP-100 body, PNP-101, PNP-102. |
| 2 | Gate 1 tests (T-1, T-2). Laser the tray. FDM: PNP-200 fixture, PNP-211 tray base. Start the shell band (≈ 10 h). |
| 3 | Pass gate 1: lock cup_lip, rebuild, start the tile plates. Assemble the placer (T-3), set GRBL, zero. FDM: crown with tree supports. T6: mill the EXO-320 mould in MDF. |
| 4 | Coupon placement on the 3018 (T-4) → gate 2. Tiles keep printing. Heat-set the 32 shell inserts. Bond the band and crown with epoxy. |
| 5 | Place the first production tile (T01), check its yield. Then run tiles as they come off the printer, ~16 min each. T6: form the A and B coupons. |
| 6–7 | Placement continues (≈ 4.2 h of machine time in total). Wick and cure each finished tile, then tug-check it (T-5). T6: scan and measure. |
| 8 | Creep check on the first tiles (T-6). Mount all 16 tiles. Fit the pads, headband and dial cradle. |
| 9 | Beanie fit, finishing, wear test (T-7). |
| 10 | Photography and video (shot list). Label on arrival. |
Gate 1: snap fit (coupon ladder)
Coupons EXO-300 (flat) and EXO-301 (curved, median tile radius) carry 6 × 6 posts at the tile pitch. Each column has a different cup lip height: 0.15, 0.20, 0.25, 0.30, 0.35 and 0.40 mm, marked 1–6 by notches on the +y edge. That gives a diametral interference of about 0.015 to 0.11 mm.
T-1 Dimensional check (per coupon, after wash, post-cure 30 min and 24 h at room temperature): 1. Drop a ball loose onto each cup and look at it with a 10× loupe. It must sit centred on the lip. 2. Pin gauges or drill shanks: the stem must be ≥ Ø1.5. Calipers: cup outside Ø3.9 ± 0.1. 3. Measure post height to the cup lip at 4 corners and the centre. All must agree within ±0.08 mm.
T-2 Snap and pull-out: 1. Put the coupon on a kitchen scale (0.1 g resolution). 2. Press a ball in by hand with the bare needle tool (or a flat punch). Record the peak reading: that is the snap force. 3. Pull-out: superglue a 0.3 mm thread to a seated ball. Pull it vertically with a luggage scale, or by adding weights to a cup, until the ball comes out. 4. Do 3 contacts per column, on the flat and the curved coupon.
| criterion | target |
|---|---|
| snap force | ≤ 4.0 N (the spring preload is 5.0 N) |
| pull-out | ≥ 1.5 N (20× the 0.05 N vacuum grip, > 1,000× ball weight) |
| cups cracked at the lip | 0 |
Pick the column with the largest pull-out that still meets the snap limit, and set cup_lip in exo/spec.py to
its value. If no column passes because the cups crack, reprint in a tough/ABS-like 70:30 flexible blend and repeat.
Gate 2: placement on the 3018
T-3 Build the placer:
1. Press two LM4UU bearings into PNP-100's nose.
2. Cut the 4 mm shafts to shaft_len (from report.json → placer.shaft_len).
3. Fit the springs (5–6 mm OD, 0.5 mm wire) over the shafts.
4. Fit PNP-101 at the bottom (M3 set screws) and PNP-102 on top.
5. Fit the female-luer-to-barb adapter and a 16 G blunt needle.
6. Run the silicone hose up the axis to the pump through an inline filter.
7. Wire the KW10 microswitch's COM and NO to the 3018 board's probe header (A5, GND).
GRBL settings:
- $6=0: the switch pulls the probe pin to GND when closed.
- $110=$111=2000
- $112=600
Set the preload by sliding PNP-102 on the shafts: the needle, pressed onto the kitchen scale, should trip the switch at 5.0–5.5 N. Read the trip from the 3018's probe LED. Repeat 10×; the spread must be ≤ 0.3 N.
Bed layout and zeroing:
1. Clamp PNP-200 and PNP-211 with the tray to the bed.
2. Jog the needle into the fixture's Ø1.8 zero hole (tile coordinates −40, 0) and send G10 L20 P1 X-40 Y0.
3. Run exo.stream zero --wcs G54.
4. Do the same for the tray's reference hole R1 with P2 and --wcs G55.
5. Pump on.
T-4 Placement test on the coupon:
1. Place 36 balls on EXO-301 at the chosen column's lip. Use a coupon layout: copy a tile entry, or jog the 6 × 6 by
hand from the .nc.
2. Repeat on 3 coupons.
| criterion | target |
|---|---|
| seated on the first press | ≥ 35/36 |
seat_dz spread (out/place_log.csv) |
σ ≤ 0.05 mm |
pick_dz spread |
σ ≤ 0.05 mm |
| cycle time | ≤ 15 s per contact |
A trip 0.3–1.2 mm high means the ball is resting on the lip. Its fix is in this order:
1. raise the preload;
2. lower cup_lip by one ladder step.
Production gate on T01: run the first full tile and require ≥ 98 % placed on the first press (63/64) and 100 % after the streamer's re-press. Only then run the other 15.
Production tile procedure (T5)
- Mount the tile on PNP-200: feet A and B over the dowels, all three feet on their pads.
- Run
exo.stream --port … place T01. The tray state carries over between tiles. Refill when the streamer stops withtray_empty. - When the log shows an
unseatedstop, seat that ball with a flat punch and resume:place T01 --from N. - Wick: a 0.5 µL drop of the tile resin at each cup rim (fine needle syringe). It wicks under the ball. Wipe off the excess with IPA on a swab, then UV-cure 4 min per side.
- T-5 Tug check: stroke every ball with a fingertip and a soft brass brush, inverted over a tray. Required: 0 balls lost. Run 10 per tile at 1.5 N with the luggage scale and thread, chosen at random.
- Record the tile's yield and time from
out/place_log.csv.
Integration (T7)
- Heat-set 32 M2 × 3 inserts into the A and B bosses. Use a flat tip, at 230 °C, and press until flush. Back up the outside of the shell with a flat block so the skin doesn't bulge.
- Bond the crown to the band on the tongue with 5-minute epoxy. Clamp with tape over the curve and cure 1 h.
- Scuff the shell (P320) and give it matte black primer. Paint the inside first; the tiles cover most of it.
- Mount the tiles in order T01 → T16, working from the vertex out. The key pin only lets each tile seat in its own site. Fit 2 × M2 × 4 button-head screws per tile, finger-tight plus 1/8 turn (PETG strips).
- Stick on the hook-and-loop dots. Fit the EXO-110 headband (8 mm foam cut to the rim) and the crown pads (cut Ø ≤
16 mm pucks at the
padssites inlayout.json). - Clip the dial cradle into the two rim slots and adjust it to the wearer.
- Stretch the beanie over the shell and fold the cuff so it covers the rim by 10 mm. Sew the label on the cuff front, centred, 8 mm above the fold.
T-6 Warp and creep: 1. Put tile T01 on PNP-200 straight after its cure. 2. Measure the height of 9 balls (centre, edges, corners) with a dial indicator or the probe: G38 onto the ball tops. 3. Re-measure after 48 h, and again after 48 h at 45 °C (car dashboard / oven at its lowest setting).
Required: change ≤ 0.15 mm.
T-7 Wear test (the wearer, 30 min, three times): - feel round the tile edges and the rim with a fingertip: no pressure points; - press down on top with 20 N (a 2 kg hand load): no ball reaches the scalp. Check with lipstick on 20 sample balls, which must leave no marks on a swim cap worn under the helmet; - the beanie shows no hard edge in profile under a raking light.
Forming study (T6, data for v1)
| step | A: insert, then form | B: form, then insert |
|---|---|---|
| carrier | EXO-310, PETG 1.0 mm (FDM 100 % or drilled sheet), 6 × 6 Ø1.65 holes at the tile pitch | same |
| contacts | 36 EXO-311 snap pins + balls, pressed in flat | — |
| form | oven at 130 °C, 4–6 min, drape over EXO-320 (MDF, median tile radius), hold with a framed clamp until cool | same, without pins |
| insert | — | the pins pressed in along each hole's own axis by hand jig |
| measure | flatbed scan at 1,200 dpi before and after, hole centres by blob fit; ball heights with the probe on the 3018 | same |
Record for both: - hole-centre shift vs ε ≈ Kρ²/6 and Kρ³/6 from architecture.md §5; - tilt of the hole axes; - springback (the scanned radius vs the mould); - pins displaced or loosened; - yield.
Use 3 coupons each. The result goes into the v1 interconnect decision; it does not change v0.
Finishing
- Shell: matte black primer outside, no gloss, since it shows through the knit stretch.
- Tiles: as printed, dark grey. Optionally dry-brush the cup rims light grey to match the concept's light stems.
- Balls: degrease with IPA after the wick cure. Gold touch-up marker only on visible scuffs.
- Beanie: lint roller and steam. Fold the cuff evenly.
Shot list (spec §15)
Shoot on a grey seamless with one key and one fill. Keep exposure at the camera's base ISO and avoid coloured gels. Everything is real hardware at real scale.
- Hero, three-quarter front, on a headform.
- Front, side, rear and three-quarter views on the headform.
- Inverted, cuff up, looking into the array (photo mode, pads off).
- Macro: 3–4 rows of 3 mm contacts, with a ruler or coin in the frame for scale.
- Exploded flat-lay: beanie, shell band and crown, one tile per region, screws and pads.
- Single tile, front (posts) and back (routing grooves, feet, key).
- Manufacturing sequence: SLA plate → tile on fixture → 3018 placing (video, 1 tile at real speed plus a 16× timelapse) → wick and cure → mounting.
- Detail: ball, cup, stem and carrier — a sectioned coupon, cut with a fine saw and sanded.
- Worn: a person in a street setting. The beanie should read as ordinary clothing.
- The cutaway and the 16-tile headform diagram come from the CAD (
out/viewer, layout figures), not from photos.