Skip to content

Quality Gates → 100% (Fase 6A + Fase 7 + plano Fase 8) - #3757

Merged
diegosouzapw merged 13 commits into
release/v3.8.24from
feat/quality-gates-phase6a-7
Jun 13, 2026
Merged

diegosouzapw merged 13 commits into
release/v3.8.24from
feat/quality-gates-phase6a-7

Conversation

@diegosouzapw

Copy link
Copy Markdown
Collaborator

Quality Gates → 100% (Fase 6A + Fase 7)

Completa a iniciativa de quality-gates: as 10 tasks restantes da Fase 6A (endurecimento sistêmico) e a Fase 7 inteira (20 gates de segurança/dead-code/mutação/ferramental community). Plano de execução e Fase 8 documentados.

✅ Fase 6A (10/10 — 4 commits)

  • 6A.3 helper stale-allowlist + aplicado em ~10 gates (⭐ pegou 1 stale real: migration 041 fantasma)
  • 6A.4 docs/architecture/QUALITY_GATES.md + seção no CLAUDE.md
  • 6A.5 motor v2: --require-tighten, eps por métrica, métrica órfã
  • 6A.6 .github/workflows/quality.yml (gates rápidos em PR→release/**)
  • 6A.7 fetch-targets v2 · 6A.8 escopo dos gates de segurança · 6A.9 known-symbols v2 (MCP/A2A/cloud) · 6A.10 test-masking v2 · 6A.11 file-size/complexity +electron/bin · 6A.12 jscpd pinado, tracked-artifacts, pre-push, run-all-gates

✅ Fase 7 (20 gates)

  • npm-validáveis (testados): knip dead-code, sonarjs cognitive-complexity, type-coverage, lockfile-lint, size-limit, dpdm, license-compliance, pr-evidence
  • externos (advisory no CI): osv-scanner, CodeQL-ratchet, gitleaks, actionlint+zizmor, Stryker, axe-a11y, semcheck — skip gracioso até binários/secrets do owner
  • SonarQube destravado (removidas exclusions **/* neutralizadoras)

🔒 Achados de segurança/compliance

  • P1 corrigido: /api/system/version (git checkout + npm install) e /api/db-backups/exportAll (tar) eram spawn-capable SEM classificação local-only → RCE-via-túnel. Classificadas em LOCAL_ONLY_API_PREFIXES (TDD).
  • Compliance: tls-client-node usa Commons Clause (restringe venda comercial) — exceção registrada para revisão.

Validação

  • typecheck:core 0 · ratchet OK (8 métricas) · 450+ testes de gate verdes
  • baseline-compare (worktree): zero regressão minha — 3 flaky pré-existentes passam isolados, 1 regressão (PR_BODY env) corrigida
  • Re-baselines conscientes documentados: eslintWarnings 3501→3658 (drift v3.8.20-24 + tooling), complexity 1746→1794

🤖 Generated with Claude Code

…ality.yml, gate docs (6A.3-helper/6A.4/6A.5/6A.6)
…copes, known-symbols v2, test-masking v2, file-size/complexity electron+bin, stale-enforcement across gates (6A.3-resto/6A.7/6A.8/6A.9/6A.10/6A.11)
… gate, pre-push reactivated, run-all-gates aggregator (6A.12)
…pi/i18n coverage metrics, eslintErrors floor, conscious eslint re-baseline 3501->3653) (INT-6A)
…cognitive-complexity, type-coverage, lockfile-lint, size-limit, dpdm circular, license-compliance, pr-evidence (7.4/7.5/7.6/7.7/7.10/7.12/7.16/7.20)
…ackups/exportAll as local-only (P1 from 6A.8 route-guard gate — RCE-via-tunnel surface)

The 6A.8 route-guard gate found two spawn-capable routes reachable past the
loopback gate: /api/system/version (git checkout + npm install) and
/api/db-backups/exportAll (tar). A leaked JWT over a tunnel could trigger them.
Classified both in LOCAL_ONLY_API_PREFIXES (loopback enforced before auth),
emptied the gate's frozen-debt set, TDD red->green.
…s/actionlint+zizmor scans, stryker/axe/semcheck configs, sonar destrava exclusions, anti-slopsquat age-check + per-module coverage; wire quality-extended advisory job (7.1/7.2/7.3/7.8/7.9/7.11/7.13/7.14/7.18/7.19)
…), contracts (fast-check/golden/SSE), resilience (toxiproxy/heap), LLM-security (promptfoo/garak)
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements Fase 7 quality gates and security audits, introducing automated checks for bundle size, circular dependencies, CodeQL alerts, cognitive complexity, dead code, license compliance, lockfile linting, tracked artifacts, type coverage, vulnerability scanning, and workflow auditing. It also updates the route guard to restrict spawn-capable routes (/api/system/version and /api/db-backups/exportAll) to loopback-only to prevent RCE. The review feedback is highly valuable, pointing out several critical Windows compatibility issues where executing .bin wrappers or npm directly via execFileSync will fail, as well as potential TypeError crashes in the quality ratchet script when baseline files are missing.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +48 to +52
stdout = execFileSync("node", [binPath, "--json"], {
encoding: "utf8",
cwd,
maxBuffer: 8 * 1024 * 1024,
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Running node with binPath (which points to node_modules/.bin/size-limit) will fail on modern npm versions (npm v9+). This is because the files in .bin/ are shell wrapper scripts rather than direct JavaScript files, causing Node.js to throw a SyntaxError when attempting to parse them.\n\nInstead, we should execute the binary directly, enabling shell execution on Windows to resolve the .cmd wrapper.

    stdout = execFileSync(binPath, [\"--json\"], {\n      encoding: \"utf8\",\n      cwd,\n      maxBuffer: 8 * 1024 * 1024,\n      shell: process.platform === \"win32\",\n    });

Comment on lines 46 to 49
for (const [key, spec] of Object.entries(baseline.metrics)) {
const current = metrics[key];
const base = spec.value;
const dir = spec.direction; // "down" = menor-é-melhor | "up" = maior-é-melhor

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

If ALLOW_MISSING is enabled and the baseline file is missing, load(BASELINE) returns {}. Consequently, baseline.metrics will be undefined, causing Object.entries(baseline.metrics) to throw a TypeError and crash the script.\n\nWe should safely default baseline.metrics to an empty object {} to prevent this crash.

for (const [key, spec] of Object.entries(baseline.metrics || {})) {\n  const current = metrics[key];\n  const base = spec.value;\n  const dir = spec.direction; // \"down\" = menor-é-melhor | \"up\" = maior-é-melhor

}

// Behavior 3: warn about orphan metrics (present in collected metrics but absent in baseline).
const baselineKeys = new Set(Object.keys(baseline.metrics));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Similarly, baseline.metrics can be undefined if the baseline file is missing or empty under ALLOW_MISSING. We should safely guard Object.keys here as well.

Suggested change
const baselineKeys = new Set(Object.keys(baseline.metrics));
const baselineKeys = new Set(Object.keys(baseline.metrics || {}));

Comment on lines +54 to +64
export function isBinaryAvailable(name) {
// Use `command -v` on Unix; `where` on Windows (via cmd).
// We shell through `sh -c` because execFileSync needs the actual path
// and we want cross-platform behaviour.
const result = spawnSync("sh", ["-c", `command -v ${name}`], {
encoding: "utf8",
timeout: 5_000,
windowsHide: true,
});
return result.status === 0 && result.stdout.trim().length > 0;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The implementation of isBinaryAvailable does not match the comment's claim of supporting Windows via where. Spawning sh directly will fail on Windows environments where sh is not available in the PATH.\n\nWe can make this check robust and cross-platform by using shell: true and choosing the appropriate command based on the platform.

export function isBinaryAvailable(name) {\n  const isWin = process.platform === \"win32\";\n  const cmd = isWin ? \"where \" + name : \"command -v \" + name;\n  const result = spawnSync(cmd, {\n    shell: true,\n    encoding: \"utf8\",\n    timeout: 5000,\n    windowsHide: true,\n  });\n  return result.status === 0 && result.stdout.trim().length > 0;\n}

Comment on lines +144 to +153
const raw = execFileSync(
"npm",
["view", pkgName, "time.created", "--json"],
{
encoding: "utf8",
timeout: timeoutMs,
// Suppress npm progress/warn output on stderr
stdio: ["ignore", "pipe", "pipe"],
}
);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Executing \"npm\" directly via execFileSync will fail on Windows because npm is distributed as a batch script (npm.cmd) rather than a direct executable.\n\nWe can resolve this by dynamically selecting the correct command name based on the platform.

    const raw = execFileSync(\n      process.platform === \"win32\" ? \"npm.cmd\" : \"npm\",\n      [\"view\", pkgName, \"time.created\", \"--json\"],\n      {\n        encoding: \"utf8\",\n        timeout: timeoutMs,\n        // Suppress npm progress/warn output on stderr\n        stdio: [\"ignore\", \"pipe\", \"pipe\"],\n      }\n    );

Comment on lines +127 to +131
const output = execFileSync(CHECKER_BIN, ["--production", "--json"], {
cwd: ROOT,
encoding: "utf-8",
maxBuffer: 32 * 1024 * 1024, // 32 MB
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Executing CHECKER_BIN directly via execFileSync will fail on Windows because the binary in .bin/ is a shell/batch wrapper rather than a direct executable.\n\nWe can fix this by enabling shell execution on Windows.

  const output = execFileSync(CHECKER_BIN, [\"--production\", \"--json\"], {\n    cwd: ROOT,\n    encoding: \"utf-8\",\n    maxBuffer: 32 * 1024 * 1024, // 32 MB\n    shell: process.platform === \"win32\",\n  });

Comment on lines +94 to +95
try {
const output = execFileSync(bin, args, { encoding: "utf8" });

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Executing bin directly via execFileSync will fail on Windows because the binary in .bin/ is a shell/batch wrapper rather than a direct executable.\n\nWe can fix this by enabling shell execution on Windows.

  try {\n    const output = execFileSync(bin, args, {\n      encoding: \"utf8\",\n      shell: process.platform === \"win32\",\n    });

@@ -31,7 +33,7 @@ export function evaluateDuplication(current, baseline, eps = EPS) {

function measureDuplicationPct() {
const out = fs.mkdtempSync(path.join(os.tmpdir(), "jscpd-"));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Executing JSCPD_BIN directly via execFileSync will fail on Windows because the binary in .bin/ is a shell/batch wrapper rather than a direct executable.\n\nWe can fix this by enabling shell execution on Windows.

  execFileSync(JSCPD_BIN, [...JSCPD_FIXED_ARGS, \"--output\", out], {\n    stdio: \"ignore\",\n    shell: process.platform === \"win32\",\n  });

Comment on lines +62 to +65
stdout = execFileSync(ESLINT_BIN, ESLINT_ARGS, {
encoding: "utf8",
maxBuffer: 64 * 1024 * 1024,
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Executing ESLINT_BIN directly via execFileSync will fail on Windows because the binary in .bin/ is a shell/batch wrapper rather than a direct executable.\n\nWe can fix this by enabling shell execution on Windows.

    stdout = execFileSync(ESLINT_BIN, ESLINT_ARGS, {\n      encoding: \"utf8\",\n      maxBuffer: 64 * 1024 * 1024,\n      shell: process.platform === \"win32\",\n    });

Comment on lines +69 to +73
stdout = execFileSync(typeCoverageBin, ["--json-output", "-p", TSCONFIG], {
encoding: "utf8",
maxBuffer: 32 * 1024 * 1024,
cwd: ROOT,
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Executing typeCoverageBin directly via execFileSync will fail on Windows because the binary in .bin/ is a shell/batch wrapper rather than a direct executable.\n\nWe can fix this by enabling shell execution on Windows.

    stdout = execFileSync(typeCoverageBin, [\"--json-output\", \"-p\", TSCONFIG], {\n      encoding: \"utf8\",\n      maxBuffer: 32 * 1024 * 1024,\n      cwd: ROOT,\n      shell: process.platform === \"win32\",\n    });

… v3.8.24 merges

These 5 files exceeded the frozen baseline solely because of already-merged,
already-reviewed v3.8.24 PRs that landed after this branch froze its baseline:
  - src/lib/providers/validation.ts        4209→4302  (#3767 qwen-web fix)
  - src/shared/components/RequestLoggerV2.tsx 1232→1276 (#3760 logs light-mode)
  - open-sse/executors/antigravity.ts      1553→1572  (#3766 antigravity refresh)
  - open-sse/executors/base.ts             1199→1205  (#3756 xhigh effort)
  - open-sse/translator/response/openai-responses.ts 873→878 (#3762 tool-call integrity)

None are touched by this branch; the bump reflects current release reality.
…t merge #3764

#3764 (self-hosted Material Symbols icon font) added material-symbols@^0.45.1
as a real dashboard dependency (used by CommandPalette and the icon set). It
landed on release after this branch froze dependency-allowlist.json, so the
check:deps gate flagged it as an unreviewed dep. Confirmed legitimate (Google
Material Symbols, present in package.json + used across src/shared/components)
and added to the allowlist.
@diegosouzapw

Copy link
Copy Markdown
Collaborator Author

Merging into release/v3.8.24. Reconciled two baselines that drifted only because of concurrent already-merged v3.8.24 PRs (none touched by this branch): bumped file-size-baseline.json for 5 files grown by #3756/#3760/#3762/#3766/#3767, and allowlisted material-symbols (real dashboard dep added by #3764). All 14 Fast Quality Gates checks green locally and in CI.

@diegosouzapw
diegosouzapw merged commit f7d895e into release/v3.8.24 Jun 13, 2026
3 checks passed
@diegosouzapw
diegosouzapw deleted the feat/quality-gates-phase6a-7 branch June 13, 2026 14:18
diegosouzapw added a commit that referenced this pull request Jun 13, 2026
…contributor credits

- Restructure [3.8.24] into ✨ Features / 🔒 Security / 🐛 Fixed / 📝 Maintenance
- Add bullets for every PR landed since v3.8.23 that was missing:
  marketplace (#3656), strict-mode CC defaults (#3776), emergency-fallback flag (#3752),
  xhigh effort (#3756), Codex memory WS (#3749), IPv6 egress (#3777),
  marketplace SSRF (#3774), CodeQL/Dependabot (#3778), anthropic sampling (#3780),
  thinking passthrough (#3775), mcp dist entry (#3765), streamed tool args (#3762),
  logs light-mode (#3760), clean-history purge (#3751), quality-gates (#3757),
  docs gaps (#3453), file-size re-baseline (#3770), E415 publish guard, i18n prune
- Move misplaced #3775 bullet out of [Unreleased] into [3.8.24]
- Date [3.8.23] header (TBD -> 2026-06-12, the release tag date)
@diegosouzapw diegosouzapw mentioned this pull request Jun 13, 2026
diegosouzapw added a commit that referenced this pull request Jun 13, 2026
…ES row

The `check:doc-links` table row in docs/architecture/QUALITY_GATES.md (added
this cycle by #3757) used a literal `[text](path)` example inside inline code.
The link checker strips fenced code blocks but not inline backticks, so it parsed
that example as a real link to a 'path' file that does not exist — turning the
'Docs Sync (Strict)' CI job (npm run check:docs-all) red. Reworded to break the
`](` adjacency; check:doc-links now passes (655 links, 0 broken).
tkgo11 pushed a commit to tkgo11/OmniRoute that referenced this pull request Sep 23, 2026
…ence#3757)

Quality Gates → 100% (Fase 6A + Fase 7 + plano Fase 8). Reconciled file-size + dep allowlist for concurrent v3.8.24 merges. Integrated into release/v3.8.24.
tkgo11 pushed a commit to tkgo11/OmniRoute that referenced this pull request Sep 23, 2026
…contributor credits

- Restructure [3.8.24] into ✨ Features / 🔒 Security / 🐛 Fixed / 📝 Maintenance
- Add bullets for every PR landed since v3.8.23 that was missing:
  marketplace (cheaper-inference#3656), strict-mode CC defaults (cheaper-inference#3776), emergency-fallback flag (cheaper-inference#3752),
  xhigh effort (cheaper-inference#3756), Codex memory WS (cheaper-inference#3749), IPv6 egress (cheaper-inference#3777),
  marketplace SSRF (cheaper-inference#3774), CodeQL/Dependabot (cheaper-inference#3778), anthropic sampling (cheaper-inference#3780),
  thinking passthrough (cheaper-inference#3775), mcp dist entry (cheaper-inference#3765), streamed tool args (cheaper-inference#3762),
  logs light-mode (cheaper-inference#3760), clean-history purge (cheaper-inference#3751), quality-gates (cheaper-inference#3757),
  docs gaps (cheaper-inference#3453), file-size re-baseline (cheaper-inference#3770), E415 publish guard, i18n prune
- Move misplaced cheaper-inference#3775 bullet out of [Unreleased] into [3.8.24]
- Date [3.8.23] header (TBD -> 2026-06-12, the release tag date)
tkgo11 pushed a commit to tkgo11/OmniRoute that referenced this pull request Sep 23, 2026
…ES row

The `check:doc-links` table row in docs/architecture/QUALITY_GATES.md (added
this cycle by cheaper-inference#3757) used a literal `[text](path)` example inside inline code.
The link checker strips fenced code blocks but not inline backticks, so it parsed
that example as a real link to a 'path' file that does not exist — turning the
'Docs Sync (Strict)' CI job (npm run check:docs-all) red. Reworded to break the
`](` adjacency; check:doc-links now passes (655 links, 0 broken).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant