Skip to content

feat: PreToolUse hook recipe for reliable session-start audit logging #3

@dernerl

Description

@dernerl

Problem

The audit-logging skill instructs the AI agent to write a session-start event at the beginning of every session. In practice, this is unreliable — the agent sometimes skips it, which creates gaps in the audit trail (days with active sessions but no log entries).

The skill works correctly when it fires, but it depends entirely on the agent proactively executing the boot sequence. There is no enforced mechanism.

Observed behaviour

  • Local audit files (~/.compliance/audit/YYYY-MM-DD.jsonl) only exist for days where the agent happened to write the event
  • Gaps of multiple days are common even with daily Claude Code usage
  • The Azure sync (Stop hook) works fine — the missing piece is the local write at session start

Proposed fix

Document a PreToolUse hook in the audit-logging skill (or a dedicated setup section) that writes the session-start event automatically, without relying on the agent's memory:

// .claude/settings.json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "bash $HOME/.compliance/hooks/session-start.sh"
          }
        ]
      }
    ]
  }
}
# ~/.compliance/hooks/session-start.sh
#!/usr/bin/env bash
TODAY=$(date +%Y-%m-%d)
LOG="$HOME/.compliance/audit/${TODAY}.jsonl"
mkdir -p "$(dirname "$LOG")"

# Only write once per day
if grep -q '"activity":"start"' "$LOG" 2>/dev/null; then exit 0; fi

EVENT_ID=$(python3 -c "import uuid; print(uuid.uuid4())")
TRACE_ID=$(python3 -c "import secrets; print(secrets.token_hex(16))")
TS=$(python3 -c "from datetime import datetime,timezone; print(datetime.now(timezone.utc).isoformat())")
echo "{\"event_id\":\"$EVENT_ID\",\"timestamp\":\"$TS\",\"trace_id\":\"$TRACE_ID\",\"event_class\":\"session\",\"activity\":\"start\",\"severity\":\"INFO\",\"outcome\":\"success\",\"summary\":\"Session started\"}" >> "$LOG"

This makes audit coverage deterministic and removes the dependency on agent behaviour.

Why this matters

For NIS2/ISO 27001 compliance, continuous audit coverage is a requirement — not best-effort. An agent that "usually" logs is not sufficient for audit purposes.

Willingness to contribute

Happy to submit a PR with the hook script and updated audit-logging/SKILL.md documentation once there is agreement on the approach.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions