mirror of
https://github.com/fsolla/teqo.git
synced 2026-11-13 06:25:20 +00:00
13 KiB
13 KiB
Guardrails
Ledger dos guardrails determinísticos colhidos de kind:agent-miss (fluxo pnpm agent:file-miss → harvest no engineering-audit → guarda programática) e dos endurecimentos de guarda existentes. Uma linha por guarda: origem, classe na escada de determinismo, mecanismo, status.
Classes (escada do Pass 3 D6 / engineering-audit → .agents/skills/engineering-audit/reference/guards.md): 1 tipo (estado ruim irrepresentável) · 2 ESLint · 3 spec de convenção · 4 análise estática em CI (knip/madge) · 5 pin comportamental · 6 doc/convenção (judgment-only declarado — não fingir que doc é guarda).
Ativos
| Guarda | Origem | Classe | Mecanismo | Status |
|---|---|---|---|---|
agent:ship exige stamp de /simplify casado com HEAD; PR Ready + auto-merge + watch até MERGED |
#83 | 3 (script + hooks) | scripts/agent-ship.mjs, .cursor/hooks/guard-pr-create.mjs (bloqueia gh pr create manual), .cursor/hooks/pr-merge-watchdog.mjs (re-engata com PR aberto) |
vivo desde 2026-07-31 (PR #89); miss fechada no Pass 4 |
Alocador de municípios em specs — sem slug fixo + mutação; sem municipio=<slug> em e2e; regex de nome de catálogo ancorada |
#73 | 3 | tests/unit/testMunicipalityAllocatorConventions.unit.spec.ts (3 regras; mutações = assign/touch/create*/payload.update municipality) |
PR #93 (Pass 4) |
Sheet compartilhada por lista — chip cells exigem CampaignListSheetProvider; invariante dev no overlay |
#52 | 3 + 5 | tests/unit/sharedSheetHostConventions.unit.spec.ts; console.error development-only em CampaignCellEditOverlay |
PR #94 (Pass 4) |
| Navegação e2e assentada — goto→goto sem settle falha o build | #54 | 3 | tests/unit/e2eNavigationConventions.unit.spec.ts (settle = await expect/waitForURL/click/reload/login/catch) |
PR #95 (Pass 4) |
| Readiness de autenticador virtual antes da cerimônia WebAuthn | #53 | 3 | mesma spec (spec com WebAuthn.addVirtualAuthenticator deve chamar expectCampaignBiometricsReady() |
PR #95 (Pass 4) |
| Convenção de navegação e2e (goto = cold load/contrato; in-shell = continuidade) | #54 | 6 (judgment-only) | parágrafo em docs/TESTING.md |
PR #95 (Pass 4) |
| Update de globals públicos nunca "qualquer autenticado" | P0 do Pass 4 (sem issue) | 3 | tests/unit/globalAccessConventions.unit.spec.ts ban Boolean(user) em src/globals |
PR #91 (Pass 4) |
| Loaders de notificação tipados pelo ator (recipientID arbitrário irrepresentável) | P0 adjacente do Pass 4 | 1 | assinatura (payload, user: CampaignUser) + overrideAccess: false sob canReadOwnNotifications |
PR #91 (Pass 4) |
Die-helpers da CLI importados onde usados; DAY_MS single-source |
P1 do Pass 4 (sem issue) | 3 | tests/unit/scriptCliConventions.unit.spec.ts |
PR #92 (Pass 4) |
src/lib não type-importa @/utilities/** (direção única também para tipos) |
dodge do Pass 3 (suggestionCatalog) | 2 | ESLint no-restricted-imports allowTypeImports: false na zona src/lib |
PR #92 (Pass 4) |
Local API com user sempre declara overrideAccess; import dinâmico de módulos server banido em utilities |
guarda ausente (medida baseline 59/0) | 3 | tests/unit/localApiOverrideAccessConventions.unit.spec.ts |
PR #92 (Pass 4) |
| Desarme determinístico do auto-merge da /testing-audit (cria→desarma→verifica atômico; draft fail-closed) | #909 | 3 (script + spec) | scripts/testing-audit-disarm.mjs (create/--pr + --draft-on-failure); pin tests/unit/testingAuditDisarmConventions.unit.spec.ts (skill /testing-audit deve referenciar o script) |
vivo desde 2026-08-25 (Pass 6) |
| Plano de intenção com decisão de dados grava os valores literais (IDs, nomes, envs, thresholds) — nunca só narrativa | #895 | 6 (judgment-only declarada — doc/convenção, não fingir que doc é guarda) | bloco "Dados da decisão (literais)" no intention-template.md + prompt "decisão de dados → valores literais presentes no plano?" no gate do plan-issue |
vivo desde 2026-08-25 (Pass 6) |
Precedentes vivos (anteriores ao primeiro harvest)
| Guarda | Origem | Classe | Mecanismo |
|---|---|---|---|
| Vocabulário banido (Praça/Núcleo/Plano de Ação, accent-tolerant) | C13 / W4f / P3-K | 3 | codebaseConventions.unit.spec.ts |
server-only em utilities acopladas (sweep payload/next/*) |
Pass 2 W2 / P3-K | 3 | codebaseConventions.unit.spec.ts |
Escadas de formActions nos wrappers (runCampaignFormAction/Redirect) |
W4d / C8 F4b / OPS14 | 3 | codebaseConventions.unit.spec.ts (sweep mapCampaignFormActionError em (campaign) — não filename) |
| Ratchet de bypass admin não documentado | P3-E | 3 | codebaseConventions.unit.spec.ts (por arquivo, só diminui) |
| Mensagens de recusa como constantes + correspondência throw↔safelist | P3-A | 3 | codebaseConventions.unit.spec.ts:216-263 |
as never banido |
Pass 1 | 2 | ESLint no-restricted-syntax |
src/lib não importa utilities/ (valores) |
Pass 2 W2 | 2 | ESLint no-restricted-imports |
| 0 ciclos de import | Pass 2 | 4 | madge (pnpm check:cycles) |
| Dead code (arquivos/deps/exports em erro) | Pass 2 W4b | 4 | knip em CI |
PR só docs/plans/ sem Closes/Fixes/Resolves |
#116 OPS12 | 4 | scripts/lib/plansOnlyClosesGuard.mjs + scripts/check-plans-only-pr-closes.mjs + job plans-only-closes em ci-pr.yml |
| Seed mínimo obrigatório com migration (contrato manifest) | OPS fluxo PR | 3 + 5 | tests/unit/seedMinimalManifest.unit.spec.ts + job CI migrate→seed→int |
| Regex de template ancorada em e2e | P3-C | 3 | codebaseConventions.unit.spec.ts (ampliada para literais no Pass 4) |
| Consent fail-closed por chave estável | D3/Onda 0 | 5 | pins int submitWhatsapp/liderança/apoiador |
Misses colhidas aguardando guarda (fila do harvest)
(nenhuma — Pass 4 fechou as 5 abertas em 2026-07-31; Pass 5 (2026-08-03) colheu 0 kind:agent-miss abertas. Novas entram aqui até o próximo audit.)
Pass 5 — guardas adicionadas (não-miss)
| Guarda | Origem | Classe | Mecanismo | Status |
|---|---|---|---|---|
| Push de notificação de campanha só após commit da transação; send soft-fail se a row sumiu | P5-P1 | 3 + 5 | onPayloadTransactionCommit em payloadTransaction.ts; schedule em createCampaignNotification; notificationPushScheduleConventions unit pin |
vivo Pass 5 |