# Event contract governance (integrations)

This document governs **outbound integration events** and related **webhook** contracts. It extends `docs/integrations/event-catalog.md` with **non-negotiable platform rules**.

---

## Immutable payload rules

- Stored integration events (`integration_events`) are **append-only logical records**: **do not mutate** `payload` after persistence.
- Corrections are modeled as **new events** or **new majors** (`v2`), not silent edits to historical payloads.
- Payloads must be **JSON-serializable** and stable for hashing (`payload_hash` uniqueness per tenant).

---

## Versioning rules

- Topic strings are **`{name}.v{MAJOR}`** (e.g. `employee.created.v1`).
- **Additive fields** within the same major are allowed only when **all current consumers** tolerate unknown keys (standard JSON practice).
- **Breaking** shape or semantics require a **new major** topic (`…v2`) and a deprecation window for `…v1` when external subscribers exist.

---

## Deprecation strategy

1. Announce **v1 topic sunset** with date and migration guide for integrators.
2. Stop **emitting new** `v1` events for that contract when the window closes (unless legally/commercially required).
3. **Replay** and **audit** may still reference historical `v1` payloads indefinitely unless a **data governance** policy says otherwise (see `data-governance.md`).

---

## Replay guarantees

- **Replay** means creating **new delivery attempts** for an existing immutable event (or operational re-dispatch), not rewriting history.
- Replays must be **idempotent on the consumer side**: consumers dedupe using **`id`** (event UUID) and acceptable **at-least-once** semantics.
- Platform retries (queue `release`, dead-letter recovery) are **not** a substitute for consumer idempotency.

---

## Consumer safety expectations

Integrators **must**:

- Verify **HMAC signatures** and **timestamp skew** (`docs/integrations/webhook-signatures.md`).
- Treat unknown JSON keys as **forward-compatible**.
- Handle **429 / 5xx** with exponential backoff and **never** assume single delivery.

The platform **must**:

- Keep **delivery logs** and **dead-letter** states observable (`/admin/integrations-health`, ops commands).
- Maintain **tenant isolation** on all dispatch and replay paths.

---

## Alignment with code structure

- Event emission belongs in **Services**; persistence and dispatch orchestration stay out of fat controllers (`PROJECT_RULES.md`).
- Cross-module emission should go through a **single integration boundary** (factory / dispatcher) to avoid divergent payload shapes.

---

## References

- `docs/integrations/event-catalog.md`
- `docs/integrations/webhook-signatures.md`
- `docs/governance/api-versioning.md`
- `docs/governance/release-management.md`
