diff --git a/.github/SECURITY.md b/.github/SECURITY.md index beb17ec1b..d3c11d485 100644 --- a/.github/SECURITY.md +++ b/.github/SECURITY.md @@ -38,7 +38,7 @@ Phase 0 and Phase 2 hardening complete as of v1.19.0. Remaining open items: | --- | --- | --- | --- | | SEC-1 | Collaboration | Mandatory password enforcement — `CollabEncryptionRequiredError` thrown in `collaborationService.ts` when no password is provided in production | ✅ Complete (Phase 0) | | SEC-2 | Documentation | Updated security policy, version table, scope, and active-item tracking | ✅ Complete (Phase 0) | -| SEC-3 | Storage | IDB at-rest encryption — `services/storage/storageEncryptionService.ts`, AES-256-GCM, PBKDF2 600k iter; `enableIdbAtRestEncryption` flag (off by default) | ✅ Implemented (Phase 2 / B-1) | +| SEC-3 | Storage | IDB at-rest encryption — `services/storage/storageEncryptionService.ts`, AES-256-GCM, PBKDF2 600k iter; `enableIdbAtRestEncryption` flag (on by default since v1.23) | ✅ Implemented (Phase 2 / B-1) | | SEC-4 | Voice | Web Speech API consent gate — GDPR Art. 13 disclosure and explicit opt-in before audio is routed to cloud STT providers | ✅ Complete (Phase 0) | | SEC-5 | Storage | IDB at-rest encryption UX — passphrase unlock modal, forgot-passphrase export flow, key rotation UI | ✅ Complete (2026-06-02) | | SEC-6 | Storage | DuckDB OPFS at-rest encryption — WAL and data files outside IDB; requires separate encryption layer | ⬜ Phase 3 (P0-4) | diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 9ef4a581f..26595a34b 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -59,11 +59,11 @@ types.ts → Core shared interfaces and types 7. **Command Center:** Palette commands live in **`services/commands/`** (i18n keys, fuzzy search, recent/pinned). **`CommandExecutorProvider`** exposes execution for Help „Try it” (`tryActionId`) and toasts with **`commandId`**. **`useGlobalKeyboardShortcuts`** reads Redux shortcut bindings; **`app/transientUiStore`** toggles palette visibility. -8. **ProForge Pipeline:** 8-stage agentic manuscript editing pipeline gated behind `featureFlags.enableProForge` (off by default). Stage sequence: `intake` → `structural` → `lineProse` → `copyEdit` → `proof` → `production` → `publishing` → `analytics`. Manuscripts are **never auto-modified** — each stage pauses at `awaitingReview`. Orchestrator: `services/proForge/proForgeOrchestrator.ts`; Redux slice: `features/proForge/proForgeSlice.ts`; UI: `components/proForge/` (ProForgeDashboard, PipelineProgressPanel, PipelineReviewPanel); docs: `docs/PROFORGE-PIPELINE.md`. +8. **ProForge Pipeline:** 8-stage agentic manuscript editing pipeline gated behind `featureFlags.enableProForge` (on by default). Stage sequence: `intake` → `structural` → `lineProse` → `copyEdit` → `proof` → `production` → `publishing` → `analytics`. Manuscripts are **never auto-modified** — each stage pauses at `awaitingReview`. Orchestrator: `services/proForge/proForgeOrchestrator.ts`; Redux slice: `features/proForge/proForgeSlice.ts`; UI: `components/proForge/` (ProForgeDashboard, PipelineProgressPanel, PipelineReviewPanel); docs: `docs/PROFORGE-PIPELINE.md`. 9. **Voice Full Support:** Gated behind `featureFlags.enableVoiceSupport` + `settings.voice.enabled`. Abstract engine pattern in `services/voice/voiceTypes.ts` (SttEngine, TtsEngine, VadEngine, WakeWordEngine, IntentEngine). `VoiceCommandService` singleton manages state machine (idle → listening → processing → speaking). Web Speech API fallbacks require zero downloads. Hooks: `useVoice`, `usePushToTalk` (Ctrl+Shift+V), `useVoiceDictation`. -10. **Feature Flags:** 21 flags in `features/featureFlags/featureFlagsSlice.ts`. Default **on**: `enableCodexAutoTracking`, `enableCrossProjectSearch`, `enablePlotBoardV2` (deprecated UI, retained for localStorage compat). All others default off. Key flags: `enableProForge`, `enableGlobalCopilot`, `enableVoiceSupport`, `enableDuckDbAnalytics`, `enableWorkerBusV2`. Do not use scattered `if (true)` hacks — all experimental features must go through a flag. +10. **Feature Flags:** **23 flags** in `features/featureFlags/featureFlagsSlice.ts`. New installs get the **full feature set** — all default **on** except five opt-in flags that default **off**: `enableRtlLayout`, `enableVoiceSupport`, `enableVoiceWasm`, `enableGlobalCopilot`, `enableLocalFirstSync`. (`enableCodexAutoTracking` + `enableCrossProjectSearch` were promoted to permanent core; `enablePlotBoardV2` + `enableCloudSync` were retired — none remain in the slice.) See `docs/FEATURE-PARITY.md`. Do not use scattered `if (true)` hacks — all experimental features must go through a flag. 11. **Global AI Copilot (v2):** `enableGlobalCopilot` flag. `CopilotPanel` (dialog/sidebar mode), `CopilotMessageList` (markdown rendering via DOMPurify), `InlineAnnotationLayer` (badge in ManuscriptEditor). Heuristic rules: `services/copilot/heuristicEngine.ts` (8 rules). Apply-to-chapter: `services/copilot/actionApplier.ts` (offset-safe edit, redux-undo, ≥70% length gate). ProForge integration: Ask-Copilot chip on each `ReviewItemCard`. Docs: `docs/COPILOT.md`, `docs/HEURISTIC-RULES.md`. @@ -175,7 +175,7 @@ See `AUDIT.md` and `TODO.md`. Key items: - `app/listenerMiddleware.ts` — occasional TypeScript friction with redux-undo `StateWithHistory` - `workers/inference.worker.ts:50` — `@ts-expect-error` on `@xenova/transformers` dynamic import (Vite resolves at build, `tsc` cannot) - **DS-5:** Delete legacy bridge block from `index.css` — deferred until DS-1 token migration verified in production -- **v2.0 stubs behind feature flags:** RTL layout (`enableRtlLayout`), Cloud-Sync R2 adapter (`enableCloudSync`), LoRA adapter inference (`enableLoraAdapters`), Plugin system loader (`enablePluginSystem`) +- **v2.0 stubs behind feature flags:** RTL layout (`enableRtlLayout`), LoRA adapter inference (`enableLoraAdapters`), Plugin system loader (`enablePluginSystem`). (The Cloud-Sync R2 adapter's `enableCloudSync` flag was **retired** in v1.20 — activation is now `CloudSyncBackend.create(..., explicitConsent)`.) - RTCDataChannel in-flight E2E encryption is **shipped** (y-webrtc patch v1.17.0) — no longer open ## Commands diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 3c866f6c5..ef8a4c971 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -6,6 +6,13 @@ updates: schedule: interval: weekly day: monday + # QNBS-v3: cooldown delays Dependabot PRs until a release has aged 7 days — matched to the + # .npmrc `minimum-release-age=10080` (7-day) supply-chain policy, so a freshly-published + # version is never PR'd before `pnpm install --frozen-lockfile` would accept it (avoids + # ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION CI failures like #154/#155). The .npmrc gate is + # install-time only; this cooldown is the PR-creation-time counterpart. + cooldown: + default-days: 7 open-pull-requests-limit: 10 groups: # QNBS-v3: react and react-dom must stay in lockstep; split bumps cause version-mismatch errors at test time. @@ -35,6 +42,8 @@ updates: schedule: interval: weekly day: monday + cooldown: + default-days: 7 open-pull-requests-limit: 5 groups: tauri-deps: @@ -50,4 +59,6 @@ updates: schedule: interval: weekly day: monday + cooldown: + default-days: 7 open-pull-requests-limit: 5 diff --git a/.github/workflows/tauri-build.yml b/.github/workflows/tauri-build.yml index 4822c170f..a00dd3943 100644 --- a/.github/workflows/tauri-build.yml +++ b/.github/workflows/tauri-build.yml @@ -167,26 +167,30 @@ jobs: [ -f "$SIG_FILE" ] || continue BASE="${SIG_FILE%.sig}" FNAME="$(basename "$BASE")" + # QNBS-v3: GitHub normalizes spaces in uploaded asset names to dots (e.g. + # "WorldScript Studio_*.AppImage" → "WorldScript.Studio_*.AppImage"). The bundle file on + # disk still has the space, so the updater URL MUST use the normalized name or it 404s. + URLNAME="${FNAME// /.}" SIG_CONTENT="$(cat "$SIG_FILE")" case "$FNAME" in *.AppImage) - LINUX_URL="${REPO_URL}/${FNAME}"; LINUX_SIG="$SIG_CONTENT" ;; + LINUX_URL="${REPO_URL}/${URLNAME}"; LINUX_SIG="$SIG_CONTENT" ;; *-setup.exe) # NSIS installer — preferred Windows updater format - WIN_URL="${REPO_URL}/${FNAME}"; WIN_SIG="$SIG_CONTENT" ;; + WIN_URL="${REPO_URL}/${URLNAME}"; WIN_SIG="$SIG_CONTENT" ;; *.msi) # MSI fallback if no NSIS sig collected yet - [ -z "$WIN_SIG" ] && { WIN_URL="${REPO_URL}/${FNAME}"; WIN_SIG="$SIG_CONTENT"; } ;; + [ -z "$WIN_SIG" ] && { WIN_URL="${REPO_URL}/${URLNAME}"; WIN_SIG="$SIG_CONTENT"; } ;; *_aarch64.app.tar.gz) # QNBS-v3: macOS updater bundle is .app.tar.gz (not .dmg). # .dmg is the user-facing installer; .app.tar.gz is what Tauri downloads for in-app updates. # aarch64 = macos-latest ARM runner. x64 runner not yet in matrix. - MAC_AARCH64_URL="${REPO_URL}/${FNAME}"; MAC_AARCH64_SIG="$SIG_CONTENT" ;; + MAC_AARCH64_URL="${REPO_URL}/${URLNAME}"; MAC_AARCH64_SIG="$SIG_CONTENT" ;; *_x64.app.tar.gz) - MAC_X64_URL="${REPO_URL}/${FNAME}"; MAC_X64_SIG="$SIG_CONTENT" ;; + MAC_X64_URL="${REPO_URL}/${URLNAME}"; MAC_X64_SIG="$SIG_CONTENT" ;; *.app.tar.gz) # Fallback for generic .app.tar.gz (older Tauri versions) - MAC_AARCH64_URL="${REPO_URL}/${FNAME}"; MAC_AARCH64_SIG="$SIG_CONTENT" ;; + MAC_AARCH64_URL="${REPO_URL}/${URLNAME}"; MAC_AARCH64_SIG="$SIG_CONTENT" ;; esac done @@ -213,4 +217,6 @@ jobs: echo "Generated latest.json:" cat latest.json - gh release upload "$TAG" latest.json --clobber + # QNBS-v3: this job has no actions/checkout, so gh has no local git context — pass --repo + # explicitly or `gh release upload` aborts with "fatal: not a git repository" (v1.23.0 fix). + gh release upload "$TAG" latest.json --clobber --repo "$GITHUB_REPOSITORY" diff --git a/AGENTS.md b/AGENTS.md index c48d7c7c6..b1ab2a678 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -84,7 +84,7 @@ WorldScript-Studio/ │ ├── status/ # App-wide status / loading flags │ ├── writer/ # Writer view state │ ├── versionControl/ # Snapshots and branches -│ ├── featureFlags/ # ~20 experimental flags (mostly off by default) +│ ├── featureFlags/ # 23 flags — full set on by default; 5 opt-in (default-off) │ ├── plotBoard/ # Ephemeral viewport/draw state (NOT undo-able; localStorage) │ ├── progressTracker/ # Writing sessions, streaks, goals │ ├── sceneComments/ # Per-scene comments (EntityAdapter) @@ -181,7 +181,7 @@ pnpm run mutation # Stryker mutation testing (CI-only; manual workflow # Analysis / budgets pnpm run analyze # Rollup visualizer → dist/bundle-analysis.html -pnpm run bundle:budget # Chunk size guard (default max 6500 KB total, 4000 KB entry) +pnpm run bundle:budget # Chunk size guard (default max 6200 KB total, 2500 KB entry) pnpm run storybook # Storybook dev server on :6006 pnpm run build-storybook # Static Storybook build pnpm run test:storybook # Test-runner against served Storybook @@ -387,7 +387,7 @@ Edge builds run `scripts/build-edge.mjs` which sets `DEPLOY_TARGET=edge` and pat ### Feature Flags -- `features/featureFlags/featureFlagsSlice.ts` gates ~20 experimental flags + `enableVoiceSupport` (mostly off by default; a few like `enableCodexAutoTracking` and `enableCrossProjectSearch` are on). +- `features/featureFlags/featureFlagsSlice.ts` gates **23 flags**. New installs get the **full feature set**: all default **on** except five opt-in flags that default **off** — `enableRtlLayout`, `enableVoiceSupport`, `enableVoiceWasm`, `enableGlobalCopilot`, `enableLocalFirstSync`. (`enableCodexAutoTracking` + `enableCrossProjectSearch` were promoted to permanent core; `enablePlotBoardV2` + `enableCloudSync` were retired — none remain in the slice.) See `docs/FEATURE-PARITY.md` for the per-flag matrix. - UI: Settings → Experimental flags. - Do not use scattered `if (true)` hacks. @@ -455,7 +455,7 @@ Central orchestration layer for all background worker tasks. Messages use short - `services/hybridRouter.ts` — routes to Web Worker pool or Rust TaskSupervisor (Tauri only) when `enableRustCompute` is on. - `services/legacyWorkerBusAdapter.ts` — shims old `@domain/ai-core` WorkerBus API onto v2. - `services/tauriTaskBridge.ts` — `invokeRustTask()`, `isRustComputeAvailable()` (60s TTL ping cache). -- Feature flags: `enableWorkerBusV2` (off by default), `enableRustCompute` (off by default; Tauri desktop only). +- Feature flags: `enableWorkerBusV2` (on by default), `enableRustCompute` (on by default; effective on Tauri desktop only). - v2 workers: `workers/v2/inference.worker.ts` (text + embed via Hugging Face transformers), `workers/v2/duckdb.worker.ts` (init/query/exec/shutdown). ### DuckDB Analytics @@ -463,7 +463,7 @@ Central orchestration layer for all background worker tasks. Messages use short - `workers/duckdbWorker.ts` runs DuckDB-WASM off main thread (OPFS persistence → in-memory fallback). - `services/duckdb/duckdbClient.ts` is a singleton proxy with AbortSignal and init retry. - Schema (`duckdbSchema.ts`): 10 tables + 5 views including `rag_chunks` (FLOAT[384]), `cross_project_index`, `codex_*`. -- Gated behind `featureFlagsSlice.enableDuckDbAnalytics` (off by default). +- Gated behind `featureFlagsSlice.enableDuckDbAnalytics` (on by default). - Dual-write (IDB + DuckDB) goes through `duckdbListenerLoader.ts` in the listener middleware. --- diff --git a/AUDIT.md b/AUDIT.md index 094585edb..cf46fac14 100644 --- a/AUDIT.md +++ b/AUDIT.md @@ -1,10 +1,24 @@ # WorldScript Studio — Codebase Audit Report -**Date:** 2026-04-17 (baseline); **follow-up chain:** … → 2026-05-28 (v1.19.0 — Security/Voice/RTL/Logger B-1..B-8) → **2026-05-30 (B-1 passphrase UX + CI unblock)** → **2026-05-31 (i18n audit + settings features + CI stabilization)** → **2026-05-31 (Edge-AI Perfection Cycle — Phases 0-7 complete)** → **2026-06-01 (Post-crash session: CI stabilisation + 14 CodeAnt AI fixes + E2E hardening)** → **2026-06-02 (Perf Phase 2.3 — pipeline-LRU unification + PR #69 CodeAnt fixes)** → **2026-06-03 (WorkerBus v2 Phase 3 — Rust TaskSupervisor + Tauri-build unblock)** → **2026-06-06 (Phase 3 i18n Expansion — ja/zh/pt/el + Intl APIs)** → **2026-06-09 (v1.21 Deep Audit Correction — Whisper WASM download UI + 3 CodeAnt fixes + CloudSync LWW)** → **2026-06-09 (feat/deep-audit-v1.21 — CSP hardening, zh locale ≤5% EN, coverage Batches A/B/C, VoiceActivityCoordinator B-2 bridge)** → **2026-06-11 (Ultimate Copilot v2 Phase 2+3 — markdown, sidebar, Apply-to-chapter, InlineAnnotation, ProForge chip; PR #110+#111)** → **2026-06-11 (v1.22.0 release — OpenRouter Cloud 5 provider, AI Execution Modes hybrid/cloud/local/eco, AiModeIndicator, SW cache-invalidation fix)** +**Date:** 2026-04-17 (baseline); **follow-up chain:** … → 2026-05-28 (v1.19.0 — Security/Voice/RTL/Logger B-1..B-8) → **2026-05-30 (B-1 passphrase UX + CI unblock)** → **2026-05-31 (i18n audit + settings features + CI stabilization)** → **2026-05-31 (Edge-AI Perfection Cycle — Phases 0-7 complete)** → **2026-06-01 (Post-crash session: CI stabilisation + 14 CodeAnt AI fixes + E2E hardening)** → **2026-06-02 (Perf Phase 2.3 — pipeline-LRU unification + PR #69 CodeAnt fixes)** → **2026-06-03 (WorkerBus v2 Phase 3 — Rust TaskSupervisor + Tauri-build unblock)** → **2026-06-06 (Phase 3 i18n Expansion — ja/zh/pt/el + Intl APIs)** → **2026-06-09 (v1.21 Deep Audit Correction — Whisper WASM download UI + 3 CodeAnt fixes + CloudSync LWW)** → **2026-06-09 (feat/deep-audit-v1.21 — CSP hardening, zh locale ≤5% EN, coverage Batches A/B/C, VoiceActivityCoordinator B-2 bridge)** → **2026-06-11 (Ultimate Copilot v2 Phase 2+3 — markdown, sidebar, Apply-to-chapter, InlineAnnotation, ProForge chip; PR #110+#111)** → **2026-06-11 (v1.22.0 release — OpenRouter Cloud 5 provider, AI Execution Modes hybrid/cloud/local/eco, AiModeIndicator, SW cache-invalidation fix)** → **2026-06-13/14 (v1.23 perfection batch — OpenRouter + AI-Execution-Mode settings sections localized/modernized, i18n single-brace interpolation bug-class fix + `i18nPlaceholders` regression guard, bundle split + budget tightening PR #130)** → **2026-06-16 (v1.23.0 release — rebrand StoryCraft → WorldScript Studio, local-first data foundation ADR-0008, Tauri blank-screen + asset-URL fixes, AI error taxonomy + retry hardening, command-palette & local-AI settings localization, WorldScript W monogram icons)** → **2026-06-16 (post-release documentation perfection pass — corpus sync, metric reconciliation, history archival, dependabot hardening)** **Scope:** Full application, repository configuration, CI/CD, documentation, release validation -**Current version:** **v1.22.0** — 2026-06-11 (OpenRouter Cloud 5 provider; AI Execution Modes hybrid/cloud/local/eco; AiModeIndicator; Ultimate Copilot AI v2 Phases 1-3; HeuristicEngine 8 rules; InsightGenerator debounce+LRU; sidebar mode; Apply-to-chapter; InlineAnnotationLayer; ProForge Ask-Copilot chip; PWA SW cache fix; **2594 keys × 11 locales**; docs/COPILOT.md + docs/HEURISTIC-RULES.md) +**Current version:** **v1.23.0** — 2026-06-16 (Rebrand StoryCraft → WorldScript Studio; local-first data foundation behind `enableLocalFirstSync` (ADR-0008); Tauri blank-screen + updater asset-URL fixes; AI error taxonomy + retry hardening; OpenRouter reactive cloud-policy; command-palette & local-AI settings localization; WorldScript W monogram icons; **2709 keys × 11 locales**; v1.23 perfection engagement — docs/AUDIT-PERFECTION-PLAN-v1.23.md) -**Quality gate (2026-06-11 — v1.22.0):** lint ✅ · typecheck ✅ · i18n:check ✅ (**2594 keys × 11 locales**) · unit tests ✅ (5 475+ / 449 files) · coverage thresholds L74/B60/F67/S72 ✅. Toolchain: Node 22/24, **pnpm 11**, Vite 8, TypeScript 7 (tsgo). +**Quality gate (2026-06-16 — v1.23.0):** lint ✅ · typecheck ✅ · i18n:check ✅ (**2709 keys × 11 locales**) · placeholder guard ✅ · unit tests ✅ (5807+ / 485 files) · coverage thresholds L74/B60/F67/S72 ✅. Toolchain: Node 22/24, **pnpm 11**, Vite 8, TypeScript 7 (tsgo). + +## v1.23.0 Post-Release Documentation Perfection Pass (2026-06-16) + +**Scope:** Bring the entire doc corpus into lockstep with the shipped v1.23.0 code, curate/restructure historical material, clear the Dependabot queue, and complete the GitHub release/package rebrand. + +- **Metric reconciliation:** `scripts/sync-readme-metrics.mjs` re-run → README now reads **2709 keys / 485 test files** (was 2706 / 481). AUDIT header (version, quality-gate, follow-up chain) advanced from the stale **v1.22.0** label to **v1.23.0** with current numbers. +- **Feature-flag truth-up:** docs claimed **21** flags; the slice has **23**. `CLAUDE.md` rewritten — the default model had inverted (new installs get the **full set**; only 5 default off: `enableRtlLayout`, `enableVoiceSupport`, `enableVoiceWasm`, `enableGlobalCopilot`, `enableLocalFirstSync`). Retired/promoted flags (`enableCodexAutoTracking`, `enableCrossProjectSearch`, `enablePlotBoardV2`, `enableCloudSync`) removed from the live list. Three slice JSDoc `(default: true)` annotations that contradicted the runtime defaults corrected to `(default: false)`. +- **Bundle budget:** current help/docs aligned to **6200 / 2500** (`AGENTS.md`); `docs/CODE_QUALITY.md` confirmed not to hardcode the figure. +- **Roadmap/TODO:** v1.23 section flipped from "ACTIVE / target 2026-06-20" to **RELEASED 2026-06-16** with the real deliverables; forward P1/P2 work consolidated into a single **Upcoming — v1.24 / v2.0 Foundation** block. +- **Corpus restructure:** archived finished plans into `docs/history/` via `git mv` — `EDGE_AI_PERFECT_PLAN.md`, `EDGE_AI_ZWISCHENSTAND.md`, `CHECKPOINT-2026-05-24.md`, `CHECKPOINT-2026-06-06.md`, `WIEDERAUFNAHME.md`; inbound links repaired (0 broken relative links). +- **Rebrand residue:** ADR-0008 present-tense "StoryCraft is offline-first" → "WorldScript Studio". Remaining `storycraft*` hits are intentional historical records (CHANGELOG version entries, archived sprints) or technical identifiers that were genuine at their version — left intact. +- **GitHub releases:** 6 historical release titles renamed StoryCraft → WorldScript (v1.3.0, v1.5.0, v1.7.0, v1.17.0, v1.20.0, v1.21.0); v1.23.0 release/tag verified correct (latest, full changelog, tag → `fbaa33c3`). +- **GitHub Packages:** orphaned `storycraft-studio` GHCR container image to be deleted so only `worldscript-studio` remains (requires `delete:packages` token scope — pending maintainer auth refresh). +- **Dependabot hardening:** added `cooldown: default-days: 7` to all three `.github/dependabot.yml` ecosystems so newly released versions age 7 days before a PR is opened — matched to the `.npmrc` `minimum-release-age=10080` (7-day) supply-chain quarantine already enforced at pnpm install-time, so a version is never PR'd before `pnpm install --frozen-lockfile` would accept it (`.github/dependabot.yml` is the source of truth for the cooldown value). Open queue handled per the CodeAnt Correction Loop: #150 candle-nn merged; #151 candle-core rebased + re-running; #152 dev-tooling fixed at root (dual `playwright-core` deduped to 1.61.0 via `pnpm-workspace.yaml` override); #154/#155 are blocked solely by the `minimum-release-age` quarantine (packages too fresh — working as designed) and clear once aged. ## v1.23 i18n Interpolation Bug-Class Fix + Regression Guard (2026-06-14) @@ -1061,7 +1075,7 @@ Delivered: WorkerBus v2 (priority preemption, backpressure, transferables), GPU - **Help:** Static chunk retrieval `services/help/helpDocRetrieval.ts` → doc context in `streamAiHelpResponse`; locale **`tryActionId`** on articles; `services/spotlightTour.ts` **`tourId`** for multiple guided flows. - **UI primitives:** `components/ui/Tooltip.tsx`, `EmptyState.tsx`; `features/status/statusSlice.ts` toast fields **`commandId`** / **`actionLabel`**; ErrorBoundary GitHub issue link. - **Section icon SSOT:** `constants/sections.tsx` → `APP_SECTIONS: Record` maps every view to icon, colorClass, textColor, accentColor. `components/ui/SectionIcon.tsx` renders the colored badge (sizes xs/sm/md/lg/xl, `aria-hidden`). All 14+ view headers, card headers, and nav items consume this SSOT. Tested in `tests/unit/SectionIcon.test.tsx`. -- **Feature flags:** `enableProjectHealthScore` (dashboard health card), `enableCrossProjectSearch` (stub) in `features/featureFlags/featureFlagsSlice.ts`. +- **Feature flags:** `features/featureFlags/featureFlagsSlice.ts` ships **23 flags** (18 default-on, 5 opt-in default-off — see `docs/FEATURE-PARITY.md`); e.g. `enableProjectHealthScore` (dashboard health card). Cross-project search is now permanent core (no flag). ### Documentation diff --git a/CLAUDE.md b/CLAUDE.md index 616816091..3c7bd78cb 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -238,9 +238,9 @@ Production uses **rolldown** (not esbuild/rollup); CI E2E runs `vite dev` — pr ### Feature Flags -Experimental features are gated behind `features/featureFlags/featureFlagsSlice.ts` (21 flags). Default **on**: `enableCodexAutoTracking`, `enableCrossProjectSearch`, `enablePlotBoardV2` (@deprecated — v1 board removed in v1.6; retained in slice for localStorage compat; hidden from Settings UI). All others default **off**. UI: Settings → Experimental flags (`FeatureFlagsSection.tsx`). Do not use scattered `if (true)` hacks. +Experimental features are gated behind `features/featureFlags/featureFlagsSlice.ts` (**23 flags**). New installs get the **full feature set**: all flags default **on** except five user-opt-in flags. `enableCodexAutoTracking` + `enableCrossProjectSearch` were promoted to permanent core behaviour (v1.20 / v1.8); `enablePlotBoardV2` and `enableCloudSync` were retired — none of those four remain in the slice. UI: Settings → Experimental flags (`FeatureFlagsSection.tsx`). Do not use scattered `if (true)` hacks. -Key flags (on by default): `enableDuckDbAnalytics`, `enableProForge`, `enableStoryBibleAdvanced`, `enableBinderResearch`, `enableCompileWizard`, `enableProjectHealthScore`, `enableAppHealthPanel`. **User opt-in (off by default):** `enableVoiceSupport` (requires browser mic permission), `enableVoiceWasm` (B-2, ~57 MB Whisper download), `enableGlobalCopilot` (ambient AI), `enableRtlLayout` (B-5, ar/he stubs only), `enableIdbAtRestEncryption` (B-1, passphrase UX complete — enable via Settings › Privacy). **Edge-AI (all off):** `enableAdaptiveAiEngine`, `enableWebnnInference`, `enableComputeShaders`, `enableWorkerBusV2`, `enableRustCompute`. **Stub/future (all off):** `enableLoraAdapters`, `enablePluginSystem`, `enableObjectsGroups`, `enableMindMaps`, `enableCharacterInterviews`. Note: `enableCloudSync` was **retired** in v1.20 (no UI shipped; `CloudSyncBackend.create()` requires explicit-consent boolean instead). +**Default on (18):** `enableStoryBibleAdvanced`, `enableBinderResearch`, `enableCompileWizard`, `enableProjectHealthScore`, `enableAppHealthPanel`, `enableDuckDbAnalytics`, `enableObjectsGroups`, `enableMindMaps`, `enableCharacterInterviews`, `enableLoraAdapters`, `enablePluginSystem`, `enableProForge`, `enableIdbAtRestEncryption` (B-1, passphrase UX complete — Settings › Privacy), `enableAdaptiveAiEngine`, `enableWebnnInference`, `enableComputeShaders`, `enableWorkerBusV2`, `enableRustCompute`. **User opt-in — default off (5):** `enableVoiceSupport` (requires browser mic permission), `enableVoiceWasm` (B-2, ~57 MB Whisper download), `enableGlobalCopilot` (ambient AI), `enableRtlLayout` (B-5, ar/he stubs only), `enableLocalFirstSync` (shadow Yjs projection, ADR-0008; Redux stays SoT). Note: `enableCloudSync` was **retired** in v1.20 (no UI shipped; `CloudSyncBackend.create()` requires explicit-consent boolean instead). ### Command Center & shortcuts @@ -329,7 +329,7 @@ All `.md` guides listed in **[`README.md`](README.md#-documentation-hub) § Docu **useAppSelectorShallow with plotBoard:** Include `plotBoard: { activeMode: 'swimlane', snapToGrid: false, selectedConnectionId: null, isDrawingConnection: false, drawFromSectionId: null, activeSubplotFilter: null, zoom: 1, panX: 0, panY: 0 }` in mock state. Connections/subplots/tensionOverrides are in `project.present.data`. Add `// biome-ignore lint/suspicious/noExplicitAny: test mock` before `(selector: (s: any) => unknown)` lines. -**FeatureFlagsState mocks:** Always include ALL 21 flags (TypeScript strict rejects partial). Flags that are **off** by default: `enableRtlLayout`, `enableVoiceSupport`, `enableVoiceWasm`, `enableGlobalCopilot`, `enableIdbAtRestEncryption`, and all edge-AI flags (`enableAdaptiveAiEngine`, `enableWebnnInference`, `enableComputeShaders`, `enableWorkerBusV2`, `enableRustCompute`). When a test needs a flag that is off by default, set it explicitly in the mock — don't assume the default. +**FeatureFlagsState mocks:** Always include ALL 23 flags (TypeScript strict rejects partial). Only **five** default **off**: `enableRtlLayout`, `enableVoiceSupport`, `enableVoiceWasm`, `enableGlobalCopilot`, `enableLocalFirstSync` — every other flag (including all edge-AI flags and `enableIdbAtRestEncryption`) defaults **on**. When a test needs a non-default flag state, set it explicitly in the mock — don't assume the default. **ConnectionLayer test IDs:** `data-testid="connection-group"` — query by testid, not role. diff --git a/README.md b/README.md index 4209bfdef..4984fe7de 100644 --- a/README.md +++ b/README.md @@ -12,8 +12,8 @@ v1.23.0 IndexedDB v8 PWA v3.0 - i18n 11 locales — 2706 keys - 5807+ tests / 481 files + i18n 11 locales — 2709 keys + 5807+ tests / 485 files Codecov Coverage License MIT CI Status @@ -269,14 +269,14 @@ A keyboard-first **command palette** (⌘K / Ctrl+K, plus configurable bindings - **Settings** — filter controls via the Settings search bar (`services/settingsSearchHints.ts`); **Import / Export** of a Zod-validated, privacy-conscious settings JSON subset (**Settings → Data** via `services/settingsExchange.ts`). - **Help Center (v1.9)** — `services/help/helpCatalog.ts` drives 50+ articles across 11 categories (including **Advanced & Power Features**, **Technical Documentation**, and **Settings Guide**); full-text search (`helpSearch.ts`); AI assistant uses 16 offline doc chunks; **Try it** actions via `tryActionId`; tours from `services/spotlightTour.ts`. The in-app **Settings Guide** documents every live settings category (incl. Fine-Tuning/LoRA, Community, Plugins). All five primary locales include translated article bodies (es/fr/it complete as of v1.9); Arabic/Hebrew article prose ships as English fallback in the RTL Beta. - **UI primitives** — shared **`Tooltip`**, **`EmptyState`**, and toast rows that trigger a **registered command** via `commandId` (see `features/status/statusSlice.ts`). -- **Feature flags** — `enableProjectHealthScore` (dashboard card) and `enableCrossProjectSearch` (cross-project index) live in `features/featureFlags/featureFlagsSlice.ts`. +- **Feature flags** — `enableProjectHealthScore` (dashboard card) lives in `features/featureFlags/featureFlagsSlice.ts`. (Cross-project search was promoted to permanent core behaviour in v1.8 and no longer has a flag.) ### 🔭 Cross-Project Search _(v2 — Privacy-Preserving Index)_ Search across **all your projects** without loading them into memory. An IndexedDB-based privacy-preserving index (DB v8, `projects-index-store`) stores only lightweight metadata per project — title, logline, word count, character names — never manuscript plaintext. - **Two-phase search:** Phase 1 queries the index (instant); Phase 2 loads the full project on demand for deep-match excerpts. -- **Auto-indexing** on every save via `listenerMiddleware` (behind the `enableCrossProjectSearch` flag). +- **Auto-indexing** on every save via `listenerMiddleware` (permanent core behaviour since v1.8). - **Index management:** `crossProjectIndexService.ts` exposes `indexProject`, `listIndexedProjects`, `removeProjectIndex`. - Fully localized across all 5 UI languages. @@ -304,7 +304,7 @@ Real-time P2P co-editing via **Yjs + collab-transport** (vendor fork of y-webrtc All project data, snapshots, and settings stored in IndexedDB can be encrypted at rest via `services/storage/storageEncryptionService.ts`: - **AES-256-GCM** with a PBKDF2-derived key (600 000 iterations, SHA-256, 32-byte random salt). -- Gated behind `featureFlags.enableIdbAtRestEncryption` (off by default — no migration risk). +- Gated behind `featureFlags.enableIdbAtRestEncryption` (on by default since v1.23; the passphrase unlock UX is complete — Settings → Privacy). - Web build: passphrase-entry unlock screen on cold start (session-scoped in-memory key). - Tauri build: transparent OS-keychain protection via `tauri-plugin-stronghold` (no user friction). - GDPR-compliant: encrypted blobs are unreadable without the passphrase, even from the browser profile directory. @@ -351,7 +351,7 @@ One-click encrypted export of your entire project library from **Settings → Da ### 🌐 Full Multi-Language Support -Shipped UI locales with **2706 i18n keys** across all 11 languages — zero hardcoded user-facing strings: +Shipped UI locales with **2709 i18n keys** across all 11 languages — zero hardcoded user-facing strings: - 🇩🇪 **German** (Deutsch) - 🇬🇧 **English** @@ -450,8 +450,8 @@ The Settings → AI panel shows a live GPU status badge with adapter details and | **PDF Export** | jsPDF | Client-side, configurable PDF document generation | | **Document Export** | docx + jszip | Word-compatible `.docx` generation (lazy-loaded) | | **PWA** | Service Worker + Web App Manifest v3 | Offline support, installability, Workbox chunking | -| **i18n** | Custom React Context (`I18nContext.tsx`) | 2706 keys × 11 locales (de/en/es/fr/it + ar/he RTL Beta + ja/zh/pt/el Beta); EN fallback; `localStorage` persistence | -| **Testing** | Vitest 4.x (5807+ tests / 481 files) + Playwright E2E | Unit/integration + cross-browser E2E; Stryker mutation (manual workflow) | +| **i18n** | Custom React Context (`I18nContext.tsx`) | 2709 keys × 11 locales (de/en/es/fr/it + ar/he RTL Beta + ja/zh/pt/el Beta); EN fallback; `localStorage` persistence | +| **Testing** | Vitest 4.x (5807+ tests / 485 files) + Playwright E2E | Unit/integration + cross-browser E2E; Stryker mutation (manual workflow) | | **Code Quality** | Biome (lint + format) + TypeScript 7 (tsgo) strict | `--error-on-warnings` in CI; zero `any` policy | | **Visualization** | Force-directed graph | Interactive character relationship network | | **Desktop** | Tauri v2 | Cross-platform installer; auto-updater via `latest.json` | @@ -488,7 +488,7 @@ WorldScript-Studio/ │ ├── sw.js # PWA Service Worker │ └── manifest.json # PWA Web App Manifest v3 ├── tests/ -│ ├── unit/ # Vitest unit tests (5807+ tests, 481 files) +│ ├── unit/ # Vitest unit tests (5807+ tests, 485 files) │ │ ├── ai/ # aiSmallModules, aiCoreFallbackPaths │ │ └── settings/ # WebLlmPanel, AiSections │ └── e2e/ # Playwright specs + helpers.ts @@ -646,10 +646,10 @@ The main pipeline is [`.github/workflows/ci.yml`](.github/workflows/ci.yml). Opt | `deploy` | `main` only | GitHub Pages after **`build` + `e2e`** succeed | | `scorecard` | weekly + `main` push | OpenSSF Scorecard — SARIF uploaded to GitHub Code Scanning | -**Current test metrics (2026-06-11):** -- **5807+ unit tests** across **481 test files** — all passing +**Current test metrics (2026-06-16):** +- **5807+ unit tests** across **485 test files** — all passing - Coverage thresholds: lines ≥ 74 · branches ≥ 60 · functions ≥ 67 · statements ≥ 72 — enforced in CI (see Codecov badge for live metrics) -- i18n: **2706 keys × 11 locales** (en/de/fr/es/it + ar/he RTL Beta + ja/zh/pt/el Beta) +- i18n: **2709 keys × 11 locales** (en/de/fr/es/it + ar/he RTL Beta + ja/zh/pt/el Beta) **CI-cloud-first workflow (recommended):** On constrained hardware run **`pnpm run lint && pnpm run i18n:check && pnpm run typecheck`** locally, then push and let CI handle coverage, E2E, Lighthouse, and Stryker. Authoritative numbers come from CI artifacts (Codecov, JUnit). After CI goes green, update the README badges and `AUDIT.md` quality-gate line from the reported metrics. See **[`docs/CI.md`](docs/CI.md) § Cloud CI-first vs local development** for the full post-merge doc-update checklist. diff --git a/ROADMAP.md b/ROADMAP.md index 76b692274..46eca542f 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -22,28 +22,36 @@ Benchmarks from the UI/PWA deep-dive (implemented in repo, no new mandatory docs --- -## v1.23 — Stabilisation & Verification (ACTIVE) - -**Status:** 🔄 In Progress — P0-Audit-Follow-up vom 12. Juni 2026. Ziel-Release: 2026-06-20. - -**P0 (Release-Blocker):** -- ✅ ROADMAP.md/TODO.md synchron zu v1.22.0 bringen und v1.23-Ziele definieren. -- ✅ Tauri Desktop Pipeline final verifizieren — `tauri-build.yml` grün auf Ubuntu/macOS/Windows (Run #27439443241); `.deb`/`.rpm`/`.AppImage`/`.dmg`/`.msi`/`.exe` Artifacts erzeugt. Signing/Updater offen für `v*` Releases. -- ✅ Dependency-Hygiene abschließen (`pnpm audit`, `pnpm outdated`, `.npmrc`-Hardening dokumentieren, Known Overrides in AUDIT.md). -- ✅ i18n Parity für `ja/zh/pt/el` + RTL (`ar/he`) auf <5 % EN-Placeholders halten (`pnpm run i18n:check` grün, 2590 Keys × 11 Locales). -- ✅ Smoke-Test-Protokoll für v1.22-Features verfasst (`docs/V1.22-SMOKE-TEST.md`) — Live-Demo + lokaler Tauri-Build. Manuelle Ausführung der Matrix (Sign-off) bleibt ein Human-only-Schritt, getrackt in `TODO.md`. - -**P1 (Diese Woche):** -- Coverage-Ziele erreichen (L≥85 %, B≥75 %, F≥80 %) — Fokus auf AI-Routing, Voice, Copilot. -- Local AI & Voice abschließen/härten (Whisper/Kokoro auf Low-End, Model-Integrity, Eco-Mode). -- Error Boundaries + strukturiertes Logging für AI/Worker-Failures verbessern. -- Accessibility Deep-Dive (manuelle Keyboard + Screen-Reader Tests). - -**P2 (Nächster Sprint / v2.0 Foundation):** -- Collaboration E2E-Encryption finalisieren & testen. -- Plugin Registry Beta aus der Sandbox-Härtung herausführen. -- Bundle-Optimierung + Code-Splitting für schwere Chunks. -- Data-Migration/Backup/CloudSync LWW E2E-Tests erweitern. +## Upcoming — v1.24 / v2.0 Foundation (PLANNED) + +Forward-looking work carried out of the v1.23 cycle: + +- **Coverage targets:** lift toward L≥85 % / B≥75 % / F≥80 % — focus on AI routing, Voice, Copilot. +- **Local AI & Voice hardening:** Whisper/Kokoro on low-end devices, model-integrity checks, Eco-Mode. +- **Error boundaries + structured logging** for AI/worker failures. +- **Accessibility deep-dive:** manual keyboard + screen-reader passes. +- **Collaboration:** finalise & test the RTCDataChannel E2E encryption path. +- **Plugin Registry Beta:** graduate from the sandbox-hardening phase. +- **Bundle optimisation:** further code-splitting for heavy chunks. +- **Local-first:** advance ADR-0008 — B2.1 Y.Text migration → B2.2 SoT flip behind `enableLocalFirstSync`. + +--- + +## v1.23.0 — Rebrand to WorldScript Studio + AI/i18n/Local-First Hardening (RELEASED 2026-06-16) + +**Status:** ✅ Released — see [`CHANGELOG.md`](CHANGELOG.md) `[1.23.0]`. + +- **Rebrand StoryCraft → WorldScript Studio:** repository metadata, build/URLs/PWA, Tauri identity, storage keys, UI components, i18n values and placeholder assets (8-phase sweep, PRs #142–#148); WorldScript "W" 8-bit monogram icons. +- **AI error taxonomy + fail-fast retry classification:** localized Copilot/Writer error messages, AI request correlation IDs, transient-vs-fatal retry gating. +- **Local-first data foundation (ADR-0008):** A0.1 perf harness → B0.1 PoC → ADR-0008 → B1.1 Yjs shadow sync, all behind `enableLocalFirstSync` (Redux stays source of truth). +- **Plug-and-play Local AI settings:** capability detection, model downloads, storage management, fallback. +- **OpenRouter + AI Execution Mode settings sections:** localized, modernized (Card + radiogroup), reactive cloud-policy block. +- **Bundle split & budget tightening (PR #130):** named `vendor-webllm`/`vendor-onnx`/`vendor-transformers` chunks; ceilings `6200 KB / 2500 KB entry`. +- **i18n interpolation bug-class fix + `i18nPlaceholders` regression guard.** +- **Tauri blank-screen fix + updater asset-URL normalization.** +- **i18n:** 2 709 keys × 11 locales. + +> Manual rebrand smoke-test sign-off matrix: [`docs/V1.23-REBRAND-SMOKE-TEST.md`](docs/V1.23-REBRAND-SMOKE-TEST.md) (human-only step). --- diff --git a/TODO.md b/TODO.md index 4ef945d27..9d7c3bfdb 100644 --- a/TODO.md +++ b/TODO.md @@ -9,10 +9,12 @@ Status: 🔄 in progress | ⬜ open | ✅ done --- -## v1.23 — P0 Audit Follow-up (ACTIVE) +## v1.23 — P0 Audit Follow-up (DELIVERED 2026-06-16) -> Ziel: Deep-Audit-P0-Items vom 12. Juni 2026 abschließen; Release-Ziel 2026-06-20. -> Archivierte v1.22-Aufgaben → [`docs/history/completed-v1.22.md`](docs/history/completed-v1.22.md). +> All P0 release-blockers closed and v1.23.0 shipped 2026-06-16. The only item still open is the +> human-only manual smoke-test sign-off (below). Forward-looking P1/P2 work has moved to the +> **Upcoming — v1.24 / v2.0 Foundation** block in [`ROADMAP.md`](ROADMAP.md). +> Archived v1.22 tasks → [`docs/history/completed-v1.22.md`](docs/history/completed-v1.22.md). ### P0 — Release-Blocker - ✅ **ROADMAP/TODO sync** — `ROADMAP.md`, `TODO.md` und `AUDIT.md` widerspruchsfrei auf v1.22.0 + v1.23-Ziele gebracht (2026-06-13). Vorheriger Drift: ROADMAP markierte alle P0 ✅, TODO noch ⬜ — jetzt evidenzbasiert abgeglichen. diff --git a/docs/AUDIT-PERFECTION-PLAN-v1.23.md b/docs/AUDIT-PERFECTION-PLAN-v1.23.md index aec581b45..38855210a 100644 --- a/docs/AUDIT-PERFECTION-PLAN-v1.23.md +++ b/docs/AUDIT-PERFECTION-PLAN-v1.23.md @@ -6,6 +6,7 @@ > inline comments are cleared (0 unresolved) before a phase is declared done. **Owner:** maintainer + Claude Code · **Started:** 2026-06-13 · **Baseline version:** 1.22.0 +**v1.23.0 shipped:** 2026-06-16 · **post-release documentation perfection pass:** 2026-06-16 (corpus sync, metric/flag reconciliation, history archival, dependabot cooldown, GitHub release/package rebrand — see `AUDIT.md` § *v1.23.0 Post-Release Documentation Perfection Pass*). Phases 2–6 below remain forward work in the v1.24 / v2.0 cycle. --- diff --git a/docs/FEATURE-PARITY.md b/docs/FEATURE-PARITY.md index f18ad9d35..2fd94c1ac 100644 --- a/docs/FEATURE-PARITY.md +++ b/docs/FEATURE-PARITY.md @@ -1,6 +1,6 @@ # WorldScript Studio — Feature Parity Matrix -**Generated:** 2026-05-28 | **Last updated:** 2026-06-01 (post-parity-audit corrections + Edge-AI flags) | **Auditor:** Senior Principal Engineer +**Generated:** 2026-05-28 | **Last updated:** 2026-06-16 (v1.23.0 reconciliation — 23-flag model, defaults corrected, retired flags removed) | **Auditor:** Senior Principal Engineer **Source of truth:** `features/featureFlags/featureFlagsSlice.ts` **Script:** `pnpm exec tsx scripts/audit-feature-parity.ts` @@ -21,37 +21,49 @@ ## Feature Parity Matrix +> **Defaults reconciled 2026-06-16 (v1.23.0):** the slice now ships the **full feature set** — +> 23 flags, **18 default-on**, **5 opt-in default-off** (`enableRtlLayout`, `enableVoiceSupport`, +> `enableVoiceWasm`, `enableGlobalCopilot`, `enableLocalFirstSync`). The retired/promoted flags +> `enableCodexAutoTracking`, `enableCrossProjectSearch` (both promoted to permanent core), +> `enablePlotBoardV2`, and `enableCloudSync` (retired) are no longer in the slice and have been +> removed from this matrix. Run `pnpm exec tsx scripts/audit-feature-parity.ts` for the live check. + | Feature Flag | Default | Slice | i18n Key | UI Toggle | `useSettingsView` Handler | Runtime Gate | Gate Location | Status | |---|---|---|---|---|---|---|---|---| -| `enableCodexAutoTracking` | ON | ✅ | ✅ | ✅ | ✅ | ✅ | `listenerMiddleware.ts:219` | 🟢 OK | -| `enableStoryBibleAdvanced` | OFF | ✅ | ✅ | ✅ | ✅ | ⚠️ | `listenerMiddleware.ts:247` only | 🟡 Partial | -| `enableBinderResearch` | OFF | ✅ | ✅ | ✅ | ✅ | ✅ | `ManuscriptView.tsx:27` | 🟢 OK | -| `enableCompileWizard` | OFF | ✅ | ✅ | ✅ | ✅ | ✅ | `ExportView.tsx:507` | 🟢 OK | -| `enableProjectHealthScore` | OFF | ✅ | ✅ | ✅ | ✅ | ✅ | `Dashboard.tsx:402` | 🟢 OK | -| `enableCrossProjectSearch` | ON | ✅ | ✅ | ✅ | ✅ | ✅ | `CrossProjectSearchPanel.tsx:133`, `listenerMiddleware.ts:133` | 🟢 OK | -| `enableAppHealthPanel` | OFF | ✅ | ✅ | ✅ | ✅ | ✅ | `GeneralSections.tsx:314` | 🟢 OK | -| `enablePlotBoardV2` | ON | ✅ | ✅ | ✅ | ✅ | ⚠️ | `helpDocRetrieval.ts` docs only | 🟡 Gate unclear | -| `enableDuckDbAnalytics` | OFF | ✅ | ✅ | ✅ | ✅ | ✅ | `useDuckDb.ts:59`, `useAnalytics.ts:50`, `duckdbListenerLoader` | 🟢 OK | -| `enableObjectsGroups` | OFF | ✅ | ✅ | ✅ | ✅ | ✅ | `App.tsx` route guard *(fixed 2026-05-29)* | 🟢 OK | -| `enableMindMaps` | OFF | ✅ | ✅ | ✅ | ✅ | ✅ | `App.tsx` route guard *(fixed 2026-05-29)* | 🟢 OK | -| `enableCharacterInterviews` | OFF | ✅ | ✅ | ✅ | ✅ | ✅ | `App.tsx` route guard *(fixed 2026-05-29)* | 🟢 OK | +| `enableStoryBibleAdvanced` | ON | ✅ | ✅ | ✅ | ✅ | ⚠️ | `listenerMiddleware.ts:247` only | 🟡 Partial | +| `enableBinderResearch` | ON | ✅ | ✅ | ✅ | ✅ | ✅ | `ManuscriptView.tsx:27` | 🟢 OK | +| `enableCompileWizard` | ON | ✅ | ✅ | ✅ | ✅ | ✅ | `ExportView.tsx:507` | 🟢 OK | +| `enableProjectHealthScore` | ON | ✅ | ✅ | ✅ | ✅ | ✅ | `Dashboard.tsx:402` | 🟢 OK | +| `enableAppHealthPanel` | ON | ✅ | ✅ | ✅ | ✅ | ✅ | `GeneralSections.tsx:314` | 🟢 OK | +| `enableDuckDbAnalytics` | ON | ✅ | ✅ | ✅ | ✅ | ✅ | `useDuckDb.ts:59`, `useAnalytics.ts:50`, `duckdbListenerLoader` | 🟢 OK | +| `enableObjectsGroups` | ON | ✅ | ✅ | ✅ | ✅ | ✅ | `App.tsx` route guard *(fixed 2026-05-29)* | 🟢 OK | +| `enableMindMaps` | ON | ✅ | ✅ | ✅ | ✅ | ✅ | `App.tsx` route guard *(fixed 2026-05-29)* | 🟢 OK | +| `enableCharacterInterviews` | ON | ✅ | ✅ | ✅ | ✅ | ✅ | `App.tsx` route guard *(fixed 2026-05-29)* | 🟢 OK | +| `enableLoraAdapters` | ON | ✅ | ✅ | ✅ | ✅ | ✅ | `useWorldScriptAI.ts` reads `selectActiveLoraOllamaTag` → `loraModelPath` *(fixed 2026-05-29)* | 🟢 OK | +| `enablePluginSystem` | ON | ✅ | ✅ | ✅ | ✅ | ✅ | `PluginRegistry.setEnabled()` + `App.tsx` sync *(fixed 2026-05-29)* | 🟢 OK | +| `enableProForge` | ON | ✅ | ✅ | ✅ | ✅ | ✅ | Handler added to `useSettingsView.ts` *(fixed 2026-05-29)*; `WriterViewUI.tsx:23` | 🟢 OK | +| `enableIdbAtRestEncryption` | ON | ✅ | ✅ | ✅ | ✅ | ✅ | `App.tsx` + `IdbUnlockModal` *(fixed 2026-05-29)*; passphrase UX complete (B-1) | 🟢 OK | +| `enableAdaptiveAiEngine` | ON | ✅ | ✅ | ✅ | ✅ | ✅ | `listenerMiddleware.ts` listeners; window gate; `useAdaptiveAi`; `App.tsx initAdaptiveAiOnStartup` *(added 2026-05-31)* | 🟢 OK | +| `enableWebnnInference` | ON | ✅ | ✅ | ✅ | ✅ | ✅ | `adaptiveAiEngine.ts` backend selection; `webnnBridge.ts` *(added 2026-05-31)* | 🟢 OK | +| `enableComputeShaders` | ON | ✅ | ✅ | ✅ | ✅ | ✅ | `computeShaderFactory.ts`; `localRagService.ts` GPU cosine; `useAdaptiveAi` *(added 2026-05-31)* | 🟢 OK | +| `enableWorkerBusV2` | ON | ✅ | ✅ | ✅ | ✅ | ✅ | `packages/worker-bus` orchestration; `ensureWebLlmPool()` / WorkerBus init | 🟢 OK | +| `enableRustCompute` | ON | ✅ | ✅ | ✅ | ✅ | ✅ | Tauri Rust compute (`src-tauri/`); verified via `tauri-build.yml` (no PR-CI gate) | 🟢 OK | | `enableRtlLayout` | OFF | ✅ | ✅ | ✅ | ✅ | ✅ | `App.tsx:271` | 🟢 OK | -| `enableCloudSync` | OFF | ✅ | ✅ | ✅ | ✅ | ✅ | `CloudSyncBackend.create()` structural `featureFlagEnabled` param *(fixed 2026-05-29)* | 🟢 OK | -| `enableLoraAdapters` | OFF | ✅ | ✅ | ✅ | ✅ | ✅ | `useWorldScriptAI.ts` reads `selectActiveLoraOllamaTag` → `loraModelPath` *(fixed 2026-05-29)* | 🟢 OK | -| `enablePluginSystem` | OFF | ✅ | ✅ | ✅ | ✅ | ✅ | `PluginRegistry.setEnabled()` + `App.tsx` sync *(fixed 2026-05-29)* | 🟢 OK | | `enableVoiceSupport` | OFF | ✅ | ✅ | ✅ | ✅ | ✅ | `App.tsx:568` | 🟢 OK | -| `enableProForge` | OFF | ✅ | ✅ | ✅ | ✅ | ✅ | Handler added to `useSettingsView.ts` *(fixed 2026-05-29)*; `WriterViewUI.tsx:23` | 🟢 OK | -| `enableIdbAtRestEncryption` | OFF | ✅ | ✅ | ✅ | ✅ | ✅ | `App.tsx` + `IdbUnlockModal` *(fixed 2026-05-29)*; passphrase UX complete (B-1) | 🟢 OK | | `enableVoiceWasm` | OFF | ✅ | ✅ | ✅ | ✅ | ✅ | `useVoice.ts:29` + handler added *(fixed 2026-05-29)* | 🟢 OK | -| `enableAdaptiveAiEngine` | OFF | ✅ | ✅ | ✅ | ✅ | ✅ | `listenerMiddleware.ts` listeners; window gate; `useAdaptiveAi`; `App.tsx initAdaptiveAiOnStartup` *(added 2026-05-31)* | 🟢 OK | -| `enableWebnnInference` | OFF | ✅ | ✅ | ✅ | ✅ | ✅ | `adaptiveAiEngine.ts` backend selection; `webnnBridge.ts` *(added 2026-05-31)* | 🟢 OK | -| `enableComputeShaders` | OFF | ✅ | ✅ | ✅ | ✅ | ✅ | `computeShaderFactory.ts`; `localRagService.ts` GPU cosine; `useAdaptiveAi` *(added 2026-05-31)* | 🟢 OK | +| `enableGlobalCopilot` | OFF | ✅ | ✅ | ✅ | ✅ | ✅ | `App.tsx` lazy `CopilotPanel` mount; `hooks/useGlobalCopilot.ts` | 🟢 OK | +| `enableLocalFirstSync` | OFF | ✅ | ✅ | ✅ | ✅ | ✅ | shadow Yjs projection (ADR-0008); Redux stays SoT | 🟢 OK | --- -## Drift Summary (2026-06-01 — All critical drifts resolved) +## Drift Summary (2026-06-16 — reconciled to the v1.23.0 23-flag model) -**All 8 critical drifts from the 2026-05-29 parity audit have been fixed.** The matrix is now fully green. +**All 8 critical drifts from the 2026-05-29 parity audit remain fixed.** The 2026-06-16 pass +corrected the `Default` column (the slice ships the full set: 18 on, 5 opt-in off), removed the +four retired/promoted flags (`enableCodexAutoTracking`, `enableCrossProjectSearch`, +`enablePlotBoardV2`, `enableCloudSync`), and added the four flags introduced since v1.21 +(`enableWorkerBusV2`, `enableRustCompute`, `enableGlobalCopilot`, `enableLocalFirstSync`). +The matrix is now fully green; `pnpm exec tsx scripts/audit-feature-parity.ts` is the live gate. ### ✅ Resolved Drifts (2026-05-29 parity audit) diff --git a/docs/IDB-ENCRYPTION.md b/docs/IDB-ENCRYPTION.md index c6c9d078b..22b925475 100644 --- a/docs/IDB-ENCRYPTION.md +++ b/docs/IDB-ENCRYPTION.md @@ -1,7 +1,7 @@ # IndexedDB At-Rest Encryption — Implementation **Status:** ✅ Implemented + Phase 1.1 UX complete — `services/storage/storageEncryptionService.ts` (v1.19.0 B-1 + 2026-05-31 Local AI Perfection Phase 1.1) -**Feature flag:** `enableIdbAtRestEncryption` (off by default — enable via Settings → Privacy) +**Feature flag:** `enableIdbAtRestEncryption` (on by default since v1.23 — manage via Settings → Privacy) **Tracking:** SEC-3 (Master Plan Phase 2 delivery) --- @@ -10,7 +10,7 @@ WorldScript Studio stores all project data in IndexedDB. API keys were already encrypted at rest via `dbService.ts` using AES-256-GCM with a locally-generated `CryptoKey`. As of v1.19.0 (B-1), `services/storage/storageEncryptionService.ts` extends at-rest encryption to all IDB stores using a passphrase-derived key, protecting data against offline extraction (e.g. from a shared or compromised browser profile). -The encryption service is gated behind `featureFlags.enableIdbAtRestEncryption` (off by default — enable in Settings → Privacy → "Encrypt project data at rest"). **Passphrase UX is complete as of 2026-05-31 (Phase 1.1):** +The encryption service is gated behind `featureFlags.enableIdbAtRestEncryption` (on by default since v1.23 — manage in Settings → Privacy → "Encrypt project data at rest"). **Passphrase UX is complete as of 2026-05-31 (Phase 1.1):** - `IdbUnlockModal` — prompts for passphrase on cold start when flag is on; rate-limiting: 3 failures → 5 s lockout, 6 failures → 30 s lockout - **Session lock** — `lockSession()` clears the in-memory key; "Lock Session" button in Settings → Privacy - **Key rotation** — `rotateKey(old, new)` re-encrypts all 5 IDB stores atomically via `reEncryptAllAppData()` + `reEncryptAllSnapshots()`; Settings → Privacy → Change Passphrase diff --git a/docs/PLUGINS-BETA.md b/docs/PLUGINS-BETA.md index 5a17ee807..74e75c79a 100644 --- a/docs/PLUGINS-BETA.md +++ b/docs/PLUGINS-BETA.md @@ -1,7 +1,7 @@ # Plugin System (Beta) -**Status:** Beta / Opt-in (v1.22.0) -**Feature Flag:** `enablePluginSystem` (off by default) +**Status:** Beta (v1.22.0) +**Feature Flag:** `enablePluginSystem` (on by default since v1.23; disable via Settings → Experimental flags) ## Overview diff --git a/docs/adr/0008-local-first-data-model.md b/docs/adr/0008-local-first-data-model.md index ee7f7f566..0b526a8f4 100644 --- a/docs/adr/0008-local-first-data-model.md +++ b/docs/adr/0008-local-first-data-model.md @@ -7,7 +7,7 @@ ## Context -StoryCraft is **offline-first** (encrypted IndexedDB + Tauri FS persistence, `redux-undo` history) +WorldScript Studio is **offline-first** (encrypted IndexedDB + Tauri FS persistence, `redux-undo` history) but **not local-first** in the CRDT sense. `services/collaborationService.ts` instantiates an *ephemeral* `Y.Doc` only on `connect()` and exposes one `getSharedText('manuscript')` seam; the manuscript's source of truth is a plain Redux object (`ProjectData`, `StorySection.content: string`). diff --git a/CHECKPOINT-2026-05-24.md b/docs/history/CHECKPOINT-2026-05-24.md similarity index 100% rename from CHECKPOINT-2026-05-24.md rename to docs/history/CHECKPOINT-2026-05-24.md diff --git a/CHECKPOINT-2026-06-06.md b/docs/history/CHECKPOINT-2026-06-06.md similarity index 100% rename from CHECKPOINT-2026-06-06.md rename to docs/history/CHECKPOINT-2026-06-06.md diff --git a/docs/EDGE_AI_PERFECT_PLAN.md b/docs/history/EDGE_AI_PERFECT_PLAN.md similarity index 100% rename from docs/EDGE_AI_PERFECT_PLAN.md rename to docs/history/EDGE_AI_PERFECT_PLAN.md diff --git a/docs/EDGE_AI_ZWISCHENSTAND.md b/docs/history/EDGE_AI_ZWISCHENSTAND.md similarity index 100% rename from docs/EDGE_AI_ZWISCHENSTAND.md rename to docs/history/EDGE_AI_ZWISCHENSTAND.md diff --git a/WIEDERAUFNAHME.md b/docs/history/WIEDERAUFNAHME.md similarity index 98% rename from WIEDERAUFNAHME.md rename to docs/history/WIEDERAUFNAHME.md index 83f675e9a..28fa1cdde 100644 --- a/WIEDERAUFNAHME.md +++ b/docs/history/WIEDERAUFNAHME.md @@ -256,7 +256,7 @@ Wenn du nach etwas suchst: > - Typecheck laufen lassen, wenn du nur Strings/UI geändert hast > - `pnpm run build` ohne dringenden Grund (langsam, RAM-fressend) > -> **Fragen?** Siehe `docs/EDGE_AI_PERFECT_PLAN.md` für die große Vision und `docs/EDGE_AI_ZWISCHENSTAND.md` für alle Details. +> **Fragen?** Siehe `EDGE_AI_PERFECT_PLAN.md` für die große Vision und `EDGE_AI_ZWISCHENSTAND.md` für alle Details (beide jetzt in `docs/history/`). --- diff --git a/features/featureFlags/featureFlagsSlice.ts b/features/featureFlags/featureFlagsSlice.ts index 1a7345d43..a6333882d 100644 --- a/features/featureFlags/featureFlagsSlice.ts +++ b/features/featureFlags/featureFlagsSlice.ts @@ -30,13 +30,13 @@ export interface FeatureFlagsState { enableLoraAdapters: boolean; /** Plugin system v0.1 — ESM-based extensions with sandboxed capability API (default: true). */ enablePluginSystem: boolean; - /** Voice Full Support — opt-in voice command, dictation and audio navigation (default: true). */ + /** Voice Full Support — opt-in voice command, dictation and audio navigation (default: false — requires browser mic permission). */ enableVoiceSupport: boolean; /** ProForge Ultimate Author Pipeline — agentic 8-stage manuscript pipeline (default: true). */ enableProForge: boolean; /** IDB at-rest encryption — AES-256-GCM passphrase-derived key for all manuscript stores (default: true). */ enableIdbAtRestEncryption: boolean; - /** Voice WASM engines — local Whisper STT + Silero VAD via ONNX; no cloud audio routing (default: true). */ + /** Voice WASM engines — local Whisper STT + Silero VAD via ONNX; no cloud audio routing (default: false — ~57 MB Whisper download, explicit opt-in). */ enableVoiceWasm: boolean; /** Adaptive AI Engine — runtime device profiler + automatic backend/model selection (default: true). */ enableAdaptiveAiEngine: boolean; @@ -48,7 +48,7 @@ export interface FeatureFlagsState { enableWorkerBusV2: boolean; /** Rust Compute — offload heavy tasks to Tauri Rust TaskSupervisor (default: true). */ enableRustCompute: boolean; - /** Global AI Copilot — beginner-friendly, context-aware, local-first in-app live assistant (default: true). */ + /** Global AI Copilot — beginner-friendly, context-aware, local-first in-app live assistant (default: false — ambient AI, user opt-in). */ enableGlobalCopilot: boolean; /** Local-First sync (shadow) — mirror the project into a Yjs doc + y-indexeddb; Redux stays SoT (default: false). */ enableLocalFirstSync: boolean;