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,214 @@
|
|
|
1
|
+
# Anti-Repetition Protocol
|
|
2
|
+
|
|
3
|
+
The director's Phase 1 reads are not advisory. They are the mechanism
|
|
4
|
+
that breaks pattern repetition, because LLM-driven generation collapses
|
|
5
|
+
to the most-likely completion by default — and "most-likely" is almost
|
|
6
|
+
always "what I did last time."
|
|
7
|
+
|
|
8
|
+
## Ledger-state inference fallback
|
|
9
|
+
|
|
10
|
+
### v1.20 update: DEPRECATED in favor of the semantic-move ledger
|
|
11
|
+
|
|
12
|
+
The detection mechanisms below (`get_last_move`, `get_action_ledger_summary`) see
|
|
13
|
+
every move executed through `apply_semantic_move` or
|
|
14
|
+
`commit_experiment`. As of v1.20, the director SKILL.md Phase 6
|
|
15
|
+
defaults to these two tools — the pre-v1.20 "raw tools + manual
|
|
16
|
+
`add_session_memory` marker" path is now the ESCAPE HATCH only, used
|
|
17
|
+
when no semantic move covers the pattern (see
|
|
18
|
+
`phase-6-execution.md` §escape-hatch policy).
|
|
19
|
+
|
|
20
|
+
**Expected state:** the ledger is populated for every committed
|
|
21
|
+
creative move. `get_last_move` returns the most recent;
|
|
22
|
+
`get_action_ledger_summary(limit=10)` returns the recent window. No
|
|
23
|
+
inference needed.
|
|
24
|
+
|
|
25
|
+
**State-inference is DEPRECATED** — kept below for the narrow case
|
|
26
|
+
where:
|
|
27
|
+
|
|
28
|
+
1. Phase 6 used the escape hatch, AND
|
|
29
|
+
2. BOTH the `move_executed` marker AND the `tech_debt` log were
|
|
30
|
+
accidentally skipped.
|
|
31
|
+
|
|
32
|
+
That is a director-discipline bug, not a design state to route around.
|
|
33
|
+
Fix it at the source (policy: v1.20 `phase-6-execution.md` §escape
|
|
34
|
+
hatch — the two memory writes are MANDATORY). Do NOT use state-
|
|
35
|
+
inference as a general-purpose substitute for the ledger; the
|
|
36
|
+
heuristic can double-count moves that ARE already in the ledger,
|
|
37
|
+
which inflates recency scores and over-penalizes families.
|
|
38
|
+
|
|
39
|
+
### The heuristic (retained for emergency-only use)
|
|
40
|
+
|
|
41
|
+
**Only when ALL of: `get_last_move()=={}`,
|
|
42
|
+
`get_action_ledger_summary(limit=10)` returns no recent moves, AND you
|
|
43
|
+
have visual evidence Phase 6 ran via escape hatch
|
|
44
|
+
without logs.** Compare the current session state (track count,
|
|
45
|
+
return track device chains, clip slot contents) against a naive
|
|
46
|
+
"blank session" baseline. Any non-default device loadout or non-empty
|
|
47
|
+
return track suggests recent creative work that the ledger missed.
|
|
48
|
+
Infer the move family from what's loaded:
|
|
49
|
+
|
|
50
|
+
| Session-state signal | Inferred recent family |
|
|
51
|
+
|---|---|
|
|
52
|
+
| Non-empty return tracks with delay/reverb chains | `device_creation` / `mix` (spatial) |
|
|
53
|
+
| New devices on MIDI tracks (Drift, Meld, Operator, etc.) | `sound_design` / `device_creation` (timbral) |
|
|
54
|
+
| Modified mixer state (volume/pan/sends non-default) | `mix` |
|
|
55
|
+
| Clips with notes in previously-empty slots | `arrangement` / `sound_design` (rhythmic) |
|
|
56
|
+
| New scenes / renamed scenes | `arrangement` (structural) |
|
|
57
|
+
|
|
58
|
+
State inference is a best-effort fallback, not a replacement for the
|
|
59
|
+
ledger. When you find yourself reaching for it, log a `tech_debt`
|
|
60
|
+
entry describing WHY you had to — the root-cause fix belongs in
|
|
61
|
+
Phase 6 discipline, not in propagating inference.
|
|
62
|
+
|
|
63
|
+
## Mandatory pre-generation reads
|
|
64
|
+
|
|
65
|
+
Run all three in parallel during Phase 1. Skipping any of them = the
|
|
66
|
+
agent will repeat.
|
|
67
|
+
|
|
68
|
+
### 1. `get_anti_preferences`
|
|
69
|
+
|
|
70
|
+
Returns moves, device families, patches, and aesthetic directions the
|
|
71
|
+
user has previously rejected (via `record_anti_preference` or implicit
|
|
72
|
+
undo signals). Treat the response as a HARD filter on Phase 3 seeds.
|
|
73
|
+
|
|
74
|
+
If a candidate plan's dominant move appears in anti-preferences → do
|
|
75
|
+
not include it. Regenerate from a different family.
|
|
76
|
+
|
|
77
|
+
### 2. `get_action_ledger_summary(limit=10)`
|
|
78
|
+
|
|
79
|
+
**v1.20 correction**: previous docs pointed at `memory_list`, which
|
|
80
|
+
reads the persistent technique library — a DIFFERENT store from
|
|
81
|
+
the action ledger. Technique-library entries require explicit
|
|
82
|
+
`memory_learn` opt-in; the ledger records every committed move.
|
|
83
|
+
For recency detection, the ledger is the correct source.
|
|
84
|
+
|
|
85
|
+
Returns `recent_moves` — the last N kept moves in this session.
|
|
86
|
+
Inspect their `move_class` (family) distribution:
|
|
87
|
+
|
|
88
|
+
| Recency count for one family | Rule |
|
|
89
|
+
|---|---|
|
|
90
|
+
| 0 of 10 | Family is cold. No penalty. |
|
|
91
|
+
| 1–2 of 10 | Family is lightly used. No penalty; prefer-other-if-tied. |
|
|
92
|
+
| 3–4 of 10 | Family is a "recent hot zone." ALLOWED as a plan's dominant family, but only as the **least-weighted** of the three. Two of the three plans must come from other families. |
|
|
93
|
+
| ≥ 5 of 10 | Family is a **stuck pattern**. EXCLUDED from all three dominant slots — the other two or three plans must cover different families. Also: run `detect_stuckness`. If confidence > 0.5, escalate to Wonder rescue. If 0.4 ≤ confidence < 0.5, see the borderline-stuckness rule in `SKILL.md` §Anti-Repetition Protocol. |
|
|
94
|
+
|
|
95
|
+
The `≥5 of 10` threshold is the same threshold Wonder's stuck-rescue
|
|
96
|
+
path expects, but the director applies it proactively on creative
|
|
97
|
+
intent — the user does not need to say "I'm stuck" for the recency
|
|
98
|
+
rule to bite.
|
|
99
|
+
|
|
100
|
+
### 3. `get_last_move`
|
|
101
|
+
|
|
102
|
+
The most recent committed move. Phase 3 plans MUST NOT exactly repeat
|
|
103
|
+
the last move's family + target combination, even with different
|
|
104
|
+
parameters. That is the clearest pattern-repetition signal.
|
|
105
|
+
|
|
106
|
+
Populate the brief's `last_move_target` field (see
|
|
107
|
+
`creative-brief-template.md`) so the constraint survives between Phase
|
|
108
|
+
1 reads and Phase 3 generation.
|
|
109
|
+
|
|
110
|
+
## The bias rule
|
|
111
|
+
|
|
112
|
+
After Phase 1 reads, compute a "recency family vector":
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
recent_families = {family: count for move in last 10 committed moves}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Apply a penalty to seeds whose dominant family has a high recency
|
|
119
|
+
count. The penalty is informal (not a numeric score) — it just means:
|
|
120
|
+
when two families are equally good choices for a plan, prefer the one
|
|
121
|
+
NOT in `recent_families`.
|
|
122
|
+
|
|
123
|
+
This is the mirror of taste-aware ranking. Taste says "lean toward
|
|
124
|
+
what the user liked." Recency bias says "don't converge back to it
|
|
125
|
+
every time."
|
|
126
|
+
|
|
127
|
+
## Concept packet `avoid` is a HARD filter
|
|
128
|
+
|
|
129
|
+
When a packet is loaded (from `artist-vocabularies.md` or
|
|
130
|
+
`genre-vocabularies.md`), its `avoid` list is not a suggestion.
|
|
131
|
+
|
|
132
|
+
- A candidate plan whose techniques fall in `avoid` → drop it, no
|
|
133
|
+
negotiation.
|
|
134
|
+
- Example: dub_techno packet's `avoid: [bright transient-heavy hats]`.
|
|
135
|
+
A plan that loads Drum Bus with boosted transients on hats is
|
|
136
|
+
rejected even if otherwise diverse.
|
|
137
|
+
|
|
138
|
+
Packets compile. Vibes compile to filters.
|
|
139
|
+
|
|
140
|
+
## Recording anti-preferences
|
|
141
|
+
|
|
142
|
+
On these signals, write to `record_anti_preference` with enough context
|
|
143
|
+
that future sessions learn from it:
|
|
144
|
+
|
|
145
|
+
| Signal | What to record |
|
|
146
|
+
|---|---|
|
|
147
|
+
| User calls `discard_preview_set` | The family + technique of every variant in the set, tagged as "rejected in context X" |
|
|
148
|
+
| User runs `undo` within 2 turns of `commit_preview_variant` | The specific move + family + context |
|
|
149
|
+
| User says "no, not that" / "try something else" after preview | The preview-set's dominant family |
|
|
150
|
+
| Evaluation verdict = `generic_fallback` | The family and technique pattern |
|
|
151
|
+
|
|
152
|
+
Do NOT record anti-preferences on:
|
|
153
|
+
|
|
154
|
+
- Simple operational `undo` (volume / pan adjustments)
|
|
155
|
+
- `undo` in service of A/B comparison
|
|
156
|
+
- User re-ordering or renaming without rejection signal
|
|
157
|
+
|
|
158
|
+
## Example — detecting the stuck pattern
|
|
159
|
+
|
|
160
|
+
Session history shows the last 5 committed moves:
|
|
161
|
+
|
|
162
|
+
1. `widen_stereo` (family=`mix`)
|
|
163
|
+
2. `tighten_low_end` (family=`mix`)
|
|
164
|
+
3. `darken_without_losing_width` (family=`mix`)
|
|
165
|
+
4. `make_punchier` (family=`mix`)
|
|
166
|
+
5. `reduce_foreground_competition` (family=`mix`)
|
|
167
|
+
|
|
168
|
+
Phase 1 detects: `mix` is 5/5 of recent history. The user just said
|
|
169
|
+
"more interesting". Without anti-repetition, the most-likely
|
|
170
|
+
completion is ANOTHER `mix` move.
|
|
171
|
+
|
|
172
|
+
Correct Phase 3 response per the recency threshold table above:
|
|
173
|
+
|
|
174
|
+
- 5 of 10 (or 5 of 5, same conclusion) → `mix` is **EXCLUDED** from
|
|
175
|
+
all three dominant slots. Not "allowed as least-weighted" — that
|
|
176
|
+
rule applies at 3–4/10, not at 5/10.
|
|
177
|
+
- Three seeds must come from `{arrangement, transition, sound_design,
|
|
178
|
+
device_creation, performance}` — all three different.
|
|
179
|
+
- Run `detect_stuckness`:
|
|
180
|
+
- `> 0.5` → route to Wonder rescue (not standard divergence)
|
|
181
|
+
- `0.4 ≤ confidence < 0.5` → borderline — stay in standard
|
|
182
|
+
divergence BUT flag to the user ("I'm staying in divergence; say
|
|
183
|
+
the word to switch to Wonder rescue mode")
|
|
184
|
+
- `< 0.4` → standard divergence, no escalation
|
|
185
|
+
|
|
186
|
+
The "allow one mix plan as least-weighted" escape hatch that earlier
|
|
187
|
+
drafts mentioned applies ONLY at 3–4/10 recency, not at ≥ 5/10.
|
|
188
|
+
At 5/10 the family is fully excluded.
|
|
189
|
+
|
|
190
|
+
## Example — respecting user-specified deepening
|
|
191
|
+
|
|
192
|
+
User says: "I like where the timbre is going — push it further."
|
|
193
|
+
|
|
194
|
+
This is an explicit opt-in to stay in `sound_design`. The family
|
|
195
|
+
diversity rule still applies (three plans, different families), BUT:
|
|
196
|
+
|
|
197
|
+
- The dominant plan (the one recommended to the user) stays
|
|
198
|
+
`sound_design`
|
|
199
|
+
- The other two plans are framed as "alternative directions if the
|
|
200
|
+
deepening direction stops paying off"
|
|
201
|
+
- No anti-preference penalty applied this turn
|
|
202
|
+
|
|
203
|
+
Explicit deepening requests ALWAYS override recency bias. Silence does
|
|
204
|
+
not.
|
|
205
|
+
|
|
206
|
+
## What NOT to do
|
|
207
|
+
|
|
208
|
+
- Do not skip Phase 1 reads because "it's obvious what the user wants"
|
|
209
|
+
- Do not treat anti-preferences as soft suggestions
|
|
210
|
+
- Do not record every discarded variant as an anti-preference — that
|
|
211
|
+
floods the store with noise. Record only when the user actively
|
|
212
|
+
rejected something (see table above).
|
|
213
|
+
- Do not record anti-preferences for moves the user never actually
|
|
214
|
+
heard (analytical-only variants that were never rendered)
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
# Creative Brief — Schema and Examples
|
|
2
|
+
|
|
3
|
+
The Creative Brief is an inline YAML block emitted during Phase 2 of the
|
|
4
|
+
director contract. It is NOT a tool call and NOT stored in memory until
|
|
5
|
+
Phase 8 (`memory_learn`). It is a conditioning payload that downstream
|
|
6
|
+
skills read in the same turn.
|
|
7
|
+
|
|
8
|
+
## Why an inline block
|
|
9
|
+
|
|
10
|
+
The brief's only job is to pin the artistic thesis and constraints
|
|
11
|
+
BEFORE generation so the three plans can be judged against it. If it
|
|
12
|
+
lives in memory or in a tool response, the agent can ignore it. Inline
|
|
13
|
+
in the turn, the agent cannot.
|
|
14
|
+
|
|
15
|
+
## Schema
|
|
16
|
+
|
|
17
|
+
```yaml
|
|
18
|
+
creative_brief:
|
|
19
|
+
identity: # one-line artistic thesis (not a genre label)
|
|
20
|
+
reference_anchors: # list — artists/genres/tracks user named
|
|
21
|
+
- type: artist # artist | genre | track | description
|
|
22
|
+
name: # e.g. "Basic Channel"
|
|
23
|
+
source: # user | inferred_from_memory | inferred_from_session
|
|
24
|
+
protected_qualities: # list — things that must survive all changes
|
|
25
|
+
- # e.g. "low-end weight", "restraint", "sparseness"
|
|
26
|
+
anti_patterns: # list — things that would break the brief
|
|
27
|
+
- # drawn from concept packet `avoid` + anti_preferences + last_move_target
|
|
28
|
+
novelty_budget: # 0.0 (conservative) to 1.0 (strange-but-plausible)
|
|
29
|
+
target_dimensions: # evaluation bias — what "better" means here
|
|
30
|
+
groove: # 0.0 to ~0.25 (weights sum loosely to 1)
|
|
31
|
+
depth:
|
|
32
|
+
contrast:
|
|
33
|
+
novelty:
|
|
34
|
+
cohesion:
|
|
35
|
+
motion:
|
|
36
|
+
clarity:
|
|
37
|
+
structure_hypothesis: # optional — only if structure is in scope
|
|
38
|
+
- section: # intro | groove_body | breakdown | return | outro
|
|
39
|
+
bars:
|
|
40
|
+
intent:
|
|
41
|
+
locked_dimensions: # list — dimensions user said don't touch
|
|
42
|
+
- # "structural" | "rhythmic" | "timbral" | "spatial"
|
|
43
|
+
last_move_target: # from Phase 1 get_last_move — do NOT re-target this combo
|
|
44
|
+
family: # e.g. "mix"
|
|
45
|
+
target: # e.g. "track_index=2" / "master" / "bass group"
|
|
46
|
+
move_id: # e.g. "make_kick_bass_lock"
|
|
47
|
+
recommended_skill_chain: # ordered skills to execute the winning plan
|
|
48
|
+
-
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Why `last_move_target`
|
|
52
|
+
|
|
53
|
+
`anti-repetition-rules.md` §3 forbids Phase 3 plans from repeating the
|
|
54
|
+
exact family + target combination of the most recent committed move.
|
|
55
|
+
That constraint lives in Phase 1 read results and can be lost between
|
|
56
|
+
phases. Putting `last_move_target` in the brief makes it survive — and
|
|
57
|
+
makes the violation visible on review. If Phase 1 returns no prior
|
|
58
|
+
move (fresh session), leave the field as `null`.
|
|
59
|
+
|
|
60
|
+
## Rules for filling each field
|
|
61
|
+
|
|
62
|
+
| Field | Source |
|
|
63
|
+
|---|---|
|
|
64
|
+
| `identity` | User prompt + concept packet `sonic_identity`. One sentence. Not a genre label. |
|
|
65
|
+
| `reference_anchors` | Explicit user references, OR inferred from `project_brain` if returning to an existing track |
|
|
66
|
+
| `protected_qualities` | Concept packet `sonic_identity` + `project_brain` identity statement. Also anything user said "keep". |
|
|
67
|
+
| `anti_patterns` | UNION of concept packet `avoid` + `get_anti_preferences` results + user's "don't" asks + the `last_move_target` combo (do not re-target) |
|
|
68
|
+
| `novelty_budget` | See the novelty_budget table below. |
|
|
69
|
+
| `target_dimensions` | Concept packet `evaluation_bias.target_dimensions` if packet is loaded; else derive from intent. Dub/ambient → depth/motion; club/dance → groove/contrast; pop → clarity/motion. |
|
|
70
|
+
| `structure_hypothesis` | Only if the request is structural. Otherwise omit. |
|
|
71
|
+
| `locked_dimensions` | Read user's prompt literally. "Don't touch the arrangement" → `structural`. Silence = no locks. Silence for rhythmic/timbral/spatial = permission. Silence for structural = permission with **conditional** disclosure: flag the intent in the `identity` line ONLY IF the Phase 3 plan set actually includes a structural plan. Compile plans first, then decide whether the disclosure is warranted — no structural plan means no disclosure. |
|
|
72
|
+
| `last_move_target` | From Phase 1 `get_last_move`. Populate family + target + move_id. If no prior move, set to `null`. |
|
|
73
|
+
| `recommended_skill_chain` | Map target_dimensions to skills. See the-four-move-rule.md family-to-dimension table. |
|
|
74
|
+
|
|
75
|
+
### Novelty budget — full table
|
|
76
|
+
|
|
77
|
+
User framing maps to `novelty_budget` values. Choose the nearest match:
|
|
78
|
+
|
|
79
|
+
| User says | novelty_budget | Notes |
|
|
80
|
+
|---|---|---|
|
|
81
|
+
| "keep the vibe, just cleaner" / "same energy, tighten it" | 0.25 – 0.35 | Conservative; bias toward `mix` and `sound_design` refinement |
|
|
82
|
+
| "a bit more like X" / "lean it slightly toward X" | 0.40 – 0.50 | Reference-adjacent; packet avoid filters matter MORE than novelty |
|
|
83
|
+
| "make it more interesting" / "develop this" / "more character" | 0.50 – 0.65 | Default creative ask; 0.55 is a safe midpoint |
|
|
84
|
+
| "take it somewhere" / "evolve this" / "mutate" | 0.60 – 0.75 | Moderately high novelty; cross-domain moves allowed |
|
|
85
|
+
| "surprise me" / "make it magical" / "I'm stuck" | 0.70 – 0.85 | High novelty; strange-but-plausible plans welcome. If `detect_stuckness > 0.5`, route to Wonder rescue instead |
|
|
86
|
+
| "I don't know what I want" / open-ended "ideas?" | 0.55 | Default to mid; let divergence surface options |
|
|
87
|
+
|
|
88
|
+
If the user frame spans two categories, pick the lower novelty. Under
|
|
89
|
+
speed pressure ("quickly"), do NOT change the novelty_budget — it is
|
|
90
|
+
the artistic posture, not the effort level.
|
|
91
|
+
|
|
92
|
+
## Example 1 — "Make it feel like Basic Channel if Dilla touched the swing"
|
|
93
|
+
|
|
94
|
+
```yaml
|
|
95
|
+
creative_brief:
|
|
96
|
+
identity: "Dub-techno space with human swing tension — chord stabs as harmonic vehicle, percussion implied not stated (structural change in scope — will add a breakdown section)"
|
|
97
|
+
reference_anchors:
|
|
98
|
+
- type: artist
|
|
99
|
+
name: "Basic Channel"
|
|
100
|
+
source: user
|
|
101
|
+
- type: artist
|
|
102
|
+
name: "J Dilla"
|
|
103
|
+
source: user
|
|
104
|
+
protected_qualities:
|
|
105
|
+
- low-end weight
|
|
106
|
+
- space as instrument
|
|
107
|
+
- restraint (subtraction over addition)
|
|
108
|
+
anti_patterns:
|
|
109
|
+
- bright transient-heavy hats
|
|
110
|
+
- crisp EDM clap dominance
|
|
111
|
+
- full-grid quantization
|
|
112
|
+
- obvious boom-bap clichés
|
|
113
|
+
novelty_budget: 0.65
|
|
114
|
+
target_dimensions:
|
|
115
|
+
depth: 0.22
|
|
116
|
+
groove: 0.20
|
|
117
|
+
motion: 0.14
|
|
118
|
+
contrast: 0.12
|
|
119
|
+
novelty: 0.12
|
|
120
|
+
cohesion: 0.10
|
|
121
|
+
clarity: 0.10
|
|
122
|
+
locked_dimensions: [] # silent = no locks, BUT structural change flagged in identity (see silent-locks rule)
|
|
123
|
+
last_move_target: null # fresh session
|
|
124
|
+
recommended_skill_chain:
|
|
125
|
+
- livepilot-sound-design-engine # chord stab + filtered delay + reverb tails
|
|
126
|
+
- livepilot-notes # swing + micro-timing shifts on hats
|
|
127
|
+
- livepilot-arrangement # negative-space section logic
|
|
128
|
+
- livepilot-evaluation # artistic dimensions must pass
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Example 2 — "Make the drums more interesting, don't touch the arrangement"
|
|
132
|
+
|
|
133
|
+
```yaml
|
|
134
|
+
creative_brief:
|
|
135
|
+
identity: "Increase drum character without destabilizing the track's form"
|
|
136
|
+
reference_anchors: [] # no external reference named
|
|
137
|
+
protected_qualities:
|
|
138
|
+
- current arrangement shape
|
|
139
|
+
- overall density
|
|
140
|
+
anti_patterns:
|
|
141
|
+
- every-bar fills
|
|
142
|
+
- ornamental velocity rides that don't alter feel
|
|
143
|
+
- sterile quantization
|
|
144
|
+
novelty_budget: 0.55
|
|
145
|
+
target_dimensions:
|
|
146
|
+
groove: 0.25
|
|
147
|
+
novelty: 0.18
|
|
148
|
+
motion: 0.15
|
|
149
|
+
contrast: 0.12
|
|
150
|
+
depth: 0.10
|
|
151
|
+
cohesion: 0.10
|
|
152
|
+
clarity: 0.10
|
|
153
|
+
locked_dimensions:
|
|
154
|
+
- structural # user said "don't touch the arrangement" — section-level off-limits; rhythmic clip edits still allowed
|
|
155
|
+
last_move_target: null
|
|
156
|
+
recommended_skill_chain:
|
|
157
|
+
- livepilot-notes # swing, ghost notes, probability, micro-timing
|
|
158
|
+
- livepilot-sound-design-engine # drum timbre variations per hit
|
|
159
|
+
- livepilot-evaluation
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Example 3 — "Just quickly, make it sound a bit more like Basic Channel"
|
|
163
|
+
|
|
164
|
+
Speed pressure ("just quickly" / "don't overthink it") does NOT skip
|
|
165
|
+
the brief; it compresses prose. Reference-adjacent ask ("a bit more
|
|
166
|
+
like") maps to `novelty_budget ≈ 0.45`.
|
|
167
|
+
|
|
168
|
+
```yaml
|
|
169
|
+
creative_brief:
|
|
170
|
+
identity: "Basic Channel-adjacent dub-techno posture — space and tail as harmonic vehicle, restrained top end"
|
|
171
|
+
reference_anchors:
|
|
172
|
+
- type: artist
|
|
173
|
+
name: "Basic Channel"
|
|
174
|
+
source: user
|
|
175
|
+
protected_qualities:
|
|
176
|
+
- existing chord content (reference-adjacent, not reference-replacement)
|
|
177
|
+
- low-end weight / mono sub
|
|
178
|
+
- current arrangement shape (structural not named in scope)
|
|
179
|
+
anti_patterns:
|
|
180
|
+
- bright transient-heavy hats # packet avoid
|
|
181
|
+
- dry signals / short tails # packet avoid
|
|
182
|
+
- pre-mixed "finished" presets # packet avoid
|
|
183
|
+
novelty_budget: 0.45 # "a bit more like" → reference-adjacent
|
|
184
|
+
target_dimensions:
|
|
185
|
+
depth: 0.24
|
|
186
|
+
motion: 0.18
|
|
187
|
+
cohesion: 0.14
|
|
188
|
+
groove: 0.12
|
|
189
|
+
contrast: 0.12
|
|
190
|
+
novelty: 0.10
|
|
191
|
+
clarity: 0.10
|
|
192
|
+
locked_dimensions: []
|
|
193
|
+
last_move_target: null
|
|
194
|
+
recommended_skill_chain:
|
|
195
|
+
- livepilot-devices # return track setup (Ping-Pong Delay → Convolution Reverb)
|
|
196
|
+
- livepilot-sound-design-engine # chord routing, filter-on-return
|
|
197
|
+
- livepilot-mix-engine # narrow-to-mono sub
|
|
198
|
+
- livepilot-evaluation
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Example 4 — Exact-parameter request (NO BRIEF)
|
|
202
|
+
|
|
203
|
+
> "Set track 3 volume to -6 dB."
|
|
204
|
+
|
|
205
|
+
This is operational, not creative. The director does not fire. No brief.
|
|
206
|
+
The agent routes directly to `set_track_volume`.
|
|
207
|
+
|
|
208
|
+
## Field-absence rules
|
|
209
|
+
|
|
210
|
+
- If `reference_anchors` is empty AND no concept packet loads → `identity`
|
|
211
|
+
comes from current `project_brain` identity statement, or from
|
|
212
|
+
re-reading the user prompt's most recent aesthetic adjective
|
|
213
|
+
- If `anti_patterns` is empty → fall back to recent `get_anti_preferences`
|
|
214
|
+
results; if that is empty too, the brief is brittle — flag the gap
|
|
215
|
+
- If `target_dimensions` cannot be inferred → use a flat weight (all
|
|
216
|
+
≈0.14) and note the weakness in the turn
|
|
217
|
+
|
|
218
|
+
## Emit rule
|
|
219
|
+
|
|
220
|
+
The brief appears ONCE per creative turn, at the top of the assistant
|
|
221
|
+
message, before any Phase 3 tool call. It is for the user to see and
|
|
222
|
+
correct. Treat user edits to the brief as authoritative.
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# Hybrid Concept Packet Compilation
|
|
2
|
+
|
|
3
|
+
**Tool:** `compile_hybrid_brief(packet_ids: list[str], weights: list[float] | None = None)`
|
|
4
|
+
**Module:** `mcp_server/creative_director/hybrid.py`
|
|
5
|
+
**Shipped:** v1.19.0 (Item B from `docs/plans/v1.19-structural-plan.md` §3)
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## When to call it
|
|
10
|
+
|
|
11
|
+
Phase 1 of the creative director skill. If the user names **two or more**
|
|
12
|
+
reference points in their request, call this tool before Phase 2 brief
|
|
13
|
+
compilation. Examples:
|
|
14
|
+
|
|
15
|
+
| User prompt | Call |
|
|
16
|
+
|---|---|
|
|
17
|
+
| "Basic Channel meets Dilla swing" | `compile_hybrid_brief(["basic-channel", "j-dilla"])` |
|
|
18
|
+
| "Villalobos but sparse like Gas" | `compile_hybrid_brief(["villalobos", "gas"])` |
|
|
19
|
+
| "Madlib chop with Photek precision" | `compile_hybrid_brief(["madlib", "photek-source-direct"])` |
|
|
20
|
+
| "Boards-of-Canada sound design, Basic Channel space, Dilla drums" | `compile_hybrid_brief(["boards-of-canada", "basic-channel", "j-dilla"])` |
|
|
21
|
+
|
|
22
|
+
Do NOT call this when:
|
|
23
|
+
|
|
24
|
+
- Only one reference is named (just load the single packet)
|
|
25
|
+
- The user names references but asks for a move that doesn't use the
|
|
26
|
+
brief's `reach_for` or `avoid` (e.g., "make the kick louder" — trivial
|
|
27
|
+
direct action, no packet merge needed)
|
|
28
|
+
- You're in a continuation turn on an already-compiled hybrid
|
|
29
|
+
brief — reuse the brief from the session record
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Merge rules (canonical)
|
|
34
|
+
|
|
35
|
+
These rules are enforced in
|
|
36
|
+
`mcp_server/creative_director/hybrid.py::_compile_from_packets`. The
|
|
37
|
+
table shows what each packet field does when N packets are merged.
|
|
38
|
+
|
|
39
|
+
| Field | Merge strategy | Rationale |
|
|
40
|
+
|---|---|---|
|
|
41
|
+
| `sonic_identity` | UNION | hybrids describe the envelope of both sounds |
|
|
42
|
+
| `reach_for.instruments` / `effects` / `packs` / `utilities` | UNION | candidate pool widens; let Phase 3 filter |
|
|
43
|
+
| `avoid` | UNION | both packets' hard filters apply — stricter wins |
|
|
44
|
+
| `rhythm_idioms` / `harmony_idioms` / `arrangement_idioms` / `texture_idioms` | UNION | all stylistic tendencies remain available |
|
|
45
|
+
| `sample_roles` | UNION | all source roles valid |
|
|
46
|
+
| `dimensions_in_scope` | UNION | scope widens to cover both |
|
|
47
|
+
| `dimensions_deprioritized` | INTERSECTION | deprioritize only when ALL packets agree — otherwise one packet wants what the other ignores |
|
|
48
|
+
| `move_family_bias.deprioritize` | INTERSECTION | same logic — don't starve a family one packet depends on |
|
|
49
|
+
| `move_family_bias.favor` | INTERSECTION when non-empty, UNION fallback with warning | focus where both agree; when disjoint, span both (warn — hybrid may blur) |
|
|
50
|
+
| `evaluation_bias.target_dimensions` | WEIGHTED AVERAGE (default uniform) | continuous blend, weights sum to 1.0 |
|
|
51
|
+
| `evaluation_bias.protect` | MAX per dimension | stricter floor wins (protect=0.80 beats 0.75) |
|
|
52
|
+
| `novelty_budget_default` | MAX | hybrid asks skew exploratory — let the more adventurous packet lead |
|
|
53
|
+
| `tempo_hint` | NEAREST-OVERLAP: intersect overlapping ranges, else midpoint + warn | disjoint tempos = real ambiguity to surface |
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Output shape
|
|
58
|
+
|
|
59
|
+
```yaml
|
|
60
|
+
type: hybrid
|
|
61
|
+
source_packets: [basic-channel, j-dilla]
|
|
62
|
+
weights: [0.5, 0.5]
|
|
63
|
+
name: "Basic Channel / Rhythm & Sound × J Dilla"
|
|
64
|
+
|
|
65
|
+
sonic_identity: [...] # UNION
|
|
66
|
+
reach_for: # UNION per-subfield
|
|
67
|
+
instruments: [...]
|
|
68
|
+
effects: [...]
|
|
69
|
+
packs: [...]
|
|
70
|
+
utilities: [...]
|
|
71
|
+
|
|
72
|
+
avoid: [...] # UNION
|
|
73
|
+
anti_patterns: [...] # alias of avoid — compat with
|
|
74
|
+
# check_brief_compliance
|
|
75
|
+
|
|
76
|
+
rhythm_idioms: [...] # UNION
|
|
77
|
+
harmony_idioms: [...]
|
|
78
|
+
arrangement_idioms: [...]
|
|
79
|
+
texture_idioms: [...]
|
|
80
|
+
sample_roles: [...]
|
|
81
|
+
|
|
82
|
+
evaluation_bias:
|
|
83
|
+
target_dimensions: # WEIGHTED AVERAGE
|
|
84
|
+
groove: 0.19 # e.g., (0.12 + 0.26) / 2
|
|
85
|
+
depth: 0.20
|
|
86
|
+
...
|
|
87
|
+
protect: # MAX per dimension
|
|
88
|
+
low_end: 0.80 # e.g., max(0.80, 0.75)
|
|
89
|
+
cohesion: 0.68
|
|
90
|
+
...
|
|
91
|
+
|
|
92
|
+
move_family_bias:
|
|
93
|
+
favor: [sound_design, device_creation] # INTERSECTION
|
|
94
|
+
deprioritize: [performance] # INTERSECTION
|
|
95
|
+
|
|
96
|
+
dimensions_in_scope: [...] # UNION
|
|
97
|
+
dimensions_deprioritized: [] # INTERSECTION (often empty for hybrids)
|
|
98
|
+
locked_dimensions: [] # NEVER locked by hybrid itself
|
|
99
|
+
|
|
100
|
+
novelty_budget_default: 0.6 # MAX
|
|
101
|
+
tempo_hint:
|
|
102
|
+
min: 107.5 # or overlap range, or midpoint+disjoint flag
|
|
103
|
+
max: 110.0
|
|
104
|
+
time_signature: "4/4"
|
|
105
|
+
disjoint: true # present only when tempo ranges didn't overlap
|
|
106
|
+
|
|
107
|
+
warnings: # human-readable ambiguity notes
|
|
108
|
+
- "Tempo ranges don't overlap (Basic Channel 120-130; J Dilla 85-95)
|
|
109
|
+
— defaulting to midpoint 108 BPM. Specify which anchor you want
|
|
110
|
+
or pick a single packet."
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Handling the `warnings` list
|
|
116
|
+
|
|
117
|
+
`warnings` is a signal the merge algorithm had to make a choice the
|
|
118
|
+
user's prompt didn't disambiguate. Surface every entry in your Phase 2
|
|
119
|
+
brief — DO NOT silently accept the defaulted value.
|
|
120
|
+
|
|
121
|
+
| Warning kind | What it means | What to do in the brief |
|
|
122
|
+
|---|---|---|
|
|
123
|
+
| **Tempo disjoint** | Source packets' tempo ranges don't overlap | Cite the ranges in the identity line, ask the user to pick an anchor or state a target tempo |
|
|
124
|
+
| **Favor union fallback** | `favor` lists had empty intersection, fell back to UNION | Note that the hybrid may span more move families than either source intends; lean harder on user framing in Phase 3 |
|
|
125
|
+
| **(Future warnings)** | Any future ambiguity the merge algorithm detects | Surface literally — don't paraphrase |
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Interoperability
|
|
130
|
+
|
|
131
|
+
- **`check_brief_compliance`** (v1.18.3): the hybrid brief passes
|
|
132
|
+
directly. The merged `avoid` list is also exposed as `anti_patterns`
|
|
133
|
+
for compat; `locked_dimensions` is always `[]` (hybrids don't lock).
|
|
134
|
+
- **Phase 3 plan candidates**: use `reach_for` to seed devices,
|
|
135
|
+
`avoid` as HARD filter on each candidate, `move_family_bias.favor` to
|
|
136
|
+
weight family diversity.
|
|
137
|
+
- **Phase 7 learning**: `source_packets` is preserved on the brief, so
|
|
138
|
+
when the user accepts a plan you can record which hybrid produced it
|
|
139
|
+
(taste over time).
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## Example: BC × Dilla
|
|
144
|
+
|
|
145
|
+
```python
|
|
146
|
+
brief = compile_hybrid_brief(["basic-channel", "j-dilla"])
|
|
147
|
+
|
|
148
|
+
# Merged avoid (UNION):
|
|
149
|
+
# bright top-end, dry signals, short tails, ... (BC)
|
|
150
|
+
# quantized drums, bright mixes, trap hi-hats, ... (Dilla)
|
|
151
|
+
# → result: both sets enforced
|
|
152
|
+
|
|
153
|
+
# Dimensions:
|
|
154
|
+
# BC deprioritizes [rhythmic]; Dilla deprioritizes [spatial]
|
|
155
|
+
# → INTERSECTION is empty → neither deprioritized in hybrid
|
|
156
|
+
# → UNION of in_scope is {structural, rhythmic, timbral, spatial}
|
|
157
|
+
|
|
158
|
+
# Favor:
|
|
159
|
+
# BC favor = {sound_design, device_creation, mix}
|
|
160
|
+
# Dilla favor = {arrangement, sound_design, device_creation}
|
|
161
|
+
# → INTERSECTION = {sound_design, device_creation}
|
|
162
|
+
# → hybrid plans cluster on sound_design + device_creation
|
|
163
|
+
|
|
164
|
+
# Tempo:
|
|
165
|
+
# BC 120-130, Dilla 85-95 → DISJOINT
|
|
166
|
+
# → warning surfaces; midpoint ~108 BPM returned
|
|
167
|
+
# → Brief must ask user to pick an anchor
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## What this is NOT
|
|
173
|
+
|
|
174
|
+
- **Not a taste classifier.** The merge is a syntactic operation over
|
|
175
|
+
packet fields. It doesn't judge whether the hybrid "makes sense" as
|
|
176
|
+
an artistic direction — that's the user's call.
|
|
177
|
+
- **Not a replacement for packet curation.** If the user asks for a
|
|
178
|
+
hybrid you've never heard of that doesn't resolve to existing
|
|
179
|
+
packets, `compile_hybrid_brief` raises `ValueError`. Fall back to
|
|
180
|
+
the narrative `.md` files and note the missing packet as v1.20+
|
|
181
|
+
scope.
|
|
182
|
+
- **Not for more than ~4 packets.** The merge runs at any N, but
|
|
183
|
+
target_dimensions weighted average gets noisy as N grows
|
|
184
|
+
("nothing is emphasized"). Prompts with 4+ references usually
|
|
185
|
+
deserve clarification, not automatic merging.
|