Skip to content

fix: 修复本地 Action 审计盲区,并区分审计未完成与基线漂移 - #8

Merged
HyxiaoGe merged 2 commits into
masterfrom
claude/project-review-feedback-0g4gvy
Aug 17, 2026
Merged

HyxiaoGe merged 2 commits into
masterfrom
claude/project-review-feedback-0g4gvy

Conversation

@HyxiaoGe

Copy link
Copy Markdown
Owner

背景

一次完整代码审阅发现一处实际漏检,以及若干会削弱审计可信度的结构性问题。

漏检的根因是两处叠加:

  1. build_source 只急切解析 .github/actions/** 下的本地 Action,其他路径靠 local_action_closure 惰性解析;
  2. audit_repository 的 inspect_action_references(source.local_actions.values()) 跑在全部 inspect 之前,而 inspect_release 从不计算受控 release 自身的 local action closure(release_capability_signals 只作用于其他 workflow,release_job_capability_signals 只作用于未声明 job)。

结果是权限最高的那条 workflow(dev Environment + registry 凭据 + self-hosted + 部署能力)可以通过 ./ci/actions/x 引入未锁定的第三方 Action,审计仍返回 PASS;prepare job 也能借同样路径隐藏部署能力。这与契约 §4「本地 Action 的外部 Action 同样受锁定约束」和 §3「prepare 必须是无部署能力的纯校验」直接冲突,属于实现与契约脱节,不是已声明的边界。

同时,周任务缺少重试与告警:任何一次 GitHub 5xx 都会表现为「漂移」,而 optional 调用的持续 5xx 会被降级成「缺少 dev Environment」这类假漂移。

改动

1. 本地 Action 盲区(先补 RED fixture 再实现)

  • 全部 uses: 引用检查移动到所有 inspect 之后执行,覆盖惰性解析结果;
  • inspect_release 解析并上报 release 侧 closure;prepare 纯净性判断覆盖其本地 Action;
  • 抽出 job_local_action_closure,与未声明 job 的判定共用;
  • 移除 inspect_primary_pr / inspect_auxiliary_pr 中的重复检查调用,避免同一 Action 被多个 workflow 引用时重复报告。

2. 审计可靠性

  • 新增 AuditUnavailable、[API_UNAVAILABLE]、ERROR 结论行与退出码 3;「审计没跑完」不再和「基线漂移」共用退出码;
  • gh api 对 5xx/429/连接失败做 4 次指数退避重试(BASELINE_AUDIT_RETRY_BASE_SECONDS 可覆盖);
  • optional 调用只在明确的终态状态码(404/403)下返回 None,持续不可用报 ERROR。

3. 可复用性与运维

  • 受保护分支参数化为 BASELINE_DEFAULT_BRANCH(默认 master),贯穿 API 路径、github.ref guard 原子、PR branches 与 branch protection 判定;四个现有仓库行为不变;
  • 引入 BASELINE_VERSION 与 CHANGELOG.md,审计输出回显版本与受保护分支;
  • 漂移 workflow 增加独立 notify job:仅用基线仓库自身 GITHUB_TOKEN 的 issues: write,只读审计 App 的零写权限不变;issue 正文只放运行链接,不回显可能含 secret 名称的审计输出。

4. 测试与文档

  • 新增 tests/unit/(27 个用例):直接覆盖表达式解析器、secret 静态可枚举性、gh api 重试与分支解析;审计器加 __main__ guard 以便导入;
  • 新增 contracts/error-codes.md 作为错误码事实源,测试双向校验实现与文档一致;
  • 删除钉死中文措辞的 34 处短语断言,改为契约骨架、文档链接与错误码覆盖等结构性断言;README / MAINTENANCE 收敛为入口,公共 MUST 只留在 contracts/;
  • 取消无效的 Co-Authored-By 强制约定(原地址解析不到任何 GitHub 账号,trailer 在 GitHub 上只是纯文本;AI 协作提交的署名实际来自 App bot 身份)。

验证

  • bash tests/test-audit.sh 全绿:133 个 fixture 用例 + 27 个单元测试 + 6 组契约校验;
  • 三个新 RED fixture 在修复前均 PASS,修复后分别报 [ACTION_PIN]、[LOCAL_ACTION]、[RELEASE_EVENT];
  • 退出码逐一验证:0 通过 / 1 漂移 / 2 参数错误 / 3 审计未完成;
  • ruff check、ruff format --check、shellcheck、py_compile、workflow YAML 解析全部通过。

合并后需按 MAINTENANCE 流程人工触发一次 Engineering baseline drift audit,确认四仓仍输出 PASS。

审阅中提出但未采纳的两项

  • 未把 deploy_capability 关键字扫描降级为 warning。现有 5 个 [PR_DEPLOY] fixture 说明这是刻意的阻塞项,且举不出四个真实仓库中的实际误报;为推测的噪音削减真实检测面不合适。改为在契约 §2 写清分工:结构性保证来自 contents: read + 无 secret + 无 Environment + 托管 runner 四条硬约束,关键字扫描是可被项目脚本绕过的次级网。
  • 未用 zizmor / actionlint 替换自研供应链检查。在一个论点全在「钉死依赖」上的仓库里引入未锁 SHA 的第三方二进制会自相矛盾;且该取舍取决于项目定位(自用护栏 vs 可复用基线),分支参数化已拆除技术障碍,定位决定留给维护者。

Generated by Claude Code

claude added 2 commits August 17, 2026 01:57
背景
----
审阅发现一处实际漏检:.github/actions/** 之外的本地 Action 只在被引用时惰性
解析,而供应链检查跑在解析之前,且 inspect_release 从不计算受控 release 自身
的 local action closure。结果是权限最高的 workflow 可以通过 ./ci/actions/x
引入未锁定的第三方 Action、prepare job 可借同样路径隐藏部署能力,审计仍返回
PASS。同时,周任务缺少重试与告警,任何一次 GitHub 5xx 都会表现为"漂移"。

改动
----
1. 本地 Action 盲区(先补 RED fixture 再实现)
   - 全部 uses: 引用检查移动到所有 inspect 之后执行,覆盖惰性解析结果。
   - inspect_release 解析并上报 release 侧 closure;prepare 纯净性判断覆盖
     其本地 Action。
   - 抽出 job_local_action_closure,与未声明 job 的判定共用。

2. 审计可靠性
   - 新增 AuditUnavailable、[API_UNAVAILABLE]、ERROR 结论行与退出码 3;
     "审计没跑完"不再和"基线漂移"共用退出码。
   - gh api 对 5xx/429/连接失败做 4 次指数退避重试;持续不可用的 optional
     端点报 ERROR,不再降级成"Environment 缺失"这类假漂移。

3. 可复用性与运维
   - 受保护分支参数化为 BASELINE_DEFAULT_BRANCH(默认 master),贯穿 API 路径、
     github.ref guard 原子、PR branches 与 branch protection 判定。
   - 引入 BASELINE_VERSION 与 CHANGELOG.md,审计输出回显版本与受保护分支。
   - 漂移 workflow 增加独立 notify job:仅用基线仓库自身 GITHUB_TOKEN 的
     issues:write,只读审计 App 权限不变;issue 正文只放运行链接,不回显可能
     含 secret 名称的审计输出。

4. 测试与文档
   - 新增 tests/unit/:直接覆盖表达式解析器、secret 静态可枚举性、gh api
     重试与分支解析;审计器加 __main__ guard 以便导入。
   - 新增 contracts/error-codes.md 作为错误码事实源,测试双向校验实现与文档。
   - 删除钉死中文措辞的 34 处短语断言,改为契约骨架、文档链接与错误码覆盖等
     结构性断言;README/MAINTENANCE 收敛为入口,公共 MUST 只留在 contracts/。
   - 统一 Co-Authored-By 约定,不再把 Codex 与 anthropic.com 邮箱域混用。

验证
----
- bash tests/test-audit.sh 全绿(133 个 fixture 用例 + 27 个单元测试 + 6 组
  契约校验)。
- 三个新 RED fixture 在修复前均 PASS,修复后分别报 [ACTION_PIN]、
  [LOCAL_ACTION]、[RELEASE_EVENT]。
- 退出码逐一验证:0 通过 / 1 漂移 / 2 参数错误 / 3 审计未完成。
- ruff check、ruff format --check、shellcheck、py_compile、workflow YAML 解析
  全部通过。

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HqomJN4HxRYdoenUgZ1KfP
背景
----
原约定要求提交追加 `Co-Authored-By: Codex <noreply@anthropic.com>`。该地址解析
不到任何 GitHub 账号,trailer 在 GitHub 上只渲染为纯文本,不产生协作者,也不
进入 contributors。其他项目 contributors 中出现的 Codex,来自
chatgpt-codex-connector 这类 GitHub App 的 bot 身份被记为 author/committer,
与提交正文是否写 trailer 无关。

改动
----
- 根 AGENTS.md 与 templates/AGENTS.md 不再强制该 trailer,并说明 AI 协作提交的
  署名实际来自 App bot 身份。
- 明确不得为满足格式而编造无法解析的邮箱地址。

验证
----
- bash tests/test-audit.sh 全绿。

Claude-Session: https://claude.ai/code/session_01HqomJN4HxRYdoenUgZ1KfP
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@HyxiaoGe
HyxiaoGe merged commit 09d3e2a into master Aug 17, 2026
1 check passed
@HyxiaoGe
HyxiaoGe deleted the claude/project-review-feedback-0g4gvy branch August 17, 2026 03:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants