|
1 |
+# CLAUDE.md — Zyquo MLX |
|
2 |
+ |
|
3 |
+## Project Identity |
|
4 |
+ |
|
5 |
+**Zyquo MLX** is the **foundry** member of the **Zyquo** family: a legendary, native macOS app written in **Swift + SwiftUI**, built **without the Xcode IDE** (Swift Package Manager + command-line toolchain where the MLX/Metal toolchain allows). Where **Zyquo Local** is a *consumer chat client* for downloaded MLX models, **Zyquo MLX** is the **power-user foundry**: a complete workbench for the full on-device MLX lifecycle on Apple Silicon — **inference of every supported model type, fine-tuning (LoRA/QLoRA and full), quantization, format conversion, dataset preparation, training runs with live metrics, evaluation, and export**. |
|
6 |
+ |
|
7 |
+Think "the local MLX studio for the Mac": pull or point at any model, run it (LLM, VLM, embeddings, and whatever else the current MLX ecosystem supports), fine-tune it on your own data with a real training UI, quantize/convert it, evaluate it, and ship the result — all locally, all Apple-Silicon-native, all beautiful. |
|
8 |
+ |
|
9 |
+**Naming conventions (use consistently everywhere):** |
|
10 |
+- Display name / product name: `Zyquo MLX` |
|
11 |
+- App bundle: `Zyquo MLX.app` |
|
12 |
+- Bundle identifier: `com.zyquo.mlx` |
|
13 |
+- Executable / SPM target: `ZyquoMLX` (no space) |
|
14 |
+- Data folder: `~/Library/Application Support/ZyquoMLX/` |
|
15 |
+- Models: `~/Library/Application Support/ZyquoMLX/Models/` |
|
16 |
+- Datasets: `~/Library/Application Support/ZyquoMLX/Datasets/` |
|
17 |
+- Training runs / checkpoints: `~/Library/Application Support/ZyquoMLX/Runs/` |
|
18 |
+- Repo module prefix in file headers: `Zyquo MLX` |
|
19 |
+- **Platform: Apple Silicon (arm64) ONLY.** MLX requires Apple Silicon. Detect Intel at launch and show a clear, polite unsupported-hardware screen. |
|
20 |
+ |
|
21 |
+--- |
|
22 |
+ |
|
23 |
+## 📋 MANDATORY FILE HEADER — EVERY CODE FILE |
|
24 |
+ |
|
25 |
+**Every single code file you write** (all `.swift` files, plus `Makefile`, shell scripts, `Package.swift`, any Python training helper scripts if used, verification scripts — anything containing code) **MUST begin with this header comment**, adapted to the file's comment syntax: |
|
26 |
+ |
|
27 |
+```swift |
|
28 |
+// |
|
29 |
+// <FileName>.swift |
|
30 |
+// Zyquo MLX |
|
31 |
+// |
|
32 |
+// Author: Simon-Pierre Boucher |
|
33 |
+// Mail: contact@spboucher.ai |
|
34 |
+// |
|
35 |
+``` |
|
36 |
+ |
|
37 |
+For shell / Python / Makefiles: |
|
38 |
+ |
|
39 |
+```bash |
|
40 |
+# |
|
41 |
+# <filename> |
|
42 |
+# Zyquo MLX |
|
43 |
+# |
|
44 |
+# Author: Simon-Pierre Boucher |
|
45 |
+# Mail: contact@spboucher.ai |
|
46 |
+# |
|
47 |
+``` |
|
48 |
+ |
|
49 |
+No exceptions. If you ever create or refactor a file and the header is missing, add it. Before declaring the project done, run a sweep over the repository to verify every code file carries the header. |
|
50 |
+ |
|
51 |
+--- |
|
52 |
+ |
|
53 |
+## 🧭 METHODOLOGY — WORK METHODICALLY, KEEP EVERYTHING COHERENT |
|
54 |
+ |
|
55 |
+You must execute this project **strictly in phase order (0 → 8)**. Do not jump ahead, do not interleave phases, do not build the fine-tuning UI before an inference run works end-to-end, and do not write any code before Phase 0 research is complete. |
|
56 |
+ |
|
57 |
+**Working rules:** |
|
58 |
+ |
|
59 |
+1. **One phase at a time.** At the start of each phase, write a checklist into `docs/PLAN.md`; check items off as you go. At the end of each phase, run a **phase checkpoint**: build (`swift build`), run what's runnable, fix all warnings/errors, write a 3–5 line phase summary in `docs/PLAN.md` before moving on. |
|
60 |
+2. **Phase gates:** Phase 0 is complete only when `docs/MLX-RESEARCH.md` (framework), `docs/TRAINING-RESEARCH.md` (fine-tuning), and `docs/BUILD.md` (no-Xcode-IDE build recipe incl. Metal) are complete. Phase 2 is complete only when a CLI POC runs inference on one small model of at least two types. Phase 3 is complete only when a real LoRA fine-tune completes on a tiny dataset and the adapted model generates. Phase 4 spec is the contract for all UI in Phase 6. Phase 7 is complete only when the multi-capability verification table is green. Phase 8 is complete only when `spctl` says "Notarized Developer ID". |
|
61 |
+3. **Single source of truth, everywhere:** |
|
62 |
+ - MLX capabilities/APIs → only as documented in Phase 0 docs; never guess an API name. |
|
63 |
+ - Curated model/dataset data → only from `Catalog` (generated from Phase 0). Live Hugging Face results come from `HubService` only. |
|
64 |
+ - Colors, fonts, spacing, radii → only from `ZyquoTheme` design tokens. Zero raw hex or magic numbers in views. |
|
65 |
+ - Inference, training, quantization, conversion → only in the `Engine/`, `Training/`, `Convert/` layers; never leak into Views/ViewModels. |
|
66 |
+ - Product naming → per the conventions above. Never `Zyquo` alone, never `ZyquoMLX` in user-facing text. |
|
67 |
+4. **Coherence sweeps:** after Phases 3, 6, and 8 (uniform naming — always `LocalModel`, `TrainingRun`, `Dataset`, `Checkpoint`; no dead code; headers present; folders match Phase 2). |
|
68 |
+5. **Compile early, compile often.** Never accumulate more than one file of unbuilt changes. |
|
69 |
+6. **Commit discipline:** one logical unit per commit, phase-prefixed. **Never commit model weights, datasets, or checkpoints** (add them to `.gitignore`). |
|
70 |
+7. **Long-running work is first-class:** training/quantization can run for minutes to hours. From the first training code, build for cancellable, resumable, observable background jobs with persisted state — not fire-and-forget. |
|
71 |
+ |
|
72 |
+--- |
|
73 |
+ |
|
74 |
+## ⚠️ PHASE 0 — MANDATORY INTENSIVE WEB RESEARCH (DO THIS FIRST, BEFORE ANY CODE) |
|
75 |
+ |
|
76 |
+Do NOT rely on training data — MLX moves fast. Perform **several intensive web research sessions** on the current MLX ecosystem and produce three documents. Use official sources: **github.com/ml-explore/mlx**, **github.com/ml-explore/mlx-swift**, **github.com/ml-explore/mlx-swift-examples**, **github.com/ml-explore/mlx-examples** (Python: LoRA/LLMS/whisper/stable-diffusion/etc.), **ml-explore.github.io/mlx** docs, **github.com/ml-explore/mlx-lm**, **huggingface.co/mlx-community**, **github.com/huggingface/swift-transformers**. |
|
77 |
+ |
|
78 |
+### 0.A — `docs/MLX-RESEARCH.md` — the MLX framework, deeply |
|
79 |
+ |
|
80 |
+Document precisely and completely: |
|
81 |
+ |
|
82 |
+1. **What MLX is and its core primitives:** the array framework, lazy evaluation & `eval()`, unified-memory model on Apple Silicon, streams/devices (GPU/CPU), `mlx.core`, `mlx.nn`, `mlx.optimizers`, automatic differentiation (`value_and_grad`), and how compute is dispatched to Metal. |
|
83 |
+2. **MLX Swift vs. MLX Python — the honest capability split.** Determine CURRENT reality: MLX has a mature **Python** stack (mlx-lm, mlx-examples for LoRA fine-tuning, quantization, VLM, whisper, stable diffusion) and a **Swift** stack (mlx-swift, mlx-swift-examples with MLXLLM/MLXVLM/MLXLMCommon, MLXNN, MLXOptimizers, MLXRandom). Document exactly which capabilities exist natively in Swift today (inference for LLM/VLM/embeddings, training primitives, LoRA) vs. which are Python-first (full fine-tuning pipelines, quantization tooling, conversion, some model types). **This determines the app's execution strategy (see 0.A.6).** |
|
84 |
+3. **Model types & the current MLX model zoo.** Document what MLX supports RIGHT NOW: text LLMs (Llama, Qwen2/2.5/3, Mistral, Gemma/2/3, Phi, DeepSeek/distills, SmolLM…), **vision-language models** (Qwen-VL, LLaVA, Idefics, Pixtral, etc. via MLXVLM / mlx-vlm), **embeddings**, **speech** (Whisper via mlx-examples), **image generation** (Stable Diffusion / FLUX via mlx-examples), and any others. For each type: which package handles it, the exact load/run APIs, and input/output formats. |
|
85 |
+4. **Inference API specifics (Swift-first, Python fallback):** loading a model dir (`ModelContainer`/factory APIs — verify names), tokenizers & chat templates, streaming generation (`AsyncSequence`/callback), generation params (temp, topP, repetitionPenalty, maxTokens, seed), KV-cache, and unloading/freeing memory (`MLX.GPU.set(cacheLimit:)`, memory APIs). |
|
86 |
+5. **Quantization & conversion:** how MLX quantizes weights (group size, bits — 4/8-bit, `nf4`-style?), the `mlx_lm.convert` / conversion tools to turn HF models into MLX format, and how to quantize during/after conversion. Document exact commands/APIs and the resulting on-disk format (`config.json`, `*.safetensors` sharding, `model.safetensors.index.json`, tokenizer files, quantization metadata). |
|
87 |
+6. **⚠️ Build & execution strategy — resolve definitively and document in `docs/BUILD.md`:** |
|
88 |
+ - Verify whether `swift build` compiles MLX's Metal kernels with only Command Line Tools or needs the full Xcode Metal toolchain. Test it. If full Xcode's metal compiler is required, the rule adapts to **command-line `swift build`/`xcodebuild` only, no Xcode IDE, no hand-authored `.xcodeproj`**, fully automated by the Makefile. |
|
89 |
+ - Decide the **execution model** for capabilities that are Python-first (likely full fine-tuning, quantization, conversion, image/audio): the app ships/manages a controlled **embedded Python environment** (e.g., a bundled venv using `mlx-lm`/`mlx` Python packages) that the Swift app drives via `Process` for those pipelines, while doing native-Swift MLX for LLM/VLM inference and LoRA where Swift supports it. Document how the venv is created/bootstrapped on first run (uv/pip), pinned versions, offline behavior, and how progress/metrics are streamed back to Swift (parse stdout / a JSON progress protocol). If, by the time you build, Swift natively supports a capability, prefer Swift and note it. |
|
90 |
+7. **Memory & performance:** estimating RAM for inference vs. training (weights + optimizer state + activations + KV cache), batching, gradient checkpointing if available, and realistic model-size limits per Mac RAM tier. |
|
91 |
+ |
|
92 |
+### 0.B — `docs/TRAINING-RESEARCH.md` — fine-tuning on MLX, concretely |
|
93 |
+ |
|
94 |
+1. **LoRA / QLoRA on MLX:** the exact `mlx-lm`/`mlx-examples` LoRA workflow — command/API surface, hyperparameters (rank, alpha, dropout, learning rate, batch size, iters/epochs, target modules, quantized base for QLoRA), how adapters are saved (`adapters.safetensors`), and how to **fuse** an adapter back into base weights. |
|
95 |
+2. **Full fine-tuning:** feasibility, memory cost, and the workflow/limits on Apple Silicon. |
|
96 |
+3. **Datasets:** the expected dataset formats (JSONL chat format, completion format, prompt/response), train/valid split, how prompts are templated, tokenization, and validation. Document at least the standard `{"messages": [...]}` and `{"prompt":..., "completion":...}` shapes MLX expects. |
|
97 |
+4. **Training loop observability:** what metrics are emitted (train/val loss, tokens/sec, iteration, learning rate), checkpoint cadence, and how to resume from a checkpoint. |
|
98 |
+5. **Evaluation:** perplexity/loss on a held-out set, quick qualitative generation checks, and comparing base vs. fine-tuned. |
|
99 |
+ |
|
100 |
+### 0.C — `docs/MODELS.md` — curated catalog + Hub integration |
|
101 |
+ |
|
102 |
+- Hugging Face Hub HTTP API (search, model info/file listing, resolve URLs, LFS, sizes, optional HF token for gated models) — same rigor as Zyquo Local. |
|
103 |
+- A curated **Featured catalog** across types and sizes (text, VLM, embeddings, speech, image-gen where applicable) with exact `mlx-community` repo IDs, sizes, quant, and min-RAM — verified to exist right now. |
|
104 |
+- A RAM table (8/16/24/32/48/64/128 GB) for inference **and** for LoRA fine-tuning (training needs more) to power in-app compatibility badges. |
|
105 |
+ |
|
106 |
+--- |
|
107 |
+ |
|
108 |
+## PHASE 1 — Project Setup |
|
109 |
+ |
|
110 |
+- **Toolchain:** SPM (`Package.swift`, target `ZyquoMLX`) depending on the MLX Swift packages from Phase 0. Build per `docs/BUILD.md`. |
|
111 |
+- **Embedded Python (if Phase 0.A.6 requires it):** Makefile target that provisions a pinned, isolated venv under `~/Library/Application Support/ZyquoMLX/py/` (mlx, mlx-lm, and needed extras), created on first launch with clear UI progress; never pollute the user's system Python. |
|
112 |
+- **App bundle:** Makefile builds release, assembles `Zyquo MLX.app` (binary, `Info.plist`, `Resources/AppIcon.icns`, any MLX metallib/resource bundles, and any bundled Python bootstrap assets), signs (Phase 8; ad-hoc for `make dev`). |
|
113 |
+- **Info.plist:** `CFBundleDisplayName` = `Zyquo MLX`, bundle ID `com.zyquo.mlx`, `LSMinimumSystemVersion` per MLX (set from Phase 0), `NSHighResolutionCapable`, `LSApplicationCategoryType` (`public.app-category.developer-tools`), `LSArchitecturePriority` arm64. |
|
114 |
+- **Entry point:** `@main` SwiftUI `App`; Apple-Silicon gate; proper activation from terminal. |
|
115 |
+- **Dependencies:** MLX Swift packages + swift-transformers (if chosen) + Apple `swift-markdown` (optional). Nothing else in Swift; Python side pinned in the venv. |
|
116 |
+ |
|
117 |
+--- |
|
118 |
+ |
|
119 |
+## PHASE 2 — Architecture + Inference POC (All Types) |
|
120 |
+ |
|
121 |
+``` |
|
122 |
+Sources/ZyquoMLX/ |
|
123 |
+├── App/ # @main, windows, Apple-Silicon gate, first-run bootstrap |
|
124 |
+├── DesignSystem/ # ZyquoTheme — family tokens, MLX foundry palette |
|
125 |
+├── Models/ # LocalModel, ModelType, Dataset, TrainingRun, Checkpoint, Job… |
|
126 |
+├── Engine/ |
|
127 |
+│ ├── InferenceEngine.swift # actor: load/run per model type (LLM/VLM/embeddings), streaming |
|
128 |
+│ ├── ModelTypeAdapters.swift # LLM, VLM, Embeddings, (Speech/ImageGen via Py bridge) |
|
129 |
+│ ├── GenerationParams.swift |
|
130 |
+│ └── MemoryAdvisor.swift # RAM estimates for inference AND training |
|
131 |
+├── Training/ |
|
132 |
+│ ├── TrainingService.swift # orchestrates LoRA/QLoRA/full runs (Swift or Py bridge) |
|
133 |
+│ ├── HyperParams.swift |
|
134 |
+│ ├── RunStore.swift # runs, checkpoints, resume, metrics history |
|
135 |
+│ └── MetricsStream.swift # live loss/tok-per-sec/LR parsing |
|
136 |
+├── Convert/ |
|
137 |
+│ ├── ConversionService.swift # HF→MLX convert, quantize, fuse adapters, export |
|
138 |
+│ └── QuantConfig.swift |
|
139 |
+├── Data/ |
|
140 |
+│ ├── DatasetService.swift # import/validate/split JSONL, preview, templating |
|
141 |
+│ └── DatasetFormats.swift |
|
142 |
+├── Hub/ |
|
143 |
+│ ├── HubService.swift # HF search/info/files |
|
144 |
+│ ├── DownloadManager.swift # resumable, progress |
|
145 |
+│ └── ModelStore.swift # local library scan/validate/delete |
|
146 |
+├── PyBridge/ # only if Phase 0.A.6 requires Python for some pipelines |
|
147 |
+│ ├── PythonRunner.swift # Process wrapper over the venv, JSON progress protocol |
|
148 |
+│ └── scripts/ # pinned helper scripts (train.py, convert.py, quantize.py…) |
|
149 |
+├── Services/ |
|
150 |
+│ ├── PersistenceService.swift |
|
151 |
+│ └── Catalog.swift # curated Featured catalog from docs/MODELS.md |
|
152 |
+├── ViewModels/ |
|
153 |
+└── Views/ |
|
154 |
+``` |
|
155 |
+ |
|
156 |
+- **`InferenceEngine` is an actor**, dispatching by `ModelType`. Native Swift MLX for LLM/VLM/embeddings; Py bridge only where Phase 0 proved necessary. |
|
157 |
+- **PHASE GATE:** CLI POC (`ZyquoMLX --infer <model-dir> ...`) runs inference on at least **two model types** (e.g., a small text LLM streaming tokens + an embedding model returning vectors, and a VLM on an image if feasible) with final stats. |
|
158 |
+ |
|
159 |
+--- |
|
160 |
+ |
|
161 |
+## PHASE 3 — TRAINING, QUANTIZATION & CONVERSION (THE FOUNDRY CORE) |
|
162 |
+ |
|
163 |
+Build the full lifecycle. **PHASE GATE:** a real **LoRA fine-tune** completes on a tiny sample dataset, emits live loss, saves an adapter, the adapter fuses into the base, and the adapted model generates visibly different output — all driven from the app. |
|
164 |
+ |
|
165 |
+### 3.A — Datasets (`DatasetService`) |
|
166 |
+- Import JSONL/CSV; validate against MLX's expected formats (chat `{"messages":[…]}` and prompt/completion); auto train/valid split; preview samples with the applied chat template; report token stats and any malformed rows with fixes. |
|
167 |
+ |
|
168 |
+### 3.B — Training (`TrainingService`, `RunStore`, `MetricsStream`) |
|
169 |
+- Configure and launch **LoRA / QLoRA** (and **full** fine-tuning where feasible) with a clear hyperparameter form (rank, alpha, dropout, LR, batch size, iters/epochs, target modules, max seq len, seed), grounded in `docs/TRAINING-RESEARCH.md`. |
|
170 |
+- Runs are **cancellable, resumable background jobs** with persisted state; checkpoints saved on cadence; **live metrics** (train/val loss curves, tokens/sec, LR, ETA) streamed to the UI. |
|
171 |
+- Whether executed natively (Swift MLX) or via the Py bridge, expose a uniform `TrainingRun` API + a clean JSON progress protocol. |
|
172 |
+- `MemoryAdvisor` gates configs that won't fit this Mac's RAM and suggests QLoRA / smaller rank / smaller base. |
|
173 |
+ |
|
174 |
+### 3.C — Quantization, conversion, fusion, export (`ConversionService`) |
|
175 |
+- Convert HF models → MLX format; **quantize** (bits/group size per Phase 0) with size/RAM preview; **fuse** LoRA adapters into base weights; export a ready-to-run MLX model directory (and optionally push/save for use in **Zyquo Local**). |
|
176 |
+- Every conversion/quant job is a tracked, cancellable background job with progress and a clear before/after size + validation step. |
|
177 |
+ |
|
178 |
+--- |
|
179 |
+ |
|
180 |
+## PHASE 4 — DESIGN SYSTEM & UI (LIGHT THEME, PIXEL-PERFECT, "FOUNDRY" IDENTITY) |
|
181 |
+ |
|
182 |
+Same design DNA and `ZyquoTheme` token system as the family, with an **"MLX foundry" identity**: technical, precise, a workbench for pros. Palette is a **molten copper-on-slate** story (forge/foundry) balanced to stay clean and Apple-like. |
|
183 |
+ |
|
184 |
+### 4.1 — Light theme |
|
185 |
+ |
|
186 |
+| Token | Value (light) | Usage | |
|
187 |
+|---|---|---| |
|
188 |
+| `background` | `#FAFAF9` (warm neutral off-white) | Canvas | |
|
189 |
+| `surface` | `#FFFFFF` | Cards, panels | |
|
190 |
+| `surfaceSecondary` | `#F3F2F0` | Hover, code/log blocks | |
|
191 |
+| `accent` | `#C2410C`→`#EA6A2B` (molten copper) paired with slate `#334155` | Primary actions, run/train buttons, active states | |
|
192 |
+| `accentSubtle` | `#FCEDE4` | Selected rows, active-run tint | |
|
193 |
+| `textPrimary` `#1A1A1C` · `textSecondary` `#6B6B72` · `textTertiary` `#9E9EA6` · `border` `#E6E4E1` | | | |
|
194 |
+| `success`/`warning`/`danger` | `#2FA36B`/`#D9822B`/`#D64545` | Job ok / caution / failed | |
|
195 |
+| chart tokens | copper (train loss), slate (val loss), teal (tok/s) | Metric curves | |
|
196 |
+ |
|
197 |
+Family rules apply (no pure black on white, 0.5pt hairlines, ultra-soft shadows on floating panels only, dark theme derived — a deep slate forge feel; **light theme is flagship**). Typography/spacing/radii identical to the family; SF Mono for logs/metrics/code. Data-dense views are allowed to be denser than the chat apps, but must stay clean and aligned. |
|
198 |
+ |
|
199 |
+### 4.2 — Layout & screens (exact spec) |
|
200 |
+ |
|
201 |
+A **workbench with a left navigator** (not a chat-first layout). Default 1360×880, min 1080×700. |
|
202 |
+ |
|
203 |
+- **Left navigator (240pt, translucent):** sections — **Models** (local library + Discover), **Datasets**, **Train** (runs), **Convert** (jobs), **Playground** (inference), **Evaluate**. Footer: settings gear, active-job indicator (spinner + count), current RAM/GPU usage readout. |
|
204 |
+- **Models:** Installed grid/list (name, type badge LLM/VLM/Embed/Speech/Image, params, quant, disk size, RAM verdict for inference & training) + Discover (live Hub search scoped to mlx-community, filters by type/size/quant, resumable downloads with progress). Actions: run in Playground, use as train base, convert/quantize, delete, reveal in Finder. |
|
205 |
+- **Datasets:** import, validate, preview with template applied, split config, token stats; per-dataset detail with sample browser and error report. |
|
206 |
+- **Train:** a **run configurator** (base model picker with RAM gating, method LoRA/QLoRA/Full, dataset picker, hyperparameter form with inline explanations and sane defaults, estimated memory & time) → **Start**. A **run detail** screen with **live loss chart** (train/val), tokens/sec, iteration/ETA, LR schedule, a streaming **log console** (SF Mono), checkpoint list, and Pause/Resume/Cancel. A runs list showing history with status pills. |
|
207 |
+- **Convert:** pick a model → convert to MLX / quantize (bits, group size) / fuse adapter / export; job cards with progress, before/after size, validation result, and "send to Zyquo Local". |
|
208 |
+- **Playground (inference):** load any local model by type and interact — for LLM/VLM a streaming chat with images for VLM; for embeddings a text→vector inspector with similarity demo; for speech a transcription panel; for image-gen a prompt→image panel (only for types MLX supports). Per-run stats (tok/s, TTFT, memory). A **compare** mode to run base vs. fine-tuned side by side. |
|
209 |
+- **Evaluate:** run held-out loss/perplexity and qualitative prompts on base vs. fine-tuned; show a compact scorecard. |
|
210 |
+- **Header (52pt):** contextual to the section; shows active model/run/job chip, memory dot, and quick actions. |
|
211 |
+- **Empty states:** each section has a beautiful, instructive empty state (first model, first dataset, first run) — must look intentional, App-Store-front-page quality. |
|
212 |
+ |
|
213 |
+**Settings** (native tabs, 760×560): 1. **General** (default paths, keep-loaded) 2. **Compute** (GPU cache limit, thread/stream options MLX exposes, memory ceiling) 3. **Python Environment** (venv status/version, reinstall/repair, pinned package versions, offline mode) — only if Py bridge used 4. **Storage** (models/datasets/runs locations, disk usage, cleanup) 5. **Hugging Face** (token, masked) 6. **Appearance** (Light/Dark/System; accent: copper default + slate, sky, emerald, violet; font size) 7. **Shortcuts** 8. **Advanced** (reveal data folder, export logs). |
|
214 |
+ |
|
215 |
+### 4.3 — Motion & 4.4 quality gate |
|
216 |
+Family motion standard; foundry-specific: loss charts animate smoothly as points stream (no reflow jank), log console autoscrolls with a jump-to-bottom pill, job progress never jumps. **Quality gate:** review every state — no models, downloading, loading, inferring, training (with live metrics), paused, resuming, cancelled, failed (OOM → suggest QLoRA/smaller), converting, quantizing, Python env installing/repairing. Consistent tokens, aligned baselines, no clipped logs, correct dark mode, clean scaling. If it looks "developer-made", iterate. |
|
217 |
+ |
|
218 |
+--- |
|
219 |
+ |
|
220 |
+## PHASE 5 — APP ICON: ULTRA-LEGENDARY "FOUNDRY" ICON, DESIGNED IN SVG |
|
221 |
+ |
|
222 |
+Designed in SVG first (`assets/icon/zyquo-mlx.svg`) → `.icns`. Sibling of Cloud/Local/Agent/Atlas: same squircle, same dominant **Z** DNA, same premium quality — telling the **MLX foundry / forge / build** story. Apply the family readability rule: the **Z is the dominant, opaque, highest-contrast focal element (~55%)** with a thin contrasting rim so it never blends into glow. |
|
223 |
+ |
|
224 |
+**Creative direction — the Z that forges.** Two directions (render both, keep the best): |
|
225 |
+1. *Z-anvil/spark:* the bold Z as the hero, with a subtle **forge spark / molten glow** rising behind its lower stroke and a minimal anvil-like base beneath — kept small and dim so the Z dominates. Reads as "where models are forged". |
|
226 |
+2. *Z-core-node:* the Z centered over a subtle **neural/graph node** or layered-tensor motif (thin stacked planes) evoking training/compute — low-contrast backdrop, Z in front. |
|
227 |
+ |
|
228 |
+- **Canvas:** Big Sur squircle (Apple curvature). |
|
229 |
+- **Palette (mirrors the app):** deep slate gradient background (`#1E293B → #0F172A`) with a **molten copper** Z (`#EA6A2B → #C2410C`) carrying a thin bright rim and a restrained glow only at the base (the "molten" hint), so the Z stays razor-sharp and clearly foreground; the supporting motif (spark/anvil or node planes) is a dim copper-slate. Distinct from Cloud (sky), Local (emerald silicon), Agent (violet), Atlas (teal-indigo), yet unmistakably the same family. |
|
230 |
+- **Precision & iteration:** clean paths, `viewBox="0 0 1024 1024"`, optical centering, effects that survive downscaling; render 16→1024, inspect, refine; simplified small-size variant (drop base motif, keep the copper Z) for 16/32px. |
|
231 |
+ |
|
232 |
+**Pipeline (Makefile):** SVG → PNGs (16→1024 incl. `@2x`) via `rsvg-convert` or CoreGraphics rasterizer → `AppIcon.iconset` → `iconutil -c icns`. SVG stays as source of truth. Derive the monochrome menu-bar template glyph and in-app wordmark from the same SVG. |
|
233 |
+ |
|
234 |
+--- |
|
235 |
+ |
|
236 |
+## PHASE 6 — Features (This is where Zyquo MLX becomes LEGENDARY) |
|
237 |
+ |
|
238 |
+### Inference (all types) |
|
239 |
+- Playground for LLM (streaming chat), VLM (image + text), embeddings (vector + similarity), and — where MLX supports it — speech (transcription) and image generation |
|
240 |
+- Per-run stats (tok/s, TTFT, peak memory); base vs. fine-tuned compare; model load/unload with verifiable memory release; `MemoryAdvisor` verdicts everywhere |
|
241 |
+ |
|
242 |
+### Fine-tuning |
|
243 |
+- LoRA / QLoRA / (full where feasible) with a real configurator + inline guidance and RAM gating |
|
244 |
+- Cancellable, **resumable** background training with checkpoints; **live loss/val curves**, tokens/sec, LR, ETA, and a streaming log console |
|
245 |
+- Adapter save + **fuse into base**; export fine-tuned model |
|
246 |
+ |
|
247 |
+### Quantization / conversion / export |
|
248 |
+- HF → MLX conversion; quantize (bits/group size) with size & RAM preview; fuse adapters; validated export; one-click "send to Zyquo Local" |
|
249 |
+ |
|
250 |
+### Data |
|
251 |
+- Dataset import/validate/split/preview with template applied; token stats; malformed-row detection & fixes |
|
252 |
+ |
|
253 |
+### Models & Hub |
|
254 |
+- In-app Hugging Face browse/search (mlx-community + filters) with resumable downloads; local library management; curated Featured catalog |
|
255 |
+ |
|
256 |
+### Evaluation & polish |
|
257 |
+- Held-out loss/perplexity + qualitative eval, base-vs-tuned scorecard |
|
258 |
+- Reused encrypted vault pattern for the HF token; export logs/metrics; per-model & per-run notes |
|
259 |
+- Shortcuts: ⌘N new run, ⌘I open Playground, ⌘L Models, ⌘D Datasets, ⌘R start/stop run, ⌘F search, ⌥Space quick inference; toggleable menu bar extra showing active-job status |
|
260 |
+ |
|
261 |
+--- |
|
262 |
+ |
|
263 |
+## PHASE 7 — VERIFICATION (MANDATORY) |
|
264 |
+ |
|
265 |
+No API keys — verification means proving the **full local MLX lifecycle works end-to-end on this Mac**: |
|
266 |
+ |
|
267 |
+1. **Inference matrix:** download and run at least one real model per supported type that fits this Mac (text LLM streaming; embeddings returning sane vectors; VLM on an image if supported; speech/image-gen if MLX supports them and RAM allows). Verify correct output, streaming, cancellation, and memory release. Record tok/s and TTFT. |
|
268 |
+2. **Training:** run a real **LoRA fine-tune** on a small dataset to completion — verify live metrics, checkpointing, **resume from checkpoint**, adapter save, **fuse**, and that the fused model generates coherently and differently from base. Run a **QLoRA** variant. Confirm OOM configs are blocked/warned by `MemoryAdvisor`. |
|
269 |
+3. **Convert/quantize:** convert an HF model to MLX and quantize it; verify the output loads and runs, with correct before/after sizes. |
|
270 |
+4. **Catalog & Hub:** dry-verify the entire Featured catalog against the live Hub (repo IDs exist, files/sizes match `docs/MODELS.md`). |
|
271 |
+5. **Python env (if used):** verify clean venv bootstrap on a fresh profile, repair flow, pinned versions, and the JSON progress protocol. |
|
272 |
+6. Produce a green results table (capability → model → ✅/❌ → metrics/notes); fix every failure until green. Test artifacts (models/datasets/runs) may be cleaned afterward; keep the smallest for dev. |
|
273 |
+ |
|
274 |
+--- |
|
275 |
+ |
|
276 |
+## PHASE 8 — SIGNING & NOTARIZATION (REAL, NOT AD-HOC) |
|
277 |
+ |
|
278 |
+The user has an existing, working signing/notarization setup for another project. **Before doing anything, read and inspect the folder:** |
|
279 |
+ |
|
280 |
+``` |
|
281 |
+/Users/simon-pierreboucher/Desktop/other/OTHER/zyquo-term |
|
282 |
+``` |
|
283 |
+ |
|
284 |
+Locate the **Developer ID Application identity name**, **Team ID**, **notarytool keychain profile (or Apple ID + app-specific password)**, entitlements, and any config there. **Reuse the exact same identity, Team ID, and notarytool credentials/profile for Zyquo MLX.** Never invent placeholders, never print secrets, never commit them. |
|
285 |
+ |
|
286 |
+Then implement `make release`: |
|
287 |
+1. Build release (arm64 only — MLX), assemble `Zyquo MLX.app` incl. MLX metallibs/resource bundles and any Python bootstrap assets. |
|
288 |
+2. `entitlements.plist` with **Hardened Runtime**; because MLX may JIT/allocate executable Metal/GPU work and (if used) the app spawns a bundled Python via `Process`, verify the minimal correct posture — you will likely need Hardened Runtime plus, if truly required by MLX/Python, `com.apple.security.cs.allow-jit` and/or `com.apple.security.cs.allow-unsigned-executable-memory` and `disable-library-validation` for the Python dylibs. **Test without them first; add only what's proven necessary**, and document why. Do NOT App-Sandbox (this is a local ML workbench needing broad file/compute access) unless the user explicitly asks. |
|
289 |
+3. **Sign nested code first** — this is the classic notarization failure point here: every bundled framework, metallib, and (if bundled) Python interpreter/dylibs/`.so` files must be signed with Hardened Runtime before signing the app. `codesign --force --options runtime --timestamp --entitlements entitlements.plist --sign "Developer ID Application: <identity from zyquo-term>" "Zyquo MLX.app"`. |
|
290 |
+4. `ditto -c -k --keepParent` → `xcrun notarytool submit "Zyquo MLX.zip" --keychain-profile "<profile from zyquo-term>" --wait`. |
|
291 |
+5. `xcrun stapler staple "Zyquo MLX.app"`; verify `spctl -a -vv` = "accepted, source=Notarized Developer ID" and `stapler validate`. |
|
292 |
+6. Optional signed+stapled DMG (`hdiutil`). |
|
293 |
+7. On failure: `notarytool log`, fix (almost always an unsigned nested Python `.so`/dylib or a missing hardened-runtime flag), resubmit until it passes. Keep `make dev` (ad-hoc) for iteration. Note: if a bundled Python environment proves impossible to notarize cleanly, document the fallback (first-run provisioning of the venv into Application Support, outside the signed bundle) chosen in Phase 0.A.6. |
|
294 |
+ |
|
295 |
+--- |
|
296 |
+ |
|
297 |
+## Engineering Standards |
|
298 |
+ |
|
299 |
+- Swift 5.9+ (Swift 6 mode if the toolchain allows); zero warnings |
|
300 |
+- `InferenceEngine` and `TrainingService` as actors; all Hub/config/metrics types `Codable`; jobs are cancellable & resumable with persisted state |
|
301 |
+- If a Py bridge is used, isolate ALL Python interaction behind `PythonRunner` with a strict JSON progress protocol; pin versions; never touch system Python |
|
302 |
+- Robust, human-readable errors for every failure class (OOM during load/train → suggest QLoRA/smaller/quantize, dataset malformed → show row & fix, unsupported architecture, disk full, venv broken → repair flow, download interrupted → resume) |
|
303 |
+- Design tokens only — no hardcoded colors/sizes in views; UI strings centralized |
|
304 |
+- `README.md` (build) + `docs/` (MLX-RESEARCH, TRAINING-RESEARCH, BUILD, MODELS, PLAN); `.gitignore` excludes weights/datasets/checkpoints/venv |
|
305 |
+- Commit in logical, phase-prefixed increments |
|
306 |
+ |
|
307 |
+## Definition of Done |
|
308 |
+ |
|
309 |
+- `make release` produces a **Developer ID–signed, notarized, stapled** `Zyquo MLX.app` (verified by `spctl`), built without the Xcode IDE |
|
310 |
+- Inference works across every MLX-supported model type available today (LLM/VLM/embeddings + speech/image-gen where supported), with streaming and verifiable memory management |
|
311 |
+- Real LoRA/QLoRA fine-tuning runs end-to-end with live metrics, checkpoints, resume, adapter fuse, and export; full fine-tuning where feasible |
|
312 |
+- Conversion + quantization produce valid MLX models; export + "send to Zyquo Local" works |
|
313 |
+- Datasets import/validate/preview correctly; Hub browse + resumable downloads + curated catalog live-verified |
|
314 |
+- `MemoryAdvisor` verdicts are accurate for this machine for both inference and training |
|
315 |
+- The copper-on-slate SVG icon exists, is striking at all sizes with the Z clearly dominant and detached from glow, embedded as `.icns` + template glyph; clearly a sibling of the other Zyquo icons |
|
316 |
+- The copper light theme matches the Phase 4 spec and passes the design quality gate; dark theme derived and correct |
|
317 |
+- Naming coherent everywhere: `Zyquo MLX` user-facing, `com.zyquo.mlx`, `ZyquoMLX` target/data folder |
|
318 |
+- **Every code file starts with the mandatory Author/Mail header** (verified by a repo-wide sweep) |
|
319 |
+- `docs/PLAN.md` shows every phase completed; the Phase 0 research docs are complete and traceable to the implementation |
|
320 |
+- Zyquo MLX feels like a polished, legendary native Mac foundry — the definitive local MLX studio |