AUR-495 — Dependência alterada no PR checada contra o OSV em qualquer ecossistema
Medido antes (pela leitura)
- Nenhum código lia dependências de um diff. A única menção a OSV era o
artefato de dados de análise (AUR-533,
internal/artifacts), que publica uma cópia OSV mas não tinha consumidor ("quando um consumidor a usar (AUR-495)",docs/configuration.md). - O registro de scanners (
internal/scanner) é feito para engines determinísticas sobre a árvore, sem acesso ao modelo; o card pede que o modelo extraia os pacotes e que o scanner seja só conferência. - O card cita
internal/analysisnos paths; a lógica nova ficou no pacote novointernal/dependencies(citado emdocs/architecture.md, exigência do teste estrutural), com o contribuidor eminternal/gatee a ligação emcmd/aurumcode, a pedido do coordenador do stream (reaproveitar a arquitetura de fontes e gate).
Decisão
internal/dependencies:extract.go: duas perguntas ao modelo (templates Markdown embutidos emprompts/): quais arquivos alterados são manifestos/lockfiles (só paths do diff são aceitos) e quais pacotes mudaram neles (ecossistema, nome, versões ou faixas, explicação,unresolved). Resposta em JSON validada.ground.go: aterra a resposta no diff (AC-008): manifesto dado ao modelo, nome presente no diff do arquivo, cada versão/faixa presente nas linhas alteradas do lado certo; o resto é descartado e declarado.conference.go:Extractorsobre todos os paths alterados; produçãoOSVScannerroda uma vezosv-scanner scan source --format json --all-packages --recursive <checkout>peloscanner.Command(ambiente mínimo,scanner.Timeout) e guarda os pacotes dos arquivos alterados. Arquivo reconhecido que o modelo não apontou entra nos manifestos e a omissão é declarada (o modelo nunca remove evidência determinística); versão nova que o scanner não lista é divergência declarada; pacote que o scanner extrai das linhas adicionadas e o modelo omitiu é inconclusivo (dependencies_extraction_gap). Binário ausente ou saída ilegível = inconclusivo (exit 128, "nenhum pacote", é vazio).osv.go: cliente da API OSV (POST /v1/query, paginação limitada, corpo limitado, advisories retirados ignorados). Severidade da fonte (database_specific.severity), versões corrigidas do pacote consultado, linkADVISORY/WEBou o registro da fonte. Frescor opcional peloDate+Ageda resposta (max_source_age_hours); semDatecom limite declarado = vencida.classify.go: os dois lados consultados (cache por execução); advisory só no head = introduzido, nos dois = pré-existente, só na base = corrigido; identidade por id ou alias. Faixa sem versão consulta o pacote inteiro. Qualquer falha descarta todos os achados e põe o motivo.internal/config/dependencies.go: seçãodependencies(ponteiro; nil = não declarada, nada muda), validada no parse e governada pela política central (governedSections). Declarada, o padrão degate.inconclusivepassa ablock(scannerEnabled).internal/gate/dependencies.go:DependenciesContributor, nono do pipeline; inconclusivo segueApplyInconclusiveMode; achados são informativos neste card (o gate é o AUR-527).cmd/aurumcode/dependency_check.go: roda no fechamento da evidência (joinEvidencede--basee--pr), depois da seleção do provedor, sobre o mesmo checkout e recusa dos scanners (scanRoot/scanBlocked). Seção declarada e verificação que não rodou =dependencies_not_run.Dockerfile: estágio que instalaosv-scannerv2.0.0 porgo install(verificado pelo checksum database do Go) e confere a versão.- Docs: seção nova em
docs/configuration.mdcom link emdocs/index.md; corrigida a frase velha da seçãoanalysis_dataque dizia que o AUR-495 consumiria a cópia OSV (a verificação usa a API ao vivo).
Como cada AC/MUT é provado
tests/acceptance/AUR-495.sh (pacotes internal/dependencies,
internal/gate, internal/config; base OSV = httptest servindo
internal/dependencies/testdata/osv-fake.json; modelo e scanner falsos):
- AC-001
TestAUR495AC001IntroducedAdvisory,TestAUR495AC001FindingLine(+ parse/governança da seção). - AC-002
TestAUR495AC002Preexisting. - AC-003
TestAUR495AC003Fixed. - AC-004
TestAUR495AC004UnknownFormatAndDivergence,TestAUR495AC004ScannerEvidenceKept(arquivo reconhecido e não apontado é lido; pacote omitido pelo modelo é inconclusivo). - AC-005
TestAUR495AC005Range. - AC-006
TestAUR495AC006SourceFailures(HTTP 503, scanner ausente,Datevelho, sem modelo, modelo falhando),TestAUR495AC006InconclusiveFollowsPolicy. - AC-007
TestAUR495AC007Monorepo. - AC-008
TestAUR495AC008InventedDependencyDiscarded. - MUT-001:
return nil, errda consulta virareturn nil, nil(falha lida como lista vazia): AC-006 fica vermelho. - MUT-002:
status = StatusPreexistingviraStatusIntroduced: AC-002 fica vermelho.
Riscos e fora do escopo
- Código escrito sem compilar (regra do stream); a prova roda no fluxo único.
- A severidade vem só da palavra da fonte; advisory sem ela é
unknowne o gate (AUR-527) a conta no topo (falha fechada). Cálculo CVSS próprio fora. - Os flags do
osv-scannerv2.0.0 (--all-packages,--recursive) e osource.pathabsoluto da saída JSON não foram executados aqui. - Arquivos fora dos
pathsdo card:internal/dependencies(pacote novo),internal/gate(contribuidor),docs/architecture.md(pacote e pipeline),docs/index.md(link da seção nova). - Os avisos de
cmd/aurumcode/dependency_check.gosão só em pt-BR, fora do catálogointernal/i18n. - Inconclusivos esperados em PRs reais (falha fechada, documentados em
docs/configuration.md): diff de manifestos acima de 256 KiB (dependencies_manifests_omitted) eosv-scanner --recursiveacima de 120 s num repositório grande (dependencies_scanner_failed).
Correções da revisão estática
- Saída do
osv-scanner: só 0 e 1 trazem relatório; 128 ("no packages found", códigos de retorno documentados do osv-scanner) é extração vazia; qualquer outro código, tempo esgotado ou processo morto édependencies_scanner_failed, mesmo com JSON (exitCode,TestScannerExitCodesAndRelativeRoot). - Raiz relativa (
--repo .):filepath.Absantes de casar os caminhos do relatório. - Quando o scanner lista o pacote, a versão e o ecossistema dele são os
consultados (
alignWithScanner,TestScannerVersionAndEcosystemWin). - Severidade pelo vetor CVSS v3 quando o banco não traz uma (
cvss.go, fórmula da especificação FIRST; v4 ficaunknown,TestCVSSSeverity). - Registros do mesmo advisory em bancos diferentes viram um
(
mergeAliases,TestAliasesMerged). dependencies.scannersó nome noPATHou caminho absoluto;osv_urledeps_dev_urlsóhttps(httpem loopback) (TestDependenciesSourcesAndScannerValidated).- Linhas do gate e avisos da revisão no catálogo
internal/i18n(pt-BR e en), detalhe do inconclusivo redigido (TestDependencyLinesFollowLanguage,TestDependencyNoticesRedactDetail). Dockerfile: o estágio do osv-scanner fixaGOPROXY,GOSUMDB,GOFLAGS=-mod=readonlyeGOTOOLCHAIN=local; a integridade é a do checksum database do Go sobre as fontes, em vez de um sha256 de binário de release.