# Map: prompt-to-chain in the plugin · Issue \#1 · flambo/semantifx

[View on GitCafe](https://git.cafe/flambo/semantifx/issues/1)

Repository: [flambo/semantifx](https://git.cafe/flambo/semantifx)

Visibility: public

State: backlog

Priority: 0

## Description

[Discussion and activity](https://git.cafe/flambo/semantifx/issues/1)

---

## Destination

A hand-off-ready spec for prompt-to-chain in the SemantiFX plugin: the user types a target prompt, the Python worker assembles an effect chain with TypeSafe Jev from a catalogue that has grown past EQ and distortion, the plugin shows the chain and optimizes it eagerly while the user can still edit it, and the optimizer runs any chain the catalogue can express. Every decision needed to start building is locked; building itself is a later effort.

## Notes

- Domain vocabulary is in `CONTEXT.md`. Chain assembly (which effects, how many, what order) is distinct from chain optimization (parameters of a fixed chain). Use those terms.
- Skills: `grilling` + `domain-modeling` for decision tickets; `research` for anything outside the repo; `prototype` for state-model or UX questions. Anything verifiable gets built by a Luna subagent from a written spec.
- Settled before charting (2026-09-16), not re-litigated here:
  - Jev is the assembly planner. Benchmark write-up: `docs/experiments/2026-09-16-jev-planner-benchmark.md`. Keep policy and thresholds in code; rich two-sentence effect descriptions in state; no persona text; question wording is a threshold knob, not an accuracy lever.
  - A CLAP-derived text description of the source audio is dropped. Measured on 2026-09-16: swapping the source string between guitar, vocal, and mix changed no chain and moved probabilities by a few hundredths. Revisit only if the catalogue gains source-dependent effects.
  - Jev calls run in the Python worker, not the plugin. The key stays out of the plugin.
  - UX flow: assemble, show, optimize eagerly; the user can edit the chain during optimization and the optimizer restarts.
  - Optimizer generalization is in scope: it must run whatever chain assembly produces.
- Every new effect type needs a differentiable Python implementation for the optimizer and a matching C++ implementation in the plugin, with parity tests. That constraint shapes the catalogue.
- Solo repo, work on `main`, no PRs. Current prototype: `inference/src/semantifx_inference/assembly.py` and `inference/diagnostics/jev_chain_assembly.py`.
- Standing preference (Oliver, 2026-09-16): the agent decides internals (protocol shapes, code generation, validation, initialization, transport) and records them on the ticket without a grill. Oliver is asked only about user interaction and high-level architecture. Tickets whose question is internal are worked by the agent alone; prototypes are built by Luna from a spec and only their outcome is reported. Goal is a working prototype, not a fully locked spec.

## Decisions so far

- [Research: differentiable effects available to the optimizer and their C++ tractability](https://github.com/flamboh/semantifx/issues/2) — only compressor and reverb are new differentiable candidates (plus trivial gain); dasp compressor ignores release and NaNs at zero knee, EQ has zero cutoff/Q gradient at 0 dB, reverb needs a frozen noise table for C++ parity; recommended order gain, compressor, reverb. Findings on `research/differentiable-effects`.
- [Research: TypeSafe Jev limits, pricing, and key distribution constraints](https://github.com/flamboh/semantifx/issues/3) — cost is negligible, but the only credential is a full-account key, access is waitlisted, limits are unpublished; developer-only now, proxy is the only future distribution path. Findings on `research/typesafe-limits`.
- [Which effect types join the catalogue, and in what order](https://github.com/flamboh/semantifx/issues/6) — catalogue is EQ, distortion, compressor, reverb; reverb first, then compressor; gain out. Compressor is dasp's design trimmed (no release, knee floored above zero); reverb uses a macro parameter layer over dasp's 25. Jev descriptions for both are on the ticket.
- [Prototype: build the optimizer's DSP graph from an arbitrary chain list](https://github.com/flamboh/semantifx/issues/4) — one type-keyed catalogue (specs, Jev description, render fn) replaces the instance-keyed schema; `instance_id` is opaque to the worker and `effect_type` selects the definition; result entries follow chain order. Fixed pair renders bit-identically. Prototype on `prototype/variable-chain-optimizer`.
- [Protocol: the assemble request and variable chains end to end](https://github.com/flamboh/semantifx/issues/7) — separate `assemble` request returning a chain in the analyze chain shape plus judgments; analyze validates any catalogue chain (unique ids, known type, complete in-range parameters, 0 to 8 long) under one `invalid_request` code; specs reach the plugin via a type-keyed `scripts/gen`; restart is latest-request-wins with the stop marker kept for plain cancel.
- [Key handling: developer-only behind a swappable transport for this spec](https://github.com/flamboh/semantifx/issues/9) — developer-only, key from `.env` read by the worker; one `Planner` protocol with Jev and mock implementations, a proxy later is a third; any failure is `assembly_unavailable`, the plugin keeps its chain and shows the message, no silent default chain.
- [Parameter initialization for newly assembled effect instances](https://github.com/flamboh/semantifx/issues/11) — new instances start from TOML defaults (gradient hazards handled in the defaults: flat EQ moves gain first, compressor knee default sits above its floor); surviving instances keep current values via `init: current`, which makes restart a warm start.
- [Assembly policy: what the plugin does on a no-change verdict](https://github.com/flamboh/semantifx/issues/5) — on a no-change verdict the plugin keeps the current chain and shows a one-line hint, no optimization starts; confidence is not shown in the first prototype, probabilities go to the debug log; threshold 0.4 with argmax fallback, gate 0.5, ties by catalogue order, no current-chain state to Jev in single-shot mode.
- [Plugin: representing, rendering, and editing a variable chain](https://github.com/flamboh/semantifx/issues/8) — fixed pool of two slots per type with chain composition as saved state, not host parameters; one C++ class per type behind a hand-written factory; audio-level parity fixtures rendered from Python; Ozone-style scrollable card rack with bypass, solo, remove, drag and a + card; structure edits restart now, knobs on release; snapshots are audible as they arrive; Stop keeps, Revert restores the pre-run state; fresh instance starts empty.
- Cut 2026-09-17 (Oliver: cut further): assembly policy (#5) shrunk to one user-facing question, threshold and tie-break and single-shot state decided by the agent on the ticket; the reverb (#10) and compressor (#12) prototypes closed into the build effort.

## Not yet specified

- Nothing. Every ticket is closed as of 2026-09-18; the way to the destination is clear and the next step is the build effort, starting from Decisions so far. First build task: record the slot-pool choice from #8 as the first ADR under `docs/adr/`.

## Out of scope

- **Reverb and compressor DSP prototypes as map tickets.** Cut 2026-09-17; Luna builds both during the build effort from a spec with parity tests as the acceptance check.
- **Threshold calibration and end-to-end evaluation.** Build-time work once the four-type catalogue runs live, not a spec decision; calibration note lives on #5.
- **Multi-turn refinement** (InstructFX2FX's init/reuse/mixed routing). A second map once single-shot prompt-to-chain works.
- **Distortion DSP quality.** Orthogonal to assembly; track separately.
- **CLAP-derived source description as Jev state.** Dropped 2026-09-16 on measurement, see Notes.
- **Replacing Jev with a custom on-device classifier.** Only worth revisiting once there is training data from real use.









