Replace request.url.includes(FIREFLY_3P_HOST_SUFFIX) with parsed-hostname
comparison (anchored endsWith), closing CodeQL alert #778.
The old substring check could be bypassed by an attacker-controlled page
visited during the browser login window — a URL like
'https://evil.com/firefly-3p.ff.adobe.io' would pass the gate and its
Bearer token would be captured as the Adobe credential.
Practical severity is low (only during operator-initiated, time-boxed
login on a temp-profile browser), but the fix is one line and matches
the dot-anchored idiom used in docker/devin-bridge/network-guard/.
Closes code-scanning #778.
typecheck:core is its own blocking CI job (quality.yml), separate from
Docs Gates/Merge integrity. Confirmed pre-existing and unrelated to
any current work by branching this worktree directly from
upstream/release/v3.8.50 with no other merges applied.
- accountSemaphore.ts: isBypassed() already excludes null/<=0
maxConcurrency before ensureGate() is called, but a boolean-
returning helper isn't a type predicate TS can narrow through.
Added a targeted `as number` at the one call site, with a comment
explaining why it's safe.
- combo/comboStructure.ts: two module-scope `const HARD_COMPAT_REASONS`
declarations with different values — a genuine "can't redeclare"
compile error, not a narrowing gap. The first (4-item set including
"output_tokens") had zero usages between its own declaration and the
second; the second (3-item set, matching the CompatFilterOptions doc
comment exactly) is what hasHardCapabilityFailure/
describeCapabilityFilterExhaustion/the third call site all actually
use. Removed the dead first declaration.
- combo/comboStructure.ts + combo/fusionPanel.ts: both accessed
`.prompt`/`.model` on a `ComboModelStep | ComboProviderWildcardStep`
union after only excluding `combo-ref`, but `ComboProviderWildcardStep`
has neither field — a real latent bug (fusionPanel would have pushed
`undefined` into a fusion panel for a wildcard step). Narrowed to
`step.kind === "model"` in comboStructure, and switched to the
already-existing `getComboModelString()` helper in fusionPanel (which
correctly resolves to null for unsupported step kinds, mirroring how
combo-ref is already skipped there). Verified directly via a
standalone script exercising both branches (wildcard vs. model step).
- combo/quotaStrategies.ts: imported `preferAntigravityConnectionsWithStoredProject`
from a module that never existed (`../antigravityProjectPersistence.ts`,
distinct from the real `antigravityProjectPersist.ts`) — the function
itself was referenced nowhere else in the codebase. Wrote the missing
implementation: prefers Antigravity connections with a discovered
`projectId` for reset-aware routing, failing open to the full list
when none have one yet (per the file's own "Exclude... from reset-aware
pool" changelog note, softened to a preference — strict exclusion
would empty the pool entirely for a fleet of freshly-added accounts).
Verified directly via a standalone script.
- compression/engines/ccr/index.ts: `enforceGlobalBudget(owner, bytes)`
was called with only `bytes` at one of its two call sites, missing the
`owner` argument the other call site (and the function's own doc
comment on preferring the calling principal's LRU eviction) already
uses correctly. Added the missing `entry.principalId` argument.
- firecrawlQuotaFetcher.ts: `fetchFirecrawlQuota` was annotated to
return `Promise<QuotaInfo | null>` but every return path constructs a
`FirecrawlQuota` (QuotaInfo extended with remainingCredits/planCredits/
extraCreditsInferred/overPlan) — the type the file already defines and
the type `parseFirecrawlCreditUsage` already correctly returns.
Widened the annotation to match; `FirecrawlQuota extends QuotaInfo` so
this stays compatible with the `QuotaFetcher` contract.
npm run typecheck:core and npm run check:dashboard-typecheck both pass
cleanly. A subset of DB-backed tests in this area also fail, but 100%
attributably to an already-tracked, unrelated migration version
collision (134 -> [ccr_blocks, proxy_logs_egress_ip], see
_tasks/features-v3.8.4/9route/POST-MERGE-AUDIT.md) — confirmed by every
failure's stack trace bottoming out at that exact error, not at
anything touched here.
Two more release/v3.8.50 base-red items, both surfaced while chasing
CI failures on unrelated PRs:
- vi.json was missing 8 keys that #9539 (NewAPI/Sub2API aggregator
balance) added to en.json without a matching i18n:sync-ui run —
pt-BR.json already had all 8, only Vietnamese drifted. Added
translations for the 6 provider-settings strings, the feature-flag
description, and the quota tooltip; verified against
tests/unit/i18n-vi-completeness.test.ts (parity, placeholder
preservation, ICU parse — all 5 assertions pass).
- src/lib/db/migrations/120_interception_rules.sql was pure comments
documenting a no-schema-change key_value namespace, with no
executable SQL statement — the migration runner logged
"FAILED: 120_interception_rules — Query contained no valid SQL
statement" on every fresh DB init. 118_provider_param_filters.sql
(same pattern, two migrations earlier) already ends with a bare
`SELECT 1;` no-op for exactly this reason; 120 was just missing it.
Verified directly against better-sqlite3 that the file now executes
without error.
Unblocks Merge integrity and Docs Gates for every PR against
release/v3.8.50, not just this branch:
- changelog.d/features/9415-newapi-sub2api-aggregator-balance.md had a
non-standard YAML frontmatter header that no other fragment in the
tree uses. check-changelog-integrity.mjs reads a fragment's first
non-blank line to validate it starts with a markdown bullet; the
frontmatter's leading `---` made that check fail regardless of the
actual bullet content further down. Removed the frontmatter and
reformatted the body to match the documented changelog.d/README.md
bullet convention.
- docs/ops/VM_DEPLOYMENT_GUIDE.md documented OMNIROUTE_MAX_POOL_SIZE
and OMNIROUTE_DB_POOL_SIZE as tunable env vars, but neither is read
anywhere in the codebase (confirmed via full-repo grep) — this repo
uses SQLite, which has no connection-pool concept these vars could
plausibly control. check:fabricated-docs --strict correctly flags
fabricated env-var claims; removed the bullet rather than
implementing a feature to match invented documentation.