From a9bb6955aa13852680ecfe7e329b313a2a48873c Mon Sep 17 00:00:00 2001 From: Somasundaram Ayyappan <1802828+somus@users.noreply.github.com> Date: Fri, 12 Jun 2026 23:56:33 +0530 Subject: [PATCH 1/2] docs(spec): add glossary and format ADRs --- README.md | 2 + docs/GLOSSARY.md | 133 ++++++++++++++++++ ...0001-schema-json-is-the-format-contract.md | 23 +++ ...02-trail-envelope-and-two-tier-identity.md | 33 +++++ .../0003-multi-segment-session-primitives.md | 33 +++++ ...ment-reconciliation-and-event-id-policy.md | 36 +++++ ...0005-session-bundles-and-child-sessions.md | 33 +++++ ...ext-compact-replaced-message-provenance.md | 31 ++++ .../0007-v0.1-draft-hardening-decisions.md | 27 ++++ docs/adr/0008-enum-extensibility-policy.md | 33 +++++ 10 files changed, 384 insertions(+) create mode 100644 docs/GLOSSARY.md create mode 100644 docs/adr/0001-schema-json-is-the-format-contract.md create mode 100644 docs/adr/0002-trail-envelope-and-two-tier-identity.md create mode 100644 docs/adr/0003-multi-segment-session-primitives.md create mode 100644 docs/adr/0004-segment-reconciliation-and-event-id-policy.md create mode 100644 docs/adr/0005-session-bundles-and-child-sessions.md create mode 100644 docs/adr/0006-context-compact-replaced-message-provenance.md create mode 100644 docs/adr/0007-v0.1-draft-hardening-decisions.md create mode 100644 docs/adr/0008-enum-extensibility-policy.md diff --git a/README.md b/README.md index 94819a5..16a0d34 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,8 @@ This repository contains the Agent Trail specification, JSON Schema artifacts, f - [`schema/v0.1.0.json`](./schema/v0.1.0.json) - frozen v0.1.0 JSON Schema artifact. - [`schema/draft.json`](./schema/draft.json) - current draft JSON Schema artifact. - [`fixtures/validation/`](./fixtures/validation/) - validation conformance fixture corpus and manifest. +- [`docs/GLOSSARY.md`](./docs/GLOSSARY.md) - shared terminology for public format discussions. +- [`docs/adr/`](./docs/adr/) - format ADRs carried forward for the spec repo. ## Related Repositories diff --git a/docs/GLOSSARY.md b/docs/GLOSSARY.md new file mode 100644 index 0000000..dd02012 --- /dev/null +++ b/docs/GLOSSARY.md @@ -0,0 +1,133 @@ +# Agent Trail Glossary + +Agent Trail defines a shared language for portable coding-agent session interchange. This glossary keeps spec, schema, and fixture discussions aligned without adding new normative requirements. + +## Language + +**Agent Trail**: +The open format and tooling ecosystem for portable coding-agent sessions. +Avoid: AgentTrail. + +**Trail file**: +A JSONL file conforming to the Agent Trail format. It contains one or more session groups. +Avoid: session dump, transcript file, conversation export. + +**Format contract**: +The stable interoperability agreement that compliant writers and readers rely on. +Avoid: TypeScript API, implementation model. + +**JSON Schema**: +The canonical machine-readable contract for validating Agent Trail records. +Avoid: generated type source, helper schema. + +**Writer-strict validation**: +Validation that proves an emitted trail file conforms exactly to a released schema and whole-file rules. +Avoid: normal validation, loose validation. + +**Reader-tolerant parsing**: +Parsing that preserves or skips unfamiliar future data without treating every unknown shape as fatal. +Avoid: strict validation, schema validation. + +**Trail envelope**: +Optional `type:"trail"` record at line 1 carrying file-level metadata, file-scope hash, a sessions manifest, and extensions. It is not part of the event graph. +Avoid: file header, outer header. + +**Header**: +The session header record with `type:"session"`. It appears on line 1 when there is no trail envelope and on line 2 when the envelope is present. +Avoid: event header. + +**Session group**: +One `type:"session"` header plus the events after it until the next session header or EOF. +Avoid: embedded trail, nested session. + +**Session bundle**: +A trail file with one or more session groups. The bundle is a forest at session-group level; each group may itself be linear or tree-native. +Avoid: multi-transcript, merged session. + +**Child session**: +A separate session group or external session spawned or forked from another session, linked by the child header's `fork_from`. +Avoid: subtree, branch, sidechain when the source stores a separate transcript. + +**Session segment**: +One trail-file artifact carrying part of a logical source session. Segments are linked by `session_uid` and ordered by `segment.seq`. +Avoid: session shard, chunk. + +**Session UID**: +Header field `session_uid` identifying the source session a segment belongs to. It is stable across all segments of one source session and is a ULID or UUID. +Avoid: session id, which is the per-artifact `id`. + +**Event**: +Any object after the header line. It is one unit of session content. +Avoid: log line when graph identity matters. + +**Entry**: +Equivalent to event. Either term may appear in prose. + +**Linear session**: +A session whose events do not use `parent_id`. Events are ordered by file position. + +**Tree session**: +A session where some events use `parent_id` to form a DAG. + +**Canonical event**: +One of the mandatory or optional event types defined by the format. +Avoid: arbitrary source event. + +**Adapter**: +Software that reads a source agent's storage and emits a trail file. +Avoid: importer, parser plugin. + +**Raw trail**: +A local trail artifact that preserves source-session fidelity before sharing. +Avoid: original trail, private copy. + +**Redacted trail**: +A separate trail artifact produced from a raw trail with sensitive content removed or normalized. +Avoid: sanitized view, safe mode. + +**Shared trail**: +A redacted trail transported through a sharing mechanism. +Avoid: public trail, hosted session. + +**Session-level content hash**: +SHA-256 of canonical bytes covering only the session header and its events, with the session header's `content_hash` pinned to ``. +Avoid: trail hash, file hash. + +**File-level content hash**: +SHA-256 of canonical bytes covering the whole file with the trail envelope's `content_hash` pinned to ``. +Avoid: session hash, transport hash. + +**Content hash**: +SHA-256 of an exact artifact's canonical bytes. + +**Canonical bytes**: +File content normalized for hashing by the Agent Trail content-addressing rules. + +**Sessions manifest**: +Optional trail-envelope field `sessions` declaring the session groups present in a trail file. The session headers in the file are authoritative. +Avoid: session list as the source of truth. + +**Source escape hatch**: +The `source.raw` field. It preserves source-format data needed for traceability or round-trip fidelity. +Avoid: canonical payload. + +**Synthesized event**: +An event the adapter constructed from indirect source data rather than mapping from one real source event. It is flagged with `source.synthesized: true`. + +## Relationships + +- A trail file conforms to the format contract. +- A trail file contains one or more session groups; multiple groups form a session bundle. +- The JSON Schema is the canonical machine-readable part of the format contract. +- Writer-strict validation checks emitted trail files before publication or storage. +- Reader-tolerant parsing is for consumers reading potentially newer trail files. +- An adapter emits a raw trail from a source agent session. +- A redacted trail is produced from a raw trail. +- A shared trail transports a redacted trail. +- A session segment belongs to a logical source session identified by session UID. +- A child session links to its parent with `header.fork_from`; intra-session branches use event `parent_id`. + +## Flagged Ambiguities + +- "Validation" can mean writer-strict validation or reader-tolerant parsing. Use the precise term when behavior matters. +- "Trail" can mean a raw, redacted, or shared artifact. Use raw trail, redacted trail, or shared trail when artifact identity matters. diff --git a/docs/adr/0001-schema-json-is-the-format-contract.md b/docs/adr/0001-schema-json-is-the-format-contract.md new file mode 100644 index 0000000..e9fbcbb --- /dev/null +++ b/docs/adr/0001-schema-json-is-the-format-contract.md @@ -0,0 +1,23 @@ +# schema.json is the format contract + +## Status + +Accepted. + +## Decision + +Agent Trail is a language-neutral interchange format, so `schema.json` is the canonical machine-readable contract through `1.0.0`. + +TypeScript types, validators, examples, and other generated artifacts derive from the schema rather than becoming separate sources of truth. This keeps non-TypeScript adopters from depending on implementation internals. + +## Considered Options + +- Keep `schema.json` canonical and derive implementation artifacts from it. +- Make TypeScript types canonical and derive `schema.json`. +- Maintain schema and TypeScript types separately with parity checks. + +## Consequences + +- Schema changes are the authoritative review surface for machine-readable format changes. +- Generated artifacts must not introduce behavior that is absent from the schema and spec prose. +- Hosted schema URLs for released versions remain immutable release snapshots. diff --git a/docs/adr/0002-trail-envelope-and-two-tier-identity.md b/docs/adr/0002-trail-envelope-and-two-tier-identity.md new file mode 100644 index 0000000..24106cf --- /dev/null +++ b/docs/adr/0002-trail-envelope-and-two-tier-identity.md @@ -0,0 +1,33 @@ +# Trail envelope and two-tier identity + +## Status + +Accepted. + +## Decision + +A trail file may carry file-level concerns on an optional `type:"trail"` record at line 1. This record is the trail envelope. It carries file-level metadata, file label, file-scope hash, optional sessions manifest, and extensions instead of overloading the session header. + +When the envelope is absent, behavior is unchanged. When present, the session header follows on line 2, and at most one envelope is allowed per file. This decouples file scope from session scope and reserves the structural slot for session bundles. + +Identity is two-tier: + +- Session-level `content_hash` lives on the session header and covers only the session header and its events. +- File-level `content_hash` lives on the trail envelope and covers the whole file with the envelope's `content_hash` pinned to ``. + +Writers stamp the session hash first, then the file hash. Transport tooling verifies the file hash. Extraction tooling recomputes the session hash. Both use the same canonicalization rules as the spec content-addressing section. + +## Considered Options + +- Add file-level fields to the session header. Rejected because it conflates file scope and session scope. +- Introduce a sidecar metadata file beside each trail. Rejected because it breaks the single-file invariant. +- Adopt an optional envelope record at line 1 with two-tier identity. Chosen. + +## Consequences + +- The schema admits trail envelopes as a first-class record shape. +- Validation dispatches by record type and whole-file position rules. +- Envelope fields are file-level metadata and are not part of the event graph. +- Session hashes remain stable when a session group is extracted from a wrapping file. +- File hashes cover wrapping metadata and the contained session groups. +- The earlier single-session manifest constraint is superseded by ADR-0005's session-bundle model. diff --git a/docs/adr/0003-multi-segment-session-primitives.md b/docs/adr/0003-multi-segment-session-primitives.md new file mode 100644 index 0000000..ad992b5 --- /dev/null +++ b/docs/adr/0003-multi-segment-session-primitives.md @@ -0,0 +1,33 @@ +# Multi-segment session primitives + +## Status + +Accepted. + +## Decision + +The session header carries three optional fields that let a reader group, order, and verify trail-file segments belonging to one logical source session: + +- `session_uid`: globally unique source-session identifier, stable across all segments. +- `segment.seq`: 1-based integer; absent or `{ "seq": 1 }` for single-segment trails. +- `segment.prev_content_hash`: SHA-256 of the previous segment's session-level `content_hash`. + +`segment.prev_content_hash` is required when `segment.seq >= 2`. It forms a verifiable chain. A `null` value is allowed when the prior segment was lost; readers warn but continue. + +The primitives sit at session-header grain so they compose with session bundles. Each session group in a file may independently be multi-segmentable. The trail envelope is unaffected. + +`session_uid` accepts ULID or UUID. ULID is recommended when a writer can choose the identifier because the time prefix gives a useful secondary sort when `segment.seq` is missing or ambiguous. UUID remains valid for sources that already expose UUID-shaped session metadata. + +## Considered Options + +- Per-event monotonic cursor plus session id. Rejected because Agent Trail already content-addresses events and supports event topology. +- Tuple position using session, shard, and per-shard sequence. Rejected because Agent Trail assumes one producer per session for this primitive. +- Globally unique event ids plus optional causal DAG plus segment chain hash. Adopted at header level as `session_uid`, `segment.seq`, and `segment.prev_content_hash`. + +## Consequences + +- The schema defines ULID, UUID, session UID, and segment shapes. +- Continuation segments require `session_uid`. +- Existing single-segment trails remain valid without segment fields. +- Reconciliation semantics build on these primitives in ADR-0004. +- The trail envelope and file-level hash model from ADR-0002 remain unchanged. diff --git a/docs/adr/0004-segment-reconciliation-and-event-id-policy.md b/docs/adr/0004-segment-reconciliation-and-event-id-policy.md new file mode 100644 index 0000000..e29a507 --- /dev/null +++ b/docs/adr/0004-segment-reconciliation-and-event-id-policy.md @@ -0,0 +1,36 @@ +# Segment reconciliation and event id policy + +## Status + +Accepted. + +## Decision + +Agent Trail defines reconciliation semantics for multi-segment sessions and tightens canonical event `id` values so segment deduplication can be based on exact string equality. + +The reconciliation model is: + +1. Group segment trails by `header.session_uid`. +2. Treat inputs without `session_uid` as pass-through single segments. +3. Sort each group by `segment.seq`; an absent `segment` counts as `seq: 1`. +4. Verify each non-first segment's `segment.prev_content_hash` against the prior segment. +5. Warn and continue on chain gaps, duplicate sequence numbers, or unverifiable links. +6. Concatenate events and deduplicate by event `id`. +7. Build a merged header from the first segment for stable fields and the last segment for late-bound fields. +8. Drop `segment` from the merged header and recompute the merged session-level `content_hash`. + +The canonical event `id` shape is constrained to the same identifier family as `session_uid`: canonical ULID, hyphenated UUID, or unhyphenated UUID. Writers must emit canonical casing so validators and reconcilers can compare ids by exact string equality. + +## Considered Options + +- Keep loose event ids and emit only warnings. Rejected because deduplication would depend on writer behavior that the schema did not enforce. +- Define a separate reconciliation-only identifier. Rejected because event `id` already carries graph identity. +- Use canonical ULID or UUID event ids. Chosen. + +## Consequences + +- Reconciliation can deduplicate events without source-specific id normalization. +- Readers can preserve partial segment groups even when chain verification is incomplete. +- Writers must not emit compound or adapter-local strings as canonical event ids. +- Stable and late-bound header field behavior is part of the format semantics, not a storage API. +- The multi-segment primitives from ADR-0003 remain the only header fields needed to opt into this behavior. diff --git a/docs/adr/0005-session-bundles-and-child-sessions.md b/docs/adr/0005-session-bundles-and-child-sessions.md new file mode 100644 index 0000000..4aadcc6 --- /dev/null +++ b/docs/adr/0005-session-bundles-and-child-sessions.md @@ -0,0 +1,33 @@ +# Session bundles and child sessions + +## Status + +Accepted. + +## Decision + +Agent Trail supports one trail file containing one or more session groups. A file with multiple groups is a session bundle: a forest of session groups. Each group remains an ordinary session and may be linear or tree-native. + +External subagents and forked transcripts are modeled as child sessions. The durable edge lives on the child session header: + +```json +{ "fork_from": { "session_id": "", "entry_id": "" } } +``` + +`entry_id` is emitted only when the source exposes a clear parent event. `content_hash` is optional best effort and refers to the parent session-level content hash when known. + +Parent events may also carry a source-visible child session id when the adapter can link the child confidently. Runtime ids that are not durable Agent Trail header ids stay in metadata or `source.raw`. + +## Considered Options + +- Encode all child work as `parent_id` subtrees inside the parent group. Rejected because some sources store full child transcripts as separate sessions, and `parent_id` must not cross groups. +- Put the authoritative graph in the envelope `sessions` manifest. Rejected because it duplicates lineage and makes extraction brittle. +- Make `header.fork_from` authoritative and keep the manifest as an index or rendering hint. Chosen. + +## Consequences + +- The file grammar is `envelope? + session groups`. +- The envelope `sessions` manifest is not authoritative over session headers. +- Whole-file validation can compare in-file parent and child links. +- Missing, ambiguous, or external-only child links remain readable. +- Adapters annotate what they know and do not invent child groups. diff --git a/docs/adr/0006-context-compact-replaced-message-provenance.md b/docs/adr/0006-context-compact-replaced-message-provenance.md new file mode 100644 index 0000000..d60a11e --- /dev/null +++ b/docs/adr/0006-context-compact-replaced-message-provenance.md @@ -0,0 +1,31 @@ +# Context compaction replacement provenance + +## Status + +Accepted. + +## Decision + +Agent Trail has a first-class `context_compact` event. Its payload includes optional `replaced_message_ids` so a writer can record which earlier Agent Trail entries were folded into the compacted context. + +Add: + +```ts +context_compact.payload.replaced_message_ids?: id[] +``` + +The values are Agent Trail entry ids, not raw source ids. They are ordered by folded source order. The field is provenance-only: writer-strict schema validation checks only the id shape, and whole-file validation does not require each id to resolve to an entry still present in the same trail file. + +Writers omit the field when provenance cannot be mapped deterministically to Agent Trail entry ids. + +## Considered Options + +- Store only the compacted summary. Rejected because sources may expose useful replacement provenance. +- Store raw source ids. Rejected because they are not portable Agent Trail graph identifiers. +- Store optional Agent Trail entry ids. Chosen. + +## Consequences + +- Consumers can render or analyze compaction provenance when present. +- Missing or dangling replacement ids do not make the trail invalid. +- Writers must omit the field rather than emitting raw source ids or empty arrays when provenance is unavailable. diff --git a/docs/adr/0007-v0.1-draft-hardening-decisions.md b/docs/adr/0007-v0.1-draft-hardening-decisions.md new file mode 100644 index 0000000..0fc3339 --- /dev/null +++ b/docs/adr/0007-v0.1-draft-hardening-decisions.md @@ -0,0 +1,27 @@ +# v0.1 draft hardening decisions + +## Status + +Accepted. + +## Decision + +Record the v0.1.0 draft hardening decisions that affect public format behavior: + +- Envelope-level token usage belongs on the first derived entry whose payload supports `usage`: `agent_message`, `agent_thinking`, or `tool_call`. +- Usage from one source envelope must not be repeated on later entries derived from the same source envelope. +- The schema definition name remains `agentMessageUsage` for v0.1.0, even though the field is no longer exclusive to `agent_message`. +- The usage placement rule aligns with the inline-first and reference-subsequent source envelope convention: one source envelope has one first derived entry for shared envelope-level facts. +- ADR numbering is append-only within a documentation lineage, but this spec repo uses compact numbering for the carried-forward spec records. + +## Considered Options + +- Keep usage only on `agent_message`. Rejected because tool-call-only and thinking-only assistant envelopes lose token accounting. +- Allow usage on every event type. Rejected because the schema surface would be broader than v0.1.0 needs. +- Rename `agentMessageUsage` immediately. Rejected because it creates unrelated schema and generated-artifact churn. + +## Consequences + +- The schema allows `payload.usage` on `agent_message`, `agent_thinking`, and `tool_call`. +- Adapters preserve token usage for assistant envelopes whose first emitted entry is a thinking block or tool call. +- Consumers should treat usage as envelope-level accounting attached to the first derived entry that can carry it. diff --git a/docs/adr/0008-enum-extensibility-policy.md b/docs/adr/0008-enum-extensibility-policy.md new file mode 100644 index 0000000..c87a8fa --- /dev/null +++ b/docs/adr/0008-enum-extensibility-policy.md @@ -0,0 +1,33 @@ +# Enum extensibility policy + +## Status + +Accepted. + +## Decision + +Agent Trail keeps structural discriminators closed and descriptive state vocabulary extensible. + +Structural discriminators gate parser or renderer dispatch and require a format version bump for new values. In the v0.1.0 schema, this includes event `type`, task-plan delta `kind`, attachment `kind`, and `taskPlanStatus`. + +Descriptive state vocabulary accepts reserved values plus vendor-namespaced extensions of the form `x-/`. Bare unknown strings remain writer-strict errors. Readers treat unknown `x-/` values as opaque strings and pass them through. + +Current extensible vocabulary includes `scope`, `reason`, `trigger`, `origin`, `command_invoke.kind`, `command_invoke.via`, and `command_invoke.result_action` slots that describe observed runtime state rather than dispatch shape. It also includes established extension surfaces such as `system_event.kind`, `vcs.type`, `session_metadata_update.field`, and custom `agent.name`. + +An `x-/` value observed across two or more adapters can be promoted into the reserved enum in a minor format bump. This follows the convention already stated for `system_event.kind` in the events section. + +`parse_fidelity.termination_reason` and `session_terminated.reason` both refer to `#/$defs/sessionTerminationReason`. They open or close together by construction; keep the shared definition rather than duplicating the enum. + +## Rationale + +Closed enums are useful where a new value changes dispatch semantics, rendering shape, graph validation, or cross-record invariants. They are too expensive for adapter-specific state vocabulary, because every source-specific reason, trigger, scope, or invocation channel would otherwise need a schema revision and minor format bump before a writer could preserve it. + +The `x-/` grammar already works for `system_event.kind` and `vcs.type`: reserved values stay portable, while vendor variance remains namespaced and machine-recognizable. Applying the same rule to descriptive state vocabulary keeps writer-strict validation strict without forcing lossy normalization. + +## Consequences + +- Schema changes that add new structural discriminator values require a format version bump. +- Schema changes that add reserved descriptive enum values can land in a minor format bump after adapter evidence shows cross-agent use. +- Writers must use `x-/` for non-reserved descriptive values and must not emit bare unknown strings. +- Readers should not fail only because an otherwise valid descriptive enum uses an unknown `x-/` value. +- Future schema edits should keep shared definitions shared when two fields are intentionally coupled, as with `#/$defs/sessionTerminationReason`. From 1d3b2356a815752ec34159d4985ea01f521bed08 Mon Sep 17 00:00:00 2001 From: Somasundaram Ayyappan <1802828+somus@users.noreply.github.com> Date: Sat, 13 Jun 2026 00:10:30 +0530 Subject: [PATCH 2/2] docs(spec): clarify ADR terminology --- docs/GLOSSARY.md | 4 ++++ docs/adr/0002-trail-envelope-and-two-tier-identity.md | 2 +- docs/adr/0005-session-bundles-and-child-sessions.md | 2 +- docs/adr/0008-enum-extensibility-policy.md | 4 +++- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/GLOSSARY.md b/docs/GLOSSARY.md index dd02012..1acdba7 100644 --- a/docs/GLOSSARY.md +++ b/docs/GLOSSARY.md @@ -48,6 +48,10 @@ Avoid: multi-transcript, merged session. A separate session group or external session spawned or forked from another session, linked by the child header's `fork_from`. Avoid: subtree, branch, sidechain when the source stores a separate transcript. +**Session id**: +The durable Agent Trail `id` on a session header. `fork_from.session_id` references this header id, not `session_uid`. +Avoid: source session id. + **Session segment**: One trail-file artifact carrying part of a logical source session. Segments are linked by `session_uid` and ordered by `segment.seq`. Avoid: session shard, chunk. diff --git a/docs/adr/0002-trail-envelope-and-two-tier-identity.md b/docs/adr/0002-trail-envelope-and-two-tier-identity.md index 24106cf..75d6643 100644 --- a/docs/adr/0002-trail-envelope-and-two-tier-identity.md +++ b/docs/adr/0002-trail-envelope-and-two-tier-identity.md @@ -6,7 +6,7 @@ Accepted. ## Decision -A trail file may carry file-level concerns on an optional `type:"trail"` record at line 1. This record is the trail envelope. It carries file-level metadata, file label, file-scope hash, optional sessions manifest, and extensions instead of overloading the session header. +A trail file may carry file-level concerns on an optional `type:"trail"` record at line 1. This record is the trail envelope. It carries file-level metadata, optional human-facing `name`, file-scope hash, optional sessions manifest, and extensions instead of overloading the session header. When the envelope is absent, behavior is unchanged. When present, the session header follows on line 2, and at most one envelope is allowed per file. This decouples file scope from session scope and reserves the structural slot for session bundles. diff --git a/docs/adr/0005-session-bundles-and-child-sessions.md b/docs/adr/0005-session-bundles-and-child-sessions.md index 4aadcc6..7f1e6e5 100644 --- a/docs/adr/0005-session-bundles-and-child-sessions.md +++ b/docs/adr/0005-session-bundles-and-child-sessions.md @@ -14,7 +14,7 @@ External subagents and forked transcripts are modeled as child sessions. The dur { "fork_from": { "session_id": "", "entry_id": "" } } ``` -`entry_id` is emitted only when the source exposes a clear parent event. `content_hash` is optional best effort and refers to the parent session-level content hash when known. +`fork_from.session_id` is the durable Agent Trail `id` of the parent session header. It is not `session_uid`, which identifies a logical source session across segments. `entry_id` is optional and is emitted only when the source exposes a clear parent event. `content_hash` is optional best effort and refers to the parent session-level content hash when known. Parent events may also carry a source-visible child session id when the adapter can link the child confidently. Runtime ids that are not durable Agent Trail header ids stay in metadata or `source.raw`. diff --git a/docs/adr/0008-enum-extensibility-policy.md b/docs/adr/0008-enum-extensibility-policy.md index c87a8fa..80b98b3 100644 --- a/docs/adr/0008-enum-extensibility-policy.md +++ b/docs/adr/0008-enum-extensibility-policy.md @@ -12,7 +12,9 @@ Structural discriminators gate parser or renderer dispatch and require a format Descriptive state vocabulary accepts reserved values plus vendor-namespaced extensions of the form `x-/`. Bare unknown strings remain writer-strict errors. Readers treat unknown `x-/` values as opaque strings and pass them through. -Current extensible vocabulary includes `scope`, `reason`, `trigger`, `origin`, `command_invoke.kind`, `command_invoke.via`, and `command_invoke.result_action` slots that describe observed runtime state rather than dispatch shape. It also includes established extension surfaces such as `system_event.kind`, `vcs.type`, `session_metadata_update.field`, and custom `agent.name`. +Current extensible vocabulary includes `scope`, `reason`, `trigger`, `origin`, `command_invoke.kind`, `command_invoke.via`, and `command_invoke.result_action` slots that describe observed runtime state rather than dispatch shape. It also includes established extension surfaces such as `system_event.kind`, `vcs.type`, and `session_metadata_update.field`. + +`agent.name` follows the same two-part contract: registered canonical names come from the canonical agent registry, while unregistered agents use `x-/`. Readers treat unknown `x-/` agent names as opaque strings and pass them through. An `x-/` value observed across two or more adapters can be promoted into the reserved enum in a minor format bump. This follows the convention already stated for `system_event.kind` in the events section.