t3-code
Identity
T3 Code is an app that runs other agents. It owns the conversation (threads, queues, approvals routing, questions, schedules, delegated tasks, checkpoints, pull request links) and drives Claude Code, Codex or Pi to do the model work. Each backing harness writes its own native transcript.-
Native format:
t3code-statev2-sqlite. One SQLite database per T3 environment (~/.t3/userdata/statev2.sqlite): an event store of whole-entity snapshots (orchestration_events) and projection tables. Raw provider protocol frames are kept in rotating logs (logs/provider/events.<threadId>.log), which can serve as native files. -
Session ID: the T3 thread ID, verbatim. Namespace: required for every T3 stream: the T3 environment ID (
~/.t3/userdata/environment-id). Derived thread IDs (import:codex:<id>,thread:delegated-task:…) repeat across installations. -
Session references: thread IDs can contain
:and%, which session references encode (ASR-059). The delegated-task threadthread:delegated-task:command%3Amcp%3A9f2cin environment6f1d2c3a-5b7e-4c21-9a0d-3e8f1b2c4d5eist3-code:6f1d2c3a-5b7e-4c21-9a0d-3e8f1b2c4d5e:thread%3Adelegated-task%3Acommand%253Amcp%253A9f2c. -
Streams: One stream per T3 thread and one per backing session, converted under that agent’s own registry entry.
nativeThreadRefsupportslineage.executedByonly when the provider kind, namespace and native ID that T3’s adapter recorded identify that agent’s session. A strength ofstrongalone does not establish identity. Pi file paths and Claude workflow keys containing:agent:<n>stay incodes.t3/nativeThreadReforcodes.t3/nativeTaskRef; never inspect arbitrary paths to recover identity. A switch of backing session adds an entry bydeclaration.state.executedBy.turnIdusesnativeTurnRef.nativeIdonly under a documented provider-turn correspondence (Codex); weak or generated turn refs remain in_meta. -
Entity keys:
turnIdis the run ID (run:thread:<threadId>:ordinal:<n>).messageIdis the T3 message ID.callIdisnativeItemRef.nativeIdonly when the provider contract identifies it as the invocation ID. Otherwise use the T3 turn item ID. Strength alone never establishes cross-source correspondence.requestIdis the runtime request ID. T3 records no model calls: there are noinferencerecords (declareinference). -
Copies and originality: A recorded link showing which provider thread owns an item can establish
copiedFromat session level only, withproof: native_field. Addrecordonly when a uniquenativeItemRef.nativeIdhas a documented native record correspondence in that backing session. Adapter strength alone is insufficient, andcallId=cannot name a tool result. T3-owned prompts, approvals, questions, triggers, notices and checkpoints are not copies merely because the thread has a backing session. Usage covers backing calls (ASR-425). -
Who wrote a message: take
authorandoriginfrom T3, not from the backing transcript, which shows every prompt T3 inserted as an ordinary user prompt. The mapping is in the table below. -
Tools: T3 drops the provider’s tool name for
command_execution,file_change,web_searchandfile_searchitems:capture.name: absent(the backing stream has the name).dynamic_toolkeepstoolName. MCP identity:unknownin the T3 stream (the Codex backing stream has it exactly). A “Workspace ready” command item is a setup script T3 ran:hookwithevent: workspace_setup. Background commands and monitors (pendingBackgroundTaskswith kindcommandormonitor) →terminalwithkind: shellormonitorandawaited; kindsubagent→subagent. -
Approvals:
approval_requestitems and runtime requests →permission.decision:accept→allow_once,acceptForSession→allow_session,acceptAlways→allow_always,decline→reject_once,cancel→cancelled.status:pending→pending,resolved→resolved,expired→expired,cancelled→resolvedwithdecision: cancelled.feedback→feedback;fullAccessOverride→reason.t3_pending_request_respondanswers questions only. Its opaquemcp:<uuid>receipt does not identify who resolved an approval: leavedeciderabsent.acceptForSessionmaps toallow_sessionin option kinds as well as decisions. The native cancel option maps to option kindcancel. -
Questions:
user_input_requestitems →input_requestwithmode: questions: questionid,header,question→text,optionswithlabel,valueanddescription,multiSelect,allowCustomAnswer→allowOther; answers →answers;blocking; an answer given later as a message (responseMode: message) →answerRefonly when an explicit recorded message ID qualifies the link;responseModealone does not.secret_request→input_requestwith one question markedsecret;secretStatussaved→answered,declined,cancelled,pending. The secret goes to an owner-only file and is never recorded (ASR-283).mcp-elicitationruntime requests →mode: formorurl. -
Turns: run status →
state:queued→queued;running→running;waiting→requires_action;completed→idlewithstopReason: end_turn;interruptedandcancelled→idlewithstopReason: cancelled;failed→idlewithstopReason: error;rolled_back→ arewindwithreason: rollback. Run attempts →state.attempt {n, reason}(initial,steering_restart,retry,provider_recovery). Run snapshots retainrestartContinuationOfRunId→continuationOf.usageLimitContinuationOfRunIdandmanualContinuationOfRunIdcan map only when their authoritative dispatch commands survive; otherwise preserve native evidence and declare_codes.t3/continuation_history. Error items →state.errorwithclass,retryable,resetAtandretry {attempt, maxAttempts, delayMs}(fromretryDelayMs). -
Checkpoints and changes:
checkpoint.captured→checkpointwithkind: git_ref,ref(the hidden ref),status,filesandturnId. A run’s diff between two checkpoints →file_changewithbasis: netandendpoints.checkpoint.rollback-requested→rewindwithreason: rollbackandrestoreRequested. -
Pull requests: a pull request link whose
sourceiscreated→vcspr_openwithevidence: observed; links with sourceagent,manualorstack→vcspr_linkwithevidence: reported. -
Notes:
compactionitems record token counts but not the replaced range:compactionwithreplaces: {state: unknown},tokens,reasonfromidleCompaction, andkind_codes.t3/compaction(T3 does not record the kind). Reasoning with no recorded visibility usesreasoning.textwithvisibilityabsent; readers must not label it full reasoning. Plans:todo_list→planType: items;proposed_plan→planType: document; provider goals →planType: goalwithstatus,budgetandused. Archive, pin and soft delete →session_info.flags; projects →session_info.project; a generated title →titleSource: model. Guest roster entries can declare participants withrole: guest; assignfromonly through a qualified recorded guest identity, never the roster or display name alone.notificationitems → notice messages. Declareinference,revision_historyandtool_result.content(T3 keeps display output only).
author and origin:
A user message’s text is what the person typed:
displayContent, with content empty and capture.content: absent, because T3 wraps first prompts and inlines handoff text before sending them.
Position basis
- Order: Compaction deletes earlier snapshots, and with them the positions at which items were created. Use a new capture, with safe-integer
seqtaken from the surviving items’ordinaland the store’s documented serialization order. Keep immutable audit logs in their own sequence order, current rows in the capture tail, and declareorderandrevision_history. Preserve IDs backed by stable T3 identity; useidScope: captureonly for purely positional IDs.
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
T3 Code: native facts without a standard field
Links
- Lineage:
thread.created.lineage.relationshipToParent: subagent→spawnedByandscope: subagent;fork→forkedFrom, withrecordfrom the fork point when T3 records it. A thread created withcreate_threadsgetsspawnedByandscope: primaryonly when its recordedlineage.parentThreadIdand creation relation identify the creator. Delegated tasks →subagentin the parent (agentfrom the child’s driver,model,awaited, andstatusrevisions fromsubagent.updated). Context handoffs → the rendered message hasderivedFrom(from the handoff’s item list); a fork whose context arrived as a summary hasinherits.mode: rendered. Provider-native subagent threads (creationSource: provider, items but no runs) are read-only copies of a Claude Code subagent transcript:authority: mirrorandexecutedBynamingclaude-code:<agentId>.rootmay be claimed for a thread whosethread.createdevent has nolineageand noforkedFrom, and that was not imported.
T3 Code link contracts
These contracts apply to4a95cee9b8, server 0.1.3-nightly.
Usage
After applying revisions, aggregateProviderTurn.turnTokenUsage components known not to overlap once per T3 run and counter. Write the aggregate as usage_summary with scope: turn, cumulative: false, coverage: partial, and usage.input.total with includesCache: true. Preserve components at codes.t3/providerUsage; components with no run use the documented vendor scope _codes.t3/provider_turn. Do not add overlapping components; tokenUsage → contextWindow.
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 about 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["codes.t3/unassigned"] with the common shape. Selection may retain these facts with any session subset, including an empty subset, but must not imply session ownership. 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. Omitted unassigned facts use a documented vendor loss or report, not a new core category.Evidence
Basis: source (fork main at4a95cee9b8, server 0.1.3-nightly), and observed (one local event store). The reverse-DNS name follows the product domain t3.codes and is provisional.
Evidence applies only to the named formats and explicit mappings above. A real capture covers only exercised behavior. A writer probe run without a model covers persistence, not model or tool execution. Authored tests do not qualify an agent version. Unlisted formats and link mappings remain unqualified.