Problem
user login reports that a session exists. It does not report who you now are, usefully.
Today, a successful headless login prints:
Authenticated as: qa-1778157478
User ID:
Key hash: d0b21a57da040e65d1ef7dfab1b17f68c421bdf9303b6608146ead43
Session expires: 2026-08-25T19:18:43Z
Every line of that is true for an alias that can do nothing. A wallet can hold several Andamio access tokens,
and user login --alias X succeeds for any of them — the gateway verifies the signature against the
address, and every token in that wallet passes. There is no error, no warning, and user status shows an
active session.
The failure only surfaces later, as an empty result that is indistinguishable from "there is genuinely nothing
to do":
$ andamio teacher assignments list --output json
{"data":[]} # exit 0
That is correct per the failure contract — an empty result must be exit 0 — which is exactly why it cannot be
the place this gets caught. The distinction that is missing is "you hold no teacher role at all" versus
"you are a teacher and have no pending reviews."
How this bit us
During the #152 preprod sweep, preprod-wallets/andamio-preprod-001 turned out to hold three access tokens:
| Alias |
Teacher courses |
Commitments awaiting review |
qa-1778157478 |
2 |
1 (SUBMITTED) |
tester_0001 |
3 |
0 |
andamio-preprod-001 |
1 |
not surveyed |
#152's own text named the wrong one. Following it literally produces a run that logs in cleanly, lists
courses, finds nothing to assess, and reports success — having exercised the headline feature not at all. It
took an explicit wrong-alias control run to establish that, and nothing in the CLI would have volunteered it.
Proposal
Have user login print the roles the authenticated alias actually holds:
Authenticated as: qa-1778157478
Roles: teacher on 2 courses, owner of 2 courses, manager of 0 projects
Session expires: 2026-08-25T19:18:43Z
And say so plainly when there are none:
Roles: none — this alias holds no owner, teacher or manager role.
If you expected otherwise, check which access token you meant:
a wallet can hold several, and login succeeds for any of them.
Cost: one call, to an endpoint the CLI already uses
Resolved 2026-08-24 — this was originally filed asking whether three role lookups were too expensive. They
are not needed. GET /api/v1/user/me, already wired up as andamio user me, returns the whole summary in
one request:
{"data":{"counts":{
"teaching_courses": 2,
"managing_projects": 1,
"pending_reviews": 1,
"enrolled_courses": 0,
"contributing_projects": 0,
"total_credentials": 0
}}}
Measured across all three access tokens in preprod-wallets/andamio-preprod-001:
| Alias |
teaching_courses |
managing_projects |
pending_reviews |
qa-1778157478 |
2 |
1 |
1 |
tester_0001 |
3 |
0 |
0 |
andamio-preprod-001 |
5 |
4 |
1 |
pending_reviews is the field that actually discriminates. tester_0001 — the alias #152 wrongly named —
reads 0, which is exactly the trap. One integer at login catches what previously took a wrong-alias
control run to establish.
So the implementation is: after a successful login, issue the existing user me call and print a line from
counts. No new endpoint, no new client code.
Remaining design notes:
- Where: stderr, per the composability rules — it is human-facing progress, not data.
user login has no
--output json payload today, so nothing structured breaks.
- Failure handling (the one real risk): a
user me call that errors must not fail the login. The
session is valid regardless; degrade to printing the alias alone. A cosmetic lookup must never fail an
authentication.
- Applies to both login paths — headless (
--skey) and browser. The browser flow is the more likely place
for a human to pick the wrong identity, since they choose it in a wallet UI.
user status is local-only today (no network calls). Adding roles there would change that property, so
login is the better home unless we want status to gain a --refresh-style flag.
Release scoping
Worth deciding deliberately rather than by merge order. 1.0 is merged to main but not tagged (#128,
gated on the mainnet 2.5 cutover in andamio-ops#189). Anything landing on main now ships as 1.0 — after
the #152 sweep that just certified 1.0's surface against the v2.5.0-rc5 gateway.
This is a new user-facing behaviour, not a defect fix found by that sweep, so landing it now would change what
was validated. Recommend it goes after the 1.0 tag unless there is a reason to pull it forward, in which
case it needs a CHANGELOG entry and a re-verify of the login leg.
Related
Andamio-Platform/andamio-dev#18 — the documentation half: the acceptance-test prerequisites assume one
access token per wallet. Docs and tooling are complementary here; neither alone closes this.
#152 — the sweep that surfaced it. Evidence in docs/validation/2026-08-preprod-v2.5.0-rc5.md, § Finding 1.
Problem
user loginreports that a session exists. It does not report who you now are, usefully.Today, a successful headless login prints:
Every line of that is true for an alias that can do nothing. A wallet can hold several Andamio access tokens,
and
user login --alias Xsucceeds for any of them — the gateway verifies the signature against theaddress, and every token in that wallet passes. There is no error, no warning, and
user statusshows anactive session.
The failure only surfaces later, as an empty result that is indistinguishable from "there is genuinely nothing
to do":
That is correct per the failure contract — an empty result must be exit 0 — which is exactly why it cannot be
the place this gets caught. The distinction that is missing is "you hold no teacher role at all" versus
"you are a teacher and have no pending reviews."
How this bit us
During the #152 preprod sweep,
preprod-wallets/andamio-preprod-001turned out to hold three access tokens:qa-1778157478SUBMITTED)tester_0001andamio-preprod-001#152's own text named the wrong one. Following it literally produces a run that logs in cleanly, lists
courses, finds nothing to assess, and reports success — having exercised the headline feature not at all. It
took an explicit wrong-alias control run to establish that, and nothing in the CLI would have volunteered it.
Proposal
Have
user loginprint the roles the authenticated alias actually holds:And say so plainly when there are none:
Cost: one call, to an endpoint the CLI already uses
Resolved 2026-08-24 — this was originally filed asking whether three role lookups were too expensive. They
are not needed.
GET /api/v1/user/me, already wired up asandamio user me, returns the whole summary inone request:
{"data":{"counts":{ "teaching_courses": 2, "managing_projects": 1, "pending_reviews": 1, "enrolled_courses": 0, "contributing_projects": 0, "total_credentials": 0 }}}Measured across all three access tokens in
preprod-wallets/andamio-preprod-001:qa-1778157478tester_0001andamio-preprod-001pending_reviewsis the field that actually discriminates.tester_0001— the alias #152 wrongly named —reads 0, which is exactly the trap. One integer at login catches what previously took a wrong-alias
control run to establish.
So the implementation is: after a successful login, issue the existing
user mecall and print a line fromcounts. No new endpoint, no new client code.Remaining design notes:
user loginhas no--output jsonpayload today, so nothing structured breaks.user mecall that errors must not fail the login. Thesession is valid regardless; degrade to printing the alias alone. A cosmetic lookup must never fail an
authentication.
--skey) and browser. The browser flow is the more likely placefor a human to pick the wrong identity, since they choose it in a wallet UI.
user statusis local-only today (no network calls). Adding roles there would change that property, sologin is the better home unless we want
statusto gain a--refresh-style flag.Release scoping
Worth deciding deliberately rather than by merge order. 1.0 is merged to
mainbut not tagged (#128,gated on the mainnet 2.5 cutover in
andamio-ops#189). Anything landing onmainnow ships as 1.0 — afterthe #152 sweep that just certified 1.0's surface against the v2.5.0-rc5 gateway.
This is a new user-facing behaviour, not a defect fix found by that sweep, so landing it now would change what
was validated. Recommend it goes after the 1.0 tag unless there is a reason to pull it forward, in which
case it needs a CHANGELOG entry and a re-verify of the login leg.
Related
Andamio-Platform/andamio-dev#18— the documentation half: the acceptance-test prerequisites assume oneaccess token per wallet. Docs and tooling are complementary here; neither alone closes this.
#152— the sweep that surfaced it. Evidence indocs/validation/2026-08-preprod-v2.5.0-rc5.md, § Finding 1.