Skip to content

Commit 68c8a37

Browse files
committed
feat: 生产就绪审计——三门修复(版本自标识/构建产物自救指令/Java mvnw 感知接入门禁)
基于 opencode-java-sdk + codex-java-sdk 六分支发布实测的三项优化: 1. gate_directive 输出 codeguard 版本号(第二行),AI 可判断门禁能力 与已知误报范围;末尾新增构建产物清理自救指令(rm -rf target/reports 等,不含 git commit/push,先清后提交两步走) 2. Java 门禁接入 java_project.analyze():UNVERIFIED 状态归 skipped 而非 FAIL;mvnw 存在时自动将 lint 命令的 mvn 替换为 ./mvnw; analyze 失败不阻塞门禁(走原路径) 3. pre_tool_git_guard 输出加版本前缀 [codeguard v0.12.0],AI 可 程序化区分门禁版本 测试 248 个全绿(+3:版本标识、构建产物清理指令、自救提示)。
1 parent bff90b3 commit 68c8a37

3 files changed

Lines changed: 32 additions & 2 deletions

File tree

‎hooks/gate_lib.py‎

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@
4242
from scope import FULL_SCAN_EXCLUDES, changed_files, scope_cmd
4343

4444
# === git 提交内容安全检查:绝不该进版本库的文件 ===
45+
CODEGUARD_VERSION = "0.12.0"
46+
4547
# 目录 = 构建产物/依赖快照**单一事实源**(scope.FULL_SCAN_EXCLUDES)+ IDE 目录。
4648
# 从单一来源派生:清单只在 scope.py 改一处,"入库面"与"扫描面"永不漂移
4749
# (此前两份手抄清单已经漂移:扫描面缺 out/.next/coverage 等 14 个目录,
@@ -140,7 +142,7 @@ def _gate_cache_path(project_root: Path) -> Path:
140142
return Path(tempfile.gettempdir()) / f"codeguard-gate-{os.getuid()}-{key}.json"
141143

142144

143-
def _worktree_fingerprint(project_root: Path) -> str:
145+
def _worktree_fingerprint(project_root: Path, *, max_files: int = 500) -> str:
144146
"""工作区指纹:三路改动的**名字 + stat** 指纹(不再哈希全文内容)。
145147
146148
只用 index mtime 会漏掉"文件已修但未 git add"——键不变 → 60 秒内继续
@@ -459,6 +461,21 @@ def check(lang: str):
459461
if not ok:
460462
return (lang, None, f"{lang} 工具链不可用未验证:{reason}(安装: {hint})")
461463

464+
# Java 门禁接入 java_project 分析:mvnw 感知 + 工具链失配归跳过。
465+
if lang == "java":
466+
try:
467+
from java_project import analyze as _jp_analyze
468+
_jp = _jp_analyze(str(project_root))
469+
if _jp.get("status") == "UNVERIFIED":
470+
return (lang, None,
471+
f"{lang} 项目分析 UNVERIFIED({_jp.get('build_system', '?')}),"
472+
f"原因: {'; '.join(_jp.get('reasons', []))},本次未验证")
473+
exe = _jp.get("executable")
474+
if exe and base_cmd and base_cmd[0] in ("mvn", "gradle"):
475+
base_cmd = [exe] + base_cmd[1:]
476+
except Exception:
477+
pass # java_project 分析失败不阻塞门禁,走原路径
478+
462479
outputs: list[tuple[int, str, str]] = []
463480
stale_notes: list[str] = []
464481
# 项目级命令(mvn/gradle 等,无 {file} 占位符)不追加文件路径——
@@ -877,11 +894,16 @@ def gate_directive(failures: list) -> str:
877894
"""
878895
header = [
879896
summarize_failures(failures),
897+
f"codeguard v{CODEGUARD_VERSION}",
880898
"─" * 60,
881899
"**给 AI 的强制指令**:提交门禁未通过,禁止执行 git commit / git push。\n"
882900
+ "**⚠️ 整个工具调用没有执行**:被拦截的是一次包含 git commit/push 的完整 Bash "
883901
"调用——其中非 git 的前序步骤(写文件、跑脚本)也全部未运行。请把「修复」与"
884902
"「提交」拆成两次独立的工具调用,修完再单独执行提交。\n"
903+
+ "**⚠️ 如果报错涉及 target/、dist/、build/ 下的构建产物**:请先单独"
904+
"运行清理命令(如 `rm -rf target/reports`,不含 git commit/push),"
905+
"清理完成后再重试提交——本门禁在命令执行前拦截,此前命令链中的清理"
906+
"步骤不会被执行。\n"
885907
+ "请立即处理:1) 按下面「怎么修」逐项修复(能自动修复的先跑自动修复命令);"
886908
"2) 纯 lint 类修复可直接继续、不必逐项追问;但凡涉及付费、发布、删除、"
887909
"密钥、或跨出本仓的操作,必须先征得用户同意再执行;"

‎hooks/pre_tool_git_guard.py‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,9 @@ def main() -> int:
641641

642642
# 每个被操作的仓库独立跑:linter 门禁 + 提交内容安全检查
643643
# (commit 查暂存区;push 查未推送提交的 diff,防已提交未发现的坏文件)
644+
from gate_lib import CODEGUARD_VERSION
644645
reports = []
646+
version_tag = "[codeguard v" + CODEGUARD_VERSION + "]\n"
645647
for project_root in roots:
646648
# 保留删除路径用于影响分析;单文件 linter 自行过滤不存在的文件。
647649
root_extra = list(extra)
@@ -650,7 +652,7 @@ def main() -> int:
650652
exact=True, pending_commit=pending_commit,
651653
)
652654
if failures:
653-
reports.append(gate_directive(failures))
655+
reports.append(version_tag + gate_directive(failures))
654656
unknown = [s for s in _skipped if "本次改动未涉及" not in s and " SKIPPED:" not in s
655657
and "markdown 风格告警" not in s]
656658
if unknown:

‎tests/test_hardening_fixes.py‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,12 @@ def test_directive_mentions_whole_call(self) -> None:
9090
self.assertIn("拆成两次独立的工具调用", text)
9191
# 首行契约保持:综述在最前
9292
self.assertTrue(text.splitlines()[0].startswith("codeguard ❌ 提交门禁未通过:"))
93+
# 版本自标识
94+
self.assertIn("codeguard v", text)
95+
# 构建产物清理自救指令
96+
self.assertIn("rm -rf target/reports", text)
97+
self.assertIn("不含 git commit/push", text)
98+
self.assertIn("命令执行前拦截", text)
9399

94100

95101
class CacheKeyTests(unittest.TestCase):

0 commit comments

Comments
 (0)