Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/fixes/15682-basereds-r2-membership-test.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- **fix(ci):** the quality-rail membership guard (G0) pins `cycles` in the fast-gates `ratchet_gates` array, completing the #15590 landing whose squash omitted the matching test update — every PR off `release/v3.8.52` was red on `Unit Tests (3/8)` + `fast-path (3/4)` over the stale gate-membership needle (#15682)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- **chore(skills):** refresh the `omni-auth` OIDC allowlist contract and `omni-settings` partial-update endpoint reference; these two mirror corrections do not claim to resolve unrelated generated-skill drift (#15682).
2 changes: 1 addition & 1 deletion docs/architecture/QUALITY_GATES.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ Runs on every PR to `main`. Blocks merge on failure.
| Script (`npm run ...`) | Validates | Blocking |
| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- |
| `check:node-runtime` | Node.js version is within the supported range | Yes |
| `check:cycles` | Circular imports across all of `src/` + `open-sse/` (AST-based, tsconfig `paths` resolved). Bare = advisory, lists the cycles. `check:cycles:ratchet` (what CI runs) blocks when the count exceeds the `metrics.cycles` ceiling in `quality-baseline.json` — currently 14, `direction: down`, so it can only fall (#15159 G-01/G-02) | Yes (ratchet) |
| `check:cycles` | Circular imports across all of `src/` + `open-sse/` (AST-based, tsconfig `paths` resolved). Bare exits 1 whenever any cycle exists (fail-closed since #15281) and lists the SCCs. `check:cycles:ratchet` (what CI runs) blocks when the count exceeds the `metrics.cycles` ceiling in `quality-baseline.json` — currently 14, `direction: down`, so it can only fall (#15159 G-01/G-02) | Yes (ratchet) |
| `check:route-validation:t06` | Zod schemas present on all routes (Tier 6 policy) | Yes |
| `check:any-budget:t11` | `@ts-expect-error // any` count does not exceed budget (Tier 11 catraca) | Yes |
| `check:provider-consistency` | Every provider in `providers.ts` has a matching entry in `providerRegistry.ts` (and vice-versa, within the allowlist) | Yes |
Expand Down
2 changes: 1 addition & 1 deletion docs/ops/RELEASE_CHECKLIST.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ matrix automatically, without any label.
- [ ] `npm run lint` — 0 errors (warnings are pre-existing)
- [ ] `npm run typecheck:core` — clean
- [ ] `npm run typecheck:noimplicit:core` — clean (strict)
- [ ] `npm run check:cycles` — no circular deps
- [ ] `npm run check:cycles:ratchet` — within the frozen `metrics.cycles` ceiling (bare `check:cycles` exits 1 on any cycle, #15281)
- [ ] `npm run check:any-budget:t11` — within budget
- [ ] `npm run check:route-validation:t06` — clean
- [ ] `npm run check:node-runtime` — supported runtime floor met (`>=22.22.2 <23`, `>=24.0.0 <27`, per `SUPPORTED_NODE_RANGE` in `src/shared/utils/nodeRuntimeSupport.ts`; aligned with `package.json` `engines`)
Expand Down
6 changes: 4 additions & 2 deletions scripts/check/check-cycles.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@
// counting them invents cycles that do not exist at runtime).
//
// Cycle count is a ratchet, not a hard zero: see config/quality/quality-baseline.json
// → metrics.cycles (G-02). `check:cycles` alone is advisory, `--ratchet` blocks.
// → metrics.cycles (G-02). Zero cycles exits 0 in every mode. With cycles present,
// plain mode exits 1 and `--ratchet` exits 1 above the ceiling or when the baseline
// is missing/invalid.

import fs from "node:fs";
import path from "node:path";
Expand Down Expand Up @@ -437,7 +439,7 @@ export function analyzeCycles(roots, cwd = process.cwd()) {

/**
* Read the `cycles` ceiling from quality-baseline.json.
* Missing/invalid baseline ⇒ null (advisory, no ceiling).
* Missing/invalid baseline ⇒ null (main() then exits 1 whenever any cycle exists).
*
* @param {string} [baselinePath]
* @returns {number | null}
Expand Down
6 changes: 3 additions & 3 deletions skills/omni-auth/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ curl https://localhost:20128/api/auth/oidc/login \
Complete OIDC login for the dashboard admin gate

Validates the `state` cookie, exchanges the authorization `code` for tokens,
verifies the ID token against the issuer's JWKS (audience = client id), and —
if `oidcAllowedSubjects` is configured — checks the token's `sub`/`email` against
that allowlist. On success it mints the same 30-day `auth_token` dashboard-session
verifies the ID token against the issuer's JWKS (audience = client id), and
checks the token's `sub`/`email` against `oidcAllowedSubjects`, which must hold at
least one entry (an empty list ends in `not_configured`). On success it mints the same 30-day `auth_token` dashboard-session
JWT used by password login and redirects to `/dashboard`.


Expand Down
2 changes: 2 additions & 0 deletions skills/omni-settings/references/endpoints.md
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,8 @@ curl https://localhost:20128/api/settings/compression \

Update global compression settings

Partial update: only the sent top-level keys change. `engines` merges by engine id — an entry overwrites only the fields it sends, engines left out are kept as-is, and until an engines row is stored the merge base is the map derived from the legacy per-engine settings.

```bash
curl -X PUT https://localhost:20128/api/settings/compression \
-H "Authorization: Bearer $OMNIROUTE_TOKEN" \
Expand Down
18 changes: 16 additions & 2 deletions tests/unit/quality-rail-gate-membership.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,29 @@ test("fast-gates carries the deterministic ratchets and security scanners from t
const block = jobBlock("fast-gates");
// #8542: all gates run inside a single aggregation step's bash loop.
// Check that the gate names appear in the arrays or the loop body.
// #15306: `cycles` moved to ratchet_gates — check-cycles.mjs exits 1 on ANY cycle
// without --ratchet (#15281), so fast-gates must run it with the frozen ceiling in
// quality-baseline.json, same as ci.yml's check:cycles:ratchet.
for (const needle of [
"cycles lockfile duplication dead-code type-coverage compression-budget",
"secrets vuln-ratchet workflows openapi-breaking",
"lockfile duplication dead-code type-coverage compression-budget",
"secrets vuln-ratchet workflows openapi-breaking cycles",
"typecheck:core",
"check:dashboard-typecheck",
"check:ts7-diagnostics-ratchet",
]) {
assert.ok(block.includes(needle), `fast-gates must contain "${needle}"`);
}
// The ratchet_gates move must be exclusive: a plain `cycles` entry would run
// check-cycles.mjs without --ratchet, which exits 1 on ANY cycle and fails
// every PR at the frozen 14-SCC ceiling (#15306). Pin the whole gates=(...)
// array, not just its current line, so a re-entry on any line trips the guard.
const plainGates = /\n(\s+)gates=\(([\s\S]*?)\n\1\)/.exec(block);
assert.ok(plainGates, "fast-gates must still carry the deterministic plain gates array");
assert.doesNotMatch(
plainGates[2],
/(^|\s)cycles(\s|$)/,
"cycles must not re-enter the plain gates array — it would run without --ratchet"
);
assert.ok(
block.includes(
"BASE_REF: ${{ github.base_ref && format('origin/{0}', github.base_ref) || '' }}"
Expand Down
Loading