The started_at throttle kept a second clock for a deadline the cache
already holds: a failed fetch caches {} with _pricing_cache_retry_after,
and the two clocks drift by the fetch duration. pricing_fetch_suppressed
reads that state directly, so the tracker drops the ad-hoc Thread
attribute and the private-constant import; the guard test now fails the
way the real fetch does (cached {}) instead of a bare no-op.
The Nous gateway can bill a catalog row to a subscription the account
holds instead of to credits, and marks such rows with
`billing_mode: "subscription"` on GET /v1/models. A free-tier account
can run them, but the picker locked every row not priced at $0.
Carry the marker into the Nous pricing entry and count it in
`_is_model_free`, which already feeds the tier partition and the
credits-depleted notice. The silent default for a free-tier account
still prefers a genuinely free model.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Reviewer P2 (kshitijk4poor): tests patch hermes_cli.models.get_cached_nous_inference_base_url
but models_pricing.pricing_cache_scope read its own module global, so the patch never reached
the call and the test passed on the default-endpoint fallback. Same seam-erosion class audited
across /tmp/rf/patch_traps.json (777 candidates) with an AST reachability check + a per-test
call-count probe (facade vs defining module) against BASE 63279301bcb; three seams actually
bypassed their patch on HEAD but not on BASE:
- hermes_cli.models.get_cached_nous_inference_base_url <- models_pricing.pricing_cache_scope
- hermes_state._connect_repair_durable <- hermes_state_repair._open_exclusive/_repair_conn/_db_opens_cleanly
- tools.approval._command_detection_variants <- approval_detection.detect_{dangerous,hardline}_command
Each now looks the name up through its facade at call time (the pattern hermes_state_repair
already used in live_writer_holds_db), restoring BASE's patchability.