BBramaDocs
Browse documentation

Brama CLI command reference

brama subscription

Enter the command group that reads the subscription pool and acts on one provider’s subscription credentials.

Invocation

brama subscription <COMMAND>

A subcommand is required. This group has no options and performs no mutation by itself.

Commands

Discover accounts without sharing grants

brama subscription discover --gateway-consumer <consumer> --bearer-role <console bearer role> --json

Run discovery where your coding harness holds its accounts. Brama reads the public account inventory and usage report, not the harness's credential store. The serving gateway also reads synchronized purchase receipts through Skrzynka. The report identifies each account's provider, address, reported plan, source and observation time. A failed source remains in errors; it is not an empty account list.

Supported local sources are omp usage accounts --json, omp usage --json and Claude Code's claude auth status. Claude Code contributes the email and reported subscription type only when its public status identifies a signed-in claude.ai account. API-key and third-party authentication are not converted into subscription accounts. An uninstalled harness is not a required dependency; an installed harness that fails or reports an incomplete identity retains its actual refusal. Brama never reads either harness's credential files.

omp usage --json also relays, per account, the provider's own plan windows (limits[]: for Claude the five-hour and the weekly ones) with each window's used fraction, reset instant and the harness's fetchedAt. Discovery records them in the usage ledger against the account's member as readings with usage_source: "harness", read at fetchedAt; a newer reading from any source replaces one, an older never does. That is how accounts.capacity in brama subscription list states what a discovered account has left before Brama holds a grant for it. A usage row that states windows but no fetchedAt, or a limit without amount.usedFraction, id or label, is refused by name in errors and records no reading for that account rather than an aged or empty one.

Receipt interpretation preserves accounts already read when a later source fails. A message without usable purchase evidence records its own error; a refused model route stops receipt interpretation for that discovery pass instead of repeating the unavailable request for every remaining message. The report retains the route's refusal and earlier observations. A subsequent maintenance pass can resume from the retained successful interpretations.

A plan's age comes from its source fact, not when discovery happened to read it: current harness status uses the report time, and a purchase receipt uses Skrzynka's sent_at. An older receipt cannot replace a newer reported plan. Purchase evidence with a missing or invalid date is refused with the message identity and cause. Pool JSON and CLI expose discovery.plan_at_ms; Desktop shows Plan fact, epoch ms, separately from first discovery and latest observation. Retained receipt interpretations without a source date are interpreted again rather than treated as current purchases.

The discovery response reports the plan and its fact time from the persisted account record, just like the pool view. Re-reading an older purchase receipt cannot make the immediate discovery result show an older plan than the account retains. The response also preserves the account's first discovery time; registration errors remain separate from these retained facts.

Desktop's Account discovery result shows the retained plan, its fact time and first discovery beside the registration outcome. An unconfirmed registration is not labelled registered, and these metadata do not claim that sign-in supplied a usable grant.

New members are named by provider and address, not priority. Discovery stores metadata and schedules the gateway's own sign-in through Weles on its selected host. An account that has no independent grant stays visible with its sign-in cause. Registration and a scheduled sign-in are not proof of usable capacity. Existing grants and retired members are not overwritten or reinstated.

Retirement also applies when an account was stored under an older member name. If its provider and address match only retired inventory members, discovery refuses before creating a provider-address member: the error names the retired member, account and provider. The CLI discovery report and Desktop's Account discovery result show this refusal. An existing nonretired member of that exact account remains eligible for metadata reconciliation. Real qualification uses an isolated gateway with an already retired legacy member and a harness that still reports its account, then checks that discovery neither adds another member nor changes retirement or sign-in state.

If a generated provider-address member ID is already occupied by a different account, discovery refuses before changing that member's ledger identity. The error identifies the coordinate, discovered account and provider in both the CLI report and Desktop's Account discovery result. The existing account, discovery metadata, credential and sign-in state remain unchanged. The real discovery_coordinate_collision_preserves_existing_member qualification in tests/subscriptions/discovery/retired.rs requires an isolated gateway with COLLISION_MEMBER naming that occupied coordinate, no prior discovery metadata on the member, and an actual harness report for EXPECTED_ACCOUNT and EXPECTED_PROVIDER; it invokes discovery and reads the member back to verify preservation.

Discovery also reads Zai account email and coding-plan tier from the harness's public metadata. A provider can declare discovery without declaring a Weles authorization or purchase capability. Such an account remains visible with its actual address, plan and source, but is not usable capacity: the missing authorization capability is retained as its grant refusal. Discovery does not copy a harness token, enable an undeclared browser login or authorize an account purchase. The existing real discovery qualification accepts the selected harness provider and Brama provider as inputs, including Zai when its actual report supplies an email.

Account observations are retained in Brama's state directory before receipt interpretation or vault inventory can delay reconciliation. An inventory refusal returns the retained observations with its cause; it does not create speculative subscription IDs or claim a grant. The next discovery pass reconciles those facts against the actual provider and account, preserving first discovery separately from the latest observation and plan date. Pending facts are cleared only after the enrollment pass persists every account successfully; concurrent reconciliation, unreadable retained state and persistence failures are explicit refusals. Older receipt interpretations missing source or discovery dates are interpreted again.

When reconciliation is refused, CLI output includes observations alongside the failure. Desktop's Account discovery result shows those addresses, reported plans, sources and first/latest observation times as awaiting reconciliation, not as registered members or usable grants. The failure beneath them explains why they have not joined the pool.

In Brama Desktop, choose Discover accounts in Subscription Pool. Discovery also runs when that view is activated and during maintenance. The resulting account rows show the same metadata and grant state as the CLI.

The Automatic sign-in report also retains checks that fail before a browser attempt, including dependency and task failures. The pool JSON exposes the current operation as automatic_sign_in.failure.stage and retains the check's code, detail and observation time in automatic_sign_in.last_check_failure. Desktop's Automatic sign-in inspector separates these from the last browser attempt and its observation time. Check failures do not pretend a browser login completed or impose a provider challenge cooldown. A later completed sign-in check or confirmed active grant supersedes the older check failure as the current failure; any retained historical check remains labelled separately.

Read and use saved resets

brama subscription list --gateway-consumer <consumer> --bearer-role <console bearer role> --refresh-usage --json
brama subscription reset codex --member <subscription-id> --reason 'restore this exhausted usage window' --gateway-consumer <consumer> --bearer-role <console bearer role> --json

Refreshing usage reads the provider's saved-credit report without consuming a credit. Each member exposes resets.offer, credit identities, remaining uses, expiry times, eligibility and any read failure. A failed read retains the older offer with its original observation time and a visible error. Desktop shows this report and provides a reasoned reset action on the selected member.

The saved-reset report separates the last check from the offer's observation time. A failed refresh advances the check time and retains its cause without making the older credit offer fresh. Both CLI and Desktop show these times and the provider's eligibility explanation, so remaining credits are not mistaken for permission to consume one.

The real reset-report refusal qualification uses a member with an already observed offer and an actual failing reset-report endpoint while provider usage remains readable. It refreshes through the CLI, verifies the new attempt and specific refusal, then reads the pool again to confirm the old offer and unchanged redemption journal. A healthy response or failure before the reset report is reached does not qualify this failure path. The journey neither changes credentials nor consumes credits.

For this refusal journey, supply RESET_REFUSAL_MEMBER, EXPECTED_RESET_REFUSAL_ENDPOINT, EXPECTED_RESET_REFUSAL_HTTP_STATUS and EXPECTED_RESET_REFUSAL from the actual provider refusal, alongside the gateway qualification inputs. The diagnostic preserves the request method, endpoint, member, HTTP status and refusal body even when that body is not JSON. A body-read failure names the read error; a successful HTTP response with malformed JSON names the decode error. Neither failure makes the retained offer current or confirms a reset.

Remote reset and policy commands likewise preserve a failing gateway's HTTP body before attempting JSON decoding. Their errors name POST, the actual endpoint and status, including a proxy's non-JSON refusal. The read-only gateway refusal journey runs subscription policy show with EXPECTED_POLICY_REFUSAL_ENDPOINT, EXPECTED_POLICY_REFUSAL_HTTP_STATUS and EXPECTED_POLICY_REFUSAL_BODY taken from an actual non-JSON refusal; pool reads must still reach the expected gateway revision. It does not set policy or consume a credit.

A reset requires a declared provider protocol, the exact member, its independent Brama grant, a reason and current eligibility. Missing declarations, mismatched providers, retired members and unsupported offers are refused. Report-refresh admission refusals are retained beside provider read failures, so the member shows why no fresh report was obtained. An intent and its outcome are recorded before and after the provider request. An uncertain response is not retried: later maintenance must reconcile the selected credit's consumption before another reset can be sent. A change in eligibility alone is not consumption evidence; if the provider exposes no consumption counter, the uncertain request remains visible and no further reset is submitted.

Read-only preparation precedes mutation intent: Brama resolves the provider organization and validates the authenticated reset request before recording it as requested. A failure there records refused with reset was not sent and the failed operation; it does not create an uncertain consumption hold. After intent is durable, a missing or unreadable POST response remains unconfirmed. CLI and Desktop show the same journal outcome.

A retired member is refused before provider report reads or reset mutation: subscription <id>: retired by its owner; no reset was sent. The refusal leaves its reset journal unchanged. Desktop disables the action for retired members; direct CLI and API calls enforce the same boundary.

Automatic use follows the policy the operator stated for the provider with brama subscription policy set (or Brama Desktop's Saved-reset policy on a member of that provider): --keep-credits credits are never spent automatically, a credit is spent on a blocked window only while that window stays blocked longer than --min-blocked-minutes, and a credit expiring within --salvage-horizon-hours is spent rather than lost. The policy is kept on the gateway in $BRAMA_STATE_DIR/reset-policy.json with its reason and time, show prints every provider's, and clear removes one. Brama states no number itself: a provider without a stated policy is only observed by maintenance, and an automatic redemption of it is refused naming the command that states one; a reset requested with brama subscription reset needs no policy. Refusals: a provider that declares no saved-reset report, an empty --reason, clearing a provider with no stated policy, and an unreadable policy file, each with its cause. Saved capacity is considered before paid acquisition; an unconfirmed reset prevents buying another account. A provider that still allows traffic is not treated as blocked merely because a displayed usage percentage looks full.

Codex expiry salvage may request a reset before the account is blocked; the provider decides whether there is useful capacity to restore. Its explicit nothing_to_reset and no_credit responses are recorded as refused, not as ambiguous consumption. No retry is sent within that operation. A later maintenance pass reads a fresh offer before deciding again. Transport failures and unrecognized outcomes remain unconfirmed and cannot authorize another mutation.

Output, state, and refusals

Pool JSON includes build, the identity of the Brama process that produced the report. Text output prints that version, source revision, platform and build time. It is the gateway's identity for remote commands, not the workstation CLI's revision. Desktop's Runtime screen exposes the gateway build through its health diagnostics; build identity does not prove a usable subscription or completion. Real subscription qualification requires GATEWAY_SOURCE_REVISION to name the intended gateway source and refuses a report from a different revision, retaining the actual response beside the CLI binary checksum and local source revision.

The real journeys check that gateway identity during setup, before account discovery, sign-in or reset requests. Missing or empty fixture inputs are refused, and a different gateway revision stops the journey before those operations. Each later pool read checks the same identity again, so a release change during the journey cannot silently inherit the earlier qualification.

Qualification also requires CLI_SOURCE_REVISION. Before contacting the gateway, the journey runs brama version, retains its actual output and refuses a binary whose product or source revision differs from the declared CLI candidate. CLI and gateway revisions are independent inputs for compatibility runs; recording a binary checksum alone does not establish which source it contains.

The group command itself produces only help or parser errors and changes no state. Omitting <COMMAND> or naming anything outside the list above is refused by Clap before a handler runs; use brama subscription --help to print the accepted tree. Taking a grant a coding harness already holds was removed: one OAuth pair has one holder, and a second one costs the first its session.

Back to the complete CLI command tree.