From 48a19ff53284eaf636f58590feb85bbd797352f9 Mon Sep 17 00:00:00 2001 From: backryun Date: Wed, 12 Aug 2026 12:08:23 -0300 Subject: [PATCH] feat(ci): extend check:tracked-artifacts never-allowed classes --- scripts/check/check-tracked-artifacts.mjs | 29 ++++++++- .../build/check-tracked-artifacts.test.ts | 65 +++++++++++++++++++ 2 files changed, 93 insertions(+), 1 deletion(-) diff --git a/scripts/check/check-tracked-artifacts.mjs b/scripts/check/check-tracked-artifacts.mjs index dddca935d1..cd6dd8414f 100644 --- a/scripts/check/check-tracked-artifacts.mjs +++ b/scripts/check/check-tracked-artifacts.mjs @@ -10,14 +10,41 @@ // - coverage/ — relatórios de cobertura gerados pelo c8 // - quality-metrics.json — saída do collect-metrics.mjs (gerado, não-versionado) // - symlinks rastreados (mode 120000) — indício de `git add -A` em worktree +// - _tasks (exato E prefixo) — repo git SEPARADO; o blob symlink rastreado causou DOIS +// wipes do diretório real (2026-08-08 e 2026-08-10; Hard Rule #23) +// - _references/ _mono_repo/ _ideia/ _cache/ — diretórios privados de raiz (regra /_*/) +// - .claude/worktrees/ — worktrees de sessão nunca entram no repo +// - docs/superpowers/ — artefatos de planejamento vivem em _tasks/, não em docs/ +// - .eslintcache* .fakebin-* dist/ .build/ .artifacts/ logs/ — caches e outputs gerados +// +// Todos os prefixos são ancorados na raiz (startsWith sobre paths do `git ls-files`): +// paths aninhados legítimos como `src/lib/logs/` NÃO são atingidos. import { execFileSync } from "node:child_process"; import { pathToFileURL } from "node:url"; -const FORBIDDEN_PREFIXES = ["node_modules/", ".next/", "coverage/"]; +const FORBIDDEN_PREFIXES = [ + "node_modules/", + ".next/", + "coverage/", + "_tasks/", + "_references/", + "_mono_repo/", + "_ideia/", + "_cache/", + ".claude/worktrees/", + "docs/superpowers/", + ".eslintcache", // matches .eslintcache, .eslintcache-complexity, .eslintcache-probe, … + ".fakebin-", // test executable shim dirs (.fakebin-/) + "dist/", + ".build/", + ".artifacts/", + "logs/", +]; const FORBIDDEN_EXACT = new Set([ "quality-metrics.json", // legacy root location (still forbidden if a stale run writes it) "config/quality/quality-metrics.json", // current generated location (collect-metrics.mjs) + "_tasks", // separate git repo — a tracked blob/symlink here wiped the real dir twice (HR#23) ]); /** diff --git a/tests/unit/build/check-tracked-artifacts.test.ts b/tests/unit/build/check-tracked-artifacts.test.ts index 99d8c05960..62a5ed4b52 100644 --- a/tests/unit/build/check-tracked-artifacts.test.ts +++ b/tests/unit/build/check-tracked-artifacts.test.ts @@ -60,3 +60,68 @@ test("checkTrackedArtifacts: multiple violations reported", () => { ]); assert.equal(result.length, 3); }); + +// --- never-allowed classes added after the _tasks tracked-symlink wipes (2026-08-08/10) --- + +test("checkTrackedArtifacts: _tasks tracked as exact entry (blob/symlink) is flagged", () => { + const result = checkTrackedArtifacts(["_tasks"]); + assert.equal(result.length, 1); + assert.ok(result[0].includes("_tasks")); +}); + +test("checkTrackedArtifacts: _tasks/ prefix is flagged", () => { + const result = checkTrackedArtifacts(["_tasks/pipeline/prs/1-analyzed/plan.md"]); + assert.equal(result.length, 1); +}); + +test("checkTrackedArtifacts: private root underscore dirs are flagged", () => { + const result = checkTrackedArtifacts([ + "_references/_sistemas_cli/relatorio.md", + "_mono_repo/_worktrees/x/file.ts", + "_ideia/draft.md", + "_cache/entry.json", + ]); + assert.equal(result.length, 4); +}); + +test("checkTrackedArtifacts: .claude/worktrees/ prefix is flagged", () => { + const result = checkTrackedArtifacts([".claude/worktrees/fix-123/src/app.ts"]); + assert.equal(result.length, 1); +}); + +test("checkTrackedArtifacts: docs/superpowers/ prefix is flagged", () => { + const result = checkTrackedArtifacts(["docs/superpowers/plans/2026-01-01-x.md"]); + assert.equal(result.length, 1); +}); + +test("checkTrackedArtifacts: .eslintcache family is flagged", () => { + const result = checkTrackedArtifacts([".eslintcache", ".eslintcache-complexity", ".eslintcache-probe"]); + assert.equal(result.length, 3); +}); + +test("checkTrackedArtifacts: .fakebin-* shim dirs are flagged", () => { + const result = checkTrackedArtifacts([".fakebin-9475/npm"]); + assert.equal(result.length, 1); +}); + +test("checkTrackedArtifacts: build/log output dirs are flagged", () => { + const result = checkTrackedArtifacts([ + "dist/server.js", + ".build/next/chunk.js", + ".artifacts/eslint-results.json", + "logs/app.log", + ]); + assert.equal(result.length, 4); +}); + +test("checkTrackedArtifacts: new prefixes are root-anchored — nested legit paths pass", () => { + const result = checkTrackedArtifacts([ + "src/lib/logs/logger.ts", + "electron/dist-electron.config.ts", + "docs/architecture/ARCHITECTURE.md", + "scripts/check/check-tracked-artifacts.mjs", + "tests/unit/build/check-tracked-artifacts.test.ts", + "bin/cli/locales/en.json", + ]); + assert.deepEqual(result, []); +});