AGENTS.md@internal/service · git:20261020.8d47d7a · 2026-10-20 · sha256 1f1e5e461ed5e4f0
AGENTS.md@internal/service git:20261020.8d47d7aA
Immutable. This exact content never changes and is served at /api/v1/blob/1f1e5e461ed5e4f0.
# Agent Instructions — `internal/service/` The rules in [`internal/AGENTS.md`](../AGENTS.md) apply here too. ## Events stay in sync with mutations Service mutate paths (create, update, delete, state flips, factor and authz writes) own Path B emitters: `audit.Emit` in the same transaction as the write. Adding, changing, or removing a mutation **must** keep events current — including **adding** a type when a new semantic mutation appears, and **removing** a type that no longer has a producer, unless rows were ever stored under it, in which case it moves to the catalog's Retired table. A change is incomplete if it: - adds a mutate without an emit, - changes a payload so it no longer matches the catalog, or - removes a mutate but leaves the type in the live Path B table. A type that has stored rows moves to Retired and keeps its `EventType` constant and OpenAPI member so those rows still decode, until its rows have aged out of retention, when the type is removed. Authority (do not duplicate payload rules or the catalog table here): - Catalog: [`docs/design/api/events-catalog.md`](../../docs/design/api/events-catalog.md) (payload rules, live Path B table, Retired table, deferred list). Context: [ADR 048](../../docs/adrs/048-wide-events-internal-audit-primitive.md), [ADR 049](../../docs/adrs/049-events-api-retention-export.md). - Types: [`internal/domain/event.go`](../domain/event.go) `EventType` constants. - Payloads: [`internal/domain/event_payload.go`](../domain/event_payload.go). - OpenAPI: payload YAML under `api/openapi/endpoints/events/payloads/`, the type's entries in `payloadByEventType` and `webhookByEventType` ([`api/cmd/gen_event_schemas/main.go`](../../api/cmd/gen_event_schemas/main.go)), and its webhook in the root `webhooks:` list of [`api/openapi/openapi-spec.yaml`](../../api/openapi/openapi-spec.yaml), which the generator checks. Regenerate with `moon run server:generate`. - Producer allowlist: [`internal/audit/catalog_producers_test.go`](../audit/catalog_producers_test.go) — live catalog types must have a producer; do not list deferred types as live.