issue-edit.sh cannot select an identity (no --login, no API fallback), and get_gitea_login ignores MOSAIC_GIT_IDENTITY while get_gitea_token honors it #1226

Open
opened 2026-08-15 07:49:22 +00:00 by Ghost · 0 comments

Sibling of #1224, which covered pr-view.sh and issue-view.sh. This one is worse, because the
affected wrapper is a write path with no fallback, so the failure can be mistaken for a
completed edit.

Symptom

$ MOSAIC_GIT_IDENTITY=orchestrator issue-edit.sh -i 92 -b "$(cat body.md)"
2026/08/15 02:46:46 user does not exist [uid: 0, name: ]
$ # exits without "Updated Gitea issue #92"; a readback shows the body unchanged

An orchestrator tea login exists, is registered against the correct host, and works — every other
wrapper in the same session used it successfully. issue-edit.sh cannot be pointed at it.

Two distinct defects

1. issue-edit.sh has no identity flag and no API fallback. It resolves the login itself:

REPO_LOGIN=$(get_gitea_login) || { ... }
CMD=(tea issue edit "$ISSUE_NUMBER" --repo "$REPO_SLUG" --login "$REPO_LOGIN")

There is no --login option (its -l is --labels), no --repo/--host override, and unlike
issue-view.sh no Gitea API fallback when tea fails. So a stale default login is unrecoverable
for this wrapper — the operation simply cannot be performed through the sanctioned path.

2. get_gitea_login ignores MOSAIC_GIT_IDENTITY, while get_gitea_token honors it. This is
the root cause and the more valuable half:

$ get_gitea_login                                  -> usc          (stale default)
$ MOSAIC_GIT_IDENTITY=orchestrator get_gitea_login -> usc          (identity ignored)
$ MOSAIC_GIT_IDENTITY=orchestrator get_gitea_token git.uscllc.com -> (correct per-slot token)

The two halves of the same auth pair disagree about who the caller is. Any wrapper built on the
login half is unreachable by identity selection, however carefully the caller sets it. Worth noting
that get_gitea_token's refusal to borrow across hosts is correct and valuable — it refused to
hand a USC identity a mosaicstack token while this very issue was being filed. The asymmetry is the
bug, not the strictness.

Why it matters beyond convenience

Gate 7 says wrappers before raw provider CLI, and gate 8 says a failed required wrapper means
blocked. Together they are right, but they mean a wrapper that cannot express identity does not
merely inconvenience an agent — it makes a legitimate, authorized, already-reviewed edit
unperformable, with the only escapes being the break-glass override or a raw tea call that gate 7
forbids. The correct outcome in that position is to stop and file this, which is what happened; the
correction that could not be written into the issue body had to go into a comment instead.

Requested

  1. issue-edit.sh: add -l/--login, -r/--repo, -H/--host (matching pr-edit.sh, which has all
    three and works), plus the API fallback issue-view.sh already carries.
  2. get_gitea_login: honor MOSAIC_GIT_IDENTITY exactly as get_gitea_token does, so identity
    resolution is consistent across the pair.
  3. Worth a sweep for other wrappers resolving login without an override — the same shape is likely
    elsewhere.
Sibling of #1224, which covered `pr-view.sh` and `issue-view.sh`. This one is worse, because the affected wrapper is a **write** path with no fallback, so the failure can be mistaken for a completed edit. ## Symptom ``` $ MOSAIC_GIT_IDENTITY=orchestrator issue-edit.sh -i 92 -b "$(cat body.md)" 2026/08/15 02:46:46 user does not exist [uid: 0, name: ] $ # exits without "Updated Gitea issue #92"; a readback shows the body unchanged ``` An `orchestrator` tea login exists, is registered against the correct host, and works — every other wrapper in the same session used it successfully. `issue-edit.sh` cannot be pointed at it. ## Two distinct defects **1. `issue-edit.sh` has no identity flag and no API fallback.** It resolves the login itself: ```sh REPO_LOGIN=$(get_gitea_login) || { ... } CMD=(tea issue edit "$ISSUE_NUMBER" --repo "$REPO_SLUG" --login "$REPO_LOGIN") ``` There is no `--login` option (its `-l` is `--labels`), no `--repo`/`--host` override, and unlike `issue-view.sh` no Gitea API fallback when `tea` fails. So a stale default login is unrecoverable for this wrapper — the operation simply cannot be performed through the sanctioned path. **2. `get_gitea_login` ignores `MOSAIC_GIT_IDENTITY`, while `get_gitea_token` honors it.** This is the root cause and the more valuable half: ``` $ get_gitea_login -> usc (stale default) $ MOSAIC_GIT_IDENTITY=orchestrator get_gitea_login -> usc (identity ignored) $ MOSAIC_GIT_IDENTITY=orchestrator get_gitea_token git.uscllc.com -> (correct per-slot token) ``` The two halves of the same auth pair disagree about who the caller is. Any wrapper built on the login half is unreachable by identity selection, however carefully the caller sets it. Worth noting that `get_gitea_token`'s refusal to borrow across hosts is *correct and valuable* — it refused to hand a USC identity a mosaicstack token while this very issue was being filed. The asymmetry is the bug, not the strictness. ## Why it matters beyond convenience Gate 7 says wrappers before raw provider CLI, and gate 8 says a failed required wrapper means `blocked`. Together they are right, but they mean a wrapper that cannot express identity does not merely inconvenience an agent — it makes a legitimate, authorized, already-reviewed edit unperformable, with the only escapes being the break-glass override or a raw `tea` call that gate 7 forbids. The correct outcome in that position is to stop and file this, which is what happened; the correction that could not be written into the issue body had to go into a comment instead. ## Requested 1. `issue-edit.sh`: add `-l/--login`, `-r/--repo`, `-H/--host` (matching `pr-edit.sh`, which has all three and works), plus the API fallback `issue-view.sh` already carries. 2. `get_gitea_login`: honor `MOSAIC_GIT_IDENTITY` exactly as `get_gitea_token` does, so identity resolution is consistent across the pair. 3. Worth a sweep for other wrappers resolving login without an override — the same shape is likely elsewhere.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mosaicstack/stack#1226