fix(mosaic): harden Gitea pr merge fallback #521
Reference in New Issue
Block a user
Delete Branch "fix/t_301e4e3b-pr-merge-gitea-empty-uid"
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?
Problem: pr-merge.sh preferred tea pr merge whenever a host tea login existed. On Gitea, tea identity preflight can succeed while non-interactive tea merge fails with the known empty identity error, permanently blocking a valid squash merge.
Change:
Exact fallback trigger:
Tests/evidence:
Tracking:
DO-178B Review: PR #521 — fix(mosaic): harden Gitea pr merge fallback
Software Level: C (Mosaic delivery wrapper/business-critical tooling)
Reviewer: ultron
Base:
755df9079eHead reviewed:
893dd19efbScope: packages/mosaic/framework/tools/git/pr-merge.sh, packages/mosaic/framework/tools/git/test-pr-merge-gitea-empty-uid.sh, docs/scratchpads/t_301e4e3b-pr-merge-gitea-empty-uid.md
Objective summary:
1 Requirements Traceability: PASS — PR body links t_245ad9d8/t_301e4e3b and issue #520.
2 Derived Requirements: PASS — API fallback safety behavior documented.
3 Configuration Management: PASS — branch targets main; head pinned above; scoped files only.
4 Functional Correctness: PASS for Gitea fallback — known empty uid path falls back; arbitrary tea failure blocks.
5 Structural Coverage: PASS for focused shell harness; broader coverage not applicable to shell wrapper.
6 Security Analysis: FAIL — eval injection remains in GitHub path of touched wrapper.
7 Data Integrity: PASS — merge action remains guarded by squash/main/queue checks before execution.
8 Robustness: PASS — fallback handles no-login and known tea identity failure; unknown failures fail closed.
9 Code Quality: FAIL — eval-based command construction remains in pr-merge.sh.
10 Framework Compliance: PASS — Mosaic squash/main/queue policies preserved for Gitea path.
11 Regression Protection: PASS for focused checks; full pnpm test failure documented as out-of-scope gateway DB setup.
12 Hands-Off Verification: PASS — diff is limited to declared wrapper/test/scratchpad scope.
Findings:
🔴 [BLOCKER] packages/mosaic/framework/tools/git/pr-merge.sh:193-195 — GitHub merge path still builds a command string with unvalidated PR_NUMBER and executes it via eval.
The review scope explicitly required verifying that shell quoting avoids eval-style injection risks. The Gitea path was fixed to quote arguments, but the same touched wrapper still has:
A mocked GitHub-platform probe with
-n '123; touch <sentinel> #'executed the injected command before reporting success. This is a command injection risk in a privileged delivery wrapper and fails the required shell-quoting check.Remediation:
PR_NUMBERbefore any metadata lookup/merge, e.g.[[ "$PR_NUMBER" =~ ^[0-9]+$ ]] || exit 1.cmd=(gh pr merge "$PR_NUMBER" --squash); [[ "$DELETE_BRANCH" == true ]] && cmd+=(--delete-branch); "${cmd[@]}".-n/--numberare rejected and do not execute on both GitHub and Gitea paths.Verification evidence run by reviewer:
bash -n packages/mosaic/framework/tools/git/pr-merge.shbash -n packages/mosaic/framework/tools/git/test-pr-merge-gitea-empty-uid.shshellcheck -x packages/mosaic/framework/tools/git/pr-merge.sh packages/mosaic/framework/tools/git/test-pr-merge-gitea-empty-uid.sh— PASSbash packages/mosaic/framework/tools/git/test-pr-merge-gitea-empty-uid.sh— PASS/home/hermes/.config/mosaic/tools/codex/codex-code-review.sh -b origin/main -o ...). Independent subagent review completed and agreed the Gitea-specific behavior is acceptable but GitHub eval is a material residual issue.Verdict: REQUEST CHANGES. Do not merge until the eval injection path is removed or PR_NUMBER is strictly validated before command construction. Tuesday should not proceed to CI/queue-guard/merge gate yet.
View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.