# NativeCAD 0.12.2 "Mäkelä" — a rod butting into a rod, and a tool list back inside its budget

**126 tools, nothing added, removed or renamed.** Two fixes, both long overdue.

## The equal-radius T-junction is analytic (CADSB-1039)
0.11.2 made the equal-radius **cross** — two rods passing through each other — analytic. A **T** is a different shape: the rod stops. It was refused `cyleq_not_through` and fell to the general engine, and that answer was unusable: **867 faces** with the tool ending on the base's axis, 443 past it, and at tangency an outright `unsupported_overlap` refusal. Reported live from the web modeller.

The boss path could not take it either, and the reason is worth stating: at r = R the tool's cap rim always reaches √(s² + R²) ≥ R, so a root is never embedded — **the cap always breaks the base's surface near the pinch directions**. That is why this is a third construction rather than a parameter of the other two.

New `cylCylEqualTee` in `ops/cylCylEqual.js` builds it exactly. Every curve is a STEP ELLIPSE, CIRCLE or LINE; nothing is fitted:
- A tool wall point (φ, s) is outside the base iff |s| > R·|sin φ|, so **the intersection is the same two planar ellipses the cross already authors**, used as the arcs t ∈ [φ*, π−φ*] and [π+φ*, 2π−φ*] with sin φ* = |s_end|/R.
- The near cap's plane is *parallel to the base axis*, so the base cuts it in **two straight chords** at u = ±√(R² − s_end²) — and those chords are **generators of the through cylinder**, so the same two lines both bound the cap slivers and cut the through wall. Using them as the wall's cut lines makes every face a disc and collapses the sub-cases into one code path: s_end = 0 is simply the degenerate end, where the chords shrink to the pinch points and the near cap vanishes.

Measured: **8 faces** (5 cylindrical + 3 planar), 14 edges, 8 vertices with the tool ending on the axis; 10 faces, 20 edges, 12 vertices short of it; V − E + F = 2 in both; `checkFull` and the watertightness gate clean; worst edge tolerance 3.6e-15; volume within 1.5e-4 of the closed form V∩ = 4k(R² − k²/3) + 2·s_end·(k|s_end| + R²·asin(k/R)), which is 8R³/3 at s_end = 0 — half the Steinmetz solid — and is itself pinned against its own 1-D integral to ~1e-11, so neither form can drift alone. Either operand order works. The cross is unregressed at 12 faces.

**Still refused by name, and still the general engine's** (the ladder continues on every one): `cyleq_tee_end_beyond_axis` — a cap *past* the base's axis but still inside it, where the wall grows two extra regions above the pinch; `cyleq_tee_no_overlap` — external tangency, which is contact rather than overlap; `cyleq_tee_far_end_not_clear`; `cyleq_tee_is_cross`.

## tools/list is back under its ceiling (CADSB-1038)
`packages/mcp/test/tool-list-budget.test.js` had been red on master through 0.11.1, 0.11.2, 0.12.0 and 0.12.1 — each release noting it as pre-existing. `tools/list` was **416,675 B** against a 409,600 B (400 KiB) ceiling. The ceiling is not decoration: an MCP client pays for the whole tool list on every session.

Now **335,220 B** across 126 tools (avg 2,660 B), clear of the 400 KiB ceiling by ~74 KB and of the stricter additive per-tool checks too. The per-description budgets were tightened; seven opening sentences were rewritten shorter and *complete* rather than left to hard-cut mid-word; the boolean tools' duplicated engine-ladder paragraph was deduped. **No tool, parameter, or first-sentence meaning was removed** — the long form stays in `cad_help` / `describe_tool` and `docs/TOOLS.md`, which is where it belongs.

## Gates
tool-list-budget **24/24** (was failing at assertion 3) · schema-sync 481/481 · mcp-smoke `dist/server.min.js` 126 tools · bundle-smoke on the shipped `.mcpb` · `dist/server.min.js` sha256 `be124f92…` identical in the tgz and the `.mcpb` · kernel suites green together: cadsb-1039 89, cadsb-1009 36, cadsb-1005 22, cadsb-1006 38, test_boolean 16.

**Downloads are served from featureboard.ai** (see `latest.json` for bytes + sha256):
https://featureboard.ai/nativecad/releases/nativecad-mcp-0.12.2.mcpb
Staged kernel: git abae4b69, tree 70bf54b6f580. Built with `SOURCE_DATE_EPOCH` pinned from a clean `git archive` export, esbuild 0.28.1.
