Last verified: 28 September 2026

Audit Log Disclosure

Every audit event type we record and how long we retain it, auto-projected from the canonical registry. The append-only hash chain ensures no prior record can be silently mutated.

Hash-chain invariant

Every row in the audit log carries entry_hash = SHA-256(prev_hash ∥ canonical_row_jcs) computed inside the audit_record() SECURITY DEFINER function. A single-row mutation breaks the chain from that point forward. verifyAuditChainSegment() recomputes the chain; attestAuditChainIntegrity() substrate-attests the verification result (requires compliance-operator capability).

Restoration via restoreAuditChainFromBackup() NEVER mutates prior segments. It appends a new audit_chain_segments row whose prior_segment_terminal_hash links to the superseded segment. Restoration requires 2-of-2 attestation from distinct custody-operator and resolution-operator principals (§ZA-ii, G4).

Retention classes

Generated from lib/registry/audit-retention-classes-registry.ts · 4 closed classes (§ZA-iii, G5 — adding a 5th class requires a §Z amendment)

Per-jurisdictional compliance frameworks (§GG) may raise retention above the baseline via ComplianceFramework.auditRetentionMinDays. Frameworks set minimums, never reduce. expires_at = max(class baseline, jurisdictional floor) is computed at insert time inside audit_record().

short — Short (90 days)

Ephemeral operational events (auth flows, session events). Regulatory floor rarely exceeds 90 days for this class; GDPR Article 30 does not mandate retention for purely transient system events.

retention: 90 days · since: ZA-iii

medium — Medium (1 year)

Standard operational audit trail (identity changes, commerce lifecycle, integrity checks). Matches common EU/UK GDPR data-minimisation guidance for business-process audit records.

retention: 365 days · since: ZA-iii

long — Long (7 years)

Governance and regulatory events (organisation creation, stewardship grants, data subject requests, substrate-operator attestations). Matches EU VAT directive + DORA + NIS2 minimum retention floors for business-critical records. 2555 days = 7 × 365 days (leap-year rounding per telemetry-pattern).

retention: 2555 days · since: ZA-iii

permanent — Permanent (never expires)

Chain-structural events that must never be deleted: audit chain restoration anchors and partition-archival attestations. Sentinel value -1 maps to expires_at = NULL in audit_log. These rows outlive any partition-drop cycle.

retention: never expires (permanent) · since: ZA-iii

Personal data in audit payloads

Every audit event type declares a PII posture from the closed set none / anonymized / personal-retained. Kinds marked personal-retained deliberately keep direct personal data (raw email address, client IP) in the audit payload for forensic traceability — an explicit owner decision (OWNER-6). Every personal-retained kind is bound to a non-permanent retention class, so the personal data expires with the row; access is gated by row-level security (auth-tier rows are readable only by the service tier and substrate operators; org-scoped rows only by members of the owning org).

8 event type(s) currently declare personal-retained; 1 declare anonymized. The per-kind posture is listed with each event type below.

Audit event types

Generated from lib/registry/audit-event-types-registry.ts · 164 registered event types

Every event type written to audit_log.event_type is registered below with its retention class. guard:audit-event-retention-class-declared (BLOCKING-from-day-one) enforces no unregistered event type can be introduced without declaring a retention class from the closed 4-value enum (§ZA-iii, G5).

auth.login

User authenticated successfully (post-callback). V1-SEC-007 / OWNER-6: login audit payloads deliberately retain the raw email (federated-routing branch) and client IP for forensic traceability — bounded at the short (90-day) retention class; rows are auth-tier (org_id NULL) so they are readable only by the service tier and substrate operators.

retention: short (90 days) · PII posture: personal-retained · subject: auth_credential · source: system

auth.callback

Auth callback completed (token exchange).

retention: short (90 days) · PII posture: none · subject: auth_credential · source: system

auth.password_changed

Password changed by the signed-in account. Payload carries the account id only — never the password, and never the email address.

retention: short (90 days) · PII posture: none · subject: auth_credential · source: system

auth.password_reset_requested

Password reset email requested for an account. Payload carries the email DOMAIN only (never the raw address) — anonymized posture per V1-SEC-007.

retention: short (90 days) · PII posture: anonymized · subject: auth_credential · source: system

auth.password_reset_completed

Password reset completed (new password set).

retention: short (90 days) · PII posture: none · subject: auth_credential · source: system

auth.second_factor_succeeded

Sign-in second factor accepted. Payload is the proof kind and the sign-in method only.

retention: short (90 days) · PII posture: none · subject: auth_credential · source: system

auth.second_factor_failed

Sign-in second factor rejected. Payload is the proof kind and the sign-in method only.

retention: short (90 days) · PII posture: none · subject: auth_credential · source: system

auth.second_factor_locked

Sign-in second factor locked after repeated failures. Payload is the proof kind and the sign-in method only.

retention: short (90 days) · PII posture: none · subject: auth_credential · source: system

identity.participant_promoted

Participant tier promoted (e.g., guest → member).

retention: medium (365 days) · PII posture: none · subject: participant · source: system

identity.invitation_created

Org invitation created. V1-SEC-007 / OWNER-6: payload deliberately retains the invitee's raw email for forensic traceability of who was invited into an org — bounded at the medium (1-year) retention class; rows are org-scoped so RLS limits reads to members of the inviting org.

retention: medium (365 days) · PII posture: personal-retained · subject: invitation · source: system

identity.invitation_accepted

Org invitation accepted.

retention: medium (365 days) · PII posture: none · subject: invitation · source: system

identity.invitation_declined

Org invitation declined by the invited participant (V066).

retention: medium (365 days) · PII posture: none · subject: invitation · source: system

person_addresses.address_added

Participant added a contact email address.

retention: medium (365 days) · PII posture: none · subject: person_email_address · source: person_addresses_service

person_addresses.address_verified

Participant verified a contact email address.

retention: medium (365 days) · PII posture: none · subject: person_email_address · source: person_addresses_service

person_addresses.address_removed

Participant removed a contact email address.

retention: medium (365 days) · PII posture: none · subject: person_email_address · source: person_addresses_service

person_addresses.member_address_updated

Participant changed the address an organisation uses.

retention: medium (365 days) · PII posture: none · subject: person_email_address · source: person_addresses_service

identity.invitation_revoked

Org invitation revoked.

retention: medium (365 days) · PII posture: none · subject: invitation · source: system

identity.pin_lockout_cleared

PIN lockout state cleared for the caller's pin_credentials row.

retention: short (90 days) · PII posture: none · subject: pin_credential · source: runtime_pin_lockout_cleared

identity.pin_failure_recorded

PIN failure recorded; lockout may have been (re)engaged.

retention: short (90 days) · PII posture: none · subject: pin_credential · source: runtime_pin_failure_recorded

org.created

Organization created.

retention: long (2555 days) · PII posture: none · subject: org · source: system

expression.primitive.checked

assertPrimitiveAllowed() outcome recorded — primitive create-path policy enforcement. E.sub4: payload includes manifestMaturity (aggregate) + dimensionMaturity (per-dimension) so audit consumers can reconstruct the tightening trajectory of any expression over time.

retention: long (2555 days) · PII posture: none · subject: expression · source: legacy_v283_expression_primitive_audit

expression.manifest.tightened

Manifest version published with one or more primitive dimensions narrowed from wildcard to finite, or finite list shortened. Payload carries (prevDimensions, newDimensions, proposingParticipantId, approvingParticipantIds[], changeRule) for audit-trail reconstruction of tightening trajectory.

retention: long (2555 days) · PII posture: none · subject: expression · source: system

expression.manifest.published

Manifest version published (any change). Complements the substrate-level expressions.version.published with steward-attestation payload (proposingParticipantId, changeRule). G.sub3.

retention: long (2555 days) · PII posture: none · subject: expression · source: system

expression.manifest.rejected

Manifest publish attempt rejected. Payload carries (reason, proposingParticipantId, changeRule) where reason ∈ steward_not_in_allowlist | maturity_gate_failed | version_bump_mismatch | manifest_invalid. G.sub3.

retention: long (2555 days) · PII posture: none · subject: expression · source: system

governance.steward.granted

New steward row inserted into expression_stewards (or revoked row re-activated). Carries (stewardId, changeRule, participantId, role, grantedByParticipantId, grantedAt). G.sub6.

retention: long (2555 days) · PII posture: none · subject: expression · source: system

governance.steward.revoked

Steward row revoked (revoked_at set on expression_stewards). Carries (stewardId, changeRule, participantId, role, revokedByParticipantId, revokedAt). G.sub6.

retention: long (2555 days) · PII posture: none · subject: expression · source: system

commons.stewardship.action

Commons stewardship action recorded (rotation, audit, etc.).

retention: medium (365 days) · PII posture: none · subject: commons · source: legacy_v261_commons_stewardship_log

integrity.snapshot

Integrity snapshot generated for a participant or org.

retention: medium (365 days) · PII posture: none · subject: attestation · source: system

integrity.attest

Attestation issued.

retention: medium (365 days) · PII posture: none · subject: attestation · source: system

integrity.verify

Integrity verification request processed.

retention: medium (365 days) · PII posture: none · subject: attestation · source: system

integrity.meter

Integrity metering update.

retention: medium (365 days) · PII posture: none · subject: attestation · source: system

data_request.submitted

Data subject access / deletion request submitted.

retention: long (2555 days) · PII posture: none · subject: data_request · source: system

p.audit_log.kernel_created

V375 self-test seed event recorded by Phase 6 of the kernel migration.

retention: short (90 days) · PII posture: none · subject: audit_log · source: system

commerce.entitlement.revoked

Entitlement grant revoked (manual revocation or order-cancel cascade).

retention: medium (365 days) · PII posture: none · subject: entitlement_grant · source: runtime_commerce_entitlements

commerce.order.cancelled

Order cancelled — grants revoked, stock variants restored.

retention: medium (365 days) · PII posture: none · subject: order · source: runtime_commerce_order_lifecycle

commerce.order.created

Order created in the commerce module.

retention: medium (365 days) · PII posture: none · subject: order · source: runtime_commerce_order_lifecycle

commerce.org_relationship.requested

Org-to-org commerce relationship requested (e.g. supplier/customer pair).

retention: medium (365 days) · PII posture: none · subject: org_relationship · source: runtime_commerce_org_relationships

org_relationship.requested

B2B org-to-org relationship requested (kernel/org-relationships service).

retention: medium (365 days) · PII posture: none · subject: org_relationship · source: runtime_kernel_org_relationships

org_relationship.approved

B2B org-to-org relationship approved (status pending→active).

retention: medium (365 days) · PII posture: none · subject: org_relationship · source: runtime_kernel_org_relationships

org_relationship.rejected

B2B org-to-org relationship rejected (status pending→terminated).

retention: medium (365 days) · PII posture: none · subject: org_relationship · source: runtime_kernel_org_relationships

org_relationship.suspended

B2B org-to-org relationship suspended (status active→suspended).

retention: medium (365 days) · PII posture: none · subject: org_relationship · source: runtime_kernel_org_relationships

org_relationship.terminated

B2B org-to-org relationship terminated (status active/suspended→terminated).

retention: medium (365 days) · PII posture: none · subject: org_relationship · source: runtime_kernel_org_relationships

procurement.requisition.status_changed

Procurement requisition status transition (create/approve/patch/convert-to-PO).

retention: medium (365 days) · PII posture: none · subject: procurement_requisition · source: runtime_procurement_requisition_lifecycle

procurement.po.status_changed

Procurement purchase-order status transition (create/patch/receiving-reconcile).

retention: medium (365 days) · PII posture: none · subject: procurement_purchase_order · source: runtime_procurement_po_lifecycle

procurement.receiving.recorded

Procurement goods-receiving recorded for a PO line item (terminal status).

retention: medium (365 days) · PII posture: none · subject: procurement_receiving · source: runtime_procurement_receiving_lifecycle

procurement.approval.status_changed

Procurement product-approval status transition (submit/approve/decline/etc.).

retention: medium (365 days) · PII posture: none · subject: procurement_product_approval · source: runtime_procurement_approval_lifecycle

procurement.portal_token.minted

Portal access token minted (vendor/customer/partner). Records metadata only — never the raw token or its hash. V1-SEC-007 / OWNER-6: payload deliberately retains the grantee's raw email for forensic traceability of external portal grants — bounded at the medium (1-year) retention class; rows are org-scoped so RLS limits reads to the issuing org's members.

retention: medium (365 days) · PII posture: personal-retained · subject: portal_access_token · source: runtime_portal_token_mint

commerce.quote.accepted

Quote accepted by recipient — quote lifecycle event.

retention: medium (365 days) · PII posture: none · subject: quote · source: runtime_commerce_quote_lifecycle

commerce.quote.created

Quote created in the commerce module.

retention: medium (365 days) · PII posture: none · subject: quote · source: runtime_commerce_quote_lifecycle

commerce.quote.declined

Quote declined by recipient — quote lifecycle event.

retention: medium (365 days) · PII posture: none · subject: quote · source: runtime_commerce_quote_lifecycle

commerce.quote.sent

Quote sent to recipient — quote lifecycle event.

retention: medium (365 days) · PII posture: none · subject: quote · source: runtime_commerce_quote_lifecycle

communications.conversation.member_added

A participant was added to a conversation (replaces V001 phase7_add_conversation_member).

retention: medium (365 days) · PII posture: none · subject: conversation · source: runtime_communications_conversation_membership

communications.message.read

A conversation message delivery was marked read by its recipient (replaces V001 phase7_mark_message_read).

retention: short (90 days) · PII posture: none · subject: message · source: runtime_communications_message_read

communications.reminder.triggered

A due reminder fired and fanned out notifications to its recipient(s) (replaces V001 process_due_reminders → due-reminders background worker).

retention: short (90 days) · PII posture: none · subject: reminder · source: runtime_communications_reminder_sweep

communications.notification.enqueued

A notification's per-channel delivery rows were materialised (in_app/email; pending or skipped-by-preference). Replaces the V001 phase7_notifications_after_insert trigger dispatch.

retention: short (90 days) · PII posture: none · subject: notification · source: runtime_communications_notification_dispatch

communications.notification.sent

A notification delivery was sent successfully (replaces V001 process_notification_deliveries → notification-delivery background worker).

retention: short (90 days) · PII posture: none · subject: notification_delivery · source: runtime_communications_notification_delivery

communications.notification.failed

A notification delivery failed (deterministic forced-fail / retry back-off; replaces V001 process_notification_deliveries failure branch).

retention: medium (365 days) · PII posture: none · subject: notification_delivery · source: runtime_communications_notification_delivery

communications.message.sent

A conversation message was sent + fanned out to its recipients (replaces the V001 phase7_messages_after_insert trigger's message_sent audit).

retention: short (90 days) · PII posture: none · subject: message · source: runtime_communications_message_send

communications.message.delivered

A conversation message's delivery fan-out completed (replaces the V001 phase7_messages_after_insert trigger's message_delivered audit).

retention: short (90 days) · PII posture: none · subject: message · source: runtime_communications_message_send

substrate_operator.attestation.backed

Universal substrate-operator attestation event — written by emitAttestationBacked() for all substrate-operator ceremonies (audit export bundle issued, chain restored, chain integrity attested, partition archived, etc.). Action-specific detail in payload.action.

retention: long (2555 days) · PII posture: none · subject: substrate_operator_attestation · source: system

audit.chain.restored

Audit chain restoration anchor event — written as the first row of the new segment opened by restoreAuditChainFromBackup(). Carries priorSegmentId + priorSegmentTerminalHash for continuity attestation. Phase 3d-ii §ZA-ii.

retention: permanent (permanent) · PII posture: none · subject: audit_chain_segment · source: system

audit.chain.integrity_verified

Audit chain integrity verification attestation — written by attestAuditChainIntegrity() via emitAttestationBacked() ceremony. Payload carries segmentId + outcome + optional failReason. Phase 3d-ii §ZA-ii.

retention: medium (365 days) · PII posture: none · subject: audit_chain_segment · source: system

audit.export_bundle.issued

Audit export bundle issued — written by exportAuditBundle() via emitAttestationBacked() ceremony. Payload carries bundleId + timeRange + jurisdiction + rowCount. Phase 3d-i §ZA.

retention: long (2555 days) · PII posture: none · subject: audit_export_bundle · source: system

audit.partition.archived

Audit log partition archived — emitted by archiveExpiredPartitions() after dropping a partition where all rows have expires_at < NOW(). Payload carries partitionName + rowCount + partitionStart + partitionEnd. Phase 3d-iii §ZA-iii. Retention class: permanent (the archival event itself must never expire).

retention: permanent (permanent) · PII posture: none · subject: audit_log_partition · source: system

backup.bundle.issued

Backup bundle issued — emitted by issueBackupBundle() after a substrate-attested backup bundle row is inserted and the Ed25519 signature ceremony completes. Payload carries bundleId + orgId + environmentId + bundleKind + retentionClass + issuedAt. Phase 3e-i §ZB-i. Retention class: long (7 years) — backup attestations are sovereign-critical governance records.

retention: long (2555 days) · PII posture: none · subject: backup_bundle · source: system

backup.bundle.verified

Substrate-attested 2-of-2 verification ceremony for a backup bundle. Custody + resolution operators ratified the JCS+Ed25519 signature against the historic signing key. Read-only ceremony per Phase 3e ratification H4 — no mutation of backup_bundles.state. Payload carries bundleId + orgId + environmentId + verifiedAt + custodyActorParticipantId + resolutionActorParticipantId. Phase 3e-ii §ZB-ii.

retention: long (2555 days) · PII posture: none · subject: backup_bundle · source: system

identity.subject.revoked

Identity subject revoked via service-layer cascade (§ZD-β R4). Emitted ONCE after all dependent primitives (mandates, devices, service-account credentials) are cascaded. Payload carries subjectId + subjectSubtypeKey + revokedBy + revokedAt + reason + cascadeCounts (per-primitive revocation tallies). Retention class: long (7 years) — identity revocations are governance-significant records per §ZA-iii G5.

retention: long (2555 days) · PII posture: none · subject: identity_subject · source: runtime_identity_subject_revoked

fork.handoff.issued

Fork handoff manifest issued — emitted by issueForkHandoffCeremony() after a substrate-attested fork handoff row is inserted and the Ed25519 signing ceremony completes (F1/F2). Payload carries handoffId + orgId + environmentId + backupBundleId + issuerActorId + issuedAt. Phase 3f-i §ZC-i. Retention class: long (7 years) — fork handoff attestations are customer-portability sovereign-critical governance records.

retention: long (2555 days) · PII posture: none · subject: fork_handoff · source: system

fork.handoff.ratified

Substrate-attested 2-of-2 ratification ceremony for a fork handoff manifest. Custody + resolution operators co-signed the fork handoff (F2 / C-EE-PRE-7 distinct-actor enforcement). Payload carries handoffId + orgId + environmentId + issuerActorId + ratifierActorId + ratifiedAt. Phase 3f-i §ZC-i.

retention: long (2555 days) · PII posture: none · subject: fork_handoff · source: system

fork.trust_anchor.admitted

Donor trust-anchor keys admitted to recipient cluster — emitted by admitDonorTrustAnchorKeys() after donor signing keys are inserted into cluster_signing_keys with provenance='fork-imported-trust-anchor' + status='retired' (F3). Payload carries admittedKidCount + kids + admitterActorId + admittedAt. Phase 3f-i §ZC-i. Domain: identity-coordination (donor key bootstrap on recipient).

retention: long (2555 days) · PII posture: none · subject: cluster_signing_keys · source: system

agents.ai_agent.provisioned

Substrate-canonical AI agent provisioning ceremony completed (§ZD-δ-2 R5 closure). Emitted by agentsService.provisionAiAgent() after all 3 cascade steps complete: (1) identity subject created (subtype_key='ai_agent', coordination-tier per T.sub9 + SS-8), (2) agent row instantiated with identitySubjectParticipantId FK bound, (3) memory store provisioned. Payload carries agentId + identitySubjectId + templateId + ownerOrgId + memoryStoreId + environmentId + provisionedAt. Rollback path: if step 2 fails, revokeIdentitySubject() undoes the orphaned subject and emits identity.subject.revoked before re-throwing. Retention class: medium (1 year) — agent provisioning lifecycle events are org-governance-significant but not jurisdiction-sovereign-critical.

retention: medium (365 days) · PII posture: none · subject: agent · source: runtime_agents_ai_agent_provisioned

identity.vc_issuer_key.admitted

External VC issuer trust anchor admitted via 2-of-2 substrate-operator ceremony — emitted by vcIssuerKeysService.admitIssuerKey() after emitAttestationBacked() 3-step ceremony + vc_issuer_keys INSERT. Payload carries issuerUri + issuerLabel + kid + admittedBy + cosignedBy + validUntil + reason + attestationRowId. §ZD-β Phase β-5 / T1.1 / R6. Retention class: long (7 years) — trust anchor admission decisions are governance-significant records per §ZA-iii G5.

retention: long (2555 days) · PII posture: none · subject: vc_issuer_key · source: runtime_vc_issuer_key_admitted

identity.vc_issuer_key.revoked

External VC issuer trust anchor revoked via 2-of-2 substrate-operator ceremony — emitted by vcIssuerKeysService.revokeIssuerKey() after emitAttestationBacked() 3-step ceremony + soft-revoke UPDATE. Payload carries issuerUri + kid + revokedBy + cosignedBy + reason + revokedAt + attestationRowId. §ZD-β Phase β-5 / T1.1 / R6. Retention class: long (7 years) — trust anchor revocation decisions are governance-significant records per §ZA-iii G5.

retention: long (2555 days) · PII posture: none · subject: vc_issuer_key · source: runtime_vc_issuer_key_revoked

programs.phase_advanced

A company-relationship advanced to a new program phase — emitted by programsService.advancePhase() after applyProgramPhaseAdvance() succeeds. Replaces the V001 advance_program_phase SECURITY DEFINER function. Payload carries programId + newPhase + unlockedLayers + unlockedSections. Retention class: medium (1 year) — program lifecycle progression records.

retention: medium (365 days) · PII posture: none · subject: program_company_relationship · source: runtime_programs_phase_advanced

strategy.bmv.current_changed

Business model version singleton-current invariant flipped — emitted by strategyBusinessVersionsService.recordBusinessModelVersionCurrentChanged() after the BMV repository atomically demoted sibling rows and flipped the target row's is_current=true. Replaces the V001 ensure_single_current_bmv trigger. Payload carries version_id + demoted_version_ids. Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: business_model_version · source: runtime_strategy_bmv_current_changed

strategy.bmv.default_changed

Business model version singleton-default invariant flipped — emitted by strategyBusinessVersionsService.recordBusinessModelVersionDefaultChanged() after the BMV repository atomically demoted sibling rows and flipped the target row's is_default=true. Replaces the V001 ensure_single_default_bmv trigger. Payload carries version_id + demoted_version_ids. Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: business_model_version · source: runtime_strategy_bmv_default_changed

strategy.bpv.current_changed

Business plan version singleton-current invariant flipped — emitted by strategyBusinessVersionsService.recordBusinessPlanVersionCurrentChanged() after the BPV write-path atomically demoted sibling rows and flipped the target row's is_current=true. Replaces the V001 unset_other_current_bpv trigger. Payload carries version_id + demoted_version_ids. Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: business_plan_version · source: runtime_strategy_bpv_current_changed

entitlements.org_type.changed

Org-type change applied — emitted by entitlementsService.applyOrgTypeChange() after the substrate revoked the from-type's default entitlements and granted the to-type's defaults (and inserted the org_type_transitions audit row). Replaces the V001 auto_grant_org_type_entitlements trigger. Payload carries targetOrgId + fromType + toType + granted[] + revoked[] + environmentId. Retention class: long (7 years) — org-type lineage is governance-significant.

retention: long (2555 days) · PII posture: none · subject: org · source: runtime_entitlements_org_type_changed

entitlements.org_type.retriggered

Org-type entitlements re-applied across a type cohort — emitted by entitlementsService.retriggerOrgTypeEntitlements() after iterating every org of a given type and calling applyOrgTypeChange(fromType=toType). Replaces the V001 retrigger_org_type_entitlements SECURITY DEFINER. Payload carries typeKey + orgsAffected. Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: org_type · source: runtime_entitlements_org_type_retriggered

entitlements.plan.granted

Plan entitlements granted — emitted by entitlementsService.grantPlanEntitlements() after iterating plan_entitlement_mappings and calling grant() per mapping. Replaces the V001 grant_plan_entitlements SECURITY DEFINER. Per-grant entitlements.grant.created events still fire; this carries the bulk summary. Payload: targetOrgId + planKey + stripePriceId + grantsApplied + environmentId. Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: org · source: runtime_entitlements_plan_granted

entitlements.plan.revoked

Plan entitlements bulk-revoked — emitted by entitlementsService.revokePlanEntitlements() after the substrate bulk-UPDATE'd subscription-source grants for the org. Replaces the V001 revoke_plan_entitlements SECURITY DEFINER. Per-grant events are NOT emitted by the bulk path (V001 didn't either). Payload: targetOrgId + grantsRevoked + environmentId. Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: org · source: runtime_entitlements_plan_revoked

commerce.order.status_changed

Order status transition recorded — emitted by commerceService.updateOrderStatus() after the substrate UPDATEd store_orders.status. Replaces the inline audit_events insert in V001 phase10_update_order_status SECURITY DEFINER. Payload carries order_id + order_number + old_status + new_status. Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: order · source: runtime_commerce_order_lifecycle

commerce.order.fulfillment_changed

Order fulfillment-status transition recorded — emitted by commerceService.updateOrderFulfillment() after store_orders.fulfillment_status UPDATE. Mirrors the lifecycle-audit trigger's payload shape so downstream consumers see the same surface they would have seen via the V001 trigger. Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: order · source: runtime_commerce_order_lifecycle

commerce.quote.viewed

Quote marked viewed by recipient — emitted by commerceService.markQuoteViewed() after store_quotes.status UPDATE to 'viewed'. Replaces the inline notification side-effect of V001 notify_quote_viewed (the audit row also moves to TS at v1). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: quote · source: runtime_commerce_quote_lifecycle

commerce.quote.expired

Quote expired by valid_until cutoff — emitted by commerceService.markQuoteExpired() after store_quotes.status UPDATE to 'expired'. Replaces the inline notification side-effect of V001 notify_quote_expired. Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: quote · source: runtime_commerce_quote_lifecycle

commerce.quote.converted

Quote converted to order — emitted by commerceService.convertQuoteToOrder() after the substrate inserted a store_orders row + line items + entitlement grants from the accepted quote. Replaces the V001 phase10_convert_quote_to_order SECURITY DEFINER inline audit_events insert. Payload carries quote_id + order_id + order_number + invoice_id + payload_sha256. Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: quote · source: runtime_commerce_quote_lifecycle

commerce.product.status_changed

Product status transition recorded — emitted by commerceService.recordProductStatusChanged() after a products.update mutation flips products.status. Replaces the inline notification side-effect of V001 notify_product_status_changed trigger. Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: product · source: runtime_commerce_product_lifecycle

document.ai.generated

AI-generated document body — emitted when an AI authoring action produces new content for a format='dox' org_content_artifact. Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: content_artifact · source: runtime_document_ai_authoring

document.ai.rewritten

AI-rewritten document body — emitted when an AI authoring action rewrites existing content for a format='dox' org_content_artifact. Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: content_artifact · source: runtime_document_ai_authoring

document.collab_session.started

Collaborative editing session opened on a format='dox' org_content_artifact (pairs with federation document.collab.session topic + V007). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: content_artifact · source: runtime_document_collab_session

document.collab_session.ended

Collaborative editing session closed on a format='dox' org_content_artifact (pairs with federation document.collab.session topic + V007). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: content_artifact · source: runtime_document_collab_session

engineering_work.unit.created

Control-plane engineering work unit opened (question/Q&A at Stage 3). Operator-plane; not a tenant work item. Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.unit.status_changed

Control-plane engineering work unit status changed (open | in-progress | answered | closed). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.mandate.bound

Control-plane engineering mandate bound to a work unit (hub-minted ai_agent, Stage 3 read actions). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.agent.bound

First action on an unbound implement / merge / deploy identity stamped the agent onto WU evidence (LP-D.1 WU-B; not a GET bind). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.packet.attached

Control-plane labelled context packet attached to a work unit (GE-3.4; WU evidence, not a Gitea commit). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.worktree.enqueued

Control-plane isolated-exec job enqueued for a trial work unit (GE-4.1; BullMQ worker, not the Control request path). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.worktree.materialized

Control-plane disposable worktree materialized at a SHA pin (GE-4.1; WU evidence, not a Gitea commit). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.command.enqueued

Control-plane isolated-exec command job enqueued (GE-4.2; run_tests / run_guard on the worker, not the request path). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.command.completed

Control-plane isolated-exec command finished; exit code + log digest on the trial WU (GE-4.2; not a git commit). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.patch.enqueued

Control-plane isolated-exec modify_files job enqueued (GE-4.3; proposed patch on the worker, not a git commit). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.patch.completed

Control-plane isolated-exec proposed patch captured; unified diff digest on the trial WU (GE-4.3; not a git commit). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.branch.enqueued

Control-plane git-gateway create_branch job enqueued (GE-5.2; BullMQ worker, not the Control request path). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.branch.created

Control-plane feature branch created at a SHA pin via the git gateway (GE-5.2; implement WU evidence, not a commit, not Gitea main). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.commit.enqueued

Control-plane git-gateway commit job enqueued onto an existing feature branch (GE-5.3; BullMQ worker, not the Control request path). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.commit.created

Control-plane attested commit on a feature branch via the git gateway (GE-5.3; trailers on implement WU evidence, not Gitea main). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.review.requested

Control-plane change request opened on an implement WU (GE-6.1; Control is authority; optional Gitea pull is a mirror). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.review.mirrored

Optional Gitea pull attached as a mirror of a Control change request (GE-6.1; never permission, never a default-branch update). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.ground_truth.enqueued

Control-plane enqueue of Ground Truth generation at a change-request tip S' (GE-6.2; Control committed digest is not rewritten). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.ground_truth.recorded

G(S') digest pointer recorded on an implement WU (GE-6.2; branch evidence, not a silent HEAD retarget; absent blob stays artifact_absent). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.ground_truth.refused

Ground Truth job ended without a digest: the change-request tip never reached the executor clone within the mirror wait (D2.1 / C-ZCT-18 item 7; the worker never fetches). Recorded once per job as groundTruthRefusal on the implement WU with the stage owed (proposed G(S') or candidate). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.challenge.recorded

Distinct verification-family identity recorded a challenge on an implement WU (GE-6.3; CON-* or claim pair; Control HEAD unchanged). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.challenge.closed

Challenge closed against primary evidence at a SHA (GE-6.3; implementation identity cannot close its own challenge; not a model summary). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.merge.requested

Control-plane merge request opened on an implement WU (GE-7.1; asks, does not merge; Gitea merge button is not permission). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.merge.acknowledged

Worker acknowledgement of a Control merge request (GE-7.1; no Gitea merge, no candidate SHA, Control HEAD unchanged). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.candidate.enqueued

Candidate commit object + G(candidate-SHA) generation enqueued (GE-7.2; Q5; does not update the default branch). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.candidate.recorded

Candidate commit SHA and G(candidate-SHA) recorded on an implement WU (GE-7.2; the digest names the content merge M — under D2.0 the admitted SHA is the digest commit C carrying it — never S' and never Control HEAD). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.candidate.construction_refused

Candidate construction refused by the constructor with main and every ref untouched (D2.0 / C-ZCT-18: tree conflict, digest file carried by S', pin or parent discipline); recorded once per job as constructionRefusal on the implement WU. Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.candidate.ci_rerun

Substrate operator asked Gitea to re-run the failed jobs of a unit's current candidate (C-ZCT-69; another attempt only; the merge still requires the newest run to be green). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.candidate.published

Candidate object pushed to refs/heads/ge/candidate-<wu>, candidate pull opened against main, and G(candidate) blob published to the operator object store (LP-D.1 transport, not permission; C-ZCT-9). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.merge.enqueued

Merge admission enqueued for a green implement WU with G(candidate-SHA) (GE-7.3; fast-forward only; force-push refused). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.merge.admitted

Pre-verified candidate SHA admitted as main; Control digest rewritten (GE-7.3; exact candidate object, never merge-then-regenerate). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.merge.refused

Merge admission refused with main unchanged (GE-7.3 typed refusal). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.provenance.joined

Verified release bundle joined to a unit SHA or an explicitly declared descendant (GE-8.1; does not flip runtime-observed). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.provenance.refused

Signed-bundle provenance join refused (GE-8.1; unverified envelope, SHA mismatch, or untraced later-SHA; rungs stay false). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.closeout.attached

Named closeout artifact attached through a GE-8.1 provenance join (GE-8.2; restore / k6 / e2e-smoke / health; rungs true only for a joined unit SHA with present evidence). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.deploy.applied

Signed release bundle applied under a deploy-identity mandate (GE-8.3; wraps applyReleaseBundle; never live FS; does not flip runtime-observed). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.deploy.refused

production_deploy refused with production unchanged (GE-8.3; verify / ordinal / chain / env apply-path failure). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.proposal.drafted

Verified Ground Truth gap projected to a draft proposal (GE-9.1; not a work unit; rungs stay false). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.proposal.refused

Proposal mutation refused with no work unit (GE-9.1 projection or GE-9.2 ratification precondition). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.proposal.accepted

Draft proposal accepted by a distinct ratifier (GE-9.2; not a work unit; proposer cannot accept; merger is not the sole acceptor). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.proposal.declined

Draft proposal refused by a ratifier with a typed reason (GE-9.2; status=refused; no work unit). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.proposal.opened

Accepted proposal materialized as exactly one Control work unit (GE-9.3; existing createWorkUnit path; intent carries the gap; not implemented). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.action.requested

Control admitted a registered engineering action under a per-WU mandate (LP-C.1). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.action.refused

Control refused a requested engineering action (unknown action, mandate miss, implementation denial, or consume refusal) (LP-C.1). Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.token.minted

Operator minted a short-lived per-WU Control EdDSA token for an already-bound mandate (LP-C.5). The token itself is never persisted. Retention class: medium (1 year).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.bind_set.completed

Operator decision 1 of 2 — work unit opened with implementer / verifier / merger bound and implement (+ verify) tokens minted in one act (C-ZCT-18 item 5). Records mandate + participant ids only — never a token.

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.harness_credential.issued

Operator issued an agent identity a harness credential (C-ZCT-19): it exchanges for per-WU tokens only under mandates the operator bound. Records the credential jti and expiry — never the credential.

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.merge.approved

Operator approved the merge of one candidate SHA whose change set touches a protected path (C-ZCT-19 merge policy).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.pin.forwarded

Implementer moved an open implement work unit pin forward to the current main tip (C-ZCT-20).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.unit.retired

Operator retired a stale or replaced work unit with a recorded reason (C-ZCT-20).

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.release.tagged

Control tagged the commit it started serving, release/<day>-<sha8>, with the merged unit's title. An existing tag is left alone.

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

engineering_work.branches.removed

Control deleted a closed unit's feature and candidate branches 14 days after it closed, and recorded any archive tag. A moved tip is kept.

retention: medium (365 days) · PII posture: none · subject: engineering_work_unit · source: runtime_engineering_work

decisions.class.configured

Org authority class for the decisions register was published as a new version row (append-only configuration).

retention: permanent (permanent) · PII posture: none · subject: org_decision_class · source: system

decisions.decider.admitted

A participant was admitted to the org decider roster (bootstrap or unanimous admission decision).

retention: permanent (permanent) · PII posture: none · subject: org_decider · source: system

decisions.decision.recorded

An immutable org governance decision record was recorded with computed outcome and vote ledger.

retention: permanent (permanent) · PII posture: none · subject: org_decision · source: system

decisions.decision.corrected

A new version of an existing decision record_key was published (correction chain via corrects_decision_id).

retention: permanent (permanent) · PII posture: none · subject: org_decision · source: system

decisions.decision.superseded

A new decision record superseded a prior record (cross-record replacement via supersedes_decision_id).

retention: permanent (permanent) · PII posture: none · subject: org_decision · source: system

decisions.decision.imported

A historical governance decision was imported with provenance source_ref (immutable native row).

retention: permanent (permanent) · PII posture: none · subject: org_decision · source: system

decisions.proposal.proposed

An active decider opened a native governance proposal awaiting per-decider votes.

retention: permanent (permanent) · PII posture: none · subject: org_decision_proposal · source: system

decisions.vote.cast

An active decider cast their own vote on an open native proposal.

retention: permanent (permanent) · PII posture: none · subject: org_decision_vote · source: system

decisions.proposal.closed

An open native proposal was closed into an immutable org_decisions row.

retention: permanent (permanent) · PII posture: none · subject: org_decision · source: system

access_request.approved

Identity operator approved a public access request and issued a single-use signup invitation (V060).

retention: medium (365 days) · PII posture: none · subject: access_request · source: runtime_access_requests

access_request.declined

Identity operator declined a public access request (V060).

retention: medium (365 days) · PII posture: none · subject: access_request · source: runtime_access_requests

ecosystem.admission.role_binding_ratified

An Admission holder member ratified a role binding. The governance attestation records the binding; this audit row names the acting person and the holder organisation.

retention: long (2555 days) · PII posture: none · subject: ecosystem_role_binding · source: system

expression_stewardship.established

The first steward of a launch expression was named. Control also writes a substrate-operator attestation; a stewardship-holder member records the acting person and the holder organisation on this audit row.

retention: long (2555 days) · PII posture: none · subject: expression_stewardship · source: system

ecosystem.attestation.incorporation_attested

An Attestation Operator member recorded an incorporation transition. The governance attestation holds the legal details and any registry extract; this audit row names the target organisation, the attesting organisation and the acting space.

retention: long (2555 days) · PII posture: none · subject: org · source: system

org_address.domain_registered

An organisation registered a mail domain it owns. V1-SEC-007 / OWNER-6: the payload also keeps the acting mailbox when the registrar was signed in with a lent address (raw email, or null). Bounded at the long retention class.

retention: long (2555 days) · PII posture: personal-retained · subject: org · source: system

org_address.registered

An organisation registered an address on a domain it owns. V1-SEC-007 / OWNER-6: the payload keeps that mailbox (raw email) and the acting mailbox when there was one. Bounded at the long retention class.

retention: long (2555 days) · PII posture: personal-retained · subject: org · source: system

org_address.loan_created

An organisation lent an address to a member. V1-SEC-007 / OWNER-6: the payload keeps the lent mailbox (raw email) and the acting mailbox when there was one. Bounded at the long retention class.

retention: long (2555 days) · PII posture: personal-retained · subject: org · source: system

org_address.loan_confirmed

The member confirmed a lent address with a one-time code. V1-SEC-007 / OWNER-6: the payload keeps the confirmed mailbox (raw email). Bounded at the long retention class.

retention: long (2555 days) · PII posture: personal-retained · subject: participant · source: system

org_address.loan_ended

A lent address stopped being held. V1-SEC-007 / OWNER-6: the payload keeps the mailbox that ended (raw email) and the acting mailbox when there was one. Bounded at the long retention class.

retention: long (2555 days) · PII posture: personal-retained · subject: org · source: system

seat_licence.step_recorded

A seat-licence decision was recorded. The audit payload carries the step name, whether it was escalated, and the fixed escalation sentence — participant and licence ids only, never a mailbox. The address used, when there was one, stays on the step row, not on this permanent audit kind.

retention: permanent (permanent) · PII posture: none · subject: licensed_seat · source: system

review_status.entry.appended

A new append-only review-status ledger row was recorded for an authorised entity.

retention: permanent (permanent) · PII posture: none · subject: review_status_entry · source: system