Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
87 commits
Select commit Hold shift + click to select a range
7a098a0
chore(release): open v3.8.45 development cycle
diegosouzapw Jul 4, 2026
bb62c2a
chore(release): parallel-cycle flow — sync-next-cycle script + Hard R…
diegosouzapw Jul 4, 2026
0757503
perf(test): tsx/esm loader + tsx 4.23 + órfãos recuperados + CI via n…
diegosouzapw Jul 5, 2026
5a4bde1
ci: dedup heavy pipeline — compat to nightly, coverage folded into un…
diegosouzapw Jul 5, 2026
059dbe9
feat(quality): no-new-warnings por PR — ESLint bulk suppressions + li…
diegosouzapw Jul 5, 2026
1e59d14
docs(changelog): v3.8.45 bullets for the tests+quality+CI pipeline ov…
diegosouzapw Jul 5, 2026
2d5bd41
fix(api): stabilize relay SSRF-guard binding for minified builds (#61…
diegosouzapw Jul 5, 2026
c04ce38
fix(mcp): forward extra context through static tool loops (#6178) (#6…
diegosouzapw Jul 5, 2026
8cb7f00
fix(services): 9Router embed route + pre-spawn port probe (#6205) (#6…
diegosouzapw Jul 5, 2026
201908d
fix(backend): system-first memory injection for strict providers (#61…
diegosouzapw Jul 5, 2026
670d502
fix(auth): clear error for stale-key decryption failures (#6148) (#6226)
diegosouzapw Jul 5, 2026
cbc16af
fix(backend): record reasoning source for zero-metered reasoning mode…
diegosouzapw Jul 5, 2026
adde9e4
fix(providers): refresh stale NVIDIA NIM model registry (#6108) (#6223)
diegosouzapw Jul 5, 2026
1473261
fix(backend): distinct max_input_tokens for GPT-family models (#6191)…
diegosouzapw Jul 5, 2026
cf6c279
fix(oauth): extract keychain-import-only guard to restore file-size f…
diegosouzapw Jul 5, 2026
e44f125
fix(dashboard): stop model-test error freezing the page (React #31 ob…
diegosouzapw Jul 5, 2026
8a7b62e
fix(dashboard): remove the always-on Auto-Routing (combo) banner from…
diegosouzapw Jul 5, 2026
f2ad9b2
fix(cline): force upstream streaming for Cline/ClinePass (streaming-o…
diegosouzapw Jul 5, 2026
b3a2cfe
fix(providers): correct Kiro model catalog to real upstream ids (#6170)
diegosouzapw Jul 5, 2026
286fdf8
fix(sse): surface ChatGPT-web image silent-drop as an accurate error …
diegosouzapw Jul 5, 2026
6816bcd
fix(dashboard): providers page data-timeout guard + live-ws standalon…
diegosouzapw Jul 5, 2026
6a12ba0
fix(translator): strip reasoning param for nvidia z-ai/glm-5.2 (#6181)
kanztu Jul 5, 2026
0ed6780
fix: add nvidia to PROVIDER_TOOL_LIMITS (1536) to prevent tool trunca…
LuisAlejandroVega Jul 5, 2026
5e3a95b
feat(provider): add Claude 5 Sonnet to Claude Web provider (#6200) (#…
Iammilansoni Jul 5, 2026
b074c6d
fix(cli): detect POSIX auto-set HOSTNAME via os.hostname() to fix bin…
Theadd Jul 5, 2026
dc7eeba
feat(sse): surface Kiro adaptive-thinking reasoning as reasoning_cont…
VXNCXNX Jul 5, 2026
b1e2725
fix(chatcore): exempt opencode client from the default 128-tool trunc…
DKotsyuba Jul 5, 2026
e755c5a
fix(providers): refresh GitHub Copilot catalog (#6154)
backryun Jul 5, 2026
00c74ea
chore(quality): rebaseline kiro-translator file-size debt from #6213
diegosouzapw Jul 5, 2026
74546ed
fix(doctor): resolve two false-positive WARNs (#6162) (#6163)
arssnndr Jul 5, 2026
44e85a7
fix(doubao-web): switch provider to Dola global (#6235)
backryun Jul 5, 2026
b834c74
fix(providers): register zed in OAuth PROVIDERS to fix Unknown provid…
anki1kr Jul 5, 2026
5acfbe8
fix(oauth): align zed in OAUTH_PROVIDER_IDS + config enum after #6078…
diegosouzapw Jul 5, 2026
0585701
fix(mitm): strip colons from macOS cert fingerprint before keychain m…
rianonehub Jul 5, 2026
9b986fa
docs(architecture): sync stale DB-layer counts (45+/55 → 95+/110+) in…
diegosouzapw Jul 5, 2026
9827ae6
fix(api): count tool_use/tool_result/thinking blocks in count_tokens …
diegosouzapw Jul 5, 2026
9ebb53e
fix(antigravity): strip trailing assistant prefill turn for Vertex Cl…
diegosouzapw Jul 5, 2026
7e2b839
fix(security): require management auth for mutable cloud routes (#623…
Jul 5, 2026
0e0ca7e
fix(dashboard): use connection.id (UUID) not connection.provider (cat…
KooshaPari Jul 5, 2026
f26aa16
feat(rankings): add 'Configured Only' filter to Free Provider Ranking…
Iammilansoni Jul 5, 2026
c347abb
fix(i18n): add 118 missing Italian translations (#6212)
serverless83 Jul 5, 2026
58abebd
test(dashboard): realign #6145 onboarding-href guard to the #6166 hel…
diegosouzapw Jul 5, 2026
826a66f
feat(providers): add Yuanbao (web) cookie-session provider (#6196) (#…
diegosouzapw Jul 5, 2026
5531fc7
feat(providers): route built-in agentrouter through dynamic CC wire i…
diegosouzapw Jul 5, 2026
776a7a3
feat(providers): bulk-add API keys for Cloudflare Workers AI (#6174) …
diegosouzapw Jul 5, 2026
cefbcfb
feat(dashboard): routing/settings UX clarity — share %, Cloud Sync re…
diegosouzapw Jul 5, 2026
1044821
feat(combo): add option to disable session stickiness (#6168) (#6252)
diegosouzapw Jul 5, 2026
149b086
feat(docker): OMNIROUTE_NO_SUDO env flag for root-less MITM cert trus…
diegosouzapw Jul 5, 2026
9285dc1
feat(providers): add Requesty as an OpenAI-compatible gateway provide…
diegosouzapw Jul 5, 2026
4d330da
fix(providers): remove deprecated MiMo v2 entries (#6248)
backryun Jul 5, 2026
9899a6d
fix(github-skills): add missing import, add unit tests, fix settings …
Moseyuh333 Jul 5, 2026
f237c07
Fix/5976 continued (#6216)
hartmark Jul 5, 2026
fc16dcd
feat(dashboard): filter Free Provider Rankings by configured/availabl…
diegosouzapw Jul 5, 2026
143b7b1
ci: unblock test jobs from the Build gate (start at minute 0) (#6275)
diegosouzapw Jul 5, 2026
f35839f
ci(build): switch Next.js production build to Turbopack (1.9x faster)…
diegosouzapw Jul 5, 2026
046093b
feat(build): make Turbopack the default bundler for dev and build (#6…
diegosouzapw Jul 5, 2026
c26984e
feat(docker): build the image with Turbopack (v3.8.27 panic gone on N…
diegosouzapw Jul 5, 2026
bfd8a65
ci: opt-in self-hosted VPS runners for the release window (anti-queue…
diegosouzapw Jul 5, 2026
8a2b522
docs(changelog): restore v3.8.45/v3.8.44 sections eaten by the #6193 …
diegosouzapw Jul 5, 2026
faf68a2
fix(dashboard): null-guard connection in EditConnectionModal base-URL…
diegosouzapw Jul 5, 2026
509fd54
chore(release-green): clear test-masking + docs-all HARD reds for the…
diegosouzapw Jul 5, 2026
fecf888
fix(quality): clear the cycle's 11 net-new ESLint errors + make valid…
diegosouzapw Jul 5, 2026
bf1481f
fix(skills): generate the missing omni-github-skills registry entry +…
diegosouzapw Jul 5, 2026
265d93f
fix(combo): restrict the #6216 empty-stream failover to truly empty b…
diegosouzapw Jul 5, 2026
dc5ae96
chore(quality): prune stale ESLint suppressions (4,273 -> 4,233)
diegosouzapw Jul 5, 2026
f680aac
fix(proxy): #6246 stop the v3.8.44 proxy IP-leak + over-deactivation …
diegosouzapw Jul 5, 2026
b6ffe8c
fix(proxy): make "Test All" read-only + add bulk enable/disable (#624…
diegosouzapw Jul 5, 2026
ddd5464
fix(resilience): evict sticky affinity on pinned-account failover (#6…
diegosouzapw Jul 5, 2026
01ce92a
fix(sse): drop commentary-phase text in Responses passthrough (#6199)…
diegosouzapw Jul 5, 2026
234956d
fix: bug-fix sweep — log path, AgentBridge DNS, opencode-go headers, …
diegosouzapw Jul 5, 2026
8e33393
fix(docker): add id= to BuildKit cache mounts for strict builders (#6…
karimalsalah Jul 5, 2026
aabefc8
fix(sse): strip zero-width markers from streamed tool-call arguments …
DKotsyuba Jul 5, 2026
efc92c6
ci(quality): merge-integrity fast-gates + pre-flight hermetic mode (#…
diegosouzapw Jul 5, 2026
1ad8b3b
fix(a2a): finish the #6186 catalog-count update — 3 hardcoded 22s lef…
diegosouzapw Jul 5, 2026
5c953d1
fix(quality): type the 7 net-new 'as any' casts from #6292 (Lint red …
diegosouzapw Jul 5, 2026
dd12539
fix(api): Zod-validate POST /api/github-skills + document new gate en…
diegosouzapw Jul 5, 2026
ffe825b
fix(quality): clear the 2 remaining heavy-gate reds on the release tip
diegosouzapw Jul 6, 2026
6f41775
fix(security): 405 method-first for /api/keys/{id}/devices (dast-smok…
diegosouzapw Jul 6, 2026
6c1d597
fix(mitm): test suite and CI must never mutate the OS trust store (OM…
diegosouzapw Jul 6, 2026
b74c63a
ci(vps): hermetic nightly pre-flight on the release runner (descoped:…
diegosouzapw Jul 6, 2026
5ecca12
chore(quality): v3.8.45 cycle-close file-size rebaseline (Phase 0 dri…
diegosouzapw Jul 6, 2026
264dda7
chore(quality): v3.8.45 cycle-close cognitive/cyclomatic rebaseline (…
diegosouzapw Jul 6, 2026
60a3e08
docs(changelog): v3.8.45 reconciliation — fold Unreleased into the ve…
diegosouzapw Jul 6, 2026
cc2f19a
chore(release): v3.8.45 — 2026-07-06
diegosouzapw Jul 6, 2026
adede73
fix(resilience): 502/503/504 keep the connection-unavailability path …
diegosouzapw Jul 6, 2026
7a14a96
fix(security): crypto-backed randomNumericId in doubao-web (CodeQL js…
diegosouzapw Jul 6, 2026
ba71a68
chore(quality): shave the #5976 fix comment back under the auth.ts fi…
diegosouzapw Jul 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
38 changes: 37 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,13 @@ OMNIROUTE_USE_TURBOPACK=1
# Hostname/bind address for the Next.js server.
# Used by: scripts/dev/run-next.mjs (HOST), Playwright runner (HOSTNAME).
# Default: 0.0.0.0 (HOST) / 127.0.0.1 (HOSTNAME inside tests).
# NOTE: Do NOT use `HOSTNAME` — it is a POSIX shell variable automatically set to
# the machine name by bash/zsh. The .env loader cannot override it (first-wins
# semantics). Use OMNIROUTE_SERVER_HOST instead for `omniroute serve`.
# See: https://github.com/diegosouzapw/OmniRoute/issues/6194
#HOST=0.0.0.0
#HOSTNAME=127.0.0.1
#OMNIROUTE_SERVER_HOST=0.0.0.0

# Environment mode — affects Next.js behavior, logging verbosity, and caching.
# Values: production | development | Default: production
Expand Down Expand Up @@ -493,6 +498,18 @@ NEXT_PUBLIC_CLOUD_URL=
#OPENCODE_GO_AUTH_COOKIE=auth=...
#OMNIROUTE_OPENCODE_GO_AUTH_COOKIE=auth=...

# OpenCode Go/Zen VPS egress (#5997): on a datacenter VPS, Cloudflare in front of
# opencode.ai/zen/go 403s chat requests that lack OpenCode CLI identity headers.
# When your clients don't already send them, set this to synthesize the CLI headers
# (User-Agent, x-opencode-client, x-opencode-project, fresh request/session UUIDs) on
# absent keys. OFF by default — forward-only is safer when clients already send them.
# Values are overridable via OPENCODE_GO_USER_AGENT / OPENCODE_USER_AGENT / OPENCODE_CLIENT /
# OPENCODE_PROJECT (defaults: opencode-cli/1.0.0 / cli / default).
#OPENCODE_SYNTHESIZE_CLI_HEADERS=true
#OPENCODE_USER_AGENT=opencode-cli/1.0.0
#OPENCODE_CLIENT=cli
#OPENCODE_PROJECT=default

# Ollama Cloud quota scraping. Prefer configuring this per connection in
# Dashboard → Providers → Ollama Cloud. The cookie is sensitive.
#OLLAMA_USAGE_COOKIE=__Secure-session=...
Expand Down Expand Up @@ -1181,7 +1198,7 @@ CURSOR_USER_AGENT="Cursor/3.4"
APP_LOG_TO_FILE=true

# Path to the application log file.
# Default: logs/application/app.log (relative to project root / DATA_DIR)
# Default: <DATA_DIR>/logs/application/app.log (DATA_DIR defaults to ~/.omniroute)
# APP_LOG_FILE_PATH=logs/application/app.log

# Maximum single log file size before rotation.
Expand Down Expand Up @@ -1516,6 +1533,11 @@ APP_LOG_TO_FILE=true
# PROXY_AUTO_REMOVE=false
# Consecutive failures before an auto-remove fires. Default: 3.
# PROXY_AUTO_REMOVE_AFTER=3
# Let automated reachability probes (the scheduler + the "Test All" button) WRITE
# a proxy's status. Default "false": probes are read-only and never deactivate a
# proxy — only the operator sets active/inactive (a flaky probe must not strand an
# assigned proxy; #6246). Set "true" to restore the legacy test-and-set behaviour.
# PROXY_HEALTH_AUTO_DEACTIVATE=false

# Allow OAuth and provider validation flows to bypass a pinned proxy and connect
# directly when proxy reachability pre-checks fail. Default: false.
Expand Down Expand Up @@ -1698,6 +1720,20 @@ APP_LOG_TO_FILE=true
# Routing-decision log verbosity: 0 silences, higher values log more bypass/route
# decisions (src/mitm/server.cjs, _internal/bypass.cjs).
# MITM_VERBOSE=1
# Strip the leading `sudo` from MITM cert-trust commands (src/mitm/systemCommands.ts) —
# for root-less / user-namespaced deployments (e.g. rootless Docker/Podman)
# where the operator trusts the CA manually (e.g. via Node's extra-CA-certs mechanism).
# OMNIROUTE_NO_SUDO=0

# ── Test/CI-only guards (never needed in production) ──
# Set automatically by tests/_setup/isolateDataDir.ts and the CI workflows: the
# test suite must NEVER mutate the OS trust store (a fake test PEM installed via
# update-ca-certificates broke all system TLS on a persistent runner, 2026-07-05).
# OMNIROUTE_SKIP_SYSTEM_TRUST=1
# check-changelog-integrity.mjs (anti CHANGELOG-eat gate): explicit base ref
# override, and the justified-removal escape hatch for intentional bullet removals.
# CHANGELOG_BASE_REF=origin/release/v0.0.0
# ALLOW_CHANGELOG_REMOVALS=1

# ── 1Proxy egress pool ──
# Used by: src/lib/oneproxySync.ts — fetches proxy nodes from the OmniRoute
Expand Down
318 changes: 129 additions & 189 deletions .github/workflows/ci.yml

Large diffs are not rendered by default.

126 changes: 126 additions & 0 deletions .github/workflows/nightly-compat.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
name: Nightly Node Compat

# Plano mestre testes+CI (Eixo D2, aprovado 2026-07-04): as matrizes de compatibilidade
# Node 24/26 custavam ~28% de CADA run do CI pesado (2 execuções completas da suíte por
# sync da release-PR) para pegar uma classe de quebra que raramente nasce num PR típico.
# Elas rodam aqui 1×/dia contra o tip da release ativa (mesmo alvo do nightly-release-green)
# e continuam obrigatórias no gate de release via workflow_dispatch do ci.yml se preciso.
# fail-fast desligado: numa quebra queremos saber TODAS as versões afetadas de uma vez.

on:
schedule:
- cron: "47 6 * * *" # 06:47 UTC diário — slot distinto dos demais nightlies
workflow_dispatch:
inputs:
branch:
description: "Branch to validate (default: highest release/vX.Y.Z)"
required: false
type: string

permissions:
contents: read
issues: write

concurrency:
group: nightly-compat
cancel-in-progress: true

jobs:
resolve-branch:
name: Resolve active release branch
runs-on: ubuntu-latest
outputs:
target: ${{ steps.branch.outputs.target }}
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0
persist-credentials: false
- name: Resolve active release branch
id: branch
env:
INPUT_BRANCH: ${{ github.event.inputs.branch }}
run: |
set -euo pipefail
if [ -n "${INPUT_BRANCH:-}" ]; then
TARGET="$INPUT_BRANCH"
else
TARGET=$(git for-each-ref --format='%(refname:short)' 'refs/remotes/origin/release/v*' \
| sed 's#origin/##' \
| sort -t/ -k2 -V \
| tail -1)
fi
case "$TARGET" in
release/v[0-9]*.[0-9]*.[0-9]*) ;;
*) echo "Refusing non-canonical branch name: $TARGET"; exit 1 ;;
esac
echo "target=$TARGET" >> "$GITHUB_OUTPUT"

compat-build-26:
name: Node 26 Compatibility Build
runs-on: ubuntu-latest
timeout-minutes: 25
needs: resolve-branch
steps:
- uses: actions/checkout@v7
with:
ref: ${{ needs.resolve-branch.outputs.target }}
persist-credentials: false
- uses: actions/setup-node@v6
with:
node-version: "26"
cache: npm
- uses: ./.github/actions/npm-ci-retry
- run: npm run build

compat-tests:
name: Node ${{ matrix.node }} Compat Tests (${{ matrix.shard }}/4)
runs-on: ubuntu-latest
timeout-minutes: 25
needs: resolve-branch
strategy:
fail-fast: false
matrix:
node: [24, 26]
shard: [1, 2, 3, 4]
env:
JWT_SECRET: ci-nightly-secret-with-sufficient-length-for-validation
API_KEY_SECRET: ci-nightly-api-key-secret-long
DISABLE_SQLITE_AUTO_BACKUP: "true"
TEST_SHARD: ${{ matrix.shard }}/4
steps:
- uses: actions/checkout@v7
with:
ref: ${{ needs.resolve-branch.outputs.target }}
persist-credentials: false
- uses: actions/setup-node@v6
with:
node-version: ${{ matrix.node }}
cache: npm
- uses: ./.github/actions/npm-ci-retry
- run: npm run check:node-runtime
- run: npm run test:unit:ci:shard

report:
name: Open / update tracking issue on failure
runs-on: ubuntu-latest
if: ${{ !cancelled() && (needs.compat-tests.result == 'failure' || needs.compat-build-26.result == 'failure') }}
needs: [resolve-branch, compat-build-26, compat-tests]
permissions:
issues: write
steps:
- name: Open or update issue
env:
GH_TOKEN: ${{ github.token }}
TARGET: ${{ needs.resolve-branch.outputs.target }}
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
run: |
set -euo pipefail
TITLE="🌙 nightly-compat: Node 24/26 failures on $TARGET"
EXISTING=$(gh issue list --repo "$GITHUB_REPOSITORY" --state open --search "$TITLE in:title" --json number --jq '.[0].number')
BODY="Nightly Node-compat run failed on \`$TARGET\`: $RUN_URL — triage which Node version/shard broke (fail-fast off, all versions reported)."
if [ -n "$EXISTING" ]; then
gh issue comment "$EXISTING" --repo "$GITHUB_REPOSITORY" --body "$BODY"
else
gh issue create --repo "$GITHUB_REPOSITORY" --title "$TITLE" --body "$BODY"
fi
13 changes: 11 additions & 2 deletions .github/workflows/nightly-release-green.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,17 @@ concurrency:
group: nightly-release-green
cancel-in-progress: true

env:
OMNIROUTE_SKIP_SYSTEM_TRUST: "1"

jobs:
release-green:
name: Validate active release branch
runs-on: ubuntu-latest
# Dynamic runner: with USE_VPS_RUNNER=true (release window / on-demand pre-flight)
# this runs on the dedicated VPS runner — clean env (no operator OMNIROUTE_API_KEY,
# no local noauth CLIs => zero machine-specific false positives) and no contention.
# Nightly cron normally finds the var false (VM off) and falls back to hosted.
runs-on: ${{ (vars.USE_VPS_RUNNER == 'true' && fromJSON('["self-hosted","omni-release"]')) || 'ubuntu-latest' }}
env:
JWT_SECRET: ci-nightly-secret-with-sufficient-length-for-validation
API_KEY_SECRET: ci-nightly-api-key-secret-long
Expand Down Expand Up @@ -88,7 +95,9 @@ jobs:
id: validate
run: |
set +e
node scripts/quality/validate-release-green.mjs --json --with-build \
# --hermetic: scrub live-test trigger vars (self-hosted runner may carry
# operator env; hosted ignores the unknown flag before #6300 lands).
node scripts/quality/validate-release-green.mjs --json --with-build --hermetic \
1> release-green.json 2> release-green.log
echo "exit=$?" >> "$GITHUB_OUTPUT"
echo "------- report -------"
Expand Down
80 changes: 73 additions & 7 deletions .github/workflows/quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ permissions:
contents: read

env:
# CI must never mutate the runner's OS trust store (2026-07-05: a cert-flow
# test installed a fake PEM on a persistent self-hosted runner and broke all
# system TLS). Belt-and-suspenders with tests/_setup/isolateDataDir.ts.
OMNIROUTE_SKIP_SYSTEM_TRUST: "1"
CI_NODE_VERSION: "24"

jobs:
Expand Down Expand Up @@ -100,7 +104,7 @@ jobs:
fi
echo "Running impacted tests:"; echo "$SEL"
mapfile -t FILES <<< "$SEL"
node --import tsx --import ./open-sse/utils/setupPolyfill.ts --import ./tests/_setup/isolateDataDir.ts --test --test-force-exit --test-concurrency=4 "${FILES[@]}"
node --import tsx/esm --import ./open-sse/utils/setupPolyfill.ts --import ./tests/_setup/isolateDataDir.ts --test --test-force-exit --test-concurrency=4 "${FILES[@]}"

fast-vitest:
name: Vitest (fast-path)
Expand Down Expand Up @@ -140,9 +144,71 @@ jobs:
node-version: ${{ env.CI_NODE_VERSION }}
cache: npm
- run: npm ci
- run: >
node --max-old-space-size=4096 --import tsx
--import ./tests/_setup/isolateDataDir.ts
--test --test-force-exit --test-concurrency=4 --test-shard=${{ matrix.shard }}/2
tests/unit/*.test.ts
"tests/unit/{api,auth,authz,build,cli,cli-helper,combo,compression,correctness,cors,dashboard,db,db-adapters,docs,executors,gamification,guardrails,lib,mcp,runtime,security,services,settings,shared,ui}/**/*.test.ts"
# QW-d: fonte única — o mesmo npm script do CI pesado/local. Fecha dois drifts do
# comando inline antigo: os dirs `memory` e `usage` estavam FORA do glob (testes
# silenciosamente não rodavam no fast path) e o setupPolyfill não era importado.
- run: npm run test:unit:ci:shard
env:
TEST_SHARD: ${{ matrix.shard }}/2

# ── Pacote 4 (plano mestre testes+CI, aprovado 2026-07-04) ─────────────────────────
# No-new-warnings por PR via ESLint bulk suppressions nativo (>=9.24). O baseline
# config/quality/eslint-suppressions.json congela as violações EXISTENTES por
# arquivo+regra; qualquer warning NOVO aparece e o --max-warnings 0 falha o job — o
# drift de +41/+88 warnings por ciclo passa a morrer no PR que o introduz, em vez de
# ser rebaselinado às cegas na release. Aperto do baseline (na reconciliação da
# release): npx eslint . --prune-suppressions --suppressions-location config/quality/eslint-suppressions.json
#
# Princípio Zero: bloqueante SÓ para branches internas (as campanhas/sessões são a
# origem do drift). PR de FORK roda em modo report (continue-on-error → o job fica
# verde com anotação; a campanha /green-prs aplica o fix via co-autoria — o
# contribuidor NUNCA é bloqueado nem cobrado).
lint-guard:
name: No new ESLint warnings
runs-on: ubuntu-latest
continue-on-error: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == true }}
steps:
- uses: actions/checkout@v7
with:
persist-credentials: false
- uses: actions/setup-node@v6
with:
node-version: ${{ env.CI_NODE_VERSION }}
cache: npm
- run: npm ci
- name: ESLint (baseline congelado — warning novo = vermelho)
run: npx eslint . --suppressions-location config/quality/eslint-suppressions.json --max-warnings 0

# Merge-integrity: pega no PR os dois vazamentos crônicos de merge que hoje só
# explodem na release-PR. (1) CHANGELOG-eat — o auto-resolve do merge come
# bullets vizinhos/seções inteiras (incidente #6193, 2026-07-05: 212 linhas /
# 130 bullets); o checkout de PR é refs/pull/N/merge, então comparar contra a
# base detecta o eat ANTES do merge. (2) SKILL.md gerado stale vs o catálogo de
# agent-skills (#6186 mergeou um id de catálogo sem rodar o gerador → 8 reds de
# integration invisíveis até a release).
#
# Princípio Zero: bloqueante SÓ para branches internas; PR de FORK roda em modo
# report (continue-on-error) — a campanha corrige via co-autoria, o contribuidor
# nunca é bloqueado.
merge-integrity:
name: Merge integrity (changelog + generated skills)
runs-on: ubuntu-latest
continue-on-error: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == true }}
env:
JWT_SECRET: ci-lint-secret-with-sufficient-length-for-validation
API_KEY_SECRET: ci-lint-api-key-secret-long
DISABLE_SQLITE_AUTO_BACKUP: "true"
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
with:
fetch-depth: 0
persist-credentials: false
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
node-version: ${{ env.CI_NODE_VERSION }}
cache: npm
- run: npm ci
- name: CHANGELOG integrity (nenhum bullet da base pode sumir no merge-result)
run: npm run check:changelog-integrity
- name: Agent-skills generator sync (SKILL.md gerado ≡ catálogo)
run: npm run check:agent-skills-sync
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -232,3 +232,4 @@ omniroute.md

# mise configuration
mise.toml
_artifacts/
Loading
Loading