Transcript envelope and lifecycle¶
Part of the termverify.transcript/v1 protocol.
Common envelope¶
Every line is an object with these required members:
| Member | Type | Meaning |
|---|---|---|
protocol |
string | Exactly termverify.transcript/v1. |
run_id |
string | Caller-supplied stable identifier for this run. |
seq |
non-negative integer | Zero-based, contiguous line sequence. |
id |
string | Stable unique record identifier within run_id. |
kind |
string | Record type from the v1 set below. |
payload |
object | Data defined by kind; no omitted required members. |
run_id and id use lowercase ASCII letters, digits, ., _, and -; they
must be non-empty and generated by the caller or deterministic harness, never
from adapter ambient randomness. The recommended identifiers are the stable
run-<fixture-or-request-name> and record-<zero-padded-seq> forms. A reader
rejects a repeated id, a changed run_id, or a non-contiguous seq.
An extension member starts with x- and has no meaning to a generic v1 reader.
All other members are reserved. A producer must not use an extension to change
the meaning of a required v1 member.
Record ordering and lifecycle¶
A valid transcript contains exactly this lifecycle shape:
run.startedatseq: 0;capability.resultrecords in configuration-table order until all requested constraints are applied, the first is unsupported, or an adapter failure terminates negotiation;- if initialization completes, exactly one initial readiness observation;
- zero or more single-flight input epochs;
- exactly one terminal record:
run.finished,run.failed, orrun.unsupported.
An adapter failure may terminate negotiation before any capability result or
after any applied prefix. The transcript then contains only run.started, that
prefix, and run.failed. A subject that exits or an adapter that fails after
negotiation but before readiness may likewise terminate without an initial
observation. run.unsupported remains negotiation-only and has no body records.
Execution epochs and causality¶
The initial readiness observation is the first semantic body record after all seven capability results. Zero or more startup diagnostics may precede it, but no input may. Its position, rather than an additional payload member, declares that initialization completed and the subject is ready for input.
After readiness, v1 is single-flight. Each epoch contains:
- exactly one input record;
- zero or more diagnostics caused while handling that input;
- exactly one observation that closes the epoch at deterministic quiescence, unless a terminal record closes it first.
The closing observation is the complete normalized evidence available at
quiescence, not an output chunk. Transcript order supplies causality, so another
input before that observation is invalid. Observations and diagnostics while
idle are invalid: diagnostics do not create hidden epochs. input.stop is the
final accepted input. Its drain epoch may contain diagnostics and an optional
final observation, followed by run.finished or run.failed; no later input is
valid.
A terminal record may also occur while idle when the subject exits naturally or the adapter fails. This ordered model intentionally excludes unsolicited body events in v1. General asynchronous work requires a future explicit polling, draining, or correlation contract rather than wall-clock quiet-window polling.
No record follows a terminal record. Input records are ordered by dispatch;
observations are ordered by the point at which the adapter captured them; event
arrays inside an observation are ordered by application emission. Records never
claim wall-clock ordering: all timing uses the configured manual clock in
integer milliseconds. A capture failure is represented by run.failed, not by
silently dropping a record.
run.started has a payload.config object containing the requested
deterministic constraints. capability.result reports each constraint's actual
outcome before the adapter accepts the first input. input.* records describe
the requested user action; observation records contain the resulting
structured evidence; diagnostic carries non-oracle information such as a
normalized process warning.
run.started.payload is closed except for x- extensions and requires exactly
config plus subject. subject is a versioned replay selector with this v1
shape:
{
"format": "termverify.replay-subject/v1",
"application": {"id": "example.app", "version": "1", "build": "build-1"},
"fixture": {"id": "basic", "version": "1"},
"adapter": {"id": "example.direct", "version": "1"},
"normalizer": {"id": "example.identity", "version": "1"},
"state_schema": {"id": "example.state", "version": "1"}
}
Every selector value uses the same lowercase ASCII identifier grammar as
run_id. Application identity separates its application version from the exact
build selector. Fixture identity selects the registered invocation without
embedding a raw command line or environment. Adapter, normalizer, and state
schema identities bind the interpretation needed for replay. An optional
platform object has exactly normalized os and architecture selectors.
Volatile hostname, account, absolute path, raw argv, and environment details
are not replay selectors and are forbidden as generic subject members. Every
subject and nested selector is closed except for uninterpreted x- extensions.
Terminal record payloads are:
| Kind | Required payload members |
|---|---|
run.finished |
exit: {"kind": "code", "value": integer} or {"kind": "signal", "value": non-empty string} |
run.failed |
error: {"code": non-empty string, "message": string, "details"?: JSON value} |
run.unsupported |
constraint, code, message, and optional details; constraint and code are non-empty strings |
Every defined record payload and nested generic protocol object is closed to
its listed members plus uninterpreted x- extensions. In particular,
capability.result permits effective, tier, and delivery only with
applied and reason only with unsupported; delivery additionally
requires the delivered tier. Application-defined JSON values such as
observation state, event data, diagnostic details, and error details
remain open semantic values rather than generic protocol objects. The
delivery.env object (present only with the spawn-env channel; see
enforcement tiers) is a
value map of delivered environment-variable names, not a generic protocol
object: its member names are exact variable names with no x- extension
semantics.
message is diagnostic only. Consumers use stable code values for behavior;
v1 reserves adapter-start-failed, adapter-runtime-failed,
constraint-unsupported, and constraint-not-enforced.