Skip to main content
Every action an AI agent takes in Forge flows through the Trust Fabric, and every Trust Fabric evaluation leaves a permanent record. This is not optional instrumentation — it is a core architectural guarantee. The audit trail is append-only, meaning application code cannot modify or delete events after they are written. Data lifecycle is managed exclusively through TTL-based retention policies. For governed AI systems, traceability is not a nice-to-have. It is how you answer: What did this agent do? Who authorized it? What constraints were applied? What did it cost?

Traceability Record

Every agent action that passes through the Trust Fabric pipeline produces an 8-field traceability record (STD-03.3). These records are stored in the trustFabricEvents table and are available for ClickHouse ingestion for long-term analytics. The record captures the full context of what happened, who acted, what the governance pipeline decided, what it cost, and how to verify it:
FieldTypeDescription
traceIdstringUnique identifier for this trace. Format: {runId}:{stepId}:{timestamp}. Used for distributed trace correlation.
decisionRecordobjectThe governance pipeline outcome: which gates ran, whether each passed, the final disposition, and the policy version in effect.
governancePacketobjectAgent identity and governance metadata: agent ID, NHI credential ID, autonomy rung, owning team, risk tier, and fiduciary flag.
executionTraceobjectExecution details: tool calls made, intermediate outputs, and timing (start/end timestamps).
costAttributionobjectToken count, compute cost, virtual key used, and budget tier. Links to the token spend attribution chain.
toolCallLogToolCallEntry[]Detailed log of every tool invocation: endpoint, method, parameters, response code, latency.
explanationPacketobject (optional)When present: the agent’s reasoning and confidence indicators for the action taken.
auditRecordobjectTamper-evidence fields: content hash, timestamp, environment ID, and schema version.

Decision Record Structure

The decisionRecord captures every gate evaluation in the pipeline:
{
  gates: [
    { gate: "gatewayHealth", passed: true },
    { gate: "agentStatus", passed: true },
    { gate: "concurrency", passed: true },
    { gate: "agentBudget", passed: true },
    { gate: "trustLevel", passed: true },
    { gate: "policyRules", passed: false, errorCode: "policy_blocked" }
  ],
  disposition: "block",
  policyVersion: "2024-03-15T00:00:00Z"
}

Governance Packet Structure

The governancePacket ties every trace back to its agent identity and organizational context:
{
  agentId: "factory-manager-01",
  nhiId: "nhi:credential:abc123",
  autonomyRung: "supervised",
  owningTeam: "platform-ops",
  riskTier: "medium",
  fiduciaryFlag: false
}
The traceability record is emitted at dispatch time via emitTraceEvent with the governance decision already known. Cost and tool call data are backfilled after execution completes via enrichTraceEvent, which patches the original record by traceId lookup.

Governance Decision Audit

Every GovernanceDecision produced by the governance engine is persisted as an audit event in the auditEvents table with category governance and event type governance_decision. This happens on every dispatch attempt — whether the decision is allow, block, or hold. The persisted decision record includes:
FieldDescription
dispositionpass, block, or hold
dispatchTypestep, delegated_run, or launch
agentIdAgent that was evaluated
gatewayIdTarget gateway
gatesFull array of gate outcomes (pass/fail/skip per gate)
blockedByWhen blocked: gate name, error code, message, retryability
heldByWhen held: policy name, policy ID, trigger
budgetSnapshotAgent and envelope spend at decision time
trustSnapshotAgent trust level vs gateway minimum
durationMsEvaluation time in milliseconds
actorIdentityStructured identity envelope (actor type, actor ID)
Post-execution governance decisions are also persisted, capturing the outcome of post-execution hooks (budget state after cost accumulation, policy violation checks, alert triggers).

Dual Write Path

Governance decisions are written to two tables in parallel:
  1. auditEvents — The general-purpose append-only audit log. Queryable by run, category, resource, actor type, and time range. Supports full-text search on event names.
  2. governanceAuditLog — A governance-specific audit table with dedicated indexes for run, agent, and disposition queries. Includes the adminOverride flag and authoritySource field.
Both writes are fire-and-forget: errors are caught and logged so audit failures never block dispatch execution.

Admin Bypass Logging

When an administrator overrides governance controls (e.g., bypassing a budget gate or approving a blocked dispatch), the bypass is captured in the adminAuditLog table. This runs in the same transaction as the mutation — not fire-and-forget — guaranteeing that no admin bypass can occur without a corresponding audit record. Each admin bypass record captures:
FieldTypeDescription
timestampnumberWhen the bypass occurred
adminUserIdstringIdentity subject of the admin
adminEmailstring (optional)Email address of the admin
actionstringThe permission key that was bypassed
permissionKeystringThe specific permission (e.g., ops:manage, governance:override)
scopeTypestring (optional)Scope category (e.g., gateway, agent, workflow)
scopeTargetIdstring (optional)The specific resource affected
The adminAuditLog table is indexed by admin user, action, and timestamp — enabling queries like “show all overrides by this admin in the last 30 days” or “show all budget bypasses across the platform.”
Admin bypass logging is transactional. If the audit write fails, the bypass mutation also fails. This is a deliberate design choice: the system prefers failing the operation over allowing an unaudited override.

Distributed Tracing

Every governance evaluation generates a traceId with the format {runId}:{stepId}:{timestamp}. This identifier propagates through the full execution chain:
  1. Governance evaluationtraceId is generated when the governance pipeline starts
  2. Trace event emission — The initial trustFabricEvents record is written with the traceId
  3. Dispatch to gateway — The traceId accompanies the dispatch payload through Bridge
  4. Post-execution enrichment — When execution completes, enrichTraceEvent uses the traceId to locate and patch the original record with cost and tool call data
The trustFabricEvents table is indexed on traceId (by_trace), agentId + timestamp (by_agent), and disposition + timestamp (by_disposition). This supports three primary query patterns:
  • Point lookup: Find the complete trace for a specific dispatch by traceId
  • Agent timeline: Reconstruct a single agent’s full activity history ordered by time
  • Disposition analysis: Find all blocked or held dispatches across the platform

Retention Policy

Audit events follow a TTL-based retention policy enforced by daily cron jobs:
TableRetentionCron Schedule
auditEvents365 daysDaily at 03:15 UTC
trustFabricEventsUnlimited (ClickHouse ingestion)
adminAuditLogUnlimited
governanceAuditLogUnlimited
tokenEvents90 daysDaily at 03:00 UTC
The retention cron for auditEvents uses cursor-based pagination to avoid re-scanning previously cleaned records. Each run deletes up to 2,000 records with a 20-second time limit, storing the cursor in the retentionPolicies table for the next run.
The 365-day retention on auditEvents is designed to satisfy SOC 2 audit log requirements. The trustFabricEvents and governanceAuditLog tables have no TTL because they serve as the platform’s permanent compliance record and ClickHouse ingestion source.

Compliance Surface

The audit trail is designed to answer the questions that compliance reviews, incident investigations, and regulatory audits require:
What happened?

Every governance decision, approval, policy change, and agent action is recorded with full context in the append-only audit log.

Who authorized it?

Actor identity envelopes on every event. Admin bypasses captured transactionally with user ID and permission key.

What constraints applied?

Gate outcomes, policy evaluations, budget snapshots, trust levels, scope constraints, and role context — all captured at decision time.

Can it be verified?

Append-only guarantees (no update/delete mutations), content hashes in traceability records, and dual-write paths for cross-referencing.

Audit Event Categories

The auditEvents table uses a category system to organize events across domains:
CategoryEvents Captured
governanceGovernance decisions, policy CRUD, approval policy changes, position creation
safety_gateIndividual gate evaluation outcomes
workflowApproval creation, approval resolution, reminder delivery
lifecycleAgent stage transitions (requested, approved, rejected)
agent_execAgent execution events
routingGateway routing decisions
evaluationEvaluation run events

Query Capabilities

Audit events support multiple query patterns through dedicated indexes:
  • By run (by_run) — All events for a specific workflow run
  • By time range (by_time) — Events within a time window, with optional open-ended queries for live tailing
  • By category (by_category) — Events filtered by domain category within a time range
  • By resource (by_resource) — Events for a specific resource type and ID
  • By actor type (by_actorType) — Events filtered by actor type (human, agent, system, delegated_agent)
  • Full-text search (search_audit) — Text search across event names, filterable by category and actor type

Next Steps