message: 429: {"code":"INFERENCE_CAP_ERROR","message":"Error 429: You have reached your 5-hour Clinepass limit. The limit resets in 1h 39m, please try again later."}

stop_reason: error


last_error: 429: {"code":"INFERENCE_CAP_ERROR","message":"Error 429: You have reached your 5-hour Clinepass limit. The limit resets in 1h 39m, please try again later."}


I read this as a read-only path/authority investigation - I traced the Telegram adapter and registry validation chain, then mapped the failing contract to the tests and the safe config boundary.

<results>
<files>
- /home/cube/projects/richard/hermes-agent/gateway/platforms/telegram.py - `TelegramAdapter._configured_nutrition_registry()` and `_get_nutrition_coaching()` do the path normalization, profile-root resolution, canonical-path comparison, and startup gating.
- /home/cube/projects/richard/hermes-agent/gateway/platforms/nutrition_coaching.py - committed-registry resolution, live-registry reload, and `validate_committed_activation()` enforcement.
- /home/cube/projects/richard/hermes-agent/gateway/platforms/nutrition_coaching_config.py - config contract for `nutrition_coaching.extra`, including relative-path validation.
- /home/cube/projects/richard/hermes-agent/tests/gateway/test_adaptive_nutrition.py - direct contract tests for registry-path containment and startup acceptance/rejection.
- /home/cube/projects/richard/hermes-agent/tests/gateway/test_nutrition_coaching.py - fixture-backed committed vs manual activation behavior and canonical registry path expectations.
- /home/cube/projects/richard/hermes-agent/hermes_constants.py - `get_hermes_home()` base-root source used when no explicit profile root is provided.
- /home/cube/projects/richard/hermes-agent/tests/hermes_cli/test_gateway_service.py - systemd unit contract for `HERMES_HOME` and stable `WorkingDirectory`.
</files>

<answer>
`registry_path=customers/registry.json` is not accepted just because the file exists. The adapter resolves it against the profile root (`adapter_config.profile_root`, then `extra.nutrition_coaching.profile_root`, then `get_hermes_home()`), rejects `.`/`..`/symlinks, and then requires the resolved file to be exactly one of:

- `<profile_root>/customers/registry.json`
- `<profile_root>/registry.json`

Then startup calls `load_committed_customer_registry(profile_root)` and `validate_committed_activation(profile_root, registry_path, customer_key)`. So under systemd, if `HERMES_HOME` is wrong/unset, or if the profile only has a hand-edited registry and not a committed activation receipt, the config is rejected even with a syntactically valid `customers/registry.json`.

The intended contract in tests is:
- config hint is relative only (`NutritionCoachingConfig.from_extra()` rejects absolute and `..`)
- canonical authority comes from the profile loader, not cwd
- committed activation is required for startup; manual enable without the committed receipt fails closed

Minimal safe fix:
- keep the registry path relative
- make the service point at the real profile root via `HERMES_HOME`/`profile_root`
- if you want the config hint that matches the accepted startup tests, use `registry.json`; the loader canonicalizes it to the committed `customers/registry.json` when present

Deterministic offline repro:
- `pytest tests/gateway/test_adaptive_nutrition.py -k 'test_telegram_registry_authority_is_configured_and_contained or test_nutrition_startup_accepts_committed_receipt_and_canonical_path or test_nutrition_startup_rejects_manual_enable_without_committed_receipt'`
- `pytest tests/gateway/test_nutrition_coaching.py -k 'test_nutrition_live_reload_rejects_manual_enable_without_committed_receipt or test_nutrition_live_reload_keeps_disable_and_revoke_live'`
</answer>

<next_steps>
Ready to proceed - no follow-up needed
</next_steps>
</results>