Workspace update streams API
Release capture accepts drafts: [{id,generation}] alongside selection_ids. Only
saved, changed SQL-well drafts belonging to the capturing project administrator
are eligible. Original inputs deduplicate by selection; each draft adds a derived
result. Ten payloads, 16 MiB each, 64 MiB/package and existing storage limits apply.
The source must still match the draft base; concurrent draft/selection changes fail.
Drafts remain unchanged. Empty drafts field is omitted from command fingerprints to
preserve pre-upgrade retries. This capability also uses existing release automation
write scope; it is not exposed through desktop sessions.
Results have authority ophiolite:derived, key project:selection, revision payload
SHA-256 and profile edited-wells/1. Parent reference/hash and draft ID/generation
are in the manifest. Original authority and current retention/sharing policy still
govern recipient reads. Inputs preserve original SQL scalar encodings and unmapped
columns; results explicitly report projection losses. Neither capture nor approval
writes upstream. Units/CRS remain declared, missing values remain distinct from zero.
Browser-only POST /api/subscriptions/{list,create,offer-preview,offer,subscribe,get, configure,unsubscribe} requires Origin/CSRF/session and current project membership.
Create/offer require administration; only the stream creator may offer versions.
Create takes name, kind (dataset/collection), release_id and command_id for retry.
Offer takes stream_id, release_id and generation, and refuses changed result identity
or mapped context. Duplicate snapshot offers are idempotent. offer-preview reports
excluded_subscribers; a nonzero count requires acknowledge_exclusions on offer.
Subscribe is idempotent per account/stream, defaults review and approved_only=false. Configure takes generation, mode(review/follow/pin), approved_only. Unsubscribe requires current generation and no saved edits. Streams are explicit frozen package sequences, not live collection membership. Limits: 100 streams/project, 100 versions per stream, 100 subscriptions/account/project, one edited result with at most 200 wells per version. Other retained package inputs remain inspectable through Releases. Current head denial produces no fallback content; existing subscription lists show a generic unavailable row. No subscriber operation resolves an upstream principal.
Consumer operations: fetch(version; 0 means head), acknowledge(version, manifest_digest), apply(version,manifest_digest,generation,automatic=false), edit-save(version,generation,patches), discard(generation). Fetch verifies retained hashes but does not record receipt. Acknowledge records a client-reported delivery; apply requires that receipt and records a durable Workspace cursor. Applied does not prove external application consumption. Same-version apply retry preserves edits; older versions cannot roll back the cursor. Automatic apply requires latest version, follow mode and no saved patches. A generation mismatch returns 409 for reload.
Get returns head state, delivery versions and the applied working table. Saved patches use Connector typed validation against retained bytes, never upstream reads. They are private, keyed by the applied version, and survive backup/restart. Discard explicitly loses those edits. Saving a working copy does not publish it onward. Every fetch/ack/apply checks snapshot or approved eligibility; approved_only requires approved. Request-review pauses delivery until approval; withdrawal stops it. Current sharing policy and project grants still apply. Inaccessible applied content is hidden, including its saved values. Recipient metadata may remain visible without payloads.
Activity profile workspace-subscription/1 contains IDs, state and version only. Delivery is client-reported, application is a server-recorded Workspace cursor change. Offer/receipt/apply events commit with their state changes. Existing exports cannot be recalled. UI polling is 15 seconds while visible; unsaved edits block automatic apply and navigation warns. Expired sessions leave local edits in the open component; a browser reload after ignoring the warning loses unsaved edits. Save before leaving.
