Comprehensive MIDI 2.0 Specification Audit Report
Initial Audit Date: 2025-12-13
Last Updated: 2025-12-16
Repository: Fountain-Coach/midi2
Version: 0.9.0 (TypeScript), 0.9.0 (Swift)
Audited Against: MIDI Association Normative Specifications (M2-100 through M2-116)
Note: This is the initial comprehensive audit. Subsequent updates should maintain version history and update the "Last Updated" date above. Metrics below reflect the latest static counts (0.9.0 release); see spec-compliance-dashboard.md for live gap status.
Executive Summary
This comprehensive audit evaluates the alignment between the midi2 repository implementation (Swift and TypeScript/JavaScript) and the MIDI 2.0 normative specifications published by the MIDI Association. The repository maintains dual canonical machine-readable artifacts (midi2.full.closed.schema.json and midi2.full.openapi.json) that serve as the single source of truth for both implementations.
Overall Assessment
Strengths:
- Excellent schema-to-implementation alignment with comprehensive OpenAPI/JSON Schema definitions
- Strong coverage of core UMP message types (Channel Voice 1.0/2.0, System, Utility, Stream)
- Robust MIDI-CI implementation with Property Exchange chunking and compression
- Active spec-audit log with page-level traceability to normative PDFs
- Broad automated tests (~354 Swift test cases across 117 files; ~199 TypeScript tests across 32 files)
- Well-documented gaps and ongoing conformance tracking
Key Gaps Identified:
- Function Block Semantics: Descriptor details beyond index/group range; (GTB negotiation implemented)
- Reserved/Unsupported Handling: Inconsistent placeholder handling across decoders
- Hardware Interop: No tests against external MIDI-CI devices
- TypeScript Coverage: Several areas marked as partial in gap-plan.md
- Visual Regression: VRT-Protocol baseline frames incomplete for CI messages
1. UMP Encode/Decode Implementation
1.1 Coverage Status
Swift Implementation
Status: ✅ Comprehensive
Evidence:
- Channel Voice 1.0:
Sources/MIDI2/Midi1ChannelVoiceBody.swift - Channel Voice 2.0:
Sources/MIDI2/Midi2ChannelVoiceBody.swift- Per-note controllers:
Sources/MIDI2/Midi2AssignPerNoteController.swift - RPN/NRPN: Absolute and relative variants
- Per-note controllers:
- Utility Messages:
Sources/MIDI2/UtilityBody.swift,Sources/MIDI2/UtilityOpcode.swift - System Messages:
Sources/MIDI2/SystemCommonRealtimeBody.swift - Stream Messages:
Sources/MIDI2/StreamBody.swift,Sources/MIDI2/StreamOpcode.swift - Data Messages: SysEx7/8, Mixed Data Set support
- Function Blocks:
Sources/MIDI2/Stream/FunctionBlockMessage.swift
Schema Alignment: All message types reflected in midi2.full.closed.schema.json $defs:
UmpMessageTypeenum (0, 1, 2, 3, 4, 5, 13, 15)Midi1ChannelVoiceBody,Midi2ChannelVoiceBodySystemCommonRealtimeBody,UtilityBodyStreamBody,FlexDataBodyDataMessageBody
Tests:
- Reserved-bit validation:
Tests/MIDI2Tests/StreamReservedBitsTests.swift - Typed message tests:
Tests/MIDI2Tests/StreamTypedTests.swift - SysEx fragmentation:
Tests/MIDI2Tests/SysEx8Tests.swift - Invalid sequences:
Tests/MIDI2Tests/SysEx8InvalidSequenceTests.swift
TypeScript Implementation
Status: ✅ Comprehensive (with noted gaps)
Evidence:
- UMP core:
midi2.js/src/ump.ts - Decoder:
midi2.js/src/decoder.ts - MIDI 1.0 compat:
midi2.js/src/midi1.ts - SysEx fragmentation:
midi2.js/src/sysex.ts - Schema bridge:
midi2.js/src/schema-bridge.ts - OpenAPI types:
midi2.js/src/generated/openapi-types.ts
Tests:
- UMP tests:
midi2.js/src/__tests__/ump.test.ts - Decoder tests:
midi2.js/src/__tests__/decoder.test.ts - MIDI 1.0 tests:
midi2.js/src/__tests__/midi1.test.ts - Schema bridge:
midi2.js/src/__tests__/schema-bridge.test.ts - Stream reserved:
midi2.js/src/__tests__/stream-reserved.test.ts
1.2 Identified Gaps
Gap 1.2.1: Reserved/Unsupported Status Handling
Severity: Medium
Spec Reference: M2-104-UM v1.1.2 (various sections)
Current State: Partial implementation with negative tests for Stream §5 and SysEx8, but inconsistent across all decoders.
Evidence:
docs/conformance-checklist.md: "Future reserved message IDs: Partial"legacy/midi2-js-gap-plan.md: "Reserved/unsupported statuses: unify placeholder handling across decoders; broaden negative tests."
Recommended Action:
- Create a comprehensive table of all reserved opcodes, status values, and bit patterns from M2-104-UM
- Implement consistent error handling/rejection across Swift and TypeScript decoders
- Add negative test vectors for each reserved value category
- Update schema with explicit reserved value documentation
Priority: Medium
Effort: Medium (2-3 days)
Gap 1.2.2: UMP Format Extensions
Severity: Low
Spec Reference: M2-104-UM v1.1.2 (Future Extensions)
Current State: Utility messages beyond JR are partial.
Evidence:
docs/conformance-checklist.md: "Utility messages beyond JR: Partial"
Recommended Action:
- Document which utility opcodes beyond Jitter Reduction are currently supported
- Add placeholders for future utility message types with clear deprecation notices
- Ensure schema allows for forward compatibility
Priority: Low
Effort: Low (1 day)
2. MIDI-CI Implementation
2.1 Coverage Status
Swift Implementation
Status: ✅ Strong (with runtime gaps)
Components:
- Discovery:
Sources/MIDI2/MidiCiDiscoveryBody.swift - Profiles:
Sources/MIDI2/MidiCiProfilesBody.swift- Session management:
Sources/MIDI2CI/ProfileSession.swift - Profile Specific Data:
Sources/MIDI2CI/ProfileSpecificData.swift - Inquiry:
Sources/MIDI2CI/ProfileInquiry.swift
- Session management:
- Property Exchange:
Sources/MIDI2/MidiCiPropertyExchangeBody.swift- Runtime:
Sources/MIDI2CI/PropertyExchange.swift - Compression:
Sources/MIDI2CI/CompressionCodec.swift(zlib, mcoded7)
- Runtime:
- Process Inquiry:
Sources/MIDI2/MidiCiProcessInquiryBody.swift- Session:
Sources/MIDI2CI/ProcessInquirySession.swift
- Session:
- ACK/NAK:
Sources/MIDI2/MidiCiAckNakBody.swift - Envelope:
Sources/MIDI2/MidiCiEnvelope.swift - Handshake:
Sources/MIDI2CI/CIHandshake.swift - Protocol Negotiation:
Sources/MIDI2CI/ProtocolNegotiation.swift
Tests:
- Integration:
Tests/MIDI2Tests/MidiCiHandshakeIntegrationTests.swift - Profile sessions:
Tests/MIDI2Tests/ProfileSessionTests.swift - Property Exchange chunking:
Tests/MIDI2Tests/PropertyExchangeChunkingTests.swift - Compression:
Tests/MIDI2Tests/PropertyExchangeCompressionTests.swift
Schema Coverage:
- All MIDI-CI message types defined in
MidiCiEnvelope,MidiCiDiscoveryBody,MidiCiProfilesBody,MidiCiPropertyExchangeBody,MidiCiProcessInquiryBody,MidiCiAckNakBody - Spec-audit log shows 28 captured entries for MIDI-CI fields with page references
TypeScript Implementation
Status: ✅ Good (envelopes; runtime gaps)
Components:
- MIDI-CI core:
midi2.js/src/midici.ts - PE subscriptions:
midi2.js/src/pe-subscriptions.ts
Tests:
- PE subscriptions:
midi2.js/src/__tests__/pe-subscriptions.test.ts - OpenAPI types:
midi2.js/src/__tests__/openapi-types.test.ts
2.2 Identified Gaps
Gap 2.2.1: Property Exchange Subscription Lifecycle
Status: ✅ Implemented
Spec Reference: M2-103-UM v1.2, Tables 43-47 (p.42-43)
Current State: Runtime state machine implemented in Swift (PropertyExchangeSession / PropertyExchangeSubscriptionManager) and TypeScript (PeSubscriptionManager). Handles start/partial/full/notify/end, resource matching, flow-control ACK/NAK, timeout backoff, and capped retries. Tests cover lifecycle, out-of-order chunks, timeouts, and resource mismatches (Tests/MIDI2Tests/PropertyExchangeSubscriptionTests.swift, midi2.js/src/__tests__/pe-subscriptions.test.ts).
Residual Risks: No real-device interop exercised; flow-control retry limits are policy defaults (configurable). Consider field trials with external devices.
- Proper NAK retransmit behavior
Gap 2.2.2: Profile Configuration Details and Reports
Severity: Medium
Spec Reference: M2-102-U v1.1, Table 6 (p.15, 17)
Current State: Details replies include version and channel mask; PSD supported; added/removed helpers present.
Evidence:
docs/conformance-checklist.md: "Profile Configuration Details: Partial"- Profile detail/added-removed reports need negative tests
Recommended Action:
- Expand profile detail report handling beyond basic version/channel mask
- Add comprehensive tests for profile added/removed notifications
- Implement profile configuration change tracking
- Add negative test cases for malformed profile detail messages
Priority: Medium
Effort: Medium (2-3 days)
Gap 2.2.3: Process Inquiry Implementation
Status: ✅ Addressed (runtime validation added)
Spec Reference: M2-101-UM v1.2, Table 40-42 (p.59-60)
Current State:
- Device ID scope validation enforced in
ProcessInquirySession(0x00–0x0F, 0x7E, 0x7F). - Message Report replies now clamp to supported filters and drop unsupported keys (intersection + min).
- Tests cover capability inquiry, message report clamping, and invalid device IDs.
Remaining Watchpoints:
- Expand coverage to full bitmap permutations if needed (system/channel/note message bitmaps).
Gap 2.2.4: MUID Management
Severity: Medium
Spec Reference: M2-101-UM v1.2 (MUID allocation/discovery)
Current State: Basic MUID handling exists but coverage is thin.
Evidence:
legacy/midi2-js-gap-plan.md: "MUID management coverage is thin"
Recommended Action:
- Implement comprehensive MUID allocation/deallocation
- Add MUID conflict detection and resolution
- Implement MUID timeout and cleanup
- Add tests for MUID lifecycle scenarios
Priority: Medium
Effort: Low-Medium (2-3 days)
3. Flex Data Implementation
3.1 Coverage Status
Swift Implementation
Status: ✅ Implemented
Evidence:
- Flex Data body:
Sources/MIDI2/FlexDataBody.swift - Demo:
Sources/midi2demo/Flex.swift - Schema definitions for all Flex types in
midi2.full.closed.schema.json:Flex.Tempo,Flex.TimeSignature,Flex.MetronomeFlex.KeySignature,Flex.ChordNameFlex.Lyric,Flex.Text,Flex.Ruby
Tests: Negative tests included in general UMP test suite
TypeScript Implementation
Status: ✅ Implemented
Evidence:
legacy/midi2-js-gap-plan.md: "Flex Data, SysEx7/8 fragment/reassemble" marked as done- OpenAPI-derived guards cover Flex Data types
3.2 Identified Gaps
Gap 3.2.1: Flex Data Validation and Edge Cases
Severity: Low
Spec Reference: M2-104-UM v1.1.2 (Flex Data sections)
Current State: Basic encoding/decoding works, but edge case validation may be incomplete.
Recommended Action:
- Add comprehensive validation for:
- Tempo range limits
- Time signature validity
- Metronome clock patterns
- Text encoding boundaries (UTF-8 validation)
- Add edge case tests:
- Maximum string lengths for Text/Lyric/Ruby
- Invalid chord names
- Reserved flex data opcodes
Priority: Low
Effort: Low (1-2 days)
4. Stream Configuration and Function Blocks
4.1 Coverage Status
Swift Implementation
Status: ✅ Implemented (runtime + validation)
Evidence:
- Endpoint Discovery:
Sources/MIDI2/Stream/EndpointDiscoveryMessage.swift- Major/minor version, max groups, reserved validation
- Stream Config:
Sources/MIDI2/Stream/StreamConfigurationMessage.swift- Typed fields, reserved-bit validation
- Function Blocks:
Sources/MIDI2/Stream/FunctionBlockMessage.swift- Index, firstGroup, groupCount fields
- Discovery:
Sources/MIDI2/Stream/FunctionBlockDiscovery.swift
- Group Terminal Blocks:
Sources/MIDI2/Stream/GroupTerminalBlocks.swift - Demo:
Sources/midi2demo/StreamConfig.swift
Tests:
- Mapping:
Tests/MIDI2Tests/StreamMappingTests.swift - Reserved bits:
Tests/MIDI2Tests/StreamReservedBitsTests.swift - Typed messages:
Tests/MIDI2Tests/StreamTypedTests.swift - Function Block discovery:
Tests/MIDI2Tests/StreamFunctionBlockDiscoveryTests.swift - GTB:
Tests/MIDI2Tests/GroupTerminalBlocksTests.swift
Schema Coverage:
StreamBody.endpointDiscoverywith filter bitmap (p.33, Figure 12)StreamBody.endpointInfoNotification(p.33, Figure 13)StreamBody.deviceIdentityNotification(p.34, Figure 14)StreamBody.endpointNameNotification(p.35, Figure 15)StreamBody.productInstanceIdNotification(p.35, Figure 16)StreamBody.functionBlockInfo(p.40, Figure 22)FunctionBlockNameNotification(p.41-42, Figure 23)- Stream opcodes 0x00-0x06, 0x10-0x12, 0x20-0x21 defined
TypeScript Implementation
Status: 🟢 Good
Evidence:
legacy/midi2-js-gap-plan.md: "Endpoint/Device Info payload fidelity and GTB semantics: tighten encode/decode and add vectors"
4.2 Status
-- Function Block descriptor runtime validation implemented (FunctionBlockInfoNotification, GroupTerminalBlocks): direction/bandwidth/active enforced, reserved bits rejected, round-trip tests in StreamMappingTests.
- GTB negotiation implemented: overlap/coverage validation, per-group allowed MT maps, ingress/egress guards (Swift
NegotiationSession+GTBValidator; TSgtb-validator,gtb-guards, decoder guards). VRT-Protocol fixtures for blocking MT=0x0/0xF and overlap cases.
Gap 4.2.2: GTB Negotiation Semantics
Status: ✅ Implemented
Spec Reference: M2-104-UM v1.1.2, Appendix I (p.122)
Current State:
- GTB-FB overlap/coverage validation enforced (
GTBValidator.validate), allow-overlap escape hatch documented. - GTB descriptors ingested into negotiation sessions (
applyGTBDescriptor,negotiate(gtbDescriptor:)) with per-group allowed MT maps. - Ingress/egress MT enforcement for GTB-restricted groups (Swift guards on UMP words; TS decoder/dispatch/gtb-guards).
- Tests:
Tests/MIDI2Tests/GroupTerminalBlocksTests.swift,midi2.js/src/__tests__/gtb-*, VRT-Protocol fixturesdocs/vrt-protocol/stream/gtb_block_mt.json,gtb_block_utility.json,gtb_overlap.json.
Residual Risks:
- Hardware interop unvalidated (USB GTB descriptors not yet captured from devices); policy defaults allow manual descriptor injection.
Priority: High
Effort: Medium-High (4-5 days)
Gap 4.2.3: Stream Configuration Semantics
Severity: Medium
Spec Reference: M2-104-UM v1.1.2, Figures 18/19 (p.37-38), Section 7.2.2.3 (p.45)
Current State: Basic protocol/JR fields captured, but negotiation flow incomplete.
Evidence:
docs/spec-audit.md: Row 17 - "JR Tx/Rx descriptions note receivers should send Stream Config Notification to switch protocols if JR is unsupported"- Protocol bits (0x01 MIDI 1.0, 0x02 MIDI 2.0, others reserved) defined
Recommended Action:
- Implement JR fallback behavior when receiver doesn't support JR
- Add protocol switching logic (MIDI 1.0 ↔︎ MIDI 2.0)
- Implement Stream Config Notification sending on capability mismatch
- Add test scenarios for negotiation failures and fallbacks
Priority: Medium
Effort: Medium (3-4 days)
Gap 4.2.4: Endpoint Info Beyond Version/Max Groups
Severity: Medium
Spec Reference: M2-104-UM v1.1.2, Figure 13 (p.33)
Current State: Major/minor version and max groups captured; additional fields need attention.
Evidence:
docs/conformance-checklist.md: "Gap: Device Info/advertisement content (beyond version/max groups)"- Schema has
endpointInfoNotificationwith staticFunctionBlocks, numberOfFunctionBlocks, UMP version, MIDI2/MIDI1 support flags, JR capability flags
Recommended Action:
- Ensure all Endpoint Info Notification fields are properly encoded/decoded:
- Static Function Blocks flag (S bit)
- Number of Function Blocks (0x00-0x20 valid, 0x21-0x7F reserved)
- UMP version major/minor
- M2/M1 support flags
- RXJR/TXJR capability flags
- Add runtime validation for reserved numberOfFunctionBlocks values (0x21-0x7F)
- Add comprehensive test vectors
Priority: Medium
Effort: Low-Medium (2 days)
5. Scheduling and Adapters (TypeScript)
5.1 Coverage Status
Status: ✅ Good (with optimization opportunities)
Evidence:
- Scheduler:
midi2.js/src/scheduler.ts - Clock:
midi2.js/src/clock.ts - Jitter:
midi2.js/src/jitter.ts - Adapters:
- WebAudio:
midi2.js/src/adapters/webaudio.ts - Three.js:
midi2.js/src/adapters/three.ts - Cannon.js:
midi2.js/src/adapters/cannon.ts
- WebAudio:
Tests:
- Scheduler:
midi2.js/src/__tests__/scheduler.test.ts - Jitter:
midi2.js/src/__tests__/jitter.test.ts - Worker clock:
midi2.js/src/__tests__/jitter.worker.test.ts
DoD Criteria (from legacy/midi2-js-dod.md):
- ✅ Scheduler delivers time-ordered events with jitter tolerance
- ✅ Supports browser, AudioContext, and worker/off-main-thread clocks
- ✅ Deterministic record/replay API
- ✅ WebAudio: voice allocation, per-note controllers, pitch bend range, channel pressure, safe disposal
- ✅ Three.js: mapping primitives with hooks
- ✅ Cannon.js: body creation/removal and impulse mapping
5.2 Identified Gaps
Gap 5.2.1: Worker-Clock JR Projection
Severity: Medium
Spec Reference: M2-104-UM v1.1.2 (Jitter Reduction)
Current State: Worker clock tests exist, but JR projection coverage needs expansion.
Evidence:
legacy/midi2-js-gap-plan.md: "Worker-clock JR projection: add coverage for off-main-thread clocks and jitter mapping"
Recommended Action:
- Add comprehensive worker-clock JR projection tests
- Validate timestamp propagation across worker boundaries
- Test clock drift compensation in worker contexts
- Add performance benchmarks for worker-based JR
Priority: Medium
Effort: Low-Medium (2-3 days)
Gap 5.2.2: Adapter Per-Note Controller Negotiation
Severity: Medium
Spec Reference: MIDI 2.0 Per-Note Controllers
Current State: Basic per-note controller support exists; negotiation needs hardening.
Evidence:
legacy/midi2-js-gap-plan.md: "Adapters: add per-note controllers/pitch-bend range negotiation and disposal safety tests"
Recommended Action:
- Implement proper per-note controller negotiation in WebAudio adapter
- Add pitch-bend range negotiation and validation
- Add disposal safety tests for all adapters
- Test multi-group streams with deterministic replay
Priority: Medium
Effort: Medium (2-3 days)
6. Jitter Reduction Implementation
6.1 Coverage Status
Swift Implementation
Status: ✅ Implemented
Evidence:
- JR Clock sender:
Sources/MIDI2/System/Utility.swift - JR Receiver:
Sources/MIDI2/System/JitterReductionReceiver.swift - Demo:
Sources/jitterdemo/JitterApp.swift - Tests:
Tests/MIDI2Tests/System/JitterReductionTests.swift - VRT-Protocol baseline:
jr/clock_timestamp.json(referenced in conformance checklist)
TypeScript Implementation
Status: ✅ Implemented
Evidence:
- JR core:
midi2.js/src/jitter.ts - Tests:
midi2.js/src/__tests__/jitter.test.ts,midi2.js/src/__tests__/jitter.worker.test.ts
6.2 Identified Gaps
Gap 6.2.1: JR Interop Testing
Severity: Low
Spec Reference: M2-104-UM v1.1.2, Section 7.2.2.3 (p.45)
Current State: Implementations exist with unit tests, but no hardware interop testing.
Evidence:
docs/conformance-checklist.md: "Interop with hardware: Missing... Gap: Capture/verify against official MIDI-CI device responses and JR sync"
Recommended Action:
- Create JR interop test suite using hardware devices or reference implementations
- Validate clock/timestamp send/receive cycles
- Test JR fallback behavior when unsupported
- Document JR interop results
Priority: Low
Effort: Medium (depends on hardware availability)
7. SysEx Packetization
7.1 Coverage Status
Status: ✅ Implemented
Evidence:
- Swift:
- SysEx7:
Sources/MIDI2/SysEx7Packet.swift - SysEx8:
Sources/MIDI2/Data/SysEx8.swift - Tests:
Tests/MIDI2Tests/SysEx8Tests.swift,Tests/MIDI2Tests/SysEx8InvalidSequenceTests.swift - VRT-Protocol:
sysex8/invalid_cases.json - Demos:
Sources/midi2demo/SysEx7.swift,Sources/midi2demo/SysEx8.swift
- SysEx7:
- TypeScript:
- SysEx core:
midi2.js/src/sysex.ts
- SysEx core:
Spec Compliance:
- ✅ Fragmentation/reassembly
- ✅ Continuation/termination flags
- ✅ Invalid sequence detection and rejection
- ✅ Edge case testing
7.2 Identified Gaps
Gap 7.2.1: Oversize SysEx Handling
Severity: Low
Spec Reference: M2-104-UM v1.1.2 (SysEx maximum sizes)
Current State: Basic fragmentation works; oversize handling needs validation.
Evidence:
legacy/midi2-js-gap-plan.md: "Expand reserved-bit/range checks for stream/flex/CI envelopes; add oversize SysEx and invalid chunk-order tests"
Recommended Action:
- Define maximum SysEx sizes per spec
- Add tests for SysEx exceeding maximum size
- Implement proper error handling for oversized messages
- Add fragmentation tests at boundary sizes
Priority: Low
Effort: Low (1 day)
8. Testing and Validation
8.1 Current State
Swift:
- ~117 test files (~354 test cases)
- Comprehensive coverage including:
- UMP message types
- Stream configuration
- MIDI-CI flows and Process Inquiry
- Property Exchange chunking and compression
- JR clock/timestamp
- SysEx7/8 fragmentation
- Invalid sequence detection
- Negative tests for reserved values
- Fuzz testing:
Tests/Fuzz/with SwiftCheck - CI integration:
.github/workflows/ci.yml
TypeScript:
- 32 test files with ~199 tests
- Coverage areas:
- UMP encoding/decoding
- MIDI-CI envelopes and PE subscriptions
- Schema bridge validation
- Stream/GTB negotiation tests
- Scheduler and clocks
- JR worker tests
- Negative/reserved value tests
- OpenAPI type conformance
- CI:
npm run ci(codegen + typecheck + vitest)
8.2 Identified Gaps
Gap 8.2.1: Visual Baseline (VRT-Protocol) Frames
Severity: Medium
Spec Reference: Internal testing methodology
Current State: Some VRT-Protocol baselines exist (JR, SysEx8 invalid cases), but CI messages incomplete.
Evidence:
docs/conformance-checklist.md: "Gap: Visual baseline frames for CI messages, automated diffs"docs/traceability.md: "VRT-Protocol pending for edge sequences" and "VRT-Protocol pending" for JR
Recommended Action:
- Create VRT-Protocol baseline JSON files for all major MIDI-CI message types
- Add automated schema regression checks in CI
- Implement visual diff tooling for baseline comparisons
- Expand to cover all Stream message variants
Priority: Medium
Effort: Medium (3-4 days)
Gap 8.2.2: Hardware Interop Tests
Severity: Medium
Spec Reference: Real-world MIDI 2.0 devices
Current State: No tests against external devices.
Evidence:
docs/conformance-checklist.md: "Interop with hardware: Missing... Gap: Capture/verify against official MIDI-CI device responses and JR sync"
Recommended Action:
- Establish test infrastructure for hardware device communication
- Create test suite against reference MIDI 2.0 implementations
- Validate MIDI-CI discovery/handshake with real devices
- Test JR sync with hardware implementations
- Document interop results and any discovered incompatibilities
Priority: Medium
Effort: High (requires hardware access and setup)
Gap 8.2.3: Negative Test Coverage Expansion
Severity: Medium
Spec Reference: M2-104-UM v1.1.2 (reserved values throughout)
Current State: Some negative tests exist (Stream, SysEx8, MDS, profiles, PE compression), but coverage is incomplete.
Evidence:
legacy/midi2-js-gap-plan.md: "Expand reserved-bit/range checks for stream/flex/CI envelopes"docs/conformance-checklist.md: "Negative tests for unsupported statuses; gap: broaden across all decoders"
Recommended Action:
- Create comprehensive negative test matrix covering:
- All reserved opcodes
- Out-of-range values for all bounded fields
- Invalid bit patterns
- Malformed packet structures
- Ensure consistent error reporting across Swift and TypeScript
- Add fuzzing tests for randomized invalid inputs
Priority: Medium
Effort: Medium-High (4-5 days)
9. Schema and OpenAPI Alignment
9.1 Current State
Status: ✅ Excellent
The repository maintains dual canonical artifacts:
midi2.full.closed.schema.json(2336 lines)midi2.full.openapi.json(2390 lines)
Schema Coverage: 63 type definitions including:
- Base types (Uint4, Uint7, Uint8, Uint14, Uint16, Uint21, Uint28, Uint32, Int32)
- UMP message types and headers
- All Channel Voice message variants (MIDI 1.0 and 2.0)
- System/Utility/Stream/Flex/Data message bodies
- Complete MIDI-CI message definitions
- Function Block and Stream configuration structures
OpenAPI Integration:
- TypeScript: Auto-generated types via
midi2.js/scripts/generate-openapi-types.mjs - Runtime guards: OpenAPI-derived validation
- CI integration:
npm run codegen+ typecheck
Spec Audit Log: 52 captured entries with page-level references to normative PDFs
9.2 Identified Gaps
Gap 9.2.1: Schema Documentation Completeness
Severity: Low
Spec Reference: Internal documentation standards
Current State: Most schema fields have descriptions with page references; some could be expanded.
Recommended Action:
- Ensure every schema field has:
- Clear description
- Spec reference (document, page, figure/table number)
- Valid value ranges
- Reserved value documentation
- Add examples for complex structures
- Cross-reference between related fields
Priority: Low
Effort: Medium (3-4 days; ongoing maintenance)
Gap 9.2.2: Schema Regression in CI
Severity: Medium
Spec Reference: Internal quality assurance
Current State: TypeScript has codegen check, but no automated schema drift detection.
Evidence:
legacy/midi2-js-gap-plan.md: "Ensure OpenAPI guard regeneration is part of CI (fail on drift)"
Recommended Action:
- Add CI check to verify OpenAPI codegen is up-to-date
- Fail build if generated types drift from schema
- Add validation that both schemas (JSON Schema and OpenAPI) remain in sync
- Create diff tool to detect schema changes
Priority: Medium
Effort: Low (1-2 days)
10. Documentation Alignment
10.1 Current State
Comprehensive Documentation:
- Main README with installation and usage examples
- Spec audit log with page-level traceability (
docs/spec-audit.md) - Conformance checklist (
docs/conformance-checklist.md) - Traceability matrix (
docs/traceability.md) - Gap plans for TypeScript (
legacy/midi2-js-gap-plan.md) - Definition of Done (
legacy/midi2-js-dod.md) - Current plan (
PLAN.md)
DoD Status:
- Swift: Most criteria met; gaps clearly documented
- TypeScript: Strong foundation; several areas marked 🚧 partial
10.2 Identified Gaps
Gap 10.2.1: DoD Validation Against Current State
Severity: Low
Spec Reference: legacy/midi2-js-dod.md
Current State: DoD documents exist but need validation against actual implementation.
Recommended Action:
- Create automated DoD checklist validator
- Cross-reference each DoD criterion with actual tests/code
- Update DoD documents to reflect current 0.7.0/0.4.0 state
- Add missing items from DoD to gap plans
Priority: Low
Effort: Low-Medium (2-3 days)
Gap 10.2.2: Unified Audit Report
Severity: Low
Spec Reference: This document
Current State: Information scattered across multiple documents.
Recommended Action:
- Consolidate audit findings into single comprehensive report (this document)
- Maintain regular update cadence
- Add executive dashboard for stakeholders
- Track gap closure progress with metrics
Priority: Low
Effort: Low (ongoing maintenance)
11. Actionable Recommendations
11.1 High Priority Items (1-2 weeks)
Property Exchange Subscription Lifecycle Implementation (Gap 2.2.1)
- Effort: 5-7 days
- Impact: Critical for complete MIDI-CI compliance
- Deliverables: State machine, flow-control ACK/NAK handlers, comprehensive tests
Function Block Descriptor Details (Gap 4.2.1)
- Effort: 4-5 days
- Impact: Required for full Stream §5 compliance
- Deliverables: Extended FunctionBlockMessage, direction/bandwidth/active fields, tests
GTB Negotiation Semantics (Gap 4.2.2)
- Effort: 4-5 days
- Impact: Important for USB-MIDI 2.0 interop
- Deliverables: GTB-FB interaction logic, protocol restrictions, tests
11.2 Medium Priority Items (2-4 weeks)
Negative Test Coverage Expansion (Gap 8.2.3)
- Effort: 4-5 days
- Impact: Robustness and spec compliance validation
- Deliverables: Comprehensive negative test matrix
Visual Baseline (VRT-Protocol) Frames (Gap 8.2.1)
- Effort: 3-4 days
- Impact: Regression prevention for schema changes
- Deliverables: VRT-Protocol baselines for all message types, automated diff tool
Profile Configuration Details (Gap 2.2.2)
- Effort: 2-3 days
- Impact: Complete MIDI-CI Profile support
- Deliverables: Extended profile detail handling, negative tests
Process Inquiry Enhancement (Gap 2.2.3)
- Effort: 2-3 days
- Impact: Full MIDI-CI Process Inquiry compliance
- Deliverables: Bitmap validation, device ID scope, message control enforcement
Stream Configuration Semantics (Gap 4.2.3)
- Effort: 3-4 days
- Impact: Protocol negotiation robustness
- Deliverables: JR fallback, protocol switching, capability mismatch handling
MUID Management (Gap 2.2.4)
- Effort: 2-3 days
- Impact: MIDI-CI reliability
- Deliverables: MUID lifecycle, conflict resolution, timeout handling
Hardware Interop Tests (Gap 8.2.2)
- Effort: High (depends on hardware)
- Impact: Real-world validation
- Deliverables: Interop test suite, results documentation
11.3 Low Priority Items (Ongoing)
Reserved/Unsupported Status Handling (Gap 1.2.1) – Complete
- Swift/TS decoders now reject reserved/unknown statuses for Flex/System/Channel Voice with aligned negative vectors.
Adapter Enhancements (Gap 5.2.2)
- Effort: 2-3 days
- Impact: TypeScript adapter robustness
- Deliverables: Per-note negotiation, disposal safety tests
Worker-Clock JR Projection (Gap 5.2.1)
- Effort: 2-3 days
- Impact: Worker context reliability
- Deliverables: Comprehensive worker JR tests
Flex Data Edge Cases (Gap 3.2.1) – Complete
- Tempo range, text-length, and metronome accent validations enforced (Swift + TS) with new negative tests.
Schema Documentation (Gap 9.2.1)
- Effort: Ongoing
- Impact: Developer experience
- Deliverables: Complete field descriptions, examples
DoD Validation (Gap 10.2.1)
- Effort: 2-3 days
- Impact: Project tracking
- Deliverables: Automated checklist validator
12. Spec Audit Log Summary
12.1 Completed Items
Total Captured: 49 entries (all marked "Captured")
Coverage by Specification:
- M2-104-UM v1.1.2 (UMP/Protocol): 26 entries
- Stream messages, opcodes, Function Blocks, Endpoint Discovery, JR, etc.
- M2-101-UM v1.2 (MIDI-CI): 3 entries
- Process Inquiry envelopes and fields
- M2-102-U v1.1 (Profiles): 1 entry
- Profile configuration messages
- M2-103-UM v1.2 (Property Exchange): 19 entries
- PE headers, chunking, flow control, subscriptions, status codes
Page Reference Coverage: All entries have page numbers and figure/table references
12.2 Pending Items
Total Pending: 3 entries
USB Group Terminal Block considerations (M2-104-UM v1.1.2, p.122)
- Status: Pending
- Reason: Runtime/interop guidance; schema complete
- Action: Document GTB-FB overlap, implement restrictions
PE subscription lifecycle (M2-103-UM v1.2, Tables 43-47)
- Status: Pending (runtime)
- Reason: Schema fields present; state machine needed
- Action: Implement subscription state tracking
TODOs in documentation
- "Iterate through each spec section, fill in page references"
- Action: Continue systematic spec review
12.3 Next Spec Audit Actions
Complete systematic review of all specs:
- M2-100-U v1.1 (Overview) - verify all references covered
- M2-116-U v1.0 (Clip File) - initial audit needed
Add missing spec sections:
- Mixed Data Set (MDS) detailed validation
- MIDI Clip File format (if in scope)
- Additional Stream message opcodes (start/end of clip 0x20/0x21)
Cross-validate existing entries:
- Verify each page reference is accurate
- Ensure schema fields match spec diagrams exactly
- Check for spec updates (errata, new versions)
13. Traceability Matrix
This section provides a comprehensive mapping between specification requirements and implementation evidence.
13.1 UMP Message Types (M2-104-UM v1.1.2)
| Message Type | Spec Ref | Schema | Swift Impl | TS Impl | Tests | Status |
|---|---|---|---|---|---|---|
| Utility (0x0) | §4 | ✅ UtilityBody |
✅ UtilityBody.swift |
✅ ump.ts |
✅ | Complete |
| System (0x1) | §6 | ✅ SystemCommonRealtimeBody |
✅ SystemCommonRealtimeBody.swift |
✅ ump.ts |
✅ | Complete |
| MIDI 1.0 Ch Voice (0x2) | §7 | ✅ Midi1ChannelVoiceBody |
✅ Midi1ChannelVoiceBody.swift |
✅ midi1.ts |
✅ | Complete |
| SysEx7 (0x3) | §8 | ✅ SysEx7Body |
✅ SysEx7Packet.swift |
✅ sysex.ts |
✅ | Complete |
| MIDI 2.0 Ch Voice (0x4) | §9 | ✅ Midi2ChannelVoiceBody |
✅ Midi2ChannelVoiceBody.swift |
✅ ump.ts |
✅ | Complete |
| SysEx8/MDS (0x5) | §10 | ✅ DataMessageBody |
✅ SysEx8.swift |
✅ sysex.ts |
✅ | Complete |
| Flex Data (0xD) | §11 | ✅ FlexDataBody |
✅ FlexDataBody.swift |
✅ (guards) | ✅ | Complete |
| Stream (0xF) | §5 | ✅ StreamBody |
✅ StreamBody.swift |
✅ (guards) | ✅ | Partial (gaps noted) |
13.2 MIDI-CI Messages (M2-101-UM v1.2)
| Message Type | Spec Ref | Schema | Swift Impl | TS Impl | Tests | Status |
|---|---|---|---|---|---|---|
| Discovery | §3.2 | ✅ MidiCiDiscoveryBody |
✅ MidiCiDiscoveryBody.swift |
✅ midici.ts |
✅ | Complete |
| Inquiry - Endpoint | §3.3 | ✅ | ✅ | ✅ | ✅ | Complete |
| Inquiry - Invalidity | §3.4 | ✅ | ✅ | ✅ | ⚠️ | Needs validation |
| NAK | §3.5 | ✅ MidiCiAckNakBody |
✅ MidiCiAckNakBody.swift |
✅ | ✅ | Complete |
| Process Inquiry | §10 | ✅ MidiCiProcessInquiryBody |
✅ MidiCiProcessInquiryBody.swift |
⚠️ | ⚠️ | Partial (Gap 2.2.3) |
13.3 Profile Messages (M2-102-U v1.1)
| Message Type | Spec Ref | Schema | Swift Impl | TS Impl | Tests | Status |
|---|---|---|---|---|---|---|
| Profile Inquiry | §4.1 | ✅ MidiCiProfilesBody |
✅ ProfileSession.swift |
✅ | ✅ | Complete |
| Profile Enable/Disable | §4.2-4.3 | ✅ | ✅ | ✅ | ✅ | Complete |
| Profile Details | §4.5 | ✅ | ✅ | ⚠️ | ✅ | TS parsing minimal; Swift session handles details/PSD/channel masks |
| Profile Specific Data | §5 | ✅ | ✅ ProfileSpecificData.swift |
⚠️ | ✅ | Partial |
13.4 Property Exchange (M2-103-UM v1.2)
| Feature | Spec Ref | Schema | Swift Impl | TS Impl | Tests | Status |
|---|---|---|---|---|---|---|
| Capability Inquiry | §4.1 | ✅ MidiCiPropertyExchangeBody |
✅ | ✅ | ✅ | Complete |
| Get Property | §4.2 | ✅ | ✅ PropertyExchange.swift |
✅ | ✅ | Complete |
| Set Property | §4.3 | ✅ | ✅ | ✅ | ✅ | Complete |
| Subscriptions | §4.4 | ✅ | ⚠️ | ⚠️ | ⚠️ | Partial (Gap 2.2.1) |
| Chunking | §6 | ✅ | ✅ | ⚠️ | ✅ | Partial |
| Flow Control ACK/NAK | §6.1-6.2 | ✅ | ⚠️ | ⚠️ | ❌ | Schema only (Gap 2.2.1) |
| Compression (zlib) | §5.1 | ✅ | ✅ CompressionCodec.swift |
⚠️ | ✅ | Partial |
| Compression (mcoded7) | §5.2 | ✅ | ✅ | ⚠️ | ✅ | Partial |
| Headers | §7 | ✅ | ✅ | ✅ | ✅ | Complete |
| Status Codes | §8 | ✅ | ✅ | ⚠️ | ⚠️ | Partial |
13.5 Stream Configuration (M2-104-UM v1.1.2 §5)
| Feature | Spec Ref | Schema | Swift Impl | TS Impl | Tests | Status |
|---|---|---|---|---|---|---|
| Endpoint Discovery | §5.1 | ✅ | ✅ EndpointDiscoveryMessage.swift |
⚠️ | ✅ | Partial (Gap 4.2.4) |
| Endpoint Info Notification | §5.1.1 | ✅ | ⚠️ | ⚠️ | ⚠️ | Partial (Gap 4.2.4) |
| Device Identity | §5.1.2 | ✅ | ✅ | ⚠️ | ⚠️ | Partial |
| Endpoint Name | §5.1.3 | ✅ | ✅ | ⚠️ | ⚠️ | Partial |
| Product Instance ID | §5.1.4 | ✅ | ✅ | ⚠️ | ⚠️ | Partial |
| Stream Config Request | §5.2 | ✅ | ✅ StreamConfigurationMessage.swift |
⚠️ | ✅ | Partial (Gap 4.2.3) |
| Stream Config Notification | §5.2.1 | ✅ | ✅ | ⚠️ | ✅ | Partial (Gap 4.2.3) |
| Function Block Discovery | §5.4 | ✅ | ✅ FunctionBlockDiscovery.swift |
⚠️ | ✅ | Partial (Gap 4.2.1) |
| Function Block Info | §5.4.1 | ✅ | ⚠️ | ⚠️ | ⚠️ | Partial (Gap 4.2.1) |
| Function Block Name | §5.4.2 | ✅ | ⚠️ | ⚠️ | ⚠️ | Partial |
| Group Terminal Blocks | Appendix I | ✅ | ✅ GroupTerminalBlocks.swift |
⚠️ | ✅ | Partial (Gap 4.2.2) |
Legend:
- ✅ Complete
- ⚠️ Partial/Needs Enhancement
- ❌ Not Implemented/Missing
14. Gap Closure Plan
14.1 Sprint 1 (Week 1-2): Critical Path Items
Goal: Close high-priority gaps blocking full MIDI-CI compliance
Property Exchange Subscription Lifecycle (5-7 days)
- Implement subscription state machine
- Add flow-control ACK/NAK runtime handlers
- Create comprehensive test suite
- Update documentation
Reserved/Unsupported Handling (2-3 days)
- Unify decoder rejection across Swift/TS
- Add negative vectors for reserved opcodes/status/bit patterns
- Document reserved handling strategy
- Create test vectors
14.2 Sprint 2 (Week 3-4): Stream Configuration
Goal: Complete Stream §5 implementation
GTB Negotiation Semantics (4-5 days)
- Document GTB-FB overlap
- Implement protocol restrictions
- Add negotiation logic
- Create interop tests
Stream Configuration Semantics (3-4 days)
- JR fallback implementation
- Protocol switching logic
- Capability mismatch handling
- Test negotiation flows
Endpoint Info Enhancement (2 days)
- Validate all Endpoint Info fields
- Add reserved value checks
- Comprehensive test vectors
14.3 Sprint 3 (Week 5-6): Testing and Validation
Goal: Expand test coverage and regression prevention
Negative Test Coverage (4-5 days)
- Create negative test matrix
- Implement consistent error handling
- Add fuzzing tests
Visual Baseline Frames (3-4 days)
- VRT-Protocol baselines for all types
- Automated diff tooling
- CI integration
14.4 Sprint 4 (Week 7-8): MIDI-CI Refinement
Goal: Complete MIDI-CI feature set
- Profile Configuration Details (2-3 days)
- Process Inquiry Enhancement (2-3 days)
- MUID Management (2-3 days)
14.5 Sprint 5 (Week 9+): Polish and Interop
Goal: TypeScript improvements and hardware validation
- Worker-Clock JR Projection (2-3 days)
- Adapter Enhancements (2-3 days)
- Hardware Interop Tests (Ongoing)
- Reserved Status Handling (2-3 days)
- Documentation Updates (Ongoing)
15. Success Metrics
15.1 Quantitative Metrics
Spec Audit Completion:
- Current: 49/52 entries captured (94%)
- Target: 100% captured with all pending items resolved
- Uncaptured entries:
- USB GTB considerations (M2-104-UM p.122) - Runtime guidance pending
- PE subscription lifecycle runtime (M2-103-UM Tables 43-47) - ✅ State machine implemented
- Remaining spec sections audit - Target: Q1 2026
Test Coverage:
- Swift: ~354 tests (target: 150+ tests) 🟢
- TypeScript: ~199 tests (target: 200 tests) 🟡 Target nearly met
- Negative tests: 60+ added across both stacks ✅
- Hardware interop: 0 → Target: Basic suite established 🔴
Schema Completeness:
- Current: 63 type definitions
- Target: 100% of normative spec fields documented with page references
Gap Closure:
- Total: 21 identified gaps
- Closed: 11 gaps (52%)
- In Progress: 2 gaps (10%)
- Remaining: 8 gaps (38%)
15.2 Qualitative Metrics
Spec Compliance:
Interoperability:
Code Quality:
Documentation:
16. Conclusion
The midi2 repository demonstrates strong alignment with MIDI 2.0 normative specifications, with comprehensive schema coverage, robust implementation of core features, and excellent traceability through the spec-audit log. The dual-stack approach (Swift reference + TypeScript portable) provides valuable cross-validation.
Key Strengths:
- Schema-driven development with machine-readable canonical artifacts
- Comprehensive page-level traceability to normative specs
- Strong test coverage with both positive and negative cases
- Active gap tracking and documentation
- Cross-platform validation (Swift ↔︎ TypeScript)
Critical Gaps to Address (updated):
- Reserved/unsupported handling consistency across decoders
- Hardware interoperability validation
- TypeScript coverage for edge cases (reserved/unsupported)
- Visual regression (VRT-Protocol) completeness for CI messages
Next Steps:
- Address reserved/unsupported handling and add negative vectors
- Expand hardware interop validation
- Broaden TS edge-case coverage and VRT-Protocol baselines
- Complete remaining spec audit entries
- Validate all DoD criteria
With focused effort on the identified gaps, particularly in MIDI-CI runtime state management and Stream configuration semantics, the repository can achieve full normative compliance with the MIDI 2.0 specifications. The existing foundation is solid, and the documented gaps provide a clear roadmap to completion.
Appendix A: Specification Document Reference
| Document | Version | Pages | Focus Areas |
|---|---|---|---|
| M2-100-U | v1.1 | 482 KB | MIDI 2.0 Overview |
| M2-101-UM | v1.2 | 1.1 MB | MIDI-CI Specification |
| M2-102-U | v1.1 | 669 KB | MIDI-CI Profiles |
| M2-103-UM | v1.2 | 1.5 MB | Property Exchange |
| M2-104-UM | v1.1.2 | 4.8 MB | UMP and Protocol |
| M2-116-U | v1.0 | 875 KB | MIDI Clip File |
Appendix B: Gap Priority Matrix
| Gap ID | Description | Priority | Effort | Impact | Sprint |
|---|---|---|---|---|---|
| 2.2.1 | PE Subscription Lifecycle | High | High | Critical | 1 |
| 4.2.1 | Function Block Descriptors | High | Med-High | Critical | 1 |
| 4.2.2 | GTB Negotiation | High | Med-High | Critical | 2 |
| 4.2.3 | Stream Config Semantics | Medium | Medium | High | 2 |
| 8.2.3 | Negative Test Coverage | Medium | Med-High | High | 3 |
| 8.2.1 | Visual Baselines (VRT-Protocol) | Medium | Medium | Medium | 3 |
| 2.2.2 | Profile Config Details | Medium | Medium | Medium | 4 |
| 2.2.3 | Process Inquiry Enhancement | Medium | Medium | Medium | 4 |
| 2.2.4 | MUID Management | Medium | Low-Med | Medium | 4 |
| 4.2.4 | Endpoint Info Beyond Version | Medium | Low-Med | Medium | 2 |
| 8.2.2 | Hardware Interop Tests | Medium | High | Medium | 5 |
| 5.2.1 | Worker-Clock JR | Medium | Low-Med | Low | 5 |
| 5.2.2 | Adapter Per-Note Controllers | Medium | Medium | Low | 5 |
| 1.2.1 | Reserved Status Handling | Medium | Medium | Low | 5 |
| 1.2.2 | UMP Format Extensions | Low | Low | Low | 5 |
| 3.2.1 | Flex Data Edge Cases | Low | Low | Low | 5 |
| 6.2.1 | JR Interop Testing | Low | Medium | Low | 5 |
| 7.2.1 | Oversize SysEx Handling | Low | Low | Low | 5 |
| 9.2.1 | Schema Documentation | Low | Ongoing | Low | Ongoing |
| 9.2.2 | Schema Regression CI | Medium | Low | Medium | 3 |
| 10.2.1 | DoD Validation | Low | Low-Med | Low | 5 |
Report Prepared By: MIDI 2.0 Specification Audit Agent
Initial Audit Date: December 13, 2025
Status: Initial Comprehensive Audit Complete
Next Review: Recommended after Sprint 1 completion or major milestone
