Audit Phase C: discovery & metadata depth (semantic metadata, mapping sources, evals)#12
Conversation
Discovery was thin: list_operators emitted param name/type/default/min/max/description but dropped the semantic metadata (semantic_tag/shape/unit/intent + display_hint) that lets an agent pick + wire params by INTENT; list_audio_operators returned only names. Each handler hand-rolled its JSON. - New shared serializer cli/control_json.h (pure, headless-testable): param_to_json / port_to_json / operator_to_json emit the full schema incl. semantic_* + display_hint + enum choices, with optional fields only when set. - list_operators uses it; list_audio_operators now returns the full per-op schema (params + semantic metadata + kind), not just names. MCP docstrings updated to advertise the hints. - test_control_json (headless) covers the serializer. Fixed a latent dangling-pointer bug this exposed: an enum param's choice_labels aliased the member vector of the TEMPORARY op that build_descriptor ran on (ensure_descriptor destroys it), so the cached descriptor's choice_labels dangled. Reading enum choices (which discovery now does) crashed. OpDescriptor now owns copies of the choice-label strings and repoints choice_labels (mirroring the owned display_name/keywords). Verified live: list_operators returns 18 ops incl. Stutter/clock=[Free,External,Metronome]; app stays up. Gate core 33/33. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Discovery could surface semantic metadata (C1) but built-in ops set none, so it returned
empty. Populated a representative set — the two SDK example ops (Drive, SineSynth — the
authoring guide's references, so they now demonstrate the practice), the canonical visual op
(Plasma), and a canonical audio effect (Bitcrush) — with vocabulary-valid semantic_tag/shape/
unit, free-form semantic_intent, descriptions, and display hints (knob).
Verified: startup validation clean (all values in the semantic_vocab); list_operators now
returns e.g. Plasma.hue = {semantic_tag: phase_01, semantic_intent: "color hue", display_hint:
knob}. Gate core 33/33.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Valid bridge sources were docstring-only; an agent had to infer them from list_tracks + a
naming convention. New list_mapping_sources endpoint + MCP tool enumerates every audio
characteristic explicitly — master + each live track (by stable id) × {level, transient, low,
mid, high} — each as a ready-to-use source string with its 0..1 range + a description. Dests
remain the params from list_operators / list_audio_ops (semantic-annotated by C1/C2).
Verified: returns 25 sources for the default 4-track session (master + 4×5); MCP parity 69<->69.
Gate core 33/33.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ring The eval suite only locked 4 visual tasks; the native audio-operator + semantic-intent agent contract was untested. Added 5 CI-gated cases (fake provider + mock transport, run by --selftest): discover_audio_ops, build_audio_chain (set instrument + add effect), set_named_audio_param, install_project_package, and semantic_intent_param (pick a param by its declared INTENT — glow intensity — not by guessing the name). Extended the harness TOOLS + MockTransport with the audio-operator / mapping-source surface so the cases run offline. Selftest: 9/9 (was 4). 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: 8605408d45
ℹ️ 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".
| case VIVID_DISPLAY_HIDDEN: return "hidden"; | ||
| case VIVID_DISPLAY_ADSR: return "adsr"; | ||
| case VIVID_DISPLAY_LFO: return "lfo"; | ||
| default: return "default"; |
There was a problem hiding this comment.
When an operator declares one of the newer valid hints (VIVID_DISPLAY_STEP_SEQ, VIVID_DISPLAY_EDITOR, or VIVID_DISPLAY_TRANSIENT from operator_api/types.h), this serializer emits display_hint: "default" even though param_to_json includes display hints specifically for discovery. In those cases list_operators/list_audio_operators will tell MCP clients that editor/transient params are normal controls, which conflicts with the UI hiding those hints and can cause agents to expose or map the wrong params; add explicit names for all defined hint constants instead of falling through to default.
Useful? React with 👍 / 👎.
Acts on Phase C of
docs/vivid-v4-api-structure-audit.md— discovery & metadata depth (issues #10, #11).Commits
control_json.h:list_operators+list_audio_operatorsnow emit the full schema with semantic metadata (semantic_tag/shape/unit/intent,display_hint, enum choices), not just name/min/max. Fixed a latent dangling-pointer crash it exposed: enumchoice_labelsaliased the temporary opbuild_descriptorran on → dangled; the descriptor cache now owns the choice strings.Plasma.hue = {phase_01, "color hue", knob}).list_mapping_sourcesendpoint + MCP tool: enumerates every valid bridge source (master + per-track × {level,transient,low,mid,high}) with ranges — previously docstring-only.Verification
Gate core 33/33; MCP parity 69↔69; eval
--selftest9/9; startup validation clean; discovery verified live (choices + semantic hints surface, app stays up).🤖 Generated with Claude Code