diff --git a/.github/CI-AUDIT.md b/.github/CI-AUDIT.md index 40d063480..62b7bd7d9 100644 --- a/.github/CI-AUDIT.md +++ b/.github/CI-AUDIT.md @@ -31,7 +31,7 @@ This document summarizes the **current inventory** and **stabilization measures* | pnpm | `package.json` `packageManager` | **11.5.2** | | Lint | Biome | `pnpm run lint` | | i18n | `scripts/check-i18n-keys.mjs` | `pnpm run i18n:check` | -| Unit | Vitest + V8 | `pnpm exec vitest run --coverage` | +| Unit | Vitest + V8 | CI: `pnpm exec vitest run --coverage`; local: targeted `pnpm exec vitest run ` | | E2E | Playwright | `CI=true pnpm run test:e2e` | | Bundle | `scripts/check-bundle-budget.mjs` | max **7000 KB** per chunk, max **4500 KB** entry (`index-*.js`) | | Lighthouse | `.lighthouserc.cjs` | Accessibility **error** ≥ 0.95; CLS **error** ≤ 0.1; Performance **warn** | @@ -54,7 +54,7 @@ This document summarizes the **current inventory** and **stabilization measures* ```bash pnpm run lint && pnpm run i18n:check && pnpm run typecheck -# optional: pnpm exec vitest run # without --coverage +# optional targeted file: pnpm exec vitest run ``` **Heavy (CI parity):** diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index e7269ec54..8964bc794 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -170,6 +170,7 @@ On any non-trivial code change add a single-line comment explaining **why**, not - Pre-commit: after explicit `pnpm run hooks:install`, `simple-git-hooks` runs Biome on staged files; CI is mandatory regardless - **⚠️ Constrained local hardware — do NOT run heavy suites locally.** This machine has ~3–4 GB RAM. **Never** run the full Vitest **coverage** suite, **Playwright E2E**, **Stryker mutation**, **Lighthouse CI**, or the **Storybook test-runner** locally — they are **CI-only by design**. Run **one heavy command at a time** (no parallel `vitest`/`biome`/`tsc`/`vite`). - Local preflight (sequential, minimal): `pnpm run lint` → `pnpm run typecheck` → `pnpm run i18n:check` (only when locale JSON changed) → **targeted** `pnpm exec vitest run ` (no `--coverage`). Run `pnpm run build && pnpm run smoke:prod` only when you touched `vite.config.ts`, `packages/ai-core`, or `workers/`. Coverage, E2E, Lighthouse, Stryker, and Storybook are **CI gate jobs** — let GitHub Actions run them. +- **Vitest watch-mode hard rule:** Never run `pnpm test`, `npm run test`, a bare Vitest command, or an untargeted wrapper. Always use `pnpm exec vitest run `; CI is the only place that runs the full coverage suite. - CI pipeline (see [`docs/CI.md`](../docs/CI.md)): **`security` → `quality`** (Biome + `tsc` + Vitest matrix) **→ `build` / `e2e` / `storybook` in parallel** → **`lighthouse`** after build → **`deploy`** on `main` after build+e2e - Branch protection should require the **`quality`** job (and other checks your team enables); job ids match `.github/workflows/ci.yml` - CI runs **`pnpm audit`** every workflow; **dependency-review** on pull requests @@ -200,9 +201,10 @@ pnpm run lint # Biome lint check pnpm run lint:fix # Biome auto-fix (lint + format) pnpm run format # Biome format pnpm run typecheck # TypeScript type checking (tsc --noEmit) -pnpm run test # Vitest watch mode -pnpm run test:run # Vitest single run -pnpm run test:coverage # Vitest with V8 coverage +pnpm exec vitest run # Targeted Vitest single run +pnpm exec vitest run --coverage \ + --coverage.thresholds.lines=0 --coverage.thresholds.functions=0 \ + --coverage.thresholds.branches=0 --coverage.thresholds.statements=0 # Targeted coverage debugging pnpm run test:e2e # Playwright E2E (requires CI=true per package.json scripts) pnpm run storybook # Storybook on port 6006 ``` diff --git a/CHANGELOG.md b/CHANGELOG.md index a0c97229b..5d97722f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,9 +7,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- **Renderer-neutral Rust Core seed:** `crates/worldscript-project` now provides headless project + schema, validation, migration, plain JSON I/O, and a test/CLI harness, with one narrow Tauri + validation command wired through the cross-workspace path dependency. + +### Changed + +- **Native desktop strategy:** ADR-0021 adopts Qt 6/Qt Quick as the future primary native product, + keeps React/PWA first-class, makes Tauri transitional, admits GPUI later behind a gate, and + retires CEF from the target architecture. +- **DesktopPlatform boundary:** direct Tauri imports are mechanically constrained by the zero- + tolerance guardrail while the renderer-neutral contract becomes the native transition surface. + ### Fixed - **CI authority closure:** Core path changes now select the Tauri consumer gate, workflow-policy tests protect local path-dependency coverage and aggregate deployment gating, and Pages deployment waits for `ci-success`. +- **Accessibility contrast:** command-palette heading contrast was corrected to meet the intended + WCAG threshold. + +### Security + +- **CI supply-chain policy:** CodeQL action references and token permissions were hardened and + Dependabot grouping was corrected so related action paths move together. ## [1.27.1] — 2026-08-14 @@ -329,7 +350,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 DuckDB excerpt-encryption wiring above, and the Claude serverless proxy section gains an explicit monitoring recommendation (platform-native Vercel/Cloudflare request analytics — no in-app logging, which would violate the proxy's zero-console-call stateless guarantee). -- **`GROK-PROVIDER-INTEGRATION-PLAN.md`** status header updated from "Plan only — do not implement +- **`docs/history/GROK-PROVIDER-INTEGRATION-PLAN.md`** status header updated from "Plan only — do not implement yet" to reflect that all phases shipped; retained as the historical design record. - **`TODO.md`** reworded the open tag/publish bullet so it no longer embeds the literal `v1.25.0` version string on the `- ⬜` bullet line itself, removing the risk that diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0046be278..13244cfaf 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -200,7 +200,8 @@ Coverage, E2E, Lighthouse, Stryker, and Storybook test-runner are **CI gate jobs ### Local vs CI (low-end friendly) -- **Before every push (recommended):** `pnpm run lint`, `pnpm run typecheck`, `pnpm run i18n:check`. Optional: `pnpm exec vitest run` **without** `--coverage` for a quick smoke. +- **Before every push (recommended):** `pnpm run lint`, `pnpm run typecheck`, `pnpm run i18n:check`. Optional: targeted `pnpm exec vitest run ` for a quick smoke. +- **Vitest hard rule:** Never invoke `pnpm test`, `npm run test`, or a bare Vitest wrapper; watch mode hangs constrained hardware. Use an explicit targeted `pnpm exec vitest run ` command. - **Full gate:** GitHub Actions runs Vitest **with** coverage thresholds, Playwright (desktop + mobile emulation in CI), Lighthouse, etc. A **green CI run** is the merge bar — you are **not** required to pass full E2E or LHCI on a weak laptop. - **Optional local E2E:** `CI=true pnpm run test:e2e` when debugging; optional mobile project: `RUN_MOBILE_E2E=1` (see [`docs/CI.md`](docs/CI.md)). - **CI artifacts:** When Playwright, coverage, or Lighthouse fails remotely, open **GitHub Actions → the workflow run → Artifacts** and inspect the uploaded reports locally — faster than reproducing the full heavy stack on low-end hardware. @@ -208,9 +209,10 @@ Coverage, E2E, Lighthouse, Stryker, and Storybook test-runner are **CI gate jobs ### Unit Tests (Vitest) ```bash -pnpm run test # Run in watch mode -pnpm run test:run # Run once (CI mode) -pnpm run test:coverage # With coverage report (same as CI quality job — heavier) +pnpm exec vitest run # Targeted single-file run +pnpm exec vitest run --coverage \ + --coverage.thresholds.lines=0 --coverage.thresholds.functions=0 \ + --coverage.thresholds.branches=0 --coverage.thresholds.statements=0 # Targeted coverage debugging ``` ### Bundle size (matches CI `build` job) @@ -228,7 +230,7 @@ On **2–4 GB RAM** (e.g. Ubuntu 20.04), use the bundled **act + Eco-Forgejo** s - **Install:** [`infra/low-end-ci/INSTALL.md`](infra/low-end-ci/INSTALL.md) - **Daily workflow:** [`infra/low-end-ci/DAILY-DRIVER.md`](infra/low-end-ci/DAILY-DRIVER.md) -- **Quick gate (no Docker):** `pnpm run ci:quick` or `pnpm run ci:quick:unit` +- **Quick gate (no Docker):** `pnpm run ci:quick`; for one targeted unit file use `VITEST_PATH=tests/unit/example.test.ts pnpm run ci:quick:unit` - **Full `ci.yml` locally:** `pnpm run ci:act` (sequential act jobs) Manual [Act](https://github.com/nektos/act) example: @@ -385,11 +387,11 @@ Open a **focused PR per theme** (storage vs. i18n vs. collaboration) to keep rev 1. Fork the repository and create a feature branch 2. Write or update tests for your changes -3. Run the full test suite: `pnpm run test:run` +3. Let CI run the full test suite; locally use only targeted `pnpm exec vitest run `. 4. Ensure Biome passes: `pnpm run lint` 5. Ensure i18n parity: `pnpm run i18n:check` 6. Ensure types compile: `pnpm run typecheck` -7. Ensure the build succeeds: `pnpm run build` +7. Ensure the build succeeds when build-affecting files changed; GitHub Actions runs the canonical build gate for every PR. 8. Submit a PR against `main` with a clear description 9. Request review from at least one maintainer diff --git a/TODO.md b/TODO.md index f4e24200f..f8b7132bb 100644 --- a/TODO.md +++ b/TODO.md @@ -8,7 +8,26 @@ Status: 🔄 in progress | ⬜ open | ✅ done --- -## Release — v1.25.0 published (2026-08-01) +## Current Sprint — Native desktop consolidation and Wave 2 G1 (2026-08-20) + +> **Status: 🔄 in progress.** The authoritative native sequence is maintained in +> [`docs/native/ROADMAP-QT-GPUI-DESKTOP.md`](docs/native/ROADMAP-QT-GPUI-DESKTOP.md), with the +> next Rust-Core capability choice recorded in [`docs/native/CORE-MIGRATION-LEDGER.md`](docs/native/CORE-MIGRATION-LEDGER.md). + +- ✅ P0 CI/deployment authority stabilization merged in PR #427 at `0309a255`. +- ✅ Cross-workspace Tauri path-dependency coverage and aggregate deployment gating are now + regression-tested in the quality job. +- 🔄 G1 remains partial: task supervision, diagnostics, contract versioning, and future R-15 + architecture remain open; no Qt or GPUI implementation is admitted yet. +- ⏭️ Next capability slice, after this consolidation pass: choose the smallest evidence-producing + logger/diagnostics or task-orchestration increment from the migration ledger. + +## Archived sprint history + +The completed release and infrastructure sections below are retained for provenance. They are not +the current sprint plan; long-term native sequencing belongs in the linked roadmap and ledger. + +## Archived — Release v1.25.0 published (2026-08-01) > **Status: ✅ Done.** Tagged, released, and live — see the GitHub Release link below. diff --git a/biome.json b/biome.json index 145ad8dba..d2e219e52 100644 --- a/biome.json +++ b/biome.json @@ -1,5 +1,5 @@ { - "$schema": "https://biomejs.dev/schemas/2.5.4/schema.json", + "$schema": "https://biomejs.dev/schemas/2.5.8/schema.json", "vcs": { "enabled": true, "clientKind": "git", diff --git a/docs/CI.md b/docs/CI.md index 464662d70..48d61a9f8 100644 --- a/docs/CI.md +++ b/docs/CI.md @@ -14,12 +14,25 @@ For historical optimization notes (targets may predate the live workflow), see [ | Tier | Where | Commands / scope | |------|--------|------------------| -| **Quick (local)** | Developer laptop | `pnpm run lint`, `pnpm run typecheck`, `pnpm run i18n:check`; optional `pnpm exec vitest run` **without** `--coverage` for a fast smoke | +| **Quick (local)** | Developer laptop | `pnpm run lint`, `pnpm run typecheck`, `pnpm run i18n:check`; optional targeted `pnpm exec vitest run ` for a fast smoke | | **Heavy (CI)** | `ci.yml` | Vitest **with** `--coverage` and thresholds, Playwright E2E (`CI=true`) including **mobile emulation** (Pixel 5 / Chromium), Lighthouse CI, Storybook static build, bundle budget + analyze. Mutation testing (Stryker) is **not** part of this pipeline — see [Mutation testing status](#mutation-testing-status). | **Merge readiness:** A green workflow run on the PR/branch matters more than reproducing every E2E or LHCI step locally. Use CI **artifacts** (Playwright HTML report, coverage, Lighthouse output) to debug failures. -**Optional local deep dive:** `CI=true pnpm run test:e2e`, `pnpm exec vitest run --coverage`, `pnpm exec lhci autorun` — only when the machine has enough CPU/RAM and time. Mobile Playwright project locally: set `RUN_MOBILE_E2E=1` (see [`playwright.config.ts`](../playwright.config.ts)). +**Local deep dive:** E2E, full-suite coverage, Lighthouse, and Storybook are CI-only on constrained hardware. For a focused local investigation, use `pnpm exec vitest run ` or `pnpm exec vitest run --coverage`; never invoke `pnpm test`, `npm run test`, or a bare Vitest wrapper. + +### Gate authority + +`✅ CI Success` is the required branch-protection status and aggregates `security`, `quality`, +`changes`, `rust-tauri`, `core-rust`, `build`, `e2e`, and `vrt`. The `deploy` job depends only on +that aggregate and remains main-push-only. + +`storybook` and `lighthouse` are currently visible, separately executed advisory jobs rather than +members of the aggregate. Their failures must still be investigated before merge under the +repository's full-suite policy; this explicit distinction prevents a red visible job from having +an undefined authority model. Storybook's test-runner and Lighthouse's desktop performance step +remain non-blocking under the exit criteria documented below. `e2e-deep` and the coverage ratchet +are also intentionally advisory. **Post-merge doc update workflow:** 1. Push the commit → CI starts automatically. @@ -225,19 +238,28 @@ longer runs a root `prepare` command. `pnpm-workspace.yaml` sets `verifyDepsBefo ## Local checks (without Act) -On **low-resource** machines, stop at the **Quick** tier (see [Cloud CI-first vs local development](#cloud-ci-first-vs-local-development)): **`pnpm run lint`**, **`pnpm run typecheck`**, **`pnpm run i18n:check`**, and optionally **`pnpm exec vitest run`** without `--coverage`. Treat **`CI=true pnpm run test:e2e`** (desktop + mobile projects in CI), **Lighthouse**, and **coverage threshold enforcement** as **CI-owned** unless you have a powerful workstation. +On **low-resource** machines, stop at the **Quick** tier (see [Cloud CI-first vs local development](#cloud-ci-first-vs-local-development)): **`pnpm run lint`**, **`pnpm run typecheck`**, **`pnpm run i18n:check`**, and optionally targeted **`pnpm exec vitest run `**. Treat **`CI=true pnpm run test:e2e`** (desktop + mobile projects in CI), **Lighthouse**, and **coverage threshold enforcement** as **CI-owned**. ```bash pnpm install --frozen-lockfile pnpm run lint pnpm run i18n:check pnpm run typecheck -pnpm exec vitest run --coverage +pnpm exec vitest run --coverage \ + --coverage.thresholds.lines=0 --coverage.thresholds.functions=0 \ + --coverage.thresholds.branches=0 --coverage.thresholds.statements=0 # targeted only +``` + +Playwright E2E, Lighthouse, Storybook, and full-suite coverage are intentionally omitted from +the local block above; GitHub Actions owns those heavy checks on this hardware. + +On standard hardware, or when debugging a build-affecting change, run the build-specific checks +separately; CI remains authoritative for the complete build and artifact checks: + +```bash pnpm run build pnpm run bundle:budget -pnpm run analyze # optional locally; CI uploads HTML report -CI=true pnpm run test:e2e -pnpm exec lhci autorun # after build + serve/preview as configured in .lighthouserc.cjs +pnpm run analyze ``` ### Node 24+ Compatibility Troubleshooting @@ -252,10 +274,10 @@ pnpm exec lhci autorun # after build + serve/preview as configured in .lightho ```bash # Simuliere CI-Bedingungen exakt -NODE_OPTIONS="--no-experimental-webstorage" pnpm exec vitest run --coverage --reporter=json --outputFile=test-results.json +NODE_OPTIONS="--no-experimental-webstorage" pnpm exec vitest run --coverage # Ohne Coverage für schnelles Feedback -pnpm exec vitest run +pnpm exec vitest run ``` **Coverage Ratchet Mechanism:** @@ -270,7 +292,7 @@ For **Ubuntu 20.04 / 2–4 GB RAM** laptops: run the **Quick tier** natively (no | Tier | Command | When | |------|---------|------| -| **Quick (daily)** | `pnpm run ci:quick` / `ci:quick:unit` | Every commit | +| **Quick (daily)** | `pnpm run ci:quick`; optional targeted `VITEST_PATH=tests/unit/example.test.ts pnpm run ci:quick:unit` | Every commit | | **Full workflow (on-demand)** | `pnpm run ci:act` | Before release / weekly | | **Eco Git** | `infra/low-end-ci/scripts/ci-eco-start.sh` | Only when pushing to local Forgejo | diff --git a/docs/CODEANT-REVIEW-LOOP.md b/docs/CODEANT-REVIEW-LOOP.md index 299c45a6d..c0a58bc79 100644 --- a/docs/CODEANT-REVIEW-LOOP.md +++ b/docs/CODEANT-REVIEW-LOOP.md @@ -3,7 +3,7 @@ > **Canonical, agent-agnostic workflow.** This is the single source of truth for how *every* > agent (Claude Code, Kimi, Cursor, Copilot, Gemini, human) handles inline PR review comments on > this repository — from CodeAnt AI **and any other reviewer or bot**. All instruction files -> (`CLAUDE.md`, `AGENTS.md`, `KIMI-INSTRUCT.md`, `.cursorrules`, `.github/copilot-instructions.md`) +> (`CLAUDE.md`, `AGENTS.md`, `docs/history/KIMI-INSTRUCT.md`, `.cursorrules`, `.github/copilot-instructions.md`) > point here. Keep this file current when the workflow or tooling changes. > > **See also:** [`DEEPSOURCE-REVIEW-LOOP.md`](DEEPSOURCE-REVIEW-LOOP.md) — the complementary, diff --git a/docs/DEPENDABOT-TRIAGE.md b/docs/DEPENDABOT-TRIAGE.md index 5ea551f5e..f3ebf5bf6 100644 --- a/docs/DEPENDABOT-TRIAGE.md +++ b/docs/DEPENDABOT-TRIAGE.md @@ -79,6 +79,19 @@ Coverage, Storybook, Lighthouse where applicable) — not just the required-chec [`CLAUDE.md`](../CLAUDE.md)'s branching-discipline section for the general "wait for advisory jobs too" rule; it applies to dependency PRs exactly as it does to feature PRs. +## OSV ignore-expiry review + +The 2026-08-20 consolidation review found **19** entries in `src-tauri/osv-scanner.toml`, all +currently sharing the `2026-11-30T00:00:00Z` review deadline. This is a synchronized review cliff, +not evidence that the risks were extended or resolved. The entries remain grouped by their real +reason: legacy GTK3/WebKit bindings, build-time `proc-macro-error`/`paste`, archived Unicode data +crates, and the transitive `extract-zip` advisory. + +No ignore deadline was extended in this pass. `extract-zip` remains a transitive Playwright browser +download dependency with no patched release and no production-runtime footprint; it must still be +rechecked before expiry and removed as soon as an upstream fix or dependency-path change makes that +possible. Review each cluster against current upstream status before changing any deadline. + ## Special-attention dependencies These need more than a changelog skim because of documented quirks elsewhere in this repo: @@ -90,6 +103,7 @@ These need more than a changelog skim because of documented quirks elsewhere in | `react` / `react-dom` | Already grouped — must stay in lockstep, split bumps cause version-mismatch errors at test time. | | `tauri*` / `wry` / `tao` | Already grouped (`tauri-deps`) — same lockstep concern for the desktop backend. | | `github/codeql-action*` | Already grouped — see incident above. | +| `@biomejs/biome` | Check the installed package version against `biome.json`'s `$schema` URL after every bump; the schema URL is versioned independently from the npm dependency declaration. | | Any WASM/WebGPU-adjacent package (`@huggingface/transformers`, `@mlc-ai/web-llm`, `onnxruntime-web`) | These ship in `vendor-*` SW-excluded chunks (`vite.config.ts` `globIgnores`) — verify a version bump didn't change the package's exported chunk structure in a way that breaks the manual-chunk mapping. | ## Merge discipline — one at a time, sequenced diff --git a/docs/adr/0016-native-grok-and-claude-providers.md b/docs/adr/0016-native-grok-and-claude-providers.md index 59b430977..8b62eac27 100644 --- a/docs/adr/0016-native-grok-and-claude-providers.md +++ b/docs/adr/0016-native-grok-and-claude-providers.md @@ -4,7 +4,7 @@ - **Date:** 2026-07-30 - **Deciders:** Maintainer + Claude Code - **Context tags:** ai, grok, anthropic, claude, cors, tauri, proxy, backend -- **Related:** [`GROK-PROVIDER-INTEGRATION-PLAN.md`](../../GROK-PROVIDER-INTEGRATION-PLAN.md) (execution plan this ADR formalizes) · extends [ADR 0012](0012-local-server-connectivity-tauri-http.md) · see also [ADR 0004](0004-csp-connect-src-byok-tradeoff.md) +- **Related:** [`GROK-PROVIDER-INTEGRATION-PLAN.md`](../history/GROK-PROVIDER-INTEGRATION-PLAN.md) (archived execution plan this ADR formalizes) · extends [ADR 0012](0012-local-server-connectivity-tauri-http.md) · see also [ADR 0004](0004-csp-connect-src-byok-tradeoff.md) ## Context @@ -127,7 +127,7 @@ for the full design. ## References -- [`GROK-PROVIDER-INTEGRATION-PLAN.md`](../../GROK-PROVIDER-INTEGRATION-PLAN.md) — full phased execution plan +- [`GROK-PROVIDER-INTEGRATION-PLAN.md`](../history/GROK-PROVIDER-INTEGRATION-PLAN.md) — archived full phased execution plan - [[0012-local-server-connectivity-tauri-http]] — the native-HTTP pattern Track A reuses - [[0004-csp-connect-src-byok-tradeoff]] — why the web CSP's `https:` scheme-source already covers Grok - [Issue #266](https://github.com/qnbs/WorldScript-Studio/issues/266) — origin of both the ADR-0012 pattern and the Ollama-in-PWA follow-up diff --git a/docs/adr/0017-pwa-browser-ollama-opt-in.md b/docs/adr/0017-pwa-browser-ollama-opt-in.md index d07b313ad..5a58b6a85 100644 --- a/docs/adr/0017-pwa-browser-ollama-opt-in.md +++ b/docs/adr/0017-pwa-browser-ollama-opt-in.md @@ -6,7 +6,7 @@ - **Context tags:** ai, ollama, cors, pwa, feature-flag - **Related:** [Issue #266](https://github.com/qnbs/WorldScript-Studio/issues/266) (comment thread, 2026-07-28/29) · narrowly widens [ADR 0012](0012-local-server-connectivity-tauri-http.md) · see - also [`GROK-PROVIDER-INTEGRATION-PLAN.md`](../../GROK-PROVIDER-INTEGRATION-PLAN.md) §7 (the + also [`GROK-PROVIDER-INTEGRATION-PLAN.md`](../history/GROK-PROVIDER-INTEGRATION-PLAN.md) §7 (the execution plan this ADR formalizes) ## Context @@ -95,5 +95,5 @@ this ADR adds a *client-side* opt-in, not a backend. - [[0012-local-server-connectivity-tauri-http]] — the desktop-only default this ADR narrowly widens - [[0016-native-grok-and-claude-providers]] — why the same proxy pattern does *not* transfer here (§ Context above) -- [`GROK-PROVIDER-INTEGRATION-PLAN.md`](../../GROK-PROVIDER-INTEGRATION-PLAN.md) §7 — full addendum +- [`GROK-PROVIDER-INTEGRATION-PLAN.md`](../history/GROK-PROVIDER-INTEGRATION-PLAN.md) §7 — full addendum this ADR formalizes diff --git a/GROK-PROVIDER-INTEGRATION-PLAN.md b/docs/history/GROK-PROVIDER-INTEGRATION-PLAN.md similarity index 99% rename from GROK-PROVIDER-INTEGRATION-PLAN.md rename to docs/history/GROK-PROVIDER-INTEGRATION-PLAN.md index 1c8e4074f..281d8bce8 100644 --- a/GROK-PROVIDER-INTEGRATION-PLAN.md +++ b/docs/history/GROK-PROVIDER-INTEGRATION-PLAN.md @@ -9,7 +9,7 @@ opt-in, experimental feature flag letting the PWA attempt direct browser-to-Olla matching the "technically: yes" option the maintainer already described in that issue's comment thread. **Status:** ✅ Complete — merged 2026-07-30, see `[Unreleased]`/`[1.25.0]` in -[CHANGELOG.md](CHANGELOG.md) for the user-facing summary. +[CHANGELOG.md](../../CHANGELOG.md) for the user-facing summary. **Execution:** All phases below (Grok wiring, Claude desktop + web proxy, Ollama-in-PWA opt-in addendum) have shipped. This file is retained as the historical design record; do not treat any "do not implement yet" language below as current. @@ -167,7 +167,7 @@ use the Tauri desktop app for Anthropic calls"*). Track B (the actual new archit and for the UI's desktop-vs-web conditional rendering. **Track A Definition of Done:** -- [ ] `streamAnthropic()` (+ image-gen + connection-test) branch on `isTauriRuntime()`; desktop calls Anthropic natively, no CORS error +- [ ] `streamAnthropic()` (+ connection-test) branches on `isTauriRuntime()`; desktop calls Anthropic natively, no CORS error - [ ] `src-tauri/tauri.conf.json` CSP includes `https://api.anthropic.com` - [ ] Desktop Settings UI shows a real API-key/model-selector flow for Claude instead of the warning block - [ ] Web/PWA UI unchanged by this track (still shows the warning, pointing at Track B once it exists) @@ -304,7 +304,7 @@ correctly `'anthropic'` throughout (`AIProvider` type, `aiProviderService.ts`'s unavailable state, confirm it doesn't silently break). **Claude Definition of Done (Track A — desktop, ships first):** -- [ ] `streamAnthropic()` (+ image-gen + connection-test) branch on `isTauriRuntime()`; desktop calls Anthropic natively, no CORS error +- [ ] `streamAnthropic()` (+ connection-test) branches on `isTauriRuntime()`; desktop calls Anthropic natively, no CORS error - [ ] `src-tauri/tauri.conf.json` CSP includes `https://api.anthropic.com` - [ ] Desktop Settings UI shows a real API-key/model-selector flow for Claude instead of the warning block - [ ] Unit tests for both runtime branches diff --git a/KIMI-INSTRUCT.md b/docs/history/KIMI-INSTRUCT.md similarity index 98% rename from KIMI-INSTRUCT.md rename to docs/history/KIMI-INSTRUCT.md index 917839b39..dbb12a94b 100644 --- a/KIMI-INSTRUCT.md +++ b/docs/history/KIMI-INSTRUCT.md @@ -38,7 +38,7 @@ Dieses Projekt läuft auf Low-End-Hardware. Beachte strikt: ## 3. CodeAnt AI PR-Review-Correction-Loop -Dieser Workflow ist die Standardvorgehensweise, wenn der Nutzer um Behebung von CodeAnt-Kommentaren bittet. +Dieser Workflow gilt für jeden offenen Pull Request: Review-Kommentare werden proaktiv geprüft und bearbeitet, auch ohne gesonderte Nutzeraufforderung. > **Kanonische Quelle:** Die vollständige, agenten-unabhängige Prozedur (inkl. GraphQL-Snippets, PR-Split > bei >100 Dateien, Merge-Regeln) lebt in **`docs/CODEANT-REVIEW-LOOP.md`**; der komplementäre, diff --git a/docs/history/completed-v1.25.0-providers.md b/docs/history/completed-v1.25.0-providers.md index bfe1a4b0f..690d596b7 100644 --- a/docs/history/completed-v1.25.0-providers.md +++ b/docs/history/completed-v1.25.0-providers.md @@ -15,7 +15,7 @@ README documented Grok and Claude as working cloud AI providers; neither was rea [ADR-0016](../adr/0016-native-grok-and-claude-providers.md) and [ADR-0017](../adr/0017-pwa-browser-ollama-opt-in.md); see `[1.25.0]` in [CHANGELOG.md](../../CHANGELOG.md) for the user-facing summary. Execution plan: -[`GROK-PROVIDER-INTEGRATION-PLAN.md`](../../GROK-PROVIDER-INTEGRATION-PLAN.md). +[`GROK-PROVIDER-INTEGRATION-PLAN.md`](GROK-PROVIDER-INTEGRATION-PLAN.md). - ✅ **Phase 1 — Grok**: wired into the primary provider dropdown + `providerFactory.ts`; the backend (`streamGrok()`) already worked, this was purely a UI/wiring gap. diff --git a/docs/native/ROADMAP-QT-GPUI-DESKTOP.md b/docs/native/ROADMAP-QT-GPUI-DESKTOP.md index 75031522c..a3400efb8 100644 --- a/docs/native/ROADMAP-QT-GPUI-DESKTOP.md +++ b/docs/native/ROADMAP-QT-GPUI-DESKTOP.md @@ -961,7 +961,7 @@ Required: [ ] task supervision renderer-neutral [ ] diagnostics renderer-neutral [ ] contract versioning policy established -[ ] native-readiness CI gate active (already true — see docs/architecture/native-readiness.md) +[ ] native-readiness CI gate active ``` ## G2 — Qt Implementation Admission diff --git a/infra/low-end-ci/DAILY-DRIVER.md b/infra/low-end-ci/DAILY-DRIVER.md index dcb4a35bf..3fbb4f8e4 100644 --- a/infra/low-end-ci/DAILY-DRIVER.md +++ b/infra/low-end-ci/DAILY-DRIVER.md @@ -17,7 +17,7 @@ Practical checklist for Ubuntu 20.04 Mate (2–4 GB RAM). **Primarily local**; G ```bash cd ~/githubcursor/WorldScript-Studio pnpm run ci:quick # lint + i18n + typecheck -pnpm run ci:quick:unit # + Vitest without coverage +VITEST_PATH=tests/unit/example.test.ts pnpm run ci:quick:unit # + one targeted Vitest file ``` Individual tests: @@ -33,7 +33,7 @@ pnpm exec vitest run tests/unit/duckdbClient.test.ts ## Before commit / push (Forgejo) ```bash -pnpm run ci:quick:unit # recommended +VITEST_PATH=tests/unit/example.test.ts pnpm run ci:quick:unit # recommended targeted check git add … && git commit -m "…" git push forgejo main # primary remote ``` @@ -123,8 +123,8 @@ Only **one** Node axis: `lts/*` (corresponds to Node 22 in act-22.04 image). Do | Alias | Action | |-------|--------| | `sc-ci` | Quick tier | -| `sc-ci-unit` | Quick + Vitest | -| `sc-ci-cov` | Quick + coverage | +| `sc-ci-unit` | Quick + targeted Vitest (`VITEST_PATH` required) | +| `sc-ci-cov` | Quick + targeted coverage (`VITEST_PATH` required; no full-suite threshold) | | `sc-act` | act sequential (PR) | | `sc-act-full` | act + storybook + Chromium-only E2E | | `sc-eco-on` / `sc-eco-off` | Forgejo start/stop + prune | diff --git a/infra/low-end-ci/bashrc-aliases.snippet b/infra/low-end-ci/bashrc-aliases.snippet index 8de262890..cc0dac777 100644 --- a/infra/low-end-ci/bashrc-aliases.snippet +++ b/infra/low-end-ci/bashrc-aliases.snippet @@ -5,8 +5,8 @@ export WORLDSCRIPT_REPO="${HOME}/githubcursor/WorldScript-Studio" export PATH="${WORLDSCRIPT_REPO}/infra/low-end-ci/scripts:${PATH}" alias sc-ci='cd "${WORLDSCRIPT_REPO}" && ci-quick.sh' -alias sc-ci-unit='cd "${WORLDSCRIPT_REPO}" && ci-quick.sh --unit' -alias sc-ci-cov='cd "${WORLDSCRIPT_REPO}" && ci-quick.sh --unit --coverage' +alias sc-ci-unit='cd "${WORLDSCRIPT_REPO}" && ci-quick.sh --unit="${VITEST_PATH:-}"' +alias sc-ci-cov='cd "${WORLDSCRIPT_REPO}" && ci-quick.sh --unit="${VITEST_PATH:-}" --coverage' alias sc-act='cd "${WORLDSCRIPT_REPO}" && ci-act-sequential.sh pull_request' alias sc-act-full='cd "${WORLDSCRIPT_REPO}" && ci-act-sequential.sh pull_request --with-storybook --e2e-chromium-only' alias sc-eco-on='ci-eco-start.sh' diff --git a/infra/low-end-ci/scripts/ci-quick.sh b/infra/low-end-ci/scripts/ci-quick.sh index a549782c0..c38c70220 100755 --- a/infra/low-end-ci/scripts/ci-quick.sh +++ b/infra/low-end-ci/scripts/ci-quick.sh @@ -11,13 +11,20 @@ require_cmd pnpm node WITH_COVERAGE=false WITH_UNIT=false +UNIT_PATH="" for arg in "$@"; do case "${arg}" in --coverage) WITH_COVERAGE=true; WITH_UNIT=true ;; - --unit) WITH_UNIT=true ;; + --unit=*) WITH_UNIT=true; UNIT_PATH="${arg#--unit=}" ;; + --unit) WITH_UNIT=true; UNIT_PATH="${VITEST_PATH:-}" ;; esac done +if [[ "${WITH_UNIT}" == true && -z "${UNIT_PATH}" ]]; then + log "A targeted test path is required: set VITEST_PATH or pass --unit=." + exit 2 +fi + export PNPM_STORE_DIR export NODE_OPTIONS="${NODE_OPTIONS:---max-old-space-size=1536}" @@ -33,9 +40,14 @@ pnpm run build-storybook if [[ "${WITH_UNIT}" == true ]]; then if [[ "${WITH_COVERAGE}" == true ]]; then - pnpm exec vitest run --coverage + # QNBS-v3: targeted coverage is diagnostic only, so it must not inherit full-suite gates. + pnpm exec vitest run "${UNIT_PATH}" --coverage \ + --coverage.thresholds.lines=0 \ + --coverage.thresholds.functions=0 \ + --coverage.thresholds.branches=0 \ + --coverage.thresholds.statements=0 else - pnpm exec vitest run + pnpm exec vitest run "${UNIT_PATH}" fi fi diff --git a/scripts/check-coverage-ratchet.mjs b/scripts/check-coverage-ratchet.mjs index 0debf4795..0704c5fb3 100644 --- a/scripts/check-coverage-ratchet.mjs +++ b/scripts/check-coverage-ratchet.mjs @@ -1,6 +1,6 @@ #!/usr/bin/env node /** - * Non-blocking: compares coverage/coverage-summary.json (produced by `pnpm run test:coverage`, + * Non-blocking: compares coverage/coverage-summary.json (produced by the CI quality job, * the json-summary reporter in vitest.config.ts) against the configured coverage thresholds, and * prints a suggestion when a metric sits comfortably above its threshold. The ratchet-up decision * stays with the maintainer (vitest.config.ts's own comment documents a "3 consecutive green runs, @@ -13,22 +13,20 @@ import { existsSync, readFileSync } from 'node:fs'; import { join } from 'node:path'; import { fileURLToPath } from 'node:url'; +import coverageThresholds from './coverage-thresholds.json' with { type: 'json' }; const root = join(fileURLToPath(new URL('.', import.meta.url)), '..'); const SUMMARY_PATH = join(root, 'coverage', 'coverage-summary.json'); -// QNBS-v3: mirrors vitest.config.ts's `coverage.thresholds` — that file isn't a plain-data module -// (it's a defineConfig() call), so this can't import it directly. Keep both in sync by hand; a -// mismatch here only makes a suggestion's "vs. threshold" number wrong, it can't mask a real -// coverage regression (vitest.config.ts's own thresholds still gate the actual build). -const THRESHOLDS = { lines: 74, functions: 67, branches: 60, statements: 72 }; +// QNBS-v3: Vitest and this advisory report share one threshold source. +const THRESHOLDS = coverageThresholds; const RATCHET_GAP = 2; // QNBS-v3: every exit path is a `return`, never `process.exit(1)` — this is advisory-only, so a missing/malformed/all-clean summary must all fall through to the same non-blocking outcome. function main() { if (!existsSync(SUMMARY_PATH)) { process.stdout.write( - '[coverage-ratchet] No coverage/coverage-summary.json found — run `pnpm run test:coverage` first. Skipping (non-blocking).\n', + '[coverage-ratchet] No coverage/coverage-summary.json found — CI has not produced the summary yet. Skipping (non-blocking).\n', ); return; } diff --git a/scripts/coverage-thresholds.json b/scripts/coverage-thresholds.json new file mode 100644 index 000000000..c0fee5cce --- /dev/null +++ b/scripts/coverage-thresholds.json @@ -0,0 +1,6 @@ +{ + "lines": 79, + "functions": 72, + "branches": 65, + "statements": 77 +} diff --git a/vitest.config.ts b/vitest.config.ts index 62c6c6a56..6af6a8822 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -3,6 +3,7 @@ import path from 'node:path'; import react from '@vitejs/plugin-react'; import { defineConfig } from 'vitest/config'; +import coverageThresholds from './scripts/coverage-thresholds.json' with { type: 'json' }; export default defineConfig({ plugins: [react()], @@ -84,10 +85,7 @@ export default defineConfig({ // by 1 point (max 5 points per quarter). Document the new baseline in this comment. // QNBS-v3 (CodeRabbit): raising these enforces the new, stricter CI floor going forward — any PR that drops coverage below L79/F72/B65/S77 now fails the quality gate instead of silently regressing under the old L74/F67/B60/S72 bar. thresholds: { - lines: 79, - functions: 72, - branches: 65, - statements: 77, + ...coverageThresholds, perFile: false, }, },