With no --login, both wrappers resolved a login by GUESSING it from the repo host
(get_gitea_login_for_host / get_gitea_login), then looked that name up in
~/.config/tea/config.yml. On git.mosaicstack.dev the guess resolves to
mosaicstack-mos-dt-0, a SHARED account. get_gitea_token_for_login returns the
matching token string with no authentication check anywhere in its body, so it
returns rc=0 for a dead credential and the `|| get_gitea_token` fallback never
fires. The identity-aware resolver was unreachable on this path.
Measured on git.mosaicstack.dev with MOSAIC_GIT_IDENTITY set:
get_gitea_token_for_login <guessed> rc=0, token authenticates HTTP 401
get_gitea_token <host> rc=0, token authenticates HTTP 200
Control: the same endpoint with no credential returns 401.
The dead token is what made this visible; it is not the defect. Had the shared
token been alive, every seat's reviews and comments would have been authored by
the shared account, making Gate-16 author-is-not-reviewer unenforceable across
the fleet. A caller that passes no --login is asking to act as ITSELF, and the
guess answered a question nobody asked.
This removes the guess and its tea lookup from the no---login path in both
wrappers. That path now resolves the acting identity's own credential via
get_gitea_token, which fails loud on a fleet host when no identity resolves.
That refusal is the correct outcome and is deliberately not fallen back from.
Unchanged on purpose:
- get_gitea_token_for_login keeps its behaviour and its 53 assert_token pins in
test-gitea-login-resolution.sh. pr-edit.sh and the explicit --login branches
still use it; --login remains the only way to reach the tea store.
- No in-function verification was added. These wrappers verify every write by
id-plus-author read-back against the credential-derived login, so a revoked
token fails at the write with no misattribution. A GET /user pre-check would
also hard-fail a live token scoped write:repository without read:user, which
returns 403 while being fully comment-capable.
Tests: 28 pass. test-issue-close-fail-closed.sh fails identically on pristine
upstream (byte-identical output) and touches issue-close.sh, which this does not
modify. The wrapper test harness inherits an ambient MOSAIC_GIT_IDENTITY into its
sandbox HOME; tests were run with it unset.
Adversarial review by fargo, who found that reordering alone is a no-op wherever
MOSAIC_GIT_IDENTITY is unset, and that a 401/403 fail-closed pre-check would
reject correctly-scoped live tokens.