---
title: AgentLog Event Schema
created: 2026-05-06
type: system
---

# AgentLog Event Schema

Single source of truth for cross-cutting event log at `_System/AgentLog/events.ndjson` (NDJSON — one JSON object per line, append-only).

Foundation for cost tracking (Wave 2.1), skill execution log (Wave 2.2), and forensics ("who did what, when").

---

## File: `_System/AgentLog/events.ndjson`

Append-only. New events go to end of file. Never edit prior events. Diff is always +N lines, never -N.

## Per-event schema

```json
{
  "ts": "2026-05-06T13:42:00Z",
  "agent": "claude-code-opsman",
  "action": "skill_run",
  "target": "lfcs-job-scaffold",
  "result": "ok",
  "notes": "2629 Erskine Park scaffolded"
}
```

### Fields

| Field | Required | Type | Notes |
|---|---|---|---|
| `ts` | yes | ISO8601 UTC | always `Z` suffix, never local timezone |
| `agent` | yes | string | see Agent identities below |
| `action` | yes | string | see Action types below |
| `target` | yes | string | path / skill name / job ID / "" |
| `result` | yes | enum | `ok` / `fail` / `warn` |
| `notes` | no | string | free-text, optional |
| `cost_usd` | no | number | reserved for Wave 2.1 cost tracking |
| `ms` | no | number | reserved for runtime tracking |

Future fields can be added without breaking older readers — JSON readers ignore unknown keys.

---

## Agent identities

| Identity | Source |
|---|---|
| `claude-code-opsman` | desk-side PM (Rocky's local + SSH to VPS) |
| `claude-code-coo` | cross-cutting system agent |
| `claude-code-rr` | RateRight codebase scope |
| `cowork-lfcs` | Claude Desktop, LFCS scope |
| `cowork-hq` | Claude Desktop, HQ vault curation |
| `cowork-curator` | Claude Desktop, mechanical curator |
| `hermes` | VPS daemon (LFCS site bot) |
| `rocky` | human edits |
| `cron:vault-health` | scheduled VPS task |
| `cron:vault-curator` | scheduled VPS task |
| `cron:auto-sync` | scheduled VPS task |
| `system` | unattributed system events |

---

## Action types

| Action | When |
|---|---|
| `commit` | git commit landed |
| `push` | git push landed |
| `cron_run` | scheduled task completed (success or fail captured in `result`) |
| `skill_run` | a skill executed (lfcs-*, hunt, matchmaker, etc.) |
| `file_write` | non-trivial vault content write |
| `file_archive` | file moved to `_Archive/` |
| `file_move` | within-vault rename/move |
| `decision` | human decision recorded (Q&A answer, gate flip) |
| `gate_block` | a gate (vault-verify, append-only, cron) refused work |
| `escalate` | agent punted to human |

---

## Emission

### From bash (existing scripts)

```bash
"$REPO_ROOT/scripts/log-event.sh" "cron:vault-health" "cron_run" "HealthLog.md" "ok" "daily probe complete"
```

The helper handles JSON-escaping, ISO timestamps, and concurrent-write locking. Failure to emit doesn't break the calling script.

### From python

```python
import json, time, fcntl, os
ev = {"ts": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
      "agent": "cron:vault-curator", "action": "cron_run",
      "target": "vault-curator.py", "result": "ok", "notes": f"queued {n} items"}
with open("HQ-Vault/_System/AgentLog/events.ndjson", "a") as f:
    fcntl.flock(f, fcntl.LOCK_EX)
    f.write(json.dumps(ev) + "\n")
```

### From Claude Code commits

Not yet automated. For now, landed commits are reflected via `git log` — same forensic answer, different surface. Wave 2.1 may add a post-commit hook.

---

## Querying

```bash
# All events from claude-code-opsman this week
jq -c 'select(.agent=="claude-code-opsman" and .ts > "2026-04-29")' events.ndjson

# All gate blocks (forensics)
jq -c 'select(.action=="gate_block")' events.ndjson

# Daily run-rate per agent
jq -r '.agent' events.ndjson | sort | uniq -c | sort -rn

# Total events
wc -l events.ndjson
```

---

## Append-only enforcement

`auto-sync.sh`'s `check-append-only.sh` gate matches `_AgentLog/.*\.md$` only — does NOT cover `events.ndjson`. Append-only is enforced by convention + this schema. Future tightening: extend gate to include `events.ndjson`.
