Compliance and Audit
Track decisions, evidence, and approvals in a versioned graph that serves as a tamper-evident audit trail.
Regulated industries need to prove what happened, when, and why. Traditional audit logs are append-only text — searchable but not queryable, flat but not connected. A versioned knowledge graph gives you structure (typed entities and relationships), traceability (every change is versioned), and discoverability (graph queries over audit data).
The ontology
node Policy {
slug: String @key
title: String @index
body: String @index
category: enum(data_privacy, security, financial, operational, hr)
status: enum(draft, active, superseded, retired)
effective_date: Date
review_date: Date?
owner: String
embedding: Vector(768) @index
}
node Control {
slug: String @key
name: String @index
description: String
framework: enum(soc2, iso27001, gdpr, hipaa, pci_dss, internal)
category: enum(access, encryption, monitoring, incident, data_handling, vendor)
status: enum(implemented, partial, planned, not_applicable)
}
node Evidence {
slug: String @key
title: String @index
type: enum(screenshot, config_export, log_extract, attestation, test_result, document)
collected_by: String
collected_at: DateTime
valid_until: Date?
body: String?
}
node Risk {
slug: String @key
title: String @index
description: String
severity: enum(critical, high, medium, low)
likelihood: enum(almost_certain, likely, possible, unlikely, rare)
status: enum(identified, assessed, mitigating, accepted, closed)
identified_at: Date
owner: String
}
node Decision {
slug: String @key
title: String @index
body: String?
type: enum(approval, exception, risk_acceptance, policy_change, access_grant)
decided_by: String
decided_at: DateTime
rationale: String
}
node Vendor {
slug: String @key
name: String @index
category: enum(cloud, saas, data_processor, sub_processor, consultant)
risk_tier: enum(critical, high, medium, low)
last_reviewed: Date?
}
// Structure
edge Implements: Control -> Policy
edge Satisfies: Evidence -> Control
edge Mitigates: Control -> Risk
edge Addresses: Decision -> Risk
edge Governs: Policy -> Vendor
edge ApprovedBy: Decision -> Policy
edge RaisedBy: Risk -> Vendor
edge References: Decision -> EvidenceRead this and you see the compliance graph: policies define rules, controls implement them, evidence satisfies controls, risks are identified and mitigated, decisions are made with rationale and evidence, vendors are governed by policies.
Queries auditors ask
Control coverage
"Which controls lack current evidence?"
query controls_without_evidence() {
match {
$c: Control { status: "implemented" }
not {
$e satisfies $c
}
}
return {
$c.name, $c.framework, $c.category
}
}[
{
"name": "Quarterly access review",
"framework": "soc2",
"category": "access"
},
{
"name": "Encryption at rest verification",
"framework": "pci_dss",
"category": "encryption"
}
]An evidence collection agent reads this and knows exactly which controls need attention.
Risk to policy traceability
"Show me the complete chain from this risk to the policies that govern it."
query risk_governance_chain($risk: String) {
match {
$r: Risk { slug: $risk }
$c mitigates $r
$c implements $p
$e satisfies $c
}
return {
$r.title, $r.severity, $r.status,
$c.name as control, $c.framework,
$p.title as policy, $p.status as policy_status,
$e.title as evidence, $e.collected_at, $e.valid_until
}
}[
{
"title": "Unauthorized data access via vendor API",
"severity": "high",
"status": "mitigating",
"control": "Vendor API key rotation",
"framework": "soc2",
"policy": "Third-party data access policy",
"policy_status": "active",
"evidence": "API key rotation log - Q1 2026",
"collected_at": "2026-03-15T10:00:00",
"valid_until": "2026-06-15"
}
]One query. Full chain from risk to control to policy to evidence. An auditor can trace any risk to its mitigation in seconds.
Decision audit trail
"What decisions were made about this risk, by whom, and what evidence supported them?"
query decision_trail($risk: String) {
match {
$r: Risk { slug: $risk }
$d addresses $r
$d references $e
}
return {
$d.title, $d.type, $d.decided_by,
$d.decided_at, $d.rationale,
$e.title as evidence, $e.type as evidence_type
}
order { $d.decided_at desc }
}Every decision is a node. Every decision links to the evidence that informed it. Every decision has a rationale. This is the audit trail that regulators ask for.
Vendor risk assessment
"Which critical vendors haven't been reviewed recently?"
query overdue_vendor_reviews() {
match {
$v: Vendor { risk_tier: "critical" }
$r raisedBy $v
$r.status != "closed"
}
return {
$v.name, $v.category, $v.last_reviewed,
$r.title as open_risk, $r.severity
}
order { $v.last_reviewed asc }
}Policy similarity search
"Which policies are relevant to this new regulation?"
query relevant_policies($regulation_text: Vector(768)) {
match {
$p: Policy { status: "active" }
}
return { $p.title, $p.category, $p.effective_date, $p.owner }
order { nearest($p.embedding, $regulation_text) }
limit 10
}When a new regulation drops, embed its text and find which existing policies are most relevant. An agent can then diff the regulation against each policy and flag gaps.
Why versioning is the killer feature
Compliance isn't just about the current state. It's about proving the state at any point in time.
Every version of the graph is queryable via Omnigraph's time-travel API. What was the risk posture six months ago? What controls were added after the last audit? What evidence expired and wasn't renewed? The answers are in the graph's history — not in a separate audit log you have to cross-reference manually.
Branch-based approval workflows
Policy changes follow an approval workflow:
- Compliance agent proposes a policy update on a branch (e.g.,
policy/update-data-privacy-2026q2) - The agent writes the updated
Policynode and creates aDecisionnode withtype: "policy_change"and rationale - Legal reviews the diff:
Policy.bodychanged, newControladded, newEvidencerequired - Legal approves → merge to main. Or: legal requests changes → agent updates on the branch
The branch is the approval workflow. The diff is the review artifact. The merge is the approval. No separate ticketing system needed.
What you can build from here
- Continuous compliance monitoring — An agent that runs coverage queries daily, flags expiring evidence, and creates collection tasks automatically.
- Framework mapping — Map controls across frameworks (SOC2, ISO 27001, GDPR). Add
MapsTo: Control -> Controledges. One control can satisfy multiple frameworks. - Audit preparation agent — Given an upcoming audit scope, traverse the graph to assemble the complete evidence package: controls, evidence, decisions, and policy chain.
- Regulatory change impact — When regulations change, embed the new text, find relevant policies, diff against requirements, and surface gaps as new
Risknodes with proposedControlmitigations.