From 8d1997ee0a8df823f92eae04112cc8cde635d355 Mon Sep 17 00:00:00 2001 From: qnbs <155236708+qnbs@users.noreply.github.com> Date: Wed, 26 Aug 2026 02:48:30 +0200 Subject: [PATCH 1/6] docs(architecture): establish reuse and ownership authority Adds ARCHITECTURE-REUSE-OWNERSHIP.md, codifying the decision order this repo already follows implicitly (fix existing owner -> extend existing owner -> narrow adapter -> extract real duplication -> refactor authority -> new subsystem only if genuinely necessary) as an explicit, checkable policy: ONE PRODUCT MODEL, ONE VERSIONED PROJECT TRUTH, ONE AUTHORITY PER SEMANTIC CAPABILITY. Distinguishes product feature truth, runtime capability truth, subsystem admission, and diagnostics/evidence as separate concerns that must not be conflated into a single authority. Reconciled directly onto current main from PR #477's frozen head (2a6da40b) -- main has made no changes to this path since the PR branched, so no textual or semantic conflict exists. --- .../ARCHITECTURE-REUSE-OWNERSHIP.md | 551 ++++++++++++++++++ 1 file changed, 551 insertions(+) create mode 100644 docs/architecture/ARCHITECTURE-REUSE-OWNERSHIP.md diff --git a/docs/architecture/ARCHITECTURE-REUSE-OWNERSHIP.md b/docs/architecture/ARCHITECTURE-REUSE-OWNERSHIP.md new file mode 100644 index 000000000..e2a12f3c5 --- /dev/null +++ b/docs/architecture/ARCHITECTURE-REUSE-OWNERSHIP.md @@ -0,0 +1,551 @@ +# WorldScript Studio — Architecture Reuse & Ownership Policy + +**Status:** Binding implementation-governance companion to the current architecture roadmap set. +**Date:** 2026-08-24 +**Applies to:** React/PWA, Tauri transitional maintenance, Rust Core extraction, Qt 6/Qt Quick migration, and any future separately admitted renderer such as GPUI. +**Does not replace:** ADR-0021, the canonical numbered native roadmap, or `DESKTOP-MIGRATION-ROADMAP-REV3.md`. + +--- + +## 1. Purpose + +WorldScript Studio already contains mature project, persistence, encryption, worker, AI, diagnostics, feature-gating, import/export, and desktop-abstraction primitives. The main architecture risk is therefore no longer a lack of abstraction. It is accidental duplication while PWA excellence, Rust Core extraction, and Qt migration proceed in parallel. + +The governing principle is: + +> **Perfect and compose the existing authority first. Introduce a new subsystem only when a real capability or ownership gap remains and the new boundary has a distinct responsibility that cannot be expressed safely by an existing authority or a narrow adapter.** + +This policy prevents the repository from becoming separate React, PWA, Tauri, Qt, Rust, and future-GPUI product architectures. + +The target is: + +```text +ONE PRODUCT MODEL +ONE VERSIONED PROJECT TRUTH +ONE AUTHORITY PER SEMANTIC CAPABILITY + ++ renderer-specific presentation ++ platform-specific adapters ++ browser-native PWA enhancements ++ Rust Core where portability, security, durability, or headless authority justify it +``` + +--- + +## 2. Authority hierarchy + +### 2.1 Native/Desktop strategy + +For native/Desktop work, read these as one authority chain: + +1. ADR-0021 fixes the Qt-first / GPUI-deferred direction. +2. `docs/native/ROADMAP-QT-GPUI-DESKTOP.md` remains the canonical numbered execution roadmap. +3. `docs/native/DESKTOP-MIGRATION-ROADMAP-REV3.md` is the normative Revision-3 refinement for #332, Tauri stop-loss, G1.5, Wave 2.5, G2.5, Qt differential qualification, and the related R-15 handoff rules. +4. `docs/native/TAURI-TRANSITIONAL-MAINTENANCE.md` is the operational Tauri support and stop-loss policy. +5. `docs/native/CORE-MIGRATION-LEDGER.md` records current authority, parity maturity, and migration state capability by capability. +6. This document constrains *how* new architecture may be introduced while those plans execute. + +Where a subject is explicitly narrowed or strengthened by Revision 3, Revision 3 controls. + +### 2.2 PWA strategy + +Issue #478 is the PWA excellence umbrella. `docs/PWA-AUDIT.md` is to be upgraded in place into the living PWA architecture and acceptance document rather than spawning multiple competing PWA roadmaps. + +PWA work may exploit browser-native capabilities where they improve the product, but browser APIs must not leak into Rust/Core or native `DesktopPlatform` contracts merely for implementation symmetry. + +--- + +## 3. Capability boundaries before package/crate boundaries + +A capability name in a roadmap does **not** authorize a new crate, package, service, manager, store, registry, queue, or state machine. + +Names such as `worldscript-storage`, `worldscript-crypto`, `worldscript-ai`, `worldscript-tasks`, or similar roadmap concepts describe responsibilities. They are not mandatory repository topology. + +Prefer extending an existing cohesive owner. Split only when at least one material benefit is demonstrated: + +- clearer semantic ownership; +- security-boundary isolation; +- dependency isolation; +- deterministic/headless test isolation; +- renderer reuse that already exists or is immediately required; +- build/runtime isolation; +- removal of existing production duplication; +- a measurable performance or lifecycle benefit that cannot be obtained within the current boundary. + +Do not split merely because a diagram looks cleaner or a future renderer exists. + +--- + +## 4. Reuse-first architecture gate + +Before adding a non-trivial new architectural component, record: + +```text +EXISTING AUTHORITY / SEED AUDIT + +Capability: +Current semantic owner: +Current runtime owner(s): +Existing reusable primitives: +Existing fixtures/tests: +Known gap: + +Can the current owner be extended safely? YES / NO +Can a narrow adapter solve the gap? YES / NO + +Would the proposed component duplicate: + schema/validation? YES / NO + persistence? YES / NO + migration? YES / NO + encryption? YES / NO + locking/admission? YES / NO + retries/queueing? YES / NO + task supervision? YES / NO + capability detection? YES / NO + external-input routing? YES / NO + diagnostics/redaction? YES / NO + feature-gating truth? YES / NO + +If new architecture is still required: +Why no existing authority can own it: +Exact responsibility: +Explicit non-responsibilities: +Which existing duplication it replaces or avoids: +Migration/compatibility strategy: +Rollback/kill criterion: +``` + +A greenfield subsystem that cannot answer these questions should not be merged. + +--- + +## 5. Preferred implementation order + +Use this order unless security/data-integrity evidence requires a different one: + +```text +1. FIX THE EXISTING OWNER +2. EXTEND THE EXISTING OWNER +3. ADD A NARROW ADAPTER +4. EXTRACT A SHARED PRIMITIVE FROM REAL DUPLICATION +5. REFACTOR AUTHORITY +6. ONLY THEN CREATE A NEW SUBSYSTEM +``` + +A new component is justified when the repository lacks the capability or the existing boundary cannot enforce the required invariant. A new component is not justified merely because the functionality is new to one renderer. + +--- + +## 6. Product semantics vs platform implementation + +Semantic/data-format/interoperability parity is required where product truth is shared. Implementation parity is not. + +```text + PRODUCT SEMANTICS + project / commands / validation / rules + │ + ┌─────────────────┴─────────────────┐ + │ │ + WEB / PWA APP NATIVE APP + React / Vite Qt / QML target + │ │ + browser capability/adapters DesktopPlatform + │ │ + IDB / SW / OPFS / Rust Core authority + WebGPU / Web APIs where portability is proven +``` + +Examples: + +- PWA Service Worker update mechanics and a future Qt updater are different implementations. They may share compatibility and data-integrity semantics, not necessarily one updater implementation. +- Browser File System Access handles are PWA adapter details. They do not belong in project/domain models. +- Browser WebGPU/WebLLM remains a PWA execution adapter even if portable AI request/result/error contracts move toward Core authority. +- Qt Quick graphics and lifecycle APIs remain renderer-specific and must not leak into shared/domain code. + +--- + +## 7. Existing authorities and seeds that must be audited before new work + +### 7.1 Feature/product maturity + +`features/featureCatalog.ts` plus the feature-flag state owns product feature maturity/default/gating truth. + +A PWA runtime-capability registry must not replace feature flags. Keep distinct: + +```text +Product feature plane: +"Has WorldScript admitted/enabled feature X?" + +Runtime capability plane: +"Can this browser expose primitive Y?" + +Subsystem admission plane: +"Can this concrete workflow safely use Y?" +``` + +### 7.2 Persistence + +Existing high-level authority includes: + +- `services/storageService.ts`; +- `services/storageBackend.ts`; +- existing IndexedDB stores; +- filesystem adapter behavior while Tauri remains supported; +- `app/persistenceCoordinator.ts`; +- `app/persistedStateFlush.ts`. + +Do not introduce a second live-project authority to add OPFS or user-selected file handles. + +### 7.3 PWA encryption migration admission + +`services/storage/protectedWriteAdmission.ts` already provides security-specific shared/exclusive Web Locks admission with a documented fallback. + +A future generic multi-context layer may reuse/extract browser primitives but must not replace or weaken this security policy. + +### 7.4 Local-AI multi-context coordination + +`packages/ai-core/src/tabLeaderElection.ts` already uses BroadcastChannel plus a heartbeat for heavy-inference leadership. + +A generic PWA coordination layer must audit this implementation first and either compose it, deliberately replace it with equivalent/proven semantics, or leave it specialized. Do not run two independent leadership authorities indefinitely. + +### 7.5 Browser local AI + +Existing architecture includes: + +- `services/localAiFacade.ts`; +- AI-core; +- WorkerBus v2; +- `services/ai/adaptiveAiEngine.ts`; +- `services/ai/localAiDeviceProfiler.ts`; +- WebGPU detection; +- GPU resource management; +- inference progress/lifecycle facilities. + +Browser-local AI work must harden/productize this stack. Do not introduce a parallel `PwaAiService` or second backend-selection layer. + +### 7.6 OPFS + +OPFS is already used by `workers/v2/duckdb.worker.ts` via `navigator.storage.getDirectory()` and a DuckDB file handle with fallback. + +Treat this as the first production seed. Do not describe OPFS as wholly greenfield and do not create a whole-application OPFS project database merely because OPFS exists. + +### 7.7 PWA install/update lifecycle + +Existing authority begins in: + +- `public/sw.js`; +- `register-sw.ts`; +- existing PWA install/update UI. + +Future update safety work must refactor this path in place. A second independent update manager is forbidden unless the old path is explicitly retired. + +### 7.8 External entry/import + +Existing inputs include: + +- PWA share-target/query handling; +- manifest launch/protocol/shortcut declarations; +- Tauri deep links; +- the existing project import thunk and validation flow. + +These should converge on one typed, bounded, untrusted external-launch intent boundary rather than each feature implementing its own privileged parser. + +### 7.9 Diagnostics + +Existing logging, diagnostic-model, sink, and redaction facilities remain the seed. PWA capability diagnostics and Qt/native diagnostics may add adapters/snapshots, but must not create unredacted parallel logging authorities. + +--- + +## 8. PWA architecture rules for #478 and #480–#489 + +### 8.1 #489 — capability/admission facade + +#489 is an aggregation and explanation layer, not a second set of low-level probes. + +It should compose existing subsystem probes and expose normalized runtime facts. Workflow-specific admission remains in the owning subsystem. + +Example: + +```text +PWA capability: WebGPU = AVAILABLE +AI workflow admission: model X = DENIED +Reason: insufficient adapter/memory/workload policy +``` + +Both statements may be true simultaneously. + +### 8.2 #480 — multi-context ownership + +Do not create one global lock manager owning storage security, projects, AI, updates, and backups. + +If common browser primitives are extracted, keep them narrow: + +- context identity; +- lock request helper; +- typed bounded BroadcastChannel envelope; +- channel lifecycle; +- capability/fallback state. + +Policy remains with subsystem owners: + +```text +storage-security admission -> storage/security +project writer ownership -> project/PWA coordination +local-AI ownership -> AI subsystem +update activation -> SW/update subsystem +``` + +BroadcastChannel is advisory coordination, never durable truth. + +### 8.3 #481 — File System Access + +Reuse existing project import/export parsing, validation, and commands. + +Default authority: + +```text +browser storage = live project authority +selected external file = explicit export/mirror/backup target +``` + +A future mode where an external file becomes authoritative requires a separate explicit conflict/authority decision. Retaining a file handle must not silently create dual authority. + +### 8.4 #482 — storage hierarchy + +Preserve IDB for authoritative structured PWA data unless evidence justifies a deliberate migration. + +Use OPFS through data-class-specific repositories for measured large/binary/random-access workloads such as model artifacts, analytics databases, or regenerable indexes. + +Do not make OPFS another whole-application `StorageBackend` competing with IndexedDB for ordinary project truth. + +### 8.5 #483 — browser-local AI + +The existing local-AI facade remains the single product abstraction. + +A durable model-artifact manifest/catalog may be introduced if current architecture lacks version/integrity/stored-size/backend/compatibility lifecycle truth, but it must live beneath the existing local-AI abstraction. + +No hidden local-to-cloud fallback is permitted. + +### 8.6 #484 — Capture Inbox and external launch + +A bounded durable Capture Inbox is a legitimate new domain capability because it does not currently exist. + +After a captured item is assigned, reuse existing project entities/surfaces. Do not create permanent parallel `CaptureNote`, `CaptureScene`, `CaptureCharacter`, etc. models. + +Share target, protocol handler, shortcuts, launch queue, file handling, and Tauri deep links should normalize to one typed `ExternalLaunchIntent` before privileged navigation or mutation. + +### 8.7 #485 — Service Worker update safety + +Current SW registration/activation remains the implementation seed. + +Refactor to one authoritative update state machine. Do not leave unconditional `skipWaiting()` plus unconditional `controllerchange` reload as the final dirty-session policy. + +Use existing persistence coordination, flush, migration-journal, and multi-client evidence. A save required for update admission must be confirmed durable according to the current persistence contract; never fake a successful flush to activate new code. + +### 8.8 #486 — installed PWA shell + +Evolve the existing manifest and `window.worldScriptPWA`/registration state. Do not create a second independent install/update state unless the old state is deliberately migrated and retired. + +Display mode may alter shell/presentation behavior but not business/domain semantics. + +### 8.9 #487 — mobile + +Mobile work is presentation, interaction, viewport, performance, and capability adaptation over the same project/domain model. + +Do not create a divergent mobile project or editor-domain model merely because layout and input differ. + +### 8.10 #488 — deferred work + +Authoritative manuscript autosave, encryption commit, key rotation, only-copy backup, or schema-migration finalization must not depend on browser Background Sync. + +Use a small bounded/versioned scheduling journal only for safe idempotent deferred work. Reuse existing WorkerBus/application handlers as executors where appropriate; do not create a second general task framework. + +--- + +## 9. Native/Rust/Qt rules + +### 9.1 Core Migration Ledger is the anti-rewrite control + +Authority moves only when parity is proven. A Rust implementation existing in the repository does not imply it is authoritative. + +For project/schema work, converge in this order: + +1. canonical persisted schema version; +2. explicit unknown-field policy; +3. import-vs-repair validation semantics; +4. golden accept/reject fixtures; +5. migration fixture parity; +6. real serialized/package-format parity; +7. explicit authority switch. + +Qt must consume the resulting authority, not create another schema. + +### 9.2 R-15/#445 is canonical native secure-storage integration + +Keep #445 as the integration/closure issue for native renderer-neutral encryption, durability, recovery, migration admission, and record identity. + +#357/#359/#360/#361 remain detailed requirements and provenance. Do not create Qt-private or new Tauri-private crypto/storage authority. + +### 9.3 Tasks + +Do not replace the mature TypeScript WorkerBus with a broad Rust task framework in one migration. + +Move task classes when renderer-neutral execution, cancellation/progress semantics, headless ownership, or native-service integration produces proven value. + +### 9.4 AI + +Portable AI request/result/error/cancellation/provider-policy contracts may migrate toward Core authority when justified. Browser WebGPU/WebLLM implementation remains a PWA adapter. Native local-AI backends may use different adapters. + +Do not port browser execution machinery to Rust merely for symmetry. + +### 9.5 Updates + +Share portable concepts such as version compatibility, migration admission, data-integrity rules, rollback expectations, and evidence maturity. + +Do not hide fundamentally different Service Worker, native updater, package-signing, and platform trust mechanisms behind a premature one-size-fits-all implementation. + +--- + +## 10. Cross-renderer evidence architecture + +Share semantic scenario definitions and evidence schema, not necessarily one mega-driver. + +Preferred shape: + +```text +Scenario specification / fixture / metrics / thresholds + │ + ┌───────────┼───────────┐ + │ │ │ + PWA driver Tauri driver Qt driver +``` + +This preserves comparable evidence without forcing artificial automation parity. + +`GOLDEN-DESKTOP-LIFECYCLE-332` remains the canonical lifecycle/performance scenario family for the #332 lineage. + +Every driver must preserve the same semantic workload and report compatible evidence fields while remaining free to use renderer-native instrumentation. + +--- + +## 11. Issue-specific reconciliation rules + +### #332 + +Keep #332 as the canonical cross-renderer lifecycle/performance evidence source. Do not create another broad Linux/WebKit/Qt performance umbrella unless a distinct proven root cause warrants a narrowly owned bug. + +### #341 + +Preserve the original user report and historical evidence. Add/maintain a shared readability oracle for contrast, font metrics, caret/scroll/overlay alignment, theme transitions, scaling, and relevant RTL/IME behavior. PWA and packaged/native evidence consume the same semantic oracle. + +### #347 + +Scenario/workspace features must project the canonical project model. Do not create a parallel screenplay project persistence format. + +### #348 + +Marketplace work extends the existing plugin registry/execution model with provenance, admission, compatibility, permission, revocation, quarantine, and UX. Do not create a second marketplace-only plugin runtime. + +### #349 + +Invite links extend the existing collaboration transport/session semantics. They are admission/scope/expiry/replay UX, not a second collaboration engine. Do not claim server-like revocation semantics if the architecture cannot provide them. + +### #446/#447/#449/#450 + +These remain dedicated quality/build authorities for coverage, suppression debt, locale bundle policy, and bundle budgets. PWA/native programs consume their evidence; they do not duplicate their tooling. + +--- + +## 12. Architecture PR checklist + +Every non-trivial architecture/migration PR should answer: + +```text +[ ] Existing semantic owner identified +[ ] Existing reusable primitives listed +[ ] No duplicate persistent authority +[ ] No duplicate schema/validation +[ ] No duplicate crypto/migration state machine +[ ] No duplicate queue/task scheduler without explicit justification +[ ] No duplicate runtime capability probe +[ ] No duplicate external-input parser +[ ] No renderer-specific product truth +[ ] Browser APIs stay out of Rust/native domain contracts +[ ] Qt APIs stay out of shared/domain code +[ ] Tauri-only investment passes TM policy +[ ] PWA specialization has explicit fallback/degradation semantics +[ ] State migration/versioning impact is explicit +[ ] Negative/failure tests are defined +[ ] Diagnostics remain privacy-safe +[ ] Existing behavior has compatibility/regression evidence +[ ] Any replaced duplicate has a removal/deprecation plan +[ ] Authority switch is explicit and evidence-backed +``` + +--- + +## 13. Refactor justification + +A substantial refactor is justified when at least one is true: + +- semantic authority is currently split and produces contradictory behavior; +- a security/data-integrity boundary cannot be enforced otherwise; +- renderer migration is blocked by concrete coupling; +- deterministic testing is impossible under current ownership; +- duplicate production implementations already exist; +- measured performance/lifecycle evidence shows the current boundary is structurally inadequate. + +A refactor is not justified merely because: + +- a future renderer exists; +- a browser/native API is fashionable; +- a new crate/service would make a diagram symmetrical; +- code could theoretically be shared; +- one platform supports a richer capability than another. + +--- + +## 14. Dependency and sequencing rule + +Do not use architecture cleanup as an excuse to bypass the active evidence/security/Core program. + +Recommended dependency direction: + +```text +Rev-3 / #332 classification + │ + ├── preserve active H1 evidence isolation + ├── Core authority convergence + ├── R-15 canonical native security + └── bounded Qt qualification + +#478 PWA excellence + │ + ├── #489 capability facade + ├── #480 multi-context correctness + ├── #482 storage health/tiering + ├── #485 update correctness + ├── #484 external intent/capture + │ ├── #481 files + │ └── #486 installed shell + ├── #483 local-AI perfection + ├── #488 deferred work + └── #487 mobile presentation +``` + +The graph is not a strict waterfall. Child work may proceed in parallel when its dependencies are satisfied and ownership is clear. + +--- + +## 15. Final rule + +```text +Keep every proven primitive that still has the right responsibility. +Strengthen it. +Compose it. +Extract only the truly shared part after real duplication is visible. +Retire duplicates when consolidation happens. +Create new architecture only where a real capability has no correct existing home. +``` + +The goal is not the fewest files or the most abstractions. The goal is **one coherent product with explicit authority and evidence-backed boundaries**. \ No newline at end of file From cde65f696ff1ead9c4ef9a6b895b3340fa92209f Mon Sep 17 00:00:00 2001 From: qnbs <155236708+qnbs@users.noreply.github.com> Date: Wed, 26 Aug 2026 02:48:51 +0200 Subject: [PATCH 2/6] docs(native): reconcile Qt migration revision 3 and Tauri handoff gates Adds DESKTOP-MIGRATION-ROADMAP-REV3.md as the normative Revision-3 amendment to the desktop migration roadmap: Qt 6/QML as the primary native UI target, Tauri as transitional only, the renderer-neutral Rust Core, R-15 durability/recovery preservation, DesktopPlatform boundary, GPUI gated strictly after Qt, and G1.5/G2.5/Wave-2.5 sequencing. Section 22's "current/next Core tranche" is written to name CORE-MIGRATION-LEDGER.md's actual row priorities precisely -- Wave-2 first-slice convergence (rows 1-3), the project state-shape compatibility adapter as a distinct G1 prerequisite (row 9), and the bounded task-supervision/diagnostics fast-follows (rows 4-5) -- rather than a single ambiguous "storage-semantics convergence" phrase that could be misread as including row 6 (IDB/ encryption), which stays out of scope until Wave 3-4. Extends QT-EARLY-KILLER-GATES.md with the Linux/Wayland/NVIDIA graphics differential lane (QF-D) as a first-class, checklist-tracked gate rather than a roadmap-only mention, and TAURI-TRANSITIONAL-MAINTENANCE.md with the authoritative #332 exit-criteria section, the unconditional stop path for high-coupling/low-reuse Tauri-only investment, and the clean-process- tree lifecycle requirement. Reconciled directly onto current main from PR #477's frozen head (2a6da40b) -- main has made no changes to any of these three paths since the PR branched, so no textual or semantic conflict exists; ADR-0021, CORE-MIGRATION-LEDGER.md, and ROADMAP-QT-GPUI-DESKTOP.md (the current canonical authorities these files defer to) are also unchanged since then. --- docs/native/DESKTOP-MIGRATION-ROADMAP-REV3.md | 982 ++++++++++++++++++ docs/native/QT-EARLY-KILLER-GATES.md | 108 +- docs/native/TAURI-TRANSITIONAL-MAINTENANCE.md | 142 ++- 3 files changed, 1183 insertions(+), 49 deletions(-) create mode 100644 docs/native/DESKTOP-MIGRATION-ROADMAP-REV3.md diff --git a/docs/native/DESKTOP-MIGRATION-ROADMAP-REV3.md b/docs/native/DESKTOP-MIGRATION-ROADMAP-REV3.md new file mode 100644 index 000000000..b68fc57ca --- /dev/null +++ b/docs/native/DESKTOP-MIGRATION-ROADMAP-REV3.md @@ -0,0 +1,982 @@ +# WorldScript Studio — Desktop Migration Roadmap Revision 3 + +**Status:** Proposed binding refinement to ADR-0021 and `ROADMAP-QT-GPUI-DESKTOP.md` +**Repository:** `qnbs/WorldScript-Studio` +**Date:** 2026-08-24 +**Primary native target:** Qt 6 + Qt Quick/QML +**Authoritative product core:** Rust +**Transitional desktop runtime:** Tauri 2 / system WebView +**Web product:** React/Vite PWA +**Deferred exploration:** GPUI +**CEF:** retired as an implementation target +**Cross-cutting implementation governance:** [`../architecture/ARCHITECTURE-REUSE-OWNERSHIP.md`](../architecture/ARCHITECTURE-REUSE-OWNERSHIP.md) + +--- + +## 1. Executive decision + +WorldScript Studio must no longer optimize toward **“a perfect Tauri desktop before Qt may start.”** + +The binding program objective becomes: + +> **Perfect the renderer-neutral product foundation; fix portable defects; classify runtime-specific defects to a defensible stop decision; convert those defects into cross-renderer acceptance tests; qualify Qt early; migrate authority deliberately; retire Tauri only after Qt Stable and field evidence.** + +The desired sequence is: + +```text +CURRENT: React/PWA + Tauri/WebKitGTK + │ + ├── preserve a safe supported Tauri transitional product + ├── fix TM-0 data/security defects + ├── fix portable app/Core defects + └── classify renderer/runtime-specific residuals + │ + ▼ + Renderer-neutral DesktopPlatform + │ + ▼ + Authoritative Rust Core + Project / Storage / Crypto / Migration / Tasks / AI / Diagnostics + │ + ┌─────────┴─────────┐ + ▼ ▼ + Qt early qualification PWA reference + │ + ▼ + Qt Quick/QML + thin bridge + Rust + │ + ▼ + packaged cross-renderer proof + │ + ▼ + Qt Stable + │ + ▼ + Tauri retirement G5 + │ + ├──────────────► PWA continues + └──────────────► GPUI exploration/admission later +``` + +Qt is **not** planned as a Qt-WebEngine recreation of the Tauri webview shell. The principal UI target remains Qt Quick/QML with a thin native integration layer to the Rust Core. Qt WebEngine may only be introduced for a narrowly isolated capability after a separate architecture, security, performance, and licensing decision. + +This roadmap also adopts the repository-wide reuse rule from `ARCHITECTURE-REUSE-OWNERSHIP.md`: capability names describe responsibilities, not mandatory new crates/packages/services. Existing semantic owners and proven primitives are extended first; new architecture is introduced only for a real ownership/capability gap. + +--- + +## 2. Why Revision 3 is necessary + +Issue #332 now provides enough packaged field evidence to distinguish several problem classes that were originally conflated: + +1. persistence/preferences — fixed and field-verified; +2. app-owned visual/compositing cost — real and materially improvable; +3. Tauri/WebKitGTK/Wayland/NVIDIA differential — plausible and increasingly isolated; +4. Alt-Tab/background-resume hard hangs — repeatedly reproduced and user-blocking; +5. abnormal WebKit process memory growth — observed, potentially related, not yet causally proven. + +The program must treat **renderer-neutral defects** and **renderer-specific defects** differently. A renderer replacement makes it wasteful to build large WebKitGTK-specific architecture when the useful engineering outcome can instead be preserved as a reusable acceptance scenario. + +Revision 3 therefore introduces: + +- a formal **Tauri Investment Gate**; +- a formal **Tauri Exit/Stop-Loss Rule**; +- explicit **portable-vs-runtime classification**; +- a **cross-renderer performance/lifecycle benchmark program**; +- **G1.5 — Tauri Evidence Exit / Qt Transfer Readiness**; +- **G2.5 — Qt Renderer Differential Gate**; +- **Wave 2.5 — Desktop Differential Baseline & #332 Classification**; +- an early **Qt Linux/Wayland/NVIDIA graphics differential lane**; +- a binding **reuse-first / one-authority-per-capability** implementation constraint through `ARCHITECTURE-REUSE-OWNERSHIP.md`. + +--- + +## 3. Binding architectural invariants + +### 3.1 Renderer owns presentation; Core owns truth + +No renderer may become authoritative for: + +- project truth; +- persistence semantics; +- migration; +- encryption; +- recovery; +- durable task state; +- AI orchestration truth; +- project compatibility rules. + +```text +React / Tauri adapter / Qt QML / future GPUI + │ + ▼ + versioned contracts + │ + ▼ + WorldScript Rust Core +``` + +### 3.2 DesktopPlatform remains a permanent substitution boundary + +The existing `packages/desktop-contracts` / `DesktopPlatform` investment is strategic infrastructure, not temporary Tauri cleanup. + +Requirements: + +- direct Tauri imports remain mechanically constrained; +- the existing zero-tolerance import guard remains required CI; +- Qt APIs must not leak into shared/domain code; +- future renderer adapters implement capability contracts rather than inventing alternate product semantics. + +### 3.3 No second desktop domain architecture + +Forbidden: + +- Tauri-only storage authority; +- Qt-only storage authority; +- renderer-specific crypto or migration rules; +- renderer-specific project formats; +- duplicated validation; +- QML/JavaScript business rules; +- broad GPU/environment heuristics as product architecture. + +### 3.4 Data integrity and security outrank migration velocity + +The transition must not weaken: + +- atomicity; +- durability; +- encryption; +- backup/recovery; +- migration admission; +- corruption/tamper detection; +- record identity binding; +- rollback. + +### 3.5 Evidence maturity is explicit + +Use the common vocabulary: + +```text +LOCAL_ONLY +CI_ONLY +PACKAGED_LOCAL +PACKAGED_TARGET_ENV +FIELD_OBSERVED +``` + +No browser-only or unit-only result may be described as packaged desktop closure. + +### 3.6 Reuse before new architecture + +`docs/architecture/ARCHITECTURE-REUSE-OWNERSHIP.md` is the cross-cutting implementation-governance companion for this roadmap. + +Before adding a non-trivial new crate, package, service, manager, store, queue, registry, capability detector, state machine, or renderer-specific subsystem: + +1. identify the current semantic owner; +2. inventory existing reusable primitives/tests/fixtures; +3. determine whether the current owner can be extended; +4. prefer a narrow adapter where the gap is platform-specific; +5. extract a shared primitive only after real duplication exists; +6. create a new subsystem only when a distinct capability/ownership gap remains. + +A roadmap capability name does **not** authorize a new crate/package by itself. + +The target remains: + +```text +ONE PRODUCT MODEL +ONE VERSIONED PROJECT TRUTH +ONE AUTHORITY PER SEMANTIC CAPABILITY +``` + +--- + +## 4. Tauri transitional investment policy + +### TM-0 — mandatory + +Fix immediately, preferably in Core/shared contracts: + +- data loss/corruption; +- incorrect save/load/recovery; +- security vulnerabilities; +- secret leakage; +- updater/package integrity failures; +- startup/recovery lockout. + +### TM-1 — user-blocking + +Investigate hard hangs, crashes, unreadable content, broken input, or startup failure. Fix when app-owned/shared or addressable by a narrow adapter correction. + +### TM-2 — high-ROI only + +Allow focused responsiveness, accessibility, privacy-safe diagnostics, packaging, or adapter work only when small, measured, and reusable. + +### TM-3 — reject + +Do not start: + +- WebKitGTK/browser-engine forks; +- broad NVIDIA/DMABUF workaround frameworks; +- global graphics override matrices as architecture; +- large Tauri-only crash/recovery subsystems; +- new Tauri-only product features; +- security weakening for compatibility. + +### Mandatory investment record + +Before non-trivial Tauri work: + +```text +severity = TM-0 / TM-1 / TM-2 / TM-3 +root cause owner = app / shared-core / adapter / runtime / compositor / driver / unknown +reproduced = yes / no / environment-limited +renderer-neutral fix = yes / no +Qt/Core reuse = high / medium / low +Tauri-only coupling = none / low / medium / high +safe small mitigation = yes / no +upstream/environment evidence = yes / no +decision = FIX / INSTRUMENT / MITIGATE / DEFER-TO-CORE / STOP-TAURI-LANE / TRANSFER-TO-QT-ACCEPTANCE +``` + +TM-3 proposals are rejected directly under this classification. The specialized #332 stop rule in `TAURI-TRANSITIONAL-MAINTENANCE.md` applies only to #332-style runtime investigations where evidence is being transferred to Qt; it is not a prerequisite for rejecting unrelated low-value Tauri-only work. + +--- + +## 5. #332 becomes a cross-renderer acceptance program + +### 5.1 Decomposition + +| Track | Current classification | Roadmap treatment | +| --- | --- | --- | +| A Persistence/preferences | Resolved + field verified | Preserve regression tests | +| B App-owned visual/performance cost | Partially hardened | Continue portable/high-ROI work | +| C WebKitGTK/Wayland/NVIDIA differential | Runtime/environment candidate | Bounded classification; no deep workaround program | +| D Alt-Tab/background resume hang | Unresolved observable | Instrument owner; transfer scenario to Qt | +| E abnormal WebKit memory growth | Unresolved observable | Classify portable leak vs runtime amplification | + +### 5.2 Portable-vs-runtime decision tree + +```text +symptom + │ + ├─ data/security defect? ───────────────► FIX (TM-0) + │ + ├─ app/Core/state/task/memory defect? ─► FIX / DEFER-TO-CORE + │ + ├─ small adapter defect? ───────────────► FIX / MITIGATE + │ + ├─ WebKit/compositor/driver correlated? ► bounded evidence + │ │ + │ ▼ + │ STOP-TAURI-LANE + │ │ + └──────────────────────────────► Qt acceptance scenario +``` + +### 5.3 Alt-Tab objective + +Do not ask “how do we perfect WebKitGTK?” Ask: + +> **Does WorldScript-owned work cause the background/resume failure, or does the presentation runtime fail after app-owned work is bounded?** + +Distinguish: + +- JS/event-loop stall; +- persistence/serialization/I/O stall; +- Tauri/Rust main-process stall; +- WebKit WebProcess crash/hang; +- GPU/compositor stall; +- memory-pressure termination; +- Core worker starvation/deadlock. + +### 5.4 Memory objective + +**Portable leak:** application state, editor models, listeners, queues, buffers, snapshots, Core data, or app-owned resources grow without bound → fix. + +**Runtime amplification/leak:** app-owned heaps remain bounded while WebKit/GPU/WebProcess memory grows abnormally → establish ownership, then transfer the soak test to Qt. + +The objective is not a forensic proof of every WebKit allocation. + +### 5.5 GOLDEN-DESKTOP-LIFECYCLE-332 + +Required semantic scenario: + +1. open representative project; +2. edit manuscript; +3. cross autosave boundary; +4. background 5 seconds; +5. return and type immediately; +6. repeat 20 Alt-Tab cycles; +7. repeat with 30-second and two-minute background intervals; +8. minimize/restore; +9. navigate Settings and Writer Studio; +10. normal close/relaunch; +11. repeat with a large project; +12. 30-minute editing/memory run; +13. longer soak; +14. repeat on PWA, Tauri and Qt using the same semantic workload. + +Required outcomes shared by all renderers: + +- zero unbounded hangs; +- zero force-kills in an admitted acceptance run; +- no UI disappearance; +- prompt post-resume input acknowledgement; +- acknowledged edits survive; +- save/close/relaunch succeeds; +- no corruption; +- clean process-tree expectations are satisfied where the renderer has helper processes attributable to the run. + +Memory outcome is renderer-status specific: + +- **Qt/PWA admission or regression acceptance:** memory/resource growth must be bounded under the admitted fixture/duration and SLO; an explanation of unbounded growth is not a pass. +- **Transitional Tauri classification:** abnormal renderer/runtime-side growth may remain explicitly explained and classified only when portable/app-owned leakage has been fixed or ruled out and the authoritative #332 stop rule is otherwise satisfied. That is transfer evidence, not a generic acceptance pass. + +--- + +## 6. Cross-renderer benchmark harness + +Create reusable cross-renderer **scenario semantics and evidence contracts** before substantial Qt feature migration. Do not require one monolithic driver/framework to control React/PWA, Tauri/WebKitGTK, and Qt identically. + +Preferred architecture: + +```text +Scenario specification / fixture / metrics / thresholds + │ + ┌───────────┼───────────┐ + │ │ │ + PWA driver Tauri driver Qt driver +``` + +Share: + +- scenario IDs/versions; +- fixture definitions; +- semantic workloads; +- measurement vocabulary; +- evidence manifest schema; +- accepted thresholds/decision rules. + +Keep renderer-specific: + +- lifecycle automation details; +- process/runtime instrumentation; +- graphics/backend probes; +- packaging/install mechanics; +- native/browser driver implementation. + +### Workloads + +- cold/warm startup; +- Settings navigation burst; +- manuscript typing burst; +- cursor/selection; +- scroll; +- panel/view switching; +- autosave; +- large project open/save; +- Alt-Tab/background-resume; +- minimize/restore; +- 30-minute session; +- 6-hour soak where practical; +- repeated launch/close; +- suspend/resume where supported. + +### Metrics + +| Metric | PWA | Tauri | Qt | GPUI later | +| --- | --- | --- | --- | --- | +| cold/warm start | baseline | baseline | target | future | +| interaction p50/p95 | baseline | baseline | target | future | +| editor input p95 | baseline | baseline | target | future | +| frame consistency | baseline | baseline | target | future | +| autosave p95 | baseline | baseline | target | future | +| idle CPU/RSS | baseline | baseline | target | future | +| 30m memory slope | baseline | baseline | target | future | +| long-soak peak | baseline | baseline | target | future | +| Alt-Tab failures | baseline | known issue | **0 target** | future | +| force-kill/crash count | baseline | baseline | **0 target** | future | + +Every measurement record names build SHA, package, toolkit/runtime, OS, display protocol, compositor, GPU, driver, fixture, methodology, and evidence maturity. + +--- + +## 7. Rust Core is the highest-value migration work + +Qt must not become a new place to hide TypeScript/Tauri authority. + +The **current execution order must remain consistent with `CORE-MIGRATION-LEDGER.md`**. Revision 3 does not silently reorder active Wave-2 work. + +Recommended authority progression: + +1. project schema/validation/migration convergence; +2. storage semantics / real serialized-project compatibility; +3. bounded task-supervision extraction already identified as a Wave-2 fast-follow; +4. diagnostics model/redaction/sink convergence already identified as a Wave-2 fast-follow; +5. Wave 3 durability/atomicity/recovery and R-15 design; +6. Wave 4 R-15 crypto/migration/rekey/admission/identity implementation; +7. AI request/orchestration contracts when separately justified by portability and stable semantics; +8. update compatibility/contracts where portable concepts genuinely exist; +9. collaboration semantics when ready. + +This is an authority progression, not a mandate to create one crate per line. `ARCHITECTURE-REUSE-OWNERSHIP.md` applies: extend cohesive existing owners first and split only with demonstrated ownership/security/test/reuse value. + +A renderer-ready capability has: + +- no DOM dependency; +- no React lifecycle dependency; +- no Tauri dependency; +- no Qt dependency; +- deterministic typed inputs/outputs; +- typed errors; +- cancellation/backpressure where relevant; +- persistence semantics; +- security classification; +- headless tests; +- large-input behavior tests; +- migration/versioning impact; +- privacy-safe diagnostics policy. + +--- + +## 8. R-15 and #357/#359/#360/#361 are migration accelerators + +R-15 must be implemented in Rust Core and consumed by renderers. It must not be delayed merely because Tauri is transitional. + +Required properties: + +- authenticated encryption; +- versioned envelope; +- renderer-neutral key lifecycle; +- atomic encrypted writes; +- durability/fsync policy; +- tamper/corruption detection; +- no avoidable plaintext temporary leakage; +- backup/recovery compatibility; +- migration from existing plaintext desktop data; +- interruption testing; +- key-loss behavior; +- large-project behavior. + +### #357 — durability + +Define temp-file fsync, rename ordering, parent-directory fsync, platform differences, errors, and recovery evidence. + +### #359 — crash-resumable rekey + +Rekey/re-encryption must be resumable and idempotent with persisted progress, old/new key identity, rollback/recovery, and interruption tests. + +### #360 — migration admission + +Reads/writes must participate in coherent migration admission. No renderer may bypass a crypto migration lock or accidentally observe mixed authority. + +### #361 — AAD/record identity + +Ciphertext must bind to the logical record/file identity and relevant envelope metadata so cross-file substitution is detected. + +**Qt Beta is blocked until required R-15 desktop properties are implemented.** No renderer may create a private substitute. + +--- + +## 9. Revised program gates + +### G0 — CEF Exit + +**Complete.** Preserve historical evidence only. + +### G1 — Core Native-Ready + +Requires DesktopPlatform enforcement, headless project lifecycle, renderer-neutral contracts, storage semantics, R-15 architecture approval, and native-readiness CI. + +### G1.5 — Tauri Evidence Exit / Qt Transfer Readiness — NEW + +This gate does **not** require #332 to be fully fixed in Tauri. + +Requires: + +- #332 decomposed by ownership; +- persistence/data-loss risks fixed or separately TM-0 tracked; +- portable memory leak investigation reaches defensible classification; +- Alt-Tab owner narrowed enough to choose FIX/MITIGATE/STOP; +- no planned broad WebKitGTK/NVIDIA workaround architecture; +- GOLDEN-DESKTOP-LIFECYCLE-332 encoded as reusable evidence specification; +- PWA/Tauri baseline measurements captured on representative target hardware; +- residual Tauri runtime limitations documented. + +Exit: + +> **Qt may proceed without waiting for perfection of WebKitGTK-specific residuals.** + +### G2 — Qt Implementation Admission + +Requires: + +- Qt license strategy; +- Qt version/LTS strategy; +- bridge scorecard; +- early killer gates; +- packaged native/Core roundtrip; +- IME/input feasibility; +- accessibility feasibility; +- lifecycle/background-resume feasibility; +- Linux/Wayland/NVIDIA probe where applicable; +- updater/packaging design. + +### G2.5 — Qt Renderer Differential Gate — NEW + +Before broad UI migration: + +- capture Qt Quick graphics backend; +- capture GPU/driver and Wayland/X11 identity; +- observe multi-GPU selection where applicable; +- run 20-cycle Alt-Tab scenario; +- demonstrate no catastrophic memory growth; +- demonstrate competitive basic input latency; +- demonstrate no new killer renderer/lifecycle problem. + +Failure pauses broad Qt investment and triggers architecture review. + +### G3 — Qt Beta + +Requires core writing workflows, project compatibility, R-15, recovery, updater/rollback, accessibility, performance SLOs, packaged #332 lifecycle acceptance, and no unresolved Critical/High security findings. + +### G4 — Qt Stable + +Requires parity, soak, large-project, installer/signing/notarization, rollback, diagnostics, migration, support playbooks, and field evidence. + +### G5 — Tauri Retirement + +Only after Qt Stable plus field-observation/rollback window. Remove Tauri; do not keep a permanent third desktop runtime. + +### G6+ — GPUI + +Remains separately admitted after Qt evidence and must consume the same Core/contracts/benchmark architecture. + +--- + +## 10. Revised execution waves + +### Wave 0 — Strategy reset / CEF retirement — COMPLETE + +Preserve the current completed status. + +### Wave 1 — DesktopPlatform boundary — COMPLETE + +Preserve and strengthen as a permanent architecture guardrail. + +### Wave 2 — Rust Core extraction — IN PROGRESS + +Continue renderer-neutral authority extraction according to the current Core Migration Ledger: project/schema/validation and storage convergence remain the primary work; bounded task-supervision and diagnostics extraction remain the documented fast-follows. Do not substitute broad Qt UI work or pull Wave-3/4 R-15 implementation ahead of unresolved Wave-2 authority prerequisites. + +### Wave 2.5 — Desktop differential baseline & #332 classification — NEW + +Bounded evidence work, not a Tauri optimization wave. + +Deliverables: + +- decomposed #332 issue; +- process/lifecycle instrumentation plan; +- portable-memory classification; +- baseline PWA/Tauri benchmark; +- GOLDEN-DESKTOP-LIFECYCLE-332; +- Tauri stop-rule decision record; +- known-runtime-limitations record where justified. + +Exit: G1.5. + +### Wave 3 — Storage correctness and R-15 design + +All output renderer-neutral and Qt-consumable. This wave begins from the Wave-2 storage/schema authority baseline rather than replacing it. + +### Wave 4 — R-15 implementation + +Implement in Rust Core. Close #357/#359/#360/#361 only with destructive/interruption/security evidence. + +### Early Qt feasibility lanes + +Begin as soon as the typed Core probe permits. Disposable only; no product shell. + +#### QF-A — lifecycle/bridge + +Window, QML, typed Rust call/event, async/cancellation, shutdown, repeated launch/close. + +#### QF-B — input/accessibility + +Keyboard/focus, IME, Unicode, BiDi/RTL, scalable/high-contrast text, accessibility tree. + +#### QF-C — crash/recovery + +Intentional failure, diagnostics, restart/recovery, no data corruption. + +#### QF-D — Linux graphics differential — NEW + +On representative Linux/Wayland/NVIDIA hardware: + +- identify Qt Quick graphics backend; +- record GPU/driver selection; +- test multi-GPU behavior where present; +- run reduced-motion/high-contrast paths; +- run Alt-Tab/minimize/restore; +- capture memory trend; +- compare with PWA/Tauri without framework-marketing conclusions. + +Kill criterion: catastrophic renderer/lifecycle behavior that cannot be bounded without violating the target architecture. + +The formal checklist and evidence row for QF-D live in `QT-EARLY-KILLER-GATES.md`; it must not remain a roadmap-only lane. + +### Wave 4.5 — Formal Qt killer-gate qualification + +Consume early-lane evidence; add packaged identity, signing/update trust, rollback, least privilege, and security evidence. + +### Wave 5 — Reusable Qt learning/benchmark harness + +Include: + +- accepted bridge/thread/lifetime proof; +- file dialog; +- clipboard; +- packaged artifact; +- benchmark hooks; +- GOLDEN-DESKTOP-LIFECYCLE-332 runner/spec; +- evidence manifest. + +The harness consumes the shared semantic scenario/evidence contract from Section 6 and may use renderer-specific drivers; it does not require PWA/Tauri/Qt automation internals to be identical. + +### Wave 6 — Qt shell/design system + +Qt Quick/QML shell, menus, pane/dock model, theme tokens, typography, icons, focus, shortcuts, notifications, dialogs, errors. No duplicated domain logic. + +### Wave 7 — Qt project lifecycle vertical slice + +Launch → recent/open → validate/migrate/decrypt → edit metadata → save → close → reopen using real Core storage/R-15 semantics. + +### Wave 8 — Qt manuscript editor foundation + +Highest-risk product surface. Prove correctness before polish: large text, graphemes, Unicode, IME, BiDi/RTL, selection, cursor, undo/redo, clipboard, drag/drop, find/replace, autosave/recovery. + +### Wave 9 — Qt performance + #332 differential + +Formal cross-renderer acceptance wave comparing PWA, final supported Tauri baseline, and Qt packaged artifact. + +Required scenarios: + +- input p50/p95; +- navigation; +- scroll/frame consistency; +- background/resume; +- memory slope; +- long soak; +- large project; +- autosave; +- reduced-motion/effects-equivalent presentation modes; +- target Linux/Wayland/NVIDIA hardware. + +Exit: no catastrophic resource/lifecycle behavior, **bounded Qt memory/resource growth under admitted fixtures**, and accepted budgets. + +### Waves 10–20 + +Retain the existing canonical roadmap domains and sequencing: + +- Wave 10 — knowledge surfaces; +- Wave 11 — plot/graph/visual surfaces; +- Wave 12 — AI orchestration; +- Wave 13 — task supervisor/native services; +- Wave 14 — accessibility hard gate; +- Wave 15 — packaging/signing/update; +- Wave 16 — crash diagnostics/recovery; +- Wave 17 — security hardening; +- Wave 18 — packaged beta; +- Wave 19 — parity/stable cutover; +- Wave 20 — Tauri retirement. + +Revision 3 tightens their admission evidence; it does not discard their existing product scope. + +--- + +## 11. Qt graphics/performance strategy + +Because the target is Qt Quick/QML, performance work must use Qt-native concepts rather than importing WebKitGTK assumptions. + +Record for relevant packaged runs: + +- Qt version/build; +- Qt Quick scene-graph backend; +- graphics API/backend selected; +- GPU identity; +- driver version; +- Wayland/X11; +- compositor/desktop environment; +- multi-GPU selection where applicable; +- render-thread stalls; +- GUI-thread stalls; +- scene-graph/resource growth; +- memory trend; +- fallback/software-rendering state if encountered. + +Do not add permanent backend overrides solely to make one benchmark green. Any override needs a compatibility matrix and explicit rationale. + +--- + +## 12. Performance SLO policy + +Do not invent absolute SLOs before baseline data exists. Establish budgets from representative hardware and workflows, then freeze them as regression gates. + +At minimum define: + +- input latency p50/p95; +- navigation latency p95; +- project-open p50/p95 by fixture class; +- autosave p95; +- idle CPU/RSS; +- 30-minute memory-growth slope; +- long-soak maximum tolerated growth; +- resume-to-first-input budget; +- zero-hang lifecycle requirement; +- zero-corruption requirement. + +A faster average must not hide catastrophic tail latency or hangs. For Qt admission, unexplained or explained **unbounded** growth is a failure; explanation may classify a transitional Tauri limitation but cannot convert an unbounded Qt leak into a pass. + +--- + +## 13. Testing architecture + +1. **Core:** Rust unit/property/fuzz/destructive tests. +2. **Contracts:** common capability contract suites. +3. **Renderer integration:** Qt lifecycle/input/accessibility/model tests; Tauri only while supported. +4. **Packaged E2E:** actual artifacts on target OS/runtime. +5. **Cross-renderer benchmark:** shared semantic workloads/fixtures/evidence schema with renderer-specific drivers. +6. **Field/soak:** representative user environments, especially Linux/Wayland/NVIDIA for #332 lineage. + +--- + +## 14. CI/CD strategy + +Keep CI change-aware and authoritative. + +Add Qt jobs only when real Qt code exists; do not create placeholder native CI. + +When Qt begins, separate: + +```text +fast Core/contracts gate +web/PWA gate +Qt build/unit gate +Qt packaged smoke +nightly heavy platform matrix +scheduled soak/performance evidence +release-candidate full matrix +``` + +Performance results should be retained as evidence artifacts. Do not make noisy microbenchmarks required until variance and runner suitability are understood. + +CodeQL/SAST/SCA/signature/release-authority requirements remain independent of renderer migration. + +--- + +## 15. Security and bridge hardening + +The Qt↔Rust boundary is a security and correctness boundary. + +Require: + +- named typed operations; +- versioned contracts; +- bounded payloads; +- explicit ownership/lifetimes; +- thread-affinity rules; +- structured errors; +- cancellation; +- bounded queues/backpressure; +- no arbitrary command execution; +- negative tests; +- fuzz/property tests where appropriate; +- no secrets in QML; +- no project truth in QML JavaScript. + +Bridge selection is scorecard-driven, not prototype-driven. + +--- + +## 16. Migration observability + +Create a privacy-safe desktop evidence manifest with fields such as: + +```text +app_version +build_sha +package_kind +renderer +runtime_or_qt_version +core_contract_version +os +kernel +session_type +compositor +gpu_vendor/model +driver +graphics_backend +fixture_id/size_class +scenario_id/scenario_version +duration buckets +memory buckets +result +failure classification +evidence maturity +``` + +Never include manuscript text, prompts, API keys, tokens, encryption keys, or private paths. + +--- + +## 17. Stop-loss / sunk-cost rules + +Stop or reframe a task when all are true: + +- strongly renderer-specific; +- does not protect data/security; +- reusable Core/Qt value is low; +- renderer replacement is already approved; +- workaround is broad/brittle; +- a bounded diagnostic can preserve the lesson as an acceptance test. + +| Work | Reuse value | +| --- | --- | +| DesktopPlatform/contracts | Very high | +| Rust Core | Very high | +| storage/recovery/R-15 | Very high | +| task supervision/diagnostics | Very high | +| portable app performance | High | +| lifecycle acceptance specs | High | +| memory classification | Medium-high | +| small Tauri adapter fixes | Medium | +| WebKitGTK compositor tuning | Low | +| global NVIDIA/DMABUF workaround architecture | Very low | +| WebKitGTK-specific recovery subsystem | Very low | + +This is a prioritization heuristic, not an accounting claim. + +--- + +## 18. Migration PR governance + +Every migration PR should state: + +```text +Wave / gate: +Authority changed? YES/NO +Existing semantic owner / seed audited? YES/NO +New crate/package/service introduced? YES/NO — if YES, why extension/adapter/extraction was insufficient: +Duplicate authority removed/avoided? YES/NO +DesktopPlatform boundary affected? YES/NO +Direct Tauri import added? YES/NO +Qt-specific API leaked into shared code? YES/NO +R-15 / #357/#359/#360/#361 invariant affected? YES/NO +#332 acceptance scenario affected? YES/NO +Data format changed? YES/NO +Security boundary changed? YES/NO +Evidence maturity: +Rollback: +``` + +Merge only after the **complete applicable required and advisory validation suite** is green, including CI, CodeQL/security/signature checks and all change-relevant advisory jobs such as E2E Deep, Lighthouse, Storybook, VRT, or equivalent evidence lanes. An advisory failure is not merge-permissive merely because branch protection does not technically require that context. All material review threads must also be resolved. Evidence-only work must not silently change product authority. + +--- + +## 19. Definition of Qt success + +Qt succeeds only if it demonstrates: + +- correct text editing/input; +- renderer-neutral data semantics; +- R-15/security parity; +- robust recovery; +- accessible workflows; +- predictable and bounded memory/resource behavior under admitted fixtures; +- acceptable interaction latency; +- background/resume stability; +- packaged update/rollback; +- representative Linux/Wayland/NVIDIA behavior; +- target Windows/macOS evidence as applicable; +- no reintroduction of renderer-specific domain authority. + +#332-derived scenarios become positive proof that the migration escaped the old renderer failure class without carrying portable defects forward. + +--- + +## 20. Tauri retirement readiness + +Tauri can be retired when: + +- Qt has G4 Stable admission; +- field-observation window passes; +- project compatibility/migration are proven; +- update/rollback/recovery are proven; +- #332 lifecycle scenario passes on Qt packaged target hardware; +- residual Tauri-only limitations are documented; +- no Tauri-only data is stranded; +- PWA remains unaffected; +- rollback/communication plan exists; +- removal deletes obsolete Tauri code/dependencies without weakening shared contracts. + +Tauri retirement is **not** contingent on retroactively fixing every WebKitGTK limitation. + +--- + +## 21. GPUI re-entry boundary + +GPUI remains deferred. If later admitted, it must consume the same Core and evidence architecture. + +Admission must prove platform support, framework/update policy, text/IME/BiDi, accessibility, performance value, packaging/update feasibility, maintenance health, no speculative React-binding dependency, GOLDEN-DESKTOP-LIFECYCLE-332 equivalent, and project/R-15 compatibility. + +Qt work should maximize Core/contracts/test reuse so future GPUI work is a renderer project rather than another domain migration. + +--- + +## 22. Immediate next actions + +### Now + +1. keep current H1 CI/evidence work isolated from desktop authority changes; +2. adopt the revised #332 decomposition and stop rule; +3. preserve the Tauri import boundary as required CI; +4. define the shared cross-renderer scenario/evidence schema and renderer-specific drivers; +5. create privacy-safe lifecycle/process instrumentation; +6. classify Alt-Tab only far enough to determine app/shared/runtime ownership; +7. classify abnormal memory growth as portable vs runtime-side; +8. avoid new global WebKitGTK/NVIDIA product overrides. + +### Current/next Core tranche + +9. complete Wave-2 first-slice convergence — project schema/validation (`CORE-MIGRATION-LEDGER.md` rows 1-2) and the narrow fs plain load/save round-trip (row 3); this excludes IDB/encryption, which stays Wave 3-4 (row 6); +10. complete the project state-shape compatibility adapter (row 9) — a required prerequisite before G1 evaluation, already locally proven with a first observation-only desktop caller, no authority switch; +11. continue the bounded task-supervision (row 5) and logger/diagnostics (row 4) fast-follows already recorded in `CORE-MIGRATION-LEDGER.md`; +12. then enter Wave 3 for durability/recovery/R-15 architecture and destructive-test design; +13. then implement Wave-4 crash-resumable rekey, migration admission, AAD/record identity, and durable protected writes in Rust Core; +14. keep AI/domain authority out of Qt/QML and do not pull browser WebGPU implementation into Rust for symmetry. + +### Earliest Qt tranche + +15. disposable lifecycle/bridge probe; +16. input/accessibility probe; +17. crash/recovery probe; +18. Linux/Wayland/NVIDIA graphics differential probe; +19. GOLDEN-DESKTOP-LIFECYCLE-332 as soon as semantically possible; +20. G2/G2.5 GO/NO-GO before broad UI migration. + +--- + +## 23. Final strategic rule + +```text +Fix what can migrate. +Measure what can regress. +Classify what is runtime-specific. +Stop when Tauri-only ROI collapses. +Turn failures into acceptance tests. +Prove Qt early on the hardware that hurt Tauri. +Keep project truth in Rust. +Reuse proven owners before inventing new architecture. +Retire Tauri only after Qt earns it. +``` + +This minimizes sunk cost without using the Qt migration as an excuse to ignore data-integrity, security, lifecycle, application-owned performance defects, or architecture duplication. \ No newline at end of file diff --git a/docs/native/QT-EARLY-KILLER-GATES.md b/docs/native/QT-EARLY-KILLER-GATES.md index df319fe40..e547903d3 100644 --- a/docs/native/QT-EARLY-KILLER-GATES.md +++ b/docs/native/QT-EARLY-KILLER-GATES.md @@ -9,12 +9,14 @@ sunk cost. The formal qualification is an additive checkpoint after the early feasibility lanes and before Wave 5 (the reusable Qt learning harness). The disposable pre-G2 qualification probe is the only -pre-G2 artifact; Wave 5 is a distinct later deliverable. It does not replace the later G2, G3, or G4 production -gates. Those gates remain necessary because a small feasibility spike cannot prove production -completeness. The early lanes are explicitly allowed before the formal Wave 4.5 checkpoint so the -cheapest fatal runtime risks are tested before storage and UI sunk cost. +pre-G2 artifact; Wave 5 is a distinct later deliverable. It does not replace the later G2, G2.5, +G3, or G4 production gates. Those gates remain necessary because a small feasibility spike cannot +prove production completeness. The early lanes are explicitly allowed before the formal Wave 4.5 +checkpoint so the cheapest fatal runtime risks are tested before storage and UI sunk cost. The pre-G2 authorization boundary is recorded as the clarifying amendment [`ADR-0022`](../adr/0022-qt-pre-g2-qualification-harness.md); it does not supersede ADR-0021. +Revision-3 graphics/lifecycle requirements are governed by +[`DESKTOP-MIGRATION-ROADMAP-REV3.md`](DESKTOP-MIGRATION-ROADMAP-REV3.md). ## Decision rule @@ -41,10 +43,16 @@ Core probe, the following disposable lanes may run in parallel with Waves 3 and explicitly provisional bridge candidate. 2. **Accessibility and input feasibility** — prove an observable accessibility tree, keyboard/focus, accessible errors, scalable/high-contrast text, RTL/BiDi, and IME smoke behavior. -3. **Crash, hang, lifecycle diagnostics and recovery feasibility** — prove project-owned diagnostics/symbolization and - deterministic restart/recovery without weakening sandbox/process isolation or corrupting test data. - -These lanes retain their own evidence and maturity labels; they are not checked off as G2/G3/G4 +3. **Crash, hang, lifecycle diagnostics and recovery feasibility** — prove project-owned + diagnostics/symbolization and deterministic restart/recovery without weakening sandbox/process + isolation or corrupting test data. +4. **Linux graphics differential** — on representative Linux/Wayland/NVIDIA hardware where + available, record Qt Quick graphics backend, GPU/driver selection, multi-GPU behavior where + exposed, Alt-Tab/minimize/restore behavior, and a bounded memory trend. Compare against the same + semantic PWA/Tauri workload without turning renderer-specific implementation details into shared + product architecture. + +These lanes retain their own evidence and maturity labels; they are not checked off as G2/G2.5/G3/G4 production gates. A failed lane stops Qt investment and returns the program to architecture review. ### Formal Wave 4.5 qualification @@ -59,9 +67,10 @@ contract, packaging/update-trust, permission, and admission review work: artifacts before product packaging work grows around it. 3. **Security and permission posture** — validate IPC/FFI, filesystem, network, and updater boundaries under the intended runtime conditions. -4. **Admission review** — use all evidence to confirm or reject the bridge scorecard, record - residual risks, and produce the G2 decision package. Larger Qt shell or feature work begins - only after G2 passes. +4. **Admission review** — use all early-lane and formal evidence to confirm or reject the bridge + scorecard, record residual risks, and produce the G2 decision package. Larger Qt shell or feature + work begins only after G2 passes; the later G2.5 renderer differential remains a separate + pre-broad-UI admission gate under Revision 3. The formal packaging and security lanes wait for the relevant Wave 4 storage/crypto/recovery semantics; the admission decision remains conjunctive: one unresolved kill gate blocks Qt @@ -74,14 +83,15 @@ implementation. | Contract/threat boundary | Qt-facing contract inventory identifies every IPC/FFI crossing, data owner, permission, cancellation path, and failure mode; no domain truth moves into QML/C++. | The bridge requires renderer-specific domain rules, arbitrary command execution, or a new broad unsafe/FFI architecture. | | Lifecycle and Core bridge | A disposable Qt 6/QML probe proves the minimum viability path: process/window creation, QML load, one typed Rust call, one Rust event to QML, one bounded async/cancellation path, clean shutdown, and three repeated launch/close cycles. It records the bridge/lifetime/threading model; it does not build the reusable Wave 5 harness. | Lifetime/threading behavior is nondeterministic, cancellation cannot be bounded, or the Core cannot remain GUI-independent. | | Accessibility and input | A real Qt Quick control sample exposes a stable accessibility tree and proves keyboard/focus, accessible errors, high contrast, scalable text, RTL/BiDi, and IME smoke behavior on a supported Linux environment. | Required semantics are not observable, custom controls require inaccessible workarounds, or IME/BiDi breaks core writing input. | +| Linux graphics differential | A disposable Qt Quick probe records scene-graph/graphics backend, GPU/driver, Wayland/X11/session context and multi-GPU selection where present; executes Alt-Tab/minimize/restore and a representative memory trend; and preserves the same semantic fixture/workload used for PWA/Tauri comparison. | Catastrophic renderer/lifecycle behavior, unexplained unbounded resource growth, unusable input latency, or a required workaround that violates the Qt Quick/Rust-Core target architecture. | | Packaging and updater trust | A packaged hello-world/Core roundtrip starts from a clean environment; signed update metadata, artifact identity, downgrade policy, rollback, and tamper rejection are exercised with ephemeral, runtime-injected throwaway test credentials only. The credentials never live in source, artifacts, logs, or production secret stores. | Artifact identity or rollback cannot be trusted, updates accept tampered input, test credentials persist outside the test process, or the packaging model requires bypassing repository signing policy. | | Crash and recovery | An intentional harness crash produces actionable diagnostics and symbols for project-owned code; restart/recovery behavior is deterministic and does not corrupt test data. | Diagnostics require weakening sandbox/process isolation, recovery loses acknowledged data, or failures cannot be reproduced from packaged evidence. | | Security and permissions | Runtime review covers sandbox/process boundaries, typed IPC/FFI allowlists and versioning, filesystem/network permissions, secret injection/storage/zeroization, updater privileges and signing trust, temporary-file permissions/cleanup, and the approved Core encryption/identity-binding invariants; negative tests prove denied operations stay denied. | A capability needs arbitrary native execution, broad filesystem/network access, plaintext secret exposure, persistent test credentials, or weakened encryption/identity binding. | -| Admission decision | A signed/ reviewed scorecard records evidence links, residual risks, owners, expiry/retest conditions, and explicit GO/NO-GO for Wave 5. | Any Critical/High security issue, unowned residual risk, or missing evidence remains at the decision meeting. | +| Admission decision | A signed/reviewed scorecard records evidence links, residual risks, owners, expiry/retest conditions, and explicit GO/NO-GO for Wave 5. | Any Critical/High security issue, unowned residual risk, or missing evidence remains at the decision meeting. | -The lifecycle/bridge, accessibility/input, and crash/recovery rows are owned by the early lanes -when they run before Wave 4.5. Formal Wave 4.5 reviews their evidence and fills any gaps; it does -not manufacture a second pass merely to satisfy the later checkpoint. +The lifecycle/bridge, accessibility/input, crash/recovery, and Linux graphics differential rows are +owned by the early lanes when they run before Wave 4.5. Formal Wave 4.5 reviews their evidence and +fills any gaps; it does not manufacture a second pass merely to satisfy the later checkpoint. ## Minimum evidence package @@ -92,6 +102,8 @@ framework: - disposable Qt feasibility probes, with no WorldScript feature UI and no Qt WebEngine; - deterministic probe results covering repeated start/close, cancellation, and clean shutdown; - an accessibility/input fixture with machine-observable tree and keyboard/IME assertions; +- a Linux graphics differential record with Qt Quick backend, GPU/driver/session identity, + Alt-Tab/minimize/restore outcome, multi-GPU observation where applicable, and memory trend; - a clean-environment packaged artifact and a test-key update/rollback fixture; - a crash fixture with a project-owned symbolized frame and recovery-state assertion; - a permission-negative-test record covering sandbox/process, denied filesystem/network/native-command @@ -107,15 +119,18 @@ generic command bridge, or hidden Qt-specific domain layer. The early qualification should use the cheapest environment that can falsify each risk and then repeat the meaningful checks in CI: -1. **Developer smoke:** fast lifecycle, keyboard, IME, and accessibility-tree checks on the - supported Linux desktop used for development. +1. **Developer smoke:** fast lifecycle, keyboard, IME, accessibility-tree and basic graphics- + backend checks on the supported Linux desktop used for development. 2. **Linux CI:** clean build, repeated lifecycle, headless display/compositor smoke, security negative tests, crash artifact collection, and deterministic result assertions. -3. **Clean packaged runtime:** install/launch/update/rollback/tamper tests against the actual +3. **Representative Linux graphics target:** where the #332 lineage applies, use real + Linux/Wayland/NVIDIA hardware to capture backend/GPU/driver identity and the reduced + `GOLDEN-DESKTOP-LIFECYCLE-332` differential before broad Qt UI investment. +4. **Clean packaged runtime:** install/launch/update/rollback/tamper tests against the actual artifact layout rather than the build tree. -4. **Later platform evidence:** Windows UI Automation, macOS VoiceOver/accessibility APIs, and - supported compositor/GPU matrices remain part of G2/G3/G4; the early Linux spike does not claim - cross-platform parity. +5. **Later platform evidence:** Windows UI Automation, macOS VoiceOver/accessibility APIs, and + supported compositor/GPU matrices remain part of G2/G2.5/G3/G4; the early Linux spike does not + claim cross-platform parity. ## Explicit non-goals @@ -125,7 +140,8 @@ repeat the meaningful checks in CI: - no Tauri retirement before Qt Stable plus the documented field window; - no R-15 shortcut, renderer-local encryption, or altered identity binding; - no broad FFI, unsafe runtime, or generic native command executor; -- no production packaging promise based only on an unpackaged developer binary. +- no production packaging promise based only on an unpackaged developer binary; +- no permanent graphics/backend override introduced solely to pass one differential run. ## Relationship to later gates @@ -134,18 +150,36 @@ cheapest useful point. Formal Wave 4.5 consumes that evidence and completes the and admission review needed to confirm or reject the provisional bridge candidate. Wave 5 turns the accepted disposable probes into the reusable executable learning harness and adds the remaining file-dialog and clipboard evidence; it does not repeat the early lanes or Wave 4.5's kill-gate work. -G2 answers -**“is Qt admitted for implementation?”** with the approved license/version/bridge strategy and -the learning harness. G3 and G4 still require project compatibility, accessibility, security, -packaging, updater, recovery, performance, signing, support, and field evidence at production -quality. Passing this qualification must never be used to check those later boxes early. - -## Crash, hang, and lifecycle hardening from #332 - -The early crash lane also covers live-process hangs and lifecycle suspension. A native probe must distinguish an intentional native crash, a Rust Core panic, a GUI event-loop stall, a stalled Core task, and a renderer or compositor failure without weakening process isolation. - -The disposable probe must provide: a bounded UI heartbeat; lifecycle events for focus, blur, background, resume, minimize, restore, and close; correlation IDs for Core requests; bounded cancellation and timeout state; and a privacy-safe diagnostic bundle containing build identity, runtime versions, last lifecycle events, task summaries, heartbeat age, persistence phase, and memory buckets. It must contain no project text, prompts, tokens, keys, private paths, or raw encryption material. - -The `GOLDEN-DESKTOP-LIFECYCLE-332` scenario is mandatory input for later Qt qualification: edit a representative project, cross an autosave boundary, background for 5 seconds, return and edit immediately, repeat 20 times, then exercise 30-second/two-minute background intervals, Writer Studio, Settings, minimize/restore, relaunch, and normal close. The required outcome is no UI disappearance, unbounded hang, lost acknowledged edit, orphan process, corruption, or force-kill requirement; first click, caret, and keyboard input must remain responsive. - -A hang gate is not passed by browser-only evidence or by an unpackaged developer binary. Results must identify their maturity (`LOCAL_ONLY`, `CI_ONLY`, `PACKAGED_LOCAL`, `PACKAGED_TARGET_ENV`, or `FIELD_OBSERVED`) and include the platform/compositor/GPU context. \ No newline at end of file +G2 answers **“is Qt admitted for implementation?”** with the approved license/version/bridge +strategy and learning harness. G2.5 then answers **“has the admitted Qt renderer avoided a new +catastrophic lifecycle/graphics/resource failure on representative target hardware before broad UI +migration?”** G3 and G4 still require project compatibility, accessibility, security, packaging, +updater, recovery, performance, signing, support, and field evidence at production quality. Passing +this qualification must never be used to check those later boxes early. + +## Crash, hang, lifecycle, and graphics hardening from #332 + +The early crash lane also covers live-process hangs and lifecycle suspension. A native probe must +distinguish an intentional native crash, a Rust Core panic, a GUI event-loop stall, a stalled Core +task, and a renderer or compositor failure without weakening process isolation. + +The disposable probe must provide: a bounded UI heartbeat; lifecycle events for focus, blur, +background, resume, minimize, restore, and close; correlation IDs for Core requests; bounded +cancellation and timeout state; and a privacy-safe diagnostic bundle containing build identity, +runtime versions, last lifecycle events, task summaries, heartbeat age, persistence phase, and +memory buckets. It must contain no project text, prompts, tokens, keys, private paths, or raw +encryption material. + +The `GOLDEN-DESKTOP-LIFECYCLE-332` scenario is mandatory input for later Qt qualification: edit a +representative project, cross an autosave boundary, background for 5 seconds, return and edit +immediately, repeat 20 times, then exercise 30-second/two-minute background intervals, Writer Studio, +Settings, minimize/restore, relaunch, and normal close. The required outcome is no UI disappearance, +unbounded hang, lost acknowledged edit, orphan process, corruption, or force-kill requirement; first +click, caret, and keyboard input must remain responsive. **For Qt admission, memory/resource growth +must be bounded under the admitted fixture and duration; an explanation of unbounded growth is +classification evidence, not a passing result.** Transitional Tauri evidence may remain classified +as runtime-limited where the authoritative stop rule is satisfied. + +A hang or graphics gate is not passed by browser-only evidence or by an unpackaged developer binary. +Results must identify their maturity (`LOCAL_ONLY`, `CI_ONLY`, `PACKAGED_LOCAL`, +`PACKAGED_TARGET_ENV`, or `FIELD_OBSERVED`) and include the platform/compositor/GPU context. \ No newline at end of file diff --git a/docs/native/TAURI-TRANSITIONAL-MAINTENANCE.md b/docs/native/TAURI-TRANSITIONAL-MAINTENANCE.md index d2e50162b..ac3044af1 100644 --- a/docs/native/TAURI-TRANSITIONAL-MAINTENANCE.md +++ b/docs/native/TAURI-TRANSITIONAL-MAINTENANCE.md @@ -4,6 +4,19 @@ This policy operationalizes ADR-0021. It limits new Tauri investment without turning the current desktop build into an unsupported or unsafe product. The PWA remains a first-class product surface, Rust Core remains the renderer-neutral authority, Qt remains gated, and GPUI remains deferred. +## Normative roadmap set + +Desktop/native work must read the roadmap set as one authority chain: + +1. `docs/adr/0021-qt-gpui-native-desktop-strategy.md` locks the architecture direction. +2. `docs/native/ROADMAP-QT-GPUI-DESKTOP.md` remains the canonical numbered execution roadmap and historical Wave/Revision-2 record. +3. `docs/native/DESKTOP-MIGRATION-ROADMAP-REV3.md` is the **normative Revision-3 amendment** for Tauri investment/exit, #332 cross-renderer evidence, G1.5/G2.5, Wave 2.5, Qt differential qualification, and related R-15 handoff rules. Where Revision 3 narrows or strengthens an older rule in those subjects, Revision 3 controls. +4. `docs/architecture/ARCHITECTURE-REUSE-OWNERSHIP.md` is the cross-cutting implementation-governance companion: reuse existing semantic owners first, prefer narrow adapters/extraction over parallel architecture, and require one authority per semantic capability. +5. This maintenance policy is the operational Tauri support/stop-loss policy consumed by both roadmap records. +6. `pnpm run native-readiness:check` mechanically validates that the Revision-3 amendment and mandatory reuse/ownership invariants remain present; removing or silently bypassing them is therefore a CI policy failure. + +Revision 3 does **not** authorize production Qt UI ahead of the existing admission gates, does not alter shipped runtime authority, and does not weaken the Core-first ordering. + ## Support boundary Until Qt reaches Stable and completes its field-observation window, Tauri must continue to provide: @@ -60,6 +73,8 @@ Reject new work that would create: - large Tauri-only UI or IPC architecture; - security or sandbox weakening to make diagnostics pass. +TM-3 is an immediate general stop classification. It does **not** need to satisfy the #332 runtime-specific exit rule. + ## Investment gate Before a non-trivial Tauri change, record: @@ -73,14 +88,31 @@ Qt/Core reuse = high / medium / low Tauri-only coupling = none / low / medium / high safe small mitigation = yes / no upstream or environment evidence = yes / no -decision = FIX / INSTRUMENT / MITIGATE / DEFER-TO-CORE / STOP-TAURI-LANE +decision = FIX / INSTRUMENT / MITIGATE / DEFER-TO-CORE / STOP-TAURI-LANE / TRANSFER-TO-QT-ACCEPTANCE ``` -If Tauri-only coupling is high, reusable Qt/Core value is low, and TM-0 does not apply, stop the Tauri lane unless an explicitly documented immediate P0 support exception exists. +Decision handling: -## #332 lifecycle evidence +- **TM-0:** fix or separately track the mandatory data/security invariant; renderer transition is not an excuse to defer it unsafely. +- **TM-3:** reject the proposal immediately under the maintenance-class definition above. +- **TM-1/TM-2 unrelated to #332:** use the investment record and reuse/ownership policy directly; choose a small reusable fix/mitigation or stop the proposed Tauri-only work when ROI/architecture constraints fail. +- **#332 runtime investigations:** if Tauri-only coupling is high, reusable Qt/Core value is low, and TM-0 does not apply, any decision to stop deep investigation must satisfy the single authoritative **Tauri exit rule for #332** below. Do not substitute a shorter implicit #332 stop criterion. + +Before proposing new architecture, also apply `docs/architecture/ARCHITECTURE-REUSE-OWNERSHIP.md`: identify the existing semantic owner/seed, prefer extension or a narrow adapter, and do not create a Tauri-only subsystem where a renderer-neutral authority is the correct destination. + +## #332: lifecycle, performance, and memory evidence + +Issue #332 is no longer treated as one generic “Tauri is sluggish” defect. It is a cross-renderer evidence source with distinct subproblems: + +```text +A. persistence / preference survival RESOLVED + FIELD-VERIFIED +B. app-owned presentation/performance cost PARTIALLY HARDENED +C. WebKitGTK / Wayland / NVIDIA differential RUNTIME/ENVIRONMENT CANDIDATE +D. Alt-Tab / background-resume hard hang UNRESOLVED-OBSERVABLE +E. abnormal WebKit process memory growth UNRESOLVED-OBSERVABLE +``` -The packaged Alt-Tab incident is classified as `UNRESOLVED-OBSERVABLE` until the owner is proven. The investigation must distinguish: +The packaged Alt-Tab incident remains `UNRESOLVED-OBSERVABLE` until the owner is proven. Investigation must distinguish: - JavaScript/event-loop or React presentation stalls; - persistence, serialization, or I/O stalls; @@ -92,10 +124,37 @@ The packaged Alt-Tab incident is classified as `UNRESOLVED-OBSERVABLE` until the Safe diagnostics may record build identity, renderer/runtime versions, lifecycle events, bounded heartbeat age, task kinds, persistence phase, dirty-generation, duration buckets, process state, and memory buckets. They must not record manuscript text, prompts, API keys, tokens, private paths, or encryption material. -Do not ship `WEBKIT_DISABLE_DMABUF_RENDERER`, `WEBKIT_DISABLE_COMPOSITING_MODE`, `__NV_DISABLE_EXPLICIT_SYNC`, or equivalent global overrides without reproducible before/after evidence, a scoped compatibility decision, and a security review. +Do not ship `WEBKIT_DISABLE_DMABUF_RENDERER`, `WEBKIT_DISABLE_COMPOSITING_MODE`, `__NV_DISABLE_EXPLICIT_SYNC`, or equivalent global overrides without reproducible before/after evidence, a scoped compatibility decision, and a security review. These are diagnostic levers, not architecture. The first reusable fix target is persistence coordination: avoid duplicate large serialization and writes while preserving dirty generations, fail-closed close behavior, and acknowledged edits. Do not remove a visibility flush or add a single-flight coordinator without proving that newer edits cannot be lost. +## Portable-vs-runtime classification gate + +Before further non-trivial #332 work: + +1. **App/shared-Core ownership:** if state transitions, serialization, I/O, task scheduling, retained resources, editor models, queues, or application memory grow/stall, fix it because the defect can migrate with the product. +2. **Adapter ownership:** if a narrow Tauri lifecycle/adapter correction removes the defect without creating new architecture, fix it as TM-1/TM-2. +3. **Runtime/compositor/driver ownership:** if the defect survives after app-owned work is bounded and correlates with WebKitGTK, Wayland, NVIDIA, DMABUF, compositor state, or WebProcess failure, preserve the evidence and evaluate the authoritative stop rule below. +4. **Unknown:** instrument only until ownership is narrow enough to choose FIX, MITIGATE, or STOP-TAURI-LANE. Do not turn uncertainty into open-ended WebKitGTK archaeology. + +## Memory classification gate + +The abnormal WebKit process footprint observed during #332 must be separated into two classes: + +### Portable/application leak + +Application/Redux/Core state, editor models, listeners, task queues, buffers, snapshots, object URLs, or other app-owned resources grow without bound. + +**Action:** fix it because it can survive the Qt migration. + +### Renderer/runtime amplification or leak + +App-owned heaps/resources remain bounded while WebKit/WebProcess/GPU-side footprint grows abnormally. + +**Action:** capture enough evidence to establish ownership, then transfer the same soak scenario to Qt instead of building a WebKitGTK-specific recovery architecture. + +The objective is classification, not proving every internal WebKit allocation. + ## GOLDEN-DESKTOP-LIFECYCLE-332 The following renderer-neutral scenario is a required future Qt acceptance input and a Tauri diagnostic target: @@ -103,15 +162,74 @@ The following renderer-neutral scenario is a required future Qt acceptance input 1. Open a representative project and edit the manuscript. 2. Cross an autosave boundary. 3. Background the window for 5 seconds, return, and edit immediately. -4. Repeat for 20 Alt-Tab cycles; also exercise 30-second and two-minute background intervals where supported. -5. Test Settings, Writer Studio, minimize/restore, normal close, relaunch, and a large project. +4. Repeat for 20 Alt-Tab cycles. +5. Exercise 30-second and two-minute background intervals where supported. +6. Test Settings, Writer Studio, minimize/restore, normal close, relaunch, and a large project. +7. Run a 30-minute editing/memory session and a longer soak suitable for the target environment. +8. Repeat the same semantic scenario on PWA, Tauri, and Qt; later GPUI may consume it after separate admission. + +Required outcomes: no UI disappearance or unbounded hang; no force-kill; first click, caret, and keyboard input are acknowledged promptly; acknowledged edits survive; save and normal close work; **every normal close/relaunch leaves a clean process tree with no orphaned WorldScript WebKit/GPU/helper process attributable to that run**; no project corruption occurs. For admitted Qt/PWA acceptance, memory/resource growth must be bounded under the accepted fixture/duration. Transitional Tauri runtime-side growth may remain explicitly classified only when portable leakage has been ruled out and the authoritative stop rule is otherwise satisfied. + +Packaged evidence must name the build SHA, release, runtime/toolkit versions, OS, compositor, display protocol, GPU/driver, launch path, fixture/scenario version, and result maturity (`LOCAL_ONLY`, `CI_ONLY`, `PACKAGED_LOCAL`, `PACKAGED_TARGET_ENV`, or `FIELD_OBSERVED`). Browser success is a reference signal, not packaged closure evidence. + +## Cross-renderer benchmark record + +For #332-derived scenarios, preserve comparable measurements where practical: + +```text +Metric / scenario PWA Tauri Qt GPUI-if-admitted +cold/warm start ... ... ... ... +Settings navigation latency ... ... ... ... +editor input latency p50/p95 ... ... ... ... +scroll/frame consistency ... ... ... ... +Alt-Tab recovery ... ... ... ... +idle RSS ... ... ... ... +30-minute RSS / slope ... ... ... ... +long-soak peak RSS ... ... ... ... +save/autosave latency ... ... ... ... +large-project open/save ... ... ... ... +force-kill/crash/hang count ... ... ... ... +orphan process after close count ... ... ... ... +``` + +Numbers are evidence, not framework marketing. Use the same project fixture, workflow, measurement definition, and target machine when comparing renderers. Share semantic scenarios and evidence schema; renderer-specific drivers/instrumentation may differ. + +## Tauri exit rule for #332 — authoritative + +**This is the single authoritative stop rule for deep #332 runtime investigation in this policy.** It does not govern unrelated TM-3 rejection or ordinary TM-1/TM-2 investment decisions. + +Deep #332 Tauri-specific debugging may stop only when **all** of the following are true: + +- data-integrity and security risks are either fixed or separately tracked as TM-0; +- app-owned duplicate work, deadlock, unbounded serialization, and portable memory leaks have been ruled out or fixed; +- the remaining failure correlates materially with WebKitGTK, compositor, GPU driver, or host-environment behavior; +- the PWA or another renderer reference remains healthy under the same product workflow; +- the remaining proposed remedy would require broad WebKitGTK/NVIDIA heuristics, global graphics overrides, runtime forks, or substantial Tauri-only recovery architecture; +- a renderer-neutral acceptance scenario and enough evidence to reproduce/compare the behavior in Qt exist. + +At that point record `RUNTIME-LIMITED` or `ENVIRONMENT-LIMITED`, retain only a safe narrow support mitigation if justified, and move the scenario into Qt killer-gate/performance evidence. This is an intended stop-loss outcome, not an engineering failure. + +## Qt handoff rule + +#332 is a **Qt migration acceptance baseline**, not a requirement to perfect Tauri before Qt begins. + +The Qt target in ADR-0021 is Qt Quick/QML with Rust Core; Qt WebEngine is not the principal UI architecture. Therefore a WebKitGTK-specific failure is not automatically portable to Qt, while app/Core/lifecycle invariants are. + +Qt qualification must rerun the semantic #332 scenarios using Qt-native instrumentation and explicitly compare: -Required outcomes: no UI disappearance or unbounded hang; first click, caret, and keyboard input are acknowledged promptly; acknowledged edits survive; save and normal close work; no force-kill or orphan process is required; no project corruption occurs. +- input/interaction latency; +- GUI/render-thread behavior; +- process memory and long-session growth; +- background/resume and minimize/restore; +- clean process-tree shutdown/relaunch behavior; +- large-project open/save/autosave; +- graphics backend/GPU identity on Linux/Wayland/NVIDIA; +- multi-GPU behavior where target hardware exposes it. -Packaged evidence must name the build SHA, release, Tauri/WebKitGTK versions, OS, compositor, display protocol, GPU/driver, launch path, and result maturity (`LOCAL_ONLY`, `CI_ONLY`, `PACKAGED_LOCAL`, `PACKAGED_TARGET_ENV`, or `FIELD_OBSERVED`). Browser success is a reference signal, not packaged closure evidence. +A Tauri failure may remain open as a documented transitional runtime limitation while Qt proves the same workflow stable. Tauri removal still requires the normal G4/G5 retirement gates; #332 does not authorize an unsafe early cutover. -## Exit and retirement +## Retirement gate -Stop deep Tauri-specific debugging when app-owned duplicate work/deadlock and data-integrity defects have been ruled out, the failure correlates with the runtime or host environment, the PWA remains healthy, and the remaining workaround would be large or brittle. Record `RUNTIME-LIMITED` or `ENVIRONMENT-LIMITED`, retain a safe support mitigation if one exists, and move the scenario into Qt killer-gate evidence. +The **#332 debugging stop decision** is governed only by the authoritative Tauri exit rule above. It is distinct from both general TM-3 rejection and **runtime retirement**. -Tauri is removed only after Qt Stable, a field-observation window, project compatibility, update/recovery confidence, and real-user lifecycle evidence all pass. This policy does not authorize production Qt UI or a PWA-only pivot. +Tauri may be removed only after Qt Stable, a field-observation window, project compatibility, update/recovery confidence, real-user lifecycle evidence, and clean shutdown/process-tree evidence all pass. This policy does not authorize production Qt UI or a PWA-only pivot. \ No newline at end of file From aefde3116a1a18ffa3f5211d26341f6865c3c400 Mon Sep 17 00:00:00 2001 From: qnbs <155236708+qnbs@users.noreply.github.com> Date: Wed, 26 Aug 2026 02:49:08 +0200 Subject: [PATCH 3/6] docs(pwa): align PWA audit with reuse-first architecture Promotes PWA-AUDIT.md from a manifest/service-worker/share-target checklist (v1.8) into a living architecture contract, applying the same reuse-first governance as ARCHITECTURE-REUSE-OWNERSHIP.md: no second storage truth, no second update manager, no second general task framework, no second live-project authority alongside existing OPFS recognition -- the PWA reuses the existing local-AI facade, ai-core, and WorkerBus rather than inventing PWA-specific equivalents. Separates browser capability truth from product feature truth, and keeps background/deferred scheduling distinct from task execution. File System Access is treated as an adapter, not a second storage backend; mobile presentation defers to the existing canonical project model. The prior checklist's substantive facts (display_override, share_target, launch_handler, protocol_handlers) are preserved, not dropped, inside the new structure. Reconciled directly onto current main from PR #477's frozen head (2a6da40b) -- main has made no changes to this path since the PR branched. README.md/AUDIT.md/TODO.md still describe the old checklist form; updating those is out of this PR's six-file scope and is a separate follow-up. --- docs/PWA-AUDIT.md | 811 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 777 insertions(+), 34 deletions(-) diff --git a/docs/PWA-AUDIT.md b/docs/PWA-AUDIT.md index f6efc6475..6c6b47fbb 100644 --- a/docs/PWA-AUDIT.md +++ b/docs/PWA-AUDIT.md @@ -1,49 +1,792 @@ -# PWA Audit — WorldScript Studio (v1.8) +# WorldScript Studio — Living PWA Architecture & Acceptance Audit -Baseline from [ROADMAP.md](../ROADMAP.md) UX/PWA section. Status: **2026-05-21**. +**Status:** ACTIVE living PWA architecture/acceptance specification +**Updated:** 2026-08-24 +**Umbrella issue:** #478 — first-class PWA excellence/hardening +**Cross-cutting architecture governance:** [`architecture/ARCHITECTURE-REUSE-OWNERSHIP.md`](architecture/ARCHITECTURE-REUSE-OWNERSHIP.md) +**Native relationship:** [`native/DESKTOP-MIGRATION-ROADMAP-REV3.md`](native/DESKTOP-MIGRATION-ROADMAP-REV3.md) -## Manifest ([public/manifest.json](../public/manifest.json)) +--- -| Check | Status | -|-------|--------| -| `display_override` (standalone + minimal-ui) | Done | -| Shortcuts (templates, manuscript, writer, scene board, session) | Done | -| `share_target` GET params | Done | -| `launch_handler` navigate-existing | Done | -| `handle_links` preferred | Done (v1.8) | -| Maskable + any icons | SVG `favicon.svg` | -| `protocol_handlers` web+worldscript | Done | +## 1. Product contract -Optional later: PNG 192/512 for store listings; `screenshots` for install UI. +WorldScript PWA is a **first-class product surface**, not a compatibility fallback for Tauri and not a temporary shell waiting for Qt. -## Service Worker ([public/sw.js](../public/sw.js)) +The product strategy is: -| Check | Status | -|-------|--------| -| Version sync via `scripts/sync-sw-version.mjs` | Done (`predev` / `prebuild`) | -| Precache via Workbox `__WB_MANIFEST` only | Done | -| Network-only for AI / inference hosts | Verify in `sw.js` route rules | -| No precache of DuckDB-WASM / large ONNX | Do not add to precache | +```text +Shared product/domain semantics + │ + ├── PWA: browser-native excellence + │ IDB / Service Worker / Web APIs / WebGPU / OPFS where admitted + │ + └── Native: DesktopPlatform + renderer-neutral Rust Core + Qt target +``` + +PWA and native renderers share semantic/data-format/interoperability contracts where the product truth is common. They do **not** require identical implementation mechanics. + +Browser APIs must not leak into Rust/Core or `DesktopPlatform` merely to make PWA and Qt look symmetrical. + +--- + +## 2. Reuse-first implementation invariant + +This program is **refinement-first, not greenfield**. + +Before adding a new PWA service, store, manager, queue, registry, state machine, worker framework, capability detector, or persistence layer, apply `ARCHITECTURE-REUSE-OWNERSHIP.md`. + +Preferred order: + +```text +1. FIX THE EXISTING OWNER +2. EXTEND THE EXISTING OWNER +3. ADD A NARROW PWA ADAPTER +4. EXTRACT A SHARED PRIMITIVE FROM REAL DUPLICATION +5. REFACTOR AUTHORITY +6. ONLY THEN CREATE A NEW SUBSYSTEM +``` + +At minimum inspect these existing seeds before designing replacements: + +- `services/storageService.ts` / `services/storageBackend.ts` / existing IndexedDB stores; +- `app/persistenceCoordinator.ts` / `app/persistedStateFlush.ts`; +- encryption migration/journal/admission, including `services/storage/protectedWriteAdmission.ts`; +- `public/sw.js` / `register-sw.ts` / existing install-update UI; +- `services/localAiFacade.ts` / AI-core / WorkerBus v2 / adaptive AI / device profiling; +- current DuckDB OPFS integration in `workers/v2/duckdb.worker.ts`; +- `features/featureCatalog.ts` and feature flags for product feature truth; +- existing diagnostics/redaction facilities; +- existing project import/export and Tauri deep-link flow. + +No new PWA enhancement may silently create a second project, schema, crypto, migration, AI, task, update, feature-gating, or diagnostics authority. + +--- + +## 3. PWA workstream / issue graph + +#478 is the umbrella. Child work should remain traceable to the following dependency model: + +```text +#478 PWA excellence +│ +├─ foundation +│ └─ #489 capability/admission facade +│ +├─ correctness/lifecycle +│ ├─ #480 multi-context ownership +│ ├─ #482 storage health/tiering +│ └─ #485 update lifecycle +│ +├─ external I/O / installed app +│ ├─ #484 ExternalLaunchIntent + Capture Inbox +│ ├─ #481 File System Access / file handling +│ └─ #486 installed shell +│ +├─ local AI +│ └─ #483 existing local-AI stack perfection +│ ├ uses #489 capability facts +│ ├ coordinates #480 +│ └ artifact/storage policy from #482 +│ +├─ deferred work +│ └─ #488 +│ ├ uses #489 capability facts +│ ├ ownership via #480 +│ ├ update compatibility via #485 +│ └ reuses existing WorkerBus/application executors +│ +└─ mobile + └─ #487 + ├ same canonical project/domain model + ├ capture enhancement via #484 + ├ storage truth via #482 + └ AI enhancement via #483 +``` + +This is a dependency graph, not a mandatory waterfall. Work may proceed in parallel when its prerequisites and ownership are explicit. + +--- + +## 4. Capability truth model (#489) + +Keep four planes separate: + +```text +1. Product feature plane + featureCatalog / feature flags + "Has WorldScript admitted/enabled feature X?" + +2. Runtime capability plane + PWA capability facade + "Can this runtime expose primitive Y?" + +3. Subsystem admission plane + AI / storage / update / files / mobile + "Can this concrete workflow safely use Y?" + +4. Diagnostics/support plane + privacy-safe composed explanation +``` + +A capability facade should compose existing probes instead of duplicating them. + +Example: + +```text +WebGPU runtime capability = AVAILABLE +Model X AI admission = DENIED +Reason = device/workload limit +``` + +Both statements may be correct. + +Support/runtime states may include: + +```text +UNAVAILABLE +AVAILABLE +AVAILABLE_WITH_LIMITATIONS +PERMISSION_REQUIRED +PERMISSION_GRANTED +PERMISSION_DENIED +BROKEN_OR_FAILED_PROBE +DISABLED_BY_POLICY +``` + +Use feature/probe results first; browser/version detection is diagnostic context or a narrowly documented compatibility exception, not the normal architecture gate. + +--- + +## 5. Manifest / installed-app contract + +Current manifest capabilities must correspond to real, tested product behavior rather than decorative metadata. + +Audit at least: + +- `display: standalone` and `display_override` including `window-controls-overlay` where present; +- 192/512 icons and maskable safe zones; +- shortcuts; +- `share_target`; +- `launch_handler`; +- `handle_links`; +- `protocol_handlers`; +- any Edge side-panel declaration; +- future admitted `file_handlers`. + +Installed mode is progressive enhancement: + +```text +normal browser tab = complete baseline product +installed PWA = enhanced shell +supported Chromium = additional window/OS integration +mobile installed PWA = touch/mobile shell +``` + +Installation is never required for project safety or core writing. + +--- + +## 6. Offline-first correctness + +Core writing must have an explicit offline contract. + +Required tests/evidence: + +- cold offline launch; +- warm offline launch; +- mid-session disconnect; +- flaky/captive/failed network; +- open local project; +- edit/autosave; +- close/relaunch; +- export/backup where local APIs permit; +- browser process eviction/restart; +- network-dependent feature failure without core writing failure. + +Acknowledged edits must not be lost merely because connectivity changes. + +AI/provider endpoints whose caching would be unsafe or misleading remain network-only. + +Offline UX must distinguish: + +- local writing available; +- cloud/provider unavailable; +- local model unavailable/not downloaded; +- update waiting; +- storage problem; +- application-shell failure. + +Do not collapse all failures into a generic “offline” message. + +--- + +## 7. Persistence and storage authority (#482) + +### 7.1 Structured live project state + +Existing IndexedDB/browser storage remains the live authoritative PWA project path unless a separate evidence-backed authority decision changes that. + +`storageService` / `StorageBackend` remain the high-level seed. + +Do not create a second whole-application OPFS project database merely because OPFS is available. + +### 7.2 OPFS + +OPFS is already present in the DuckDB worker via `navigator.storage.getDirectory()` and a DuckDB file handle with fallback. + +Treat that as the production seed. + +Preferred use is **per data class**, e.g. where measured benefit exists for: + +- analytics/WASM database files; +- local-AI model artifacts; +- large RAG/index artifacts; +- selected large binary/regenerable data. + +Each admitted class needs: + +- authority classification; +- performance/storage rationale; +- fallback; +- staging/commit/recovery model; +- cleanup/orphan policy; +- encryption classification. + +### 7.3 Cache Storage + +Use Cache Storage for explicit safe network-derived/refetchable resources, not as a generic project database. + +### 7.4 User-controlled export / File System Access + +File System Access (#481) is an optional adapter over existing import/export semantics. + +Default: + +```text +browser storage = live project authority +selected file = explicit mirror/export/backup target +``` + +Retaining a file handle must not silently create a second writer authority. + +### 7.5 Persistence/quota UX + +Where supported, expose truthful `navigator.storage.persisted()` / `persist()` / `estimate()` state. + +The storage-health UI should distinguish: + +- authoritative projects/structured data; +- images/assets; +- snapshots/backups; +- RAG/indexes; +- local-AI models; +- regenerable caches; +- Service Worker assets; +- quota/persistence state. + +Factory reset/clear-site-data is a destructive last resort, not normal first-line recovery. + +--- + +## 8. Encryption and migration truth + +Browser origin privacy is not equivalent to WorldScript product encryption. + +Keep distinct: + +- credential/API-key storage; +- opt-in project-data encryption; +- collaboration crypto; +- origin-private storage; +- native R-15 protection. + +Existing IDB encryption journal/admission remains authoritative for current PWA protected-data semantics. + +`services/storage/protectedWriteAdmission.ts` already uses security-specific shared/exclusive Web Locks. Generic #480 coordination may compose/extract browser primitives but must not replace/weaken security migration policy. + +Any IDB→OPFS protected-data movement must preserve the admitted encryption/migration/identity semantics and avoid plaintext staging downgrades. + +--- + +## 9. Multi-context correctness (#480) + +The PWA may have browser tabs, installed windows, workers and a Service Worker active concurrently. + +The goal is safe ownership, not accidental last-writer-wins. + +Existing coordination seeds include: + +- Web Locks protected-write admission; +- BroadcastChannel/localStorage heartbeat local-AI leadership. + +Generic extraction, if justified, should be limited to primitives such as: + +- context identity; +- lock request helper; +- typed/versioned bounded channel envelope; +- channel lifecycle; +- capability/fallback reporting. + +Subsystem policy remains with subsystem owners. + +For project writer ownership, safely handle: + +- same project opened twice; +- different projects in different windows; +- read-only secondary context; +- explicit takeover; +- active writer crash/reload; +- background/frozen context; +- migration during editing; +- installed PWA + normal tab. + +BroadcastChannel is advisory coordination, never durable truth. + +Unsupported Web Locks capability must not silently restore unsafe concurrent writing. + +--- + +## 10. Service Worker and update safety (#485) + +Existing authority begins in: + +- `public/sw.js`; +- `register-sw.ts`; +- current PWA update/install UI. + +Update hardening must refactor this path **in place** or explicitly retire replaced paths. Do not build a second update manager next to the current one. + +The current unconditional install-time `skipWaiting()` / controller-change reload behavior is not sufficient as the final dirty-session/multi-client protocol. + +Target update state model: + +```text +NO_UPDATE +→ UPDATE_DISCOVERED +→ DOWNLOADED_WAITING +→ CLIENTS_ASSESSED +→ SAFE_TO_ACTIVATE | USER_ACTION_REQUIRED +→ ACTIVATING +→ RELOADING/RECONNECTING +→ VERIFIED +→ RECOVERY_REQUIRED +``` + +Before activation consider: + +- dirty/acknowledged edit state; +- confirmed persistence/flush state; +- live clients; +- active migration/recovery; +- backup/export critical section; +- local-AI/model artifact transition where interruption matters; +- app-code/storage-schema compatibility. + +A `Save & update` action must wait for the real durable persistence contract, not an optimistic or queued save request. + +Large model artifacts should have a lifecycle independent of app-shell cache churn unless compatibility requires invalidation. + +Required N→N+1 tests include clean/dirty/multiple clients, offline transition, asset failure and representative schema migration. + +--- -## Runtime ([App.tsx](../App.tsx)) +## 11. Local AI (#483) -| Check | Status | -|-------|--------| -| `?view=` validated on boot | Done | -| Share target → toast + sessionStorage + URL clean | Done | -| `document.documentElement.lang` from i18n | Done | +The existing local-AI architecture remains the single product abstraction: -## Install UX (optional) +- `services/localAiFacade.ts`; +- AI-core; +- WorkerBus v2; +- adaptive AI; +- local device profiling/WebGPU detection; +- GPU resource management; +- existing progress/cancellation/lifecycle facilities. -- `beforeinstallprompt` deferred banner — feature-flagged future work -- Offline fallback copy via `useAnnounce` on failed navigation +Do not create a parallel PWA AI facade/backend selector/worker queue. -## Local verification +Expose execution truth clearly: + +```text +Browser local — WebGPU +Browser local — WASM/CPU +Local server — Ollama / compatible endpoint +Cloud provider +Unavailable / fallback +``` + +Never label a path local if manuscript context leaves the device. + +Model/workload admission must be more specific than `navigator.gpu` existence. + +A durable model-artifact manifest/catalog is justified only if existing architecture lacks lifecycle truth for: + +- model/version/quantization identity; +- size/hash/integrity; +- stored generation/location; +- backend/runtime compatibility; +- download/ready/active/removable state; +- provenance/license metadata. + +If introduced, it lives beneath the existing local-AI facade and coordinates storage with #482. + +No hidden local→cloud escalation is permitted. + +--- + +## 12. External launch / capture / files (#484/#481/#486) + +Unify external entry mechanisms under one bounded typed boundary: + +```text +PWA share target +protocol handler +shortcut +launch handler / launchQueue +file handler +Tauri/native deep-link adapter + │ + ▼ +ExternalLaunchIntent + │ + ▼ +allowlisted router / required confirmation + │ + ▼ +existing commands/import/domain actions +``` + +External payloads are untrusted and may never directly trigger: + +- provider calls; +- plugin installation; +- secret/token changes; +- destructive project replacement; +- arbitrary filesystem/network access; +- arbitrary URL execution. + +### Capture Inbox + +A bounded durable Capture Inbox is a legitimate new product capability because persistent capture does not currently exist. + +Once assigned, captured content should reuse canonical existing project entities/surfaces. Do not maintain parallel `CaptureNote`, `CaptureScene`, `CaptureCharacter`, etc. models after assignment. + +Durable acknowledgement must precede “Captured” success UI. + +Current GET share-target compatibility may remain initially, but evaluate an admitted POST/multipart path for private content when browser support and bounded threat/size handling are proven. + +--- + +## 13. Installed shell (#486) + +Evolve current manifest + `register-sw.ts` + `window.worldScriptPWA`/events rather than creating an unrelated second install/update state. + +If a typed service/store replaces the global/event path, migrate and retire the duplicate deliberately. + +Installed-mode enhancements may include: + +- contextual install UX; +- Window Controls Overlay; +- shortcuts; +- link/protocol/file/share handling; +- meaningful local badging; +- explicit opt-in notifications for justified long tasks; +- compact/side-panel companion workflow where genuinely useful. + +Display mode affects shell/presentation behavior, not project/business/persistence/AI semantics. + +--- + +## 14. Mobile (#487) + +Mobile uses the same canonical project/domain/command/persistence model. + +Mobile-specific concerns include: + +- responsive shell/drawers/sheets; +- touch targets; +- `VisualViewport` / Virtual Keyboard behavior; +- safe areas/orientation; +- wake-lock lifecycle; +- mobile performance/admission policy; +- compact action/status presentation. + +Do not create a separate mobile project model or editor domain merely because presentation differs. + +Test the existing editor's caret/selection/IME/touch/viewport correctness before proposing a replacement editor architecture. + +Heavy AI/analytics/graph/model initialization remains lazy and capability-admitted; editor-ready time and autosave responsiveness take priority. + +--- + +## 15. Deferred/background work (#488) + +Browser background APIs are opportunistic, not a native daemon. + +Authoritative manuscript autosave, encryption commit, key rotation, only-copy backup, destructive cleanup, and schema-migration finalization must not depend on Background Sync. + +The current `worldscript-autosave` Background Sync naming/contract must be reconciled so future code/docs cannot mistake SW scheduling for durability authority. + +A new component may be introduced only as a small bounded/versioned scheduling journal owning: + +- task identity/kind; +- idempotency key; +- eligibility/backoff; +- attempt/cancellation/failure state; +- bounded non-sensitive payload/reference metadata; +- queue-schema version. + +Execution should reuse existing WorkerBus/application services where suitable. Do not create a second general PWA task framework. + +--- + +## 16. Performance and responsiveness + +PWA is a measured reference renderer, not merely “faster than Tauri.” + +Measure representative hardware/classes for: + +- cold/warm startup; +- editor-ready/time-to-interactive; +- input latency p50/p95; +- scroll/frame consistency; +- Settings/Writer Studio navigation; +- project open/save/autosave; +- large-project behavior; +- background/resume; +- 30-minute and long-session memory/resource trend; +- WebGPU/model initialization; +- bundle/chunk transfer + parse/execute cost. + +Coordinate bundle limits with #450 rather than creating competing PWA-only bundle-budget tooling. + +Lazy-load genuinely cold work, but never hide correctness work or move expensive initialization onto the first critical user interaction merely to improve a synthetic startup number. + +PWA memory/resource growth must be bounded for admitted regression acceptance. An explanation of unbounded growth is diagnostic classification, not a pass. + +--- + +## 17. Accessibility and readability + +Coordinate with #341 and use a shared semantic oracle rather than renderer-specific definitions of “readable.” + +Validate: + +- contrast under themes/accessibility presets; +- editable/mirror/overlay font and geometry parity; +- caret/selection/scroll alignment; +- theme transitions; +- zoom/text scaling; +- reduced motion/transparency; +- keyboard-only workflows; +- focus restoration; +- screen-reader announcements for save/offline/update/model states; +- RTL/BiDi/IME where applicable; +- mobile keyboard/viewport behavior. + +PWA evidence does not automatically close packaged Tauri/Qt rendering regressions; the semantic oracle is shared while renderer evidence is classified separately. + +--- + +## 18. Cross-browser support policy + +Maintain evidence-backed tiers: + +```text +SUPPORTED +SUPPORTED_WITH_LIMITATIONS +BEST_EFFORT +UNSUPPORTED +``` + +At minimum classify current: + +- Chrome/Chromium desktop; +- Edge desktop; +- Firefox desktop; +- Safari macOS; +- Android Chromium; +- iOS/iPadOS Safari browser/installed mode. + +Document relevant differences in: + +- installability; +- Service Worker/update behavior; +- Web Locks/BroadcastChannel; +- OPFS/StorageManager; +- File System Access/file handling; +- WebGPU/local AI; +- background APIs; +- mobile keyboard/viewport APIs. + +Do not block high-value Chromium-native enhancement merely to simulate feature parity. Baseline writing must degrade explicitly and safely. + +--- + +## 19. Security/privacy + +Audit: + +- CSP and worker boundaries; +- cross-origin isolation requirements if introduced; +- provider routing, especially Claude web proxy truth; +- local-vs-cloud AI truth; +- cache poisoning/stale-code/version skew; +- external launch/share/protocol/file inputs; +- imports/archives; +- storage/encryption semantics; +- diagnostics/redaction; +- telemetry policy. + +No performance/capability/support diagnostic may contain manuscript text, prompts/results, API keys/tokens, encryption material, private local paths or raw provider payloads. + +Coordinate translated security wording with #382 rather than introducing PWA-specific contradictory claims. + +--- + +## 20. CI / release evidence + +PWA acceptance should grow beyond “production build succeeds.” + +Evidence categories include: + +- manifest/installability validation; +- Service Worker policy tests; +- offline smoke/E2E; +- transactional update lifecycle tests; +- IndexedDB migration/recovery fixtures; +- PWA accessibility smoke; +- capability-registry normalization/fallback tests; +- browser matrix at evidence-appropriate cadence; +- Pages/Vercel routing/base-path/SW-scope parity; +- deterministic performance/bundle ratchets where runner variance permits them. + +Do not duplicate dedicated quality authorities: + +- #446 remains executable coverage-scope authority; +- #447 remains suppression-debt/ratchet authority; +- #449 remains generated locale-bundle policy authority; +- #450 remains bundle-budget authority. + +PWA owns the PWA acceptance contract consuming those controls. + +--- + +## 21. Cross-renderer relationship to #332 / Qt + +PWA is both: + +1. an independently valuable product; +2. a useful reference renderer for portable-vs-runtime differential evidence. + +`GOLDEN-DESKTOP-LIFECYCLE-332` should share semantic scenario definitions/fixtures/metrics/evidence schema across PWA, Tauri and Qt, while each renderer uses its own appropriate driver/instrumentation. + +PWA success does not equal packaged native closure. Qt success does not retire/freeze PWA. + +Portable fixes move into shared/domain/Core layers only when they are actually portable. Browser-specific excellence remains behind PWA/browser boundaries. + +--- + +## 22. User-driven evidence + +When field observations are useful, prefer small privacy-safe records: + +- browser/version and OS; +- normal tab vs installed PWA; +- online/offline state; +- approximate project size; +- local AI/Ollama/cloud AI active or not; +- exact workflow and visible symptom; +- redacted screenshot where safe. + +Never ask users to post manuscript content, API keys/tokens, encryption material, private paths, full storage dumps or sensitive provider payloads. + +--- + +## 23. Current acceptance checklist + +### Architecture / ownership + +- [ ] Every major PWA capability has one named semantic owner. +- [ ] Existing seeds were inventoried before new architecture was introduced. +- [ ] No silent duplicate project/storage/schema/crypto/migration/AI/task/update/feature-gating authority exists. +- [ ] Any replaced path has an explicit migration/deprecation/removal plan. +- [ ] Browser APIs remain outside native Core/DesktopPlatform contracts unless the shared contract is genuinely platform-neutral. + +### Offline / persistence + +- [ ] Cold/warm offline writing path is deterministic. +- [ ] Acknowledged edits survive offline/relaunch/process eviction. +- [ ] IDB migration/recovery/storage-pressure tests exist. +- [ ] OPFS use is data-class-specific and evidence-driven. +- [ ] Persistence/quota UX is truthful. +- [ ] Export/backup exists before destructive recovery actions. + +### Concurrency / update + +- [ ] Same project cannot silently have two independent PWA writers. +- [ ] Security migration admission remains fail-closed. +- [ ] Dirty clients block unsafe update activation/reload. +- [ ] N→N+1 update lifecycle has multi-client/offline/schema-transition evidence. +- [ ] Service Worker is not project-data or migration authority. + +### Local AI + +- [ ] Existing local-AI facade remains the single product abstraction. +- [ ] Runtime capability and model/workload admission are distinct. +- [ ] Heavy inference is off the UI thread. +- [ ] Cancellation/device-loss/OOM recovery preserves editor/autosave state. +- [ ] Model artifact lifecycle/integrity/storage is explicit. +- [ ] No hidden local→cloud fallback exists. + +### Installed / external / mobile + +- [ ] Manifest declarations correspond to admitted tested behavior or are explicitly deferred/removed. +- [ ] External inputs normalize through one typed validation boundary. +- [ ] Capture Inbox acknowledgement is durable. +- [ ] File System Access cannot silently create dual project authority. +- [ ] Mobile uses the canonical project/domain model. +- [ ] Virtual keyboard/safe-area/touch/accessibility evidence exists. + +### Security / quality / deployment + +- [ ] Browser support matrix is explicit and evidence-backed. +- [ ] PWA diagnostics are privacy-safe. +- [ ] Security wording aligns with #382/current provider/storage truth. +- [ ] Coverage/suppression/locale/bundle controls reconcile #446/#447/#449/#450 rather than duplicate them. +- [ ] Pages/Vercel PWA routing and Service Worker scope are smoke-tested. +- [ ] Performance/resource regression budgets are measured rather than arbitrary. + +--- + +## 24. Local verification + +On constrained development machines, use the repository's bounded pre-push gate as the local baseline: ```bash -pnpm run build && pnpm run preview -# Lighthouse PWA category (CI or powerful machine) -pnpm exec lhci autorun +pnpm run ci:prepush ``` -See also [docs/CI.md](CI.md) and [infra/low-end-ci/DAILY-DRIVER.md](../infra/low-end-ci/DAILY-DRIVER.md). +Do **not** run Lighthouse, E2E/deep-E2E, VRT, Storybook browser suites, or broad browser-matrix jobs locally on constrained machines merely to satisfy this document. Those heavyweight checks are cloud-CI evidence and must remain there unless the repository's explicit machine policy later changes. Targeted lightweight unit/typecheck/policy commands may be run locally when they are directly relevant and remain within the documented resource envelope. + +Documentation-only evidence must not be presented as runtime acceptance. Lighthouse/E2E/browser-matrix acceptance is established from the corresponding CI runs and artifacts, not by overloading low-end developer hardware. + +See also: + +- [`docs/CI.md`](CI.md) +- [`infra/low-end-ci/DAILY-DRIVER.md`](../infra/low-end-ci/DAILY-DRIVER.md) +- [`architecture/ARCHITECTURE-REUSE-OWNERSHIP.md`](architecture/ARCHITECTURE-REUSE-OWNERSHIP.md) +- [`native/DESKTOP-MIGRATION-ROADMAP-REV3.md`](native/DESKTOP-MIGRATION-ROADMAP-REV3.md) + +--- + +## 25. Non-goals + +- forcing PWA to emulate every native OS integration; +- forcing Qt to embed a web renderer to preserve PWA implementation details; +- creating a second live project store because OPFS/File System Access exists; +- creating a second local-AI/task/update stack for PWA; +- treating browser origin privacy as product encryption; +- sacrificing offline safety/security for Lighthouse scores; +- requiring installation for core writing; +- making basic writing Chromium-only because enhanced local AI is Chromium-first; +- treating PWA as disposable after Qt succeeds. \ No newline at end of file From 6a34b8930f940f5abcc27fd64f4869118781c502 Mon Sep 17 00:00:00 2001 From: qnbs <155236708+qnbs@users.noreply.github.com> Date: Wed, 26 Aug 2026 02:49:24 +0200 Subject: [PATCH 4/6] chore(native): enforce roadmap governance in native-readiness checks Extends check-native-readiness.mjs to validate the three preceding commits' new/expanded content: canonical Revision-3 sequencing, the scoped Revision-3 transfer gates (validated inside their real document sections via the existing section() helper, not brittle whole-document substring checks, so a summary bullet can never mask a deleted gate body), the Tauri stop policy, and the reuse/ownership governance assertions against ARCHITECTURE-REUSE-OWNERSHIP.md. Reuses the existing read()/section()/requireText() helpers throughout -- no new parser or policy-checking authority. Deterministic, no network, no runtime mutation; fast enough for routine local admission (confirmed via pnpm run ci:prepush). Reconciled directly onto current main from PR #477's frozen head (2a6da40b) -- confirmed this does not duplicate any check performed by a different current-main script, and does not reference anything absent from main (docs/adr/0022-qt-pre-g2-qualification-harness.md and docs/architecture/native-readiness.md, which the pre-existing assertions already read, both exist unchanged). --- scripts/check-native-readiness.mjs | 123 ++++++++++++++++++++++++++++- 1 file changed, 122 insertions(+), 1 deletion(-) diff --git a/scripts/check-native-readiness.mjs b/scripts/check-native-readiness.mjs index 465662d2f..b41a47406 100644 --- a/scripts/check-native-readiness.mjs +++ b/scripts/check-native-readiness.mjs @@ -5,6 +5,9 @@ import process from 'node:process'; const root = process.cwd(); const read = (relativePath) => fs.readFileSync(path.join(root, relativePath), 'utf8'); const roadmap = read('docs/native/ROADMAP-QT-GPUI-DESKTOP.md'); +const roadmapRev3 = read('docs/native/DESKTOP-MIGRATION-ROADMAP-REV3.md'); +const tauriPolicy = read('docs/native/TAURI-TRANSITIONAL-MAINTENANCE.md'); +const reusePolicy = read('docs/architecture/ARCHITECTURE-REUSE-OWNERSHIP.md'); const earlyGates = read('docs/native/QT-EARLY-KILLER-GATES.md'); const adr0022 = read('docs/adr/0022-qt-pre-g2-qualification-harness.md'); const nativeReadiness = read('docs/architecture/native-readiness.md'); @@ -24,6 +27,21 @@ const section = (source, heading, nextHeading) => { const earlyLanes = section(roadmap, '## Early Native Feasibility Lanes', '## Wave 3'); const waveFive = section(roadmap, '## Wave 5 —', '## Wave 6 —'); const g1 = section(roadmap, '## G1 — Core Native-Ready', '## G2 —'); +const rev3G15 = section( + roadmapRev3, + '### G1.5 — Tauri Evidence Exit / Qt Transfer Readiness — NEW', + '### G2 — Qt Implementation Admission', +); +const rev3G25 = section( + roadmapRev3, + '### G2.5 — Qt Renderer Differential Gate — NEW', + '### G3 — Qt Beta', +); +const rev3Wave25 = section( + roadmapRev3, + '### Wave 2.5 — Desktop differential baseline & #332 classification — NEW', + '### Wave 3 — Storage correctness and R-15 design', +); const earlyOrder = [ 'Lifecycle and bridge spike', 'Accessibility and input feasibility', @@ -60,6 +78,104 @@ for (const wave of ['21', '22', '23', '24']) { failures.push(`GPUI Wave ${wave} must not remain a numbered roadmap wave.`); } } + +// QNBS-v3: Validate mandatory Revision-3 gates inside their real sections so summary bullets cannot mask deleted gate bodies. +requireText( + rev3G15, + 'GOLDEN-DESKTOP-LIFECYCLE-332 encoded as reusable evidence specification', + 'Revision 3 G1.5 must retain the reusable #332 lifecycle evidence requirement.', +); +requireText( + rev3G15, + 'PWA/Tauri baseline measurements captured on representative target hardware', + 'Revision 3 G1.5 must retain representative PWA/Tauri baseline evidence.', +); +requireText( + rev3G25, + 'capture Qt Quick graphics backend', + 'Revision 3 G2.5 must retain Qt graphics-backend evidence.', +); +requireText( + rev3G25, + 'run 20-cycle Alt-Tab scenario', + 'Revision 3 G2.5 must retain the Alt-Tab differential scenario.', +); +requireText( + rev3Wave25, + 'portable-memory classification', + 'Revision 3 Wave 2.5 must retain portable-memory classification.', +); +requireText( + rev3Wave25, + 'Tauri stop-rule decision record', + 'Revision 3 Wave 2.5 must retain the Tauri stop-rule decision record.', +); +requireText( + roadmapRev3, + 'GOLDEN-DESKTOP-LIFECYCLE-332', + 'Revision 3 must retain the cross-renderer #332 lifecycle acceptance scenario.', +); +requireText( + tauriPolicy, + 'DESKTOP-MIGRATION-ROADMAP-REV3.md` is the **normative Revision-3 amendment**', + 'The Tauri policy must explicitly designate Revision 3 as a normative roadmap amendment.', +); +requireText( + tauriPolicy, + '## Tauri exit rule for #332 — authoritative', + 'The Tauri policy must have exactly one named authoritative #332 stop rule.', +); +if ((tauriPolicy.match(/## Tauri exit rule for #332/g) ?? []).length !== 1) { + failures.push('The Tauri policy must contain exactly one #332 exit-rule heading.'); +} +requireText( + tauriPolicy, + 'clean process tree with no orphaned WorldScript WebKit/GPU/helper process', + 'The lifecycle acceptance policy must reject orphan processes after close/relaunch.', +); + +// QNBS-v3: Keep cross-cutting ownership/reuse governance mechanically present without turning the companion policy into another roadmap. +requireText( + reusePolicy, + 'Capability boundaries before package/crate boundaries', + 'Architecture governance must retain the capability-before-crate/package rule.', +); +requireText( + reusePolicy, + 'Reuse-first architecture gate', + 'Architecture governance must retain the explicit existing-authority/seed audit.', +); +requireText( + reusePolicy, + 'ONE AUTHORITY PER SEMANTIC CAPABILITY', + 'Architecture governance must preserve one semantic authority per capability.', +); +requireText( + reusePolicy, + 'Scenario specification / fixture / metrics / thresholds', + 'Cross-renderer governance must share scenario semantics without requiring a mega-driver.', +); +requireText( + reusePolicy, + 'A PWA runtime-capability registry must not replace feature flags.', + 'PWA runtime capability and product feature-admission truth must remain separate.', +); +requireText( + reusePolicy, + 'Do not introduce a second live-project authority to add OPFS or user-selected file handles.', + 'PWA storage enhancements must not create a silent second live-project authority.', +); +requireText( + reusePolicy, + 'A second independent update manager is forbidden unless the old path is explicitly retired.', + 'PWA update hardening must refine or retire the existing SW/update path rather than duplicate it.', +); +requireText( + reusePolicy, + /do not create a second general task framework/i, + 'Deferred PWA work must reuse task execution architecture rather than duplicate it.', +); + requireText( earlyGates, 'planned → locally proven → CI-proven → packaged-proven → admitted', @@ -70,6 +186,11 @@ requireText( 'The formal Wave 4.5 qualification consumes the early-lane evidence', 'Wave 4.5 must consume early-lane evidence instead of silently duplicating it.', ); +requireText( + earlyGates, + 'Linux graphics differential', + 'Qt qualification must include the Revision-3 Linux graphics differential lane.', +); requireText( waveFive, /does not repeat or\s+re-prove the early lifecycle, accessibility\/input, or crash gates/, @@ -97,6 +218,6 @@ if (failures.length > 0) { process.exitCode = 1; } else { console.log( - 'Native-readiness policy check passed: early lanes, maturity vocabulary, GPUI boundary, and Wave 5 sequencing are consistent.', + 'Native-readiness policy check passed: canonical sequencing, scoped Revision-3 transfer gates, Tauri stop policy, reuse/ownership governance, maturity vocabulary, GPUI boundary, and Wave 5 sequencing are consistent.', ); } From 71aecca449fbfea9bb08fcae7c0e49ffe8a90ff4 Mon Sep 17 00:00:00 2001 From: qnbs <155236708+qnbs@users.noreply.github.com> Date: Wed, 26 Aug 2026 03:03:57 +0200 Subject: [PATCH 5/6] fix: link Revision 3 into the canonical authority chain, close gate loopholes Root-clustered remediation for the first fresh review epoch on the reconciled head (three codex findings): - Broken binding authority chain (P1): AGENTS.md, CLAUDE.md, and ADR-0021 all direct contributors to ROADMAP-QT-GPUI-DESKTOP.md as the full Qt strategy, but that document still self-identifies as "Revision: 2" with no mention of DESKTOP-MIGRATION-ROADMAP-REV3.md anywhere in any of the three canonical entry points -- confirmed via direct grep. A contributor following the documented path would never discover G1.5, G2.5, or Wave 2.5. Each of the four files now explicitly names Revision 3 as a binding amendment at the point where it already points to the roadmap, rather than leaving it a standalone, undiscoverable "proposed" refinement. - Gate-matrix internal contradiction (P1): the Linux graphics differential row's kill condition said "unexplained unbounded resource growth," while Revision 3's own admission rule (and this same file's general kill criteria, two sections later) states that explained or unexplained unbounded growth is a failure -- an explanation cannot convert an unbounded Qt leak into a pass. The qualifier created exactly the loophole it was flagged for: a scorecard could record a pass on this row while failing the governing roadmap rule on the same evidence. Removed the qualifier; the row now states explicitly that an explanation does not convert a pass. - Checker scope gap (P2): the QF-D assertion searched the entire QT-EARLY-KILLER-GATES.md document for the phrase "Linux graphics differential," so deleting the actual Gate-matrix row (with its binding proof/kill-condition requirements) would still pass, since the same phrase survives in the early-lane heading and ownership text elsewhere in the file. Scoped the assertion to the "## Gate matrix" section specifically (reusing the existing section() helper, not a new parser) and added a second assertion on the kill condition's exact wording, so a future edit weakening either the row's presence or its "explained or not" language fails the check. Empirically verified both directions: temporarily deleted the row and confirmed the check now fails with the new assertion (it would have silently passed before this fix); restored the row and confirmed the check passes again. All three findings validated against the exact current file content before fixing (not just the reviewer's wording). Local validation: lint, 4-checker typecheck, ci:prepush, native-readiness check all clean. --- AGENTS.md | 2 +- CLAUDE.md | 2 +- docs/adr/0021-qt-gpui-native-desktop-strategy.md | 3 ++- docs/native/QT-EARLY-KILLER-GATES.md | 2 +- docs/native/ROADMAP-QT-GPUI-DESKTOP.md | 1 + scripts/check-native-readiness.mjs | 10 ++++++++-- 6 files changed, 14 insertions(+), 6 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 4f045bf52..cf06c01ec 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -16,7 +16,7 @@ The app supports a multi-provider AI stack (Gemini, OpenAI, Claude, Grok, OpenRouter, Ollama, WebLLM, ONNX Runtime Web, Transformers.js), four AI execution modes (Hybrid / Cloud / Local / Eco), real-time collaboration with E2E encryption, a Plot Board v2 with swimlane/canvas/timeline modes, character/world management, manuscript export, voice dictation, and a 19-locale i18n layer. -**Native desktop strategy is changing (ADR-0021, 2026-08-20) — read before touching desktop/native code.** CEF is retired from the target architecture. Current direction: React/PWA stays the web product → Tauri 2 is **transitional only** (itself retired once Qt reaches Stable) → an authoritative Rust Core (`crates/`, an independent Cargo workspace from `src-tauri/`) → Qt 6/Qt Quick as the primary native product → GPUI admitted later, behind a strict gate. Full plan: `docs/native/ROADMAP-QT-GPUI-DESKTOP.md`; decision record: `docs/adr/0021-qt-gpui-native-desktop-strategy.md`. Extraction has started: `crates/worldscript-project` (renderer-neutral project schema/validation/migration, headless — no GUI deps) is wired to one real Tauri command (`worldscript_project_validate` in `src-tauri/src/commands/project_core.rs`) via a cross-workspace Cargo path dependency, and the first typed DesktopPlatform caller observes its bounded verdict on desktop loads without changing the existing TS authority. The envelope is synthesized and partial; unknown TS-only fields are not validated. Priority order for what gets extracted next: `docs/native/CORE-MIGRATION-LEDGER.md`. +**Native desktop strategy is changing (ADR-0021, 2026-08-20) — read before touching desktop/native code.** CEF is retired from the target architecture. Current direction: React/PWA stays the web product → Tauri 2 is **transitional only** (itself retired once Qt reaches Stable) → an authoritative Rust Core (`crates/`, an independent Cargo workspace from `src-tauri/`) → Qt 6/Qt Quick as the primary native product → GPUI admitted later, behind a strict gate. Full plan: `docs/native/ROADMAP-QT-GPUI-DESKTOP.md`, amended by the binding `docs/native/DESKTOP-MIGRATION-ROADMAP-REV3.md` (gates G1.5/G2.5, Wave 2.5); decision record: `docs/adr/0021-qt-gpui-native-desktop-strategy.md`. Extraction has started: `crates/worldscript-project` (renderer-neutral project schema/validation/migration, headless — no GUI deps) is wired to one real Tauri command (`worldscript_project_validate` in `src-tauri/src/commands/project_core.rs`) via a cross-workspace Cargo path dependency, and the first typed DesktopPlatform caller observes its bounded verdict on desktop loads without changing the existing TS authority. The envelope is synthesized and partial; unknown TS-only fields are not validated. Priority order for what gets extracted next: `docs/native/CORE-MIGRATION-LEDGER.md`. --- diff --git a/CLAUDE.md b/CLAUDE.md index aa420ca0a..0c7fc4294 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -101,7 +101,7 @@ WorldScript Studio is an offline-first PWA — a React 19 SPA with Google Gemini ### Native desktop strategy (ADR-0021) — read before touching desktop/native code -CEF (Chromium Embedded Framework) is **retired from the target architecture**, not deferred (2026-08-20). Current direction, decided in `docs/adr/0021-qt-gpui-native-desktop-strategy.md` (supersedes ADR-0019/0020): React/PWA stays the first-class web product → **Tauri 2 is transitional only** and is itself retired once Qt reaches Stable (not a permanent third runtime) → an authoritative **Rust Core** (`crates/`, independent Cargo workspace from `src-tauri/Cargo.toml` — see below) → **Qt 6/Qt Quick (QML)** as the only current native production target ("Hardened Edition"). **GPUI** remains a separately gated exploration, not a numbered execution commitment; see `docs/native/GPUI-EXPLORATIONS.md`. The Qt-first roadmap has 22 execution entries (Wave 0–20 plus Wave 4.5): `docs/native/ROADMAP-QT-GPUI-DESKTOP.md`. If you find CEF referenced as a *future* target anywhere in the repo, that's stale history (see `docs/historical/cef/README.md`) — flag it. +CEF (Chromium Embedded Framework) is **retired from the target architecture**, not deferred (2026-08-20). Current direction, decided in `docs/adr/0021-qt-gpui-native-desktop-strategy.md` (supersedes ADR-0019/0020): React/PWA stays the first-class web product → **Tauri 2 is transitional only** and is itself retired once Qt reaches Stable (not a permanent third runtime) → an authoritative **Rust Core** (`crates/`, independent Cargo workspace from `src-tauri/Cargo.toml` — see below) → **Qt 6/Qt Quick (QML)** as the only current native production target ("Hardened Edition"). **GPUI** remains a separately gated exploration, not a numbered execution commitment; see `docs/native/GPUI-EXPLORATIONS.md`. The Qt-first roadmap has 22 execution entries (Wave 0–20 plus Wave 4.5): `docs/native/ROADMAP-QT-GPUI-DESKTOP.md`, amended by the binding `docs/native/DESKTOP-MIGRATION-ROADMAP-REV3.md` (gates G1.5/G2.5, Wave 2.5). If you find CEF referenced as a *future* target anywhere in the repo, that's stale history (see `docs/historical/cef/README.md`) — flag it. **Rust Core extraction is in progress.** `crates/worldscript-project` (Wave 2 first slice) is a renderer-neutral project schema/validation/migration/plain-I/O crate mirroring `types.ts`'s `StoryProject`/`Character`/`World`/`StorySection` as plain `Vec` (not Redux's `EntityState` union — the typed boundary adapter normalizes both array and EntityState inputs for the bounded shadow caller). Proven headless (`cargo test` + `wsproj` CLI, zero GUI/Tauri deps) and wired to one real Tauri command, `worldscript_project_validate` (`src-tauri/src/commands/project_core.rs`), via a **path dependency across two independent Cargo workspaces** — `crates/worldscript-project` is a member of the `crates/` workspace, `src-tauri/Cargo.toml` depends on it by path without unifying the workspaces; this compiles and links cleanly. The first DesktopPlatform caller observes a synthesized, partial envelope during desktop project loads; it does not switch authority and unknown TS-only fields are not validated. `docs/native/CORE-MIGRATION-LEDGER.md` sets the capability-priority order for what's extracted next (logger/diagnostics and task-orchestration expansion before IDB storage/encryption or `features/project/` domain logic). CI: new `core-rust` job mirrors `rust-tauri`'s fmt/check/clippy/test but needs no GTK/WebKit apt-get steps (zero GUI deps); both are path-scoped via the `changes` job and legitimately show `skipping` on PRs that don't touch their respective directories. diff --git a/docs/adr/0021-qt-gpui-native-desktop-strategy.md b/docs/adr/0021-qt-gpui-native-desktop-strategy.md index 8479828a4..2ad1a872a 100644 --- a/docs/adr/0021-qt-gpui-native-desktop-strategy.md +++ b/docs/adr/0021-qt-gpui-native-desktop-strategy.md @@ -5,7 +5,8 @@ companion PR #407; see `docs/native/ROADMAP-QT-GPUI-DESKTOP.md` §15 Wave 0). **Supersedes:** [[0019-cef-desktop-runtime-strategy]], [[0020-cef-binding-choice-thin-cpp-host]]. This ADR does not add any Qt, GPUI, or Rust-Core code — it locks direction only, exactly as ADR-0019 and ADR-0020 did for CEF. Full strategy, waves, and gates: -`docs/native/ROADMAP-QT-GPUI-DESKTOP.md`. +`docs/native/ROADMAP-QT-GPUI-DESKTOP.md`, amended by the binding +`docs/native/DESKTOP-MIGRATION-ROADMAP-REV3.md` (gates G1.5/G2.5, Wave 2.5). ## Context diff --git a/docs/native/QT-EARLY-KILLER-GATES.md b/docs/native/QT-EARLY-KILLER-GATES.md index e547903d3..34b8c1421 100644 --- a/docs/native/QT-EARLY-KILLER-GATES.md +++ b/docs/native/QT-EARLY-KILLER-GATES.md @@ -83,7 +83,7 @@ implementation. | Contract/threat boundary | Qt-facing contract inventory identifies every IPC/FFI crossing, data owner, permission, cancellation path, and failure mode; no domain truth moves into QML/C++. | The bridge requires renderer-specific domain rules, arbitrary command execution, or a new broad unsafe/FFI architecture. | | Lifecycle and Core bridge | A disposable Qt 6/QML probe proves the minimum viability path: process/window creation, QML load, one typed Rust call, one Rust event to QML, one bounded async/cancellation path, clean shutdown, and three repeated launch/close cycles. It records the bridge/lifetime/threading model; it does not build the reusable Wave 5 harness. | Lifetime/threading behavior is nondeterministic, cancellation cannot be bounded, or the Core cannot remain GUI-independent. | | Accessibility and input | A real Qt Quick control sample exposes a stable accessibility tree and proves keyboard/focus, accessible errors, high contrast, scalable text, RTL/BiDi, and IME smoke behavior on a supported Linux environment. | Required semantics are not observable, custom controls require inaccessible workarounds, or IME/BiDi breaks core writing input. | -| Linux graphics differential | A disposable Qt Quick probe records scene-graph/graphics backend, GPU/driver, Wayland/X11/session context and multi-GPU selection where present; executes Alt-Tab/minimize/restore and a representative memory trend; and preserves the same semantic fixture/workload used for PWA/Tauri comparison. | Catastrophic renderer/lifecycle behavior, unexplained unbounded resource growth, unusable input latency, or a required workaround that violates the Qt Quick/Rust-Core target architecture. | +| Linux graphics differential | A disposable Qt Quick probe records scene-graph/graphics backend, GPU/driver, Wayland/X11/session context and multi-GPU selection where present; executes Alt-Tab/minimize/restore and a representative memory trend; and preserves the same semantic fixture/workload used for PWA/Tauri comparison. | Catastrophic renderer/lifecycle behavior, unbounded resource growth (explained or not — an explanation does not convert an unbounded Qt leak into a pass), unusable input latency, or a required workaround that violates the Qt Quick/Rust-Core target architecture. | | Packaging and updater trust | A packaged hello-world/Core roundtrip starts from a clean environment; signed update metadata, artifact identity, downgrade policy, rollback, and tamper rejection are exercised with ephemeral, runtime-injected throwaway test credentials only. The credentials never live in source, artifacts, logs, or production secret stores. | Artifact identity or rollback cannot be trusted, updates accept tampered input, test credentials persist outside the test process, or the packaging model requires bypassing repository signing policy. | | Crash and recovery | An intentional harness crash produces actionable diagnostics and symbols for project-owned code; restart/recovery behavior is deterministic and does not corrupt test data. | Diagnostics require weakening sandbox/process isolation, recovery loses acknowledged data, or failures cannot be reproduced from packaged evidence. | | Security and permissions | Runtime review covers sandbox/process boundaries, typed IPC/FFI allowlists and versioning, filesystem/network permissions, secret injection/storage/zeroization, updater privileges and signing trust, temporary-file permissions/cleanup, and the approved Core encryption/identity-binding invariants; negative tests prove denied operations stay denied. | A capability needs arbitrary native execution, broad filesystem/network access, plaintext secret exposure, persistent test credentials, or weakened encryption/identity binding. | diff --git a/docs/native/ROADMAP-QT-GPUI-DESKTOP.md b/docs/native/ROADMAP-QT-GPUI-DESKTOP.md index 7b2377d16..d9ccff654 100644 --- a/docs/native/ROADMAP-QT-GPUI-DESKTOP.md +++ b/docs/native/ROADMAP-QT-GPUI-DESKTOP.md @@ -17,6 +17,7 @@ until Qt admission and cutover gates are satisfied, **and itself retired once Qt **Architecture rule:** no domain/business logic duplication across renderers **Revision:** 2 — early killer-gate sequencing and GPUI exploration boundary **Revision date:** 2026-08-21 +**Amended by Revision 3:** [`DESKTOP-MIGRATION-ROADMAP-REV3.md`](DESKTOP-MIGRATION-ROADMAP-REV3.md) is a binding amendment to this roadmap — it adds gates G1.5 and G2.5 and Wave 2.5, and must be read together with this document, not as an optional standalone note. ## Document status and corrections applied at adoption (Wave 0, 2026-08-20) diff --git a/scripts/check-native-readiness.mjs b/scripts/check-native-readiness.mjs index b41a47406..e0c86c30c 100644 --- a/scripts/check-native-readiness.mjs +++ b/scripts/check-native-readiness.mjs @@ -42,6 +42,7 @@ const rev3Wave25 = section( '### Wave 2.5 — Desktop differential baseline & #332 classification — NEW', '### Wave 3 — Storage correctness and R-15 design', ); +const gateMatrix = section(earlyGates, '## Gate matrix', '## Minimum evidence package'); const earlyOrder = [ 'Lifecycle and bridge spike', 'Accessibility and input feasibility', @@ -187,9 +188,14 @@ requireText( 'Wave 4.5 must consume early-lane evidence instead of silently duplicating it.', ); requireText( - earlyGates, + gateMatrix, 'Linux graphics differential', - 'Qt qualification must include the Revision-3 Linux graphics differential lane.', + 'The Gate matrix must include a Linux graphics differential row, not just an early-lane mention.', +); +requireText( + gateMatrix, + /unbounded resource growth \(explained or not/, + 'The Linux graphics differential kill condition must reject unbounded growth whether or not it is explained.', ); requireText( waveFive, From d6a0e3897aef1fe858b63ef110ca41754f8c6a2b Mon Sep 17 00:00:00 2001 From: qnbs <155236708+qnbs@users.noreply.github.com> Date: Wed, 26 Aug 2026 03:21:10 +0200 Subject: [PATCH 6/6] fix: resolve Revision-3 authority/scenario ambiguity, fix MD018 nits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Root-clustered remediation for the second fresh review epoch on the reconciled head (four CodeRabbit findings, plus two low-cost markdownlint nits folded into the same consolidated push): - Execution-entry count ambiguity: CLAUDE.md said "the Qt-first roadmap has 22 execution entries... amended by the binding [Revision 3]" in one sentence, which could be misread as 22 being the post-amendment total. Split into two sentences: 22 is the base roadmap; Revision 3 adds a 23rd (Wave 2.5) plus gates G1.5/G2.5. - Revision-3 authority-status contradiction: DESKTOP-MIGRATION-ROADMAP-REV3.md's own Status line said "Proposed binding refinement," while ARCHITECTURE-REUSE-OWNERSHIP.md and this same reconciliation's own new note in ROADMAP-QT-GPUI-DESKTOP.md both already call it the normative, binding amendment. Changed the Status line to "Adopted binding refinement" to match -- confirmed no other "Proposed" status language exists elsewhere in the file. - Representative-hardware exception not tied to the Decision rule: the early "Linux graphics differential" lane says "where available" / "where the #332 lineage applies" without connecting those conditionals to this same document's own Decision rule, which requires a written rationale and architecture decision for any non-applicable gate rather than a silent skip. Both conditional mentions now explicitly reference that requirement. - Dual-use GOLDEN-DESKTOP-LIFECYCLE-332 identifier: the early lane called its own scoped-down probe "the reduced GOLDEN-DESKTOP-LIFECYCLE-332 differential" using the same bare identifier as the full fourteen-step scenario defined in REV3.md §5.5, so a partial graphics-only run could be conflated with the canonical full scenario used for later Qt qualification. Renamed the early-lane subset to GOLDEN-DESKTOP-LIFECYCLE-332-QF-D with an explicit, self-contained definition (Alt-Tab/minimize-restore cycles plus a bounded memory-trend sample) and an explicit "must never be substituted for the full scenario" statement; added a reciprocal cross-reference at the full scenario's own description pointing back to REV3.md §5.5 as the authoritative definition. - Markdownlint MD018 (leading #NNN read as an ATX heading): wrapped the issue reference in backticks at all 5 flagged prose locations across TAURI-TRANSITIONAL-MAINTENANCE.md, PWA-AUDIT.md, ARCHITECTURE-REUSE-OWNERSHIP.md (x2), and DESKTOP-MIGRATION-ROADMAP-REV3.md. Swept the same six files for any other line-leading #NNN pattern the linter didn't flag; found three more, all inside fenced ```text code blocks where MD018 does not apply -- left unchanged, confirmed as correct exemptions, not missed instances. All findings validated against the exact current file content before fixing. Local validation: lint, 4-checker typecheck, ci:prepush, native-readiness check all clean. --- CLAUDE.md | 2 +- docs/PWA-AUDIT.md | 2 +- .../ARCHITECTURE-REUSE-OWNERSHIP.md | 4 +-- docs/native/DESKTOP-MIGRATION-ROADMAP-REV3.md | 4 +-- docs/native/QT-EARLY-KILLER-GATES.md | 25 +++++++++++++------ docs/native/TAURI-TRANSITIONAL-MAINTENANCE.md | 2 +- 6 files changed, 24 insertions(+), 15 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 0c7fc4294..2ca8ec16d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -101,7 +101,7 @@ WorldScript Studio is an offline-first PWA — a React 19 SPA with Google Gemini ### Native desktop strategy (ADR-0021) — read before touching desktop/native code -CEF (Chromium Embedded Framework) is **retired from the target architecture**, not deferred (2026-08-20). Current direction, decided in `docs/adr/0021-qt-gpui-native-desktop-strategy.md` (supersedes ADR-0019/0020): React/PWA stays the first-class web product → **Tauri 2 is transitional only** and is itself retired once Qt reaches Stable (not a permanent third runtime) → an authoritative **Rust Core** (`crates/`, independent Cargo workspace from `src-tauri/Cargo.toml` — see below) → **Qt 6/Qt Quick (QML)** as the only current native production target ("Hardened Edition"). **GPUI** remains a separately gated exploration, not a numbered execution commitment; see `docs/native/GPUI-EXPLORATIONS.md`. The Qt-first roadmap has 22 execution entries (Wave 0–20 plus Wave 4.5): `docs/native/ROADMAP-QT-GPUI-DESKTOP.md`, amended by the binding `docs/native/DESKTOP-MIGRATION-ROADMAP-REV3.md` (gates G1.5/G2.5, Wave 2.5). If you find CEF referenced as a *future* target anywhere in the repo, that's stale history (see `docs/historical/cef/README.md`) — flag it. +CEF (Chromium Embedded Framework) is **retired from the target architecture**, not deferred (2026-08-20). Current direction, decided in `docs/adr/0021-qt-gpui-native-desktop-strategy.md` (supersedes ADR-0019/0020): React/PWA stays the first-class web product → **Tauri 2 is transitional only** and is itself retired once Qt reaches Stable (not a permanent third runtime) → an authoritative **Rust Core** (`crates/`, independent Cargo workspace from `src-tauri/Cargo.toml` — see below) → **Qt 6/Qt Quick (QML)** as the only current native production target ("Hardened Edition"). **GPUI** remains a separately gated exploration, not a numbered execution commitment; see `docs/native/GPUI-EXPLORATIONS.md`. The base Qt-first roadmap has 22 execution entries (Wave 0–20 plus Wave 4.5): `docs/native/ROADMAP-QT-GPUI-DESKTOP.md`. The binding `docs/native/DESKTOP-MIGRATION-ROADMAP-REV3.md` amendment adds a 23rd (Wave 2.5) plus gates G1.5/G2.5. If you find CEF referenced as a *future* target anywhere in the repo, that's stale history (see `docs/historical/cef/README.md`) — flag it. **Rust Core extraction is in progress.** `crates/worldscript-project` (Wave 2 first slice) is a renderer-neutral project schema/validation/migration/plain-I/O crate mirroring `types.ts`'s `StoryProject`/`Character`/`World`/`StorySection` as plain `Vec` (not Redux's `EntityState` union — the typed boundary adapter normalizes both array and EntityState inputs for the bounded shadow caller). Proven headless (`cargo test` + `wsproj` CLI, zero GUI/Tauri deps) and wired to one real Tauri command, `worldscript_project_validate` (`src-tauri/src/commands/project_core.rs`), via a **path dependency across two independent Cargo workspaces** — `crates/worldscript-project` is a member of the `crates/` workspace, `src-tauri/Cargo.toml` depends on it by path without unifying the workspaces; this compiles and links cleanly. The first DesktopPlatform caller observes a synthesized, partial envelope during desktop project loads; it does not switch authority and unknown TS-only fields are not validated. `docs/native/CORE-MIGRATION-LEDGER.md` sets the capability-priority order for what's extracted next (logger/diagnostics and task-orchestration expansion before IDB storage/encryption or `features/project/` domain logic). CI: new `core-rust` job mirrors `rust-tauri`'s fmt/check/clippy/test but needs no GTK/WebKit apt-get steps (zero GUI deps); both are path-scoped via the `changes` job and legitimately show `skipping` on PRs that don't touch their respective directories. diff --git a/docs/PWA-AUDIT.md b/docs/PWA-AUDIT.md index 6c6b47fbb..e04b1f115 100644 --- a/docs/PWA-AUDIT.md +++ b/docs/PWA-AUDIT.md @@ -64,7 +64,7 @@ No new PWA enhancement may silently create a second project, schema, crypto, mig ## 3. PWA workstream / issue graph -#478 is the umbrella. Child work should remain traceable to the following dependency model: +`#478` is the umbrella. Child work should remain traceable to the following dependency model: ```text #478 PWA excellence diff --git a/docs/architecture/ARCHITECTURE-REUSE-OWNERSHIP.md b/docs/architecture/ARCHITECTURE-REUSE-OWNERSHIP.md index e2a12f3c5..703173532 100644 --- a/docs/architecture/ARCHITECTURE-REUSE-OWNERSHIP.md +++ b/docs/architecture/ARCHITECTURE-REUSE-OWNERSHIP.md @@ -260,7 +260,7 @@ Existing logging, diagnostic-model, sink, and redaction facilities remain the se ### 8.1 #489 — capability/admission facade -#489 is an aggregation and explanation layer, not a second set of low-level probes. +`#489` is an aggregation and explanation layer, not a second set of low-level probes. It should compose existing subsystem probes and expose normalized runtime facts. Workflow-specific admission remains in the owning subsystem. @@ -384,7 +384,7 @@ Qt must consume the resulting authority, not create another schema. Keep #445 as the integration/closure issue for native renderer-neutral encryption, durability, recovery, migration admission, and record identity. -#357/#359/#360/#361 remain detailed requirements and provenance. Do not create Qt-private or new Tauri-private crypto/storage authority. +`#357`/`#359`/`#360`/`#361` remain detailed requirements and provenance. Do not create Qt-private or new Tauri-private crypto/storage authority. ### 9.3 Tasks diff --git a/docs/native/DESKTOP-MIGRATION-ROADMAP-REV3.md b/docs/native/DESKTOP-MIGRATION-ROADMAP-REV3.md index b68fc57ca..9693708ee 100644 --- a/docs/native/DESKTOP-MIGRATION-ROADMAP-REV3.md +++ b/docs/native/DESKTOP-MIGRATION-ROADMAP-REV3.md @@ -1,6 +1,6 @@ # WorldScript Studio — Desktop Migration Roadmap Revision 3 -**Status:** Proposed binding refinement to ADR-0021 and `ROADMAP-QT-GPUI-DESKTOP.md` +**Status:** Adopted binding refinement to ADR-0021 and `ROADMAP-QT-GPUI-DESKTOP.md` **Repository:** `qnbs/WorldScript-Studio` **Date:** 2026-08-24 **Primary native target:** Qt 6 + Qt Quick/QML @@ -899,7 +899,7 @@ Qt succeeds only if it demonstrates: - target Windows/macOS evidence as applicable; - no reintroduction of renderer-specific domain authority. -#332-derived scenarios become positive proof that the migration escaped the old renderer failure class without carrying portable defects forward. +`#332`-derived scenarios become positive proof that the migration escaped the old renderer failure class without carrying portable defects forward. --- diff --git a/docs/native/QT-EARLY-KILLER-GATES.md b/docs/native/QT-EARLY-KILLER-GATES.md index 34b8c1421..2a653120d 100644 --- a/docs/native/QT-EARLY-KILLER-GATES.md +++ b/docs/native/QT-EARLY-KILLER-GATES.md @@ -50,7 +50,9 @@ Core probe, the following disposable lanes may run in parallel with Waves 3 and available, record Qt Quick graphics backend, GPU/driver selection, multi-GPU behavior where exposed, Alt-Tab/minimize/restore behavior, and a bounded memory trend. Compare against the same semantic PWA/Tauri workload without turning renderer-specific implementation details into shared - product architecture. + product architecture. If representative hardware is genuinely unavailable for a given run, this + lane follows the Decision rule above — a written rationale and architecture decision, never a + silent skip. These lanes retain their own evidence and maturity labels; they are not checked off as G2/G2.5/G3/G4 production gates. A failed lane stops Qt investment and returns the program to architecture review. @@ -123,9 +125,14 @@ repeat the meaningful checks in CI: backend checks on the supported Linux desktop used for development. 2. **Linux CI:** clean build, repeated lifecycle, headless display/compositor smoke, security negative tests, crash artifact collection, and deterministic result assertions. -3. **Representative Linux graphics target:** where the #332 lineage applies, use real - Linux/Wayland/NVIDIA hardware to capture backend/GPU/driver identity and the reduced - `GOLDEN-DESKTOP-LIFECYCLE-332` differential before broad Qt UI investment. +3. **Representative Linux graphics target:** where the `#332` lineage applies, use real + Linux/Wayland/NVIDIA hardware to capture backend/GPU/driver identity and run + `GOLDEN-DESKTOP-LIFECYCLE-332-QF-D` — a named, fixed subset of the full + `GOLDEN-DESKTOP-LIFECYCLE-332` scenario (§5.5 of `DESKTOP-MIGRATION-ROADMAP-REV3.md`) scoped to + the Alt-Tab and minimize/restore cycles plus a bounded memory-trend sample, not an ad hoc + reduction — before broad Qt UI investment. The full fourteen-step scenario, including the + 30-minute and longer soak runs, remains the mandatory input for later Qt qualification described + below; a `-QF-D` run must never be substituted for it. 4. **Clean packaged runtime:** install/launch/update/rollback/tamper tests against the actual artifact layout rather than the build tree. 5. **Later platform evidence:** Windows UI Automation, macOS VoiceOver/accessibility APIs, and @@ -170,10 +177,12 @@ runtime versions, last lifecycle events, task summaries, heartbeat age, persiste memory buckets. It must contain no project text, prompts, tokens, keys, private paths, or raw encryption material. -The `GOLDEN-DESKTOP-LIFECYCLE-332` scenario is mandatory input for later Qt qualification: edit a -representative project, cross an autosave boundary, background for 5 seconds, return and edit -immediately, repeat 20 times, then exercise 30-second/two-minute background intervals, Writer Studio, -Settings, minimize/restore, relaunch, and normal close. The required outcome is no UI disappearance, +The `GOLDEN-DESKTOP-LIFECYCLE-332` scenario (full definition: §5.5 of +`DESKTOP-MIGRATION-ROADMAP-REV3.md` — not the `-QF-D` early-lane subset above) is mandatory input +for later Qt qualification: edit a representative project, cross an autosave boundary, background +for 5 seconds, return and edit immediately, repeat 20 times, then exercise 30-second/two-minute +background intervals, Writer Studio, Settings, minimize/restore, relaunch, and normal close. The +required outcome is no UI disappearance, unbounded hang, lost acknowledged edit, orphan process, corruption, or force-kill requirement; first click, caret, and keyboard input must remain responsive. **For Qt admission, memory/resource growth must be bounded under the admitted fixture and duration; an explanation of unbounded growth is diff --git a/docs/native/TAURI-TRANSITIONAL-MAINTENANCE.md b/docs/native/TAURI-TRANSITIONAL-MAINTENANCE.md index ac3044af1..24bd19466 100644 --- a/docs/native/TAURI-TRANSITIONAL-MAINTENANCE.md +++ b/docs/native/TAURI-TRANSITIONAL-MAINTENANCE.md @@ -211,7 +211,7 @@ At that point record `RUNTIME-LIMITED` or `ENVIRONMENT-LIMITED`, retain only a s ## Qt handoff rule -#332 is a **Qt migration acceptance baseline**, not a requirement to perfect Tauri before Qt begins. +`#332` is a **Qt migration acceptance baseline**, not a requirement to perfect Tauri before Qt begins. The Qt target in ADR-0021 is Qt Quick/QML with Rust Core; Qt WebEngine is not the principal UI architecture. Therefore a WebKitGTK-specific failure is not automatically portable to Qt, while app/Core/lifecycle invariants are.