diff --git a/.changeset/tidy-slots-close.md b/.changeset/tidy-slots-close.md new file mode 100644 index 000000000..0acbc7d5b --- /dev/null +++ b/.changeset/tidy-slots-close.md @@ -0,0 +1,5 @@ +--- +"catalog": patch +--- + +Remove storage media card slots (SD, microSD) from hardware io, 44 entries across 44 files. Card slots hold media, not cables, so the setup graph cannot use them, the same reasoning as Bluetooth and Wi-Fi. New validation error E120 blocks reintroducing them by name while leaving option and expansion card bays legal. diff --git a/CLAUDE.md b/CLAUDE.md index 355203cd1..bb994506e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -172,6 +172,14 @@ ports — the app doesn't support them in the setup graph. Mention them in absent from the io type vocabulary, so such entries fail validation (E117). (`rf` antenna jacks on wireless mic systems are real ports and stay.) +**No storage media slot io entries.** SD, microSD, CompactFlash, Memory Stick +and kin hold media, not cables, so the setup graph can do nothing with them — +the same reasoning as Bluetooth/Wi-Fi. An io entry whose name identifies a +storage slot fails validation (E120). Mention the slot in +`description`/`details`/`specs` instead. Option and expansion card bays +(Dante/MADI option cards) accept cards that present real connectors, so those +stay legal with `connection: card-slot`. + **Passive speakers use `speaker-level`, not `line`.** Passive-loudspeaker inputs (speakON, binding-post, banana, euroblock, barrier/spring terminals) carry amplified signals — set `type: speaker-level`. `line` is for low-voltage diff --git a/data/hardware/1010-music-bento.yaml b/data/hardware/1010-music-bento.yaml index e12cd08f4..0b5e9096a 100644 --- a/data/hardware/1010-music-bento.yaml +++ b/data/hardware/1010-music-bento.yaml @@ -150,14 +150,6 @@ io: connection: usb-c maxConnections: 1 position: Bottom - - key: HUgOxSwJ - name: microSD Card Slot - signalFlow: bidirectional - category: digital - type: proprietary - connection: card-slot - maxConnections: 1 - position: Right versions: - name: 1.4.7 releaseDate: 2026-03-16 diff --git a/data/hardware/1010-music-blackbox-2.yaml b/data/hardware/1010-music-blackbox-2.yaml index 707bf77db..1d5587232 100644 --- a/data/hardware/1010-music-blackbox-2.yaml +++ b/data/hardware/1010-music-blackbox-2.yaml @@ -113,14 +113,6 @@ io: connection: 1/8-inch maxConnections: 1 position: Top - - key: qkWgD1C5 - name: microSD Card Slot - signalFlow: bidirectional - category: digital - type: proprietary - connection: card-slot - maxConnections: 1 - position: Right videos: - provider: youtube videoId: 1a33_40c0CQ diff --git a/data/hardware/1010-music-blackbox.yaml b/data/hardware/1010-music-blackbox.yaml index 5dee7bb28..59594cf2c 100644 --- a/data/hardware/1010-music-blackbox.yaml +++ b/data/hardware/1010-music-blackbox.yaml @@ -129,14 +129,6 @@ io: connection: 1/8-inch maxConnections: 1 position: Top - - key: mrL8BUoR - name: microSD Card Slot - signalFlow: bidirectional - category: digital - type: proprietary - connection: card-slot - maxConnections: 1 - position: Top versions: - name: Firmware 3.1.2 description: Adds multisample import using filename to set root note and diff --git a/data/hardware/1010-music-bluebox.yaml b/data/hardware/1010-music-bluebox.yaml index 210283a91..7db5f8ac2 100644 --- a/data/hardware/1010-music-bluebox.yaml +++ b/data/hardware/1010-music-bluebox.yaml @@ -141,14 +141,6 @@ io: connection: 1/8-inch maxConnections: 1 position: Bottom - - key: jyo1aa0G - name: microSD Card Slot - signalFlow: bidirectional - category: digital - type: proprietary - connection: card-slot - maxConnections: 1 - position: Bottom links: - url: https://forum.1010music.com/forum/products/bluebox-compact-digital-mixer-recorder/learning-material-bluebox type: resource diff --git a/data/hardware/1010-music-fireball.yaml b/data/hardware/1010-music-fireball.yaml index 283436e31..04fed2d7c 100644 --- a/data/hardware/1010-music-fireball.yaml +++ b/data/hardware/1010-music-fireball.yaml @@ -85,14 +85,6 @@ io: connection: 1/8-inch maxConnections: 1 position: Bottom - - key: IO93ZeEi - name: microSD Card Slot - signalFlow: bidirectional - category: digital - type: proprietary - connection: card-slot - maxConnections: 1 - position: Bottom links: - url: https://1010music.com/wp-content/uploads/2022/01/Nanobox-Fireball-Quick-Start-Guide-Jan-2022.pdf type: resource diff --git a/data/hardware/1010-music-lemondrop.yaml b/data/hardware/1010-music-lemondrop.yaml index 44655432c..ff6ca45a8 100644 --- a/data/hardware/1010-music-lemondrop.yaml +++ b/data/hardware/1010-music-lemondrop.yaml @@ -86,14 +86,6 @@ io: connection: 1/8-inch maxConnections: 1 position: Bottom - - key: O3r1nMqE - name: microSD Card Slot - signalFlow: bidirectional - category: digital - type: proprietary - connection: card-slot - maxConnections: 1 - position: Bottom links: - url: https://1010music.com/wp-content/uploads/2022/01/Nanobox-Lemondrop-Quick-Start-Guide-Jan-2022.pdf type: resource diff --git a/data/hardware/1010-music-nanobox-razzmatazz.yaml b/data/hardware/1010-music-nanobox-razzmatazz.yaml index ee9a7e72c..6bbe3a62e 100644 --- a/data/hardware/1010-music-nanobox-razzmatazz.yaml +++ b/data/hardware/1010-music-nanobox-razzmatazz.yaml @@ -91,14 +91,6 @@ io: connection: 1/8-inch maxConnections: 1 position: Bottom - - key: hUess2vW - name: microSD Card Slot - signalFlow: bidirectional - category: digital - type: proprietary - connection: card-slot - maxConnections: 1 - position: Bottom links: - url: https://1010music.com/wp-content/uploads/2022/10/Nanobox-Razzmatazz-Quick-Start-Guide-2022-09-19a.pdf type: resource diff --git a/data/hardware/1010-music-tangerine.yaml b/data/hardware/1010-music-tangerine.yaml index 37a98d92c..534085543 100644 --- a/data/hardware/1010-music-tangerine.yaml +++ b/data/hardware/1010-music-tangerine.yaml @@ -82,14 +82,6 @@ io: connection: 1/8-inch maxConnections: 1 position: Bottom - - key: Eg95avj3 - name: microSD Card Slot - signalFlow: bidirectional - category: digital - type: proprietary - connection: card-slot - maxConnections: 1 - position: Bottom versions: - name: 1.2.28 links: diff --git a/data/hardware/denon-dj-prime-2.yaml b/data/hardware/denon-dj-prime-2.yaml index 528730d32..7beaa295d 100644 --- a/data/hardware/denon-dj-prime-2.yaml +++ b/data/hardware/denon-dj-prime-2.yaml @@ -172,14 +172,6 @@ io: connection: usb-b maxConnections: 1 position: Bottom - - key: YHVhOFDG - name: SD Card Slot - signalFlow: input - category: digital - type: usb - connection: built-in - maxConnections: 1 - position: Top - key: vsYbPFFw name: Ethernet signalFlow: bidirectional diff --git a/data/hardware/denon-dj-prime-4.yaml b/data/hardware/denon-dj-prime-4.yaml index 428eab157..bc437e8f2 100644 --- a/data/hardware/denon-dj-prime-4.yaml +++ b/data/hardware/denon-dj-prime-4.yaml @@ -226,14 +226,6 @@ io: connection: usb-b maxConnections: 1 position: Bottom - - key: YH1oRgqE - name: SD Card Slot - signalFlow: input - category: digital - type: usb - connection: built-in - maxConnections: 1 - position: Top - key: xFjvHEgD name: Ethernet Link signalFlow: bidirectional diff --git a/data/hardware/denon-dj-prime-go-plus.yaml b/data/hardware/denon-dj-prime-go-plus.yaml index 6ff97a751..9dd256c1b 100644 --- a/data/hardware/denon-dj-prime-go-plus.yaml +++ b/data/hardware/denon-dj-prime-go-plus.yaml @@ -141,14 +141,6 @@ io: connection: usb-b maxConnections: 1 position: Right - - key: jQQDkWad - name: SD Card Slot - signalFlow: input - category: digital - type: usb - connection: built-in - maxConnections: 1 - position: Right - key: oVIKylFg name: Power Input (DC) signalFlow: input diff --git a/data/hardware/denon-dj-prime-go.yaml b/data/hardware/denon-dj-prime-go.yaml index bfc9bf818..b2cc6520a 100644 --- a/data/hardware/denon-dj-prime-go.yaml +++ b/data/hardware/denon-dj-prime-go.yaml @@ -143,14 +143,6 @@ io: connection: usb-b maxConnections: 1 position: Right - - key: bIhCIMlp - name: SD Card Slot - signalFlow: input - category: digital - type: usb - connection: built-in - maxConnections: 1 - position: Right - key: G3CcpVUg name: Ethernet (Network) signalFlow: bidirectional diff --git a/data/hardware/denon-dj-sc5000-prime.yaml b/data/hardware/denon-dj-sc5000-prime.yaml index cb430571a..e7df81211 100644 --- a/data/hardware/denon-dj-sc5000-prime.yaml +++ b/data/hardware/denon-dj-sc5000-prime.yaml @@ -157,14 +157,6 @@ io: connection: usb-b maxConnections: 1 position: Bottom - - key: 0QneVNlV - name: SD Card Slot - signalFlow: input - category: digital - type: usb - connection: built-in - maxConnections: 1 - position: Top - key: S8NCg0gK name: Ethernet Link Port signalFlow: bidirectional diff --git a/data/hardware/denon-dj-sc5000m-prime.yaml b/data/hardware/denon-dj-sc5000m-prime.yaml index 2ba858649..579266101 100644 --- a/data/hardware/denon-dj-sc5000m-prime.yaml +++ b/data/hardware/denon-dj-sc5000m-prime.yaml @@ -133,14 +133,6 @@ io: connection: usb-a maxConnections: 1 position: Top - - key: 1Fw58nY5 - name: SD Card Slot - signalFlow: bidirectional - category: digital - type: usb - connection: card-slot - maxConnections: 1 - position: Top links: - type: support title: Downloads diff --git a/data/hardware/denon-dj-sc6000m-prime.yaml b/data/hardware/denon-dj-sc6000m-prime.yaml index a891ecf3a..a7100d7e8 100644 --- a/data/hardware/denon-dj-sc6000m-prime.yaml +++ b/data/hardware/denon-dj-sc6000m-prime.yaml @@ -129,14 +129,6 @@ io: connection: usb-a maxConnections: 1 position: Top - - key: Ci7GtnYW - name: SD Card Slot - signalFlow: bidirectional - category: digital - type: usb - connection: card-slot - maxConnections: 1 - position: Top - key: 9DpJ8Iuk name: Remote Start Input signalFlow: input diff --git a/data/hardware/intellijel-multigrain.yaml b/data/hardware/intellijel-multigrain.yaml index fb8b73aba..62c31540a 100644 --- a/data/hardware/intellijel-multigrain.yaml +++ b/data/hardware/intellijel-multigrain.yaml @@ -148,14 +148,6 @@ io: connection: 1/8-inch maxConnections: 1 position: Top - - key: 7y4Mzf4n - name: SD Card - signalFlow: bidirectional - category: digital - type: proprietary - connection: card-slot - maxConnections: 1 - position: Top links: - url: https://intellijel.com/downloads/manuals/multigrain_manual_v1.4_2026.05.01.pdf type: resource diff --git a/data/hardware/marantz-cd-50n.yaml b/data/hardware/marantz-cd-50n.yaml index 16e685312..80e68a80e 100644 --- a/data/hardware/marantz-cd-50n.yaml +++ b/data/hardware/marantz-cd-50n.yaml @@ -104,14 +104,6 @@ io: connection: usb-b maxConnections: 1 position: Right - - key: 8Fzgzn8p - name: USB Memory Stick Input - signalFlow: input - category: digital - type: usb - connection: usb-a - maxConnections: 1 - position: Left - key: 6N1eUBKp name: Ethernet signalFlow: bidirectional diff --git a/data/hardware/midas-dp48.yaml b/data/hardware/midas-dp48.yaml index 137da2319..15795b6fa 100644 --- a/data/hardware/midas-dp48.yaml +++ b/data/hardware/midas-dp48.yaml @@ -66,14 +66,6 @@ io: connection: 1/4-inch maxConnections: 1 position: Right - - key: 57NSOebW - name: SD Card Slot - signalFlow: bidirectional - category: digital - type: usb - connection: built-in - maxConnections: 1 - position: Top - key: Pauk6Im0 name: Stereo Ambience Microphone (built-in) signalFlow: input diff --git a/data/hardware/numark-mixstream-pro-go.yaml b/data/hardware/numark-mixstream-pro-go.yaml index f0d8eee9c..bf6f21715 100644 --- a/data/hardware/numark-mixstream-pro-go.yaml +++ b/data/hardware/numark-mixstream-pro-go.yaml @@ -115,14 +115,6 @@ io: connection: usb-b maxConnections: 1 position: Top - - key: PAyEWMge - name: SD Card Slot - signalFlow: bidirectional - category: digital - type: usb - connection: built-in - maxConnections: 1 - position: Top - key: HWUqIOON name: Power Adapter Input signalFlow: input diff --git a/data/hardware/numark-mixstream-pro-plus.yaml b/data/hardware/numark-mixstream-pro-plus.yaml index bc7241f24..6c778f6a1 100644 --- a/data/hardware/numark-mixstream-pro-plus.yaml +++ b/data/hardware/numark-mixstream-pro-plus.yaml @@ -100,14 +100,6 @@ io: connection: usb-b maxConnections: 1 position: Bottom - - key: WZ1e3XoL - name: SD Card Slot - signalFlow: bidirectional - category: digital - type: usb - connection: built-in - maxConnections: 1 - position: Top - key: QyxRuZ0z name: DC Power Input signalFlow: input diff --git a/data/hardware/numark-mixstream-pro.yaml b/data/hardware/numark-mixstream-pro.yaml index c7c089abd..1d5828043 100644 --- a/data/hardware/numark-mixstream-pro.yaml +++ b/data/hardware/numark-mixstream-pro.yaml @@ -126,14 +126,6 @@ io: connection: usb-b maxConnections: 1 position: Bottom - - key: JVpF9Foc - name: SD Card Slot - signalFlow: bidirectional - category: digital - type: usb - connection: built-in - maxConnections: 1 - position: Top - key: bdeL2N8h name: DC Power Input signalFlow: input diff --git a/data/hardware/tascam-bd-mp1mkii.yaml b/data/hardware/tascam-bd-mp1mkii.yaml index 3db0b4efb..0832e4610 100644 --- a/data/hardware/tascam-bd-mp1mkii.yaml +++ b/data/hardware/tascam-bd-mp1mkii.yaml @@ -157,14 +157,6 @@ io: connection: usb-a maxConnections: 1 position: Right - - key: 6FXbjd2b - name: SD Card Slot - signalFlow: input - category: digital - type: usb - connection: built-in - maxConnections: 1 - position: Left - key: QEKkJ35S name: RS-232C Control signalFlow: bidirectional diff --git a/data/hardware/tascam-bd-mp4k.yaml b/data/hardware/tascam-bd-mp4k.yaml index f0761c4ea..c2e4b7d22 100644 --- a/data/hardware/tascam-bd-mp4k.yaml +++ b/data/hardware/tascam-bd-mp4k.yaml @@ -147,14 +147,6 @@ io: connection: rca maxConnections: 1 position: Right - - key: 9hQI3EEM - name: SD Card Slot - signalFlow: input - category: digital - type: usb - connection: built-in - maxConnections: 1 - position: Left - key: POU465CR name: USB 3.0 Type-A signalFlow: input diff --git a/data/hardware/tascam-cd-400u.yaml b/data/hardware/tascam-cd-400u.yaml index e1530537c..13927d84f 100644 --- a/data/hardware/tascam-cd-400u.yaml +++ b/data/hardware/tascam-cd-400u.yaml @@ -35,14 +35,6 @@ io: connection: 1/8-inch maxConnections: 1 position: Left - - key: vdEgngc6 - name: SD Card Slot - signalFlow: input - category: digital - type: usb - connection: built-in - maxConnections: 1 - position: Left - key: CYwnLRnd name: USB Type-A (Media) signalFlow: input diff --git a/data/hardware/tascam-dp-006.yaml b/data/hardware/tascam-dp-006.yaml index 6bcefc322..d3c0af29d 100644 --- a/data/hardware/tascam-dp-006.yaml +++ b/data/hardware/tascam-dp-006.yaml @@ -80,14 +80,6 @@ io: connection: usb-b maxConnections: 1 position: Right - - key: HDsF5QAu - name: SD Card Slot - signalFlow: bidirectional - category: digital - type: usb - connection: built-in - maxConnections: 1 - position: Right prices: - amount: 159 currency: USD diff --git a/data/hardware/tascam-dp-24sd.yaml b/data/hardware/tascam-dp-24sd.yaml index 8f5353182..6557fe6ce 100644 --- a/data/hardware/tascam-dp-24sd.yaml +++ b/data/hardware/tascam-dp-24sd.yaml @@ -152,14 +152,6 @@ io: connection: 1/8-inch maxConnections: 1 position: Right - - key: R2QirQfC - name: SD Card Slot - signalFlow: bidirectional - category: digital - type: usb - connection: built-in - maxConnections: 1 - position: Top - key: YRUE65oP name: AC Power signalFlow: input diff --git a/data/hardware/tascam-dr-05x.yaml b/data/hardware/tascam-dr-05x.yaml index 0e5f61b64..d485c2e59 100644 --- a/data/hardware/tascam-dr-05x.yaml +++ b/data/hardware/tascam-dr-05x.yaml @@ -57,11 +57,3 @@ io: connection: usb-b maxConnections: 1 position: Bottom - - key: NWaqbjDY - name: microSD Card Slot - signalFlow: bidirectional - category: digital - type: usb - connection: built-in - maxConnections: 1 - position: Right diff --git a/data/hardware/tascam-dr-05xp.yaml b/data/hardware/tascam-dr-05xp.yaml index 477d9dc3d..6dca0c423 100644 --- a/data/hardware/tascam-dr-05xp.yaml +++ b/data/hardware/tascam-dr-05xp.yaml @@ -57,14 +57,6 @@ io: connection: usb-c maxConnections: 1 position: Bottom - - key: 82OPjJan - name: microSD Card Slot - signalFlow: bidirectional - category: digital - type: usb - connection: built-in - maxConnections: 1 - position: Right prices: - amount: 102 currency: USD diff --git a/data/hardware/tascam-dr-07x.yaml b/data/hardware/tascam-dr-07x.yaml index 44bc7c19e..d6759054d 100644 --- a/data/hardware/tascam-dr-07x.yaml +++ b/data/hardware/tascam-dr-07x.yaml @@ -57,14 +57,6 @@ io: connection: usb-b maxConnections: 1 position: Bottom - - key: HJ3ITvPs - name: microSD Card Slot - signalFlow: bidirectional - category: digital - type: usb - connection: built-in - maxConnections: 1 - position: Right prices: - amount: 119 currency: USD diff --git a/data/hardware/tascam-dr-07xp.yaml b/data/hardware/tascam-dr-07xp.yaml index 53e14cfdb..3a59e7fba 100644 --- a/data/hardware/tascam-dr-07xp.yaml +++ b/data/hardware/tascam-dr-07xp.yaml @@ -57,14 +57,6 @@ io: connection: usb-c maxConnections: 1 position: Bottom - - key: GLIPTSO4 - name: microSD Card Slot - signalFlow: bidirectional - category: digital - type: usb - connection: built-in - maxConnections: 1 - position: Right prices: - amount: 148 currency: USD diff --git a/data/hardware/tascam-dr-10l_pro.yaml b/data/hardware/tascam-dr-10l_pro.yaml index 2cba41b91..5e3c3ed35 100644 --- a/data/hardware/tascam-dr-10l_pro.yaml +++ b/data/hardware/tascam-dr-10l_pro.yaml @@ -47,14 +47,6 @@ io: connection: usb-c maxConnections: 1 position: Bottom - - key: mVH5zw85 - name: microSD Card Slot - signalFlow: bidirectional - category: digital - type: usb - connection: built-in - maxConnections: 1 - position: Right prices: - amount: 157 currency: USD diff --git a/data/hardware/tascam-dr-10x.yaml b/data/hardware/tascam-dr-10x.yaml index bc1187a0b..55149eeba 100644 --- a/data/hardware/tascam-dr-10x.yaml +++ b/data/hardware/tascam-dr-10x.yaml @@ -47,14 +47,6 @@ io: connection: usb-b maxConnections: 1 position: Right - - key: G7WBFzxU - name: microSD Card Slot - signalFlow: bidirectional - category: digital - type: usb - connection: built-in - maxConnections: 1 - position: Left prices: - amount: 127 currency: USD diff --git a/data/hardware/tascam-dr-40x.yaml b/data/hardware/tascam-dr-40x.yaml index 0187bc899..e84d9e949 100644 --- a/data/hardware/tascam-dr-40x.yaml +++ b/data/hardware/tascam-dr-40x.yaml @@ -65,14 +65,6 @@ io: connection: usb-b maxConnections: 1 position: Bottom - - key: fPTK0Wjz - name: SD Card Slot - signalFlow: bidirectional - category: digital - type: usb - connection: built-in - maxConnections: 1 - position: Right prices: - amount: 219 currency: USD diff --git a/data/hardware/tascam-dr-40xp.yaml b/data/hardware/tascam-dr-40xp.yaml index 4ec8496de..f3fb8d5a5 100644 --- a/data/hardware/tascam-dr-40xp.yaml +++ b/data/hardware/tascam-dr-40xp.yaml @@ -64,14 +64,6 @@ io: connection: usb-c maxConnections: 1 position: Bottom - - key: 6qaxZUEb - name: microSD Card Slot - signalFlow: bidirectional - category: digital - type: usb - connection: built-in - maxConnections: 1 - position: Left prices: - amount: 259 currency: USD diff --git a/data/hardware/tascam-fr-av2.yaml b/data/hardware/tascam-fr-av2.yaml index 60f2f91b3..7a8109f7f 100644 --- a/data/hardware/tascam-fr-av2.yaml +++ b/data/hardware/tascam-fr-av2.yaml @@ -82,14 +82,6 @@ io: connection: usb-c maxConnections: 1 position: Right - - key: lPphekG8 - name: microSD Card Slot - signalFlow: bidirectional - category: digital - type: usb - connection: built-in - maxConnections: 1 - position: Bottom prices: - amount: 399 currency: USD diff --git a/data/hardware/tascam-mixcast_4.yaml b/data/hardware/tascam-mixcast_4.yaml index a04afbfc9..9f92cca35 100644 --- a/data/hardware/tascam-mixcast_4.yaml +++ b/data/hardware/tascam-mixcast_4.yaml @@ -145,14 +145,6 @@ io: connection: usb-c maxConnections: 1 position: Right - - key: EoS20In8 - name: SD Card Slot - signalFlow: bidirectional - category: digital - type: usb - connection: built-in - maxConnections: 1 - position: Right - key: flc1NvBu name: DC Power signalFlow: input diff --git a/data/hardware/tascam-model_12.yaml b/data/hardware/tascam-model_12.yaml index b0c8fad77..fc94768ef 100644 --- a/data/hardware/tascam-model_12.yaml +++ b/data/hardware/tascam-model_12.yaml @@ -228,14 +228,6 @@ io: connection: usb-c maxConnections: 1 position: Right - - key: g05xtN79 - name: SD Card Slot - signalFlow: bidirectional - category: digital - type: usb - connection: built-in - maxConnections: 1 - position: Left - key: en25nceh name: MIDI In signalFlow: input diff --git a/data/hardware/tascam-model_16.yaml b/data/hardware/tascam-model_16.yaml index 8ec6900eb..dfbe3c28b 100644 --- a/data/hardware/tascam-model_16.yaml +++ b/data/hardware/tascam-model_16.yaml @@ -278,14 +278,6 @@ io: connection: usb-b maxConnections: 1 position: Right - - key: AXPTLuJ7 - name: SD Card Slot - signalFlow: bidirectional - category: digital - type: usb - connection: built-in - maxConnections: 1 - position: Left - key: lJa92t5a name: Footswitch signalFlow: input diff --git a/data/hardware/tascam-model_24.yaml b/data/hardware/tascam-model_24.yaml index 0c15cd2af..348b45f56 100644 --- a/data/hardware/tascam-model_24.yaml +++ b/data/hardware/tascam-model_24.yaml @@ -400,14 +400,6 @@ io: connection: usb-b maxConnections: 1 position: Right - - key: qqzrB0vN - name: SD Card Slot - signalFlow: bidirectional - category: digital - type: usb - connection: built-in - maxConnections: 1 - position: Top - key: ab8hrIVP name: AC Power signalFlow: input diff --git a/data/hardware/tascam-model_2400.yaml b/data/hardware/tascam-model_2400.yaml index 6bac168d3..0db19510c 100644 --- a/data/hardware/tascam-model_2400.yaml +++ b/data/hardware/tascam-model_2400.yaml @@ -517,14 +517,6 @@ io: connection: built-in maxConnections: 1 position: Right - - key: aw8f2wpD - name: SD Card Slot - signalFlow: bidirectional - category: digital - type: usb - connection: built-in - maxConnections: 1 - position: Top - key: DPRsuBYa name: Footswitch signalFlow: input diff --git a/data/hardware/tascam-portacapture_x6.yaml b/data/hardware/tascam-portacapture_x6.yaml index 53146d3a1..55e11ddc2 100644 --- a/data/hardware/tascam-portacapture_x6.yaml +++ b/data/hardware/tascam-portacapture_x6.yaml @@ -91,14 +91,6 @@ io: connection: usb-c maxConnections: 1 position: Bottom - - key: w9mWthTj - name: microSD Card Slot - signalFlow: bidirectional - category: digital - type: usb - connection: built-in - maxConnections: 1 - position: Right prices: - amount: 279 currency: USD diff --git a/data/hardware/tascam-portacapture_x8.yaml b/data/hardware/tascam-portacapture_x8.yaml index bac1aa0f7..be3082c68 100644 --- a/data/hardware/tascam-portacapture_x8.yaml +++ b/data/hardware/tascam-portacapture_x8.yaml @@ -123,14 +123,6 @@ io: connection: usb-c maxConnections: 1 position: Bottom - - key: lQd2e5yI - name: microSD Card Slot - signalFlow: bidirectional - category: digital - type: usb - connection: built-in - maxConnections: 1 - position: Right prices: - amount: 379 currency: USD diff --git a/data/hardware/tascam-vs-r264.yaml b/data/hardware/tascam-vs-r264.yaml index e50a21ed9..b012ba7df 100644 --- a/data/hardware/tascam-vs-r264.yaml +++ b/data/hardware/tascam-vs-r264.yaml @@ -91,14 +91,6 @@ io: connection: usb-a maxConnections: 1 position: Right - - key: wo3baYi0 - name: SD Card Slot - signalFlow: bidirectional - category: digital - type: usb - connection: built-in - maxConnections: 1 - position: Left - key: UujU3aJd name: DC Power Input signalFlow: input diff --git a/data/hardware/tascam-vs-r265.yaml b/data/hardware/tascam-vs-r265.yaml index 6229b58f5..597099caa 100644 --- a/data/hardware/tascam-vs-r265.yaml +++ b/data/hardware/tascam-vs-r265.yaml @@ -104,14 +104,6 @@ io: connection: usb-a maxConnections: 1 position: Left - - key: 9ohuKlAT - name: SD Card Slot - signalFlow: bidirectional - category: digital - type: usb - connection: built-in - maxConnections: 1 - position: Left - key: gDRNciQZ name: DC Power Input signalFlow: input diff --git a/docs/VALIDATION_ERRORS.md b/docs/VALIDATION_ERRORS.md index db65a4172..39a4971bd 100644 --- a/docs/VALIDATION_ERRORS.md +++ b/docs/VALIDATION_ERRORS.md @@ -357,6 +357,25 @@ means. Delete the key instead. --- +### E120: Storage Media Slot as IO + +An io entry's name identifies a storage media slot (SD, microSD, SDHC/SDXC, +CompactFlash, Memory Stick, SmartMedia, xD). + +Storage slots hold media, not cables, so the setup graph can do nothing with +them: no cable ever runs from a card slot to another device. This is the same +reasoning that keeps `bluetooth` and `wifi` out of the io type vocabulary. +Mention the slot in `description`, `details`, or `specs` instead. + +Deliberately narrow: option and expansion card bays (Dante/MADI option cards, +console expansion slots) accept cards that present their own connectors, so +"Option Card Slot" and similar names stay legal, as do `connection: card-slot` +entries for those bays. + +**Fix:** Delete the io entry and note the slot in the entry's prose fields. + +--- + ### E199: Validation Error A generic validation error that doesn't fall into a more specific category. diff --git a/scripts/__tests__/io-heuristics.test.ts b/scripts/__tests__/io-heuristics.test.ts index b1dd20d2c..adab7ba20 100644 --- a/scripts/__tests__/io-heuristics.test.ts +++ b/scripts/__tests__/io-heuristics.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from "vitest"; -import { isIoCombineCandidate } from "../lib/io-heuristics.js"; +import { isIoCombineCandidate, STORAGE_MEDIA_SLOT } from "../lib/io-heuristics.js"; describe("isIoCombineCandidate", () => { it("flags several single jacks collapsed into one entry", () => { @@ -41,3 +41,45 @@ describe("isIoCombineCandidate", () => { ).toBe(true); }); }); + +describe("STORAGE_MEDIA_SLOT", () => { + const storage = [ + "SD Card Slot", + "microSD Card Slot", + "Micro SD Card - Flashed", + "SD Card", + "SDHC Card Slot", + "CompactFlash Slot", + "Memory Stick Slot", + // Slot-only spellings: the media token alone marks these as storage. + "SD Slot", + "microSD Slot", + "SDXC Slot", + "xD Slot", + "CF Slot", + ]; + for (const name of storage) { + it(`matches storage slot '${name}'`, () => { + expect(STORAGE_MEDIA_SLOT.test(name)).toBe(true); + }); + } + + // Option bays present real connectors, mic names contain "cardioid", and + // "Soundcard"/"DSD" must not trip the sd stem. + const legal = [ + "Option Card Slot", + "64x64 I/O Option Card Slot", + "Expansion Card Slot (DN32-USB/ADAT/MADI/DANTE)", + "Thunderbolt 3 Option Card", + "UAD-2 PCIe Accelerator Cards", + "USB 2.0 (20 Channel 24-bit/96kHz Soundcard)", + "4011 Cardioid Microphone", + "Detachable Hypercardioid Boom Microphone Input", + "DSD Card", + ]; + for (const name of legal) { + it(`leaves '${name}' alone`, () => { + expect(STORAGE_MEDIA_SLOT.test(name)).toBe(false); + }); + } +}); diff --git a/scripts/lib/error-codes.ts b/scripts/lib/error-codes.ts index 0b3d9dd26..b98135c3b 100644 --- a/scripts/lib/error-codes.ts +++ b/scripts/lib/error-codes.ts @@ -40,6 +40,7 @@ export enum ValidationErrorCode { E117_INVALID_IO_TYPE = "E117", E118_NAME_ARTIFACT = "E118", E119_INVALID_CAPABILITY = "E119", + E120_STORAGE_MEDIA_SLOT = "E120", E199_VALIDATION_ERROR = "E199", // Reference errors (E2xx) @@ -205,6 +206,10 @@ const ERROR_INFO: Record = { title: "Invalid capability", anchor: "e119-invalid-capability", }, + [ValidationErrorCode.E120_STORAGE_MEDIA_SLOT]: { + title: "Storage media slot as IO", + anchor: "e120-storage-media-slot-as-io", + }, [ValidationErrorCode.E199_VALIDATION_ERROR]: { title: "Validation error", anchor: "e199-validation-error", diff --git a/scripts/lib/io-heuristics.ts b/scripts/lib/io-heuristics.ts index eadc061c1..22855a4a2 100644 --- a/scripts/lib/io-heuristics.ts +++ b/scripts/lib/io-heuristics.ts @@ -54,3 +54,18 @@ export function isIoCombineCandidate(io: IoLike, owner?: IoOwner): boolean { if (owner?.primaryCategory && AGGREGATE_CATEGORIES.has(owner.primaryCategory)) return false; return true; } + +/** + * Storage-media slots (SD, microSD, CompactFlash, Memory Stick and kin) are + * not connectable ports: they hold media, not cables, so the setup graph can + * do nothing with them — the same reasoning that keeps Bluetooth and Wi-Fi + * out of the io type vocabulary. Validation hard-fails an io entry whose + * name matches (E120); the slot belongs in description/details/specs. + * + * Deliberately narrow: option and expansion card bays (Dante/MADI option + * cards, 500-series style bays) accept cards that PRESENT connectors, so + * "Option Card Slot" and friends must not match, and neither may "cardioid" + * in microphone names. + */ +export const STORAGE_MEDIA_SLOT = + /\b(?:micro\s*)?sd(?:hc|xc)?[\s-]*(?:card|slot)|\bmemory\s*(?:card|stick)|compact[\s-]*flash|\bcf[\s-]*(?:card|slot)|smart[\s-]*media|\bxd[\s-]*(?:picture[\s-]*)?(?:card|slot)/i; diff --git a/scripts/validate.ts b/scripts/validate.ts index 5ac65de3d..bd32aae74 100644 --- a/scripts/validate.ts +++ b/scripts/validate.ts @@ -12,7 +12,7 @@ import { parse as parseYaml } from "yaml"; import { z } from "zod"; import { looksLikeAcronymName } from "./lib/acronym-exclusions.js"; import { getDocsUrl, ValidationErrorCode } from "./lib/error-codes.js"; -import { isIoCombineCandidate } from "./lib/io-heuristics.js"; +import { isIoCombineCandidate, STORAGE_MEDIA_SLOT } from "./lib/io-heuristics.js"; import { findDuplicateIoKeys, IO_KEY_PATTERN } from "./lib/io-keys.js"; import { findNameArtifacts, @@ -216,7 +216,12 @@ function getErrorCodeFromZodIssue(issue: { } } - // IO field errors + // IO field errors. E120 is raised only by the io name check, so it is + // keyed to the name path: a connectorDetail VALUE that happens to contain + // the phrase must still classify as E115, not E120. + if (path.endsWith(".name") && message.includes("storage media slot")) { + return ValidationErrorCode.E120_STORAGE_MEDIA_SLOT; + } if (message.includes("invalid io signal flow")) { return ValidationErrorCode.E111_INVALID_IO_SIGNAL_FLOW; } @@ -432,7 +437,20 @@ const IOSchema = z .string() .regex(IO_KEY_PATTERN, "IO key must be exactly 8 alphanumeric characters") .optional(), - name: z.string(), + name: z.string().check((ctx) => { + if (STORAGE_MEDIA_SLOT.test(ctx.value)) { + ctx.issues.push({ + code: "custom", + message: + `Storage media slot '${ctx.value}' is not a connectable port. ` + + `Memory card slots hold media, not cables, so the setup graph cannot ` + + `use them (same reasoning as Bluetooth/Wi-Fi). Mention the slot in ` + + `description/details/specs instead. Option and expansion card bays ` + + `that accept I/O cards stay legal.`, + input: ctx.value, + }); + } + }), signalFlow: z.string().check((ctx) => { if (!VALID_IO_SIGNAL_FLOWS.has(ctx.value)) { const suggestion = findClosestMatch(ctx.value, VALID_IO_SIGNAL_FLOWS);