Skip to content

CAP-PFM-OPS-010Preserve a shared record-activity trail

Markdown

CAP-PFM-OPS-010

Preserve a shared record-activity trail

Markdown
  • DocumentDraft
  • Product intentConfirmed
  • ImplementationObserved

KindCapabilityProduct areaPlatformModuleOperational RecordsRevision1

Read atservices-platform ad3f6a65

The Formal Contract

The narrative above explains; the sections below are authoritative — the rules, scenarios and tests this document binds.

Outcomes
Shared writers can join the owning change transaction.Application authority cannot rewrite retained activity.Typed metadata excludes free-text explanations and record contents.
Surfaces
jobapi
Preconditions
The event type and metadata vocabulary are declared in both the writer and database checks.
Postconditions
The stored entry remains until workspace purge under the current retention policy.
Constraints
Activity events remain separate from security history for access, role and licence decisions.
Intent sources
services-platform:docs/audit-events.md#2026-10-12 — Final acceptance (the shared append-only store)services-platform:docs/audit-events.md#The merge event (decision D8, 2026-10-12)

Controls

21 controls apply, from the corpus control catalogue.

TC-AZ-001 TC-AZ-002 TC-AZ-003 TC-AZ-004 TC-DAT-001 TC-DAT-002 TC-DAT-003 TC-DAT-004 TC-LOG-002 TC-LOG-003 TC-LOG-004 TC-LOG-005 TC-PI-001 TC-PI-003 TC-PI-005 TC-TEN-001 TC-TEN-002 TC-TEN-003 TC-VEN-001 TC-VEN-002 TC-VEN-003

Business Rules

10 rules, 9 to be proved before approval. A rule's product intent is derived from its origin: 10 confirmed by a product decision, the rest inheriting this capability's confirmed.

IdRuleKindEnforced atProvenance
01must prove
Confirmed
The database permits declared view, merge, intervention, eligibility, custom-record and attention events and rejects undeclared event types.
validationservice, databasetest
services-platform:modules/audit/tests/integration/db/audit-events.table.integration.spec.js#refuses an event type the store does not hold, by audit_events_event_type_check
02must prove
Confirmed
Each event type has its own metadata allow list and a one-kilobyte limit, preventing inline reasons, expressions and keys belonging to other types.
validationservice, databasetest
services-platform:modules/audit/tests/integration/db/audit-events.table.integration.spec.js#refuses an intervention that carries its reason inline: the reason lives in Commerce’s intervention_log row
03must prove
Confirmed
The application database role cannot update or delete stored activity events.
invariantdatabasetest
services-platform:modules/audit/tests/integration/db/audit-events.table.integration.spec.js#refuses an UPDATE of the event by the application role, so a trail cannot be rewritten
04must prove
Confirmed
Workspace row policies prevent reading another workspace’s events or inserting an event for that other workspace.
invariantdatabasetest
services-platform:modules/audit/tests/integration/db/audit-events.table.integration.spec.js#refuses a row written for another tenant from this tenant’s session, by the policy’s WITH CHECK
05must prove
Confirmed
Database-generated time-based event identities break ties between millisecond timestamps to provide stable history ordering.
invariantdatabasetest
services-platform:modules/audit/tests/integration/db/audit-events.table.integration.spec.js#refuses an instant finer than a millisecond, by audit_events_occurred_at_precision_check
06must prove
Confirmed
Mutation-event writers participate in an existing caller transaction, and business-change atomicity requires the owning caller to invoke them within that transaction.
policyserviceobserved
07must prove
Confirmed
A merge records its survivor and each absorbed record within the merge transaction, avoids duplicate lines on repeat application and refuses unattributed execution.
origin: services-platform:docs/audit-events.md#The merge event (decision D8, 2026-10-12)
policydatabasetest
services-platform:tests/integration/db/merge-participant.integration.spec.ts#writes one row for the survivor and one for each record merged away
08must prove
Confirmed
Activity events are removed only through workspace purge, which deletes bounded batches and refuses workspaces outside deletion.
lifecycledatabasetest
services-platform:modules/audit/tests/integration/services/persistence/audit-events.integration.spec.js#is refused by the database, so the purger is never a delete-by-tenant tool
09must prove
Confirmed
The query-reader role receives only read authority for activity events and remains subject to workspace isolation.
permissiondatabasetest
services-platform:modules/audit/tests/integration/db/audit-events.table.integration.spec.js#refuses an INSERT by that role, because the grant is SELECT and nothing else
10
Confirmed
The product should decide activity retention before high-volume use; the current decision leaves retention unresolved.
origin: services-platform:docs/audit-events.md#2026-10-12 — Final acceptance (Andrew: decide later)
lifecycledatabaseunknown

Scenarios

IdGivenWhenThenProvenance
01An owning operation supplies an eligibility-change event.The shared writer records the event under its execution context.The event identifies the actor, definition, action and supplied version metadata.inferred
services-platform:modules/audit/tests/integration/services/persistence/audit-events.integration.spec.js#answers the event whole, the actor the execution’s caller and the occurrence key minted for it
02The workspace remains outside deletion.A caller invokes the restricted event purge.The database rejects the purge and retains the events.inferred

The Markdown files under specs/ in rhythmsoftware/rhythm-v2-docs are the canonical source of truth. This reader is a generated, read-only projection of them.