Write each record as a single JSON object on one line. JSON lines append cleanly, stream well, and are trivially ingestible by columnar stores and log pipelines. Several emerging proposals converge on this shape. An IETF draft for an agent audit trail specifies a JSON record structure linked by tamper-evident SHA-256 hash chaining, transport-agnostic and exportable to JSONL, Syslog, and CSV (agent audit trail draft). A separate community specification for agent decision records uses structured JSON serialization with required frontmatter validation (Agent Decision Records).
Here is a complete record for a support agent that changes a renewal status:
{
"decision_id": "01JQ8Z4T7K9M2",
"correlation_id": "run_7f3a91",
"timestamp": "2026-03-04T14:22:07.418Z",
"tenant_id": "acme-eu",
"actor": {"type": "human", "id": "user_1192", "auth": "session"},
"task": {"type": "renewal_status_change", "request_ref": "ticket:88412"},
"inputs": [
{"kind": "user_message", "sha256": "9c1f...", "ref": "ticket:88412/msg:3"},
{"kind": "retrieval", "sha256": "4ab0...", "ref": "kb:renewal-policy#v4"},
{"kind": "tool_result", "tool": "get_account", "sha256": "77de...", "ref": "crm:acct:4411@v27"}
],
"model": {
"provider": "example",
"name": "frontier-small",
"version": "snapshot-2026-02-11",
"temperature": 0.0,
"max_tokens": 800
},
"prompt": {
"template_id": "renewal_agent",
"prompt_hash": "b3e1c8...",
"token_count": 1840
},
"output": {
"raw": "{\"action\":\"update_renewal\",\"status\":\"paused\"}",
"ref": "blob:decisions/01JQ8Z4T7K9M2/output.txt"
},
"policy": {"name": "renewal-policy", "version": "v4", "verdict": "allow", "reasons": ["account_owner_verified", "below_risk_threshold"]},
"reviewer": {"type": "automated_rule", "id": "policy-engine", "version": "v4"},
"reason": "Account owner requested pause; amount below threshold; no exceptions matched.",
"action": {"tool": "billing.updateRenewal", "target_ref": "crm:acct:4411", "idempotency_key": "01JQ8Z4T7K9M2-act"},
"outcome": {"state": "verified", "result_ref": "billing-event:ee91c2", "version_after": 28}
}
Two format decisions are worth copying. First, store references and hashes for large or sensitive inputs and outputs rather than copying content; the pointer respects the retention rules of the system that owns the data. Second, split the record into a planned phase and an outcome phase. Write the decision before the side effect so a timeout or crash is itself recorded, then append the verified result. That pattern turns ambiguity into an explicit unknown state instead of silently implying success, and the idempotency key from the planned record prevents duplicate retries (decision logs, evidence without chain of thought).
Hash chaining is optional at small scale and worth the effort at audit scale. Including the previous record's digest in each new record makes tampering detectable, which is exactly what general log management guidance recommends: centralized collection plus integrity protection such as tamper-evident or write-once storage for records used in investigations (policy decision log format and retention).