feat: god-tier MIDI dimension expansion + full supercharge architecture (#73)
* feat: god-tier MIDI dimension expansion + full supercharge architecture
Expands the music plugin from 4 internal merge buckets to 21 fully independent MIDI dimensions, adds stable entity identity with MutateOp tracking, agent provenance with HMAC signing, an append-only op log, voice-aware Music RGA CRDT, music query DSL, invariants engine, and hierarchical bar-chunk manifests.
MIDI dimension expansion (midi_merge.py, plugin.py): - From 4 buckets (notes/harmonic/dynamic/structural) to 21 internal dims - pitch_bend, channel_pressure, poly_pressure now independent dimensions - CC split by controller: cc_modulation, cc_volume, cc_pan, cc_expression, cc_sustain, cc_portamento, cc_sostenuto, cc_soft_pedal, cc_reverb, cc_chorus, cc_other — all independently mergeable - tempo_map, time_signatures, track_structure remain non-independent - Backward-compatible user-facing aliases (melodic/rhythmic/harmonic/ dynamic/structural still work)
New core modules: - muse/core/provenance.py: AgentIdentity, HMAC-SHA256 signing, key I/O - muse/core/op_log.py: OpEntry, Lamport timestamps, append-only log, checkpointing, replay, to_structured_delta
New music plugin modules: - muse/plugins/music/entity.py: NoteEntity, EntityIndex, entity ID assignment, entity-aware diff with MutateOp - muse/plugins/music/_music_query.py: tokenizer, recursive descent parser, evaluator, run_query over commit history - muse/plugins/music/_invariants.py: InvariantRule/Report/Violation, 4 built-in checks (max_polyphony, pitch_range, key_consistency, no_parallel_fifths) - muse/plugins/music/manifest.py: BarChunk, TrackManifest, MusicManifest, hierarchical per-bar manifests, partial diff by bar hash - muse/plugins/music/_crdt_notes.py: NotePosition, RGANoteEntry, MusicRGA with voice-aware position ordering (bass→soprano)
Domain types (domain.py): FieldMutation, MutateOp, EntityProvenance Store types (core/store.py): 6 agent provenance fields on CommitRecord CLI: muse music-query, muse music-check registered in app.py Benchmark: tools/benchmark.py harness for parse/diff/merge/query/RGA Tests: 215 passing across 7 new test suites Docs: 5 architecture documents in docs/
* refactor: rename music→midi domain, strip all 5-dim backward compat
- Rename muse/plugins/music/ → muse/plugins/midi/ (git mv, history preserved) - Rename _music_query.py → _midi_query.py - Rename CLI commands: music_check → midi_check, music_query → midi_query with updated command names (music-check→midi-check, music-query→midi-query) - Change _DOMAIN_TAG from "music" to "midi" in plugin.py - Rename MusicPlugin → MidiPlugin everywhere; update registry and all imports - Change default domain: "music" → "midi" in init.py and registry.py - Remove all 5-dimension backward-compat aliases from DIM_ALIAS: melodic, rhythmic, harmonic, dynamic, structural — gone entirely - Rewrite test_domain_schema.py: tests all 21 MIDI dimensions by name, schema kind, and independence flag; asserts "music" no longer in registry - Rewrite test_music_midi_merge.py: tests all 21-dim _classify_event routing, per-dimension conflict detection, independent auto-merge, and strategy rules; removes all references to old coarse dimension names - Update test_core_attributes.py examples to use new MIDI dimension names - Update all doc files and README.md: replace 5-dim descriptions with 21-dimension MIDI schema; update module paths and class names throughout
* feat: implement 3 missing plan items — property tests, format_version, schema auto-dispatch
Three gaps from the supercharge plan now fully implemented:
1. **hypothesis property-based tests** (`tests/test_property_based.py`) - All six CRDT types (LWWRegister, VectorClock, ORSet, RGA, AWMap, GCounter) verified against commutativity, associativity, and idempotency with @given - LCS round-trip: self-diff → empty ops, empty-base, empty-target, content provenance, op-count upper bound - OT diamond property: for arbitrary concurrent InsertOp pairs, applying transform() in either order produces identical final sequences
2. **Bug fixes discovered by hypothesis** - LWWRegister.join: non-commutative when (timestamp, author) tie but values differ — added value as deterministic tiebreaker - RGA.join: non-commutative when same element ID has different values across replicas — added lexicographic value tiebreaker
3. **CommitRecord.format_version** (`muse/core/store.py`) - New field tracks schema evolution: 1=base, 2=structured_delta, 3=sem_ver, 4=agent provenance; new commits write version 4; old JSON defaults to 1
4. **snapshot_diff() auto-dispatch** (`muse/core/diff_algorithms/__init__.py`) - Public function: given a DomainSchema + two SnapshotManifests → StructuredDelta - ScaffoldPlugin.diff() now delegates to snapshot_diff() — zero set-algebra boilerplate - New plugin authors call snapshot_diff(self.schema(), base, target) for free file-level diffs without implementing diff() from scratch
All verified: 1319 pytest tests green, mypy 0 errors, typing_audit 0 violations.
---------
Co-authored-by: Gabriel Cardona <gabriel@tellurstori.com>
Comments
0No comments yet. Be the first to start the discussion.