# Decision record (WP33 TITAN-MoE) Format: D-NNN · date · decision · rationale · alternatives considered · consequences. ## D-001 · 2026-11-01 · Project location and numbering Decision: the project is UQO Working Paper No. 33, stored at `Recherche-UQO/ia/titan-moe/` (category `ia/`, after WP30/31), future bare repo `gitsrv:srv/git/wp33_uqo.git`. Inside, the directory structure follows the mandate (`titan/`, `metal/`, `transport/`, `adapters/`, `tests/`, `benchmarks/`, `research/`, `figures/`, `paper/`, `artifacts/`, `scripts/`). Rationale: one numbered folder per paper is the series standard (`HARMONISATION.md`); the mandate's `wp33_titan_moe/` name is honoured as the repository name. Deviation noted in README "Notes". ## D-002 · 2026-11-01 · Reference MLX backend first; third-party code as shallow git-ignored clones Decision: Gate B is a pure-MLX reference implementation on top of `mlx.core` ops (`gather_qmm`, `gather_mm`), not a fork of mlx-lm. Colibri, mlx, mlx-lm and llama.cpp are shallow-cloned under `third_party/` for audit only; hashes are recorded. Rationale: mandate ("reference MLX backend first; optimized C++/Metal/Swift only where justified"); keeps the repo small. ## D-003 · 2026-11-01 · First model: OLMoE-1B-7B-0125-Instruct, 4-bit MLX conversion Decision: `mlx-community/OLMoE-1B-7B-0125-Instruct-4bit` (rev `e2384419`, Apache-2.0, 16 layers, 64 experts, top-8, no shared expert). Rationale: small (3.9 GB), fully open licence, supported by mlx-lm (`olmoe.py`), llama.cpp (GGUF) and Colibri (OLMoE engine), so three baselines can be compared on the same architecture; 64 experts × 16 layers gives a non-trivial routing/caching problem. Alternatives: Qwen1.5-MoE-A2.7B (non-Apache licence), gpt-oss-20b (MXFP4, larger). Medium/large candidates (Qwen3-30B-A3B, gpt-oss-120b, Qwen3-235B) are deferred to Gate C/F and need an explicit download authorization above 20 GB. ## D-004 · 2026-11-01 · Unreachable nodes are excluded, not assumed Decision: nodes that did not answer SSH within 15 s at inventory time are excluded from WP33 experiments until re-probed; the paper's hardware table only lists machines whose specifications were read live (`sysctl`, `system_profiler`). ## D-005 · 2026-11-01 · Slot-table execution with `gather_qmm` on stacked slot buffers Decision: each layer owns a `SlotTable` of `capacity` resident experts in stacked MLX buffers; expert ids are remapped to slot ids and executed with the same `mx.gather_qmm` kernel mlx-lm uses, so the compute path is identical for resident and just-loaded experts. Loading = in-place slice assignment (`buf[slot] = tensor`), measured at 0.305 ms for the 9 tensors of one OLMoE expert into 216 MB buffers (`benchmarks/raw/gateB/design/slot_update_microbench_laptop.txt`), i.e. MLX reuses the buffer rather than copying it. Prefill rows whose unique-expert union exceeds the capacity are chunked greedily by rows (exact). Alternatives measured: per-expert `quantized_matmul` loop 0.43 ms/layer vs 0.26 ms for gather_qmm (1 token, top-8); re-stacking 8 experts per call 0.50 ms/layer. Consequence: the host must read the router's choice (`tolist()`) before each layer's expert kernels — the unavoidable synchronization of demand loading, shared with Colibri; its cost is measured in Gate C. ## D-006 · 2026-11-01 · Activation parity Decision: use mlx-lm's compiled `swiglu` (silu(gate)·up in one fused kernel). Rationale: an unfused fp16 `up·sigmoid(gate)·gate` gave max |Δlogit| = 0.0195 vs mlx-lm; the fused version gives 0.0 (bit-identical) — see `benchmarks/raw/tests/numerical_*.json`.