# UX Workspace Studio

## Temporary walkthrough checkpoint

The normal workspace saves preferences. After it finishes loading, choose **Prepare temporary walkthrough**, then **Confirm temporary walkthrough**. Presets, appearance controls, undo/reset, JSON import and every Studio table control now use page memory: appearance uses `applyAppearance`, and the table is recreated with `persistState:false`.

Repeated temporary resets keep the original in-memory form checkpoint. **Restore saved workspace** reads the latest saved appearance/table values, including changes made in another tab, without writing an old snapshot over them. It clears the empty-state rehearsal and restores the in-page form/JSON preview. Reload exits temporary mode and resumes the ordinary saved workspace. Denied/quota storage stays page-only and cannot survive reload.

The preservation assertion starts after normal initialization and explicit confirmation. Existing safe startup migration, expiry/corruption handling and the storage write probe still occur before that checkpoint. A scene URL never starts or resets a walkthrough automatically.

Rendered regression (restricted loopback preview already running):

```sh
STUDIO_BASE_URL=http://127.0.0.1:4173 node lab/workspace-studio/tests/recording.mjs
```

Provide `PLAYWRIGHT_MODULE` when Playwright is installed outside the repository and `STUDIO_EVIDENCE_DIR` for a private report directory. This checks post-checkpoint write absence, exact valid envelope preservation, repeated reset, newer cross-tab state, interrupted reload and denied/quota recovery with synthetic settings. Tests and private evidence are excluded from the public artifact.

## Computer tutorial and scene tools

- `/lab/workspace-studio/recording.html`: original nine-cut result-first script, with numbered SAY / SHOW / EXPECTED instructions, speaker notes and real tutorial/scene links. `recording-script.md` provides the complete no-JavaScript text; `recording-plan.mjs` is its content source.
- Main demo: Before, Operations comparison, Rejected import and Reset rehearsal operate only inside the confirmed temporary session. A hash or chapter link navigates only. The comparison uses actual authored CSS and DataTables, not images or a backend fixture claim.
- Shared recording tools supply optional presentation (Escape exits), copyable safe snippets, a generated script/draft transcript and local validation of a future video URL. They do not upload, track, persist the URL, load a thumbnail/iframe or claim a video exists. Studio's visible Prepare/Confirm/Restore controls remain the single lifecycle controller.
- `tests/story.mjs` verifies actual scene states/nonmutation, chapter anchors, presentation focus and media/network boundaries against the restricted loopback preview. Private final keyframes and the matching script/shot index are reviewed separately; intermediate captures are not a release artifact.
- Tutorial checkpoint 9 explains the actual nonpersisting table/appearance path, current-store restore, bounded in-page checkpoint, stale file revisions and empty-mode isolation, with alternatives, pros/cons, pitfalls and runnable verification. Existing checkpoint anchors 1–8 remain stable. The owned-surface inventory explicitly covers recording resources, shared shells/architecture and the standalone Gateway/native boundaries.

## Empty-state recovery and stale file reads

The ordinary **Show empty state** rehearsal uses a separate `persistState:false` table initialized from the current DataTables state. Clearing rows therefore cannot save a clamped page over the real table. Restoring dealer data reads the latest persistent table handle, including another tab's newer choices; it does not write the old snapshot back. Appearance keeps its ordinary mode unless the full temporary walkthrough is active. Denied/quota mode restores the current page-only table checkpoint.

File imports carry session and selection revisions. A file read that finishes after reset/restore, empty-mode transition, a newer file selection or navigation is ignored before import. This invalidates stale work; no background clipboard read or remote upload is involved.

`tests/empty-state.mjs` verifies exact saved envelopes through interrupted empty reload, latest cross-tab recovery, delayed-file nonmutation, denied/quota fallback and actual control rectangles at 320px with large monospace text, airy spacing and side navigation. Data-table cells may scroll in their container; ordinary sorting controls reflow to one column.

## Optional resources and recoverable loading

The main app does not import recorder code, plan or style until **Show recording tools** is selected. Optional failure cannot prevent the nine appearance controls or dealer table from booting. A live status explains loading/failure, an eight-second timeout bounds waiting, and at most three explicit user-triggered attempts are allowed. Retry uses a bounded same-origin module suffix after a failed module-map entry. No automatic polling occurs. A static guide and complete script remain available without JavaScript. The guide intentionally loads its recording resources because that is its purpose.

`tests/loading.mjs` verifies no eager optional requests, plan failure/nonmutation, one successful retry/no duplicate panel, bounded exhaustion, an actual eight-second timeout, DataTables' fallback with 72 readable synthetic rows, reload recovery and no-JavaScript script access.

Measured local response-body inventory (Node.js 24.19.0, Chromium 151.0.7922.34, a cold context at 1920×1080, no-store restricted preview, synthetic rows): the eager pre-change route made 16 requests totaling 280,945 body bytes, including 208,969 JavaScript bytes. After isolation it made 13 requests totaling 263,844 body bytes, including 192,260 JavaScript bytes. These measurements precede the final presentation typography and compare the same shared foundation; optional content is fetched later only on intent. They count response bodies without assuming compression, headers or transport overhead. They do not establish faster field loading, production throughput or monetary savings. Final integrated artifact bytes are recorded separately by the integration writer.

Official basis: [MDN dynamic import](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import), [web.dev code splitting](https://web.dev/articles/reduce-javascript-payloads-with-code-splitting), and [W3C status messages](https://www.w3.org/WAI/WCAG22/Understanding/status-messages.html), checked October 25, 2026.

Every update package requires an executor and a distinct independent critic with at least **five substantive critique → fix → re-verification cycles**, as required by the repository contributor guidance. Builder checks alone do not satisfy that policy.

Prepared in the existing Zyel Lab repository; no deployment performed. This is the Studio builder's implementation and execution evidence. Independent reviewer outcomes belong to the integration release record and must not be inferred from the builder's checks.

## Run locally

From the integrated repository root, use the shared restricted static server:

```powershell
node lab/tools/serve.mjs .
```

Open `http://127.0.0.1:4173/lab/workspace-studio/`. This server blocks backend/config paths instead of exposing the repository's PHP application. Do not open the database-backed root page, expose a repository-wide PHP server beyond loopback, or copy private environment files into a preview. The E2E runner also provides its own restricted loopback server when only this builder worktree is available.

The page depends on the integration writer's `lab/shared/{runtime,storage,data,table}.mjs`, `shell.css` and vendored DataTables files. Do not copy or commit another builder's shared files. No production database, API or account is used here.

## Walkthrough

1. Apply Editorial, Operations or Focus first. Adjust any of the nine allowlisted settings.
2. Navigate the form and modal using the keyboard. Form values never enter storage.
3. Sort region descending then dealer name ascending. Search/filter, choose a page length, hide a column and move columns using buttons or header dragging.
4. Reload: appearance and this table's arrangement return. Other routes keep their own table state.
5. Inspect/download JSON. Import a valid changed document, then try an unknown font or future version: invalid imports explain rejection and retain current state.
6. Use the empty preview and restore data. Reset appearance and table preferences separately.

## Contract and boundaries

- Appearance store: shared `zyel.lab:v2:global:appearance`, exact token enums, 30-day lifetime. Appearance follows across the new Lab demos; Celebration internals remain outside this contract.
- Table store: shared scope `table:workspace-studio:workspace-studio-dealers`, separate from GIS and portal tables.
- Transfer: `format=zyel.workspace.preferences`, `schemaVersion=2`, `scope=workspace-studio`; exact known keys only. Known v1 documents lacking focus migrate to standard focus. Unknown versions/scopes fail closed.
- Maximum import is 16 KiB UTF-8. Search terms and each filter are at most 100 characters; no control characters, imported regex flags, arbitrary CSS URLs/templates or unknown columns/fields are accepted. Search text may contain markup-looking characters but remains inert text; it is never inserted as HTML. An extra HTML/template field is rejected. Page lengths are 5, 10, 25, 50 or 100. At least one column must stay visible. Named sort columns retain meaning after reorder.
- Validation precedes mutation. Table API operations run before appearance; failure triggers best-effort rollback and a visible recovery instruction if rollback also fails. Browser APIs do not provide a transaction across storage and table DOM.
- Shared storage handles malformed/expired state, known-key migration, denied access, quota fallback and same-origin storage events. Storage failure becomes visible memory-only operation.
- Only appearance and table configuration are persisted. Use synthetic search terms; no credentials, records, form content or conversations are saved. Storage is browser/device-local, not account sync.
- 72 synthetic dealer records and synthetic revenue. No client references, certifications, high-traffic or people-leadership claims.
- No approved isolated WordPress environment was available. No WordPress plugin or embed was installed or tested. WordPress support/accessibility evidence remains a gap.

## Verified dependency/runtime versions

- Node.js 24.19.0 (local tests and CPU benchmark).
- Chromium 151.0.7922.34 (local browser evidence).
- DataTables 3.1.4 and ColReorder 3.1.2 (shared vendored files, locally exercised through the shared adapter). The integration shared dependency record owns upstream URLs, hashes and license notices.
- Browser-native ES modules, JSON/TextEncoder, dialog and CSS custom properties. No runtime dependency added by Studio itself.
- Authored form boundaries use a separate `--st-control-line` token from decorative panel dividers. The browser suite measures input/select/JSON-textarea/DataTables search and length boundaries against both inside and surrounding backgrounds in all three themes, requiring at least 3:1. Text samples require at least 4.5:1; this targeted check does not claim a full accessibility audit.

## Tests actually run

```powershell
node --test lab/workspace-studio/tests/model.test.mjs
node --check lab/workspace-studio/studio.mjs
node lab/workspace-studio/tests/benchmark.mjs
node lab/workspace-studio/tests/browser.mjs
```

The E2E runner requires the development `playwright` package and installed Chromium, opens the shared restricted loopback static server on an ephemeral port, and closes both afterward. It refuses source-only routes, case/backslash variants and non-GET/HEAD methods. If Playwright is outside the worktree, set `PLAYWRIGHT_MODULE` to its existing module URL; set `PLAYWRIGHT_BROWSERS_PATH` only if its browser cache is elsewhere. No new installation or account is required in the prepared executor. `STUDIO_EVIDENCE_DIR` selects a private evidence directory; otherwise the runner writes under the OS temporary directory, preserving historical evidence in this route. The selected Windows executor required a sandbox exception for Chromium to reach its own loopback server; this is not a live-site test.

Historical baseline: model 9 tests passed; `evidence/browser-results.json` records the original eight-checkpoint browser run with its timestamp/version. Those files do not prove the later recording package. The updated browser runner now checks nine tutorial checkpoints. Expanded lifecycle/story/empty-state regressions and independent five-cycle outcomes belong to the integration review evidence, with exact revisions and separate screenshots; they must not be inferred from the historical baseline.

Pure-model tests also exercise malformed/oversized JSON, UTF-8 byte size, all shipped presets, prototype-looking keys, future/wrong-scope envelopes, known v1 migration, invalid directions, duplicates, all-hidden columns and bounded undo snapshots.

## Measured result and limitations

`tests/benchmark.mjs` warms 1,000 parses, then measures seven batches of 10,000 parses of the same 565-byte synthetic preference document. On Windows x64, Node 24.19.0, AMD Ryzen 9 9900X3D, median batch mean was 0.00541865 ms/parse; min/max batch means were 0.00524954/0.00676986 ms. The script reports its own environment for reproduction.

This is CPU-only local contract-validation evidence. It excludes browser rendering, DataTables, storage, network and I/O. It is not a traffic or production-load result. Do not extrapolate it into user-perceived latency or client-scale claims.

## Deployment, rollback and maintenance

Publication requires integration review and whatever exact approval the owner has authorized. Stage this additive route with the matching shared assets, test migration and browser failure states, and preserve all existing Celebration/admin/CRM work. Open any PR as draft.

Keep the previous reviewed static file set. Rollback restores that prior release and Lab links; never reset the owner's dirty checkout or delete broad route trees. Preserve the preference-version compatibility boundary. After an authorized deployment, read back the actual Studio/tutorial URLs and smoke-test Celebration before calling anything live.

Add known migrations and tests when changing schema. Recheck DataTables/ColReorder compatibility, exact pins and vendor license notices on upgrades. Keep the owned-surface inventory accurate and revisit storage, modal, responsive, reduced-motion and forced-color behavior. A prepared demo is technical evidence, not complete job or procurement qualification.

## Official references

- https://datatables.net/ref/core/option/stateSave
- https://datatables.net/ref/core/option/stateDuration
- https://datatables.net/ref/core/option/stateSaveCallback
- https://datatables.net/manual/extensions/colreorder/
- https://datatables.net/manual/components/vue/
- https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API
- https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion
- https://www.w3.org/WAI/WCAG22/Understanding/non-text-contrast.html

Checked October 25, 2026. The tutorial is presented under Chason Arthur's author name without asserting he personally wrote every generated line or operated this prototype at an unproven scale.
