feat(platform): give AuthState::LoginFailed a typed kind - #401
feat(platform): give AuthState::LoginFailed a typed kind#401filvecchiato wants to merge 7 commits into
Conversation
Imod7
left a comment
There was a problem hiding this comment.
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.
hosts/dotli: take main's pointer (dotli-community 29ef38b); the branch side was a stale gitlink from the pre-community dotli repo.
| let reason = reason.to_ascii_lowercase(); | ||
| // Every phrasing seen for an exhausted allowance period names both, and no | ||
| // other failure this workspace can render names both. | ||
| if reason.contains("no free") && reason.contains("slot") { |
There was a problem hiding this comment.
Moderate. This rule matches "no free" and "slot" anywhere in the reason, so it is a guess, but LoginFailureKind::NoFreeAllowanceSlots is documented as "Deterministic until the period rolls over: retrying wastes the user's remaining budget". I ran three transient strings through the classifier and all came back NoFreeAllowanceSlots: "no free slot in the connection pool, try again", "no free memory for slot allocation", "no free worker slot available, retrying shortly". That doc is host-facing, it is copied verbatim into truapi_platform.swift:1562-1564, so it is what an iOS host author reads when deciding whether to offer a retry. I would not narrow this rule, that reintroduces the bug this commit fixed. Could you soften the doc on the variant instead: say the kind is recovered heuristically from wallet prose and is a strong hint rather than a proof, and phrase the guidance as "do not make retry the primary action".
Closes #390.
LoginFailed { kind, reason }withLoginFailureKind::{NoFreeAllowanceSlots, Other}. Hosts branch onkindand usereasonas display copy.EncryptedResponse::Failed(String), so the core recovers the discriminant once inruntime/login_failure.rsinstead of leaving every host to regex it.SlotErrorDisplayimpls, 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
kindmeans hosts won't need a second API change when it lands.