Instrument recognition v2 + capability-recognition audit & fixes - #1889
Merged
Conversation
…lity protocol Supersede the v1 SysEx protocol (52-byte identity, blocks 1/5/6/7, 32-bit feature-flag bitmask) with the v2 Instrument Recognition & Capability Protocol: - Block 1 handshake reduced to 24 bytes, pivoting on a per-exemplar instance_id plus descriptor_size / revision / 2-bit flags. - Block 0x10 chunked JSON descriptor transfer (level 1) and Block 0x11 change notification. - Rich descriptor model: voices, polyphony constraints, two-phase prepare/excite timing, consumable resources, per-family physical. - GMB-side override arbitration via cached-descriptor diff (section 6). Add section 12 documenting the compatibility verification against the current codebase: the outbound identity request already matches v2, parseIdentityReply() still assumes the 52-byte v1 frame, no block 5/6/7 consumer was ever implemented (clean removal), the capabilities_source CHECK constraint rejects the new "descriptor" value, and type/subtype/ note-mode keys line up with InstrumentTypeConfig.js and the schema. Fix two internal inconsistencies from the draft: a reference to a non-existent SYSEX_CAPABILITIES.md, and a stray reserved[2] field that conflicted with the stated 24-byte size. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BZ7sHZ9pTnJMt6h9Cus5mn
…cache Add the initial GMB-side scaffolding for the v2 Instrument Recognition & Capability Protocol (docs/SYSEX_IDENTITY.md): - DeviceManager.parseGmbHandshake() decodes the 24-byte v2 block 1 (proto_ver 0x02, instance_id, firmware, descriptor_size, revision, HTTP/push flags). parseIdentityReply() now tries it ahead of the 52-byte v1 frame, which is kept as a deprecated fallback. - instance_id / revision are decoded over the full 32 bits (high nibble 0x0f). The shared decode7BitTo32Bit() masks the 5th byte to 3 bits (0x07, 31-bit cap); reused as-is it would drop bit 31 of a per-exemplar instance_id and halve the id space, so the handshake uses a dedicated decode. instance_id persists into sysex_device_id via the existing saveSysExIdentity() path. - Migration 033 adds descriptor_revision + descriptor_json to instruments_latency (ETag + cached descriptor for the override diff, section 6). Additive only: widening the capabilities_source CHECK to allow 'descriptor' needs a table rebuild and is deferred (documented in section 12). Covered by tests/devicemanager-handshake-v2.test.js (12 tests). Full backend suite green (1108 tests). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BZ7sHZ9pTnJMt6h9Cus5mn
…tocol Rewrite wiki/Instrument-Developer-Guide.md for the v2 Instrument Recognition & Capability Protocol: level 0 (24-byte handshake) vs level 1 (JSON descriptor), per-exemplar instance_id derivation and its hardware sources, full-32-bit 7-bit encoding, chunked block 0x10 / HTTP descriptor serving, block 0x11 change notification, transport requirements, and a v1 migration note. The old v1 blocks 5/6/7 firmware guide is gone. Fix stale v1 references in sibling pages: - Interface-Instrument-Creation: "Block 5/6/7 SysEx" → level-1 descriptor (instruments list / physical block); drop capabilities_source='sysex'. - Interface-Hand-Management: CC wiring now declared via the descriptor's physical block, not Block 7. - Hardware-Integration: note the GMB v2 handshake alongside the Universal Identity Request; drop the stale line count. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BZ7sHZ9pTnJMt6h9Cus5mn
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Résumé
Fait évoluer la reconnaissance auto des instruments vers le protocole v2, audite toute la chaîne « reconnaissance des capacités », corrige les points bloquants, et câble le pipeline descripteur de bout en bout. Chaque changement est testé (1202 tests backend verts, ESLint/Prettier clean).
1. Protocole v2 (spec + firmware guide)
docs/SYSEX_IDENTITY.md— spec v1 → v2 : handshake 24 o (instance_idpar exemplaire,descriptor_size,revision,flags), transfert descripteur (0x10), notification (0x11), descripteur riche (voices, contraintes de polyphonie, timingprepare/excite, ressources,physical), arbitrage des surcharges (§6), + un §12 de vérification de compatibilité avec suivi des correctifs.2. Audit complet
docs/audit/AUDIT_INSTRUMENT_CAPABILITIES_2026-08-05.md— audit croisé (ingestion / stockage-validation / consommation), avec table de suivi des correctifs.3. Correctifs & implémentation
P1 — bugs (
fix(capabilities)) : mappingsaveSysExIdentity(sysex_family/model/versiontoujoursNULL), affichage modal identité, perte de configs à l'INSERT, durcissement des écritures (enum +MidiListParser).P2-1 — reconnaissance auto (
feat(devices)) :device_connectedémis + sonde d'identité debouncée à la connexion avec timeout/retries.P2-5 — gamme moteur (
feat(playback)) :octave_mode/scale_rootdésormais appliqués par le moteur (ScaleSnapper), plus seulement matérialisés par le frontend.P2-3 — enforcement live (
feat(routing)) : clamp stateless partagé (NoteEnforcement) appliqué au route-through temps réel + délégué par le scheduler.P2-2 — pipeline descripteur v2, câblé de bout en bout :
DescriptorProtocol(pur) — réassemblage bloc0x10(§3), validation §5, diff des surcharges §6, mapper §5→capacités, lookahead §9.DescriptorService— validate → applique chaque instrumentconfiguredau store de capacités → purge des surcharges §6 → broadcastinstruments_configured.DeviceManager— un handshake v2 niveau 1 déclenche le fetch séquentiel bloc0x10(timeout/retries) → réassemblage →DescriptorService. Enregistré dans le DI.P3 (
fix(capabilities)) : lecturepolyphonyrobuste (un 0 stocké désactivait le gate) + test unitaire du hot-pathgetTimingConstraints.Tests & couverture
Tout est couvert par des tests unitaires : mapping identité, sonde auto (fake timers),
ScaleSnapper, snap scheduler,NoteEnforcement, clamp routeur,DescriptorProtocol/DescriptorService, fetch0x10(fake timers),CapabilityResolver. 1202 tests / 101 suites verts. Les I/O DB et SysEx réelles ne sont pas intégration-testables ici (nibetter-sqlite3ni stack MIDI) — structurées autour de fonctions pures testées + la suite existante comme garde de non-régression.Restant (documenté §12 / suivi d'audit) : cache DB
revision/descripteur précédent, persistance des surcharges, écoute bloc0x11, chemin HTTP, valeurcapabilities_source='descriptor'(après migration CHECK —'auto'en attendant) ; filtragesupported_ccs, schémas d'enveloppe déclaratifs, voix secondaires côté moteur, enforcement stateful sur le live.🤖 Generated with Claude Code
https://claude.ai/code/session_01BZ7sHZ9pTnJMt6h9Cus5mn