feat(ai): resolve an AI usage level per record and publish it as ai.usage

Three levels (frugal, standard, full) with an operator ceiling and default
and a per-account choice within them, resolved in the capability layer for
the record and published on GET /api/auth/me as ai.usage: the level in
effect, the stored choice, the bounds, why (user, default, admin_cap), the
three options with whether each is allowed and an estimate of tokens per
day scaled from the record's last seven full days of coach_usage, and the
measured mean. A delegate sees the level, never the owner's spend.

PUT /api/auth/me/ai-usage stores the account's own choice or null for the
default, refusing a level above the ceiling with 422 ai.usage.aboveCeiling
and meta.maxLevel. The new supplementLabel capability needs standard or
above; below it the capability is unavailable with the new usage_level
reason, refused with 403 ai.usage.levelTooLow and meta.requiredLevel.

Refs #1217
This commit is contained in:
Marc-André Bombeck committed 2026-10-15 22:49:01 +02:00
1 parent e573f28ae8
commit 6f673a7b84
22 files changed
+1342 -84

No files matched your search

+3
View File
@@ -43,7 +43,10 @@ export const ERROR_CODE_CATALOGUE: Readonly<Record<string, readonly string[]>> =
"ai.provider.none",
"ai.record.notPermitted",
"ai.unavailable",
"ai.usage.aboveCeiling",
"ai.usage.defaultAboveCeiling",
"ai.usage.invalid",
"ai.usage.levelTooLow",
"ai.usage.rateLimited",
],
ai_provider: ["ai_provider.invalid", "ai_provider.no_fields"],