Self-Hosted Data Refresh
Toda solução self-hosted da Koder Stack que importa conteúdo externo — bases de dados (geodados, células, endereços, modelos), pacotes espelhados, ou informação colhida da internet (rankings, radares, pesquisas) — deve ser PROJETADA, desde o primeiro slice, com uma estrutura de atualização periódica desse conteúdo: refresh incremental agendado, versionamento+rollback dos snapshots, métrica de frescor com alerta de SLA, e radar de fontes quando a fonte externa evolui. Complemento temporal da self-hosted-first: os 5 gates decidem SE self-hosteamos; esta policy garante que o que foi self-hosteado não apodrece. Diretiva do owner 2026-06-11 (sessão rastreador.crescer.net), ticket de origem projects/koder-stack#191.
Diretiva (owner, 2026-06-11): "Sempre que a gente implementar uma solução self-hosted que demande importação de bases de dados, atualizações de versões de pacotes, pesquisas na internet, etc., a nossa solução deve ser projetada considerando necessariamente a implementação de uma estrutura de atualizações periódicas das bases de dados, versões de pacotes, pesquisas na internet por informações atuais, etc."
Um flip self-hosted sem refresh degrada silenciosamente: o mapa desatualiza, a base de células envelhece, o ranking de modelos fica obsoleto — e o componente "aprovado nos 5 gates" volta a perder da alternativa externa sem que nenhum alerta dispare. Esta policy fecha esse buraco por construção, não por vigilância humana.
Quando se aplica
Um componente está no escopo quando hospeda conteúdo importado cuja fonte de verdade é externa e continua evoluindo lá fora:
| Categoria | Exemplos na Stack |
|---|---|
| Bases de dados importadas | geodados OSM/CNEFE (Koder Atlas, karavan geo embarcado), base de células LBS (karavan#018), corpora, dicionários |
| Modelos/pesos de IA | catálogo modelreg (stack-RFC-008), modelos de transcrição on-device (specs/media/transcription.kmd) |
| Pacotes/versões de software | espelhos aptOCI de terceiros, imagens-base de container, toolchainsSDKs redistribuídos, vendored upstreams com release cadence própria — inclui acompanhar novas versões e patches de segurança dos pacotes hospedados, não só a presença do espelho |
| Pesquisa materializada (internet) | qualquer informação coletada por pesquisa na internet e hospedada como dado: rankingsradares (ai-model-recommendations.md, geo-source-recommendations.md), catálogos de preçosspecshomologações (ex.: fichas AnatelMercado Livre do procurement), regulamentos, listas públicas — a pesquisa que a gerou deve ser re-executável periodicamente, não um one-shot |
Quando NÃO se aplica
- Dado gerado pela própria Stack (telemetria, posições de assets,
conteúdo de usuário) — a fonte de verdade é interna; vale
always-on/ retenção, não esta policy. - Dado consumido em runtime direto da fonte (API externa chamada a
cada request) — não há snapshot hospedado; vale
self-hosted-first(avaliar se deveria virar snapshot, e aí esta policy entra). - Fixtures de teste e dados congelados por contrato (golden files,
corpus de regressão) — imutabilidade é a feature; documentar o congelamento onde o dado vive.
- Vendored code de build (libs vendoradas) — governado por
runtime-lib-first.kmd/SemVer, não por refresh de dado.
As quatro obrigações (R1–R4)
Projetar desde o primeiro slice — entram no design e no ticket de implementação, não num follow-up:
R1 — Refresh incremental agendado
- Pipeline agendado (cron/scheduler) de atualização; nunca apenas
reimport manual sob demanda.
- Incremental quando a fonte oferece (diffs OSM, replication,
apt-mirrordelta, HF revisions); reimport completo só como fallback documentado. - Cadência declarada e proporcional à fonte (geodados: dias; *acotes de
softwarepatches de segurança: horas a dias* rankingspesquisas de internet: por release ou semanal).
- Pra pesquisa de internet materializada, R1 significa que a coleta é
um job re-executável (script/crawler versionado com critérios documentados), nunca um copy-paste manual que ninguém sabe reproduzir.
R2 — Versionamento + rollback
- Cada ciclo produz snapshot versionado; o anterior permanece
restaurável (rollback de 1 passo no mínimo).
- Atualização atômica do ponto de vista do consumidor (swap de
símlinkpartiçãoalias — nunca dado meio-atualizado servindo tráfego; alinha com
always-on).
R3 — Métrica de frescor + alerta de SLA
- Métrica exportada de idade do dado (
<comp>_data_age_secondsouequivalente, por dataset/região) —
observability-first(3 sinais). - SLA de frescor declarado no design; alerta dispara quando estourar
(refresh atrasado = incidente silencioso por definição; o alerta é o que o torna visível).
R4 — Radar de fontes (quando a fonte evolui como ecossistema)
- Se existem fontes alternativas que surgem/evoluem (modelos novos,
Overture vs OSM, novas bases governamentais), manter registry rankeado com varredura periódica — modelo provado:
registries/ai-model-recommendations.mde ogeo-source-recommendations.mddo atlas#002-B. - O radar alimenta
self-hosted-first(que fonte incorporar/flipar). - Fonte única e estável (ex.: CNEFE por Censo) → R4 degrada pra "assinar
o ciclo de release da fonte" (item de R1), sem registry próprio.
Declaração — koder.toml [[imported_data]]
Algoritmo-estático, dado-dinâmico (mesmo padrão da self-hosted-first): componentes no escopo declaram cada dataset importado:
[[imported_data]]
name = "osm-brazil" # identificador do dataset
source = "geofabrik:brazil-latest" # fonte de verdade externa
refresh = "daily" # cadência (R1)
mechanism = "osm-diffs" # incremental | full-reimport | <named>
freshness_sla = "7d" # gatilho de alerta (R3)
rollback = true # snapshot anterior restaurável (R2)
radar = "registries/geo-source-recommendations.md" # R4 (ou omitido)A IA/auditoria lê os blocos, não prosa. Componente no escopo sem bloco [[imported_data]] é o anti-drift primário desta policy.
Anti-patterns
- Import-and-forget — subir a base na PoC e prometer o refresh "depois
do MVP". O refresh é parte do design (diretiva do owner é explícita: necessariamente).
- Refresh manual heróico — "alguém roda o script quando lembrar".
Sem cron + alerta, não conta como R1/R3.
- Update destrutivo — sobrescrever in-place o dataset servindo
tráfego (viola R2 e
always-on). - Frescor invisível — pipeline existe mas nenhuma métrica diz se
rodou; a primeira notícia do atraso vem de um usuário com mapa velho.
Casos-modelo (conformes na origem)
- Koder Atlas —
atlas#002: OSM diffs + Nominatim replication +snapshot/rollback + métrica de frescor + radar de fontes (R1–R4 completos; é o template).
- Autocuração de modelos (stack-RFC-008) — modelreg→eval→curator com
discover periódico de HF (R1+R4); transcrição on-device do Dek consome via model catalog (
specs/media/transcription.kmd). - Karavan geo embarcado / LBS — karavan#017 e #018 já nasceram com
refresh by design citando esta policy.
Enforcement
- Gatilho no CLAUDE.md (tabela de Gatilhos): implementar solução
self-hosted que importa dadospacotesinformação externa → ler esta policy antes.
- Review`k-go`: tickets de componente no escopo devem citar R1–R4
(ou justificar exclusão pelo "Quando NÃO se aplica").
/k-housekeep(futuro): varrerkoder.tomlpor componentes comheurística de dado importado sem
[[imported_data]]— advisory até o audit script existir (mesma trilha de fases da RFC-002).
Cross-references
self-hosted-first.kmd— irmã: decide oflip; esta mantém o flip saudável no tempo.
observability-first.kmd— R3 é um casodos 3 sinais.
always-on.kmd— R2 (swap atômico) é o contrato derollout aplicado a dados.
- Origem: diretiva owner 2026-06-11 +
projects/koder-stack#191.