Modelo de execução
O que cada etapa lê, o que escreve e o que deliberadamente não faz.
As quatro coisas envolvidas
Tudo no modelo de execução é uma relação entre quatro coisas distintas. Mantê-las separadas é o que torna o resto previsível.
- Estrutura esperada — os diretórios declarados na sua especificação. O contrato.
- Estado do workspace — o que está de fato em disco sob o diretório raiz agora.
- Plano — a diferença entre os dois, calculada e impressa sem alterar nada.
- Fingerprint registrado — o SHA-256 da especificação a partir da qual o workspace foi construído pela última vez, guardado em
.orv.lock.
Ordem das etapas
especificação (.orvienm.yaml)
↓
parse YAML inválido → saída 4
↓
validate estrutura inválida → saída 1
↓
plan diff somente leitura
↓
apply desvio → saída 3; caso contrário, create
↓
verify / status / doctorO parse e a validação rodam no início de todo comando, não apenas quando você os invoca diretamente. Uma especificação que falha na validação não chega ao plan nem ao apply.
O que o apply governa
O apply cria o diretório raiz nomeado por structure.name e todos os diretórios declarados dentro dele. Se a raiz já existe, ele cria os diretórios declarados que estão faltando e deixa o resto em paz. Essa é toda a sua superfície de escrita.
Ele não apaga, move nem renomeia nada, e não toca no conteúdo de arquivos. Um diretório que existe mas não foi declarado fica exatamente como está — o Orvienm não trata “ausente da especificação” como “não deveria existir”, porque um workspace raramente pertence a uma única ferramenta.
O apply é idempotente em efeito: rodá-lo contra um workspace que já corresponde reporta a estrutura como conforme e não escreve nada. Ele não é atômico — se a criação de diretórios falhar no meio, os diretórios já criados permanecem.
Como ler um plano
O plan imprime uma linha por diretório e um resumo. Os três marcadores são:
+ create— declarado, ausente em disco. O apply vai criá-lo.= keep— declarado e já presente. O apply vai deixá-lo em paz.? undeclared— presente em disco, não declarado. O apply não o cria nem o remove.
O resumo conta cada categoria. Nenhum comando da CLI atual executa exclusão, e o plano não nomeia nenhuma operação que o engine não vá executar.
Desvio
Desvio no Orvienm significa que a especificação mudou, não o sistema de arquivos. No primeiro apply bem-sucedido, o fingerprint da especificação é escrito em .orv.lock. Nas execuções seguintes, o apply recalcula esse fingerprint e compara.
Se forem diferentes, o apply se recusa a rodar e sai com 3. Remover .orv.lock aceita a nova especificação. Passar --dry-run contorna o bloqueio sem escrever nada.
Um diretório apagado à mão não gera desvio. Use verify para conferir se os diretórios declarados ainda existem, ou doctor para o quadro completo.
Convergência
Um workspace convergiu quando o doctor reporta HEALTHY: a raiz existe, nenhum diretório declarado está faltando, nenhum diretório não declarado está presente, e o fingerprint corresponde ao lock.
O verify é uma checagem mais estreita — os diretórios declarados existem, nada além disso — e o status fica entre os dois ao acrescentar o lock e o fingerprint. O verify sai com 0 quando a estrutura está completa e com 2 quando não está, sem precisar de flag: ele é o portão estrutural. O doctor reporta seu diagnóstico e sai com 0 por padrão; doctor --strict é a invocação que quebra um pipeline diante de qualquer coisa diferente de HEALTHY.
Um diretório declarado só é satisfeito por um diretório. Um arquivo comum parado em um caminho declarado não conta como esse diretório: verify, status e doctor reportam o workspace como incompleto, e o apply recusa a colisão em vez de resolvê-la — ele nomeia o caminho, não cria nada, sai com 2 e deixa o arquivo exatamente como estava.
O que é determinístico
Duas propriedades valem de forma precisa, e vale enunciá-las em vez de generalizar.
- O fingerprint é calculado a partir de um manifesto canônico contendo apenas
version,style,structure.namee a lista de diretórios ordenada. Reordenar diretórios, reformatar o arquivo ou acrescentar comentários não o altera. Mudarstylealtera. - Dada a mesma especificação e o mesmo estado do workspace, o apply produz os mesmos diretórios.
As duas valem também para entradas aninhadas: um caminho declarado se expande nos diretórios que implica, e plan, verify e doctor raciocinam sobre esse mesmo conjunto expandido.
Evoluir uma especificação
O apply cria os diretórios declarados que faltam, exista a raiz ou não, então um workspace pode crescer. O que fica entre você e esse crescimento é o bloqueio por desvio, não o apply: editar uma especificação muda o fingerprint dela, e o apply então se recusa a rodar e sai com 3 sem tocar em nada.
Para aceitar uma mudança que você pretendia, remova o lock e aplique de novo:
$ orvienm apply .orvienm.yaml ! Drift detected Current YAML fingerprint differs from .orv.lock. Update YAML or remove .orv.lock to proceed. # exit 3 $ rm .orv.lock $ orvienm apply .orvienm.yaml Structure already exists. Added missing directories: + data/ .orv.lock generated successfully. # exit 0 $ orvienm plan .orvienm.yaml # Create: 0
O apply cria o que a nova especificação acrescentou, mantém tudo o que já estava lá e registra o novo fingerprint. O plan então reporta Create: 0 e o workspace convergiu.
Remover o lock é hoje a única forma de aceitar uma mudança de especificação, e é um instrumento grosseiro: descarta o fingerprint registrado em vez de reconhecer a passagem de um para o outro, e aceita todas as edições do arquivo de uma vez — inclusive uma raiz renomeada ou entradas que você removeu. Revise a especificação antes de remover o lock. Uma etapa dedicada de reconhecimento é uma questão de design em aberto, não um recurso entregue.
Limitações atuais
O apply também não é atômico: se a criação de diretórios falhar no meio, os diretórios já criados permanecem.
Para os argumentos exatos e os códigos de saída de cada comando, veja a Referência da CLI; para o que uma falha específica significa, veja a Solução de problemas.