Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .agents/plugins/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,20 @@
"source": {
"source": "url",
"url": "https://github.com/partme-ai/partme-codeguard-plugin.git",
"ref": "v0.14.7"
"ref": "v0.14.8"
},
"policy": {
"installation": "AVAILABLE",
"authentication": "ON_USE"
},
"category": "Developer Tools",
"version": "0.14.7",
"version": "0.14.8",
"description": "Evidence-backed code checks and Git content gates for AI assistants, with Maven/Gradle module impact analysis. Save hooks provide feedback; unverified checks are explicit.",
"icon": "https://cdn.jsdelivr.net/gh/full-stack-plugins/codeguard-plugin@v0.14.7/assets/official-logo.png",
"icon": "https://cdn.jsdelivr.net/gh/full-stack-plugins/codeguard-plugin@v0.14.8/assets/official-logo.png",
"interface": {
"displayName": "代码规范守卫",
"shortDescription": "Trustworthy code checks and Java impact analysis",
"logo": "https://cdn.jsdelivr.net/gh/full-stack-plugins/codeguard-plugin@v0.14.7/assets/official-logo.png"
"logo": "https://cdn.jsdelivr.net/gh/full-stack-plugins/codeguard-plugin@v0.14.8/assets/official-logo.png"
}
}
]
Expand Down
2 changes: 1 addition & 1 deletion .codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "codeguard",
"version": "0.14.7+codex.20260923",
"version": "0.14.8+codex.20260923",
"description": "Evidence-backed code checks and Git content gates for AI assistants, with Maven/Gradle module impact analysis. Save hooks provide feedback; unverified checks are explicit.",
"author": {
"name": "Full Stack Skills / PartMe.AI",
Expand Down
2 changes: 1 addition & 1 deletion .zcode-plugin/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"en": "CodeGuard",
"zh-CN": "代码规范检查"
},
"version": "0.14.7",
"version": "0.14.8",
"description": "Evidence-backed code checks and Git content gates for AI assistants, with Maven/Gradle module impact analysis. Save hooks provide feedback; unverified checks are explicit.",
"description_i18n": {
"en": "Evidence-backed code checks and Git content gates for AI assistants, with Maven/Gradle module impact analysis. Save hooks provide feedback; unverified checks are explicit.",
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ python3 scripts/run_check.py --mcp /path/to/project
| list_languages | Registry ids and display names |
| analyze_java_impact | Read-only plan; accepts path and optional changed array |

Output logs default to <project>/out/.codeguard-last.log; CLI --quiet disables log writing. A failed multi-command check logs output from every executed check. The MCP execution trace reports phase, sequence, program, exit/failure and output lengths; it does not echo argv, environment overrides or captured output. Local logs can contain sensitive checker output: keep them out of version control. MCP auto_fix does not write when a Git scope cannot be established.
Output logs default to <project>/out/.codeguard-last.log; CLI --quiet disables log writing. A failed multi-command check logs output from every executed check. Diagnostic logs are replaced atomically with owner-only file permissions on POSIX; a symlinked output directory disables log writing without changing the check verdict. The MCP execution trace reports phase, sequence, program, exit/failure and output lengths; it does not echo argv, environment overrides or captured output. Local logs can contain sensitive checker output: keep them out of version control. MCP auto_fix does not write when a Git scope cannot be established.

## Configuration and coverage

Expand Down
2 changes: 1 addition & 1 deletion README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ python3 scripts/run_check.py --mcp /path/to/project
| list_languages | 注册表语言标识和名称 |
| analyze_java_impact | 只读计划,接受 path 和可选 changed 数组 |

日志默认在 <project>/out/.codeguard-last.log;CLI --quiet 关闭写日志。多命令检查失败时,日志保存每条已执行检查的完整输出。MCP 执行轨迹只返回阶段、序号、程序名、退出/故障及输出长度,不回显 argv、环境覆盖或检查器输出。本地日志可能含敏感文本,应排除出版本控制。MCP auto_fix 无法确定 Git 范围时不会写入。
日志默认在 <project>/out/.codeguard-last.log;CLI --quiet 关闭写日志。多命令检查失败时,日志保存每条已执行检查的完整输出。诊断日志以原子替换写入,POSIX 上仅当前用户可读写;输出目录是符号链接时不写日志,但检查结论不变。MCP 执行轨迹只返回阶段、序号、程序名、退出/故障及输出长度,不回显 argv、环境覆盖或检查器输出。本地日志可能含敏感文本,应排除出版本控制。MCP auto_fix 无法确定 Git 范围时不会写入。

## 配置与覆盖

Expand Down
2 changes: 1 addition & 1 deletion docs/current-architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ flowchart TD
```

`execution` 只记录进程证据,不把非零退出自动认定为代码违规。`verdict`、CVE 与 Dockerfile 报告解析决定 PASS、FAIL 或 UNVERIFIED;入口仅按各自协议呈现和聚合退出码。Git 提交检查使用 index 或预测暂存快照,推送检查使用 HEAD;保存钩子只给反馈。计划、未执行和未验证不能宣传为通过。
`language_check` 将 `PlanExecution` 的实际命令依序映射为应用层有界 `execution_trace`(检查、修复、复检阶段);`check_application` 将其进一步压成 MCP 安全元数据,不回显原始 argv、环境覆盖或捕获输出。失败日志保留各已执行检查的完整输出,可能含敏感文本,应排除出版本控制。终止命令仍决定既有状态、退出码和旧字段;未运行的计划命令不进入证据。
`language_check` 将 `PlanExecution` 的实际命令依序映射为应用层有界 `execution_trace`(检查、修复、复检阶段);`check_application` 将其进一步压成 MCP 安全元数据,不回显原始 argv、环境覆盖或捕获输出。失败日志保留各已执行检查的完整输出,可能含敏感文本,应排除出版本控制。项目日志和门禁截断日志共用 `storage.write_private_text` 的私有原子落盘;预置日志文件链接不被跟随,默认 `out` 目录为链接或不可写时不返回虚假日志路径,也不覆盖检查结论。终止命令仍决定既有状态、退出码和旧字段;未运行的计划命令不进入证据。
Git 命令的仓库定位与拟暂存解析共用入口传入的 cwd;显式 `cd`/`git -C` 无法绑定 Git 工作树时,硬门禁给出目标未验证并阻断,不退回到调用者仓或无关子仓。未给出显式目标且调用目录非仓时仍保留 workspace 子仓兜底。静态命令解析不等于完整 Shell 执行模拟。
一条命令链中的 Git 副作用先绑定为仓库与操作的有序对,再按仓库聚合检查面:纯 push 不读取该仓未提交的 index,同仓 commit→push 则保留已有 HEAD 与拟提交内容的并集。仓库级、内联及链式 `skipGate` 均按目标仓与操作顺序生效;已存在的仓库配置也可被同链先行 `git config --unset` 取消。链式设置跨 `||`、`;` 或换行时无法证明生效,门禁要求拆分命令;写入其它文件的 config 设置也不构成本仓豁免。语法、仓库归属、间接脚本与拟暂存分析共用引号/转义感知切分;参数文本中的控制符不能合成豁免。解析能力仍限于受支持的静态 Shell 形态。
一层 `bash`/`sh`/`zsh` 的 `-c`(含组合短选项)及可读脚本现在携带调用目录与正文进入同一 Git 操作计划;脚本内的 `git add` 可进入拟暂存范围,外层和内层 Git 操作按仓分别检查。识别到无法建模的间接 Git 操作、脚本内 `skipGate` 配置变更或跨解释器的暂存/提交关系时,明确以 Git 意图 UNVERIFIED 阻断,不借用调用者仓的检查结果。动态脚本、任意控制流及 Python/Node 中构造的 subprocess 仍未建模。
Expand Down
2 changes: 1 addition & 1 deletion kimi.plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "codeguard",
"version": "0.14.7",
"version": "0.14.8",
"description": "Evidence-backed code checks and Git content gates for AI assistants, with Maven/Gradle module impact analysis. Save hooks provide feedback; unverified checks are explicit.",
"author": {
"name": "Full Stack Skills / PartMe.AI"
Expand Down
4 changes: 4 additions & 0 deletions openspec/changes/refactor-codeguard-architecture/design.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ flowchart TD

`scripts/check_architecture.py` 仅解析第一方 scripts/hooks 的 AST,不执行被检查源码;检查所有静态导入(含函数内导入)、内核模块显式依赖白名单、相对导入与导入环。新增内核模块必须登记政策;不是 CodeGraph 的语义调用图替代,也不能保证运行时计算出来的动态加载关系。reporting 当前仍负责诊断日志落盘,所以只把 models/verdict 称为纯内核,不把整个包夸大为无 IO。CI 已配置独立检查步骤;真实远端运行留到发布验收。

本轮审计发现 CLI/MCP 与 Git 门禁均直接写原始诊断日志:前者位于项目 `out`,后者使用可预测的临时文件名。保留各自的日志路径和呈现职责,但由 `storage` 的统一私有原子文本写入负责落盘;应用不得再用普通 `write_text` 跟随预置链接或留下默认可读权限。日志故障只影响日志证据的可用性,不得覆盖检查结论;这不是完整的对抗性文件系统沙箱。

### 5. 命令语法、仓库观察与路径政策分离

`git_syntax` 只解释已支持的静态命令形态,不查文件、不起进程;`git_context` 负责仓库探测、读取一层解释器脚本和映射提交面,仓库探测复用执行内核。`PreToolUse` 入口保留宿主 JSON、绕过审计、门禁调用及报告输出,旧 Python helper 导入继续可用。间接脚本读取只保留一个实现,主入口不再重复读取脚本来判定模式。
Expand Down Expand Up @@ -299,6 +301,8 @@ tracked,`-f` 保留指定忽略文件;无显式路径的 -A/-u 仍按 [git a

## Risks / Trade-offs

- CLI `fix` 的结果条数不保证等于语言条数:一个 shell 语言可同时产生 zsh 跳过和 shfmt 执行结果。呈现及退出码须遍历每条实际结果,并使用结果自身的 `language`,不能按输入语言列表 `zip` 截断;真实 Git 工作树与失败 formatter 的黑盒测试防止假成功回归。

- 私有 monkeypatch 测试耦合旧模块 → 保留公开兼容面,新增黑盒行为测试先行;不以删除测试解决失败。
- 改造过程中两条路径暂时并存 → tasks 明确每个调用点迁移,最终审计重复实现是否消失。
- 主干还有其他会话开发 → 每批改动前核对 status;不覆盖未认领修改、不自动切分支。
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,30 @@
- **WHEN** 权威命令的 argv 含凭据文本,且检查器输出也包含该文本
- **THEN** 真实子进程仍收到原始 argv,MCP 的 `check_code_style` 和 `auto_fix` 执行轨迹不回显凭据;日志仍按既有本地路径保存原始诊断

### Requirement: Diagnostic logs SHALL be private and atomic

CLI/MCP 失败日志与 Git 门禁截断诊断日志可能包含检查器的原始敏感输出。写入 MUST 使用同一基础设施边界,创建的文件在支持 POSIX 权限的平台上 MUST 仅允许当前用户读写;替换 MUST 原子可见,不能跟随预置的日志文件符号链接覆盖其它文件。默认 `out` 日志目录若本身是符号链接,MUST 不向链接目标写入。日志写入失败 MUST 不掩盖已经得出的检查状态,且不得返回并不存在的日志路径。既有日志路径与内容格式保持不变;这不承诺抵御并发替换父目录的完整文件系统竞态。

#### Scenario: A pre-existing diagnostic log is a symlink
- **WHEN** 项目或临时目录里预置的日志文件指向另一文件,检查器随后产生失败诊断
- **THEN** 链接目标内容保持不变,实际日志以仅当前用户可读的完整内容替换日志路径

#### Scenario: The project output directory is a symlink or unavailable
- **WHEN** 默认 `out` 是指向其它目录的符号链接或不可写入的路径
- **THEN** 检查的 FAIL/UNVERIFIED 结论保持不变,不写入链接目标,也不返回虚假的 `log_path`

#### Scenario: Repair retains the original scope
- **WHEN** delta 或 save 检查失败并成功运行 formatter
- **THEN** 复检执行原物化命令,仅包含原检查范围;被跳过的文件不导致漏掉其它文件的复检

### Requirement: CLI fix SHALL account for every repair outcome

同一语言可同时产生跳过子范围与实际 formatter 结果。CLI MUST 遍历应用返回的每条结果,而不是按语言数截断;任何实际 formatter 失败或不可验证结果 MUST 不得被同语言的 SKIPPED 提示掩盖为成功。既有逐条提示与 dry-run 行为保持可见。

#### Scenario: Mixed shell and zsh changes with a failing formatter
- **WHEN** Git 改动同时包含 `.zsh` 与 `.sh`,前者安全跳过 formatter,后者 formatter 实际运行并失败
- **THEN** CLI 同时显示跳过说明与 formatter 失败,退出非零;不得只处理第一条 SKIPPED 结果

#### Scenario: No executable commands
- **WHEN** 计划没有任何可执行命令
- **THEN** 规划调用方返回 SKIPPED、PLANNED 或 UNVERIFIED;执行器拒绝将空计划解释为成功
Expand Down
4 changes: 2 additions & 2 deletions openspec/changes/refactor-codeguard-architecture/tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,6 @@
- [x] 5.1 增加自动架构依赖/循环检查并接入 CI,临时源码树注入反向依赖/函数内导入/相对导入环后确实拒绝;本地已验证,远端 CI 待发布阶段。不以文件行数当合格标准。
- [x] 5.2 四个历史 skipped 已全部恢复;Dockerfile CLI 接入统一报告解析与扫描应用,14 项真实进程边界测试通过;基线比较按诊断内容和次数核验并要求基线实际 FAIL,三项误豁免用例先红后绿。完整 433 项单测零跳过、142 项回归零失败。
- [x] 5.3 新增当前架构 Mermaid 与扩展指南;报告版本读取插件 manifest,双语 README 指向当前证据,旧设计标明历史范围;双语标题/链接/版本及本地链接存在性测试通过。发布版本仍需在 5.5 检查。
- [x] 5.4 全量单测/真实 hook 回归/ruff/语言 schema/vendor 离线与在线/本 change strict 和逐条规格追溯通过;第二十批 500 项单测、143 项真实 Hook 回归、57 项/11 规则,证据见 verification.md。仅证明本地契约,不等同三宿主现场验收。
- [ ] 5.5 按仓规升级版本、生成市场元数据、授权的 PR/CI/不可变 tag/Release 闭环;第二十批已发布 v0.14.6(插件 PR #52、市场 PR #9、源码 PR/main CI、注释 tag/正式 Release 均核对;市场 PR 无 CI 检查)。第二十一批新增的逐命令证据仍只在本地,需独立升级版本并发布。宿主安装运行独立记录,未授权不得改宿主。
- [x] 5.4 全量单测/真实 hook 回归/ruff/语言 schema/vendor 离线与在线/本 change strict 和逐条规格追溯通过;第二十二批最终 512 项单测、143 项真实 Hook 回归、57 项/11 规则,证据见 verification.md。仅证明本地契约,不等同三宿主现场验收。
- [ ] 5.5 按仓规升级版本、生成市场元数据、授权的 PR/CI/不可变 tag/Release 闭环;第二十一批已发布 v0.14.7(插件 PR #53、市场 PR #10、源码 PR/main CI、注释 tag/正式 Release 均核对;市场 PR 无 CI 检查)。第二十二批诊断日志与 CLI 汇总修复已获用户授权推送、合并 main,正在执行 v0.14.8 发布闭环。宿主安装运行独立记录,未授权不得改宿主。
- [ ] 5.6 完成全目标审计,代码/规格/证据一致后同步并归档 change,才可将整体优化标记完成。
11 changes: 11 additions & 0 deletions openspec/changes/refactor-codeguard-architecture/verification.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,3 +223,14 @@
- 真实 MCP stdio RED 复现:`codeguard.json` 权威命令中的哨兵 token 经原始 argv 和检查器输出进入新增轨迹,扩大了公开面。`check_application` 现将 `check_code_style` 与 `auto_fix` 的新增轨迹压成阶段/序号/程序名/退出与故障/输出长度,不回显 argv、环境覆盖或输出文本;原始证据仍由内部执行结果和本地失败日志保留。后者可能含敏感内容,文档明确要求排除版本控制,不宣称日志已脱敏。
- 新目标测试经真实 `mcp_tool_payload` 路径转绿;进一步通过官方 MCP SDK 的 stdio 客户端从 `check_code_style` 收到两条实际命令状态与完整失败日志路径,token 未出现在 JSON 响应。加入 `auto_fix` 轨迹收敛测试后完整本地单测 **503/503、0 skipped**,Hook 回归 **143/0/0**,Ruff、架构门禁、语言 schema **57 项/11 规则**、vendor 离线/在线、本 change strict 与 diff whitespace 通过。受管技能与 lock 未改;这仍是本地证据,当前发布的 v0.14.6 不含本批修改,三宿主安装现场、真实 Maven/Gradle、在线漏洞库及 Windows 未验收。
- 宿主安装登记只读抽查:本机 ZCode 的 `installed_plugins.json` 将 `codeguard@full-stack-plugins` 指向 `v0.12.1` 与其缓存目录;它不能证明 v0.14.6 或本批在 ZCode 的加载/触发。当前抽查的 Codex/Kimi 缓存路径未提供当前版证据,但不能据路径缺失推断所有宿主环境均未安装。宿主安装和真实加载需在后续有权限的独立验收中验证,不由源码测试、市场 ref 或旧缓存替代。

- 第二十一批随后发布为 v0.14.7:源码 PR #53 合并到 `1543a93ae893040633ced2818b6dd7fb30752c40`,市场 PR #10 合并到 `e5816b097006f65db24a7ac2c5d00080faae9ee1`;源码 PR 与合并后 main 的 `skills-check` 均通过。远端注释 tag 解引用到源码合并提交,正式 GitHub Release 非 draft、非 prerelease;市场 Codex/ZCode/Kimi 生成清单校验及导航版本为 0.14.7。市场 PR 没有报告 CI 检查,不声称市场 CI 通过。此发布只覆盖第二十一批及此前代码,不覆盖以下新工作树。

## 第二十二批实际验证:诊断日志私有原子落盘

- 继续做 CLI 能力矩阵黑盒审计:真实 Git 仓同时修改 `.zsh` 和 `.sh`,假 shfmt 确实被调用并退出 2;原 `fix.py` 按 `zip(results, languages)` 只打印第一条 zsh 跳过,错误返回 0。新测试 RED 后改为按每条结果的语言呈现和聚合,目标测试连同 `detect`/`init` 入口及日志测试 9/9 GREEN。

- 临时 CodeGraph 索引同步到最新源码(源仓未初始化索引),沿 `language_check.run_check → 项目 out 日志` 与 `reporting._truncate_detail → 临时门禁日志` 两条链定位到普通 `Path.write_text`。两处均写原始检查器输出;文档虽提示可能含敏感文本,但项目日志在默认 022 umask 下为 0644。预置日志路径符号链接会覆盖目标文件,项目 `out` 目录链接会把日志写到外部;`out` 是普通文件时,`mkdir` 异常会掩盖已有检查结论。
- 真实文件系统新增 5 项 RED:项目日志权限、项目日志文件链接、输出目录链接、不可用输出目录、门禁截断日志链接。统一由 `storage.write_private_text` 在同目录创建私有临时文件并原子替换,拒绝直接链接的日志目录;两类应用只决定路径与内容。日志不可用时不返回虚假的路径,检查状态保持原判;保留既有日志内容格式与可见路径。另加原子替换失败的故障注入,证明旧日志不被截断、临时文件清理、既有判定保留。目标 6/6 通过,POSIX 创建权限为 0600,链接目标保持原样。
- 完整本地单测 **512/512、0 skipped**,真实 Hook 回归 **143/0/0**;Ruff、架构依赖/循环、语言 schema **57 项/11 规则**、vendor 离线与在线、本 change strict、diff whitespace 通过,受管技能及 lock 未改。CodeGraph `affected` 对本次文件返回空,但实际新增测试和原有调用链覆盖存在,不将该空结果当无影响证据。
- 本批仅证明静态预置链接、POSIX 权限和原子替换语义;不承诺抵御并发替换父目录的完整文件系统竞态,也没有 Windows 实机、三宿主现场、在线 CVE 或大型 Maven/Gradle 验收。v0.14.7 的 CI/Release 不能证明此新代码;v0.14.8 发布证据须单独记录。
Loading
Loading