TODO
Roadmap de desenvolvimento do Ioruba, reescrito em 2026-06-17 a partir do estado real do código após o release v1.2.0.
Todos os Scrums anteriores estão cumpridos. O histórico detalhado vive no git e no CHANGELOG.md; este documento olha para frente.
Formato:
[x]concluído ·[ ]pendente- descrição
(tag/tag/tag)-fácil|médio|difícil
Estado atual (baseline v1.2.0)
- Firmware (
firmware/arduino/ioruba-controller): Arduino Nano,NUM_KNOBSparametrizável por define (IORUBA_NUM_KNOBS), masANALOG_PINS = {A0,A1,A2}ainda fixo em 3. HandshakeHELLO board=...; fw=...; protocol=...; knobs=N, framev0|v1|..., calibração + EEPROM (magic/schema).PROTOCOL_VERSION=2, AVR 10-bit. - Shared (
packages/shared): protocolo e perfil já genéricos em contagem de knobs. Assume ADC 10-bit em todo lugar (SLIDER_MAX=1023,validation/protocolrejeitam>1023). - Desktop (
apps/desktop): Tauri 2 + React 19, store Zustand, serial viatauri-plugin-serialplugin. Backends de áudio:linux(pactl: master/app/source/sink),windows(WASAPI: master),macos(CoreAudio: master),unsupported. Telemetria de sessão + watch log. - Distribuição: release multiplataforma (deb/rpm/AppImage/nsis/msi/app) + PKGBUILD AUR + provenance; instalador one-line (
scripts/install.sh/install.ps1).
Prioridade declarada: integração hardware↔SO, mais placas, eficiência, organização, ampliação, distribuição e UX completa.
Scrum 11 — Hardware: mais placas e mais knobs
Foco principal pedido. Hoje só Nano AVR com 3 pinos fixos.
- Parametrizar
ANALOG_PINSpor placa em vez de{A0,A1,A2}fixo — tabela de pinos por MCU/board selecionada em compile-time, dimensionada porNUM_KNOBS(firmware/hardware)-médio- Tabela
ANALOG_PINSpor placa (ARDUINO_AVR_*/ESP32/RP2040),static_assert(NUM_KNOBS <= ANALOG_PIN_COUNT). Usa os primeiros NUM_KNOBS canais.
- Tabela
- Matriz de compilação de firmware no CI por FQBN (Nano, Uno, Mega2560, Leonardo, Micro) via
arduino-cli, espelhando o gate atual(firmware/ci/hardware)-médio- Job
firmwarematrizado por FQBN + jobfirmware-host(parser default + wide 8k/12-bit). Scriptsfirmware:compile:matrix/firmware:test:wide.
- Job
- Suporte a Arduino Mega (A0..A15) habilitando >6 knobs no mesmo board — validar limites de ADC e frame
(firmware/hardware/expansão)-médio- Mega compila com 12 knobs (verificado local + host wide 8 knobs). Frame/EEPROM/struct já dimensionados por NUM_KNOBS.
- Suporte a placas de 12-bit (ESP32, RP2040/Pico): reportar
adcBitsno handshake e normalizar a resolução no shared (hojeSLIDER_MAX=1023fixo quebra 4095)(firmware/shared/protocol)-difícil- Firmware deriva
ADC_MAXdeIORUBA_ADC_BITS(auto 12 em ESP32/RP2040, 10 em AVR). Shared remove o lock 1023: funções de mixer/runtime recebemadcMaxopcional e o parser de frame aceita até 16-bit; normalização usafirmwareInfo.adcBits. Ainda pendente: toolchain real ESP32/RP2040 e teste em hardware.
- Firmware deriva
- Toolchain para ESP32/RP2040 (core
arduino-cliadicional ou avaliação de PlatformIO)(firmware/build/hardware)-difícil- Optou-se por cores
arduino-cli(não PlatformIO): job CIfirmware-archmatrizaesp32:esp32+rp2040:rp2040(earlephilhower) com caches próprios. Ambos compilam (verificado local). Corrigida colisãoBOARD_NAMEcom macro do core arduino-pico.
- Optou-se por cores
- Handshake estendido: reportar
board,mcueadcBits; bumpPROTOCOL_VERSIONse incompatível, com fallback para v2(firmware/protocol)-médiomcu/adcBitsadicionados como campos aditivos do handshake; protocolo mantido em v2 (campos opcionais, hosts antigos ignoram, novos assumem 10-bit quando ausentes) — sem quebra de compatibilidade.
- Detecção automática e exibição do board/MCU no desktop a partir do
board=do handshake(frontend/hardware/ux)-fácil- Tile “Hardware” no
OverviewSignalPanelmostra board · MCU +adcBits-bit · protocolo (com aviso de incompatibilidade).
- Tile “Hardware” no
- Suporte a botões/encoders além de potenciômetros (mute/next/prev) — novo tipo de input no protocolo e perfil
(firmware/shared/expansão)-difícil- Firmware aceita
IORUBA_NUM_BUTTONS/IORUBA_NUM_ENCODERS, usaINPUT_PULLUP, debounce e quadratura, e só emiteEV type=...após opt-inEVENTS ONpara preservar desktops antigos. Shared parseiaEVbutton/encoder; perfil ganhoucontrolscom bindingsmute/next/prev; desktop resolve eventos, executa ações via Tauri (pactl/playerctlno Linux, mute no Windows) e registra suporte/erros no watch log.
- Firmware aceita
- Documentar pinagem e matriz de placas suportadas em
docs/guides/hardware-setup.md(docs/hardware)-fácil- Seção “Supported boards” (tabela MCU/bits/canais/max-knobs/ordem de pinos) + mirror PT-BR.
Scrum 12 — Integração SO↔áudio mais profunda
Hoje Windows/macOS só controlam master. Linux tem cobertura completa.
- Per-app volume no Windows via
IAudioSessionManager2/ISimpleAudioVolume— targetsapplicationfora do Linux(backend/audio/windows)-difícil - Enumerar e controlar
sink/sourceno Windows (devices de saída/entrada)(backend/audio/windows)-difícil - Avaliar per-app volume no macOS (sem API pública trivial; investigar
AudioObjectpor processo ou rejeitar formalmente)(backend/audio/macos/research)-difícil - Ação de mute/toggle por knob ou botão, não só set de volume
(backend/shared/frontend)-médio - Mapear hotkeys globais (
tauri-plugin-global-shortcutjá presente) a ações de mixagem(frontend/backend/ux)-médio - Avaliar backend PipeWire nativo no Linux (sem fork/exec de
pactl)(backend/audio/linux/research)-difícil - Estudo: transporte MIDI como alternativa à serial para controladores genéricos
(backend/protocol/research)-difícil
Scrum 13 — Eficiência e otimização
- Estender o cache de inventário (TTL ~250ms, já existe no Linux) aos backends Windows/macOS — hoje re-inicializam COM/CoreAudio a cada chamada
(backend/audio/performance)-médio - Reusar handle de device (COM apartment /
IMMDevice/AudioObjectID) entre chamadas respeitando thread-affinity(backend/audio/performance)-difícil - Coalescing/debounce de writes de volume sob movimento rápido de knob, por target
(backend/runtime/performance)-médio - Reduzir o bundle do chart (
charts~353KB gzip 104KB) — lib mais leve ou code-split por aba(frontend/bundle/performance)-médio - Instrumentar e logar latência knob→áudio no watch log (já há timings de boot/connect/refresh)
(observability/performance)-fáciluse-serial-runtimecronometraapplySliderTargetsBatchcomperformance.now(); emitewarningno watch log quando passa deAUDIO_APPLY_SLOW_MS(80ms), com tempo + nº de alvos (sem flood).
- Perfilar consumo em sessão longa (telemetria + watch log) e validar ausência de leaks
(performance/observability)-médio
Scrum 14 — Organização e qualidade de código
- Extrair lógica duplicada dos backends (
describe_target,summarize_slider_outcomerepetidos emwindows.rs/macos.rs/linux.rs) paraaudio/common.rs(backend/refactor/organização)-médio - Testes host-independentes para
summarize_slider_outcome/describe_target(hoje sem testes emwindows.rs/macos.rs)(test/backend/coverage)-fácil - Cobertura de testes do store Zustand (
ioruba-store.ts), incl. reset desessionStatsvia wrapper doset(test/frontend/coverage)-médio - Documentar o contrato Rust↔TS dos backends e o dispatch por
cfgemaudio/mod.rs(docs/backend/organização)-fácil - Gate de
shellcheckno CI parascripts/install.she demais scriptssh(ci/quality)-fácil- Job
scripts-lintno CI rodashellcheckem install.sh/run-appimage-compat.sh/validate-appimage.sh (passam limpo). Script localnpm run lint:scripts.
- Job
- Lint de PowerShell (
PSScriptAnalyzer) parascripts/install.ps1(ci/quality)-fácil- Mesmo job
scripts-lint: PSScriptAnalyzer via pwsh, reporta Warning+Error, falha só em Error.
- Mesmo job
Scrum 15 — Distribuição e updates
- Auto-updater in-app (
tauri-plugin-updater+latest.jsonno release) — bloqueado em chave de assinatura/secret no CI; preparar infra e deixar a chave como TODO(dist/release/security)-difícil - Assinatura + notarização macOS (hoje
.appunsigned; installer faz strip de quarantine)(dist/macos/security)-difícil - Gerar
.dmgno macOS além do.app.tar.gz(dist/macos)-médio - Manifest Homebrew cask para macOS
(dist/macos/packaging)-médio - Manifest Scoop e submissão winget para Windows
(dist/windows/packaging)-médio - Automatizar publicação do AUR (
ioruba-desktop/-bin) no fluxo de release(dist/linux/ci)-médio - Endurecer o instalador one-line: testar arm64 Linux/macOS e cobrir ausência de assets
(dist/installer/quality)-fácil
Scrum 16 — Telemetria e dados
- Export dos
sessionStatspara arquivo (JSON/CSV) via dialog, reusando o padrão do export de perfil/watch log(frontend/backend/telemetry)-fácil- Formatters puros
sessionStatsToJson/sessionStatsToCsvno shared (+testes), comando Tauriexport_session_stats(filtros JSON/CSV), botões JSON/CSV noSessionStatsPanel.
- Formatters puros
- Histórico de telemetria persistente em disco (opt-in) para análise pós-sessão
(backend/telemetry/persistence)-médio - Visualização comparativa entre sessões (picos, médias, duração)
(frontend/telemetry)-médio
Scrum 17 — Ampliação: automação e comunidade
- Regras condicionais de mixagem (“quando o app X tocar, reduzir Y”) — subsistema acima do mapeamento knob→target; exige design/spec
(shared/backend/frontend/expansão)-difícil - Galeria/repositório de presets compartilháveis pela comunidade (import/export por arquivo já existe)
(frontend/product/expansão)-difícil - Perfis por aplicação ativa (trocar mapeamento conforme o app em foco)
(backend/frontend/expansão)-difícil
Scrum 18 — Experiência completa
- Wizard de calibração de knobs na UI (ler/escrever
minRaw/maxRaw/deadzone via comandoCONFIG, que já existe no protocolo)(frontend/firmware/ux)-médio - Auditoria de acessibilidade (a11y) do dashboard, foco/teclado/aria
(frontend/a11y/ux)-médio - Ampliar i18n além de en/pt-BR (estrutura de
i18n.tsjá suporta)(frontend/i18n)-médio - Exibir board/MCU/
adcBits/protocolo detectados num painel de diagnóstico claro(frontend/hardware/ux)-fácilHardwarePanel(seção Hardware): placa, MCU, resolução do ADC, protocolo (compat.), knobs e calibração por knob, com estado vazio. Integrado à navegação agrupada nova.
- Indicador visual de latência e saúde da conexão sempre visível (alinhado ao
.impeccable.md)(frontend/ux/observability)-fácilConnectionHealthIndicatorno topo do sidebar (sempre visível): dot colorido por estado + label + frescura do sinal (tempo desde o último frame, tick 1s) como proxy de latência. Store ganhoulastFrameAt. +4 testes.
Não-objetivos
- Reintroduzir tooling de build na raiz fora de
apps//packages//firmware/. - Cobertura completa de áudio em plataformas sem backend nativo — nesses casos, modo UI/demo ou suporte parcial com banners explícitos.