Skip to content

feat(audit): register the six reserved types the document module emits - #1100

Merged
antoinetoussaint-byte merged 2 commits into
mainfrom
audit-register-document-store-types
Oct 13, 2026
Merged

antoinetoussaint-byte merged 2 commits into
mainfrom
audit-register-document-store-types

Conversation

@antoinetoussaint-byte

@antoinetoussaint-byte antoinetoussaint-byte commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Goal

A document module emits six audit types in the host's reserved saas namespace. The SDK's DeclareAuditEventTypes refuses that namespace, and the host registry did not carry them, so the host refused every emission and the rows stayed undelivered in the module's outbox. Registering them in the canonical registry is the route the owner chose over renaming into a module namespace (a rename would change the emission identity the retry deduplication relies on).

Classification: fix, at the place that owns the behaviour (the host's audit registry). Nothing is worked around.

The six types (payloads copied from the emitting module's vendored registry and its emitters)

Type Category Fields (R = required) PII
saas.datasource.protection_changed system solution; R policy_revision, retired (bool), owner, binding_sha256 none
saas.document.source_verified system solution; R version_id, source_id, receipt_job_id, policy_revision, binding_sha256, effect_sha256, owner none
saas.document.read_unscoped access (observation) solution, actor_principal_id, owner_principal_id, initiator, duration_ms (int); R correlation_id, outcome (enum empty/denied/failed) none
saas.document.search_unscoped access (observation) same as read_unscoped none
saas.document.confirmed lifecycle document fields with R version; R extractor, extractor_version, field, format, address (max 1024). Requires entry and idempotency key. The confirmed value is deliberately not a field none
saas.document.extractor_revised lifecycle document fields with R version; R extractor_key (128), revision (int), digest (64), retired (bool), request_type (128), proposal_kind (16); parent_digest (64); proposal_source (512). Requires entry and idempotency key proposal_source (free text a person or tool supplies)

The other fields are identifiers, digests, enums, counts or a reference position in a format's own notation (address), not free text. Visibility and retention follow the existing saas.document.* entries (external, 30d). source_verified and protection_changed have no emitter in the module yet; they are registered as the module's vendored registry already defines them.

What changed

  • audit_registry.go: six constants, six definitions, and the shared documentUnscopedReadFields.
  • audit_parity_test.go: the six are classified as emitted outside RPC (through EmitAuditEvent).
  • audit_registry_test.go: TestValidatePayload_DocumentModuleReservedTypes covers required fields, bounds, enums, undeclared fields (no value, no boundary on the unscoped types), entry and idempotency requirements, and the PII mark.
  • Regenerated, not hand-edited: saas.events.codefly.yaml (go test ./pkg/business -run AuditEventsContribution -update), then event-catalog.json, asyncapi.json, communication.md and eventcatalog/catalog_gen.go via the composition generator declared in module.package.codefly.yaml.

What I reused

The existing mutation/observation/required/requiresEntry/requiresIdempotencyKey/pii constructors, documentFields, and the saas.document.dead_letter_redriven precedent (same walk: registry, contribution, parity list, composition). No new mechanism. Not reused on purpose: the module's pending copy and its datasource folder-write types, which are not part of this ask.

Verification run

Not verified: golangci-lint run ./pkg/business/... reports 7 findings, all in files this PR does not touch (pre-existing); the full codefly ci run, the frontend and SDK suites, and a live delivery from a deployed module against this host.

🤖 Generated with Claude Code

Revision after review (08e6d87). This PR now registers four types, not six: saas.document.confirmed, saas.document.extractor_revised, saas.document.read_unscoped and saas.document.search_unscoped, the four the document module emits today, each checked against its emitter's payload. saas.datasource.protection_changed and saas.document.source_verified have no emitter on the module's main. Declared types only grow, so they wait for the PR that brings their emitter back. The proposal_source PII comment now gives the real reason: it is an unvalidated 512-byte string, though it names a run, receipt or derivation. The test fixtures use proposal_kind: person, a value the module actually sends. Generated outputs were rerun through the composition generator and AuditEventsContribution -update. Local runs: go test -race on business, eventcatalog and cataloggen, the tools ./composition tests and check-boundaries.sh all pass.

antoinetoussaint-byte and others added 2 commits October 12, 2026 19:13
A document module reports six audit types in the host's reserved `saas`
namespace, which a module cannot declare through DeclareAuditEventTypes. The
host refused them, so they stayed undelivered in the module's outbox:
saas.datasource.protection_changed, saas.document.source_verified,
saas.document.read_unscoped, saas.document.search_unscoped,
saas.document.confirmed and saas.document.extractor_revised.

Registered in the canonical registry with the payload the module sends;
the events contribution, event catalog, asyncapi and communication docs are
regenerated by the declared composition generator.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
saas.datasource.protection_changed and saas.document.source_verified have no
emitter on the document module's main (their last one was removed with the
unpublished source-provenance work). Declared types only grow, so they are
registered with the PR that brings their emitter back, aligned with the other
saas.document.* types. The proposal_source PII comment now states the real
reason: an unvalidated 512-byte string, though it names a run, receipt or
derivation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@antoinetoussaint-byte
antoinetoussaint-byte added this pull request to the merge queue Oct 12, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 12, 2026
@antoinetoussaint-byte
antoinetoussaint-byte added this pull request to the merge queue Oct 12, 2026
Merged via the queue into main with commit 71152e8 Oct 13, 2026
24 of 25 checks passed
@antoinetoussaint-byte
antoinetoussaint-byte deleted the audit-register-document-store-types branch October 25, 2026 17:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant