livepilot 1.26.0 → 1.26.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +41 -0
- package/README.md +1 -1
- package/installer/codex.js +87 -9
- package/livepilot/.Codex-plugin/plugin.json +8 -0
- package/livepilot/.claude-plugin/plugin.json +8 -0
- package/livepilot/.mcp.json +8 -0
- package/livepilot/agents/livepilot-producer/AGENT.md +314 -0
- package/livepilot/commands/arrange.md +47 -0
- package/livepilot/commands/beat.md +81 -0
- package/livepilot/commands/evaluate.md +51 -0
- package/livepilot/commands/memory.md +22 -0
- package/livepilot/commands/mix.md +47 -0
- package/livepilot/commands/perform.md +42 -0
- package/livepilot/commands/session.md +13 -0
- package/livepilot/commands/sounddesign.md +58 -0
- package/livepilot/rubrics/default_preset_check.md +82 -0
- package/livepilot/rubrics/layer_accumulation.md +79 -0
- package/livepilot/rubrics/layer_precision.md +79 -0
- package/livepilot/rubrics/modulation_presence.md +63 -0
- package/livepilot/rubrics/sound_design_depth.md +40 -0
- package/livepilot/skills/livepilot-arrangement/SKILL.md +164 -0
- package/livepilot/skills/livepilot-composition-engine/SKILL.md +151 -0
- package/livepilot/skills/livepilot-composition-engine/references/form-patterns.md +97 -0
- package/livepilot/skills/livepilot-composition-engine/references/transition-archetypes.md +102 -0
- package/livepilot/skills/livepilot-core/SKILL.md +261 -0
- package/livepilot/skills/livepilot-core/references/ableton-workflow-patterns.md +831 -0
- package/livepilot/skills/livepilot-core/references/affordances/_schema.md +160 -0
- package/livepilot/skills/livepilot-core/references/affordances/devices/auto-filter.yaml +133 -0
- package/livepilot/skills/livepilot-core/references/affordances/devices/chorus-ensemble.yaml +91 -0
- package/livepilot/skills/livepilot-core/references/affordances/devices/compressor.yaml +98 -0
- package/livepilot/skills/livepilot-core/references/affordances/devices/convolution-reverb.yaml +113 -0
- package/livepilot/skills/livepilot-core/references/affordances/devices/corpus.yaml +84 -0
- package/livepilot/skills/livepilot-core/references/affordances/devices/drift.yaml +105 -0
- package/livepilot/skills/livepilot-core/references/affordances/devices/echo.yaml +108 -0
- package/livepilot/skills/livepilot-core/references/affordances/devices/eq-eight.yaml +95 -0
- package/livepilot/skills/livepilot-core/references/affordances/devices/glue-compressor.yaml +88 -0
- package/livepilot/skills/livepilot-core/references/affordances/devices/granulator-iii.yaml +104 -0
- package/livepilot/skills/livepilot-core/references/affordances/devices/hybrid-reverb.yaml +83 -0
- package/livepilot/skills/livepilot-core/references/affordances/devices/operator.yaml +98 -0
- package/livepilot/skills/livepilot-core/references/affordances/devices/ping-pong-delay.yaml +104 -0
- package/livepilot/skills/livepilot-core/references/affordances/devices/poli.yaml +98 -0
- package/livepilot/skills/livepilot-core/references/affordances/devices/saturator.yaml +98 -0
- package/livepilot/skills/livepilot-core/references/affordances/devices/shifter.yaml +77 -0
- package/livepilot/skills/livepilot-core/references/affordances/devices/simpler.yaml +113 -0
- package/livepilot/skills/livepilot-core/references/affordances/devices/utility.yaml +95 -0
- package/livepilot/skills/livepilot-core/references/affordances/devices/vinyl-distortion.yaml +92 -0
- package/livepilot/skills/livepilot-core/references/affordances/devices/wavetable.yaml +98 -0
- package/livepilot/skills/livepilot-core/references/artist-vocabularies.md +389 -0
- package/livepilot/skills/livepilot-core/references/automation-atlas.md +272 -0
- package/livepilot/skills/livepilot-core/references/concepts/_schema.md +158 -0
- package/livepilot/skills/livepilot-core/references/concepts/artists/akufen.yaml +116 -0
- package/livepilot/skills/livepilot-core/references/concepts/artists/aphex-twin.yaml +133 -0
- package/livepilot/skills/livepilot-core/references/concepts/artists/arca-sophie.yaml +131 -0
- package/livepilot/skills/livepilot-core/references/concepts/artists/autechre.yaml +130 -0
- package/livepilot/skills/livepilot-core/references/concepts/artists/basic-channel.yaml +140 -0
- package/livepilot/skills/livepilot-core/references/concepts/artists/basinski.yaml +126 -0
- package/livepilot/skills/livepilot-core/references/concepts/artists/boards-of-canada.yaml +124 -0
- package/livepilot/skills/livepilot-core/references/concepts/artists/burial.yaml +127 -0
- package/livepilot/skills/livepilot-core/references/concepts/artists/com-truise-tycho.yaml +121 -0
- package/livepilot/skills/livepilot-core/references/concepts/artists/daft-punk.yaml +117 -0
- package/livepilot/skills/livepilot-core/references/concepts/artists/dj-premier-rza.yaml +119 -0
- package/livepilot/skills/livepilot-core/references/concepts/artists/gas.yaml +134 -0
- package/livepilot/skills/livepilot-core/references/concepts/artists/hawtin.yaml +127 -0
- package/livepilot/skills/livepilot-core/references/concepts/artists/isolee-luomo.yaml +130 -0
- package/livepilot/skills/livepilot-core/references/concepts/artists/j-dilla.yaml +133 -0
- package/livepilot/skills/livepilot-core/references/concepts/artists/jeff-mills.yaml +120 -0
- package/livepilot/skills/livepilot-core/references/concepts/artists/johannsson-richter.yaml +132 -0
- package/livepilot/skills/livepilot-core/references/concepts/artists/madlib.yaml +124 -0
- package/livepilot/skills/livepilot-core/references/concepts/artists/moodymann-theo-parrish.yaml +121 -0
- package/livepilot/skills/livepilot-core/references/concepts/artists/oneohtrix-point-never.yaml +126 -0
- package/livepilot/skills/livepilot-core/references/concepts/artists/photek-source-direct.yaml +120 -0
- package/livepilot/skills/livepilot-core/references/concepts/artists/rashad-spinn-traxman.yaml +122 -0
- package/livepilot/skills/livepilot-core/references/concepts/artists/robert-henke.yaml +113 -0
- package/livepilot/skills/livepilot-core/references/concepts/artists/shackleton.yaml +124 -0
- package/livepilot/skills/livepilot-core/references/concepts/artists/skream-mala.yaml +119 -0
- package/livepilot/skills/livepilot-core/references/concepts/artists/stars-of-the-lid.yaml +119 -0
- package/livepilot/skills/livepilot-core/references/concepts/artists/tim-hecker.yaml +122 -0
- package/livepilot/skills/livepilot-core/references/concepts/artists/villalobos.yaml +135 -0
- package/livepilot/skills/livepilot-core/references/concepts/genres/ambient.yaml +137 -0
- package/livepilot/skills/livepilot-core/references/concepts/genres/boom_bap.yaml +124 -0
- package/livepilot/skills/livepilot-core/references/concepts/genres/deep-minimal.yaml +130 -0
- package/livepilot/skills/livepilot-core/references/concepts/genres/deep_house.yaml +130 -0
- package/livepilot/skills/livepilot-core/references/concepts/genres/detroit_techno.yaml +116 -0
- package/livepilot/skills/livepilot-core/references/concepts/genres/disco.yaml +123 -0
- package/livepilot/skills/livepilot-core/references/concepts/genres/downtempo.yaml +129 -0
- package/livepilot/skills/livepilot-core/references/concepts/genres/drone.yaml +133 -0
- package/livepilot/skills/livepilot-core/references/concepts/genres/drum-and-bass.yaml +119 -0
- package/livepilot/skills/livepilot-core/references/concepts/genres/dub-techno.yaml +132 -0
- package/livepilot/skills/livepilot-core/references/concepts/genres/dub.yaml +129 -0
- package/livepilot/skills/livepilot-core/references/concepts/genres/dubstep.yaml +120 -0
- package/livepilot/skills/livepilot-core/references/concepts/genres/experimental.yaml +136 -0
- package/livepilot/skills/livepilot-core/references/concepts/genres/footwork.yaml +119 -0
- package/livepilot/skills/livepilot-core/references/concepts/genres/hip-hop.yaml +132 -0
- package/livepilot/skills/livepilot-core/references/concepts/genres/house.yaml +126 -0
- package/livepilot/skills/livepilot-core/references/concepts/genres/hyperpop.yaml +128 -0
- package/livepilot/skills/livepilot-core/references/concepts/genres/idm.yaml +134 -0
- package/livepilot/skills/livepilot-core/references/concepts/genres/lo_fi.yaml +129 -0
- package/livepilot/skills/livepilot-core/references/concepts/genres/microhouse.yaml +138 -0
- package/livepilot/skills/livepilot-core/references/concepts/genres/minimal-techno.yaml +116 -0
- package/livepilot/skills/livepilot-core/references/concepts/genres/modern-classical.yaml +123 -0
- package/livepilot/skills/livepilot-core/references/concepts/genres/soul.yaml +125 -0
- package/livepilot/skills/livepilot-core/references/concepts/genres/synthwave.yaml +123 -0
- package/livepilot/skills/livepilot-core/references/concepts/genres/techno.yaml +123 -0
- package/livepilot/skills/livepilot-core/references/concepts/genres/trap.yaml +120 -0
- package/livepilot/skills/livepilot-core/references/concepts/genres/uk-garage.yaml +121 -0
- package/livepilot/skills/livepilot-core/references/device-atlas/00-index.md +110 -0
- package/livepilot/skills/livepilot-core/references/device-atlas/distortion-and-character.md +687 -0
- package/livepilot/skills/livepilot-core/references/device-atlas/drums-and-percussion.md +753 -0
- package/livepilot/skills/livepilot-core/references/device-atlas/dynamics-and-punch.md +525 -0
- package/livepilot/skills/livepilot-core/references/device-atlas/eq-and-filtering.md +402 -0
- package/livepilot/skills/livepilot-core/references/device-atlas/midi-tools.md +963 -0
- package/livepilot/skills/livepilot-core/references/device-atlas/movement-and-modulation.md +874 -0
- package/livepilot/skills/livepilot-core/references/device-atlas/space-and-depth.md +571 -0
- package/livepilot/skills/livepilot-core/references/device-atlas/spectral-and-weird.md +714 -0
- package/livepilot/skills/livepilot-core/references/device-atlas/synths-native.md +953 -0
- package/livepilot/skills/livepilot-core/references/device-knowledge/00-index.md +34 -0
- package/livepilot/skills/livepilot-core/references/device-knowledge/automation-as-music.md +204 -0
- package/livepilot/skills/livepilot-core/references/device-knowledge/chains-genre.md +173 -0
- package/livepilot/skills/livepilot-core/references/device-knowledge/creative-thinking.md +211 -0
- package/livepilot/skills/livepilot-core/references/device-knowledge/effects-distortion.md +188 -0
- package/livepilot/skills/livepilot-core/references/device-knowledge/effects-space.md +162 -0
- package/livepilot/skills/livepilot-core/references/device-knowledge/effects-spectral.md +229 -0
- package/livepilot/skills/livepilot-core/references/device-knowledge/instruments-synths.md +243 -0
- package/livepilot/skills/livepilot-core/references/genre-vocabularies.md +382 -0
- package/livepilot/skills/livepilot-core/references/m4l-devices.md +352 -0
- package/livepilot/skills/livepilot-core/references/memory-guide.md +178 -0
- package/livepilot/skills/livepilot-core/references/midi-recipes.md +402 -0
- package/livepilot/skills/livepilot-core/references/mixing-patterns.md +578 -0
- package/livepilot/skills/livepilot-core/references/overview.md +300 -0
- package/livepilot/skills/livepilot-core/references/pack-knowledge.md +319 -0
- package/livepilot/skills/livepilot-core/references/sample-manipulation.md +724 -0
- package/livepilot/skills/livepilot-core/references/sound-design-deep.md +140 -0
- package/livepilot/skills/livepilot-core/references/sound-design.md +393 -0
- package/livepilot/skills/livepilot-corpus-builder/SKILL.md +379 -0
- package/livepilot/skills/livepilot-creative-director/SKILL.md +462 -0
- package/livepilot/skills/livepilot-creative-director/references/anti-repetition-rules.md +214 -0
- package/livepilot/skills/livepilot-creative-director/references/creative-brief-template.md +222 -0
- package/livepilot/skills/livepilot-creative-director/references/hybrid-compilation.md +185 -0
- package/livepilot/skills/livepilot-creative-director/references/move-family-diversity-rule.md +258 -0
- package/livepilot/skills/livepilot-creative-director/references/phase-6-execution.md +409 -0
- package/livepilot/skills/livepilot-creative-director/references/the-four-move-rule.md +192 -0
- package/livepilot/skills/livepilot-devices/SKILL.md +213 -0
- package/livepilot/skills/livepilot-devices/references/load_browser_item-uri-grammar.md +82 -0
- package/livepilot/skills/livepilot-evaluation/SKILL.md +195 -0
- package/livepilot/skills/livepilot-evaluation/references/capability-modes.md +176 -0
- package/livepilot/skills/livepilot-evaluation/references/evaluation-contracts.md +121 -0
- package/livepilot/skills/livepilot-evaluation/references/memory-promotion.md +110 -0
- package/livepilot/skills/livepilot-mix-engine/SKILL.md +144 -0
- package/livepilot/skills/livepilot-mix-engine/references/mix-critics.md +143 -0
- package/livepilot/skills/livepilot-mix-engine/references/mix-moves.md +105 -0
- package/livepilot/skills/livepilot-mixing/SKILL.md +164 -0
- package/livepilot/skills/livepilot-notes/SKILL.md +130 -0
- package/livepilot/skills/livepilot-performance-engine/SKILL.md +122 -0
- package/livepilot/skills/livepilot-performance-engine/references/performance-safety.md +98 -0
- package/livepilot/skills/livepilot-release/SKILL.md +151 -0
- package/livepilot/skills/livepilot-sample-engine/SKILL.md +117 -0
- package/livepilot/skills/livepilot-sample-engine/references/sample-critics.md +87 -0
- package/livepilot/skills/livepilot-sample-engine/references/sample-philosophy.md +51 -0
- package/livepilot/skills/livepilot-sample-engine/references/sample-techniques.md +131 -0
- package/livepilot/skills/livepilot-sound-design-engine/SKILL.md +247 -0
- package/livepilot/skills/livepilot-sound-design-engine/references/patch-model.md +119 -0
- package/livepilot/skills/livepilot-sound-design-engine/references/sound-design-critics.md +118 -0
- package/livepilot/skills/livepilot-wonder/SKILL.md +143 -0
- package/m4l_device/LivePilot_Analyzer.amxd +0 -0
- package/m4l_device/LivePilot_Elektron.amxd +0 -0
- package/m4l_device/LivePilot_Elektron.maxpat +758 -0
- package/m4l_device/livepilot_bridge.js +1 -1
- package/m4l_device/livepilot_elektron_bridge.js +82 -0
- package/mcp_server/__init__.py +1 -1
- package/mcp_server/composer/develop/apply.py +1 -1
- package/mcp_server/composer/full/apply.py +32 -6
- package/mcp_server/composer/full/brief_builder.py +9 -0
- package/mcp_server/evaluation/feature_extractors.py +152 -8
- package/mcp_server/m4l_bridge.py +5 -0
- package/mcp_server/mix_engine/state_builder.py +19 -2
- package/mcp_server/mix_engine/tools.py +22 -0
- package/mcp_server/runtime/execution_router.py +6 -0
- package/mcp_server/runtime/mcp_dispatch.py +18 -0
- package/mcp_server/runtime/remote_commands.py +2 -0
- package/mcp_server/server.py +11 -7
- package/mcp_server/sound_design/tools.py +33 -0
- package/mcp_server/tools/_agent_os_engine/evaluation.py +7 -44
- package/mcp_server/tools/_agent_os_engine/models.py +2 -1
- package/mcp_server/tools/_conductor.py +5 -2
- package/mcp_server/tools/_evaluation_contracts.py +1 -1
- package/mcp_server/tools/_snapshot_normalizer.py +32 -3
- package/package.json +20 -5
- package/remote_script/LivePilot/__init__.py +1 -1
- package/remote_script/LivePilot/server.py +63 -2
- package/requirements.txt +3 -3
- package/server.json +3 -3
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
# Move-Family Diversity Rule
|
|
2
|
+
|
|
3
|
+
The single mechanical rule that prevents pattern-repetition: when the
|
|
4
|
+
director generates three plans, their DOMINANT moves must come from
|
|
5
|
+
three DIFFERENT `move.family` values.
|
|
6
|
+
|
|
7
|
+
This is not taste. This is a structural constraint enforced before
|
|
8
|
+
preview or ranking.
|
|
9
|
+
|
|
10
|
+
## Family vs. dimension — two different axes
|
|
11
|
+
|
|
12
|
+
The director reasons on two orthogonal axes:
|
|
13
|
+
|
|
14
|
+
- **`move.family`** — WHERE in the semantic_moves registry the dominant
|
|
15
|
+
move lives. Six stable values, code-enforced. This is what the
|
|
16
|
+
diversity rule operates on.
|
|
17
|
+
- **`dimension`** — WHAT kind of musical consequence the plan has.
|
|
18
|
+
Four values: structural / rhythmic / timbral / spatial. This is what
|
|
19
|
+
the four-move rule operates on.
|
|
20
|
+
|
|
21
|
+
A rhythmic plan has a rhythmic DIMENSION but its FAMILY is typically
|
|
22
|
+
`arrangement` (clip-level pattern change) or `sound_design` (per-hit
|
|
23
|
+
timbre variation that changes feel). That is **not** a fudge — it is
|
|
24
|
+
the correct taxonomy, because rhythmic work in Ableton happens via
|
|
25
|
+
note editing + grooves, which are tooled through those families. Tag
|
|
26
|
+
such a seed with `dimension_hint: "rhythmic"` so downstream evaluation
|
|
27
|
+
knows what dimension was touched.
|
|
28
|
+
|
|
29
|
+
## The seven canonical families
|
|
30
|
+
|
|
31
|
+
Source of truth: the semantic-move registry, populated by both
|
|
32
|
+
`mcp_server/semantic_moves/*.py` AND `mcp_server/sample_engine/moves.py`.
|
|
33
|
+
Never invent an eighth family at the director level.
|
|
34
|
+
|
|
35
|
+
| Family | What it covers | Typical moves | Maps to dimension |
|
|
36
|
+
|---|---|---|---|
|
|
37
|
+
| `mix` | Level / EQ / dynamics / space-via-send / stereo | `tighten_low_end`, `widen_stereo`, `make_punchier`, `darken_without_losing_width`, `reduce_repetition_fatigue`, `make_kick_bass_lock`, `reduce_foreground_competition` | spatial (usually) |
|
|
38
|
+
| `arrangement` | Section-level structure, clip density, and clip-level rhythmic edits | `refresh_repeated_section`, plus structural moves in `mix_moves.py`. Rhythmic plans that edit notes / grooves / motifs sit here via `dimension_hint: "rhythmic"`. | structural — or rhythmic with dimension_hint |
|
|
39
|
+
| `transition` | Between-section energy and motion | `create_buildup_tension`, `smooth_scene_handoff`, `increase_contrast_before_payoff`, `bridge_sections`, `open_chorus`, `create_breakdown`, `increase_forward_motion` | structural |
|
|
40
|
+
| `sound_design` | Timbre of individual sources. Per-hit velocity / probability / micro-timing variations also sit here when they change feel, not pattern. | `add_warmth`, `add_texture`, `shape_transients`, `add_space` | timbral — or rhythmic with dimension_hint when per-hit-timing oriented |
|
|
41
|
+
| `performance` | Live-safe energy shaping | `recover_energy`, `decompress_tension`, `safe_spotlight`, `emergency_simplify` | (context-specific) |
|
|
42
|
+
| `device_creation` | New device / rack / instrument load. Generates Max for Live M4L devices procedurally. | `create_chaos_modulator`, `create_feedback_resonator`, `create_wavefolder_effect`, `create_bitcrusher_effect`, `create_karplus_string`, `create_stochastic_texture`, `create_fdn_reverb` | timbral |
|
|
43
|
+
| `sample` | Sample-based creative moves — chop, layer, stretch, resample, one-shot. Lives in `sample_engine/moves.py`. | `sample_chop_rhythm`, `sample_texture_layer`, `sample_vocal_ghost`, `sample_break_layer`, `sample_resample_destroy`, `sample_one_shot_accent` | rhythmic (chop / break / one-shot) or timbral (texture / vocal_ghost / resample) |
|
|
44
|
+
|
|
45
|
+
**Discovery:** always call `list_semantic_moves(domain=<family>)` at
|
|
46
|
+
runtime to enumerate — do not hardcode move IDs. Families are stable;
|
|
47
|
+
the move catalog grows. As of v1.26.2 the runtime returns 44 moves
|
|
48
|
+
across all 7 domains.
|
|
49
|
+
|
|
50
|
+
**Why the director never invents an eighth `rhythmic` family:** the
|
|
51
|
+
move registry is the execution substrate. A family that exists in
|
|
52
|
+
documentation but not in `semantic_moves/*.py` or `sample_engine/moves.py`
|
|
53
|
+
cannot be compiled into an experiment seed via the registry path. It
|
|
54
|
+
would force every rhythmic seed onto the `freeform` / `technique`
|
|
55
|
+
source path with a hand-assembled `compiled_plan`. Cleaner to keep the
|
|
56
|
+
family set code-aligned and use `dimension_hint` to record the musical
|
|
57
|
+
consequence.
|
|
58
|
+
|
|
59
|
+
**Note on the `sample` family:** sample-based creative work was
|
|
60
|
+
historically documented as "sample_engine is not a semantic_move
|
|
61
|
+
family" (see the Sample-heavy workflows section below). That was wrong
|
|
62
|
+
— v1.18.0 verification against `list_semantic_moves()` confirmed
|
|
63
|
+
`sample` is a legitimate domain with 6 moves. Prefer sample-family
|
|
64
|
+
moves over tagging sample work as `sound_design` or `device_creation`
|
|
65
|
+
when the dominant operation IS chopping / stretching / resampling.
|
|
66
|
+
|
|
67
|
+
## The rule
|
|
68
|
+
|
|
69
|
+
Generate three seeds. For each seed, identify its DOMINANT move (the
|
|
70
|
+
first step in the compiled plan, or the single `move_id` for
|
|
71
|
+
`source="semantic_move"` seeds). The `.family` attribute of those three
|
|
72
|
+
dominant moves must be three different values from the canonical set.
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
plan_A.dominant.family != plan_B.dominant.family
|
|
76
|
+
plan_B.dominant.family != plan_C.dominant.family
|
|
77
|
+
plan_A.dominant.family != plan_C.dominant.family
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
If any two match → regenerate the offending plan from a different family.
|
|
81
|
+
|
|
82
|
+
## Low-novelty escape hatch
|
|
83
|
+
|
|
84
|
+
The 3-distinct-families rule exists to prevent collapse-to-mode on
|
|
85
|
+
creative intent. But "creative intent" spans a wide novelty range (see
|
|
86
|
+
`creative-brief-template.md` novelty_budget table). At the conservative
|
|
87
|
+
end, the rule fights against the user's ask.
|
|
88
|
+
|
|
89
|
+
**If the brief's `novelty_budget < 0.35`** (e.g., "keep the vibe, just
|
|
90
|
+
cleaner", "tighten it up", "final polish"), the 3-family rule is
|
|
91
|
+
RELAXED:
|
|
92
|
+
|
|
93
|
+
| novelty_budget | Minimum distinct families |
|
|
94
|
+
|---|---|
|
|
95
|
+
| `< 0.35` | 1-2 is honest; 3 is fabricated |
|
|
96
|
+
| `0.35 – 0.50` | 2 minimum; 3 ideal |
|
|
97
|
+
| `> 0.50` | 3 required (standard rule) |
|
|
98
|
+
|
|
99
|
+
**Rationale:** low novelty_budget signals refinement, not exploration.
|
|
100
|
+
A user asking "make it cleaner" under an active Basic Channel packet
|
|
101
|
+
rightly gets 1-2 mix-family plans (low-end clean-up, tail tail-taming,
|
|
102
|
+
send level adjustment) — inventing a structural or sound_design plan
|
|
103
|
+
for them would ignore what they asked for. That's exactly the
|
|
104
|
+
"generic_fallback" failure mode the verdict taxonomy catches on the
|
|
105
|
+
OTHER end — the director shouldn't produce it preemptively by forcing
|
|
106
|
+
divergence the user didn't want.
|
|
107
|
+
|
|
108
|
+
**Honesty requirements when the escape hatch applies:**
|
|
109
|
+
- State the novelty_budget value in the brief's notes
|
|
110
|
+
- Name the rule: "Low-novelty escape hatch — 3-family rule relaxed"
|
|
111
|
+
- Still differentiate the 1-2 plans meaningfully (different target,
|
|
112
|
+
different parameter direction) — the rule relaxation is about the
|
|
113
|
+
family-count constraint, NOT the no-fabricated-distinctness rule
|
|
114
|
+
which applies always
|
|
115
|
+
|
|
116
|
+
**Anti-pattern under the escape hatch:** shipping 2 plans that are
|
|
117
|
+
"same move with different EQ Q" or "same send at different levels".
|
|
118
|
+
Even under relaxed family rules, plans must have distinct musical
|
|
119
|
+
consequence. Use different TARGETS (different tracks) or different
|
|
120
|
+
MECHANISMS (EQ vs. Utility gain vs. saturator input drive) to stay
|
|
121
|
+
honest.
|
|
122
|
+
|
|
123
|
+
## How to pick the dominant move for a multi-step seed
|
|
124
|
+
|
|
125
|
+
For `source="freeform"` / `"synthesis"` / `"composer"` / `"technique"`
|
|
126
|
+
seeds that arrive with a compiled plan:
|
|
127
|
+
|
|
128
|
+
1. The dominant move is the step with the **highest musical consequence**,
|
|
129
|
+
not the first step in execution order.
|
|
130
|
+
2. Heuristic: a step that changes identity (new device, new section,
|
|
131
|
+
new timbre) outranks a step that tunes parameters.
|
|
132
|
+
3. If ambiguous: tag the seed with a `family_hint` in the seed dict and
|
|
133
|
+
use that.
|
|
134
|
+
|
|
135
|
+
## Anti-examples — fabricated distinctness
|
|
136
|
+
|
|
137
|
+
**REJECT these seed sets.** They look different but collapse to one pattern:
|
|
138
|
+
|
|
139
|
+
- Three `mix` plans with different EQ curves on the same track
|
|
140
|
+
→ all `family="mix"` — the agent is converging to "mixing".
|
|
141
|
+
- `add_warmth` + `add_texture` + `add_space` — all three are `sound_design`.
|
|
142
|
+
The agent found the sound-design hammer and is hitting everything.
|
|
143
|
+
- Three seeds using different references (Villalobos / Basic Channel /
|
|
144
|
+
Gas) but all routing to `sound_design` moves — reference diversity
|
|
145
|
+
is not family diversity.
|
|
146
|
+
- Two plans that both add a send to the same reverb with different levels.
|
|
147
|
+
|
|
148
|
+
**ACCEPT these:** family is actually different.
|
|
149
|
+
|
|
150
|
+
- Plan A: `arrangement` (breakdown at bar 48) + Plan B: `sound_design`
|
|
151
|
+
(dub chord on pad) + Plan C: `mix` (widen_stereo on hats bus)
|
|
152
|
+
- Plan A: `transition` (increase_forward_motion into drop) + Plan B:
|
|
153
|
+
`device_creation` (add Granulator III on vocal) + Plan C:
|
|
154
|
+
`sound_design` (shape_transients on kick)
|
|
155
|
+
|
|
156
|
+
## Edge cases
|
|
157
|
+
|
|
158
|
+
### User pre-locked a dimension
|
|
159
|
+
|
|
160
|
+
If the brief's `locked_dimensions` excludes one or more dimensions
|
|
161
|
+
(e.g., "don't touch the arrangement"), the families that map to those
|
|
162
|
+
dimensions are off-limits. See `the-four-move-rule.md` for the map.
|
|
163
|
+
|
|
164
|
+
With one lock: the remaining families still must differ across three plans.
|
|
165
|
+
With two locks: only 2 dimensions left — ship 2 plans, not 3 (honesty rule).
|
|
166
|
+
|
|
167
|
+
### Mix excluded by recency — family-collision risk
|
|
168
|
+
|
|
169
|
+
When the recency rule excludes `mix` (≥ 5 of 10 in `get_action_ledger_summary(limit=10)`), the
|
|
170
|
+
natural fallback plans often collapse into two `arrangement`-family
|
|
171
|
+
plans — one structural (insert a breakdown) and one rhythmic (clip
|
|
172
|
+
groove + probability edits). Both are honest `arrangement` with
|
|
173
|
+
different `dimension_hint` tags, but the diversity rule requires three
|
|
174
|
+
distinct families.
|
|
175
|
+
|
|
176
|
+
**Pre-empt the collision:** when `mix` is excluded and you want both
|
|
177
|
+
structural AND rhythmic coverage, route the structural plan through
|
|
178
|
+
`transition` family (`create_breakdown`, `create_buildup_tension`,
|
|
179
|
+
`bridge_sections`, `increase_forward_motion`) rather than
|
|
180
|
+
`arrangement`. Both families can deliver structural consequence;
|
|
181
|
+
`transition` is the one that leaves `arrangement` free for the
|
|
182
|
+
rhythmic plan.
|
|
183
|
+
|
|
184
|
+
Allowed combinations when mix is excluded:
|
|
185
|
+
- `transition` (structural) + `arrangement` (rhythmic) + `sound_design` (timbral) ✅
|
|
186
|
+
- `arrangement` (structural) + `sound_design` (rhythmic, per-hit) + `device_creation` (timbral) ✅
|
|
187
|
+
- `arrangement` (structural) + `arrangement` (rhythmic) — ❌ family collision, regenerate
|
|
188
|
+
|
|
189
|
+
### Fewer than three families plausibly apply
|
|
190
|
+
|
|
191
|
+
Example: the user's "more warmth on the master" request genuinely only
|
|
192
|
+
has `mix` and `sound_design` as credible families. Do NOT fabricate a
|
|
193
|
+
`device_creation` plan to hit three.
|
|
194
|
+
|
|
195
|
+
- Ship two plans across the two real families
|
|
196
|
+
- Document explicitly: "Only 2 plans — the ask narrows to {mix,
|
|
197
|
+
sound_design}; forcing a third would be theatre."
|
|
198
|
+
- This is inherited from Wonder's honesty rule
|
|
199
|
+
- This is ACCEPTABLE on stuck-rescue contexts; on a first-pass creative
|
|
200
|
+
call, re-read the concept packet and check whether a third family
|
|
201
|
+
was overlooked before giving up
|
|
202
|
+
|
|
203
|
+
### The concept packet mandates a family
|
|
204
|
+
|
|
205
|
+
If the packet's `reach_for.techniques` cluster in one family, use that
|
|
206
|
+
family for the dominant plan — but the OTHER two plans still vary.
|
|
207
|
+
Packet specifies the center; diversity rule specifies the spread.
|
|
208
|
+
|
|
209
|
+
### Sample-heavy workflows
|
|
210
|
+
|
|
211
|
+
As of v1.18.0, `sample` IS a semantic_move family (registry lives in
|
|
212
|
+
`sample_engine/moves.py`). For dominant-sample work, prefer sample-
|
|
213
|
+
family moves directly:
|
|
214
|
+
|
|
215
|
+
- Rhythmic chopping → `sample_chop_rhythm` or `sample_break_layer`
|
|
216
|
+
- Atmospheric layering → `sample_texture_layer`
|
|
217
|
+
- Vocal transformation → `sample_vocal_ghost`
|
|
218
|
+
- Destructive transformation → `sample_resample_destroy`
|
|
219
|
+
- Punctuation → `sample_one_shot_accent`
|
|
220
|
+
|
|
221
|
+
Only fall back to `sound_design` or `device_creation` when the dominant
|
|
222
|
+
action is PATCH-level programming or NEW-device loading rather than
|
|
223
|
+
sample-level manipulation. Loading Simpler with a degraded source,
|
|
224
|
+
for instance, is `device_creation` (loading the instrument); chopping
|
|
225
|
+
an already-loaded sample is `sample`.
|
|
226
|
+
|
|
227
|
+
### Rhythmic plans
|
|
228
|
+
|
|
229
|
+
A rhythmic plan (one whose primary consequence is swing / ghost-note
|
|
230
|
+
programming / probability / motif transformation / groove assignment)
|
|
231
|
+
dominates as `arrangement` if it edits clip content or pattern, OR as
|
|
232
|
+
`sound_design` if it shapes per-hit timbre/velocity in a way that
|
|
233
|
+
changes feel. Always attach `dimension_hint: "rhythmic"` to the seed.
|
|
234
|
+
|
|
235
|
+
Two rhythmic plans across a diverse set are fine IF their dominant
|
|
236
|
+
families differ (one `arrangement`, one `sound_design`). Two rhythmic
|
|
237
|
+
plans both tagged `arrangement` = fabricated distinctness by the same
|
|
238
|
+
rule that forbids two `mix` plans.
|
|
239
|
+
|
|
240
|
+
## What to write into the turn
|
|
241
|
+
|
|
242
|
+
After Phase 3 generation, explicitly state the family split. Example:
|
|
243
|
+
|
|
244
|
+
> Three plans:
|
|
245
|
+
> - **A (sound_design):** Dub chord stab into filtered delay send.
|
|
246
|
+
> - **B (arrangement):** Negative-space breakdown at bar 48, ghost percussion only.
|
|
247
|
+
> - **C (mix):** Widen stereo on hats bus, narrow sub to mono under 80 Hz.
|
|
248
|
+
|
|
249
|
+
This makes the diversity legible and auditable by the user.
|
|
250
|
+
|
|
251
|
+
## Why this works
|
|
252
|
+
|
|
253
|
+
"Pattern repetition" is a signal that the agent keeps choosing the same
|
|
254
|
+
family (usually `mix` or `sound_design`, because those are the
|
|
255
|
+
easiest/safest). Forcing three families forces the agent to consider
|
|
256
|
+
structural and transitional moves it would otherwise skip. That is
|
|
257
|
+
where the "distinct musical idea, not just distinct parameters"
|
|
258
|
+
property comes from.
|
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
# Phase 6 — Execution Contracts (v1.20+)
|
|
2
|
+
|
|
3
|
+
Full contracts for the 10 semantic moves shipped in v1.20.0, plus the
|
|
4
|
+
escape-hatch policy for patterns not yet covered. Read this alongside
|
|
5
|
+
the Phase 6 decision table in `SKILL.md`.
|
|
6
|
+
|
|
7
|
+
Every NEW move listed here takes its user targets via
|
|
8
|
+
`apply_semantic_move(move_id, mode, args)`, where `args` is threaded
|
|
9
|
+
into the compiler's kernel as `kernel["seed_args"]`. The pre-v1.20 33
|
|
10
|
+
moves (mix / arrangement / transition / sound_design / performance /
|
|
11
|
+
sample families) still read only from `session_info` and ignore args.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Routing family (v1.20 commit 1)
|
|
16
|
+
|
|
17
|
+
### `build_send_chain`
|
|
18
|
+
|
|
19
|
+
Load an ordered device chain onto a return track. The Basic Channel /
|
|
20
|
+
dub-techno / ambient send-architecture primitive.
|
|
21
|
+
|
|
22
|
+
| Field | Type | Required | Notes |
|
|
23
|
+
|---|---|---|---|
|
|
24
|
+
| `return_track_index` | int | yes | 0 = Return A, 1 = Return B, ... (0-based) |
|
|
25
|
+
| `device_chain` | list[str] | yes | Device names in load order. Duplicates allowed (e.g., two Echos stacked). |
|
|
26
|
+
|
|
27
|
+
Compiled steps (per device in order, then a final verify read):
|
|
28
|
+
|
|
29
|
+
1. `find_and_load_device(track_index=-(return_track_index+1), device_name=<name>, allow_duplicate=True)`
|
|
30
|
+
2. ... (one per device)
|
|
31
|
+
3. `get_track_info(track_index=-(return_track_index+1))` — read-only verify.
|
|
32
|
+
|
|
33
|
+
Risk: **medium** (return chains affect every track routing sends there).
|
|
34
|
+
Protect: `low_end=0.6` (dub returns can accumulate sub mud).
|
|
35
|
+
Family: `device_creation`.
|
|
36
|
+
|
|
37
|
+
**Typical caller:** "build me a Basic Channel dub architecture on
|
|
38
|
+
Return A" → build_send_chain({return_track_index: 0, device_chain:
|
|
39
|
+
["Echo", "Auto Filter", "Convolution Reverb"]}).
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
### `configure_send_architecture`
|
|
44
|
+
|
|
45
|
+
Set send levels across a set of source tracks in a single move.
|
|
46
|
+
|
|
47
|
+
| Field | Type | Required | Notes |
|
|
48
|
+
|---|---|---|---|
|
|
49
|
+
| `source_track_indices` | list[int] | yes | 0-based; negative indices for returns |
|
|
50
|
+
| `send_index` | int | yes | Which send slot (0 = Send A, 1 = Send B, ...) |
|
|
51
|
+
| `levels` | list[float] | yes | 0.0-1.0. Must be same length as source_track_indices. Out-of-range values are clamped with a warning. |
|
|
52
|
+
|
|
53
|
+
Compiled steps: one `set_track_send` per (track, level) pair.
|
|
54
|
+
|
|
55
|
+
Risk: **low**. Protect: `clarity=0.5` (overdone sends muddy the mix).
|
|
56
|
+
Family: `mix`.
|
|
57
|
+
|
|
58
|
+
**Typical caller:** "route all percussion to the dub reverb at -10 dB" →
|
|
59
|
+
configure_send_architecture({source_track_indices: [2, 3, 4], send_index: 0, levels: [0.35, 0.35, 0.35]}).
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
### `set_track_routing`
|
|
64
|
+
|
|
65
|
+
Rewire a track's output routing. Useful for setting up bus architectures
|
|
66
|
+
("Sends Only") or routing a track to a specific return.
|
|
67
|
+
|
|
68
|
+
| Field | Type | Required | Notes |
|
|
69
|
+
|---|---|---|---|
|
|
70
|
+
| `track_index` | int | yes | 0-based; negative for returns |
|
|
71
|
+
| `output_routing_type` | str | at least one of output_* required | e.g., "Sends Only", "Master" |
|
|
72
|
+
| `output_routing_channel` | str | | Display name from Live (e.g., "Post Mixer") |
|
|
73
|
+
|
|
74
|
+
Compiled steps: single `set_track_routing` call.
|
|
75
|
+
|
|
76
|
+
Risk: **medium** (a bad routing silences or feedback-loops audio).
|
|
77
|
+
Protect: `clarity=0.5`. Family: `mix`.
|
|
78
|
+
|
|
79
|
+
**Typical caller:** "send track 0 to bus-only so it only feeds the return" →
|
|
80
|
+
set_track_routing({track_index: 0, output_routing_type: "Sends Only"}).
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## Device-mutation family (v1.20 commit 2)
|
|
85
|
+
|
|
86
|
+
### `configure_device`
|
|
87
|
+
|
|
88
|
+
Reconfigure an existing device in bulk — set N parameters in one
|
|
89
|
+
undoable move. The ergonomic replacement for a chain of
|
|
90
|
+
`set_device_parameter` raw calls.
|
|
91
|
+
|
|
92
|
+
| Field | Type | Required | Notes |
|
|
93
|
+
|---|---|---|---|
|
|
94
|
+
| `track_index` | int | yes | Negative allowed (returns, master=-1000) |
|
|
95
|
+
| `device_index` | int | yes | Position in the track's chain |
|
|
96
|
+
| `param_overrides` | dict[str, Any] | yes | `{param_name: value}`. At least one entry required. |
|
|
97
|
+
|
|
98
|
+
Compiled steps: single `batch_set_parameters` call. Each
|
|
99
|
+
`{param_name, value}` pair is normalized into Live's preferred shape
|
|
100
|
+
(`parameter_name` key).
|
|
101
|
+
|
|
102
|
+
Risk: **low**. Protect: `{}` — caller declares via the specific
|
|
103
|
+
param_overrides. Family: `sound_design`.
|
|
104
|
+
|
|
105
|
+
**Preset library note (v1.21 scope):** the plan originally called for
|
|
106
|
+
`preset_name` + an affordance-YAML library. v1.20 ships `param_overrides`
|
|
107
|
+
only — once a preset library lands, the preset simply resolves to the
|
|
108
|
+
same dict and the move contract stays identical.
|
|
109
|
+
|
|
110
|
+
**Typical caller:** apply an affordance preset (affordance YAML →
|
|
111
|
+
resolved param dict) → configure_device({track_index: -1, device_index: 0,
|
|
112
|
+
param_overrides: {"Decay Time": 4000.0, "Dry/Wet": 0.35, "Size": 1.0}}).
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
### `remove_device`
|
|
117
|
+
|
|
118
|
+
Delete a device with a required audit reason. Destructive but undoable
|
|
119
|
+
via Live's undo stack.
|
|
120
|
+
|
|
121
|
+
| Field | Type | Required | Notes |
|
|
122
|
+
|---|---|---|---|
|
|
123
|
+
| `track_index` | int | yes | |
|
|
124
|
+
| `device_index` | int | yes | |
|
|
125
|
+
| `reason` | str | **yes** | Non-empty, non-whitespace. Destructive ops must be justified. |
|
|
126
|
+
|
|
127
|
+
Compiled steps:
|
|
128
|
+
|
|
129
|
+
1. `delete_device(track_index, device_index)`
|
|
130
|
+
2. `add_session_memory(category="device_removal", content="Removed track=<ti> device_index=<di>: <reason>")`
|
|
131
|
+
|
|
132
|
+
Risk: **medium**. Protect: `signal_integrity=0.9` (live signal-path
|
|
133
|
+
removal can silence audio). Family: `sound_design`.
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## Content family (v1.20 commit 3)
|
|
138
|
+
|
|
139
|
+
### `load_chord_source`
|
|
140
|
+
|
|
141
|
+
Create a named MIDI clip at a specific slot with chord voicing notes.
|
|
142
|
+
Feeds a `build_send_chain` return chain for dub-chord workflows.
|
|
143
|
+
|
|
144
|
+
| Field | Type | Required | Notes |
|
|
145
|
+
|---|---|---|---|
|
|
146
|
+
| `track_index` | int | yes | |
|
|
147
|
+
| `clip_slot` | int | yes | Non-negative |
|
|
148
|
+
| `notes` | list[dict] | yes | `[{pitch, start_time, duration, velocity?, probability?}]`; non-empty |
|
|
149
|
+
| `name` | str | yes | Non-whitespace |
|
|
150
|
+
| `length_beats` | float | no | Default 4.0 (one bar 4/4) |
|
|
151
|
+
|
|
152
|
+
Compiled steps (ordered, all remote_command):
|
|
153
|
+
|
|
154
|
+
1. `create_clip(track_index, clip_index=clip_slot, length=length_beats)`
|
|
155
|
+
2. `add_notes(track_index, clip_index=clip_slot, notes=...)`
|
|
156
|
+
3. `set_clip_name(track_index, clip_index=clip_slot, name=...)`
|
|
157
|
+
|
|
158
|
+
Risk: **low**. Protect: `cohesion=0.6`. Family: `sound_design`.
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
### `create_drum_rack_pad`
|
|
163
|
+
|
|
164
|
+
Add one pad (chain) to a Drum Rack, loading a sample + setting Snap=0
|
|
165
|
+
post-load. Wraps the Live 12.4 native `replace_sample_native` flow.
|
|
166
|
+
Build kits one pad at a time à la Dilla.
|
|
167
|
+
|
|
168
|
+
| Field | Type | Required | Notes |
|
|
169
|
+
|---|---|---|---|
|
|
170
|
+
| `track_index` | int | yes | Track containing the Drum Rack |
|
|
171
|
+
| `pad_note` | int | yes | MIDI 0-127. Standard drum map: 36=Kick, 38=Snare, 42=CHH, 46=OHH. |
|
|
172
|
+
| `file_path` | str | yes | Absolute path to the audio file |
|
|
173
|
+
| `rack_device_index` | int | no | Auto-detects first Drum Rack if omitted |
|
|
174
|
+
| `chain_name` | str | no | Display name for the new chain |
|
|
175
|
+
|
|
176
|
+
Compiled steps: single `add_drum_rack_pad` call (backend=`mcp_tool`,
|
|
177
|
+
async — it composes insert_rack_chain + set_drum_chain_note +
|
|
178
|
+
insert_device + replace_sample_native + hygiene internally).
|
|
179
|
+
|
|
180
|
+
Risk: **low**. Family: `device_creation`.
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## Metadata family (v1.20 commit 4)
|
|
185
|
+
|
|
186
|
+
### `configure_groove`
|
|
187
|
+
|
|
188
|
+
Assign a groove to clips and optionally tune its timing_amount. The
|
|
189
|
+
Dilla-swing primitive; pre-resolve the groove_id via `list_grooves()`
|
|
190
|
+
before calling.
|
|
191
|
+
|
|
192
|
+
| Field | Type | Required | Notes |
|
|
193
|
+
|---|---|---|---|
|
|
194
|
+
| `track_index` | int | yes | |
|
|
195
|
+
| `clip_indices` | list[int] | yes | Non-empty; non-negative entries |
|
|
196
|
+
| `groove_id` | int | yes | From `list_grooves()` |
|
|
197
|
+
| `timing_amount` | float | no | 0.0-1.0; clamped with warning on out-of-range |
|
|
198
|
+
|
|
199
|
+
Compiled steps:
|
|
200
|
+
|
|
201
|
+
1. `assign_clip_groove(track_index, clip_index=<each>, groove_id)` — one per clip
|
|
202
|
+
2. `set_groove_params(groove_id, timing_amount=<clamped>)` — only if provided
|
|
203
|
+
|
|
204
|
+
Risk: **low**. Protect: `clarity=0.5`. Family: `arrangement`.
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
### `set_scene_metadata`
|
|
209
|
+
|
|
210
|
+
Set scene name / color / tempo in one conditional move. Each field is
|
|
211
|
+
optional; at least one required.
|
|
212
|
+
|
|
213
|
+
| Field | Type | Required | Notes |
|
|
214
|
+
|---|---|---|---|
|
|
215
|
+
| `scene_index` | int | yes | Non-negative |
|
|
216
|
+
| `name` | str | no | |
|
|
217
|
+
| `color_index` | int | no | |
|
|
218
|
+
| `tempo` | float | no | BPM. **set_scene_tempo DOES affect playback timing on scene fire — use cautiously inside a performance context.** |
|
|
219
|
+
|
|
220
|
+
Compiled steps: one tool call per provided field (`set_scene_name` /
|
|
221
|
+
`set_scene_color` / `set_scene_tempo`). Zero-field calls reject.
|
|
222
|
+
|
|
223
|
+
Risk: **low**. Family: `arrangement`.
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
### `set_track_metadata` (bundled rename + color)
|
|
228
|
+
|
|
229
|
+
Set track name and/or color in a single bundled move. Both fields are
|
|
230
|
+
optional; at least one required.
|
|
231
|
+
|
|
232
|
+
| Field | Type | Required | Notes |
|
|
233
|
+
|---|---|---|---|
|
|
234
|
+
| `track_index` | int | yes | Negative indices for returns allowed |
|
|
235
|
+
| `name` | str | no | |
|
|
236
|
+
| `color_index` | int | no | |
|
|
237
|
+
|
|
238
|
+
Compiled steps: one call per provided field. Zero-field calls reject.
|
|
239
|
+
|
|
240
|
+
Risk: **low**. Family: `mix`.
|
|
241
|
+
|
|
242
|
+
**Why bundled?** Phase 6 usage always pairs rename with color (name is
|
|
243
|
+
what the director types; color carries aesthetic meaning — green for
|
|
244
|
+
analog, orange for harmonic, etc.). The bundled move replaces two
|
|
245
|
+
raw calls with one named intent.
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
## Escape-hatch policy (v1.20, phased cutover)
|
|
250
|
+
|
|
251
|
+
When no semantic move in Phase 6's decision table covers the pattern,
|
|
252
|
+
the director may fall back to raw tool calls — BUT only with the
|
|
253
|
+
mandatory logging contract below. The hatch is explicitly a phased-
|
|
254
|
+
cutover transitional state; v1.21+ closes patterns as they accumulate
|
|
255
|
+
tech_debt log entries.
|
|
256
|
+
|
|
257
|
+
### The three mandatory calls (in order)
|
|
258
|
+
|
|
259
|
+
1. **The raw tool call itself** — e.g., `set_device_parameter(...)`,
|
|
260
|
+
`load_browser_item(...)`, `create_take_lane(...)`.
|
|
261
|
+
2. **`add_session_memory(category="move_executed", ...)`** — one-line
|
|
262
|
+
ledger entry summarizing the move's family + target + brief
|
|
263
|
+
identity. Anti-repetition is blind without this.
|
|
264
|
+
3. **`add_session_memory(category="tech_debt", ...)`** — tracking log
|
|
265
|
+
that names the uncovered pattern. Use wording specific enough that
|
|
266
|
+
v1.21 release planning can turn it into a semantic move.
|
|
267
|
+
|
|
268
|
+
### Example: the director rewires a track group (pattern not yet in decision table)
|
|
269
|
+
|
|
270
|
+
```python
|
|
271
|
+
# Raw tool call (no semantic move covers "rename track group")
|
|
272
|
+
ableton.send_command("set_group_name", {"group_index": 0, "name": "DRUMS"})
|
|
273
|
+
|
|
274
|
+
# Mandatory 2/3: ledger marker for anti-repetition
|
|
275
|
+
add_session_memory(
|
|
276
|
+
category="move_executed",
|
|
277
|
+
content="mix:group-0 rename to DRUMS — brief: stem organization for export",
|
|
278
|
+
engine="creative_director",
|
|
279
|
+
)
|
|
280
|
+
|
|
281
|
+
# Mandatory 3/3: tech_debt log so v1.21 can close the gap
|
|
282
|
+
add_session_memory(
|
|
283
|
+
category="tech_debt",
|
|
284
|
+
content="no semantic_move for: rename a track group (set_group_name). "
|
|
285
|
+
"Suggested move: set_group_metadata, family=mix, "
|
|
286
|
+
"seed_args={group_index, name?, color_index?}",
|
|
287
|
+
engine="creative_director",
|
|
288
|
+
)
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### What the two entries do differently
|
|
292
|
+
|
|
293
|
+
| Entry | Consumer | Scrub? |
|
|
294
|
+
|---|---|---|
|
|
295
|
+
| `move_executed` | Anti-repetition Phase 3 recency table | Stable — never scrubbed |
|
|
296
|
+
| `tech_debt` | v1.21 release planning | Scrubbed per release after closure |
|
|
297
|
+
|
|
298
|
+
### Honesty rules for the hatch
|
|
299
|
+
|
|
300
|
+
- **Don't treat the hatch as a shortcut.** Default is always
|
|
301
|
+
`apply_semantic_move`. The hatch is the branch you take once you've
|
|
302
|
+
checked the decision table AND run
|
|
303
|
+
`list_semantic_moves(domain="<family>")`.
|
|
304
|
+
- **Don't skip the tech_debt log because "that pattern is weird."**
|
|
305
|
+
Weird patterns are exactly the ones v1.21 should close. The log is
|
|
306
|
+
the input.
|
|
307
|
+
- **Don't use `category="tech_debt"` for other purposes.** It's a
|
|
308
|
+
specific contract with release planning. Use a different category
|
|
309
|
+
(e.g., `observation`) for general session notes.
|
|
310
|
+
|
|
311
|
+
---
|
|
312
|
+
|
|
313
|
+
## Affordance-preset resolution (bridge into configure_device)
|
|
314
|
+
|
|
315
|
+
**Shipping in v1.21.** The affordance library lives at
|
|
316
|
+
`mcp_server/affordances/devices/<slug>.yaml` and exposes a Python loader
|
|
317
|
+
at `mcp_server.affordances`. When the plan calls for a preset-style
|
|
318
|
+
reconfiguration (e.g., "dub cathedral reverb", "ping-pong dub delay"),
|
|
319
|
+
you have two equivalent dispatch paths:
|
|
320
|
+
|
|
321
|
+
### Preferred (v1.21+): pass the preset reference to configure_device
|
|
322
|
+
|
|
323
|
+
The compiler resolves the preset YAML at compile time. This keeps the
|
|
324
|
+
director's turn clean (no filesystem call in Python) and makes the
|
|
325
|
+
dispatch self-describing:
|
|
326
|
+
|
|
327
|
+
```python
|
|
328
|
+
apply_semantic_move(
|
|
329
|
+
"configure_device",
|
|
330
|
+
mode="explore",
|
|
331
|
+
args={
|
|
332
|
+
"track_index": -1,
|
|
333
|
+
"device_index": 0,
|
|
334
|
+
"device_slug": "reverb", # required when preset is used
|
|
335
|
+
"preset": "dub-cathedral", # v1.21 library name
|
|
336
|
+
},
|
|
337
|
+
)
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
`device_slug` is REQUIRED when `preset` is supplied — v1.21 doesn't
|
|
341
|
+
auto-infer from class_name (that's v1.22 scope). The compiler returns
|
|
342
|
+
a clear warning if `device_slug` is missing.
|
|
343
|
+
|
|
344
|
+
### Preset + explicit override (merge semantics)
|
|
345
|
+
|
|
346
|
+
The compiler merges preset-resolved params first, then applies any
|
|
347
|
+
explicit `param_overrides` on top (last-write-wins at dict-key
|
|
348
|
+
granularity):
|
|
349
|
+
|
|
350
|
+
```python
|
|
351
|
+
apply_semantic_move(
|
|
352
|
+
"configure_device",
|
|
353
|
+
mode="explore",
|
|
354
|
+
args={
|
|
355
|
+
"track_index": -1,
|
|
356
|
+
"device_index": 0,
|
|
357
|
+
"device_slug": "reverb",
|
|
358
|
+
"preset": "dub-cathedral",
|
|
359
|
+
"param_overrides": {"Decay Time": 0.5}, # overrides preset's 0.85
|
|
360
|
+
},
|
|
361
|
+
)
|
|
362
|
+
# Result: Decay Time=0.5 (explicit wins), Room Size=0.95 (from preset),
|
|
363
|
+
# Dry/Wet=0.40 (from preset), etc.
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
### Fallback: resolve explicitly in Python
|
|
367
|
+
|
|
368
|
+
When you want to inspect or modify the resolved params before dispatch,
|
|
369
|
+
call the loader directly:
|
|
370
|
+
|
|
371
|
+
```python
|
|
372
|
+
from mcp_server.affordances import resolve_preset
|
|
373
|
+
|
|
374
|
+
preset = resolve_preset("reverb", "dub-cathedral")
|
|
375
|
+
# preset = {"Decay Time": 0.85, "Room Size": 0.95, "Dry/Wet": 0.40, ...}
|
|
376
|
+
|
|
377
|
+
apply_semantic_move(
|
|
378
|
+
"configure_device",
|
|
379
|
+
mode="explore",
|
|
380
|
+
args={
|
|
381
|
+
"track_index": -1,
|
|
382
|
+
"device_index": 0,
|
|
383
|
+
"param_overrides": preset, # equivalent to path (1) above
|
|
384
|
+
},
|
|
385
|
+
)
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
### v1.21 library content
|
|
389
|
+
|
|
390
|
+
Minimal (3 seed presets, by design — v1.22 expands):
|
|
391
|
+
|
|
392
|
+
| device_slug | preset | description |
|
|
393
|
+
|----------------|----------------|------------------------------------------|
|
|
394
|
+
| `reverb` | `dub-cathedral`| Basic Channel-adjacent huge space |
|
|
395
|
+
| `delay` | `ping-pong-dub`| Dotted-8th ping-pong, feedback 0.45 |
|
|
396
|
+
| `auto-filter` | `slow-sweep` | Bar-long LFO LP sweep, moderate resonance|
|
|
397
|
+
|
|
398
|
+
List available presets programmatically via
|
|
399
|
+
`mcp_server.affordances.list_devices()` and
|
|
400
|
+
`mcp_server.affordances.list_presets(device_slug)`.
|
|
401
|
+
|
|
402
|
+
---
|
|
403
|
+
|
|
404
|
+
## See also
|
|
405
|
+
|
|
406
|
+
- `SKILL.md` §Phase 6 — the entry-level decision table
|
|
407
|
+
- `references/anti-repetition-rules.md` §v1.20 update — how ledger
|
|
408
|
+
entries feed the recency table
|
|
409
|
+
- `docs/plans/v1.20-structural-plan.md` — design rationale + §7 risks
|