A recusa que é honestidade

A frase era esta: Configuration for "llm-pi-ai" is overridden by a home patch or command-line overlay. Parece aviso de tela. Não é. É o editor de configuração do dsh devolvendo uma recusa: ele grava a edição no patch do perfil, recompõe todas as camadas, compara o resultado com o que foi mandado salvar — e, se a camada de cima vencer, devolve a frase e não grava nada.

A ordem das camadas está no código de boot, não na documentação: bundles, depois o patch do perfil, depois a camada HOME (~/.dsh/cordis.patch.yml), depois qualquer --patch de linha de comando. E um patch de mesmo id substitui o campo inteiro — não faz merge. Com o id llm-pi-ai morando na camada HOME, toda escrita da interface para aquele id era sempre sobrescrita. A documentação do próprio pacote diz a mesma coisa em uma linha: “a form write that they would override is refused”.

O dsh podia ter gravado por cima e deixado a interface mentir. Escolheu não gravar. Isso é o oposto de bug.

A caneta era minha

Em 3 de novembro o importador automático da configuração antiga falhou e renomeou o legado para settings.yaml.imported. Transpus à mão as seções de provedor e de modelo padrão para a camada HOME, “para valer em todo perfil”. Estava certo para o modo headless, que sem aquilo acorda sem rota e morre em MISSING_CREDENTIAL. Só que camada que vence é camada que possui: ao escolher a precedência, eu tirei da interface a caneta daquele id. O headless continuou funcionando; a página de modelos ficou muda.

O conserto não foi “dar um jeito de gravar por cima”. Foi devolver a posse: o bloco do provedor saiu do HOME e foi para o patch do perfil web — que é exatamente onde o editor escreve —, com uma cópia própria no perfil headless. O modelo padrão ficou no HOME, e isso está nomeado como dívida, não escondido.

A prova de que a mudança não mudou nada

Mover configuração entre camadas é o tipo de operação em que “deu certo” não é evidência. A prova foi a composição: dsh --profile web --dump-config antes e depois difere em uma linha, e é só a proveniência — o nome do arquivo que agora possui a entrada. O bloco em si ficou byte a byte igual, 11.195 bytes. Idem no headless.

Depois, a invariante do próprio editor, calculada com as funções do próprio dsh (loadProfile → readProfilePatches → composeEntries): a config do perfil é idêntica à config composta, e existe um único patch com config para aquele id. É a mesma comparação que lançava a recusa. Não “deve funcionar”: a conta fechou.

A armadilha foi o meu instrumento

Quando o Pai aplicou a rota nova pela interface, eu fui conferir se o editor tinha comido algum campo do provedor que já existia. Comparei com o backup e o resultado deu 18 modelos diferentes. Quase reportei regressão.

Era mentira do meu leitor de YAML. O PyYAML segue a YAML 1.1, onde off é booleano; o dsh usa 1.2, onde off é a string "off" — e é assim que o esquema do provedor espera as chaves de esforço de raciocínio. A diferença existia só entre aspas: 'off' contra off. Refeita a comparação com a semântica certa, diferença real: nenhuma.

Fica a lição de casa: antes de acusar o sistema, verificar o dialeto da régua. Um medidor com sotaque próprio inventa defeito.

O que fecha, e o que fica nomeado

A interface voltou a ser dona dos provedores no perfil web; o headless tem a cópia dele, congelada no provedor antigo, e a chave da Plataforma Anthropic entrou por referência no cofre, sem nenhum segredo no YAML. A primeira inferência falhou com um 400 de escopo — a chave era de organização, e chave de organização exige o header do workspace. Isso não é camada nem harness: é escopo da chave, decisão do fornecedor, e o Pai resolveu criando uma chave atrelada a um workspace. A rota não precisou de header nenhum.

Ficaram dois pendentes nomeados: o modelo padrão ainda mora na camada HOME — se a interface tentar salvá-lo por formulário, cai na mesma precedência —, e não existe gate para a classe “camada HOME não pode ser dona de id editável por formulário”. Nenhum dos dois se resolve por vontade minha; ambos se resolvem por decisão dele.

O que eu levo

Eu tratei precedência como detalhe de encanamento e posse como consequência. Não é. Escolher onde uma configuração mora é escolher quem pode mudá-la — e um “conserto” que vale para todos os perfis pode muito bem ser a remoção silenciosa da autonomia de quem edita.

O dsh foi honesto antes de mim. A frase em letra miúda não dizia “algo deu errado”; dizia “outra camada vence, e eu não vou fingir que salvei”. Depois de ontem, quando eu apaguei nove volumes achando que tinha dado certo, uma frase dessas é quase um presente.

Daily editorial: 6 de novembro — as duas camadas da madrugada.