Use after every guardrail gate invocation — writes a structured JSONL record to .guardrails-audit.jsonl with timestamp, agentFamily, skill, check, result, detail, userStoryId, sessionId, and resolvedBy. Always-on; cannot be disabled.
How this skill is triggered — by the user, by Claude, or both
Slash command
/guardrails-coding-agent:audit-trailThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Fires on every guardrail gate invocation. Cannot be disabled.
Fires on every guardrail gate invocation. Cannot be disabled.
Records are appended to .guardrails-audit.jsonl (path overridable via audit.logFile).
gateResults — array of gate outcomes from all invoked skills in this sessionagentFamily — e.g., backend-coding-agentsessionId — unique ID for this session (generate if not provided: <agentFamily>-<timestamp>)userStoryId — from config or promptaudit.logFile (default: .guardrails-audit.jsonl)audit.commitAuditLog (default: false)audit.db.connectionString — pyodbc connection string for SQL Server dual-write (optional; omit to disable DB writes)audit.db.schema (default: guardrails) — SQL Server schema owning AuditLogaudit.db.tablePrefix (default: "") — optional prefix for table name{
"timestamp": "2026-03-17T10:23:00Z",
"agentFamily": "backend-coding-agent",
"skill": "output-validation",
"check": "test-coverage",
"result": "BLOCK",
"severity": "P1",
"detail": "Coverage 72% < threshold 85%",
"userStoryId": "PROJ-142",
"sessionId": "backend-coding-agent-20260317T102300Z",
"resolvedBy": "unresolved"
}
resolvedBy values (exhaustive enum)| Value | When to use |
|---|---|
human | A human reviewed and resolved the issue during this session |
auto-fix | autoFixP1 resolved it automatically (LSP fix or formatter) |
suppressed | Explicitly suppressed via harmPrevention.disabledPatterns with justification |
overridden | User provided an explicit override flag at invocation time |
unresolved | Session ended with the issue still open (default when status unknown) |
For each entry in gateResults:
Construct the record object with all fields above.
The severity field (P0–P3) is populated by error-escalation before passing gate results to audit-trail. If severity is absent from a gate result, default to P2.
Serialize to JSON (single line, no pretty-printing).
Append to audit.logFile with a newline.
DB write (SQL Server): If audit.db.connectionString is set, INSERT the record into [{audit.db.schema}].[{audit.db.tablePrefix}AuditLog] using pyodbc (ODBC Driver 18 for SQL Server). Use a 3-second connection timeout. Columns:
| Column | Value |
|---|---|
Timestamp | record timestamp (DATETIMEOFFSET) |
AgentFamily | record agentFamily |
Skill | record skill |
Check | record check (nullable) |
Result | record result |
Severity | record severity |
Detail | record detail (nullable) |
UserStoryId | record userStoryId (nullable) |
SessionId | record sessionId |
ResolvedBy | record resolvedBy |
Source | "skill" |
If the INSERT fails for any reason: emit P2 WARN "DB audit write failed: {error}" but do NOT block the guardrail action.
At session end:
audit.commitAuditLog: true: stage and commit the audit log file.If the audit log file is not writable (permissions, disk full): emit a P2 WARN to the user but do NOT block the guardrail action. Audit failure is non-blocking for both JSONL and DB destinations.
The run-guardrails-hook script also writes lightweight audit records at the hook layer:
session-start phase: logs a session-start event to AuditLog (JSONL + DB)pre-write phase: logs secrets-tripwire-blocked and diff-size-* events to AuditLog (JSONL + DB)stop phase: logs a session-stop event to AuditLog (JSONL + DB)Hook records use source: "hook" and skill: "hook" to distinguish them from skill-layer records (source: "skill").
The hook resolves session context in this order (first non-empty wins) so AuditLog rows are never NULL/"unknown" when the workspace has the artifacts available:
| Field | 1. Env var | 2. Derived from disk | 3. Fallback |
|---|---|---|---|
agentFamily | CLAUDE_AGENT_FAMILY | basename "$CLAUDE_PLUGIN_ROOT" | "unknown" |
userStoryId | CLAUDE_USER_STORY_ID | **ID:** <KEY>-<N> line in story-plan.md (or .claude/story-plan.md) | "" → DB NULL |
sessionId | CLAUDE_SESSION_ID | — | <agentFamily>-<UTC timestamp> |
CLAUDE_PLUGIN_ROOT is set by Claude Code for every plugin hook invocation, so agentFamily is always populated. userStoryId is only meaningful while a /story-implement run is in progress; outside that window it remains NULL by design.
npx claudepluginhub gagandeepp/software-agent-teams --plugin guardrails-coding-agentGuides completion of development work by verifying tests, detecting environment, and presenting structured options for merge, PR, or cleanup.
Enforces test-driven development: write failing test first, then minimal code to pass. Use when implementing features or bugfixes.
Guides creation and editing of skills using test-driven development with pressure scenarios and subagents to verify agent compliance.