- [x]**Map the mlx-c API surface** — Read all 27 headers. Full map in FINDINGS.md: ~180 ops functions, Go binds ~40. Identified 8 high-priority unbound functions. *(Done 2026-02-19)*
- [x]**Understand the error model** — Free-form strings only (`"<msg> at <file>:<line>"`). No error codes or categories. Handler stores string, Go checks return code. Details in FINDINGS.md. *(Done 2026-02-19)*
- [x]**Check memory management patterns** — Arrays are refcounted via `shared_ptr<ArrayDesc>`. Double-free is UB. Free during async is safe. NULL-free is safe. Details in FINDINGS.md. *(Done 2026-02-19)*
- [x]**Find `mlx_contiguous` or equivalent** — **FOUND**: `mlx_contiguous(res, a, allow_col_major, stream)` at `ops.h:220`. Plus `_mlx_array_is_row_contiguous()` for checking. GoLand Claude: see FINDINGS.md for recommended pattern. *(Done 2026-02-19)*
- [x]**Verify `mlx_array_data_*` eval semantics** — Does NOT auto-evaluate. Returns raw buffer pointer (crash/garbage if unevaluated). `Materialise()` before data access is essential. `item()` auto-evaluates but `data()` does not. *(Done 2026-02-19)*
- [x]**Check if `mlx_cumsum` exists** — **FOUND**: `mlx_cumsum(res, a, axis, reverse, inclusive, stream)` at `ops.h:344`. GoLand Claude can now implement proper TopP sampling. *(Done 2026-02-19)*
- [x]**Survey `mlx_contiguous` / `mlx_flatten` / `mlx_copy`** — All three exist. `mlx_contiguous` is the correct tool (forces row-major). `mlx_copy` may preserve non-contiguous layout. `mlx_flatten` works but changes shape semantics. *(Done 2026-02-19)*
- [x]**What does `mlx_clear_cache()` release?** — Releases allocator pool cache back to system. Does NOT touch active memory. Safe mid-generation. *(Done 2026-02-19)*
- [x]**Is `mlx_array_free()` safe on graph-referenced arrays?** — Yes, safe. Arrays use `shared_ptr<ArrayDesc>`. Freeing the C handle just decrements refcount. Graph computation continues normally. *(Done 2026-02-19)*
- [x]**MLX allocator pool behaviour** — `mlx_array_free()` returns memory to internal pool (not system). Pool reuses allocations. Under sustained inference, memory should plateau. Call `mlx_clear_cache()` to release pool to system if needed. *(Done 2026-02-19)*
- [x]**Research structured error info** — No structured info available. Free-form string only. Format is stable: `"<message> at <file>:<line>"`. GoLand Claude should use return code (0/1) + stored error string pattern. *(Done 2026-02-19)*
- [ ]**API gap analysis** — When the GoLand Claude needs a C function that isn't exposed by mlx-c, document the gap here and research if upstream mlx-c supports it or if a patch is needed.
---
## Workflow
1. GoLand Claude or Virgil writes tasks here
2. Pick up in order, mark `[x]` when done
3. New findings → `cpp/FINDINGS.md`
4. If Go changes needed → note in FINDINGS.md for GoLand Claude