← 2.1.16 Test tested · runtime-test

Combo Test: Task Metadata for Audit Trails — runtime test

Hands-on runtime battle-test of Combo Test: Task Metadata for Audit Trails. Result: PASS.

Task metadata field enables runtime audit trails by storing and merging arbitrary JSON structures across create and update operations.

How It Works

The metadata field in Claude Code's task API accepts any JSON object at creation and update time. When creating a task, metadata is stored directly in the task's underlying JSON file (~/.claude/tasks/{session-id}/{task-id}.json). On updates, metadata merges with existing values rather than replacing them: fields not mentioned in the update are preserved, matching fields are replaced, and new fields are added.

This design supports audit patterns where agents append to event arrays, add timestamps, or track state changes without clobbering prior entries.

What the Test Found

The runtime test created a task with initial metadata {"created_at": "2026-01-22T23:40:00Z", "audit_log": ["task created"]}, then updated it with {"audit_log": [...], "last_update": "..."}. The JSON file inspection confirmed that created_at was preserved, audit_log was replaced with the new array, and last_update was added—validating the merge semantics. Metadata storage itself is fully working and extensible.

A key limitation emerged: TaskGet does not display metadata in the CLI, so audit trails must be read via direct JSON file access. This is not a storage bug but an API visibility gap.

Why It Matters

Audit trails are critical for agent runtime debugging and compliance. By storing rich context—event sequences, timestamps, decision chains—in task metadata, agents can reason about task history without external persistence. The merge semantics mean agents can append events incrementally and add context in layers without coordination.

Caveats

The recommended pattern requires agents to handle array updates carefully: updating metadata replaces arrays rather than appending, so agents must read current metadata, modify it, and write it back to accumulate events. No built-in timestamp generation means agents must add ISO dates manually. And metadata visibility through the CLI is absent, requiring workarounds for human inspection or subagent helpers for programmatic access.

Primary source
⎘ 2.1.16/tests/combo-03-task-metadata/TEST-RESULTS.mdverbatim from the corpus

Combo Test: Task Metadata for Audit Trails

Hypothesis

Task metadata field can store arbitrary structured data, enabling audit trails.

Test Results

Test 1: Initial Metadata on Create

TaskCreate with metadata: {"created_at": "...", "audit_log": ["task created"]}

Result: ✅ PASS - Metadata stored in JSON file

Test 2: Metadata Visibility

TaskGet for task with metadata

Result: ⚠️ PARTIAL - TaskGet does NOT display metadata, but it's in the JSON file

Test 3: Metadata Update with Merge

TaskUpdate with metadata: {"audit_log": [...], "last_update": "..."}

Result: ✅ PASS - Metadata MERGES (doesn't replace)

  • Preserved: created_at (wasn't in update)
  • Updated: audit_log (replaced with new array)
  • Added: last_update (new field)

Test 4: Raw JSON Inspection

Storage: ~/.claude/tasks/{session-id}/{task-id}.json Schema:

{
  "id": "19",
  "subject": "...",
  "description": "...",
  "activeForm": "...",
  "status": "pending",
  "blocks": [],
  "blockedBy": [],
  "metadata": {
    "created_at": "2026-01-22T23:40:00Z",
    "audit_log": ["task created", "work started 23:41"],
    "last_update": "2026-01-22T23:41:00Z"
  }
}

Key Findings

  1. Metadata is fully extensible - store any JSON structure
  2. Merge on update - partial updates don't clobber existing keys
  3. Not visible via TaskGet - need to read JSON directly for metadata
  4. Audit trail viable - append to arrays, add timestamps, track changes

Workflow Validation

Status: ✅ VALIDATED with caveats

The audit trail workflow works but requires:

  • Direct JSON file reads to see metadata (or subagent helper)
  • Careful array handling (update replaces arrays, doesn't append)
  • No built-in timestamps (must add manually)

Recommended Pattern

# On task creation
metadata: {"created": "ISO_DATE", "events": []}

# On significant action
# Read current metadata → append to events → write back
# Or use merge: {"last_event": "description", "updated": "ISO_DATE"}
Evidence & receipt
◇ ed25519 receipt
idtest_5101432a1226ca1d45401540
alged25519
pubkey9b87705613b1e2fd064d57fa75a6b679d2856ceafad6b1daa8f982493871b6dd
siged1e322c36fe3c081b8756e5bd4b9d9c68ac68f76c34656f2b5b6ca96fb54538d484a8fa47b530150c64d76b00754d9f9df0eabb0ed04777b49d6d7ada38260c

Signed with an ed25519 key held off the repo. Anyone can verify against the published public key; nobody without the secret key can forge it. Click verify: it recomputes the signature in your browser. The signature proves integrity and authorship of this exact content — not a third-party timestamp or that the underlying claim is objectively true. signedAt is when the @f3/attest pipeline ran, not when the work happened; the evidence refs carry the source dates.

Connected