Audit Phase A: API clarity + agent surface (docs, operator-API, MCP parity)#10
Conversation
…behavior - README.md: rewrite as the current product entrypoint (two-surface DAW + visuals node-graph + mapping bridge, MCP-native, running today). Stop framing Session View as a future proof target — it's the shipped DAW surface. Point to CLAUDE.md / app/ARCHITECTURE.md / the ADRs for current truth; mark the pre-runtime planning artifacts as historical. - app/README.md: correct the stale foreground/background note. VERIFIED LIVE (Finder frontmost, vivid backgrounded): the control server keeps draining and beats keep advancing — the outer loop ticks directly (macOS doesn't fire run-loop timers for a background app) + App Nap is disabled. The old note claiming the server "stops draining" backgrounded was wrong; `surface texture unavailable` is a benign render skip. - docs/experiments/README.md: mark the Session-View prototype folder historical (the model it proved is now shipped in app/). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The public operator-API headers carried stale lane→value migration self-descriptions that
were flatly wrong about the live state. Fixed the contradictions + moved the ABI history out.
- types.h: move the v4→v11 ABI changelog OUT of the #define into
docs/operator-api/abi-changelog.md; leave a one-line pointer. Rewrite the port
value_type/multiplicity comment ("additive... live path until Phase 7") to the live
contract (it IS the arity declaration). Drop the "Phase 4/5a; additive" framing on the
context values[]/value_outputs blocks. Clean the include comments.
- value_model.h: the header claimed it was "INERT: nothing #includes it yet... runtime still
uses the lane API" — false (types.h + value_view.h include it; it's the ABI multiplicity
authority). Rewrote the top block + the stale "Phase 1 bumps from 5" note.
- value_view.h: claimed the contexts "do not expose a values[] array yet — Phase 4" — false
(VividFrameContext/VividAudioContext expose values/value_outputs today). Rewrote to the
live contract.
- Added docs/operator-api/{README,abi-changelog}.md (current-ABI reference + the history).
No behavior change (comments + docs only). Full build green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Public headers (the agent-facing C API + operator-API + UI headers) read like internal phase archaeology. Replaced ~47 phase-label prefixes in doc comments (P10/P14/P15/P18/P22/ P23/P24/P27/P28/M4/M6/M6.5/A0/A1/A2/A5/A6/AO-1/AO-4/AG-0/AG-1/P4.4/M0/M2-followup) with behavior-first descriptions. vst3_host.h (the session C API, 13 sites) done by hand; the remaining 34 across operator_api/audio/ui headers via an exact-match sweep. Kept ADR references (they name live decisions, not phases). Comment-only; full build green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Native audio-operator workflows existed on the control server but had no MCP tools, so agents
couldn't reach them. Closed the gap + guarded it, and unified operator discovery.
- MCP tools (mcp/vivid_mcp.py): expose the 12 missing control methods —
list_audio_ops, set_track_audio_instrument, add_audio_effect, remove_audio_effect,
set_audio_op_param, slice_to_midi, arm_track, note_on, note_off, record, metronome,
set_clip_loop. Plus a new list_audio_operators discovery tool.
- Discovery (control_server.cpp): new list_audio_operators handler returning
{instruments, effects} from session_available_audio_op_count/name — the audio peer of
list_operators (which is visual-only). Exposed as an MCP tool so agents discover native
audio ops the same way as visual ones.
- Parity guard (mcp/tests/test_mcp_parity.py): a static, server-free test that diffs the
control handlers vs the bridge's _post calls in BOTH directions — fails on a control
method with no MCP tool (unless allowlisted, e.g. set_playing -> play/stop) and on an MCP
tool calling a nonexistent method. Wired into version-guard CI (ubuntu+uv, every PR).
Parity now 68 handlers <-> 68 tools (1 intentionally unexposed). Verified live via the
control endpoints: list_audio_operators returns the catalog; an agent can build
Sampler -> Bitcrush -> Stutter, set params, and inspect via list_audio_ops + get_audio_graph.
Gate core 30/30.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Production gate (core): ✅ PASS
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 16103c3289
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| """Slice an audio clip into a new MIDI track driven by a native Sampler loaded with the | ||
| clip's slices (ascending pitches from C1 trigger successive slices). slice_mode: 1 = | ||
| transients, 3 = 16-step grid. Returns the new track index.""" | ||
| return _post("slice_to_midi", {"track": track, "scene": scene, "slice_mode": slice_mode}) |
There was a problem hiding this comment.
Send the slice mode under the server’s expected key
When an MCP client calls slice_to_midi(..., slice_mode=3) for the documented 16-step grid, this wrapper posts slice_mode, but the control handler reads b.value("mode", 1) in app/src/cli/control_server.cpp, so the requested/default grid mode is ignored and every MCP call falls back to transient slicing. Please send the field as mode (or update the handler) so agents can select the intended slicing mode.
Useful? React with 👍 / 👎.
Acts on Phase A of
docs/vivid-v4-api-structure-audit.md— the clarity + agent-surface tranche (audit issues #1, #2, #12, #3, #6). Each finding was verified against current code first.Commits
README.mdrewritten as the current two-surface + bridge entrypoint (Session View is shipped, not a future target);app/README.mdcorrected (the control server keeps draining while backgrounded — verified live: Finder frontmost, beats advancing, server responding); experiments marked historical.types.hintodocs/operator-api/abi-changelog.md; fixed the false self-descriptions invalue_model.h("nothing #includes it" — two headers do) andvalue_view.h("contexts don't exposevalues[]" — they do).P##/M#/AO-#/AG-#prefixes from public headers (comment-only; build green).list_audio_operatorscatalog (the audio peer oflist_operators); added a static bidirectional parity test (mcp/tests/test_mcp_parity.py, wired into CI) so the surfaces can't drift. Parity now 68 ↔ 68.Verification
Sampler → Bitcrush → Stutter, set params, and inspect vialist_audio_ops+get_audio_graph— entirely over MCP.Phases B–D (SDK examples/validation/authoring guide; discovery-metadata depth; the
input.cpp/control_server.cpprefactors) are scoped in the plan and deferred.🤖 Generated with Claude Code