Skip to content

Schema: AuditLogEntry

File: audit-log-entry.json

Used by: REQ-O-030 · REQ-C-031


Purpose

One line of the opt-in audit log, and one item of data.entries returned by tool audit-log. It records a single command invocation so that an incident review can reconstruct what an agent ran, with which arguments, and how it ended, long after the response itself is gone (§33).

Three design decisions shape the type:

  • Same values as the response. timestamp, command, exit_code, duration_ms, request_id, and trace_id repeat the invocation's meta fields, so an entry joins to a captured response or trace by request_id or trace_id
  • Warnings as codes. warnings keeps only the codes of the response's warnings[]. Facts that must be queryable later, such as an over-privileged credential or disabled injection protection, survive without copying message text
  • Bounded by construction. An entry never exceeds 16 KiB; oversized args values are replaced with [TRUNCATED] and truncated is set, so one entry is always one write

AuditLogEntry

Field Type Required Description
timestamp string ISO 8601 date-time yes Invocation start time, matching meta.timestamp
command string yes Command path equal to meta.command, space- or dot-separated as the framework spells it (config set, config.set)
args object yes Parsed argument map after REQ-F-034 redaction; never the raw argv. A passthrough command (REQ-C-031) records its forwarded argv as "argv": "[OMITTED]"
exit_code integer 0–255 yes Process exit code, matching meta.exit_code
duration_ms integer yes Wall-clock milliseconds, matching meta.duration_ms
request_id string yes Unique invocation identifier, matching meta.request_id
trace_id string when TOOL_TRACE_ID is set Trace ID propagated from TOOL_TRACE_ID (REQ-F-025)
session_id string when the session variable is set Agent session identifier, recorded verbatim from the framework's one documented session variable (<PREFIX>SESSION_ID unless it already reads a prefixed one)
effects object mutating streams Events per effect value of a mutating stream (REQ-O-004): its summary line's effects, or the events emitted before a failure
warnings string[] yes Codes from the response's warnings[], in emission order; may be empty
truncated boolean no true when args values were replaced to fit 16 KiB

Examples

Successful deploy with a redacted secret

{"timestamp": "2026-03-17T14:00:01Z", "command": "deploy", "args": {"env": "prod", "token": "[REDACTED]"}, "exit_code": 0, "duration_ms": 1247, "request_id": "req-001", "trace_id": "abc123", "warnings": []}

Dry run under an over-privileged credential, inside an agent session

{"timestamp": "2026-03-17T14:05:22Z", "command": "delete", "args": {"resource_id": "r-42", "dry_run": true}, "exit_code": 0, "duration_ms": 8, "request_id": "req-002", "session_id": "s-1", "warnings": ["CREDENTIAL_OVER_PRIVILEGED"]}

Mutating stream: one entry for the whole run

{"timestamp": "2026-03-17T14:06:10Z", "command": "sync-users", "args": {"source": "users.csv"}, "exit_code": 0, "duration_ms": 412, "request_id": "req-005", "effects": {"created": 2, "noop": 1}, "warnings": []}

sync-users streamed three events (REQ-O-004); the entry repeats its summary line's effects instead of logging each event.

Large payload truncated to fit the entry cap

{"timestamp": "2026-03-17T14:07:00Z", "command": "import", "args": {"source": "s3://bucket/data.json", "raw_payload": "[TRUNCATED]"}, "exit_code": 0, "duration_ms": 5310, "request_id": "req-003", "warnings": [], "truncated": true}

Valid: passthrough command, forwarded argv omitted

{"timestamp": "2026-03-17T14:09:30Z", "command": "ingest", "args": {"argv": "[OMITTED]"}, "exit_code": 2, "duration_ms": 412, "request_id": "req-004", "warnings": []}

ingest hands its arguments to another tool's parser (REQ-C-031). Without a schema for them the framework cannot redact them, so it records none; exit_code 2 is the delegated tool's own.

Invalid: raw argv instead of the parsed map

{"timestamp": "2026-03-17T14:00:01Z", "command": "deploy", "args": ["--env", "prod", "--token", "abc123"], "exit_code": 0, "duration_ms": 1247, "request_id": "req-001", "warnings": []}

Violation: args must be an object. Raw argv cannot be redacted reliably and leaks the token.


Common mistakes

  • Logging raw argv. Redaction (REQ-F-034) works on named arguments; a positional token or --token=abc inside a string list slips through
  • Writing trace_id: null when TOOL_TRACE_ID is unset. Omit the field, as meta.trace_id does
  • Copying full warning objects. warnings holds codes only; message text is for humans and bloats every line
  • Truncating the serialized line. Cutting the JSON text produces an invalid line; replace values in args and set truncated
  • command differs from meta.command. The entry repeats meta.command exactly; a framework that answers config.set in meta.command must not log config set, or the reverse, and must not mix both spellings in one log

Agent interpretation

  • Join an entry to a response or trace by request_id or trace_id, never by timestamp
  • exit_code non-zero with args.dry_run or args.validate_only set means nothing was changed; the entry still shows what was attempted
  • truncated: true means some args values are [TRUNCATED]; do not replay the invocation from the entry
  • effects marks a mutating stream and counts its events; with a non-zero exit_code, the counts cover the events completed before the failure. An absent effects on an entry written before AuditLogEntry 1.1 means unknown, not zero
  • args.argv equal to [OMITTED] marks a passthrough command (REQ-C-031): the forwarded arguments were never written, and its exit_code is the delegated tool's, so a 2 does not rule out side effects
  • A [REDACTED] value is a declared secret; never try to recover it from other sources
  • warnings containing INJECTION_PROTECTION_DISABLED marks an invocation whose external data was returned untagged; treat its outputs as untrusted during review
  • An empty result from tool audit-log means no matching invocation was recorded while the log was enabled; a disabled log fails with AUDIT_LOG_DISABLED instead

Coding agent notes

Type representation - Generate args as a string-keyed map of JSON values, not as a typed struct; its keys are the command's argument names - Generate warnings as a list of strings and trace_id, session_id, effects, and truncated as optional fields that are omitted, not null - Generate effects as a string-keyed map of non-negative integers; its keys are effect values such as created or would_create

Construction - Build the entry from the same values the envelope factory writes to meta, after the exit code is known and before the response is emitted - Serialize once, check the byte length, and replace the largest args values with [TRUNCATED] until the line fits 16 KiB

Tests to generate - Every written line validates against audit-log-entry.json - A secret argument appears as [REDACTED] - A 50 MB argument yields one entry of at most 16 KiB with truncated: true


Implementation notes

  • additionalProperties: false keeps the entry shape predictable for tool audit-log filters and external log shippers; command-specific facts belong in args
  • The 16 KiB cap keeps each entry a single O_APPEND write well under common pipe and filesystem atomicity limits
  • The log file is created with mode 0600; entries still carry unredacted hostnames, ids, and paths
  • The entry is not wrapped in a ResponseEnvelope; the buffered tool audit-log answer (the default, or --no-stream when the command is streaming-default) returns entries inside data.entries of a normal envelope with meta.pagination

Document Relationship
REQ-O-030 Consumes: defines the audit log and the audit-log command that emit this type
REQ-C-031 Consumes: a passthrough command records its forwarded argv as [OMITTED]
schemas/response-envelope.md Provides: the meta values each entry repeats and the envelope around data.entries
§33 Observability & Audit Trail Sources: the failure mode this schema addresses