# Local creator workflow

Start the local stack with `npm run dev`, then run `npm run operator:init`. Read the generated key file locally and enter it at [the creator desk](http://127.0.0.1:4000/creator). The command prints its file location, never its contents. Demo player cookies and world server keys do not grant operator access. The operator cookie is host-only, HttpOnly, SameSite Strict, scoped to `/operator`, and expires after two hours. This is a local development operator workflow, not production authentication.

Import the included ninth cosmetic:

```powershell
npm run creator:import -- --root contributions/aurora-lab
```

The CLI resolves the selected directory and each manifest, GLB and source path to a real path. Absolute paths, traversal, remote resources and symlink/junction escapes are rejected. The JSON manifest names one self-contained GLB and its source/rights files; ZIPs and arbitrary scripts are not executed. `contributions/aurora-lab/source.mjs` is the original procedural source; running it locally regenerates the checked-in Aurora wings GLB. Its manifest and licence describe the CC0 permission.

In the desk, select the draft, edit and save metadata, and choose **Validate draft**. Inspect the report and rotate the animated reference-body preview. Test idle, walk, run, jump, fall, land, wave and dance. **Publish approved version** makes the product available immediately in the central catalogue and world displays. A player can try it on locally, complete its clearly labelled simulated checkout, equip it, and return to a world. Another explorer sees the canonical revision on the next appearance refresh, normally within five seconds.

Import a new manifest/GLB with the same product ID and a new version to revise a product. Published assets are immutable. Existing ownership, equipped outfits and pending orders keep their pinned revision. Delisting stops new acquisition while owned revisions remain loadable; it is not emergency withdrawal. Metadata edits to a validated draft require validation again.

## Processing and storage

States are `draft → processing → validated → published`, with structured `failed` reports and retryable worker failures. Submitted manifest, source files and GLB are immutable private inputs. Each attempt captures its own metadata. A single child worker runs outside HTTP requests and SQLite write transactions, with a 20-second deadline, 192 MiB V8 heap limit, 16 MiB GLB limit and 64 KiB output-report limit. The heap cap is not an operating-system RSS cap or a complete security sandbox. The worker receives no operator/world keys, has external fetching disabled, and never writes the database.

The official Khronos glTF Validator checks structure. glTF Transform inspects and deduplicates equal accessors/materials. Platform checks enforce the fixed rig, coverage, bounded animations, geometry and material profile. Reports count decoded RGBA8 texture memory including mips, even though this first composition profile rejects textured products. Optimized output is re-read and revalidated; rig, animation samples, geometry and attribution fingerprints must be preserved. Automated tests also compare posed vertices before and after processing using all eight reference clips.

Central checks the worker output hash and completes a content-addressed public asset write before the short publication transaction references it. Files and SQLite do not share an atomic transaction: an interrupted publication may leave an unreferenced complete file, which is safe to retain for later audited cleanup. Never delete `assets/versions` merely because a product is delisted. Back up the database, its adjacent `.creator` directory and `assets/versions` together. Startup marks interrupted processing attempts failed and retryable; it preserves drafts and publication records.

Validation and browser evidence: `npm test`, `npm run test:e2e`, `reports/content-validation.json`, `reports/creator-workflow.json`, and `reports/migration.json`. Tests run against a separate disposable database under `.runtime`; they do not reset the local demo database.
