[PITCH] SCI: Transformando executáveis legados em contratos de I/O estáveis
SCI (Spectrum Command Interface)
Eu tinha um tabuleiro de xadrez que não movia as peças.
Era um projeto pessoal: uma interface de visualização onde os movimentos eram feitos via notação e código Morse, o clique do mouse gerava pontos e traços. Funcionava. E por trás de tudo, um Stockfish conversando por stdin/stdout seguindo o UCI (Universal Chess Interface).
O que me impressionou não foi a força do motor. Foi a arquitetura. O Stockfish não tem API. Não tem servidor. Ele implementa um protocolo textual determinístico: lê uma linha, escreve uma linha e isso foi suficiente para que um ecossistema inteiro surgisse em volta.
Meses depois, problema diferente: dez binários legados num ambiente de produção, cada um gerado por uma stack diferente (Fortran, COBOL, C), e uma dashboard web que precisava consumir os resultados. Sem acesso ao código-fonte de alguns. Sem tempo para FFI. Sem como mexer no ABI.
A pergunta que ficou: e se eu fizesse o que o UCI faz, mas sem o domínio fixo do xadrez?
O que é o SCI
O SCI (Spectrum Command Interface) é uma camada de protocolo para execução de binários. Você aponta para um executável qualquer e define como mapear input em argv — ele cuida do resto.
Na prática, ele funciona como:
- um adapter de execução
- um validador de entrada tipada
- um compilador de templates para
argv - e um protocolo textual de I/O baseado em linhas (
stdin→stdout)
Configuração (sci.toml)

Modo Persona (stdio)

Modo Machine (stdio)

Isso é tudo. A partir daí, qualquer coisa que saiba fazer pipe — Node, Python, Go, Bun, um script shell — consegue consumir o binário sem tocar nele.
O que o SCI não é
Não é servidor HTTP.
Não é RPC formal.
Não parseia o output (isso é responsabilidade de quem integra).
Não entende o que o binário faz.
Se você quiser HTTP, fila, gRPC — você escreve um wrapper. O SCI permanece puro, exatamente como o Stockfish permanece puro enquanto GUIs e servidores constroem mundos em volta dele.
Por que sem shell
A execução é feita via:
exec.Command(bin, argv...)
Sem /bin/sh. Sem interpolação de string.
Os caracteres ;, &&, |, crases — tudo isso é tratado como argumento, não como código.
Isso elimina uma classe inteira de vulnerabilidades (injeção de shell).
O SCI não amplia a superfície de ataque nesse vetor.
Ainda assim, o binário continua sendo uma fronteira de confiança, e deve ser tratado como tal.
Transporte
O SCI funciona em dois modos de transporte:
- stdio — pipe direto, ideal para integração local e wrappers
- Unix socket — para uso como daemon em container
Configuração (sci.toml)

Machine (socket)

E dois modos de interface:
- machine — saída previsível, sem cores, para automação
- persona — banner, cores, logs, para uso manual
Contrato
Inspirado diretamente no UCI:
- Entrada: linhas de texto via
stdin - Saída: linhas de texto via
stdout - Sucesso: linhas que começam com
ok - Erro: linhas que começam com
err
Isso cria um protocolo simples, determinístico e fácil de integrar — sem dependência de linguagem, framework ou stack.
Estado atual
O projeto está em v0.1.1-alpha. Binários pré-compilados disponíveis para Linux/amd64, Darwin/arm64 e Windows/amd64 via GitHub Actions.
Exemplos prontos em /examples/:
- Fortran (decaimento radioativo)
- COBOL (validação Luhn)
- Docker (daemon via socket)
Clientes em /packaging/: Node (Typescript) e Python.
Hoje, já utilizo o SCI para expor binários científicos — incluindo implementações em Fortran — como interfaces consumíveis em ambientes Docker. Nenhuma reescrita. Nenhum binding. Nenhuma alteração no código original.
Apenas um contrato de I/O estável entre sistemas de épocas diferentes.