Skip to content

spanforge.core.compliance_mapping

Programmatic compliance testing via the public spanforge.compliance facade: v1.0 compatibility checks, audit chain integrity verification, and multi-tenant isolation testing.

All compliance functions can be called directly without pytest.

See the Compliance User Guide for usage examples.


Compatibility checker

CompatibilityViolation

@dataclass(frozen=True)
class CompatibilityViolation:
    check_id: str
    rule: str
    detail: str
    event_id: str

A single compliance non-conformance found during a check.

Attributes:

AttributeTypeDescription
check_idstrNumeric code, e.g. "CHK-1".
rulestrShort description of the rule violated.
detailstrHuman-readable description of the specific problem.
event_id`strNone`

CompatibilityResult

@dataclass
class CompatibilityResult:
    passed: bool
    events_checked: int
    violations: List[CompatibilityViolation]

Result of a compatibility compliance check across a batch of events.

Evaluates as True in a boolean context only when passed=True.

Attributes:

AttributeTypeDescription
passedboolTrue only when zero violations are found.
events_checkedintNumber of events that were inspected.
violationsList[CompatibilityViolation]Full list of violations.

test_compatibility(events: Sequence[Event]) -> CompatibilityResult

Apply the spanforge v1.0 compatibility checklist to events.

Checks performed:

Check IDRule
CHK-1Required fields (schema_version, source, payload) are present and non-empty.
CHK-2event_type uses a registered namespace or valid x.* custom prefix.
CHK-3source matches the <service>@<semver> pattern.
CHK-5event_id is a valid 26-character ULID.

Args:

ParameterTypeDescription
eventsSequence[Event]One or more Event instances to inspect.

Returns: CompatibilityResult

Example:

from spanforge.compliance import test_compatibility

result = test_compatibility(my_events)
if not result:
    for v in result.violations:
        print(f"[{v.check_id}] {v.rule}: {v.detail}")

Audit chain integrity

ChainIntegrityViolation

A single chain integrity violation (broken prev_id link, tampered signature, or non-monotonic timestamp).

ChainIntegrityResult

Result of verify_chain_integrity(). Evaluates as True only when no violations were found.

Attributes: passed, chain_result, violations, events_verified, gaps_detected.


verify_chain_integrity(events: Sequence[Event], org_secret: str, *, check_monotonic_timestamps: bool = True) -> ChainIntegrityResult

Verify the structural integrity of an ordered event chain.

Checks:

  • Each event's prev_id points to the preceding event's event_id.
  • Timestamps are monotonically non-decreasing.
  • No gaps in the chain.

Args:

ParameterTypeDescription
eventsSequence[Event]Ordered list of events (oldest first).
org_secretstrHMAC key used when the chain was signed.
check_monotonic_timestampsboolWhen True (default), also check that timestamps are non-decreasing.

Returns: ChainIntegrityResult


Multi-tenant isolation

IsolationViolation

A single isolation violation found during tenant boundary checking.

IsolationResult

Result of verify_tenant_isolation() or verify_events_scoped(). Evaluates as True only when no violations were found.

Attributes: passed, violations.


verify_tenant_isolation(group_a: Sequence[Event], group_b: Sequence[Event], *, strict: bool = False) -> IsolationResult

Verify that events from two tenant groups do not share org_id values.

Args:

ParameterTypeDescription
group_aSequence[Event]First tenant's events.
group_bSequence[Event]Second tenant's events.
strictboolWhen True, events with org_id=None are also flagged as violations.

Returns: IsolationResult


verify_events_scoped(events: Sequence[Event], *, expected_org_id: str | None = None, expected_team_id: str | None = None) -> IsolationResult

Verify that all events in events carry the expected scope values.

Useful for asserting that a batch of events belongs to a single organisation or team.

Args:

ParameterTypeDescription
eventsSequence[Event]Events to check.
expected_org_idstr | NoneExpected organisation ID, or None to skip the org check.
expected_team_idstr | NoneExpected team ID, or None to skip the team check.

Returns: IsolationResult


Compliance Mapping Engine

ComplianceMappingEngine

Maps spanforge telemetry events to regulatory framework clauses and generates evidence packages with gap analysis and HMAC-signed attestations.

from spanforge.compliance import ComplianceMappingEngine

engine = ComplianceMappingEngine()

ComplianceAttestation

@dataclass
class ComplianceAttestation:
    model_id: str
    framework: str
    from_date: str
    to_date: str
    total_events: int
    clauses_covered: int
    clauses_total: int
    coverage_pct: float
    gaps: list[str]
    attestation_id: str
    timestamp: str
    signature: str
    model_owner: str | None
    model_risk_tier: str | None
    model_status: str | None
    model_warnings: list[str]
    explanation_coverage_pct: float | None

Key attributes:

AttributeTypeDescription
model_ownerstr | NoneOwner from ModelRegistry, or None if unregistered.
model_risk_tierstr | NoneRisk tier from ModelRegistry (e.g. "high", "low").
model_statusstr | NoneModel status: "active", "deprecated", or "retired".
model_warningslist[str]Warnings for deprecated, retired, or unregistered models.
explanation_coverage_pctfloat | NonePercentage of decision events with matching explanation.* events.

generate_evidence_package(model_id, framework, from_date, to_date, audit_events=None) -> ComplianceEvidencePackage

Generate a complete evidence package for a regulatory framework.

Args:

ParameterTypeDescription
model_idstrAI model identifier (e.g. "gpt-4o").
frameworkstrOne of: eu_ai_act, iso_42001, nist_ai_rmf, gdpr, soc2, hipaa.
from_datestrStart of audit period (ISO-8601).
to_datestrEnd of audit period (ISO-8601).
audit_eventslist[dict] | NoneEvents to analyse; omit to load from TraceStore.

Returns: ComplianceEvidencePackage — contains framework, model_id, mappings, gap_report, and attestation.

Clause-to-event-prefix mapping

FrameworkClauseEvent prefixes
GDPRArt. 22consent.*, hitl.*
GDPRArt. 25llm.redact.*, consent.*
EU AI ActArt. 13explanation.*
EU AI ActArt. 14hitl.*, consent.*
EU AI ActAnnex IV.5llm.guard.*, llm.audit.*, hitl.*
SOC 2CC6.1llm.audit.*, llm.trace.*, model_registry.*
NIST AI RMFMAP 1.1llm.trace.*, llm.eval.*, model_registry.*, explanation.*