Self-Hosted Data Refresh

mandatory

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-mirror delta, 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_seconds ou

    equivalente, 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.md e o geo-source-recommendations.md do 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 Atlasatlas#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): varrer koder.toml por componentes com

    heurística de dado importado sem [[imported_data]] — advisory até o audit script existir (mesma trilha de fases da RFC-002).

Cross-references