Status: planned 2026-05-23 (epic cppmega-mlx-v7-q)
Driver: 8-lane parallel audit (Lanes 1–8: Gallery, Canvas, Tokenizer, Data,
Training, Checkpoints, Optim, Distributed) against the operator promise from
the Raschka LLM gallery walkthrough. Audit report at
docs/UI-TO-TRAIN-AUDIT-2026-05-23.md. Found 5 production-blocking gaps + 3
polish + 2 coverage; this plan closes them.
| Q# | bd id | Title |
|---|---|---|
| Q01 | cppmega-mlx-zcbs | DataInspector file picker (P0 BLOCKING, Lane 4) |
| Q02 | cppmega-mlx-ofd2 | Edge validation in FlowCanvas (P0 BLOCKING, Lane 2) |
| Q03 | cppmega-mlx-9avx | Checkpoint history UI + compress/strict (P1, Lane 6) |
| Q04 | cppmega-mlx-2d47 | Close 5 Raschka gallery preset gaps (P1, Lane 1) |
| Q05 | cppmega-mlx-bfbi | smoke_zero1 CLI implementation (P1, Lane 8) |
| Q06 | cppmega-mlx-sbz8 | Train UI polish — B/S + nesting + plasticity (P2) |
| Q07 | cppmega-mlx-x4vd | E2E coverage gaps — extras + edge + adapter (P2) |
| Q08 | cppmega-mlx-bpge | Late warnings + multi-node receipt (P3) |
V7-Q is intentionally smaller than V5/V6 (8 epics, ~24 sub-tickets vs V6's 25 gaps / 190 sub-tickets) because the closure surface is narrower — V5/V6 wired the math; V7-Q wires the operator UX on top.
V6 closed the backend-ready → UI-wired → real-math triangle. The honest
audit pass that followed (docs/UI-TO-TRAIN-AUDIT-2026-05-23.md) walked
the Raschka-gallery operator promise step-by-step and found that the
math paths work end-to-end, but several operator surfaces are stub
or text-only:
The promise "user uploads a parquet file (or picks one from the matrix)" is half-shipped: matrix-pick works, upload doesn't.
| Q# | Audit lane | UI work needed |
|---|---|---|
| Q01 | Lane 4 | <input type="file"> + POST /upload/parquet endpoint |
FlowCanvas accepts isValidConnection?: IsValidConnection (line 20)
but App.tsx:1215 never passes it. Incompatible drops succeed silently
and fail at server verify. Client-side rejection contract exists in the
React Flow prop but is unused.
| Q# | Audit lane | UI work needed |
|---|---|---|
| Q02 | Lane 2 | Pass isValidConnection from App, derive set from catalog.list_options('compatible_edges') |
Backend supports save/load with arch-hash, compression, strict modes,
mid-run trigger; UI surfaces only the two raw text paths. 5 of 71
Raschka entries have bricks but no preset factory. smoke_zero1 CLI
documented but unimplemented.
| Q# | Audit lane | UI/CLI work needed |
|---|---|---|
| Q03 | Lane 6 | ckpt.list_history RPC + dropdown + 3 toggles + V7-H05 WS |
| Q04 | Lane 1 | 4 preset factories: abs_pos_embed / mlstm / per_layer_embed; tiny_aya wire-in |
| Q05 | Lane 8 | cppmega_mlx.cli.smoke_zero1 + mlx.launch wrapper + receipt regression |
B and S not exposed as train controls. loss_scaler.overflow_steps
nests under loss_scaler dict in backend but UI reads flat
extras.loss_scaler_overflows — silent mismatch, overflow markers
don't render. Plasticity / MTP / IFIM / MHC extras flow through but
have no styled panel.
| Q# | Audit lane | Work |
|---|---|---|
| Q06 | Lane 5 | B + S inputs; fix nesting at stages.py:2245; add 4 styled sub-panels |
readTrainExtras reads 7/16 promised keys; no e2e for manual edge
connect or GotchasTab adapter suggestions.
| Q# | Audit lane | Work |
|---|---|---|
| Q07 | Lane 2+5 | Extend readTrainExtras + 2 new Playwright specs |
Tokenizer compatibility check at preview time, peak-RSS regression at real >1 GiB checkpoint, multi-node throughput receipt. The last one is BLOCKED on peer-48 hardware (external).
| Q# | Audit lane | Work |
|---|---|---|
| Q08 | Lane 4+6+8 | tokenizer-at-preview, >1GB peak-RSS test, multi-node note |
After v7-Q every step of the operator promise from
docs/UI-TO-TRAIN-AUDIT-2026-05-23.md §"happy path" works without
copy-paste of paths, without silent shape-contract failures, and with
71/71 Raschka gallery coverage. The honest audit is re-runnable and
returns zero P0/P1 gaps.
cppmega-mlx-v7-q (epic)
├── Q01 file picker (P0, 3 sub)
├── Q02 edge validation (P0, 3 sub)
├── Q03 ckpt history (P1, 4 sub)
├── Q04 5 gallery presets (P1, 4 sub)
├── Q05 smoke_zero1 CLI (P1, 3 sub)
├── Q06 train UI polish (P2, 3 sub)
├── Q07 e2e coverage (P2, 3 sub)
└── Q08 late warnings (P3, 3 sub)
Total: ~24 sub-tickets (much smaller than V6 because closure surface
is narrow — V7-Q is the "polish on top of V6's wiring" pass)
- Q01.1 Backend
POST /upload/parquetendpoint incppmega_v4/jsonrpc/server.pywith size-cap 2 GiB, suffix-validate, write to${VBGUI_UPLOAD_DIR:-/tmp/vbgui_uploads}/<uuid>.parquet, return{"path": str}. TTL cleanup 24 h. - Q01.2 UI:
<input type="file" accept=".parquet">inDataInspector.tsx:194-198with testiddata-inspector-file-upload. On change:FileReader.readAsArrayBuffer→ POST → set text field to returned path. - Q01.3 Tests: vitest mock fetch + path-set; pytest
TestClientPOST a 1 KiB synthetic parquet; Playwrightpage.setInputFileson the testid, assert preview RPC fires with the returned path.
- Q02.1 Backend
catalog.list_options("compatible_edges")returns[{src_kind, dst_kind}]derived fromcppmega_v4/buildspec/shape_contract.SHAPE_CONTRACTS. - Q02.2 UI:
App.tsxon preset/brick changes pulls compatible-edges set once; closuresvalidateEdge({source, target})→contractSet.has(${srcKind}→${dstKind}). PassisValidConnection={validateEdge}to FlowCanvas at line 1215. - Q02.3 Tests: vitest renders FlowCanvas with
isValidConnection=()=>false, attempts onConnect, asserts edge not added; pytest catalog endpoint coverage for all 25 bricks; Playwright dropsattention+embed_lookup, attempts connect, asserts no React Flow edge node appears.
- Q03.1 RPC
ckpt.list_history(directory: str = ".") → list[CkptEntry]. Scans recursively for*.safetensors, reads metadata viaread_ckpt_metadata(header-only, no full load), sorts by mtime desc, caps at 100. CkptEntry:{path, mtime, size_bytes, arch_hash, opt_kind, global_step, has_opt_sidecar}. - Q03.2 UI: new
CheckpointHistoryDropdown.tsxcomponent invbgui/src/components/, wire intoTopBar.tsxnext to ckpt path input. Each row:<basename> · arch_hash[:8] · step N · mtime. Click → fillsckpt_load_pathtext field. - Q03.3 UI:
TrainOptionsPanel.tsxadds 3 controls —compressdropdown (none / weights-int8 / opt-fp16 / both),ckpt_strictcheckbox,opt_state_strictcheckbox. Forward viastage_options.train. - Q03.4 V7-H05 mid-run trigger: backend adds
_TRIGGER_CHECKPOINT_TOKENSset + WS message handlerckpt.trigger {token, path}→ train loop checks each step → saves via existing_save_compressed+ sidecar. UI: existingTrainLiveControlsbutton'sonScheduleCheckpointcallback rewired to send the WS message.
- Q04.1
gpt2_xl_specs(...)incppmega_v4/architectures/presets.pyusingabs_pos_embedbrick. Closes Raschka #1. - Q04.2 Wire existing
tiny_aya_parallel_specs()intoPRESETSdict with key"tiny_aya". Closes Raschka #44. - Q04.3
xlstm_7b_specs(...)usingmlstmbrick. Closes Raschka #50. - Q04.4
gemma_4_e2b_specs(...)+gemma_4_e4b_specs(...)usingper_layer_embedbrick. Closes Raschka #57+58. Remove 5 xfail markers fromtests/v4/test_galcov_stage_d.py:204-211. Acceptance: 71/71 (100%).
- Q05.1
cppmega_mlx/cli/smoke_zero1.pyentrypoint with argparse--hosts H1,H2,...,--world-size W,--num-steps N,--out path. Wrapsmlx.launch -n W --hosts H1,H2,...around thebench/bench_zero1_loopbackpayload. - Q05.2 Each rank runs ZeRO-1 wrapper over a tiny MLP; captures per-rank loss +
gradient_reduce_ms. Rank 0 collects + writes receipt JSON{world_size, hosts, losses, reduce_ms, parity_max_delta}. - Q05.3 Regression: receipt regeneratable via
python -m cppmega_mlx.cli.smoke_zero1 --hosts 127.0.0.1,127.0.0.1matches existingbench/baselines/zero1_loopback_2proc_m4.jsonwithin tolerances. pytest hook for loopback receipt.
- Q06.1
TrainOptionsPanel.tsxaddstrain-opt-B(number 1-32) andtrain-opt-S(number 1-8192) inputs. App overridesspec.dim_env.B/Sbeforepipeline.run. - Q06.2 Fix nesting at
cppmega_v4/runner/stages.py:2245: also flattenextras["loss_scaler_overflows"] = loss_scaler_overflow_steps(keep nestedloss_scaler.overflow_stepsfor back-compat). vitest pins both. - Q06.3
TrainExtrasOverlay.tsx: add conditional sub-panels —PlasticityPanel(FIRE/DASH/ReDo),MTPPanel(k-head losses),IFIMPanel(instr-FIM loss),MHCPanel(multi-head consistency). Each renders only when its key present in extras.
- Q07.1 Extend
vbgui/e2e/utils/train_extras.ts:readTrainExtrasto all 16 promised keys (losses, losses_smoothed, val_losses, lr_trajectory, perplexity, bpb, dtype_state, fp8_active, fim_active, sharding_applied, side_channels_observed, per_brick_grad_norms, moe.*, optimizer_kind, gradient_reduce_ms, weight_delta_norm).12_train_convergence.spec.tsasserts all 16 present + finite where applicable. - Q07.2 New
vbgui/e2e/scenarios/74_manual_edge_connect.spec.ts: drop two compatible bricks, manually draw edge via React FlowconnectionLine, verify edge appears, assert verify RPC accepts. - Q07.3 New
vbgui/e2e/scenarios/75_adapter_suggestions.spec.ts: load preset with intentional shape mismatch, navigate to GotchasTab, click "Suggest adapters", assert chain renders and "Apply" inserts adapter nodes on canvas.
- Q08.1 Extend
data.preview_parquetRPC: accept optionaltokenizer_sourcearg → returnsroundtrip_pass_rate: floatfield → DataInspector shows badge inline with preview, not waiting until train. - Q08.2 pytest
test_checkpoint_streaming_peak_rss.pygenerates 1.5 GiB synthetic checkpoint →load_auto→ assertsmx.metal.get_peak_memory()< 200 MiB during load. - Q08.3 Multi-node throughput receipt: file a
BLOCKEDnote in bd ticket — peer-48 TB5 + macOS 26.2 + M4 family hardware required (perdocs/multimac_training.md:114-129). Carry hardware-blocker notes; not implementable without external resource.
bd update <id> --claim- Implement (each sub-task atomic)
- Code review (self if <100 LOC, gsd-code-reviewer otherwise)
- Perf check (no >5% regression on affected suite)
- Regression (pytest + vitest + e2e affected)
git addspecific files → commit → push → verify on origin/mainbd close <id>only after push verified
| Surface | Before v7-Q | Target v7-Q |
|---|---|---|
| pytest | ~2540 | ≥2570 |
| vitest | ~428 | ≥440 |
| Playwright deep e2e cells | ~1170 | ≥1175 |
| Raschka gallery coverage | 66/71 (93%) | 71/71 (100%) |
| extras keys read by e2e | 7/16 | 16/16 |
| P0 audit gaps | 2 | 0 |
| P1 audit gaps | 3 | 0 |
| Hardware-blocked gaps | 1 | 1 (external) |
- Real cross-Mac ZeRO-1 receipt (BLOCKED on peer-48 hardware)
- 1B+ param training matrix on Mac
- A/B hyperparameter search UI
- LoRA / PEFT adapter wiring
- Tokenizer mutation UI (read-only by design per Lane 3)
- Sophia / Adafactor / Tiger / AdEMAMix optimizers (deferred per Lane 7)
- Live inference serving from trained checkpoint
- Model weight quantisation post-train
All 8 Q-gaps closed (Q08.3 carried as hardware-blocker note). Zero P0/P1
audit findings on re-run. Closure report at
tests/fixtures/e2e_matrix_v7_q_report.md. Re-run audit
(docs/UI-TO-TRAIN-AUDIT-2026-05-23.md re-execution) returns 0 BLOCKING
gaps.