fix(git-tools): harden Gitea PR metadata wrappers #518
Closed
jason.woltje
wants to merge 1 commits from
fix/t-a292e96f-gitea-pr-metadata into main
pull from: fix/t-a292e96f-gitea-pr-metadata
merge into: mosaicstack:main
mosaicstack:main
mosaicstack:mos-comms-live
mosaicstack:mos-comms
mosaicstack:feat/tess-interaction-agent
mosaicstack:fix/tess-docs-format
mosaicstack:next
mosaicstack:draft/mosaic-platform-prd
mosaicstack:enhance/tmux-send-buffer-race
mosaicstack:enhance/561-python-is-python3
mosaicstack:feat/federation-m3-verb-list
mosaicstack:fix/fleet-restart-tightloop-guard
mosaicstack:feat/federation-m3-scope-service
mosaicstack:feat/installer-dev-build-from-source
mosaicstack:fix/federation-tasks-prettier
mosaicstack:fix/installer-provider-gate-and-local-gateway-redis
mosaicstack:chore/fed-m3-dag-fix
mosaicstack:feat/federation-m3-verb-capabilities
mosaicstack:feat/federation-m3-query-source
mosaicstack:chore/fed-m3-backlog-sync
mosaicstack:release/mosaic-0.0.48
mosaicstack:fix/persona-class-pane-export
mosaicstack:feat/h3-fleet-provision
mosaicstack:fix/db-republish-backlog
mosaicstack:docs/north-star-per-agent-model-switch
mosaicstack:release/mosaic-0.0.46
mosaicstack:feat/a3a-agent-class-env
mosaicstack:feat/a3b-persona-contract
mosaicstack:feat/orchestrator-persona
mosaicstack:feat/h4-persona-overrides
mosaicstack:feat/h2-system-profiles
mosaicstack:feat/h1-persona-library
mosaicstack:feat/h-northstar-personas
mosaicstack:feat/a4-mosaic-backlog
mosaicstack:feat/a1-north-star
mosaicstack:feat/a2-role-registry
mosaicstack:release/mosaic-cli-0.0.45
mosaicstack:fix/h2-readiness-available
mosaicstack:release/mosaic-cli-0.0.44
mosaicstack:fix/fleet-pane-idle-activity
mosaicstack:release/mosaic-cli-0.0.43
mosaicstack:feat/h1-heartbeat-readiness
mosaicstack:release/mosaic-cli-0.0.42
mosaicstack:fix/fleet-claude-trust-gate-644
mosaicstack:fix/db-pglite-test-flake
mosaicstack:fix/framework-drift-reseed-642
mosaicstack:release/mosaic-cli-0.0.41
mosaicstack:chore/ci-base-node-24-alpine
mosaicstack:chore/ci-cache-phase1-prebaked-image
mosaicstack:feat/633-comms-block-runbook
mosaicstack:chore/ci-base-image
mosaicstack:feat/f3-m3-update-reseed
mosaicstack:feat/p6-docs-compliance-alpha
mosaicstack:release/mosaic-0.0.39
mosaicstack:feat/p5-overlay-composer
mosaicstack:release/mosaic-0.0.38
mosaicstack:feat/f3-m2-pi-harness
mosaicstack:feat/f3-watch-workdir
mosaicstack:feat/f3-hb-consistency
mosaicstack:release/mosaic-0.0.37b
mosaicstack:feat/fleet-mutable-add-remove
mosaicstack:feat/f3-pi-harness-hb
mosaicstack:feat/p4-1-comment-cleanup
mosaicstack:feat/fleet-presets-init
mosaicstack:feat/p4-upgrade-safe-migration
mosaicstack:feat/fleet-suite-prd
mosaicstack:release/mosaic-cli-0.0.37
mosaicstack:feat/fleet-ps-show-unmanaged
mosaicstack:release/mosaic-cli-0.0.36
mosaicstack:feat/fleet-heartbeat-sidecar
mosaicstack:feat/fleet-phase3-enablement
mosaicstack:release/mosaic-cli-0.0.35
mosaicstack:feat/fleet-launch-path
mosaicstack:feat/fleet-observability
mosaicstack:feat/p3-1-governance-gate-hardening
mosaicstack:feat/p3-constitution-extraction
mosaicstack:feat/p1p2-sanitization-gate
mosaicstack:feat/framework-constitution-alpha
mosaicstack:feat/p0-license-leak-sanitize
mosaicstack:docs/framework-agency-patterns
mosaicstack:fix/fleet-install-script-perms
mosaicstack:fix/fleet-preserve-agent-env
mosaicstack:release/mosaic-cli-0.0.32
mosaicstack:fix/fleet-release-hardening
mosaicstack:feat/fleet-cli-local-canary
mosaicstack:plan/tmux-fleet-durable-install
mosaicstack:fix/pi-skill-args-all-discover
mosaicstack:feat/pi-mosaic-tools-skill
mosaicstack:feat/tools-cheatsheet-salience
mosaicstack:fix/tooling-eval-injection-jq-json
mosaicstack:feat/us007-agent-registration
mosaicstack:docs/merge-authority-rule
mosaicstack:feat/mosaic-as-provisioning
mosaicstack:fix/pr-ci-wait-stdin-collision
mosaicstack:fix/t_301e4e3b-pr-merge-gitea-empty-uid
mosaicstack:ci/publish-appservice-image
mosaicstack:feat/mosaic-as-daemon
mosaicstack:feat/mosaic-as-m4a
mosaicstack:fix/pi-token-lean-skills
mosaicstack:fix/git-wrapper-rollup-20260526
mosaicstack:fix/git-wrapper-repo-detection
mosaicstack:fix/woodpecker-wrapper-legacy-mosaic
mosaicstack:fix/gitea-pr-metadata-login-t-a292e96f
mosaicstack:fix/t_a292e96f-pr-metadata-gitea
mosaicstack:fix/t_3a368a52-gitea-usc-login
mosaicstack:fix/bootstrap-hotfix
mosaicstack:fix/populate-known-packages-list
mosaicstack:fix/idempotent-init
No Reviewers
No Label
Milestone
No items
No Milestone
Projects
Clear projects
No project
Assignees
jason.woltje
Clear assignees
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: mosaicstack/stack#518
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.
Delete Branch "fix/t-a292e96f-gitea-pr-metadata"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Fix Mosaic Gitea PR metadata and merge preflight wrappers for USC repos. Normalizes Gitea head/base refs, rejects API error payloads, falls back to host-specific credentials, and avoids selecting the git.mosaicstack.dev tea login for git.uscllc.com merge preflight. Verification: bash -n, shellcheck, fixture harness, live sanitized PR #1905/#1908 metadata, and dry-run merge preflight.
7e1fb898e3to006d3f375e006d3f375eto88c3f6cd9188c3f6cd91toa665c0ac4cDO-178B Review: PR #518 — Mosaic pr-metadata.sh Gitea metadata fix
Software Level: B (merge tooling / credentialed Gitea API fallback)
Reviewer: Ultron
Base:
755df9079eHead:
a665c0ac4cVerdict: REQUEST CHANGES
Scope reviewed:
Verification performed:
Blocking findings:
🔴 [BLOCKER] packages/mosaic/framework/tools/git/pr-merge.sh:185 and :208 — host matching is bypassed when GITEA_LOGIN is set.
The fix claims tea login selection only happens when the login URL matches the repo host, but both dry-run and real merge use:
TEA_LOGIN="${GITEA_LOGIN:-$(find_tea_login_for_host "$HOST" || true)}"
That means any inherited GITEA_LOGIN overrides host validation. I verified this with a fixture repo whose origin is git.uscllc.com:
GITEA_LOGIN=mosaicstack ... pr-merge.sh -n 1905 --dry-run
-> Dry run: would merge PR #1905 on git.uscllc.com with tea login 'mosaicstack'
This preserves the exact wrong-login failure mode when the environment contains GITEA_LOGIN=mosaicstack, and it contradicts the acceptance criterion that the wrapper must not select the unrelated MosaicStack login for USC repos. Fix approach: validate any explicit GITEA_LOGIN against tea login list URL before use, or remove the env override and require host-derived selection only; fallback to the authenticated API path if the named login does not match HOST.
🟡 [IMPORTANT] packages/mosaic/framework/tools/git/pr-metadata.sh:62/:73 and pr-merge.sh:138-143/:152-157 — credential material is still passed to curl via command-line arguments.
The new basic-auth fallback passes username:password through
curl -u "$basic_auth", and token auth is passed through-H "Authorization: token $token". This avoids logging in normal script output, but command-line arguments may be visible to same-host process inspection while curl is running. Because the review request explicitly includes “no token leakage,” this should be hardened before merge if feasible. Fix approach: use curl config via a temporary chmod 600 file/fd, netrc with restricted permissions, or another mechanism that avoids putting bearer/basic credentials in argv; ensure cleanup uses trap.Non-blocking observations:
DO-178B objective summary:
1 Requirements Traceability: PASS — task and scratchpad map the regression and acceptance criteria.
2 Derived Requirements: PASS — API fallback and login matching are documented.
3 Configuration Management: PARTIAL — PR/head verified; CI blocked by infra.
4 Functional Correctness: FAIL — GITEA_LOGIN env override can reselect the wrong login.
5 Structural Coverage: PASS for added targeted shell harness; no full repo coverage expected for wrapper script.
6 Security Analysis: FAIL — credential argv exposure remains; wrong-login override can route a merge through unintended auth config.
7 Data Integrity: PASS — merge still requires base main and squash; non-main fixture rejected.
8 Robustness: PASS for API error/non-JSON handling in metadata path.
9 Code Quality: PASS — no shellcheck findings.
10 Framework Compliance: PARTIAL — docs/scratchpad present; CI blocked externally.
11 Regression Protection: PASS for local harness and live metadata checks; CI not green due infra.
12 Hands-Off Verification: PASS — review worktree clean after inspection.
Verdict: REQUEST CHANGES until the GITEA_LOGIN host-validation bypass is fixed. The credential argv exposure should also be addressed or formally accepted as existing tooling risk before merge.
Closing as superseded by #524 (rollup
821e19d). Orchestration assessment (rebase onto current main): every functional fix from this PR — set -euo pipefail, write_metadata(), curl_gitea_pull(), --dry-run, detect-platform get_gitea_token() hardening, test-pr-metadata-gitea.sh — is already present in main via #524. The post-rebase residual is regressive (older pr-merge.sh missing PR-number validation + empty-uid API fallback). No unique content remains. — orchestrator (mos)Pull request closed