Skip to content

Commit b84adf9

Browse files
authored
ci: add base-governed PR size exception registry (#540)
* ci: add base-governed PR size exception registry * test: isolate local PR-size fixtures from CI event identity * fix: reconcile PR-size exception review findings * docs: refresh test count after governance coverage * refactor: close governance review nitpicks
1 parent ca2f364 commit b84adf9

5 files changed

Lines changed: 779 additions & 24 deletions

File tree

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
<img src="https://img.shields.io/badge/Storage-IndexedDB_v8-F59E0B" alt="IndexedDB v8">
1414
<img src="https://img.shields.io/badge/PWA-v3.0-5BB974?logo=pwa" alt="PWA v3.0">
1515
<img src="https://img.shields.io/badge/i18n-19_locales-2925_keys-0EA5E9" alt="i18n 19 locales — 2925 keys">
16-
<img src="https://img.shields.io/badge/Tests-7205%2B_%2F_589_files-22C55E" alt="7205+ tests / 589 files">
16+
<img src="https://img.shields.io/badge/Tests-7219%2B_%2F_589_files-22C55E" alt="7219+ tests / 589 files">
1717
<img src="https://img.shields.io/codecov/c/github/qnbs/WorldScript-Studio?logo=codecov&label=Coverage" alt="Codecov Coverage">
1818
<img src="https://img.shields.io/badge/License-MIT-22C55E" alt="License MIT">
1919
<img src="https://img.shields.io/github/actions/workflow/status/qnbs/WorldScript-Studio/.github/workflows/ci.yml?branch=main&logo=github" alt="CI Status">
@@ -511,7 +511,7 @@ The Settings → AI panel shows a live GPU status badge with adapter details and
511511
| **Document Export** | docx + jszip | Word-compatible `.docx` generation (lazy-loaded) |
512512
| **PWA** | Service Worker + Web App Manifest v3 | Offline support, installability, Workbox chunking |
513513
| **i18n** | Custom React Context (`I18nContext.tsx`) | 2925 keys × 19 locales (de/en/es/fr/it + ar/he/fa RTL Beta + ja/zh/pt/el/fi/sv/hu/is/eu/ru/ko Beta); EN fallback; `localStorage` persistence |
514-
| **Testing** | Vitest 4.x (7205+ tests / 589 files) + Playwright E2E | Unit/integration + cross-browser E2E; Stryker mutation (manual workflow) |
514+
| **Testing** | Vitest 4.x (7219+ tests / 589 files) + Playwright E2E | Unit/integration + cross-browser E2E; Stryker mutation (manual workflow) |
515515
| **Code Quality** | Biome (lint + format) + TypeScript 7 (tsgo) strict | `--error-on-warnings` in CI; zero `any` policy |
516516
| **Visualization** | Force-directed graph | Interactive character relationship network |
517517
| **Desktop** | Tauri v2 | Cross-platform installer; auto-updater via `latest.json` |
@@ -549,7 +549,7 @@ WorldScript-Studio/
549549
│ ├── sw.js # PWA Service Worker
550550
│ └── manifest.json # PWA Web App Manifest v3
551551
├── tests/
552-
│ ├── unit/ # Vitest unit tests (7205+ tests, 589 files) — count spans tests/, components/, packages/*/tests/, not just this folder
552+
│ ├── unit/ # Vitest unit tests (7219+ tests, 589 files) — count spans tests/, components/, packages/*/tests/, not just this folder
553553
│ │ ├── ai/ # aiSmallModules, aiCoreFallbackPaths
554554
│ │ └── settings/ # WebLlmPanel, AiSections
555555
│ └── e2e/ # Playwright specs + helpers.ts
@@ -711,7 +711,7 @@ The main pipeline is [`.github/workflows/ci.yml`](.github/workflows/ci.yml). Opt
711711
| `scorecard` | weekly + `main` push | OpenSSF Scorecard — SARIF uploaded to GitHub Code Scanning |
712712

713713
**Current test metrics (2026-08-27, source-synchronized; CI remains authoritative for pass/fail):**
714-
- **7205+ unit tests** across **589 test files** — CI is authoritative for pass/fail
714+
- **7219+ unit tests** across **589 test files** — CI is authoritative for pass/fail
715715
- Coverage thresholds: lines ≥ 80 · branches ≥ 66 · functions ≥ 72 · statements ≥ 78 — enforced in CI (see Codecov badge for live metrics)
716716
- i18n: **2925 keys × 19 locales** (en/de/fr/es/it + ar/he/fa RTL Beta + ja/zh/pt/el/fi/sv/hu/is/eu/ru/ko Beta)
717717

config/pr-size-exceptions.json

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
{
2+
"schemaVersion": 1,
3+
"exceptions": [
4+
{
5+
"id": "pr-539-dual-graph-report-regeneration",
6+
"repository": "qnbs/WorldScript-Studio",
7+
"prNumber": 539,
8+
"baseRef": "main",
9+
"headRef": "chore/dual-graph-solo-local-optimization",
10+
"maxFiles": 30,
11+
"maxCommits": 15,
12+
"maxNonExemptMeaningfulLines": 3000,
13+
"supplementalLineAllowances": [
14+
{
15+
"path": "graphify-out/GRAPH_REPORT.md",
16+
"maxMeaningfulLines": 5050
17+
},
18+
{
19+
"path": ".codegraph/CODEGRAPH_REPORT.md",
20+
"maxMeaningfulLines": 150
21+
}
22+
],
23+
"allowedPaths": [
24+
".codegraph/CODEGRAPH_REPORT.md",
25+
".gitignore",
26+
".graphifyignore",
27+
".vscode/tasks.json",
28+
"AUDIT.md",
29+
"CLAUDE.md",
30+
"README.md",
31+
"config/graph-tools-versions.json",
32+
"docs/codegraph.md",
33+
"docs/dual-graph-setup.md",
34+
"docs/graphify.md",
35+
"graphify-out/GRAPH_REPORT.md",
36+
"package.json",
37+
"scripts/codegraph-bootstrap.mjs",
38+
"scripts/codegraph-report.d.mts",
39+
"scripts/codegraph-report.mjs",
40+
"scripts/dual-graph-update.mjs",
41+
"scripts/graphSourceFingerprint.d.mts",
42+
"scripts/graphSourceFingerprint.mjs",
43+
"scripts/graphify-bootstrap.mjs",
44+
"scripts/graphify-report.mjs",
45+
"scripts/graphs-cli.mjs",
46+
"scripts/pre-commit-codegraph.mjs",
47+
"tests/unit/scripts/codegraphReport.test.ts",
48+
"tests/unit/scripts/graphSourceFingerprint.test.ts",
49+
"turbo.json"
50+
],
51+
"reason": "One-time deterministic replacement of stale committed graph reports; executable tooling remains governed by the ordinary absolute meaningful-line ceiling."
52+
}
53+
]
54+
}

scripts/check-pr-size.d.mts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ export interface GitDependencies {
44
args: string[],
55
options: { encoding: 'utf8' },
66
) => { status: number | null; stdout: string; stderr: string; error?: Error };
7+
readFileSync?: (path: string, encoding: 'utf8') => string;
8+
existsSync?: (path: string) => boolean;
9+
writeFileSync?: (path: string, content: string) => void;
10+
unlinkSync?: (path: string) => void;
11+
env?: NodeJS.ProcessEnv;
712
}
813

914
export function getChangedFilesNumstat(
@@ -28,6 +33,35 @@ export function parseNumstat(numstatOutput: string): NumstatRow[];
2833

2934
export function computeMeaningfulLines(rows: NumstatRow[]): number;
3035

36+
export interface SupplementalLineAllowance {
37+
path: string;
38+
maxMeaningfulLines: number;
39+
}
40+
41+
export interface PrSizeException {
42+
id: string;
43+
repository: string;
44+
prNumber: number;
45+
baseRef: string;
46+
headRef: string;
47+
maxFiles: number;
48+
maxCommits: number;
49+
maxNonExemptMeaningfulLines: number;
50+
supplementalLineAllowances: SupplementalLineAllowance[];
51+
allowedPaths: string[];
52+
reason: string;
53+
}
54+
55+
export function computeNonExemptMeaningfulLines(
56+
rows: NumstatRow[],
57+
exception?: PrSizeException,
58+
): number;
59+
60+
export function computeSupplementalReportLines(
61+
rows: NumstatRow[],
62+
exception: PrSizeException,
63+
): Record<string, number>;
64+
3165
export function computeGovernedFileCount(rows: NumstatRow[]): number;
3266

3367
export function isAllDocs(rows: NumstatRow[]): boolean;
@@ -70,6 +104,15 @@ export interface PrSizeEvaluation {
70104
lineCount?: number;
71105
commitCount?: number;
72106
allDocs?: boolean;
107+
nonExemptLineCount?: number;
108+
supplementalReportLines?: Record<string, number>;
109+
exception?: {
110+
applied: boolean;
111+
id?: string;
112+
identityMatch: boolean;
113+
pathScopeMatch: boolean;
114+
baseGoverned: boolean;
115+
};
73116
severity?: SizeSeverity;
74117
report?: string;
75118
}

0 commit comments

Comments
 (0)