Skip to content

feat(platform): give AuthState::LoginFailed a typed kind - #401

Open
filvecchiato wants to merge 11 commits into
mainfrom
feat/typed-login-failure
Open

feat(platform): give AuthState::LoginFailed a typed kind#401
filvecchiato wants to merge 11 commits into
mainfrom
feat/typed-login-failure

Conversation

@filvecchiato

Copy link
Copy Markdown
Collaborator

Closes #390.

  • LoginFailed { kind, reason } with LoginFailureKind::{NoFreeAllowanceSlots, Other}. Hosts branch on kind and use reason as display copy.
  • The wallet reports refusals as prose over EncryptedResponse::Failed(String), so the core recovers the discriminant once in runtime/login_failure.rs instead of leaving every host to regex it.
  • That text comes from this workspace's own SlotError Display impls, and the tests classify straight from them — rewording one now fails CI here rather than silently turning a host's fast-fail into a retry loop.

Typing the inter-host wire itself is a follow-up: it needs a coordinated wallet rollout, and kind means hosts won't need a second API change when it lands.

@filvecchiato
filvecchiato requested a review from a team August 14, 2026 13:41

@Imod7 Imod7 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rust/crates/truapi-host-cli/src/main.rs line 1170 already does this classification:

err.to_string().contains("no free StatementStore slot")

With the new classify_login_failure, the same fact lives in two crates under two different rules, and the CLI copy is the weaker one: case-sensitive, and no long-term-storage marker. It is load-bearing, prepare_pairing_response uses it to rotate an exhausted auto-managed account. Could you move the markers plus one predicate into rust/crates/truapi-server/src/runtime/statement_allowance/slot.rs, next to the SlotError Display strings they mirror, and call it from both places. I tried it: pub fn reports_exhausted_period(text: &str) -> bool there, classify_login_failure as a wrapper, and the CLI calling truapi_server::statement_allowance::slot::reports_exhausted_period(&err.to_string()). It compiles and the new tests stay green.

Comment thread rust/crates/truapi-server/src/runtime/login_failure.rs Outdated
Comment thread rust/crates/truapi-server/src/runtime/auth_state.rs
Comment thread rust/crates/truapi-platform/src/lib.rs
@filvecchiato
filvecchiato requested a review from Imod7 August 17, 2026 16:31
Comment thread rust/crates/truapi-server/src/runtime/login_failure.rs Outdated
The signing host's account rotation and the login-failure classifier both
recover "this period has no slot left" from error text. Move the rule to
statement_allowance::slot as reports_exhausted_period, beside the SlotError
Display strings it mirrors, and call it from both. The CLI copy was
case-sensitive and matched only the statement-store rendering.
The kind is recovered from wallet prose this workspace does not control, so
a transient "no free slot" wording classifies the same way. Say so on the
variant and in the five host-facing copies: retry should not be the primary
action, rather than being impossible.
@filvecchiato

Copy link
Copy Markdown
Collaborator Author

On the duplicated classification in truapi-host-cli/src/main.rs — done, along the lines you suggested.

reports_exhausted_period(text: &str) -> bool now lives in rust/crates/truapi-server/src/runtime/statement_allowance/slot.rs, beside the SlotError Display strings it mirrors. classify_login_failure is a wrapper over it, and is_statement_slot_exhaustion calls truapi_server::statement_allowance::slot::reports_exhausted_period(&err.to_string()). The CLI picks up both things its own copy was missing: case-insensitivity and the long-term-storage rendering.

register_pairing_allowances only reaches register_statement_account, so NoFreePgasSlot is not reachable from that call site and the widening does not change which failures rotate an auto-managed account. FreeSlotsAwaitingSubmission still reads false, which is what keeps a pass from replacing a slot that is about to free up.

Added an_exhausted_period_is_reported_whatever_wraps_it in slot.rs, covering the rotation-relevant shape: the raw SlotError, the same error wrapped in the CLI’s "allowance registration for {label} failed: {e}" context, the long-term-storage variant, and FreeSlotsAwaitingSubmission staying false. The classifier tests in login_failure.rs are unchanged and green.

…locator

statement_allowance is cfg'd out on wasm32, and the browser host classifies
login failures, so hosting the predicate in its slot module broke the wasm32
build. It lives in runtime::login_failure and is re-exported as
truapi_server::reports_exhausted_period; the test pinning it against the
SlotError renderings stays beside those strings.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AuthState::LoginFailed carries only free text, so hosts must regex-match prose to classify a failure

3 participants