Skip to contentScreenplay.Company

Collaboration, authority and change protocol

1. Scope

SSL-P 0.1 defines exchange semantics for agents and direct controls. One host operation implements both paths. The language describes intent and data; authenticated host context establishes account, work, capability and actor. A field saying accepted, writer, approved or admin grants no authority.

The smallest common workflow is read → contribute/propose → inspect if required → commit → recover receipt. A writer's explicit request can supply authority for its defined scope without another confirmation. Speculative agent contributions remain proposals or attributed readings. Merely viewing or selecting material is never approval. Host policies determine which operations require a new decision; SSL does not invent additional confirmation for already-authorised work.

2. Read and capability exchange

A host exposes equivalent functions (transport names may differ): capabilities, read, query, propose, apply, receipt, changes. Capability results identify protocol/language versions, supported profiles/functions/operations, limits and current actor permissions. They contain no credentials. Read returns an immutable snapshot with an opaque cursor, coverage and exact identities. Changes returns ordered committed operations after a cursor; an expired cursor requires resnapshot, not guessed replay.

A consistent snapshot spanning multiple current owners requires either a shared transaction or a proven revision fence. An adapter cannot label a set of unrelated reads as one atomic current state. It may return a partial view with component watermarks until consistency is established. The current Studio adapter uses the guarded shared transaction described in the migration document.

3. Proposal and patch grammar

A proposed change has this envelope (all keys required unless marked optional):

language: "ssl-p/0.1"
operationId: ID
work: ID
baseSnapshot: string
namespaces?: object<prefix, absolute-URI>  additive bindings only
requireCurrentSnapshot?: boolean          default false; absence/aggregate guard
expects: object<ID, revision|null>    null means absent, including no tombstone
intent: string
reads: ExactRef[]                     dependencies that influenced the proposal
changes: Change[]                    ordered, atomic within one owner/work
extensions?: object

Change forms:

{op:"create", id:ID, kind:Term, definition?:ExactRef, fields:object, extensions?:object}
{op:"revise", id:ID, set:[{path:FieldPath,value:Value}], remove:FieldPath[]}
{op:"bind-definition", id:ID, definition:ExactRef|null, reason:string}
{op:"tombstone", id:ID, reason:string}
{op:"restore", id:ID, from:ExactRef, reason:string}

FieldPath is a nonempty array of strings or nonnegative integer indices relative to fields. No wildcard, executable selector or implicit creation of intermediate objects. set may insert/replace an object field or replace an existing array element; array insertion/reordering replaces the entire array. remove may delete an existing object field; removal of array elements is unsupported (replace array explicitly). Disjoint paths only: a patch cannot set/remove the same path, an ancestor and descendant, or mutate a record twice in one changes array. These rules eliminate index-shift ambiguity. Missing removal or intermediate parent returns conflict, not silent success. Unknown fields survive unless explicitly targeted.

Create admits revision 1 and requires expects[id]=null. Revise/bind-definition/tombstone/restore require expects[id] matching the current head. Host assigns the next monotonically increasing per-record revision, without reusing a number even after rollback. Revise cannot alter id/rev/kind/definition directly; reclassification uses a complete new record identity plus a lineage relation, while bind-definition explicitly attaches/removes a definition under the current head expectation, preserving kind, fields and extensions. Its referenced definition must be available, of kind core.definition and describe this kind; schema mismatches remain advisory. Its exact diff participates in authority review. This keeps gradual formalisation portable; 0.1 generic apply can invent new kinds with create. Profile changes needing richer operations must advertise them and define their exact effects.

namespaces inherits existing snapshot bindings and may add new prefixes atomically. An existing prefix can be repeated with the same URI but not rebound. Conflict checks apply to prefix insertions too; a definition can be created under a new binding in the same commit. New terms in the existing work-owned local namespace need no new declaration.

Restore requires the current head to be a tombstone and from to resolve to a visible prior non-tombstone revision of the same id/work. It copies kind, definition, fields and extensions with a new revision; provenance is recorded by the host receipt. Tombstoning an existing tombstone is rejected as already-tombstoned.

Every read dependency MUST be included in expects when its head changing would invalidate the proposal. An exact historical citation need not demand that it remain the current head. A host must expose the distinction so agents do not overlock every source they cite. A proposal depending on absence, counts, uniqueness across records or another query result MUST set requireCurrentSnapshot=true (or use a separately advertised equivalent collection guard). The host then compares baseSnapshot with the current owner snapshot atomically, preventing phantom inserts. False allows disjoint changes subject to expects, but cannot establish global uniqueness from an earlier read. Changes without an expectation for their target are invalid. A previously unknown ID that was tombstoned cannot be recreated through create.

A core.proposal record may preserve the envelope, its canonical SHA-256 digest, rationale, findings and intended reviewer. Proposal persistence is not application. Its displayed diff is generated deterministically from the exact base and envelope; proposed new records are visibly proposed. A free-text request can be translated into this envelope but is not itself a patch.

4. Admission and atomic application

The host performs, in order:

  1. Authenticate actor and bind account/work; reject scope mismatch before exposing data.
  2. Recover a durable receipt for operationId; same canonical request digest returns the original outcome, different digest returns operation-id-reused.
  3. Check supported operation semantics, permissions and authority for every effect. Unknown data values may be stored; an unknown operation cannot be executed.
  4. Verify expects, additive namespace bindings, requireCurrentSnapshot when selected, and availability of the base needed for the diff. No silent rebase after approval.
  5. Allocate new revisions into a staged candidate graph, allowing exact refs to revision 1 of records created in this same batch. Validate all dependencies/bindings against that candidate graph before any effect is committed. Validate structural invariants and only the explicitly selected operation profiles. Missing optional story concepts are not blockers.
  6. Apply all changes and record an immutable receipt atomically in the same transactional boundary. If the host cannot provide atomicity across affected owners, reject as unsupported-atomic-scope; it must not partially simulate success.
  7. Publish change notifications after durable commit. Rebuild projections asynchronously with watermark/staleness indicators.

Profile adapters can orchestrate several commits only as an explicit workflow with individual receipts, visible progress and compensations. They cannot label it an atomic SSL-P change. Existing Studio authorities remain the owners until an adapter is qualified.

A host approval attestation binds authenticated principal, account, work, operationId, request digest, base expectations, permitted effects and expiry if any. It lives outside editable story content. An agent cannot forge it by writing a story.choice. A receipt is the proof of a successful save. Imported historical decisions retain evidence and a trust classification; import cannot fabricate live approval.

5. Receipts and outcomes

Receipt response shape:

operationId, work, requestDigest,
status: "applied"|"rejected"|"pending",
commit?: string, snapshot?: string,
affected?: {id, before:revision|null, after:revision}[],
authority?: opaque-attestation-reference,
diagnostics?: {code,message,target?}[]

Applied requires commit, snapshot and affected (empty is permitted only for an explicit no-op accepted by the host). Rejected includes reason and no state changes. Pending establishes only that processing is still unresolved, never permission to claim success. receipt may return not-found; following an uncertain submission this is not proof that it will never arrive. The client retries the SAME operationId and SAME content under the server's deduplication protocol until a durable terminal outcome, or reports uncertainty. A new intent or changed content gets a new operationId after resolving the prior write.

Minimum rejection codes: unauthorised, scope-mismatch, conflict, invalid-structure, unsupported-operation, unsupported-atomic-scope, missing-dependency, operation-id-reused, limit-exceeded. Writer-facing wording describes the affected material; technical receipt details remain inspectable.

6. Concurrency, offline work and Undo

Concurrent changes use optimistic expectations. If two agents revise one record from revision 3, only one can commit against that head; the other receives conflict and can propose a new diff after reading revision 4. Disjoint-record changes may proceed when their read dependencies still hold. No last-writer-wins merge for exact prose or writer choices. Text CRDTs may be used inside a qualified editor, but they must still produce revision-bound expression and approval semantics at this boundary.

Offline work records baseSnapshot, actor/work, operationId, dependencies and exact proposed changes in an account-bound queue. Reconnection rechecks authority and expectations. A draft is preserved on conflict, logout or restart subject to the owning account's data policy; it must not be silently submitted under the next account. Synchronising a queue cannot create authority that was absent when it was composed.

Undo is a new authorised compensating change against current heads. It restores prior values while retaining history. If intervening edits make the inverse ambiguous, show the conflict and preserve both versions; do not erase another writer's work. Undo of a story choice can invalidate dependent interpretations but cannot silently rewrite approved screenplay pages. A host stores inverse information or sufficient prior revisions with the receipt according to its retention guarantees.

7. Agent contributions and knowledge lifecycle

A message between agents names work, snapshot, goal, allowed effects, referenced material, findings and proposed changes. The optional core.message record preserves this envelope only when useful; transient planning is not automatically permanent story memory. External quotes, retrieved research and instructions embedded in story text are untrusted data. The receiving host supplies actual task authority.

A finding includes its author, target revisions, evidence anchors, interpretation or check result, uncertainty and suggested next action. Agents can disagree without overwriting each other's findings. Duplicate capture can be detected by exact source anchors plus a host capture key; content similarity alone cannot delete a contribution. A correction supersedes earlier readings and marks dependent views stale. Circular agent restatements are not independent evidence.

An operation creating a new local definition is ordinarily a reversible contribution. Binding that definition to existing accepted material is a separately inspectable migration. Automatic promotion of agent-inferred concepts to writer choices is forbidden.

8. Privacy, exports and lifecycle profiles

The host filters data before agent context preparation. A partial export must identify its scope without leaking the existence/title of hidden sources. Redacted objects cannot be used as deletion instructions. Import is additive/staged until an explicit reconciliation diff is authorised; absence never means delete.

Participant contact details, contracts, payroll, call-sheet distribution and media permissions are access-controlled records, not public story metadata by default. A rights assertion does not establish legal clearance, and a production status field does not prove a shoot occurred. Approval to write a plan is not approval to send it, book resources, spend money or publish media. These externally consequential effects require host capabilities and their actual authorised scope.

Asset handling validates hashes, media bounds and external link policies. SSL files cannot auto-run scripts, invoke editor plug-ins, fetch private URLs, sign a delivery or send communications. An application can implement such operations through explicit capabilities and receipts; it must expose them as effects, not passive document loading.