# WP04 asynchronous identity contracts

This document is the normative contract for the audited `workspace` package. Host work is represented only by returned `Effect` values; the workspace performs no I/O and keeps no second effect queue.

## Identity and terminal callbacks

- Document-less tabs never need discard confirmation and close immediately.
- A close confirmation is identified by the exact `(uri, request, prompted_revision)` triple. Duplicate attempts for that pending identity emit no duplicate prompt. Cancel clears it. Exact confirmed discard closes after same-revision save or reload terminal transitions; a newer document revision invalidates the confirmation, and a stale reply is ignored.
- Loads and watcher reloads carry request identity. A newer operation supersedes an older in-flight operation. A notification token is used only to deduplicate or supersede in-flight reloads; it does not order file states.
- A save is identified by `(uri, request, revision)`. It writes the text captured at that revision and uses the current `FileVersion` as the host compare-and-swap token. `FileVersion` is opaque and unordered, not a timestamp or advisory hint.
- For every load, reload, or save request, the first matching terminal callback wins exactly. Later callbacks for that consumed identity are ignored.

## Load freshness and authority

After the winning `Load` effect, the host must atomically read the latest text together with its `FileVersion` and return that exact snapshot. The exact callback response is authoritative even when its version token differs from the notification token that triggered the load. Tokens must never be compared for recency.

## Save, watcher, and failure semantics

Saves are single-flight. Matching save success installs the exact submitted text as the saved baseline and advances to the returned version. Cleanliness is determined by equality between current content and that baseline, never by revision equality: edits during a save remain dirty unless they restore exactly the submitted text.

All watcher observations deferred during an in-flight save are reconciled after its first terminal callback. They are not reduced to merely the newest observation. An unknown token or any token different from the reconciled known version forces stale/conflict handling; only an exactly known duplicate can be dismissed.

`SaveFailure::NotCommitted` guarantees that the attempted bytes were not committed, preserves the current document and content-relative dirty state, and may be retried when dirty or stale. `SaveFailure::OutcomeUnknown` retains the last known pre-save version but never advances it or claims the attempted commit; the tab remains unresolved until host reconciliation. A save conflict likewise cannot acknowledge the attempted revision.

Watcher reload failure preserves prior content and its existing dirty state, marks the tab stale, and leaves it editable. It does not strand retained content in `Failed` or manufacture dirty state.

## Snapshot, document, and view-state boundaries

`TabSnapshot` is an immutable detached value. `Document` fields are private, and every public array accessor returns a detached copy, so callers cannot mutate document state through an alias. All mutations pass through validated methods.

Per-URI view state is retained across close and reopen. It is cleared only when explicitly set to `None`.

## Current non-goals

WP04 does not provide a persistence host adapter, merge UI, or conflict-resolution algorithm. It makes no large-file throughput, latency, or memory-performance claim. Those limitations do not weaken the identity, atomic snapshot, or CAS rules above.

## Audited gates

The final audit passes **72 wasm**, **72 wasm-gc**, **73 JavaScript**, and **72 native** tests, plus all-target check, `moon info`, `moon fmt`, and `git diff --check`.
