From ghengis-skills
Use when building autonomous workflows that need accountability -- provides an immutable hash-chained audit trail pattern for tracking what agents did, when, and why, with tamper detection
How this skill is triggered — by the user, by Claude, or both
Slash command
/ghengis-skills:audit-ledgerThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Immutable, hash-chained audit trail for agent workflows. Every significant action gets a ticket. Each entry includes the hash of the previous entry, creating a tamper-proof chain. If anyone modifies or deletes an entry, the chain breaks and verification detects it.
Immutable, hash-chained audit trail for agent workflows. Every significant action gets a ticket. Each entry includes the hash of the previous entry, creating a tamper-proof chain. If anyone modifies or deletes an entry, the chain breaks and verification detects it.
This is an accountability methodology, not a library. Apply it by maintaining structured log files alongside your work in Claude Code sessions, multi-agent workflows, or any autonomous pipeline where you need to answer: what happened, who did it, and why.
Record every action that changes state or has external consequences:
Skip entries for internal processing noise that does not affect outcomes:
Rule of thumb: If you would want to know about it during a post-mortem, record it. If it is implementation plumbing, skip it.
Every entry includes prev_hash -- the SHA-256 hash of the previous entry. This creates an append-only chain where modifying or removing any entry breaks all subsequent hashes.
Entry 1: prev_hash = "0000...0000" (genesis) --> hash(entry1) = "a1b2..."
Entry 2: prev_hash = "a1b2..." --> hash(entry2) = "c3d4..."
Entry 3: prev_hash = "c3d4..." --> hash(entry3) = "e5f6..."
If Entry 2 is modified after the fact, its hash changes, which means Entry 3's prev_hash no longer matches -- the chain is broken. Verification walks the chain and detects the first break point.
Hash the full JSON representation of each entry with deterministic key ordering:
hash = SHA-256(JSON.stringify(entry, sorted_keys=true))
The genesis entry (first entry in the ledger) uses a prev_hash of 64 zeros: "0000000000000000000000000000000000000000000000000000000000000000".
Each ledger entry is a single JSON object with these fields:
{
"ticket_id": "uuid-v4",
"prev_hash": "sha256-of-previous-entry",
"timestamp": "2026-04-07T14:32:01.123Z",
"chain_id": "session-or-workflow-id",
"goal_id": "optional-goal-or-task-id",
"agent_name": "builder",
"action": "tool_call",
"detail": "Wrote 47 lines to src/auth.ts implementing JWT validation",
"tool_name": "write_file",
"cost_usd": 0.003,
"tokens": 1240,
"status": "success",
"duration_ms": 342
}
| Field | Type | Required | Description |
|---|---|---|---|
ticket_id | string (UUID) | yes | Unique identifier for this entry |
prev_hash | string (hex) | yes | SHA-256 hash of the previous entry (64 zeros for genesis) |
timestamp | string (ISO 8601) | yes | When the action occurred, UTC |
chain_id | string | yes | Groups entries by session, workflow, or conversation |
goal_id | string | no | Links entry to a specific goal or task |
agent_name | string | yes | Which agent or role performed the action |
action | string | yes | Action type (see Action Types below) |
detail | string | yes | Human-readable description, max 500 chars |
tool_name | string | no | Name of tool invoked, if applicable |
cost_usd | number | no | Cost of the operation in USD |
tokens | integer | no | Tokens consumed by the operation |
status | string | no | Outcome: success, error, partial, skipped |
duration_ms | integer | no | Wall-clock duration in milliseconds |
| Action | Use For |
|---|---|
route | Request routed to a department or agent |
tool_call | Tool executed (file write, API call, shell command) |
delegate | Work delegated to a subagent |
complete | Task or goal completed |
fail | Task or step failed |
decision | Routing or strategy decision made |
state_change | Configuration or mode transition |
Start a new file each day. Name files by date in ISO format:
ledger/
2026-04-05.jsonl
2026-04-06.jsonl
2026-04-07.jsonl
Each file contains one JSON entry per line (JSONL format). The hash chain spans across files -- the first entry of a new day references the last entry of the previous day.
Walk the chain from the beginning and verify each entry's prev_hash matches the computed hash of the preceding entry.
prev_hash = "0000...0000" (64 zeros)
total = 0
valid = 0
first_break = null
for each file in sorted(ledger/*.jsonl):
for each line in file:
entry = parse_json(line)
total += 1
expected_prev = prev_hash
if entry.prev_hash == expected_prev:
valid += 1
else if first_break is null:
first_break = { file, line_number, entry_number: total }
prev_hash = SHA-256(JSON.stringify(entry, sorted_keys=true))
result = {
valid: first_break is null AND total > 0,
entries_checked: total,
valid_links: valid,
first_break: first_break
}
| Break Pattern | Likely Cause |
|---|---|
| Single break at entry N, rest valid | Entry N-1 was modified after the fact |
| Break at entry N, all subsequent broken | Entry N or earlier was deleted or inserted |
| Multiple scattered breaks | File was manually edited or entries were reordered |
| First entry breaks | Genesis entry was modified or prev_hash was not set to zeros |
The JSONL format supports grep-based querying for quick lookups. For structured queries across large ledgers, maintain a parallel index.
# All entries from today
cat ledger/2026-04-07.jsonl
# Entries between specific times
grep '"timestamp":"2026-04-07T1[4-6]' ledger/2026-04-07.jsonl
grep '"agent_name":"builder"' ledger/*.jsonl
grep '"goal_id":"refactor-auth-module"' ledger/*.jsonl
grep '"action":"fail"' ledger/*.jsonl
# Extract all cost values and sum them
grep -o '"cost_usd":[0-9.]*' ledger/2026-04-07.jsonl
For more complex queries (aggregations, joins, time-series), load the JSONL into a SQLite table or use jq:
# Total cost per agent today
cat ledger/2026-04-07.jsonl | jq -s 'group_by(.agent_name) | map({agent: .[0].agent_name, total_cost: (map(.cost_usd) | add)})'
# All failed actions with their details
cat ledger/2026-04-07.jsonl | jq 'select(.status == "error")'
At the beginning of a multi-step task or autonomous workflow, create a ledger file and record the genesis entry:
{"ticket_id":"a1b2c3d4","prev_hash":"0000000000000000000000000000000000000000000000000000000000000000","timestamp":"2026-04-07T14:00:00Z","chain_id":"session-001","goal_id":"refactor-auth","agent_name":"orchestrator","action":"route","detail":"Starting auth module refactor -- decomposed into research, build, validate","tool_name":null,"cost_usd":0,"tokens":0,"status":"success","duration_ms":0}
After each significant action, append an entry. In multi-agent cascades, each agent appends its own entries with the same chain_id.
When something goes wrong, the ledger answers:
agent_namedetail field for contextcost_usd across entriesSum cost_usd and tokens across entries to understand where budget went:
Total session cost: $0.47
researcher: $0.12 (25%)
builder: $0.28 (60%)
validator: $0.07 (15%)
| Pattern | How It Uses the Ledger |
|---|---|
| OORT Cascade | Each role appends entries; validator checks the chain before accepting |
| Compute Adaptation | Tier changes are recorded as state_change entries |
| Constitutional AI | Violations are recorded with action: "fail" and the rule ID in detail |
| Goal Tracking | Goals reference goal_id; completion entries mark goal resolution |
| Deep Research | Each research phase appends entries; iteration count tracked via chain |
| If you notice... | The problem is... | Fix it by... |
|---|---|---|
| Hundreds of entries per minute | Recording too granularly | Only recording state-changing actions |
All entries have cost_usd: 0 | Not tracking costs | Estimating cost from token counts and model tier |
detail field is always the same template | Not providing useful context | Writing specific descriptions of what changed and why |
No fail entries in a long session | Not recording failures | Recording errors, timeouts, and retries |
| Chain verification never runs | Ledger exists but is not trusted | Running verification at session end or before audits |
Entries have no goal_id | Cannot trace actions to objectives | Assigning goal IDs when goals are created |
npx claudepluginhub kgan01/ghengis-skills --plugin ghengis-skillsRecords agent run tool calls, decisions, inputs, outputs, token use, and approval steps as repeatable evidence for debugging, auditing, cost review, or release decisions.
Records audit logs of user inputs (verbatim), agent actions, phase transitions, and gate decisions with ISO 8601 timestamps. Supports SOC2/ISMS-P retention policies (30/90/365 days) per project.
View audit logs, decision traces, and session history for AI transparency. Supports log, trace, summary, and search subcommands.