diff --git a/.gitignore b/.gitignore index c251d70..0f5d3bb 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,6 @@ target # Container integration test output /test-results/ + +# MkDocs local build output +/site/ diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..30d0807 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,138 @@ +# Changelog + +Este arquivo registra mudanças relevantes do GitDatabase a partir do histórico +Git. O projeto ainda não possui tags de release; por isso, as seções históricas +usam data e marco funcional em vez de atribuir versões que não foram publicadas. + +O formato segue as categorias do [Keep a Changelog](https://keepachangelog.com/), +adaptadas para manter rastreabilidade entre commits e arquivos. + +## Unreleased + +### Added + +- Documentação de contexto, componentes e topologias do sistema. +- Documentação detalhada dos pipelines, garantias de idempotência, falhas e + recuperação. +- Matriz de atributos de qualidade, riscos e critérios de prontidão para + produção. +- Roadmap priorizado com onze funcionalidades ausentes, dependências e critérios + de aceite. +- GitHub Action separada para clonar um repositório real, indexar metadados e + conteúdo, executar consultas SQL e publicar relatório no Job Summary. +- Docker Compose e imagem de teste com PostgreSQL efêmero, GitDatabase, `git` e + `psql`. + +### Changed + +- A documentação principal agora explicita princípios, invariantes, limitações, + ciclo de vida dos dados, integridade, backup e troubleshooting. +- A navegação do MkDocs agrupa as novas visões de arquitetura e inclui o roadmap. +- O piloto documenta Rust 1.89 como requisito efetivo do `Cargo.lock` atual e + inclui o cenário E2E em containers. +- Saídas locais de MkDocs e do teste em containers são ignoradas pelo Git. + +### Validation + +- `mkdocs build --strict` concluído com sucesso. +- Teste E2E em containers concluído com 9/9 asserções SQL aprovadas sobre + `DevComputaria/DevComputaria.Prompting`. + +### Traceability + +| Commit | Mudança | Arquivos principais | +| --- | --- | --- | +| `2306dc5` | arquitetura detalhada e roadmap | `docs/architecture/**`, `docs/roadmap.md`, `docs/database.md`, `docs/runbook.md`, `mkdocs.yml` | +| `9e68359` | teste de integração em containers | `.github/workflows/container-integration-test.yml`, `docker/Dockerfile.integration-test`, `docker/docker-compose.integration-test.yml`, `docker/run-container-integration-test.sh` | + +## 2026-05-03 — Portal de documentação + +### Added + +- Portal MkDocs Material com páginas de início, arquitetura, banco, piloto e + runbook. +- Workflow de publicação automática no GitHub Pages. + +### Changed + +- Dependências Rust e implementação de leitura Git foram atualizadas. +- Dependências MkDocs passaram a ser controladas por + `requirements-docs.txt`. +- Metadados do site, copyright e ocultação do gerador foram configurados. + +### Traceability + +| Commit | Mudança | Arquivos principais | +| --- | --- | --- | +| `5a48eed` | dependências e refactors Git/loader | `Cargo.toml`, `Cargo.lock`, `crates/gitbase-git/src/lib.rs` | +| `800a539` | documentação e deploy MkDocs | `docs/**`, `mkdocs.yml`, `.github/workflows/docs-gh-pages.yml` | +| `d0f7dc6` | requirements do portal | `requirements-docs.txt`, `.github/workflows/docs-gh-pages.yml` | +| `3c9b95c` | refinamento da CI de docs | `requirements-docs.txt`, `.github/workflows/docs-gh-pages.yml` | +| `e74544b` | configuração final do site | `mkdocs.yml` | + +## 2026-04-26 — Pipeline GitDatabase funcional + +### Added + +- Sincronização de repositórios, refs, commits, pais, trees e files. +- Schema `gitbase` e migrations de metadados Git. +- Hidratação lazy de blobs com limite de tamanho e detecção de binário. +- Autenticação do gateway pgwire e hidratação sob demanda por `blob_hash`. +- UAST para Go e Rust com projeções de funções e imports. +- Busca full-text baseada em `tsvector` e função + `gitbase.search_code(pattern, lang)`. +- Testes de integração para metadata, blobs, busca e UAST. +- CI Rust com fmt, Clippy e testes. +- Hooks pre-commit e política de segurança. + +### Changed + +- Formatação e APIs internas dos crates foram consolidadas. +- Configurações de indexação ganharam defaults e limites opcionais. +- A chamada de sync nos testes passou a usar slices de paths. + +### Removed + +- PRD e plano iniciais foram removidos quando deixaram de representar a + implementação corrente. + +### Traceability + +| Commit | Mudança | Arquivos principais | +| --- | --- | --- | +| `52884b5` | schema e sync Git | `crates/gitbase-git/**`, `crates/gitbase-loader/**`, `crates/gitbase-db/src/metadata.rs`, `migrations/20260426000001_git_metadata.sql` | +| `ed484fc` | blobs e autenticação pgwire | `crates/gitbase-db/src/blobs.rs`, `crates/gitbase-loader/src/lib.rs`, `crates/gitbase-pgwire/src/handler.rs` | +| `36cbab6` | UAST Go/Rust | `crates/gitbase-uast/**`, `crates/gitbase-db/src/uast.rs`, `migrations/20260426000002_uast.sql` | +| `33597c2` | busca, Dockerfile e guias | `crates/gitbase-db/src/search.rs`, `migrations/20260426000003_search.sql`, `Dockerfile`, `README.md`, `docs/**` | +| `ee01e1f` | CI Rust | `.github/workflows/gitdatabase-ci.yml` | +| `8ae6110` | pre-commit | `.pre-commit-config.yaml`, `README.md` | +| `c9441b4` | política de segurança | `SECURITY.md` | +| `511ee70` | remoção de especificações obsoletas | `plan.md`, `prd.md` | + +## 2026-04-19 — Bootstrap do projeto + +### Added + +- Workspace Rust inicial com CLI, banco e servidor pgwire. +- Migration inicial para habilitar `pg_trgm`. +- PostgreSQL local via Docker Compose. +- Licença MIT e arquivos básicos do repositório. + +### Traceability + +| Commit | Mudança | Arquivos principais | +| --- | --- | --- | +| `35049b6` | estrutura inicial do repositório | `.gitignore`, `LICENSE`, `README.md` | +| `59777c1` | workspace e esqueleto funcional | `Cargo.toml`, `crates/gitbase-cli/**`, `crates/gitbase-db/**`, `crates/gitbase-pgwire/**`, `docker/docker-compose.yml` | + +## Known gaps + +As limitações abertas não são tratadas como funcionalidades entregues. Elas estão +descritas e priorizadas em [docs/roadmap.md](docs/roadmap.md), com destaque para: + +- alinhamento do toolchain Rust; +- classificação de linguagem; +- sync transacional e reparável; +- reconciliação de refs/force-pushes e foreign keys; +- gestão nativa de repositórios remotos; +- observabilidade e endurecimento do pgwire. diff --git a/README.md b/README.md index 88bcbd0..39f5fa5 100644 --- a/README.md +++ b/README.md @@ -252,6 +252,16 @@ como artefato da execução. Este repositório possui documentação versionada em `docs/` com publicação automática para `gh-pages` via GitHub Actions. +Conteúdo técnico principal: + +- [Visão geral de arquitetura](docs/architecture.md) +- [Contexto e componentes](docs/architecture/system-context.md) +- [Pipelines e consistência](docs/architecture/data-pipelines.md) +- [Atributos de qualidade](docs/architecture/quality-attributes.md) +- [Modelo de dados](docs/database.md) +- [Plano de funcionalidades ausentes](docs/roadmap.md) +- [Changelog](CHANGELOG.md) + ### Rodar localmente ```bash diff --git a/docs/architecture.md b/docs/architecture.md index f6cf860..b3e5cfc 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -2,6 +2,31 @@ Esta página descreve a arquitetura implementada no código atual do GitDatabase. +## Como ler esta documentação + +- [Contexto e componentes](./architecture/system-context.md): fronteiras, + processos, crates, topologias e segurança +- [Pipelines e consistência](./architecture/data-pipelines.md): ciclo de vida dos + dados, idempotência e recuperação +- [Atributos de qualidade](./architecture/quality-attributes.md): riscos de + produção, capacidade, segurança e estratégia de testes +- [Banco de dados](./database.md): modelo relacional, índices e consultas +- [Plano de funcionalidades](./roadmap.md): lacunas priorizadas e critérios de + aceite + +## Princípios implementados + +1. **PostgreSQL como plataforma de dados:** persistência, busca e consultas usam + capacidades nativas do banco. +2. **Conteúdo endereçado por hash:** blobs, índice textual e UAST são + deduplicados por SHA-1 do objeto Git. +3. **Ingestão em estágios:** metadata, conteúdo, busca e semântica podem evoluir + e ser reexecutados separadamente. +4. **Git permanece fonte de verdade:** o banco é uma projeção consultável; a + hidratação ainda depende dos objetos locais. +5. **Limites antes de parsing:** tamanho, binário e UTF-8 protegem os estágios de + conteúdo. + ## Workspace e crates O projeto é um workspace Rust com os seguintes crates: @@ -38,6 +63,10 @@ Blobs hidratados + índice de busca + UAST Consultas SQL / pgwire ``` +O pipeline é eventualmente consistente: concluir `sync` não implica que blobs, +busca ou UAST estejam atualizados. Consulte a +[matriz de reexecução](./architecture/data-pipelines.md#matriz-de-reexecucao). + ## Detalhes de implementação relevantes ### 1) Descoberta e leitura Git (`gitbase-git`) @@ -92,6 +121,28 @@ Consultas SQL / pgwire - Encaminha queries para PostgreSQL real (`sqlx`) - Em consultas `SELECT`, tenta hidratar blobs referenciados por `blob_hash` antes de executar +## Invariantes e limites + +- `repositories.path` é único e também participa indiretamente da identidade do + repositório. +- commits, files e tree entries pertencem a um repositório lógico, mas essa + relação ainda não é protegida por foreign keys. +- `files` representa ocorrências por commit; não é uma visão apenas do HEAD. +- `blobs`, `code_index` e `uast_cache` são globais por hash. +- uma linha em `blobs` com `content IS NULL` pode representar binário, objeto + acima do limite ou hidratação ainda pendente. +- a implementação atual não reconcilia deleções e force-pushes. +- o listener pgwire usa autenticação cleartext e deve permanecer em rede + protegida. + +## Decisões que ainda precisam de ADR + +- identidade estável do repositório: path, remote URL ou UUID; +- retenção de histórico após refs deixarem de alcançar commits; +- atomicidade por commit versus por repositório; +- versionamento e invalidação dos caches search/UAST; +- exposição do pgwire como gateway administrativo ou somente leitura. + ## Variáveis de ambiente mais usadas - `DATABASE_URL` @@ -104,3 +155,11 @@ Consultas SQL / pgwire - `GITBASE_BIND_ADDR` - `GITBASE_PG_USER` - `GITBASE_PG_PASSWORD` + +## Estado de maturidade + +O projeto implementa um pipeline funcional e possui testes unitários, integração +com PostgreSQL e um cenário E2E em containers. Antes de produção multiusuário, +as prioridades são consistência transacional, reconciliação, integridade +referencial, alinhamento do toolchain e endurecimento do pgwire. A ordem proposta +está no [roadmap](./roadmap.md). diff --git a/docs/architecture/data-pipelines.md b/docs/architecture/data-pipelines.md new file mode 100644 index 0000000..fdf740c --- /dev/null +++ b/docs/architecture/data-pipelines.md @@ -0,0 +1,172 @@ +# Pipelines, consistência e recuperação + +Esta página detalha o ciclo de vida dos dados desde o repositório Git até as +interfaces SQL. Os nomes das operações correspondem às funções e comandos atuais. + +## Pipeline completo + +```text +discover_repositories + │ + ▼ +collect_refs + collect_commits + │ + ▼ +repositories / refs / commits / trees / files + │ + ▼ +hydrate_missing_blobs ──▶ blobs.content + │ + ├──▶ index_search ──▶ code_index ──▶ search_code(...) + │ + └──▶ index_uast ────▶ uast_cache ──▶ functions / imports +``` + +Cada estágio é executado separadamente. Não existe um coordenador persistente de +jobs nem uma tabela de checkpoints do pipeline. + +## 1. Descoberta de repositórios + +`gitbase-git::discover_repositories` aceita um ou mais roots. + +1. Se o root for um working tree ou bare repo, ele é usado diretamente. +2. Caso contrário, `walkdir` procura diretórios `.git` e estruturas bare. +3. Symlinks não são seguidos. +4. O ID é calculado com SHA-1 do path textual. +5. O nome é o último componente do path. + +Consequência: dois paths diferentes para o mesmo remoto são entidades distintas, +e uma mudança de path não é reconhecida como rename. + +## 2. Sincronização de metadados + +`sync_repositories` processa os repositórios sequencialmente. + +```text +para cada repositório + upsert repository + coletar e upsert refs + caminhar commits alcançáveis a partir das refs + carregar hashes de commits já existentes + para cada commit novo + upsert commit e pais + upsert todas as tree_entries + upsert todos os files +``` + +### Idempotência + +- repositórios e refs usam chaves naturais compostas para `UPSERT`; +- commits já existentes são ignorados por completo; +- repetir um sync sem novos commits tende a gerar apenas upserts de repositório e + refs; +- dados parcialmente gravados para um commit já existente não são reparados por + uma repetição normal, pois o commit causa o `continue` do snapshot inteiro. + +### Consistência atual + +Cada statement usa uma conexão do pool e faz commit individual. Não há transação +por repositório. Uma interrupção pode deixar commit sem todos os pais, trees ou +files. Também não há fase de reconciliação para apagar refs removidas ou objetos +que ficaram inalcançáveis após rebase/force-push. + +## 3. Hidratação de blobs + +O sync armazena referências a hashes, mas não lê todo conteúdo imediatamente. +`hydrate_missing_blobs` seleciona hashes de arquivos sem `blobs.content` e chama +`hydrate_blobs`. + +Para cada hash: + +1. um cache com conteúdo é reutilizado e recebe novo `last_used_at`; +2. o banco informa em quais repositórios o hash aparece; +3. paths fora dos `repo_roots` permitidos são descartados; +4. o objeto é lido do primeiro repositório capaz de fornecê-lo; +5. binários e blobs acima do limite são registrados sem conteúdo; +6. texto aceito é persistido como `bytea`. + +O cache é global por SHA-1 do blob, portanto conteúdo idêntico entre repositórios +é armazenado uma vez. Não existe política automática de expiração ou garbage +collection, apesar de `last_used_at` permitir implementá-la. + +## 4. Índice de busca + +`fetch_search_candidates` seleciona blobs textuais hidratados que ainda não estão +em `code_index`. O conteúdo UTF-8 não vazio vira um `tsvector` com configuração +`simple`. + +A linguagem é obtida primeiro de `files.language`; quando ela está ausente, há +fallback por extensão apenas para Go e Rust usando o detector de UAST. Assim, o +filtro `lang` não cobre as demais linguagens presentes nos repositórios. + +`gitbase.search_code(pattern, lang)`: + +- transforma o padrão com `websearch_to_tsquery('simple', ...)`; +- filtra por linguagem somente quando `lang` é informado; +- calcula score com `ts_rank_cd`; +- faz join com todas as ocorrências do blob em `files`. + +Por isso, o mesmo blob pode gerar várias linhas quando aparece em vários commits. + +## 5. UAST e projeções + +Os candidatos são blobs hidratados associados a algum path. O path determina a +linguagem: + +- `.go` → Go; +- `.rs` → Rust; +- outras extensões → não suportadas. + +O tree-sitter produz um documento compacto com funções e imports, armazenado em +`uast_cache`. As tabelas `uast_functions` e `uast_imports` facilitam consultas +relacionais; as views acrescentam repositório, commit e path via `files`. + +O cache é identificado somente pelo hash do blob. Alterações na versão do parser +ou no formato da projeção não invalidam automaticamente documentos antigos. + +## 6. Consulta pgwire e hidratação sob demanda + +O handler classifica uma consulta como leitura somente quando o texto, após +trim, começa com `SELECT`. + +- `SELECT`: procura literais de 40 caracteres próximos a `blob_hash`, hidrata até + 50 hashes, executa a consulta e materializa todas as linhas antes da resposta; +- demais consultas: executa o SQL e retorna uma tag `OK` com linhas afetadas. + +A extração de hashes é lexical, não usa parser SQL. CTEs iniciadas com `WITH`, +prepared statements e protocolo estendido não têm tratamento especializado. + +## Matriz de reexecução + +| Estágio | Seguro repetir | Unidade incremental | Reparo de dados parciais | +| --- | --- | --- | --- | +| `health` | sim | migration | SQLx controla versões | +| `sync` | parcial | commit novo | não para commit já existente | +| `hydrate-blobs` | sim | blob sem conteúdo | sim, se a origem estiver acessível | +| `search-index` | sim | blob sem índice | exige truncar para reindexar conteúdo existente | +| `uast` | sim | blob sem cache | exige truncar para nova versão do parser | + +## Falhas e recuperação + +| Falha | Estado provável | Recuperação atual | +| --- | --- | --- | +| repositório ilegível | sync interrompido | corrigir permissão/path e repetir | +| PostgreSQL indisponível | comando falha | restaurar conexão e repetir | +| interrupção durante sync | metadados parciais possíveis | inspeção manual; commit existente pode exigir limpeza | +| blob ausente no objeto Git | contador `missing` | restaurar objetos/fetch e repetir hidratação | +| conteúdo acima do limite | blob sem conteúdo | aumentar limite e repetir após revisar cache | +| parser UAST falha | comando interrompido | corrigir parser/conteúdo e reindexar | +| índice desatualizado | resultado antigo | truncar índice/cache e executar novamente | + +## Métricas recomendadas + +Até existir telemetria nativa, estas métricas podem ser derivadas do banco: + +- duração e exit code de cada comando; +- commits novos por sync; +- razão entre blobs hidratados e hashes distintos em `files`; +- razão entre `code_index` e blobs textuais hidratados; +- cobertura UAST por linguagem; +- idade de `cached_at`, `last_used_at` e `indexed_at`; +- refs do banco que não existem mais no repositório de origem; +- commits sem files/tree entries como indicador de carga parcial. diff --git a/docs/architecture/quality-attributes.md b/docs/architecture/quality-attributes.md new file mode 100644 index 0000000..c5f6d1b --- /dev/null +++ b/docs/architecture/quality-attributes.md @@ -0,0 +1,152 @@ +# Atributos de qualidade e riscos + +Este documento registra como a implementação atual atende requisitos não +funcionais e quais controles precisam evoluir antes de uso em produção. + +## Resumo executivo + +| Atributo | Estado atual | Risco principal | Próximo controle | +| --- | --- | --- | --- | +| Consistência | eventual entre estágios | sync parcial e dados obsoletos | transação + reconciliação | +| Disponibilidade | comandos reiniciáveis | dependência de filesystem e PostgreSQL | checkpoints e retries classificados | +| Segurança | credencial pgwire simples | cleartext e SQL amplo | TLS + privilégio mínimo + autorização | +| Performance | deduplicação por blob e índices GIN | histórico completo por commit | escopo por refs e processamento concorrente | +| Observabilidade | logs estruturados e relatórios de CI | sem métricas/traces | métricas por estágio e tabela de runs | +| Portabilidade | Rust + PostgreSQL + Docker | toolchain declarado divergente | pin único e verificação de MSRV | +| Testabilidade | unitários, integração DB e E2E | cenários destrutivos ausentes | testes de force-push, falha parcial e upgrade | + +## Consistência e integridade + +### Garantias existentes + +- chaves primárias evitam duplicidade das entidades principais; +- upserts tornam os caminhos felizes repetíveis; +- blobs e índices semânticos são deduplicados por hash; +- migrations são aplicadas antes de cada operação; +- o teste de containers valida o pipeline completo contra um repositório real. + +### Riscos + +- ausência de foreign keys permite referências órfãs; +- sync não é atômico por repositório; +- remoções no Git não são propagadas; +- caches não carregam versão do algoritmo/parser; +- commits existentes impedem reparo automático de suas projeções. + +### Meta proposta + +Uma execução deve produzir um snapshot internamente consistente ou não publicar +nenhuma alteração para aquele repositório. A reconciliação deve distinguir +histórico preservado de objetos inalcançáveis que podem ser removidos. + +## Segurança + +### Dados processados + +Código-fonte pode conter segredos, dados pessoais e propriedade intelectual. O +banco replica conteúdo textual de blobs e amplia sua superfície de acesso. + +### Controles existentes + +- limite de tamanho para hidratação; +- binários não são persistidos como conteúdo; +- roots permitidos restringem a origem de blobs; +- usuário e senha pgwire são configuráveis; +- o workflow usa somente permissão `contents: read`. + +### Controles ausentes + +- TLS nativo no listener pgwire; +- hash/armazenamento seguro da senha do gateway; +- autorização por repositório, schema ou tipo de statement; +- redaction explícita de SQL e paths nos logs; +- secret scanning antes de persistir conteúdo; +- política de retenção e exclusão verificável. + +O gateway não deve ser exposto à internet no estado atual. Em produção, use rede +privada, backend PostgreSQL com privilégios mínimos e proteção de transporte na +frente do listener. + +## Performance e capacidade + +### Características atuais + +- o tree walk é realizado para cada commit novo; +- files e tree entries são armazenados por commit; +- processamento de repositórios e blobs é sequencial; +- pgwire usa `fetch_all`, mantendo o resultado completo em memória; +- GIN acelera full-text search e trigrams aceleram paths; +- deduplicação de conteúdo reduz armazenamento quando blobs se repetem. + +### Variáveis de capacidade + +| Variável | Impacto | +| --- | --- | +| commits alcançáveis | tempo de sync e linhas em files/tree entries | +| arquivos por commit | maior multiplicador de armazenamento | +| blobs únicos | hidratação, busca e cache UAST | +| tamanho máximo do blob | memória, I/O e tamanho do banco | +| conexões do pool | concorrência com PostgreSQL | +| cardinalidade da busca | memória do processo pgwire | + +Antes de definir SLOs, deve-se criar um benchmark com repositórios pequeno, +médio e grande, registrando tempo, CPU, RSS, I/O e crescimento das tabelas. + +## Disponibilidade e recuperação + +O GitDatabase não mantém estado de execução fora das tabelas de domínio. A +recuperação é baseada em repetir comandos e, em alguns casos, truncar caches. + +Requisitos recomendados: + +- backup consistente do PostgreSQL antes de migrations destrutivas; +- retenção independente dos repositórios Git de origem; +- readiness que verifique migrations e acesso aos roots; +- timeout e cancelamento gracioso por estágio; +- registro persistente de runs, duração, contadores e erro final; +- runbook de restore testado periodicamente. + +## Observabilidade + +`tracing` fornece eventos de conexão, migration e totais por comando. Ainda +faltam correlação e métricas operacionais. + +Modelo mínimo proposto para uma run: + +- `run_id`, comando, início, fim e status; +- repositório e ref alvo; +- contadores lidos, inseridos, atualizados, removidos e ignorados; +- erro classificado e retryable; +- versão do binário, schema, parser e configuração efetiva; +- duração de descoberta, leitura Git, banco e indexação. + +## Compatibilidade e upgrades + +- o package declara MSRV 1.80, mas o lock atual exige Rust 1.89; +- migrations são somente forward e não há procedimento de downgrade; +- caches UAST/search não registram versão do gerador; +- mudanças em `search_vector` ou parsers exigem reindexação manual. + +Uma release deve publicar matriz de compatibilidade com Rust, PostgreSQL e schema, +além de marcar quando um upgrade exige rebuild de cache. + +## Estratégia de testes alvo + +| Camada | Cobertura atual | Cobertura a adicionar | +| --- | --- | --- | +| unidade | UAST Go/Rust | detecção de linguagem, parser SQL/hashes | +| integração | sync, blobs, search, UAST | rollback, reconciliação, foreign keys | +| container E2E | clone real e nove asserts SQL | UAST, rerun idempotente e falha controlada | +| compatibilidade | CI em stable | MSRV real, PostgreSQL suportado e upgrades | +| segurança | CodeQL | auth/TLS, SQL authorization e secret handling | + +## Critérios para produção + +O projeto deve ser considerado pronto para produção somente depois de: + +1. corrigir consistência transacional e reconciliação; +2. alinhar toolchain e automatizar upgrade de schema/cache; +3. adicionar TLS e política de autorização ou remover exposição direta do pgwire; +4. publicar métricas, health/readiness e limites de recursos; +5. validar backup/restore e exclusão de dados; +6. medir capacidade com datasets representativos. diff --git a/docs/architecture/system-context.md b/docs/architecture/system-context.md new file mode 100644 index 0000000..f40a6b3 --- /dev/null +++ b/docs/architecture/system-context.md @@ -0,0 +1,157 @@ +# Contexto e componentes do sistema + +Este documento descreve as fronteiras do GitDatabase, os processos executáveis e +as dependências entre os crates. Ele representa o código disponível no branch +principal e não pressupõe serviços que ainda estejam no roadmap. + +## Objetivo arquitetural + +O GitDatabase transforma objetos Git locais em um modelo relacional consultável. +O PostgreSQL é, ao mesmo tempo, armazenamento persistente, mecanismo de busca +textual e backend das consultas expostas por pgwire. + +O sistema foi desenhado para estes casos de uso: + +- inventariar repositórios, refs, commits, árvores e arquivos; +- consultar histórico e conteúdo com SQL; +- compartilhar conteúdo idêntico por `blob_hash`; +- buscar termos em blobs textuais; +- projetar funções e imports de Go e Rust; +- permitir acesso por clientes compatíveis com o protocolo PostgreSQL. + +Não fazem parte da implementação atual: hospedar repositórios Git, clonar ou +atualizar remotos automaticamente, executar código indexado, oferecer uma API +HTTP ou substituir o PostgreSQL como fonte de consulta. + +## Visão de contexto + +```text +┌──────────────────────┐ filesystem ┌──────────────────────┐ +│ Repositórios Git │ ─────────────────────▶ │ GitDatabase │ +│ working tree / bare │ │ CLI + loaders │ +└──────────────────────┘ └──────────┬───────────┘ + │ SQL/sqlx + ▼ +┌──────────────────────┐ pgwire/SQL ┌──────────────────────┐ +│ Clientes SQL │ ◀────────────────────── │ PostgreSQL │ +│ psql, BI, scripts │ via GitDatabase │ schema gitbase │ +└──────────────────────┘ ou acesso direto └──────────────────────┘ +``` + +### Atores e responsabilidades + +| Ator | Fornece | Consome | +| --- | --- | --- | +| Operador | paths, credenciais e limites de processamento | logs, exit code e relatórios | +| Repositório Git | refs, commits, trees e blobs | operações de leitura local | +| PostgreSQL | persistência, migrations, índices e execução SQL | conexões autenticadas | +| Cliente SQL | consultas e credenciais pgwire | linhas e tags de execução | +| CI | checkout, Docker e rede para o repositório de teste | relatório Markdown e status | + +## Visão de containers de runtime + +O termo *container* nesta seção representa uma unidade executável, não +necessariamente um container Docker. + +### CLI `gitbase` + +Processo batch que seleciona um dos comandos `health`, `sync`, `hydrate-blobs`, +`search-index` ou `uast`. Cada execução cria um pool `sqlx`, aplica migrations e +encerra ao concluir. O comando `serve` mantém um listener pgwire ativo. + +### PostgreSQL + +Componente stateful. As migrations são compiladas no binário por +`sqlx::migrate!` e executadas durante toda conexão criada por `gitbase-db`. Os +objetos de domínio ficam no schema `gitbase`; o controle de migrations do SQLx +fica na tabela `_sqlx_migrations`. + +### Filesystem Git + +Fonte de verdade dos objetos Git. O banco guarda o path absoluto descoberto e a +hidratação posterior depende de esse path continuar acessível. Mover ou apagar o +repositório pode impedir a leitura de blobs ainda não hidratados. + +### Gateway pgwire + +Listener TCP que implementa autenticação por senha em texto claro no protocolo e +o protocolo de consulta simples. As consultas são encaminhadas ao PostgreSQL. +Antes de um `SELECT`, hashes literais associados a `blob_hash` podem disparar +hidratação sob demanda, limitada a 50 hashes por consulta. + +## Componentes Rust + +| Crate | Responsabilidade | Dependências internas | +| --- | --- | --- | +| `gitbase-cli` | parsing de argumentos, configuração e orquestração | db, loader, pgwire | +| `gitbase-git` | descoberta e leitura de objetos Git com `gix` | nenhuma | +| `gitbase-db` | conexão, migrations e operações SQL | nenhuma | +| `gitbase-loader` | coordenação dos pipelines de ingestão e índices | git, db, uast | +| `gitbase-uast` | detecção Go/Rust e projeções tree-sitter | nenhuma | +| `gitbase-pgwire` | autenticação, protocolo simples e proxy SQL | loader, db | + +```text +gitbase-cli +├── gitbase-loader +│ ├── gitbase-git +│ ├── gitbase-db +│ └── gitbase-uast +├── gitbase-db +└── gitbase-pgwire + ├── gitbase-loader + └── gitbase-db +``` + +## Modos de execução + +### Batch explícito + +É o modo recomendado para cargas previsíveis. O operador executa cada estágio e +controla limites por comando. Uma falha retorna exit code diferente de zero e o +estágio pode ser repetido porque as escritas usam `UPSERT` ou verificam o cache. + +### Serviço pgwire + +É adequado para clientes SQL que não acessam diretamente o PostgreSQL. O gateway +não isola o banco: consultas que não começam com `SELECT` são executadas com as +permissões da `DATABASE_URL`, inclusive DDL e DML. + +### Integração em containers + +O Compose de integração cria PostgreSQL efêmero e um executor contendo a CLI, +`git` e `psql`. O executor clona o repositório de referência, percorre todo o +pipeline e produz um relatório que a GitHub Action envia ao Job Summary. + +## Fronteiras de confiança + +1. **Operador → CLI:** paths e URLs devem ser considerados entrada não confiável. +2. **Repositório → parsers:** conteúdo de blobs não é confiável; há limite de + tamanho, classificação binária e validação UTF-8 antes dos índices. +3. **Cliente → pgwire:** SQL é encaminhado ao banco sem política de autorização + por comando. A credencial do backend deve aplicar privilégio mínimo. +4. **GitDatabase → PostgreSQL:** a conexão deve permanecer em rede privada e com + TLS quando atravessar uma fronteira de host. + +## Topologias suportadas + +| Topologia | Uso | Observações | +| --- | --- | --- | +| CLI e PostgreSQL locais | desenvolvimento | compose atual publica PostgreSQL em `5433` | +| CLI em job + PostgreSQL gerenciado | cargas agendadas | repositórios precisam estar montados no job | +| pgwire + PostgreSQL na mesma rede | consultas compartilhadas | não expor pgwire sem proteção de transporte | +| Compose efêmero de integração | CI | banco usa `tmpfs` e é descartado ao final | + +## Restrições técnicas atuais + +- o ID do repositório é SHA-1 do path; mover o diretório muda sua identidade; +- a sincronização não remove refs ou commits que deixaram de ser alcançáveis; +- não há transação envolvendo todo o sync de um repositório; +- as tabelas de metadados não possuem foreign keys; +- `files.language`, `files.size` e a classificação binária inicial não são + preenchidos a partir do tree walk; +- UAST suporta somente Go e Rust; +- pgwire implementa apenas simple query e materializa todas as linhas em memória; +- o toolchain declarado como Rust 1.80 diverge do `Cargo.lock`, que atualmente + contém dependências que exigem Rust 1.89. + +As correções propostas estão organizadas no [plano de funcionalidades](../roadmap.md). diff --git a/docs/database.md b/docs/database.md index 8a2bde6..ca93cf6 100644 --- a/docs/database.md +++ b/docs/database.md @@ -32,6 +32,40 @@ Esta página descreve o modelo de dados criado pelas migrations atuais. - `gitbase.uast_functions` - `gitbase.uast_imports` +## Relacionamentos lógicos + +```text +repositories +├── refs +├── commits +│ ├── commit_parents +│ ├── tree_entries +│ └── files ───────────────┐ +└────────────────────────────┤ + ▼ + blobs + ├── code_index + └── uast_cache + ├── uast_functions + └── uast_imports +``` + +Esses relacionamentos são aplicados pelos joins e chaves primárias, mas as +migrations atuais não definem foreign keys. Assim, o banco não impede órfãos se +um operador executar DML manual ou se um pipeline for interrompido. + +## Granularidade e identidade + +| Entidade | Chave | Granularidade | +| --- | --- | --- | +| repository | `id` | path descoberto convertido em SHA-1 | +| ref | `repository_id, name` | ref local/remota/tag por repositório | +| commit | `repository_id, hash` | commit alcançável por alguma ref | +| file | `repository_id, commit_hash, path` | ocorrência do path em um commit | +| blob | `hash` | conteúdo Git global e deduplicado | +| code index | `blob_hash` | documento textual por conteúdo | +| UAST | `blob_hash` | documento semântico por conteúdo | + ## Índices relevantes - `files_path_trgm_idx` (GIN trigram em `files.path`) @@ -63,6 +97,52 @@ Implementação usa `websearch_to_tsquery('simple', pattern)` e `ts_rank_cd(...) As views fazem join entre projeções UAST e `files` por `blob_hash` para expor contexto de repositório/commit/path. +Como um blob pode ocorrer em muitos commits, uma função ou import pode aparecer +repetidamente nas views. Filtre por ref/commit ou use `DISTINCT` conforme o caso. + +## Ciclo de vida dos dados + +| Evento | Efeito atual | +| --- | --- | +| commit novo | novas linhas de commit, tree e file | +| ref movida | target da ref é atualizado | +| ref apagada | linha antiga permanece | +| force-push | novos commits entram; antigos permanecem | +| repo movido | novo ID baseado no path; registro anterior permanece | +| blob repetido | conteúdo e índices são reutilizados pelo hash | +| parser alterado | cache UAST não é invalidado automaticamente | + +## Consistência a verificar + +```sql +-- Commits sem arquivos e sem tree entries podem indicar carga parcial. +SELECT c.repository_id, c.hash +FROM gitbase.commits c +LEFT JOIN gitbase.files f + ON f.repository_id = c.repository_id AND f.commit_hash = c.hash +LEFT JOIN gitbase.tree_entries t + ON t.repository_id = c.repository_id AND t.commit_hash = c.hash +GROUP BY c.repository_id, c.hash +HAVING COUNT(f.path) = 0 AND COUNT(t.path) = 0; +``` + +```sql +-- Arquivos cujo repositório não existe. +SELECT COUNT(*) AS orphan_files +FROM gitbase.files f +LEFT JOIN gitbase.repositories r ON r.id = f.repository_id +WHERE r.id IS NULL; +``` + +```sql +-- Cobertura do conteúdo por hash distinto, sem multiplicação por commit. +SELECT + COUNT(DISTINCT f.blob_hash) AS referenced, + COUNT(DISTINCT f.blob_hash) FILTER (WHERE b.content IS NOT NULL) AS hydrated +FROM gitbase.files f +LEFT JOIN gitbase.blobs b ON b.hash = f.blob_hash; +``` + ## Consultas úteis ### 1) Quantidade de repositórios sincronizados @@ -113,3 +193,13 @@ LIMIT 100; - `files` é versionada por commit (mesmo path pode aparecer várias vezes) - `code_index` indexa por `blob_hash` (um blob pode estar em múltiplos commits) - UAST depende de blob textual hidratado e linguagem suportada +- o filtro `lang` usa `code_index.language`; atualmente a inferência automática + cobre apenas extensões Go e Rust quando `files.language` está vazio +- não remova rows de `repositories` isoladamente sem avaliar projeções órfãs +- alterações no algoritmo de busca ou parser exigem rebuild manual dos caches + +## Evolução planejada + +O [plano de funcionalidades](./roadmap.md) propõe foreign keys, reconciliação, +garbage collection, versionamento de cache e uma API de busca orientada a +snapshot. diff --git a/docs/index.md b/docs/index.md index a97ddcd..4b4399f 100644 --- a/docs/index.md +++ b/docs/index.md @@ -26,6 +26,18 @@ O fluxo principal do sistema é: ## Navegação da documentação - [Arquitetura](./architecture.md): componentes, fluxo e responsabilidades dos crates +- [Contexto e componentes](./architecture/system-context.md): fronteiras e topologias +- [Pipelines](./architecture/data-pipelines.md): consistência, idempotência e recuperação +- [Atributos de qualidade](./architecture/quality-attributes.md): riscos e prontidão para produção - [Banco de dados](./database.md): tabelas, índices, função de busca e views - [Pilot](./pilot.md): execução ponta a ponta para validação rápida - [Runbook](./runbook.md): operação diária, manutenção e troubleshooting +- [Roadmap](./roadmap.md): funcionalidades ausentes priorizadas +- [Changelog](https://github.com/DevComputaria/gitdatabase/blob/main/CHANGELOG.md): evolução por commit + +## Estado atual + +O núcleo de ingestão, hidratação, busca, UAST Go/Rust e gateway pgwire está +implementado. O projeto possui validação E2E em containers, mas ainda requer +trabalho de consistência, reconciliação, segurança e observabilidade antes de uma +operação multiusuário em produção. Consulte o [roadmap](./roadmap.md). diff --git a/docs/pilot.md b/docs/pilot.md index 169d947..99a5b20 100644 --- a/docs/pilot.md +++ b/docs/pilot.md @@ -5,7 +5,7 @@ Este guia mostra um fluxo de validação ponta a ponta do GitDatabase com os com ## Pré-requisitos - PostgreSQL 16+ -- Rust 1.80+ +- Rust 1.89 para o `Cargo.lock` atual - Repositórios Git para indexar > O `pg_trgm` é habilitado automaticamente pelas migrations executadas na conexão. @@ -76,6 +76,27 @@ SELECT COUNT(*) FROM gitbase.blobs WHERE content IS NOT NULL; SELECT COUNT(*) FROM gitbase.code_index; ``` +## Validação automatizada em containers + +O cenário mantido pela CI clona `DevComputaria/DevComputaria.Prompting`, executa +o pipeline e aplica asserções SQL: + +```bash +mkdir -p test-results +docker compose -f docker/docker-compose.integration-test.yml up \ + --build \ + --abort-on-container-exit \ + --exit-code-from integration-test \ + integration-test +``` + +O relatório fica em `test-results/container-integration-test.md`. Finalize com: + +```bash +docker compose -f docker/docker-compose.integration-test.yml down \ + --volumes --remove-orphans +``` + ## Observações importantes - `sync` é incremental para commits já conhecidos. @@ -85,3 +106,6 @@ SELECT COUNT(*) FROM gitbase.code_index; - `--limit` em `search-index` - `--limit` em `uast` - `--limit` em `hydrate-blobs` +- O requisito Rust 1.89 reflete as dependências travadas atuais, apesar de o + manifest e o Dockerfile principal ainda declararem 1.80; o alinhamento está + planejado como GD-001. diff --git a/docs/roadmap.md b/docs/roadmap.md new file mode 100644 index 0000000..c56d7ab --- /dev/null +++ b/docs/roadmap.md @@ -0,0 +1,268 @@ +# Plano de funcionalidades ausentes + +Este plano foi derivado da implementação atual, das migrations, dos testes e dos +workflows. Ele prioriza correção de dados antes de expansão funcional. + +## Princípios de priorização + +- **P0:** impede corrupção, operação previsível ou build reproduzível; +- **P1:** completa o ciclo operacional esperado por uma plataforma de indexação; +- **P2:** amplia escala, protocolos e análise semântica; +- cada item deve entregar migration, código, testes, métricas e documentação; +- mudanças de schema ou cache precisam de estratégia de upgrade e rollback. + +## Sequência recomendada + +```text +P0.1 Toolchain reproduzível + │ + ├──▶ P0.2 Classificação de arquivos + │ + └──▶ P0.3 Sync transacional e reparável + │ + └──▶ P0.4 Reconciliação + integridade referencial + │ + └──▶ P1.1 Gestão de remotos e jobs + │ + ├──▶ P1.2 Observabilidade + └──▶ P1.3 Busca aprimorada +``` + +## P0 — Fundação de correção + +### GD-001 — Alinhar toolchain e build de produção + +**Problema:** `rust-version` e o Dockerfile principal usam Rust 1.80, enquanto o +`Cargo.lock` contém crates que exigem Rust 1.89. + +**Escopo:** + +- definir uma única versão mínima suportada; +- atualizar `Cargo.toml`, Dockerfile, CI e documentação; +- usar `cargo build --locked` em imagens; +- adicionar job que compile explicitamente na MSRV; +- documentar política de atualização do lockfile. + +**Critérios de aceite:** + +- build local, CI e imagem usam a mesma versão mínima; +- `cargo test --workspace --locked` passa na MSRV; +- dependência que elevar MSRV falha de forma explícita na CI. + +**Tamanho:** pequeno. **Dependências:** nenhuma. + +### GD-002 — Classificação de arquivo e linguagem + +**Problema:** o tree walk grava `language = NULL`, `size = NULL` e +`is_binary = false`. O índice só infere Go/Rust, tornando o filtro `lang` +incompleto. + +**Escopo:** + +- detector central baseado em extensão e nomes conhecidos; +- preencher linguagem e tamanho no sync quando disponíveis; +- consolidar a classificação binária após hidratação; +- suportar inicialmente C#, JavaScript/TypeScript, Python, Java, Go e Rust; +- backfill versionado para linhas existentes. + +**Critérios de aceite:** + +- fixtures por linguagem alimentam `files.language` e `code_index.language`; +- `search_code(pattern, lang)` retorna somente a linguagem solicitada; +- linguagens desconhecidas continuam válidas com `NULL`; +- relatório de sync apresenta contagem por classificação. + +**Tamanho:** médio. **Dependências:** GD-001. + +### GD-003 — Sync transacional, reparável e auditável + +**Problema:** statements são confirmados individualmente e commits existentes +pulam a reconstrução de files/tree entries. + +**Escopo:** + +- transação por repositório; +- staging ou marca de run antes da publicação; +- modo `--repair` para recalcular projeções de commits existentes; +- tabela de runs com status, versão e contadores; +- erro contextualizado por repositório/commit/path. + +**Critérios de aceite:** + +- falha injetada no meio de um commit não deixa projeções parciais visíveis; +- `--repair` restaura dados removidos intencionalmente em teste; +- duas execuções sem mudança são idempotentes; +- run final registra duração, totais e erro. + +**Tamanho:** grande. **Dependências:** GD-001. + +### GD-004 — Reconciliação e integridade referencial + +**Problema:** refs apagadas, force-pushes e repositórios removidos não são +refletidos no banco; não há foreign keys. + +**Escopo:** + +- reconciliar o conjunto atual de refs; +- definir política `preserve-history` versus `prune-unreachable`; +- adicionar foreign keys compostas e cascades revisadas; +- garbage collection de blobs, search e UAST sem referências; +- comando `doctor` para detectar órfãos e divergências. + +**Critérios de aceite:** + +- teste com branch removida elimina ou preserva dados conforme a política; +- teste com force-push não mantém ref apontando para hash antigo; +- migrations validam dados existentes antes de criar constraints; +- `doctor` retorna exit code não zero para inconsistências. + +**Tamanho:** grande. **Dependências:** GD-003. + +## P1 — Operação como plataforma + +### GD-005 — Cadastro e atualização de repositórios remotos + +**Problema:** a CLI aceita apenas roots locais; clone/fetch hoje depende de +automação externa. + +**Escopo:** + +- comandos `repo add`, `repo list`, `repo sync` e `repo remove`; +- URL, branch/refspec, diretório gerenciado e estado do último fetch; +- autenticação por mecanismo externo seguro, sem persistir tokens no banco; +- clone bare e fetch incremental; +- allowlist de hosts e limites de tamanho/tempo. + +**Critérios de aceite:** + +- um remoto público pode ser cadastrado, clonado, atualizado e indexado; +- credenciais não aparecem em logs, URLs persistidas ou relatórios; +- falhas de rede são classificadas e permitem retry; +- remoção respeita a política de retenção do GD-004. + +**Tamanho:** grande. **Dependências:** GD-004. + +### GD-006 — Agendamento, fila e concorrência controlada + +**Problema:** não há coordenador de jobs ou exclusão mútua por repositório. + +**Escopo:** + +- fila persistente de sync/hydrate/search/UAST; +- lease por repositório com timeout; +- retries exponenciais para falhas transitórias; +- limites globais e por estágio; +- cancelamento gracioso e retomada. + +**Critérios de aceite:** + +- dois workers não publicam simultaneamente o mesmo repositório; +- job interrompido expira e pode ser retomado; +- retries não repetem falhas permanentes indefinidamente; +- backlog e duração ficam observáveis. + +**Tamanho:** grande. **Dependências:** GD-003, GD-005. + +### GD-007 — Observabilidade operacional + +**Problema:** existem logs e contadores finais, mas não métricas, traces ou +histórico persistente de execução. + +**Escopo:** + +- `run_id` em todos os logs; +- métricas de duração, throughput, skips, erros e backlog; +- endpoints separados de liveness/readiness quando em modo serviço; +- dashboard e alertas de referência; +- queries de cobertura publicadas no runbook. + +**Critérios de aceite:** + +- uma falha pode ser correlacionada do job ao repositório e commit; +- readiness falha quando banco, migration ou roots obrigatórios falham; +- alertas cobrem falha repetida, backlog e queda de cobertura. + +**Tamanho:** médio. **Dependências:** GD-003; integra com GD-006. + +### GD-008 — Busca por snapshot e resultados não duplicados + +**Problema:** `search_code` pode retornar o mesmo blob para muitos commits e não +oferece filtro direto por repositório/ref/path. + +**Escopo:** + +- API SQL versionada com filtros por repositório, ref, commit e path; +- modo `latest` baseado no commit alvo da ref; +- destaque de trechos e linha aproximada; +- paginação estável; +- plano de compatibilidade para a função atual. + +**Critérios de aceite:** + +- busca em `latest` retorna uma ocorrência por path do snapshot; +- filtros combinados usam índices verificados por `EXPLAIN`; +- paginação não perde nem duplica resultados; +- benchmark define limite de latência para corpus de referência. + +**Tamanho:** grande. **Dependências:** GD-002, GD-004. + +## P2 — Expansão semântica e protocolo + +### GD-009 — UAST versionada e multilíngue + +- versionar parser/schema no cache e invalidar somente dados incompatíveis; +- adicionar C#, TypeScript/JavaScript e Python; +- projetar tipos, chamadas e dependências além de funções/imports; +- criar fixtures reais e métricas de erro por linguagem. + +**Aceite resumido:** rebuild seletivo por versão, três novas linguagens e +compatibilidade documentada. **Tamanho:** grande. **Dependências:** GD-002. + +### GD-010 — Endurecimento do pgwire + +- TLS e autenticação sem senha cleartext; +- autorização read-only por padrão; +- protocolo estendido/prepared statements; +- streaming de linhas com backpressure; +- parser SQL para classificação e hidratação sob demanda. + +**Aceite resumido:** clientes comuns conectam com TLS, usuário read-only não +executa DDL/DML e consultas grandes não são materializadas integralmente. +**Tamanho:** grande. **Dependências:** GD-007. + +### GD-011 — Retenção, privacidade e exclusão + +- políticas por repositório para conteúdo, histórico e caches; +- detecção opcional de segredos antes da hidratação; +- exclusão verificável e relatório de impacto; +- auditoria de acesso a conteúdo. + +**Aceite resumido:** remoção elimina todas as projeções cobertas pela política e +gera evidência auditável sem revelar o conteúdo. **Tamanho:** grande. +**Dependências:** GD-004, GD-005. + +## Primeiro incremento recomendado + +O primeiro ciclo deve entregar GD-001 e GD-002, seguido do esqueleto de run do +GD-003. Esse corte elimina a divergência de build, torna a busca por linguagem +útil e cria a base observável para alterar a semântica de sincronização. + +### Entregáveis do ciclo + +1. toolchain 1.89 alinhada em código, container, CI e docs; +2. módulo compartilhado de detecção de linguagem; +3. migration de backfill de `files.language`; +4. testes E2E com filtro por `csharp` e `rust`; +5. tabela `index_runs` e `run_id` nos logs; +6. ADR definindo identidade de repositório e política de reconciliação. + +## Definição de pronto comum + +Uma funcionalidade do roadmap só está pronta quando: + +- migrations forward foram testadas com dados existentes; +- testes unitários, integração e container cobrem sucesso e falha; +- métricas e logs não expõem conteúdo ou credenciais; +- runbook contém implantação, rollback e troubleshooting; +- arquitetura e modelo de dados foram atualizados; +- impacto de compatibilidade e reindexação está explícito no changelog. diff --git a/docs/runbook.md b/docs/runbook.md index fc5cc03..07aa445 100644 --- a/docs/runbook.md +++ b/docs/runbook.md @@ -72,8 +72,44 @@ Para operação incremental diária: 3. `search-index --limit ...` 4. `uast --limit ...` (quando aplicável) +## Checklist antes de operar + +1. confirme a versão do binário e do schema; +2. valide espaço disponível no PostgreSQL; +3. garanta que os mesmos paths de repositório usados no sync estão montados para + a hidratação; +4. execute `health`; +5. registre contagens de baseline; +6. evite dois processos de sync sobre o mesmo repositório até existir lock + distribuído; +7. para manutenção destrutiva, faça backup e registre as tabelas afetadas. + +## Teste de integração em containers + +```bash +mkdir -p test-results +docker compose -f docker/docker-compose.integration-test.yml up \ + --build \ + --abort-on-container-exit \ + --exit-code-from integration-test \ + integration-test +``` + +O exit code do serviço `integration-test` define o resultado. O relatório contém +o commit clonado e as contagens observadas. Sempre encerre a infraestrutura: + +```bash +docker compose -f docker/docker-compose.integration-test.yml down \ + --volumes --remove-orphans +``` + ## Reindexação +!!! warning + Os comandos abaixo removem dados derivados. Faça backup quando o ambiente não + puder ser reconstruído imediatamente e evite executá-los enquanto indexadores + ou clientes pgwire estiverem ativos. + ### Recriar índice de busca ```sql @@ -132,6 +168,45 @@ GROUP BY language ORDER BY COUNT(*) DESC; ``` +### Detectar possível sync parcial + +```sql +SELECT c.repository_id, c.hash +FROM gitbase.commits c +LEFT JOIN gitbase.files f + ON f.repository_id = c.repository_id AND f.commit_hash = c.hash +LEFT JOIN gitbase.tree_entries t + ON t.repository_id = c.repository_id AND t.commit_hash = c.hash +GROUP BY c.repository_id, c.hash +HAVING COUNT(f.path) = 0 AND COUNT(t.path) = 0; +``` + +### Acompanhar idade dos caches + +```sql +SELECT + MIN(cached_at) AS oldest_cached, + MAX(cached_at) AS newest_cached, + MIN(last_used_at) AS oldest_use, + MAX(last_used_at) AS newest_use +FROM gitbase.blobs; +``` + +## Backup e restore + +O estado persistente está no PostgreSQL. Repositórios Git continuam necessários +para hidratar hashes ausentes. + +```bash +pg_dump --format=custom --schema=gitbase "$DATABASE_URL" \ + --file gitbase.dump +``` + +Restaure primeiro em um banco separado, execute `health` e compare contagens antes +de promover o banco. A tabela `_sqlx_migrations` está fora do schema `gitbase`; +para um backup completo da instância GitDatabase, inclua-a ou use dump do banco +inteiro. + ## Troubleshooting ### `search_code` retorna vazio @@ -156,3 +231,18 @@ ORDER BY COUNT(*) DESC; - Reduza escopo com `--limit` nos indexadores. - Ajuste `--max-connections` e conexão do PostgreSQL. - Execute cargas pesadas fora do horário de pico. + +### Dados antigos após branch removida ou force-push + +- Este é um limite conhecido: o sync atual atualiza refs existentes, mas não + remove refs ausentes nem commits inalcançáveis. +- Não apague commits manualmente sem considerar files, trees, parents e caches. +- Registre o caso e siga a política de retenção definida para o ambiente; a + reconciliação automática está planejada em GD-004. + +### Commit existe, mas files/tree entries estão incompletos + +- Uma repetição comum não reprocessa o snapshot de um commit já cadastrado. +- Restaure de backup ou remova cuidadosamente todas as projeções daquele commit + dentro de uma transação antes de repetir o sync. +- O modo de reparo está planejado em GD-003. diff --git a/mkdocs.yml b/mkdocs.yml index 16f89f1..63e0c89 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -25,7 +25,12 @@ markdown_extensions: nav: - Início: index.md - - Arquitetura: architecture.md + - Arquitetura: + - Visão geral: architecture.md + - Contexto e componentes: architecture/system-context.md + - Pipelines e consistência: architecture/data-pipelines.md + - Atributos de qualidade: architecture/quality-attributes.md - Banco de dados: database.md - Pilot: pilot.md - Runbook: runbook.md + - Roadmap: roadmap.md