fix(quality): drain the two Fast Quality Gates base-reds (lockfile + mutation coverage) - #11438
Merged
diegosouzapw merged 1 commit intoAug 24, 2026
Merged
Conversation
`Fast Quality Gates` has been failing on every open PR against release/v3.8.50 with "2 gate(s) failed: mutation-test-coverage lockfile". Neither belongs to any feature branch, so they are drained here. check:lockfile — a transitive dev/optional entry (libxmljs2 → brace-expansion@2.1.4) landed with a `resolved` URL pointing at registry.npmmirror.com instead of registry.npmjs.org, which lockfile-lint rejects as a supply-chain policy violation. Verified before touching it: the recorded `integrity` (sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==) is byte-identical to the official npmjs tarball's, so the package content is the same and this is a provenance slip — someone's install ran behind the mirror registry — not a tampered package. Repointed the URL; `integrity` untouched. It was the only non-npmjs host in the lockfile (2690 npmjs entries). check:mutation-test-coverage — two covering unit tests were missing from stryker.conf.json's tap.testFiles, so their mutant kills did not count: repro-glm-iso-reset-24h-cap (accountFallback.ts) and repro-combo-persisted-cooldown-preskip (comboPredicates.ts). Inserted in place. Both gates verified green locally. The diff is three lines: re-serializing either file would have reordered a curated list for no reason.
diegosouzapw
added a commit
that referenced
this pull request
Sep 3, 2026
…tap.testFiles The new tests/unit/authz/credential-export-always-protected.test.ts covers src/server/authz/routeGuard.ts, so check:mutation-test-coverage --strict fails until it is listed — its mutant kills would not count otherwise. Inserted in place (no re-serialization: a JSON round-trip on this file reorders ~10 curated entries that are already out of alphabetical order, cf. #11438).
diegosouzapw
added a commit
that referenced
this pull request
Sep 3, 2026
…HSA-5926-2w35-7h4q) (#12600) * fix(authz): hard-gate every credential export and CLI-config write GHSA-5926-2w35-7h4q: `POST /api/providers/{id}/claude-auth/export` and `.../codex-auth/export` gate on `requireManagementAuth(request)` with no `alwaysRequireAuth`, and neither path was in ALWAYS_PROTECTED_API_PATHS. Under `requireLogin=false` — the local-first default — both fail open, so anyone who knows a connection id downloads the operator's raw Claude/Codex OAuth access_token / refresh_token (plus the Codex id_token). This is the third recurrence of one class. GHSA-mghq-58h3-qcqj added /api/db-backups; GHSA-v7g9-7f55-5g46 added the /api/settings/*-json siblings mghq had missed; these two are the siblings both missed. So the fix is written against the class, not the two reported routes. Sweeping every route that hands out stored credentials, dumps captured traffic, or writes the operator's CLI config turned up four more on the fail-open tier: - GET /api/logs/export — dumps call_logs (prompts and responses) and proxy_logs for up to 168h. - /api/cli-tools/codex-profiles — GET leaks the operator's account label; PUT writes attacker-supplied auth.json and config.toml straight into the host's Codex CLI config. Its only guard is ensureCliConfigWriteAllowed() with no targetPath, which checks CLI_ALLOW_CONFIG_WRITES — default true. Paired with the POST that stores an arbitrary profile, that is: save a profile holding the attacker's auth.json, apply it, and the operator's CLI now runs on attacker credentials (or, via config.toml, an attacker base URL). - {claude,codex}-auth/apply-local and providers/agy-auth/apply-local — write a stored credential into ~/.codex/auth.json and ~/.gemini/antigravity-cli/antigravity-oauth-token. The traffic-inspector HAR exports were already covered by LOCAL_ONLY. Routes with a dynamic segment cannot be expressed in the exact/prefix list — a `/api/providers/` prefix would hard-gate the whole provider surface and break every keyless install — so this adds ALWAYS_PROTECTED_API_PATTERNS, mirroring the existing LOCAL_ONLY_API_PATTERNS, and `isAlwaysProtectedPath` consults both. The apply-local routes get ALWAYS_PROTECTED rather than LOCAL_ONLY on purpose: it closes the anonymous hole without breaking an operator driving the dashboard through a tunnel. Deliberately NOT adding `{ alwaysRequireAuth: true }` at the handlers. Tier 2 is the architecture's designated mechanism and the guard runs before the handler; a second copy of the same decision inside each route is exactly the kind of duplicate that drifts out of sync (cf. the dashboardCsrf prefix scan that had to be unified in #11417). tests/unit/authz/credential-export-always-protected.test.ts — 5 tests, red before the fix. Written as an inventory of the whole class rather than two more assertions, plus negative cases: the neighbouring provider routes must stay on MANAGEMENT, and a connection id containing a slash must not slip past `[^/]+`. openapi.yaml marks the seven newly-gated operations `x-always-protected`, and openapi-security-tiers.test.ts now resolves `{param}` placeholders so it can validate the pattern entries too. Reported by @skeletonsec. Closes GHSA-5926-2w35-7h4q * chore(quality): register the credential-export authz test in stryker tap.testFiles The new tests/unit/authz/credential-export-always-protected.test.ts covers src/server/authz/routeGuard.ts, so check:mutation-test-coverage --strict fails until it is listed — its mutant kills would not count otherwise. Inserted in place (no re-serialization: a JSON round-trip on this file reorders ~10 curated entries that are already out of alphabetical order, cf. #11438).
diegosouzapw
added a commit
that referenced
this pull request
Sep 10, 2026
…les (#13229) `check:mutation-test-coverage --strict` has been failing Fast Quality Gates on every open PR against release/v3.8.51. It grew from 2 missing entries to 5 in roughly an hour, so it is drifting faster than PRs land. Four test files cover a mutated module without being listed, so their mutant kills do not count: open-sse/services/accountFallback.ts <- openai-compatible-per-upstream-402-health src/sse/services/auth.ts <- openai-compatible-per-upstream-402-health <- quota-window-label src/shared/utils/circuitBreaker.ts <- combo/execute-target-gates open-sse/services/combo/comboStructure.ts <- combo-pin-implicit-allowlist Registration only — no test or module is touched, and no gate is weakened; the listing is what makes those kills count in the first place. Inserted in place, never through a JSON round-trip: re-serializing this file reorders the ~10 curated entries that are already out of alphabetical order (learned the hard way in #11438). check:mutation-test-coverage now reports no drift. check:tracked-artifacts OK, prettier clean. Worth noting for whoever adds the next test: this gate fires whenever a NEW test happens to cover one of the 31 mutated modules, which is easy to do without realising. Registering it in the same commit is cheaper than a CI round-trip.
muhamadgalihsaputra
pushed a commit
to niyatna/NiyatnaRoute
that referenced
this pull request
Sep 27, 2026
…w#11438) `Fast Quality Gates` has been failing on every open PR against release/v3.8.50 with "2 gate(s) failed: mutation-test-coverage lockfile". Neither belongs to any feature branch, so they are drained here. check:lockfile — a transitive dev/optional entry (libxmljs2 → brace-expansion@2.1.4) landed with a `resolved` URL pointing at registry.npmmirror.com instead of registry.npmjs.org, which lockfile-lint rejects as a supply-chain policy violation. Verified before touching it: the recorded `integrity` (sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==) is byte-identical to the official npmjs tarball's, so the package content is the same and this is a provenance slip — someone's install ran behind the mirror registry — not a tampered package. Repointed the URL; `integrity` untouched. It was the only non-npmjs host in the lockfile (2690 npmjs entries). check:mutation-test-coverage — two covering unit tests were missing from stryker.conf.json's tap.testFiles, so their mutant kills did not count: repro-glm-iso-reset-24h-cap (accountFallback.ts) and repro-combo-persisted-cooldown-preskip (comboPredicates.ts). Inserted in place. Both gates verified green locally. The diff is three lines: re-serializing either file would have reordered a curated list for no reason. Co-authored-by: Xiangzhe <bakryun0718@proton.me>
muhamadgalihsaputra
pushed a commit
to niyatna/NiyatnaRoute
that referenced
this pull request
Sep 27, 2026
…HSA-5926-2w35-7h4q) (diegosouzapw#12600) * fix(authz): hard-gate every credential export and CLI-config write GHSA-5926-2w35-7h4q: `POST /api/providers/{id}/claude-auth/export` and `.../codex-auth/export` gate on `requireManagementAuth(request)` with no `alwaysRequireAuth`, and neither path was in ALWAYS_PROTECTED_API_PATHS. Under `requireLogin=false` — the local-first default — both fail open, so anyone who knows a connection id downloads the operator's raw Claude/Codex OAuth access_token / refresh_token (plus the Codex id_token). This is the third recurrence of one class. GHSA-mghq-58h3-qcqj added /api/db-backups; GHSA-v7g9-7f55-5g46 added the /api/settings/*-json siblings mghq had missed; these two are the siblings both missed. So the fix is written against the class, not the two reported routes. Sweeping every route that hands out stored credentials, dumps captured traffic, or writes the operator's CLI config turned up four more on the fail-open tier: - GET /api/logs/export — dumps call_logs (prompts and responses) and proxy_logs for up to 168h. - /api/cli-tools/codex-profiles — GET leaks the operator's account label; PUT writes attacker-supplied auth.json and config.toml straight into the host's Codex CLI config. Its only guard is ensureCliConfigWriteAllowed() with no targetPath, which checks CLI_ALLOW_CONFIG_WRITES — default true. Paired with the POST that stores an arbitrary profile, that is: save a profile holding the attacker's auth.json, apply it, and the operator's CLI now runs on attacker credentials (or, via config.toml, an attacker base URL). - {claude,codex}-auth/apply-local and providers/agy-auth/apply-local — write a stored credential into ~/.codex/auth.json and ~/.gemini/antigravity-cli/antigravity-oauth-token. The traffic-inspector HAR exports were already covered by LOCAL_ONLY. Routes with a dynamic segment cannot be expressed in the exact/prefix list — a `/api/providers/` prefix would hard-gate the whole provider surface and break every keyless install — so this adds ALWAYS_PROTECTED_API_PATTERNS, mirroring the existing LOCAL_ONLY_API_PATTERNS, and `isAlwaysProtectedPath` consults both. The apply-local routes get ALWAYS_PROTECTED rather than LOCAL_ONLY on purpose: it closes the anonymous hole without breaking an operator driving the dashboard through a tunnel. Deliberately NOT adding `{ alwaysRequireAuth: true }` at the handlers. Tier 2 is the architecture's designated mechanism and the guard runs before the handler; a second copy of the same decision inside each route is exactly the kind of duplicate that drifts out of sync (cf. the dashboardCsrf prefix scan that had to be unified in diegosouzapw#11417). tests/unit/authz/credential-export-always-protected.test.ts — 5 tests, red before the fix. Written as an inventory of the whole class rather than two more assertions, plus negative cases: the neighbouring provider routes must stay on MANAGEMENT, and a connection id containing a slash must not slip past `[^/]+`. openapi.yaml marks the seven newly-gated operations `x-always-protected`, and openapi-security-tiers.test.ts now resolves `{param}` placeholders so it can validate the pattern entries too. Reported by @skeletonsec. Closes GHSA-5926-2w35-7h4q * chore(quality): register the credential-export authz test in stryker tap.testFiles The new tests/unit/authz/credential-export-always-protected.test.ts covers src/server/authz/routeGuard.ts, so check:mutation-test-coverage --strict fails until it is listed — its mutant kills would not count otherwise. Inserted in place (no re-serialization: a JSON round-trip on this file reorders ~10 curated entries that are already out of alphabetical order, cf. diegosouzapw#11438).
muhamadgalihsaputra
pushed a commit
to niyatna/NiyatnaRoute
that referenced
this pull request
Sep 27, 2026
…les (diegosouzapw#13229) `check:mutation-test-coverage --strict` has been failing Fast Quality Gates on every open PR against release/v3.8.51. It grew from 2 missing entries to 5 in roughly an hour, so it is drifting faster than PRs land. Four test files cover a mutated module without being listed, so their mutant kills do not count: open-sse/services/accountFallback.ts <- openai-compatible-per-upstream-402-health src/sse/services/auth.ts <- openai-compatible-per-upstream-402-health <- quota-window-label src/shared/utils/circuitBreaker.ts <- combo/execute-target-gates open-sse/services/combo/comboStructure.ts <- combo-pin-implicit-allowlist Registration only — no test or module is touched, and no gate is weakened; the listing is what makes those kills count in the first place. Inserted in place, never through a JSON round-trip: re-serializing this file reorders the ~10 curated entries that are already out of alphabetical order (learned the hard way in diegosouzapw#11438). check:mutation-test-coverage now reports no drift. check:tracked-artifacts OK, prettier clean. Worth noting for whoever adds the next test: this gate fires whenever a NEW test happens to cover one of the 31 mutated modules, which is easy to do without realising. Registering it in the same commit is cheaper than a CI round-trip.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Drains the two gates that have been failing
Fast Quality Gateson every open PR againstrelease/v3.8.50:Neither belongs to any feature branch, so per the base-red doctrine they are fixed here rather than inside someone's PR.
check:lockfileA transitive dev + optional entry (
libxmljs2→brace-expansion@2.1.4) landed with aresolvedURL pointing at the npmmirror registry, whichlockfile-lintrejects as a supply-chain policy violation.Checked before touching it — the recorded
integrityis byte-identical to the official npmjs tarball's:So the package content is the same one npmjs serves. This is a provenance slip — an install that ran behind the mirror registry, and the lockfile carried the URL back — not a tampered package. Repointed the URL;
integrityuntouched.It was the only non-npmjs host in the file (2690
registry.npmjs.orgentries, 1 mirror).check:mutation-test-coverageTwo covering unit tests were missing from
stryker.conf.json'stap.testFiles, so their mutant kills did not count:open-sse/services/accountFallback.tstests/unit/repro-glm-iso-reset-24h-cap.test.tsopen-sse/services/combo/comboPredicates.tstests/unit/repro-combo-persisted-cooldown-preskip.test.tsInserted in place.
Validation
check:lockfile—✔ No issues detectedcheck:mutation-test-coverage --strict—✓ No drift — every covering unit test is listed in tap.testFilescheck:tracked-artifacts,prettier --check— PASSThe whole diff is three lines. A first attempt re-serialized
stryker.conf.jsonthrough a JSON round-trip and the sort silently reordered ~10 curated entries that were already out of alphabetical order; that was thrown away and redone as an in-place insert. Worth knowing if you ever automate edits to that file.Not fixed here
stryker.conf.jsonhas a pre-existing duplicate entry (tests/unit/aihorde-optional-api-key.test.tsappears twice). Harmless and out of scope for a base-red drain — flagging it rather than folding it in.The other
release/v3.8.50base-reds are untouched by this PR: openapi-coverage ratchet,route-body-validation-t06(volcengine-plan routes), the "350 providers" doc-count drift, ESLint stale suppressions, and the unit-shard failures tracked under #9985.