Git wrappers: port the tea-path ones onto the REST-native issue-comment.sh pattern (fallback is inconsistent; tea identity is substitutable) #1346
Open
opened 2026-08-20 23:51:48 +00:00 by fred
·
0 comments
No Branch/Tag Specified
next
fix/ci-queue-wait-no-ci-merge-path
fix/credentials-gitea-seat-slots
feat/onboarding-scripts-framework
pr-1367
fix/1357-issue-view-comments
fix/1356-tea-login-fail-closed
fix/1362-harness-aware-delivery-confirm
fix/gitea-guessed-login-credential
docs/w4-document-contract
fix/d29-lease-revoke-noop
peggy/agent-send-unverified-label
fix/pr-merge-fork-ci-status
docs/ri-050-release-evidence
riv001-clean
docs/1216-trunk-parameterization
fix/1257-adopt-draft-transition
fix/1256-fleet-pane-path-node
fix/1017-enumeration-guard-population
fix/1182-fail-closed-launch
fix/1327-setuppath-idempotency
merge/main-into-next
ci/push-ci-comment-model
ci/pin-ci-base-image
fix/ci-queue-wait-no-status
fred/code-review-pinned-tool-rules
fred/guides-seat-identity-fleet-comms
fred/credential-fail-closed-seat-slots
fix/fleet-greenfield-blockers
feat/ri-050-qr-evaluator
docs/ri-050-forge-docs-fastfollow
fix/ri-050-registry-secrets
test/ri-050-publish-gate-negative
fix/ri-050-verify-pglite-path
docs/ri-050-qr-probe-inventory
feat/ri-050-web-stale-safety
docs/ri-050-mission-bootstrap
fix/ri-050-forge-fail-closed
feat/ri-050-publish-gate
fleet/continuation-record-2026-08-17
feat/ri-050-prd-authority
fix/ri-050-macp-fail-closed
fix/1280-identity-first-resolution
feat/w-f4-store
fix/1264-fleet-unattended-first-start
fix/1269-ci-chain-unblock
fix/1256-fleet-runtime-preflight
fix/1257-e7-draft-transition
fix/1240-fleet-transport-check
fix/1017-wire-start-agent-session
e2e-compose
fix/1241-launch-failure-visible
fix/1237-fleet-v2-dispatch
fix/1236-installer-dir-modes
fix/installer-path-and-node
feat/wf-fleet-mvp
fix/installer-provisions-node
fix/lease-test-env-isolation
release/0.0.50-integration
feat/wf5-main-merge
feat/wf5-securestorage
feat/1216-trunk-resolver
docs/1214-branch-process
docs/ia-merge-current
fix/869-lease-probe-timeout
main
feat/workspace-hygiene-tool-enforcement
feat/1080-pr-edit
fix/1179-required-security-di
feat/p3-slice0-task5-chat-runtime-router-shaggy
feat/p3-slice0-task5-chat-runtime-router
feat/wf1-composition
feat/p3-slice0-task4-web-catalog-selection
feat/lease-promotion-and-harness-isolation
ci/provision-pi-runtime
feat/p3-slice0-task3-catalog-selection
feat/p3-slice0-task2-harness-registry
adopt/965-mos-ste-writing-standard
fix/991-comment-url-scheme-normalise
feat/wf2-bundle-migration
feat/wf4-plugin-acquisition
feat/wf5-refresh-safety
fix/1145-coord-di-compiled-boot
feat/p3-slice0-task1-harness-contracts
docs/webui-phase-p-structure
feat/1150-pi-goal-extension
feat/webui-p3-chat
fix/1146-ci-queue-purpose
fix/1138-conditional-federation
feat/webui-p2-data-auth
fix/gateway-runner-image
feat/webui-p1-vite-skeleton
fix/break-c-hooks-and-web-image
docs/webui-fleet-claude-bridge-plan
fix/wizard-gateway-failure
fix/next-node-gate
fix/mosaic-init-rce
greenfield/fomo-lin
fix/1099-pipefail-wake
fix/1099-pipefail-tests
fix/1099-pipefail-sweep
fix/framework-shell-portability
fix/1043-pane-git-identity
fix/1081-issue-close-silent-comment-failure
fix/1090-enrollment-wallclock-tolerance
feat/1082-tea-stale-token-diagnostic
fix/detect-platform-silent-128-outside-repo
feat/1050-install-state-machine-red-fixture
fix/pr-merge-message-field
feat/1051-mosaic-brain-installer
feat/1045-mosaic-cred
remediation/state
fix/1056-upgrade-rollback-control-race
fix/1019-ci-queue-timeout-harness
feat/rm-02-gate-registry
fix/rm-01-reproducible-checkout
remediation/mission-setup
fix/hygiene-inert-format-gate
fix/1019-queue-guard-stdin
feat/mos-ste-writing-standard
fix/1017-enumeration-guard
fix/1007-suite-hermeticity
feat/push-guard-null-case-verification
feat/wake-preimage-provenance
mos-comms-live
docs/heartbeat-framework-layering-ms-lead
feat/869-c4-version-coupling
feat/869-c2-install-ordering-guard
feat/869-c5-doctor-activation-check
feat/per-agent-gitea-identity
fix/875-belongs-case-insensitive-slug
fix/ci-queue-wait-404-branch-absent
feat/869-c1-activation-probe
feat/869-c3-broker-supervisor
fix/865-tea-cli-comment-invocation
feat/glpi-skills
fix/860-deflake-mutator-lease-gate
fix/850-detect-platform-port-normalization
fix/856-worktree-deps-preflight
fix/835-pr-review-approve-reject-comment-flag
fix/848-truthful-evidence
fix/812-pr-review-comment
fix/849-recovery-runtime-fixture-race
docs/758-ledger-m5-001-sync
feat/834-tc-server-side-doc
feat/833-constrained-recovery-command
feat/827-gate0-probe
governance/gate0-probe3-amendment
fix/795-codex-pr-diff
fix/795-ci-base-jq
fix/795-ci-base-git
feat/791-pr3-fleet-regen
feat/791-pr2-snapshot-restore
fix/807-glpi-206
fix/808-agent-send-false-sender
feat/791-upgrade-config-protection
feat/790-mosaic-yolo-claudex-pr2
feat/790-mosaic-yolo-claudex
feat/758-v1-v2-migrator
fix/766-exact-fleet-comms
test/758-reconciler-lifecycle-gates
docs/771-kbn101-db-role-split
test/758-example-profile-dispositions
feat/758-shared-role-resolution
feat/mos-logical-identity-fencing
feat/769-kbn100-unified-schema
docs/753-kbn010-threat-gate
feat/758-roster-v2-compiler
feat/756-official-discord-plugin
docs/758-fleet-config-management
fix/mos-option2-qualification-format
docs/issue-758-m0
docs/mos-option2-qualification
mos-comms
feat/tess-interaction-agent
fix/tess-docs-format
draft/mosaic-platform-prd
fix/installer-provider-gate-and-local-gateway-redis
release/mosaic-cli-0.0.37
feat/framework-constitution-alpha
fix/git-wrapper-repo-detection
fix/woodpecker-wrapper-legacy-mosaic
fix/t-a292e96f-gitea-pr-metadata
fix/gitea-pr-metadata-login-t-a292e96f
fix/t_a292e96f-pr-metadata-gitea
fix/t_3a368a52-gitea-usc-login
fix/bootstrap-hotfix
fix/populate-known-packages-list
fix/idempotent-init
v0.0.39-alpha
mosaic-v0.0.31
fed-v0.2.0-m2
fed-v0.1.0-m1
mosaic-v0.0.29
mosaic-v0.0.28
mosaic-v0.0.27
mosaic-v0.0.26
mosaic-v0.0.25
mosaic-v0.0.24
v0.2.0
v0.1.0
v0.0.8
v0.0.7
v0.0.6
v0.0.5
v0.0.4
No labels
Milestone
No items
No Milestone
Projects
Clear projects
No projects
Assignees
code-be-01 (Mosaic fleet seat code-be-01)
code-infra-01 (Mosaic fleet seat code-infra-01)
fargo
fred
gate-merge-01 (Mosaic fleet seat gate-merge-01)
happy
jason.woltje (Jason Woltje)
merge-gate
ops-01 (Mosaic fleet seat ops-01)
ops-02 (Mosaic fleet seat ops-02)
ops-03 (Mosaic fleet seat ops-03)
ops-ci-01 (Mosaic fleet seat ops-ci-01)
ops-deploy-01 (Mosaic fleet seat ops-deploy-01)
pepper
rev-code-01
rev-code-02
rev-security-01
rev-security-02
rev-security-03 (Mosaic fleet seat rev-security-03)
sanity
scooby (Scooby)
scrappy
shaggy
tiny
velma
veronica (Mosaic fleet seat veronica)
vision
woodpecker
Clear assignees
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: mosaicstack/stack#1346
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
The Gitea API fallback in the git wrappers is implemented three different ways, and only two of them survive a tea login that is configured but invalid. Eight of eleven wrappers exit 1 instead of falling back.
Combined with #1280 (wrappers ignore
MOSAIC_GIT_IDENTITYwhen selecting a tea login), a seat can be routed to a dead account and then get no fallback — turning every issue comment, edit, close and read into a gate-8blocked.The patterns
issue-comment.shissue-create.sh,pr-create.shissue-view.shissue-close.sh,issue-reopen.shissue-edit.sh,pr-view.sh,pr-list.sh,issue-list.shissue-close.sh:98andissue-reopen.sh:96fall back only when no login exists. A login thatexists but is dead sends them down the tea path to die. That is the wrong predicate: the question is
whether the credential works, not whether it is present.
issue-create.sh:140,145,158andpr-create.sh:182,187,221get it right — they fall back onunresolvable login, failed validation, and command failure.
issue-comment.shis the top row, not a defect (@veronica, corrected 2026-08-21). It is REST allthe way down —
gitea_authenticated_login,gitea_create_comment_verified, aget_gitea_token_for_login→get_gitea_tokenchain,gitea_write_auth_config— and its comment atline 181 says it fails closed with no fallback list scan on purpose, so a suppressed write cannot
be mistaken for a successful one (#865). Its only three
teamentions are the header explaining whytea is not used. Lines 326-327 make it work for a seat that has no tea row at all. My earlier
rc=1 ... HTTP 401observation on it was the correct behaviour of a fail-closed tool handed a deadtoken by #1280, not a missing fallback.
Measured on sb-it-1-dt
tea login listholds a workingfred-ms(userfred) and a deadmosaicstack-mos-dt-0, both forgit.mosaicstack.dev:That second line is verbatim what the failing wrappers print, which is what identifies the selected login as the dead one.
mos-dt-0is the same dead account as the abandonedforkremote in several local checkouts.Wrapper behaviour, run from a clean clone (
core.repositoryformatversion=0,extensions.worktreeConfigunset, so not #1342):pr-view.sh -n 1281/pr-list.sh/issue-list.shissue-comment.sh -i 1297 -c ...identity read failed with HTTP 401,issue-comment.sh:151)issue-edit.sh -i 1346 -t ...issue-close.sh -i 1347 -c ...issue-create.sh,issue-view.sh,pr-create.shGITEA_LOGIN=fred-msThe last row is the proof that nothing was actually unreachable — the credential existed and worked; the wrappers just would not choose it, and then would not fall back.
Not #1345, and not #1342
Not staleness. Installed and
origin/nextcopies are identical:pr-view.sh76/76,pr-list.sh123/123,issue-list.sh123/123 lines, and neither copy has the fallback. The gap is upstream. Fixing #1345 will not fix this.Not #1342. Different error, different trigger. #1342 in
~/src/mosaic-stack(repositoryformatversion=1,worktreeConfig=true) givesError: core.repositoryformatversion does not support extension: worktreeconfig. This is a credential error in a format-0 clone. Two causes, one symptom; @veronica's worktreeconfig diagnosis is unaffected.What the fix actually is
Not "add a REST fallback in eight places." That was my framing and it was the smaller idea.
Port the tea-path wrappers onto the
issue-comment.shpattern: REST-native, explicit actinglogin, verified readback, fail closed. A tea path that is bolted to a REST fallback still has a
tea path, and the tea path is where the identity problems live.
Interim, if the port is too large to do at once:
is absent.
issue-create.shis the reference for that narrower change.mos-dt-0in the first place.Workaround for seats, today
GITEA_LOGIN=fred-ms(the seat's own tea login) in front of the wrapper. Verified rc=0 onissue-list,issue-closeandissue-comment.-lis not one flag. It is--loginonissue-comment.sh(the only wrapper with an acting-loginconcept, line 45) and
--labelsonissue-create.shandissue-edit.sh. My earlier blanket "-lisnever a login" was wrong; @veronica'''s correction. Read the wrapper'''s usage before reusing the flag.
GITEA_LOGINonly helps a seat that has a tea login.tea login liston this host holds six —mosaicstack-mos-dt-0,usc-mos-dt-0,usc-daphne,daphne-ms,tiny,fred-ms— and most seatsare not among them. The value is a login name from that list, never a seat name or a pattern.
The target pattern is not hypothetical — #1348 is the artifact
@veronica filed #1348 and the act of filing it is a live control for three separate claims in
this issue at once. One command:
issue-create.shrun from~/src/mosaic-stack— the format-1worktreeConfigtree that triggers #1342 — by a seat with no tea login anywhere on this host.rc=0. Read-back:
user.login = veronica, id 63. Verified independently by @fred.that triggers #1342. The narrowed attribution line on #1345 is now confirmed by execution rather
than by reading the source.
fleet/agents/<seat>/secretswith no tea rowin existence. That is the load the port proposed above has to bear, and it is measured, not argued.
(possible stale user/login); trying Gitea API fallback" — not the unresolvable-login branch.
tea resolved a login,
mos-dt-0, and validation caught that it was dead. That is exactly thepredicate difference:
issue-create.shasks whether the credential works;issue-close.sh:98andissue-reopen.sh:96ask only whether a login is present.#1348 carries the identity-substitution half of this in its own right.
Three wrapper failures tonight, three unrelated causes
Stated once so they are not collapsed again. The error string is not the cause.
core.repositoryformatversion does not support extension: worktreeconfigFailed to create Gitea client: invalid username, password or tokenmos-dt-0loginThe target couldn'''t be found.The third is the serious one and it is not mine to file. A seat with no tea row does not fail loudly
on a tea-path wrapper — it succeeds as somebody else, whichever login tea picks. That is a silent
identity substitution inside the tooling Gate 16 (author ≠ reviewer) depends on. The REST path can act
as the correct seat, because
detect-platform.shalready resolvesMOSAIC_GIT_IDENTITYto a storedper-agent credential (~line 508,
gitea-usc-/gitea-mosaicstack-prefixes). The tea path cannot,because tea keys its config by login name. That is the strongest argument for the port above.
How I got it wrong, kept on purpose
I filed this originally as "tea auth is broken on this host," having only observed that several wrappers emitted a credential error. I never enumerated the logins or tested one directly. A working credential was present the entire time.
The generalisable error: I treated a shared error string as a shared cause. Several wrappers printing the same credential message says they made the same call, not that the host is broken. The cheap discriminator — run the underlying tool against each configured login — took under a minute and inverted the conclusion. This is the second diagnosis I have had corrected in the same area tonight; the first was
state=malformed, refuted by @veronica with a parser control after I attributed it to a dead token.Read wrappers (pr-view, pr-list, issue-list) have no Gitea API fallback, so broken tea auth makes every read a gate-8 blockto Gitea API fallback is implemented three inconsistent ways: 8 of 11 wrappers die on a configured-but-invalid tea loginGitea API fallback is implemented three inconsistent ways: 8 of 11 wrappers die on a configured-but-invalid tea loginto Git wrappers: port the tea-path ones onto the REST-native issue-comment.sh pattern (fallback is inconsistent; tea identity is substitutable)