From e5722193b3159681b91905c76ffb1f88a1858d40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?FabioLeit=C3=A3o?= Date: Fri, 3 Jul 2026 20:52:25 -0300 Subject: [PATCH 1/2] docs(adr): add ADR-0080 local validation gate inviolable (#1152) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Records the shared enforcement law: full check-all before any push/PR, economia de enforcement (no new always-on rules), and Registro ≠ Enforcement. Refs #1152 Co-authored-by: Cursor --- ...R-0080-local-validation-gate-inviolable.md | 51 +++++++++++++++++++ docs/adr/INVENTORY.txt | 5 +- docs/adr/README.md | 1 + 3 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 docs/adr/ADR-0080-local-validation-gate-inviolable.md diff --git a/docs/adr/ADR-0080-local-validation-gate-inviolable.md b/docs/adr/ADR-0080-local-validation-gate-inviolable.md new file mode 100644 index 00000000..c53e8f22 --- /dev/null +++ b/docs/adr/ADR-0080-local-validation-gate-inviolable.md @@ -0,0 +1,51 @@ +# ADR-0080 — O gate de validação LOCAL é INVIOLÁVEL: check-all completo (all-greens, zero regressões) antes de QUALQUER push ou PR + +- **Status:** Accepted +- **Date:** 2026-07-03 +- **Deciders:** Fabio Tavares Leitão (operador / owner do repositório) +- **Gate-Change-Approved-By:** Fabio Tavares Leitão + +## Contexto + +O tier de validação **LOCAL** — `pre-commit` + os testes anti-regressão completos (`pytest`, ~1600) + **Bandit** + **Zizmor** + **Semgrep** — foi construído ao longo de meses **exatamente para NÃO depender do round-trip do GitHub** (esperar minutos por erro remoto e refazer). As regras `check-all-gate.mdc` e `never-weaken-security-gates.mdc` sempre mandaram rodar isso local antes de push/PR. + +Em 2026-07-03 constatou-se: (a) não havia `pre-push` hook forçando o gate; (b) o executor pushou rodando apenas testes *targeted* (`2 passed`), não o suite completo; (c) um modelo chegou a **sugerir confiar no CI remoto**. E a tentativa de "reforçar" o mandato **degenerou em proliferar regras `alwaysApply: true`** — queimando contexto, **o oposto do objetivo.** Este ADR corrige as duas pontas: **rigor absoluto** no gate **e** **economia de contexto** no enforcement. + +## Decisão (absoluta, não-negociável) + +**Nenhum agente, modelo, ferramenta ou automação tem o direito de sequer SUSPEITAR que o `check-all` e todo o ritual de validações locais possa não rodar antes de QUALQUER push ou PR.** + +1. O código **NUNCA** sai desta máquina com a menor chance de qualquer coisa exceto **ALL GREENS** e **NO REGRESSIONS**. +2. O ritual local completo (`./scripts/check-all.sh --enforced`) **DEVE passar 100% verde LOCAL, ANTES** de todo push e de toda abertura/atualização de PR. *(Commit local intermediário = pre-commit + checks leves; o full check-all é antes de PUBLICAR no GitHub.)* +3. O que o GitHub CI faz **DEPOIS** é **IRRELEVANTE** para esta regra. CI é *backstop*, **NUNCA substituto**. **Confiar no CI em vez do gate local é PROIBIDO.** +4. **Sugerir, adiar, reduzir ou agir como se** o gate pudesse ser pulado = **VIOLAÇÃO desta ADR.** + +## Como é imposto — ENFORCEMENT (mecânico + econômico em contexto) + +São **duas peças, e só duas**: + +1. **TRAVA mecânica:** o pre-push hook **VERSIONADO** (`.githooks/pre-push` + `core.hooksPath`) roda `check-all.sh --enforced`; falhou → **push abortado**. + teste **tamper-evident** no CI-*required* (removeu o hook → CI falha → não merge). *(issue #1151)* +2. **UMA regra que JÁ é always-on:** `check-all-gate.mdc` (two-tier: commit-local leve / push-PR full). **Nada além dela.** + +### Economia de enforcement (parte da decisão — igual peso ao rigor) + +**É PROIBIDO criar regras `alwaysApply: true` novas para reafirmar este mandato.** Repetir a regra em N always-on **queima contexto sem adicionar enforcement.** A trava é o **hook**; a regra always-on é **uma só** (`check-all-gate.mdc`). Documentação **contextual/situacional** (globs, `@rule`, session-token) é permitida e encorajada; **always-on nova, não.** Novas always-on ferem `docs/ops/CURSOR_RULES_PHASE2_SITUATIONALIZATION.md` (economia de contexto) e são **anti-padrão**. + +## Registro ≠ Enforcement (não confundir — foi a raiz do incidente) + +- **Este ADR** = registro durável do **PORQUÊ** + governança. É **DOC** (`docs/adr/`), lido **on-demand** — **NÃO carrega em toda sessão, NÃO causa bloat.** +- **O enforcement** = **hook** (mecânico) + **1 regra** já-always-on. **O rigor vem do mecanismo, não de repetir a regra.** + +## Governança da mudança + +Mudar/remover/bypassar o gate exige trailer **`Gate-Change-Approved-By: `**. `git push --no-verify` só com aprovação **explícita e logada**. Violação → **Safe-Hold** + report ao operador. + +## Consequências + +- Pushes mais lentos localmente (1600 + scans). **ACEITÁVEL e INTENCIONAL** — custo de nunca entregar quebrado e nunca depender do round-trip remoto. +- Todo clone (main dev box — hoje a workstation Linux primária, pode voltar à primária Windows — + secondary) herda o gate no setup. +- Violação = falha de governança. + +## Autoridade + +Owner = **operador (Fabio Tavares Leitão)**. Claude = auditor read-only. Cursor = executor. Esta ADR **supera qualquer default de agente ou modelo.** diff --git a/docs/adr/INVENTORY.txt b/docs/adr/INVENTORY.txt index 649de294..04f5f3b0 100644 --- a/docs/adr/INVENTORY.txt +++ b/docs/adr/INVENTORY.txt @@ -1,5 +1,5 @@ # ADR Inventory - generated by scripts/inv-adr.ps1 -# GeneratedUtc: 2026-07-01T09:34:57Z +# GeneratedUtc: 2026-07-03T23:48:05Z # Algorithm: SHA256 # Format: NUMBER | STATUS | FILE_HASH | FILENAME | TITLE | RATIFIED_BY # RATIFIED_BY: - = N/A; PENDING = ratification line with signature PENDING; @op = stamped @@ -81,5 +81,6 @@ 0077 | Accepted | F8A4C9D3B2BE2BEE3721C5AE09476F9CD066DB0B58E6B3174D4B783B123A1BAF | ADR-0077-filesystem-scan-no-client-gitignore-by-design.md | Filesystem scan does not honor client `.gitignore` (deliberate design) | - 0078 | Proposed | 5FEF0DCAC3DA292E33519F24FE6387584C04A850771958FF78B19D3EEB856990 | ADR-0078-multi-pattern-regex-benchmark-gate-regexset-before-vectorscan.md | Multi-pattern regex acceleration gated by benchmark (RegexSet before Vectorscan) | - 0079 | Proposed | 158C68D90B9C6934F0FAAC392E86C6C889FA8F5A6E9AD8197168205946435F9D | ADR-0079-ecosystem-engineering-rigor-canon.md | Ecosystem engineering rigor canon (UMADR satellites) | - +0080 | Accepted | B217F4C1FA5C96661EEF968C37500E20C09023C3D86186580496CEE7CB61E422 | ADR-0080-local-validation-gate-inviolable.md | local validation gate inviolable | - # -# InventoryHash: A4D38F67D132F63EA4E99EEDB6723FD37AE7B6D00CE2C17E97D29053D5B7013D +# InventoryHash: 87BD2025208408CE4DB3386EEC40EC0FC161078FBF38E3D7217BE236087A5F5B diff --git a/docs/adr/README.md b/docs/adr/README.md index 11088fc8..f2e20ee2 100644 --- a/docs/adr/README.md +++ b/docs/adr/README.md @@ -97,6 +97,7 @@ Short, durable notes that capture **why** the project chose an approach—not on | 0077 | [Filesystem scan does not honor client `.gitignore`](ADR-0077-filesystem-scan-no-client-gitignore-by-design.md) | Accepted | | 0078 | [Multi-pattern regex: RegexSet before Vectorscan (benchmark gate)](ADR-0078-multi-pattern-regex-benchmark-gate-regexset-before-vectorscan.md) | Proposed | | 0079 | [Ecosystem engineering rigor canon (UMADR satellites)](ADR-0079-ecosystem-engineering-rigor-canon.md) | Proposed | +| 0080 | [Local validation gate is inviolable: full check-all before any push or PR](ADR-0080-local-validation-gate-inviolable.md) | Accepted | ## Related docs From 99c2676887aed5734e8d3592ddc64f85da1aca34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?FabioLeit=C3=A3o?= Date: Fri, 3 Jul 2026 23:54:56 -0300 Subject: [PATCH 2/2] =?UTF-8?q?Gate-Change-Approved-By:=20@FabioLeitao=20(?= =?UTF-8?q?#1160)=20|=20ADR-0080=20ratificado=20=E2=80=94=20gate=20check-a?= =?UTF-8?q?ll=20inviolavel,=20dog-food=20do=20proprio=20produto=20contra?= =?UTF-8?q?=20ela=20mesma=20|=202026-07-03?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ``` -----BEGIN SSH SIGNATURE----- U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAgyEpOM79Y37xE8qOhlhghEfLh9P TzRdk6n8nzLfBNGqwAAAAEZmlsZQAAAAAAAAAGc2hhNTEyAAAAUwAAAAtzc2gtZWQyNTUx OQAAAEDZM3214qPqwzTrFIexlcC2D+o0wOhLlF78UpAMBWJIk8WXc2AltEprYIQW81BUjX tlJ9tx/PeXLMVxnJF7N2EA -----END SSH SIGNATURE----- ```