Finish TEN-WP-0010: mutable grouping, contract corrected, handoffs sent

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
tegwick 2026-08-17 22:53:10 +02:00
parent 2e1c4e15e6
commit bdf9f5f643
4 changed files with 108 additions and 8 deletions

View file

@ -145,6 +145,27 @@ deployment's canonical currency (`GUARDRAIL_CURRENCY`, default `EUR`).
budget far faster than a human operator can notice, so its default ceiling is
set for the blast radius, not the buying power.
### Grouping can change (TEN-WP-0010)
A tenant's grouping is **mutable**, through
`POST /tenants/{id}/grouping` (action `tenant.grouping.set`). Reclassifying a
tenant moves every grouping-derived ceiling with it — a `trial` tenant
reclassified to `medium` goes from a zero spend budget to €1 000.
Two consequences for anyone reading guardrails:
- **A ceiling can change with no guardrail write against it.** The audit record
is the `tenant_grouping_changed` event on the tenant, not an entry in the
guardrail change log. That is deliberate: a guardrail trail containing
entries no guardrail write produced would be worse than one that is complete
but needs two event types read together.
- **Precedence is unchanged.** A per-tenant override still wins over the new
grouping default. Reclassification moves the grouping layer only.
Grouping is read from the tenant record, never parsed from the identifier's
middle segment — that segment is historical, and the two are expected to
diverge after a reclassification.
### Currency
Spend limits carry their currency explicitly. Because precedence resolves