Files
stack/packages/mosaic/framework/tools/git
ms-lead-reviewer 597b06e10d fix(tools/git): restore executable bit on new per-agent-identity scripts
core.filemode=false in this worktree meant the initial commit recorded
git-credential-mosaic, test-git-credential-mosaic.sh, and
test-gitea-token-identity.sh as 100644. git invokes a path-configured
credential.helper directly (exec, not `sh <path>`), so git-credential-mosaic
must carry the executable bit; the two test scripts match the 100755
convention already used by the other test-*.sh harnesses in this directory.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 11:44:43 -05:00
..
2026-07-12 20:49:43 +00:00
2026-07-12 20:49:43 +00:00

Git provider wrappers

These scripts provide host-aware GitHub and Gitea issue, pull-request, milestone, and CI operations.

Durable review provenance

A successful provider write command—or a wrapper message based only on that command's exit code—is not durable review provenance. Review comments count as durable provenance only after the wrapper reads the created provider record back and verifies that it belongs to the intended repository and pull request and contains the exact submitted body (or verifies the provider-returned record ID).

pr-review.sh therefore fails closed when a Gitea comment cannot be written, its created comment ID cannot be identified, or provider read-back does not match. It reports comment success only after that read-back verification passes.

Per-agent Gitea identity (Gate-16 author≠reviewer)

By default, git push/fetch (via git-credential-mosaic) and the API wrappers above (via detect-platform.sh's get_gitea_token) all authenticate as the single shared Gitea account/token configured through tools/_lib/credentials.sh. That means every agent in a fleet commits, pushes, and opens PRs under one identity — with no cryptographic separation between an author and a reviewer.

Both git-credential-mosaic and get_gitea_token() resolve an optional per-agent identity before falling back to the shared account:

  1. MOSAIC_GIT_IDENTITY environment variable, or
  2. git config --get mosaic.gitIdentity (set per-worktree; persists on disk across non-persistent shells — git config mosaic.gitIdentity <agent-id>), or
  3. (git-credential-mosaic only) the username git itself supplies for the credential request.

If the resolved identity has a token file at ~/.config/mosaic/secrets/gitea-tokens/gitea-{usc,mosaicstack}-<agent-id>.token, that identity + token is used. Nothing configured → nothing changes: with no per-slot token file present, both tools fall through to the existing shared-account path unchanged, so this feature is a no-op on any host that hasn't provisioned per-slot tokens.

Enabling it for a clone

The framework installer syncs git-credential-mosaic to ~/.config/mosaic/tools/git/git-credential-mosaic (executable) on every install/update, but does not register it as git's credential helper automatically. Registration is a one-time, explicit step:

# Per-repo (recommended — scopes the helper to this clone only):
git config credential.helper "$HOME/.config/mosaic/tools/git/git-credential-mosaic"

# Per-worktree identity pin (Gate-16 separation):
git config mosaic.gitIdentity <agent-id>

This is deliberately not auto-registered on install/update: credential.helper is global, order-sensitive git config (~/.gitconfig) that can already hold an operator-chosen credential manager (keychain, store, manager-core, …) for repositories unrelated to Mosaic. Silently inserting an entry on every framework install/upgrade risks reordering or shadowing that operator-owned surface across the whole host — the same operator-owned config the installer's manifest system is otherwise careful never to touch. Because identity is already resolved per-worktree (mosaic.gitIdentity), the correct granularity for registering the helper is per-clone too, so a documented manual step is the right shape here, not a global auto-write.

PowerShell parity

detect-platform.ps1's Gitea wrappers authenticate through tea CLI logins (Get-GiteaLoginForHost), not a raw-token get_gitea_token-equivalent function — there is nothing to prepend the identity-resolution block to on the PowerShell side. A native PowerShell git-credential helper is also unnecessary: git-credential-mosaic is invoked by git's credential-helper protocol (stdin/stdout), which works identically under Git for Windows' bundled bash/sh when configured via credential.helper, without a .ps1 counterpart. A tea-login-based per-agent identity for the PowerShell wrappers is a separate, larger design (mapping identities to tea login profiles) and is out of scope here.