feat(review-gate): PR 自动审查闸门组件 + mcp-server --call 模式 - #15
Merged
Conversation
Add the 4th component: zcode-review-gate, a polling daemon that watches open PRs on configured GitHub repos, reviews each new head sha via the bridge's zcode_pr_review (git diff + mimosa deep scan + read-only ZCode recheck), and posts the pass/concerns verdict back as a PR comment. Same head sha is never reviewed twice (state-file dedup); failures retry with exponential backoff. Tokens never touch disk (injected per-command via git -c http.extraHeader). Also add a one-shot '--call TOOL <json>' mode to zcode-mcp-server so scripts/daemons can invoke a single tool without a stdio MCP session; locks/retries/read-only guardrails all go through the same TOOL_HANDLERS path. stdio behavior is unchanged.
P1:
- inject git token via GIT_CONFIG_COUNT/KEY/VALUE env (git>=2.31)
instead of -c argv; env is per-user, argv leaks to ps. GitError
messages never include env content (pinned by test)
- pass ZCODE_BRIDGE_REVIEW_TIMEOUT=REVIEW_TIMEOUT(3600) to the --call
subprocess so mcp-server's default 300s zcode timeout can't cut
deep-tier reviews short
P2:
- verdict regex excludes 'P' in the gap (P0[^\dP]{0,12}) so the
'P0/P1/P2 各 0/0/2' enumeration format fails parsing to None
(fail-safe concerns + note) instead of misreading numbers
- cache review result (report/verdict/counts) in state on comment
failure (status=comment_failed); retry with same head only re-posts
the comment, never re-runs the expensive zcode review; cache cleared
once reviewed
- rate-limit detection: also treat bare 429 and Retry-After header as
RateLimited, preferring Retry-After over X-RateLimit-Reset
- clone: dedicated 600s timeout, cleanup on failure, self-heal
incomplete clones via rev-parse check (delete + rebuild)
- clamp config lower bounds (poll>=30s, retry base>=1, max>=base,
attempts>=1) and comment max_body>=2000
- derive git web base from github_api (api.github.com->github.com,
GHE <host>/api/v3-><host>)
- include subprocess stderr tail (500 chars) in review failure errors
- re-read 'now' per PR instead of once per round
- systemd unit: TimeoutStopSec=120 with rationale; docs updated
(status enum pending/comment_failed, --call exit 1 wording, timeout
passthrough, token env wording)
Tests: 27 new cases (380 total) covering all of the above; ruff clean
- ensure_clone: only rc!=0 rev-parse failures trigger delete+rebuild; transient faults (OSError/TimeoutExpired) re-raise as repo-level round failure so a healthy clone is never deleted on a hiccup - split review timeouts: ZCODE_REVIEW_TIMEOUT (3600, passed through to mcp-server's zcode budget) vs REVIEW_TIMEOUT (= +120s headroom for the mimosa scan and process teardown on the gate side) - README: note gave_up keeps the cached report (<=max_body each) in the state file for forensics (watch its size), and that PR comments are at-least-once (issue comments have no idempotency key)
…rer)
GitHub's git smart-HTTP endpoints reject the Bearer scheme for OAuth
tokens (gho_*): 'remote: invalid credentials' on clone/fetch, while the
same token works fine as Bearer on the REST API. Switch the env-injected
http.extraHeader to Basic: base64('x-access-token:' + token), the
official placeholder username. REST (urllib) side keeps Bearer unchanged.
Verified live: ls-remote with x-access-token Basic succeeds with the
same token that failed as Bearer.
…t PATH systemd --user defaults to PATH=/usr/local/bin:/usr/bin:/bin (no ~/.local/bin), while the standard install puts components in ~/.local/bin — so a bare mcp_server name always failed with FileNotFoundError under the default deployment form (GC-8G live test). Two-pronged fix: - gate resolves a bare mcp_server name via PATH first, then falls back to ~/.local/bin/<name> when it exists and is executable (DEBUG-logged); anything else is passed through to the existing OSError path - the unit template now ships Environment=PATH=%h/.local/bin:... by default instead of mentioning it as optional; README install/config wording updated
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概要
第 4 个组件
packages/review-gate:常驻轮询 GitHub 仓库 open PR,对新 head sha 调zcode_pr_review完成审查(git diff + mimosa 深扫 + zcode 只读复核),带 verdict(pass/concerns + P0/P1/P2 分布)回贴 PR 评论。state 文件按 head sha 去重,失败指数退避。systemd --user 单元随包提供。变更
packages/review-gate/:gate 脚本 +zcode-review-gate.service+ README(安装/卸载/配置/运维/限制)packages/mcp-server/zcode-mcp-server:新增--call <tool> '<json>'一次性调用模式(+43 行零侵入,exit 0/1/2;锁/限流/只读护栏全走 TOOL_HANDLERS 路径)tests/test_review_gate.py+tests/test_mcp_call.py(+34 用例,全 fake 不碰网络/真实 git)验证