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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 10 additions & 55 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,70 +7,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

- **Desktop publishing:** Require the complete Linux, Windows and macOS ARM installer, signature, SBOM and notices matrix; cryptographically verify updater payloads; stage releases as drafts and revalidate the uploaded inventory immediately before publication (PR #1202; issue #1201).
<!-- release-candidate: v1.29.3 -->

- **Local AI storage:** Namespace the Transformers.js browser cache as WorldScript-owned and restrict cache counts and clearing to that bucket. Preserve WebLLM, vendor-global, legacy, and unrelated caches; localize the retained-cache and first-use download behavior, and report partial deletion failures instead of announcing a successful clear (PR #1200; issue #526; successor to #1148).
## [1.29.3] — 2026-11-08

- **Vercel retention:** Check the protected canonical Production URL with a team-scoped Vercel CLI request using one existing project automation-bypass secret; do not create or rotate secrets from a read-only run. Reject redirects and all responses except one HTTP 200, and document that the protected probe does not establish anonymous reachability (PR #1198; issue #627).
- **Storage safety and privacy:** Factory Reset and startup recovery now clear only exact WorldScript-owned browser keys, preserve ambiguous same-origin values, and retain the encryption salt until primary IndexedDB deletion succeeds. Incomplete database inventories and deletion failures stop the reset and are announced accessibly (#1196; #1125).

- **Storage reset:** Limit factory and startup cleanup to exact app-owned storage keys, disclose intentionally retained ambiguous same-origin browser values, and retain the IndexedDB encryption salt until primary deletion succeeds. Require a complete IndexedDB inventory before any destructive reset step so dynamic Local-First stores cannot be missed; announce failures through a pre-mounted localized status region (PR #1196; successor to #1147; issue #1125).
- **Local model cache ownership:** Transformers.js uses a dedicated WorldScript cache bucket; counts and clears are limited to that bucket, and partial clear failures are reported. WebLLM, vendor-global, legacy, and other unowned caches are intentionally preserved. A changed WebLLM model-library URL may require preparing the model online again before offline use (#1200; #526; #1191).

- **DOCX export:** Updated `docx` to 9.15.1 and its resolved `@types/node` dependency to 26.6.6; the existing export contract remains covered by focused tests (PR #1194; Dependabot source PR #1193).
- **DOCX export:** Updated the export library to 9.15.1 while retaining the existing export contract and regression coverage (#1194).

- **AI dependencies:** Updated the coordinated Vercel AI SDK family: `@ai-sdk/google` 4.0.109, `@ai-sdk/openai` 4.0.106, `@ai-sdk/react` 4.0.163, and `ai` 7.0.159. The lockfile keeps their provider, provider-utils, gateway, and MCP dependencies aligned; Redux Toolkit remains at 2.12.0 and WebLLM stays on its separate qualification path (PR #1189; Dependabot source PR #1184).
- **AI providers and runtime:** Updated the coordinated AI SDK provider packages and the curated WebLLM runtime. Redux Toolkit remains pinned to 2.12.0 while 2.13.0 is held for prototype-named entity-ID regressions (#1189; #1191; #1183).

- **Local AI runtime:** Updated the curated WebLLM runtime to 0.2.87, including its upstream model-configuration refresh. The supported model catalog and inference contract are unchanged. After an update that changes a versioned model-library URL, prepare each WebLLM model online before relying on it offline; unchanged model weights remain cached (PR #1191; Dependabot source PR #1190).
- **Security and dependencies:** Updated DOMPurify and compatible dependency floors, Tauri plugins, rustix, and the tested UUID/IndexedDB packages (#1145; #1149; #1179; #1181; #1182). Four npm and ten Rust advisories remain time-bounded accepted risks tracked in #1163 and #1164; this release does not claim they are fixed, and their current waivers expire 2026-11-30.

- **CI dependencies:** Upgrade the SHA-pinned `pnpm/setup` GitHub Action to v3.1.2 in the shared setup action and both policy workflows. Keep project Node selection with `actions/setup-node`, and preserve the trusted workflow's frozen, script-disabled install (PR #1188; Dependabot source PR #1160).
- **Desktop release integrity:** Release publishing now requires the complete Linux, Windows, and macOS Apple Silicon installer and updater matrix, verified updater signatures, three SBOMs and notices files, validated update metadata, and a verified uploaded asset inventory before the release is made public (#1202; #1201).

- **Developer tooling:** Updated Biome from 2.5.8 to 2.6.4 and aligned its configuration schema. Resolved the new component-factory findings and repo-wide lint diagnostics across test harnesses, retry timing, sorted entity pairs, Aurora cascade ordering, and DOM text reads; lowered the suppression ratchet by two removed directives (PR #1185; Dependabot source PR #1171).
- **Build and developer tooling:** Updated the pnpm/setup GitHub Action, Biome, React/Vite and related test tooling while keeping Node selection explicit and the trusted workflow install frozen and script-disabled (#1188; #1185; #1168).

- **Tauri dependencies:** Updated the locked Rust plugins `tauri-plugin-dialog` to 2.8.4, `tauri-plugin-updater` to 2.14.1, and `tauri-plugin-single-instance` to 2.5.5, with their resolved `rfd`, `base64`, and Windows target dependency changes (PR #1179; Dependabot source PR #1170).

- **Rust dependencies:** Updated the resolved `rustix` lock entry from 1.1.5 to 1.1.6, including the upstream fix for truncated macOS `SCM_RIGHTS` messages (PR #1181; Dependabot source PR #1169).

- **Dependencies:** Updated the test dependency `fake-indexeddb` to 6.2.7 and resolved `uuid` to 14.0.3 without narrowing its existing manifest range. Keep all resolved Redux Toolkit instances at 2.12.0 while 2.13.0 is held for prototype-named entity ID regressions (PR #1182; Dependabot source PR #1172).

- **CI operations:** Defined a five-merge/24-hour, Pages-degraded recovery contract for #1176. Exact-main quality, security, CodeQL, Production, and review gates remain required; Vercel retention and deletions stay on hold until the full push workflow succeeds (PR #1177).

- **Operations:** Made ordinary Vercel preview retention operator-agnostic across qualified local Claude Code CLI, Codex CLI, and future Cursor Cloud leases, with one maintainer-designated operator at a time. Cursor Cloud remains `NOT_ADMITTED` for deletions until the separate maintainer-approved capability gate in #1174; local credentials are never copied to Cloud. PRs open ready for review; SAFE-only and protection gates are unchanged (PR #1175).

- **Dependencies:** Bumped React 19.3.1, Vite 8.3.5, the dev-tooling group (Playwright, Storybook, Vitest
and others), 42 minor/patch packages including the AI SDK and the `@tauri-apps/*` plugins, and the
matching Rust `tauri-plugin-*` crates (`notification` 2.8.0, `shell` 2.6.0, `updater` ~2.14). Biome is
held at 2.5.8 until its 2.6 rule changes are fixed in a separate change, and `@reduxjs/toolkit` is held at 2.12.0 because 2.13.0 changes how entity adapters treat prototype-named IDs (two existing tests fail); the language selector trigger now includes the visible language name in its accessible name (WCAG 2.5.3, newly reported by axe-core 4.14); `tauri-plugin-deep-link` moves to 2.6.3, which builds against `rust-ini` 0.21.3 (PR #1168; Dependabot source PRs
#1104, #1154, #1155, #1157, #1165).

- **Rust dependencies:** Bumped `tokio` to 1.54.1 in the Tauri backend and `unicode-normalization` to
0.1.26 in the Rust Core workspace; lockfile-only, MSRV pins unchanged (PR #1167; Dependabot source PRs
#1153, #1156).

- **CI dependencies:** Moved all four `github/codeql-action` references (`init`, `autobuild`, `analyze`,
`upload-sarif`) to v4.39.1 together, and bumped `Swatinem/rust-cache` and `docker/login-action`
(v4.7.0) in the workflows (PR #1166; Dependabot source PRs #1158, #1159).

- **Security (dependencies):** Updated the shipped HTML sanitizer to DOMPurify 3.4.17, including
jsPDF's optional copy, for XHTML/SVG, shadow-root template and detached-hook fixes. Raised the
LHCI-only `ip-address` dependency floor to 10.7.4 for GHSA-rxp7-6hxx-x8q5 (PR #1145, #1132).
Focused sanitizer regressions and a transitive lockfile floor assertion cover both fixes.

- **Security (dependencies):** Raised bounded floors for patched `undici`, `body-parser`,
`fast-uri`, `qs` and `serialize-javascript`; upgraded only Zod 4 and moved Lighthouse's
supported Puppeteer 25.x line to a release using Zod 4. Removed the OSV ignore for the
withdrawn `sprintf-js` advisory while retaining the package. Also raised `follow-redirects`
(>=1.16.2) and `joi` (>=18.3.1). Four advisories have no compatible fix and are accepted as
time-bounded vulnerabilities, not fixes: `deepmerge` (`GHSA-gcqx-w48m-w2h4`), Zod 3 via the
Codecov plugin (`GHSA-mrhx-c7xc-m3w5`), `glob` (`GHSA-3g3m-2fjr-6pw4`) and `minimatch`
(`GHSA-g3hv-75wg-m249`). Each ignore expires on 2026-11-30 at the latest; every affected copy is
development tooling and none is reachable from the production dependency graph in the lockfile.
A test pins the affected copies, their parent packages and that absence, and fails when they
change. Tracked in [#1146](https://github.com/qnbs/WorldScript-Studio/issues/1146) and
[#1163](https://github.com/qnbs/WorldScript-Studio/issues/1163) (PR #1149).

- **Post-release v1.29.2 truth sync:** removed the release-candidate markers from README.md and
CHANGELOG.md now that the `v1.29.2` tag and GitHub Release are published, and recorded the real
release evidence in AUDIT.md, TODO.md and `docs/RELEASE-V1.29.2-EVIDENCE.md` (see `## [1.29.2]`
below and #1139).
- **Storage-format scope:** This maintenance release adds no project storage format or encrypted-at-rest migration; the separately gated R-15 work remains outside v1.29.3 (#926).

## [1.29.2] — 2026-10-22

Expand Down
56 changes: 56 additions & 0 deletions docs/RELEASE-V1.29.3-EVIDENCE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# v1.29.3 release evidence

**Status: PREPARATION IN PROGRESS — NOT RELEASED.** This record starts with every release
state pending. The latest published release remains [v1.29.2](https://github.com/qnbs/WorldScript-Studio/releases/tag/v1.29.2).
No v1.29.3 tag, GitHub Release, or GHCR publication has been created.

## State ladder

| State | Required evidence | Status |
| ----------- | --------------------------------------------------------------------------------------------------------- | ------- |
| `PREPARED` | Signed release-preparation PR merged; version metadata synchronized; resulting-main gates complete | PENDING |
| `CANDIDATE` | Exact protected main SHA frozen after push CI/CD, CodeQL, Pages, Production, and retention proof | PENDING |
| `QUALIFIED` | Fresh exact-candidate OSV, 3-OS packaging, asset inventory, updater and data-preservation checks terminal | PENDING |
| `TAGGED` | Signed annotated `v1.29.3` tag verified against the qualified SHA | PENDING |
| `PUBLISHED` | Exact-tag Tauri and GHCR workflows publish the complete signed asset set | PENDING |
| `VERIFIED` | Release, updater manifest/signatures, checksums, GHCR, and post-release truth sync read back | PENDING |

## Baseline checks already completed

These checks apply only to the pre-preparation main commit below. They do not qualify the
versioned release candidate.

- Protected main before the preparation PR: `5295b163864f75af3576fe1b884ba1b5437e4114`.
- Push CI/CD [run 42492667174](https://github.com/qnbs/WorldScript-Studio/actions/runs/42492667174) and CodeQL [run 42492667095](https://github.com/qnbs/WorldScript-Studio/actions/runs/42492667095): SUCCESS on that exact SHA.
- GitHub Pages job 128774564802 succeeded for that SHA. Artifact 13623275352 has digest `sha256:15a251c42090226a274cb7f24bdad39bc56c5d864591a67154c5966ac8b6ea34`; public URL returned HTTP 200, which alone does not prove byte-for-byte freshness.
- Vercel Production `dpl_F5YZ8gT3qD2T2pgEXU4XVEUGNywC` was READY on that SHA with the three canonical aliases. SAFE-only retention receipt: [#627](https://github.com/qnbs/WorldScript-Studio/issues/627#issuecomment-6723593626), one obsolete preview removed, `SAFE=1`, `UNKNOWN=0`, all 54 protected records preserved, terminal postproof passed.
- Stored updater key preflight on protected main: [Tauri workflow run 42496866632](https://github.com/qnbs/WorldScript-Studio/actions/runs/42496866632), job 128780977915 SUCCESS. It signed a throwaway payload and verified it against the current embedded public key; tampered data and a wrong key were rejected. This is key-availability evidence on the pre-preparation SHA, not candidate build evidence.
- The current `src-tauri/tauri.conf.json` updater public key matches the configuration at tag `v1.29.2`. The published v1.29.2 `latest.json` contains `linux-x86_64`, `windows-x86_64`, and `darwin-aarch64`, each with a signature. The v1.29.2 cryptographic readback remains documented in [its evidence record](RELEASE-V1.29.2-EVIDENCE.md).
- The same workflow dispatch also runs unpublishing Linux, Windows, and macOS ARM bundle qualification on the pre-preparation SHA; those three jobs were still running when this record was drafted. Their eventual result does not replace the exact-candidate dispatch required after preparation.

## Candidate and release gates

For each gate, append the exact SHA, workflow/job URL, artifact name and digest, result, and any
limitation only after a terminal result exists. A result from another SHA does not qualify the
candidate.

| Gate | Evidence to record | Status |
| -------------------------------------- | ---------------------------------------------------------------------------------------------------------- | ------- |
| Resulting-main CI/CD and CodeQL | Exact push run IDs and SHA | PENDING |
| Pages publication and public freshness | Deploy job, artifact/build SHA, independent site content check | PENDING |
| Vercel Production and retention | READY deployment, three aliases, authenticated HTTP probe, exact-main SAFE/PROTECTED/UNKNOWN and postproof | PENDING |
| Exact-ref OSV | Fresh scan of `pnpm-lock.yaml`, `src-tauri/Cargo.lock`, and `crates/Cargo.lock` | PENDING |
| 3-OS candidate builds | Exact-SHA workflow dispatch; Linux, Windows, and macOS Apple Silicon | PENDING |
| Packaged runtime and data preservation | Document each executed packaged-state protocol and platform limitation | PENDING |
| Complete release assets | All expected installers, signatures, three SBOMs, three notices, and `latest.json` | PENDING |
| Signed annotated tag | Tag-object and target-commit verification | PENDING |
| Tauri/GHCR publication | Exact-tag runs, complete assets, manifest and immutable image digest | PENDING |

## Scope and known limitations

- Proposed version: `1.29.3`, pending completion of all release gates. No v1.30/R-15 storage-authority change is included.
- Supported desktop targets: Linux x86_64, Windows x64, and macOS Apple Silicon. Intel macOS is not claimed.
- Apple Developer ID/notarization and Windows Authenticode are not implemented in this release lane.
- RTK 2.13.0 remains held; the shipped dependency graph must retain the reviewed 2.12.0 resolution.
- Four npm and ten Rust advisories remain accepted risks tracked by #1163 and #1164, with current waiver expiry 2026-11-30. A successful scan with those waivers is not evidence that the vulnerabilities are fixed.
- Legacy, WebLLM, vendor-global, and unowned browser caches remain preserved unless positively proven to be WorldScript-owned.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "worldscript-studio",
"private": true,
"version": "1.29.2",
"version": "1.29.3",
Comment thread
sourcery-ai[bot] marked this conversation as resolved.
Resolved
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
"description": "WorldScript Studio — offline-first, AI-powered creative writing application.",
"author": "QNBS",
"keywords": [
Expand Down Expand Up @@ -82,7 +82,7 @@
"graphs:refresh": "node scripts/graphs-cli.mjs refresh",
"build": "vite build",
"build:edge": "node scripts/build-edge.mjs",
"prebuild:pages": "node scripts/copy-duckdb-assets.mjs && node scripts/copy-third-party-licenses.mjs",
"prebuild:pages": "node scripts/sync-sw-version.mjs && node scripts/copy-duckdb-assets.mjs && node scripts/copy-third-party-licenses.mjs",
"build:pages": "vite build",
"build:turbo": "turbo run build",
"preview": "vite preview",
Expand Down
2 changes: 1 addition & 1 deletion public/sw.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// ============================================================

// QNBS-v3: version bump auto-synced from package.json by scripts/sync-sw-version.mjs — every CACHE_STATIC/CACHE_DYNAMIC name changes too, so this alone invalidates all prior caches on next activate.
const APP_VERSION = '1.29.2';
const APP_VERSION = '1.29.3';
const CACHE_STATIC = `worldscript-static-v${APP_VERSION}`;
const CACHE_DYNAMIC = `worldscript-dynamic-v${APP_VERSION}`;
const CACHE_IMAGES = `worldscript-images-v${APP_VERSION}`;
Expand Down
2 changes: 1 addition & 1 deletion scripts/runtime-asset-steps.d.mts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const RUNTIME_ASSET_SCRIPTS: readonly string[];
export const EDGE_PREP_SCRIPTS: readonly string[];

export interface EdgeBuildSpawnResult {
status: number | null;
Expand Down
19 changes: 11 additions & 8 deletions scripts/runtime-asset-steps.mjs
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
import { join } from 'node:path';

/**
* Build steps that produce gitignored, self-hosted runtime assets from pinned dependencies. npm runs
* them through `prebuild`, but `build:edge` (Vercel) calls `vite build` directly and skips that
* hook — without them production served index.html (SPA rewrite) for /duckdb/*.wasm and
* /licenses/*.txt.
* Single list for both paths: package.json `prebuild` and scripts/build-edge.mjs.
* Build preparation shared by npm hooks and direct edge builds. `build:edge` calls Vite directly
* and skips `prebuild`, so it must synchronize the service-worker cache version as well as create
* the gitignored runtime assets before Vite copies public files.
* Single list for package.json build hooks and scripts/build-edge.mjs.
*/
export const RUNTIME_ASSET_SCRIPTS = ['copy-duckdb-assets.mjs', 'copy-third-party-licenses.mjs'];
export const EDGE_PREP_SCRIPTS = [
'sync-sw-version.mjs',
'copy-duckdb-assets.mjs',
'copy-third-party-licenses.mjs',
];

/**
* The edge build: every runtime asset step, then `vite build`. A failed step (nonzero status or a
* The edge build: every preparation step, then `vite build`. A failed step (nonzero status or a
* signal) stops before vite and returns a nonzero exit code. `spawn` is node:child_process
* `spawnSync`, injected so tests can run the sequence without building.
*/
export function runEdgeBuild({ spawn, scriptsDir, env, log = console.error }) {
for (const script of RUNTIME_ASSET_SCRIPTS) {
for (const script of EDGE_PREP_SCRIPTS) {
const step = spawn(process.execPath, [join(scriptsDir, script)], { stdio: 'inherit' });
if (step.status !== 0) {
log(`[build-edge] ${script} failed`);
Expand Down
2 changes: 1 addition & 1 deletion src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "worldscript-studio"
version = "1.29.2"
version = "1.29.3"
description = "AI-powered creative writing and world-building application"
authors = ["QNBS"]
license = "MIT"
Expand Down
Loading
Loading