Imported from zitadel/nextgen (
internal/service/AGENTS.md). Install upstream withnpx skills add zitadel/nextgen --skill service. Copyright stays with the author.
Agent Instructions — internal/service/
These instructions apply to internal/service/. Defer to
internal/AGENTS.md (format before push) and root
AGENTS.md for broader rules.
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
EventTypeconstant 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(payload rules, live Path B table, Retired table, deferred list). Context: ADR 048, ADR 049. - Types:
internal/domain/event.goEventTypeconstants. - Payloads:
internal/domain/event_payload.go. - OpenAPI: payload YAML under
api/openapi/endpoints/events/payloads/plus the map inapi/cmd/gen_event_schemas/main.go; regenerate withmoon run server:generateorgo generate ./api/. - Producer allowlist:
internal/audit/catalog_producers_test.go— live catalog types must have a producer; do not list deferred types as live.
