opencode
Identity
-
Names:
opencode/ai.opencode. -
Native format:
opencode-sqlite. Read session/message/part tables and available sequencedsession_messageorsession_entrytables in one transaction, including WAL. Keep alternate migration representations as vendor records. Only layouts verified at this entry’s pin are covered. -
Session ID: Native
session.idorsession_v2.id, with no namespace for the pinned CLI format. A table name or path is not part of identity. -
Entity keys: Message
idand toolcallID, verbatim. Keep part-row IDs separately. A uniquely owned tool part’s currentstatesupplies its call and completed/error result. Reused call IDs are ambiguous. Step/message usage supports an inference derived from its native message or step-part ID. -
Notes: Fold text, reasoning and files under the native message. Keep ignored parts outside model context. Native input excludes cache reads/writes; output excludes reasoning, so add output and reasoning only when both exist. Cost is harness-estimated USD. Model selection is requested, not served. Keep
revertmetadata when its part boundary falls inside a folded message. Summary/prune/checkpoint/patch fields without exact target or endpoint contracts remain metadata. A todo snapshot must contain the complete item list.
Position basis
- Order and captures: Use native sequence order; legacy order is message
time_createdthen message ID, with part-ID order. Rewritten tool and text rows keep their transcript positions as defined by the source and their contents as observed. These rows do not establish the history of earlier state changes. ASR-015 requires deterministic native-key record IDs across independent captures. A destination’s first-observation position ledger cannot replace that rule or reorder the current source.
Use only positions established by the stated format and mapping evidence. Current-state rows without transcript positions form the snapshot tail. A protocol commit boundary takes precedence over physical EOF; uncommitted bytes are not a gap.
Destinations
opencode: native facts without a standard field
Links
- Lineage:
session.parent_idsupplies onlyrelatedUnknown;fork_session_idsuppliesforkedFromwhere that exact field exists at the pinned revision. A task tool’smetadata.sessionIdnames its child. It does not identify the inverse delegating call in a child header. No copies, root or copied-prefix length follow from matching IDs.
revert state that refers to a message part does not represent a rewind of the whole message or establish that a rewind occurred in the past. Preserve it and declare branches when its boundary cannot be represented. Part-level revert and splice models remain deferred.
Usage
Select one uniquely owned step report when the source establishes its accounting identity. Use a message report only when it does not overlap a selected step report. Keep reports that cannot be linked as native evidence and declare incompleteusage. Native input excludes cache reads and writes; output excludes reasoning. Cost is harness-estimated USD. These rules for what usage counts include depend on the pinned backend contract.
Select one report per native accounting identity only when this entry establishes that identity. Keep unjoinable or overlapping reports as native evidence. Declare incomplete semantic coverage. Schema defaults and placeholder zeros are not reported usage. Rules for what the backend includes in usage counts require evidence; do not infer them from a model name.
Lane and unassigned facts
Facts without established session ownership use manifest_meta["ai.opencode/unassigned"] with the common shape. A selection may retain these facts alongside any subset of sessions, including an empty subset, but must not imply that any session owns them. State the selection policy in the export report.
Losses
Declare every applicable loss under ASR-157. Missing model rendering, accounting joins, lineage or exact context boundaries remain losses when this entry does not qualify them. Unknown ownership is not itself lost data. Report omitted unassigned facts using a documented vendor loss category or report rather than a new core category.Evidence
Basis: source-verified: OpenCode1.18.18, commit 65c35977bd564e23c0e9cf124b3e3e3b9308e9e8. Sanitized official 1.18.34 to 2.0.21 migration fixtures cover user messages and migration; assistant semantics have authored tests. The pin does not qualify every later layout.
Evidence applies only to the named formats and explicit mappings above. A real capture covers only exercised behavior. A no-model writer probe covers persistence, not model or tool execution. Authored tests do not qualify an agent version. Unlisted formats and link mappings remain unqualified.
Observations from 2026-10-27
observed, version 1.19.4: OpenCode 1.19.4 retained edit, shell-test, resume, fork and child sessions. These findings cover only the exercised SQLite layout. Folding text into a message must preserve every native part row separately in native.record or native.blob; a fold does not authorize dropping part identity or extra fields.
The ctx conversion produced 3 streams and 116 records, with 0 errors, 3 notices, 0 gaps and 0 unidentified inputs under validator-v0.1.2. These counts describe the selected output; an empty bundle qualifies no source format. No sanitized native fixture was retained for this observation.
Whole native records use native.record or native.blob, with JSON text columns preserved as strings. The exporter’s own bookkeeping for serialization, partitioning and message keys belongs in the exporter namespace (rs.ctx for ctx), not to a provider metadata destination. These runs add no evidence for approvals, lineage links, compaction boundaries or exact request context that they did not exercise.