fix(billing): rename user-facing "terminal billing" copy to Remote Spending (#68355)

* fix(billing): rename user-facing "terminal billing" copy to Remote Spending

The capability was renamed Remote Spending on the portal (consent CTA:
"Allow Remote Spending"; per-terminal states Granted/Stopped), but the
terminal, desktop, and docs still said "terminal billing" everywhere.

- Feature name: Remote Spending in titles/labels, lowercase mid-sentence.
- Step-up action verb is now "allow", matching the portal consent CTA.
- Kill-switch-off recovery copy points at the actual control ("a billing
  admin can turn it on from the portal's Hermes Agent page") instead of
  the dead-end "manage it on the portal".
- Per-terminal revoke copy uses the portal vocabulary ("stopped").
- Wire identifiers (cli_billing_enabled, cli_billing_disabled, ...) are
  unchanged; copy, comments, docs, and test expectations only.

* fix(billing): correct the post-step-up denial diagnosis + finish the desktop rename

Adversarial review findings: (1) a repeated insufficient_scope after a
successful step-up is a per-terminal authorization failure, but the copy
blamed the org kill-switch and pointed at the wrong recovery control —
now: "Remote Spending still isn't active for this terminal — the
authorization didn't take. Retry, or make this change on the portal."
(2) the desktop step-up flow started in Remote Spending vocabulary but
finished in "billing management access" — renamed both end states.
(3) prettier formatting on the touched files (matches the post-merge
fmt bot).
This commit is contained in:
Siddharth Balyan
2026-07-21 12:20:25 +05:30
committed by GitHub
parent 7a8852ddcb
commit b0da653ac8
28 changed files with 159 additions and 142 deletions
+6 -6
View File
@@ -1,4 +1,4 @@
"""Nous Portal terminal-billing HTTP client (Phase 2b).
"""Nous Portal Remote Spending HTTP client (Phase 2b).
Thin, fail-loud client for the four ``/api/billing/*`` endpoints the terminal
billing screens drive. Companion to ``hermes_cli/nous_account.py`` (which owns
@@ -90,8 +90,8 @@ class BillingScopeRequired(BillingError):
"""``403 insufficient_scope`` — the held token lacks ``billing:manage``.
The lazy step-up trigger: catching this kicks off a fresh device-connect that
requests ``billing:manage`` (and tells the user an ADMIN must tick "Allow
terminal billing"). Also fires mid-session if the scope is stripped on refresh
requests ``billing:manage`` (and tells the user an ADMIN must select "Allow
Remote Spending"). Also fires mid-session if the scope is stripped on refresh
after the user loses ADMIN.
"""
@@ -363,11 +363,11 @@ def _raise_for_error(
)
raise BillingAuthError(message or "Authentication required.", **common)
if status == 403:
# This terminal's spending was revoked (NOT the same as never having the
# scope). Disable spend UI immediately; recovery is reconnect.
# Remote spending was stopped for this terminal (NOT the same as never
# having the scope). Disable spend UI immediately; recovery is reconnect.
if error == "remote_spending_revoked":
raise BillingRemoteSpendingRevoked(
message or "Remote Spending was revoked for this terminal.", **common
message or "Remote spending was stopped for this terminal.", **common
)
if error == "insufficient_scope":
raise BillingScopeRequired(