Skip to content

Commit f683bc7

Browse files
authored
Merge pull request #60 from full-stack-plugins/release/codeguard-v0.14.13
release: codeguard v0.14.13
2 parents fd0f771 + 6fc5799 commit f683bc7

14 files changed

Lines changed: 290 additions & 28 deletions

File tree

‎.agents/plugins/marketplace.json‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,20 @@
99
"source": {
1010
"source": "url",
1111
"url": "https://github.com/partme-ai/partme-codeguard-plugin.git",
12-
"ref": "v0.14.12"
12+
"ref": "v0.14.13"
1313
},
1414
"policy": {
1515
"installation": "AVAILABLE",
1616
"authentication": "ON_USE"
1717
},
1818
"category": "Developer Tools",
19-
"version": "0.14.12",
19+
"version": "0.14.13",
2020
"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.",
21-
"icon": "https://cdn.jsdelivr.net/gh/full-stack-plugins/codeguard-plugin@v0.14.12/assets/official-logo.png",
21+
"icon": "https://cdn.jsdelivr.net/gh/full-stack-plugins/codeguard-plugin@v0.14.13/assets/official-logo.png",
2222
"interface": {
2323
"displayName": "代码规范守卫",
2424
"shortDescription": "Trustworthy code checks and Java impact analysis",
25-
"logo": "https://cdn.jsdelivr.net/gh/full-stack-plugins/codeguard-plugin@v0.14.12/assets/official-logo.png"
25+
"logo": "https://cdn.jsdelivr.net/gh/full-stack-plugins/codeguard-plugin@v0.14.13/assets/official-logo.png"
2626
}
2727
}
2828
]

‎.codex-plugin/plugin.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "codeguard",
3-
"version": "0.14.12+codex.20260923",
3+
"version": "0.14.13+codex.20260923",
44
"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.",
55
"author": {
66
"name": "Full Stack Skills / PartMe.AI",

‎.zcode-plugin/plugin.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"en": "CodeGuard",
66
"zh-CN": "代码规范检查"
77
},
8-
"version": "0.14.12",
8+
"version": "0.14.13",
99
"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.",
1010
"description_i18n": {
1111
"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.",

‎docs/current-architecture.md‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ flowchart TD
2828

2929
`execution` 只记录进程证据,不把非零退出自动认定为代码违规。`verdict`、CVE 与 Dockerfile 报告解析决定 PASS、FAIL 或 UNVERIFIED;入口仅按各自协议呈现和聚合退出码。Git 提交检查使用 index 或预测暂存快照,推送检查使用 HEAD;保存钩子只给反馈。计划、未执行和未验证不能宣传为通过。
3030
Git 准确快照的二进制读取独立于文本检查执行器:先严格解析 index/HEAD 对象列表的 NUL 帧、模式、ID、类型/阶段和唯一文件名,并与独立路径列举核对;`cat-file` 两阶段响应再逐项核对 ID、blob 类型、大小与边界,按 SHA-1/SHA-256 blob 对象格式复算内容哈希。缺项、截断、尾部脏数据或同长度内容替换均不交付临时树,而是明确标记 Git UNVERIFIED。原始 index 不在观察过程中改写。该校验不是恶意 Git 进程沙箱或完整 Git/Shell 模拟。
31-
`language_check` 将 `PlanExecution` 的实际命令依序映射为应用层有界 `execution_trace`(检查、修复、复检阶段);`check_application` 将其进一步压成 MCP 安全元数据,不回显原始 argv、环境覆盖或捕获输出。MCP `auto_fix` 先以 `fingerprint.file_content` 对仓内改动文件采集有总量预算的流式身份,仓外路径、符号链接或读取故障不启动 formatter;复检后无法再次采集身份时保留实际执行证据但不宣称已确认 `fixed`。`fix_results` 只公开状态与安全元数据;formatter stderr 尾部写入私有 `.codeguard-fix.log` 后只公开路径,日志不可用时不退回公开原文。失败日志保留各已执行检查的完整输出,可能含敏感文本,应排除出版本控制。项目日志和门禁截断日志共用 `storage.write_private_text` 的私有原子落盘;预置日志文件链接不被跟随,默认 `out` 目录为链接或不可写时不返回虚假日志路径,也不覆盖检查结论。终止命令仍决定既有状态、退出码和旧字段;未运行的计划命令不进入证据。
31+
`language_check` 将 `PlanExecution` 的实际命令依序映射为应用层有界 `execution_trace`(检查、修复、复检阶段);`check_application` 将其进一步压成 MCP 安全元数据,不回显原始 argv、环境覆盖或捕获输出。MCP `auto_fix` 以 `fingerprint.file_content` 对仓内改动文件在修复前、formatter 后、复检后分别采集有总量预算的流式身份,仓外路径、符号链接或读取故障不启动 formatter;顶层 `fixed` 只归因于 formatter 且复检后仍保留的变化。公开 `fix_results` 将命令成功 `formatter_succeeded` 与逐项修复确认 `fixed` 分离;只有唯一成功执行的 formatter 且内容变化可验证时才把全局变化归给该项,多 formatter 执行不猜测归属。后续身份不可采集、formatter 失败后仍有内容变化或检查器改写目标文件时,保留实际执行证据、整体标为 UNVERIFIED,不把未知副作用声称为已确认修复。`fix_results` 只公开状态与安全元数据;formatter stderr 尾部写入私有 `.codeguard-fix.log` 后只公开路径,日志不可用时不退回公开原文。失败日志保留各已执行检查的完整输出,可能含敏感文本,应排除出版本控制。项目日志和门禁截断日志共用 `storage.write_private_text` 的私有原子落盘;预置日志文件链接不被跟随,默认 `out` 目录为链接或不可写时不返回虚假日志路径,也不覆盖检查结论。终止命令仍决定既有状态、退出码和旧字段;未运行的计划命令不进入证据。
32+
`run_fix` 的历史 `fixed` 字段仍表示 formatter 命令以 0 退出,供旧调用方决定是否复检;它本身不是内容变化证明。CLI `fix` 因而只报告 formatter 执行成功与文件变化未验证,不再把退出码 0 呈现为已确认修复。
3233
Git 命令的仓库定位与拟暂存解析共用入口传入的 cwd;显式 `cd`/`git -C` 无法绑定 Git 工作树时,硬门禁给出目标未验证并阻断,不退回到调用者仓或无关子仓。未给出显式目标且调用目录非仓时仍保留 workspace 子仓兜底。静态命令解析不等于完整 Shell 执行模拟。
3334
workspace 兜底产生的每个子仓是合成目标,暂存观察也绑定该子仓根目录;不能继续以非 Git 的 workspace cwd 解析,从而把脏子仓的已知违规变成未知放行。
3435
一条命令链中的 Git 副作用先绑定为仓库与操作的有序对,再按仓库聚合检查面:纯 push 不读取该仓未提交的 index,同仓 commit→push 则保留已有 HEAD 与拟提交内容的并集。仓库级、内联及链式 `skipGate` 均按目标仓与操作顺序生效;已存在的仓库配置也可被同链先行 `git config --unset` 取消。链式设置跨 `||`、`;` 或换行时无法证明生效,门禁要求拆分命令;写入其它文件的 config 设置也不构成本仓豁免。语法、仓库归属、间接脚本与拟暂存分析共用引号/转义感知切分;参数文本中的控制符不能合成豁免。解析能力仍限于受支持的静态 Shell 形态。

‎kimi.plugin.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "codeguard",
3-
"version": "0.14.12",
3+
"version": "0.14.13",
44
"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.",
55
"author": {
66
"name": "Full Stack Skills / PartMe.AI"

‎openspec/changes/refactor-codeguard-architecture/design.md‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ flowchart TD
6060

6161
三个通过真实进程复现的缺口同时收敛:Java 计划的 JAVA_HOME 不再被调用方丢弃;混合 shell/zsh 的第一项跳过不会掩盖 formatter 成功并阻止复检;delta >50 回退全量却无项目命令时明确 UNVERIFIED,不把 `{file}` 替换为空执行。以上遵循原来的范围和可信度契约,不扩大自动修复权限。
6262

63+
`run_fix` 的兼容 `fixed` 字段历史上是 formatter 成功退出标志,`run_check(fix=True)` 仍据此决定是否复检;它不是内容差异。CLI 展示层不改写这一兼容字段,但只报告 formatter 已执行成功、内容变化未验证,不把进程退出码包装为文件已修复。MCP 顶层的 `fixed` 另由有界文件身份比较证明;内层旧字段的最终迁移需单独处理兼容性。
64+
6365
### 4. 标准化由自动化约束维持
6466

6567
真实进程测试覆盖超时/非零/编码/路径与副作用;真实 Git 测试覆盖内容快照;原生 stdio MCP 测试覆盖协议。架构门禁检查依赖方向和循环依赖,不以文件行数或类数量作为合格标准。所有既有测试保留行为断言;若私有导入变化,更新测试必须说明原契约对应的新边界。
@@ -68,8 +70,8 @@ flowchart TD
6870

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

71-
MCP 的 `auto_fix` 还必须在应用层单独投影公开结果:`run_fix` 保留执行所需的原始命令与 stderr,但 JSON 只允许修复状态、退出码及收敛后的执行元数据。formatter 的 stderr 尾部写入项目 `out/.codeguard-fix.log`,成功落盘才公开私有日志路径;日志不可写时不回退输出原文。此边界不修改 CLI 的本地诊断契约,也不把私有日志路径当成宿主已读取的证明。
72-
修复范围的前后观察复用 `fingerprint.file_content` 的流式散列和 64 MiB/10,000 文件预算;应用层先确认路径在根内、拒绝直接符号链接、设备和循环路径,再允许 `run_fix`。读取故障或身份超限不会靠整份 `read_bytes` 兜底;修复后观察失败仍返回已执行的修复与复检结果,但顶层 `fixed` 不可据此宣称成功。架构依赖门禁显式允许应用服务依赖 fingerprint 基础设施,不增加反向依赖。
73+
MCP 的 `auto_fix` 还必须在应用层单独投影公开结果:`run_fix` 保留执行所需的原始命令与 stderr,内部 `fixed` 维持退出码成功的兼容语义;JSON 用 `formatter_succeeded` 表示这个事实,逐项 `fixed` 只表示唯一可归因且复检后稳定的内容变化。多 formatter 执行时可以保留顶层观察到的变化,但逐项不猜测归属;失败命令后的部分改写整体转 UNVERIFIED。公开面只允许修复状态、退出码及收敛后的执行元数据。formatter 的 stderr 尾部写入项目 `out/.codeguard-fix.log`,成功落盘才公开私有日志路径;日志不可写时不回退输出原文。此边界不修改 CLI 的本地诊断契约,也不把私有日志路径当成宿主已读取的证明。
74+
修复范围的前后观察复用 `fingerprint.file_content` 的流式散列和 64 MiB/10,000 文件预算;应用层先确认路径在根内、拒绝直接符号链接、设备和循环路径,再允许 `run_fix`。读取故障或身份超限不会靠整份 `read_bytes` 兜底。身份分别在修复前、formatter 返回后、检查器返回后采集:`fixed` 只来自 formatter 阶段且在复检后仍保留的变化;检查器改写目标文件或任一后续身份不可靠时,顶层 UNVERIFIED 且不宣称已确认修复,同时保留实际修复与复检证据。架构依赖门禁显式允许应用服务依赖 fingerprint 基础设施,不增加反向依赖。
7375

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

‎openspec/changes/refactor-codeguard-architecture/specs/execution-kernel/spec.md‎

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646

4747
检查计划 MUST 显式区分 repo、delta 与 save,保存物化后的命令、工作目录和逐命令环境覆盖。执行 MUST 按序进行,首个非零结果终止普通检查批次,保留已执行证据;未执行的命令不得计为成功。空计划不得生成 PASS。Java 原生计划给出的环境覆盖 MUST 在子进程中生效,不改变宿主环境。修复后的检查 MUST 复用原计划,不重新扩大范围。Git 门禁的逐文件基线豁免是独立策略,不由通用执行器决定。
4848
语言检查与修复的应用结果 MUST 保留实际运行的每条命令身份、目录、退出码、故障标识和有界输出摘要;MCP 适配不得只保留终止命令,但其公开执行轨迹 MUST 只包含阶段、序号、程序名、退出码、故障标识和输出长度,不得新增暴露原始 argv、命令环境覆盖或任意检查器输出。失败日志 MUST 保留同一检查批次中此前已执行命令的完整输出,不能只记录最后一条。证据不得把尚未运行的计划命令写成已执行。
49-
MCP `auto_fix` 的 `fix_results` 公开面 MUST 同样只保留状态、退出码、安全元数据和可用诊断路径,不得因复制内部修复字典而回显 formatter 原始 argv 或 stderr。实际修复诊断仍应在可写时以私有原子日志保存;日志写入失败不得改变修复和复检结论,也不得回退为公开原文。
49+
MCP `auto_fix` 的 `fix_results` 公开面 MUST 同样只保留状态、退出码、安全元数据和可用诊断路径,不得因复制内部修复字典而回显 formatter 原始 argv 或 stderr。内部兼容 `fixed` 只表示 formatter 命令成功退出;公开结果 MUST 将此事实单独标为 `formatter_succeeded`,公开的逐项 `fixed` 只有在内容变化可唯一归因于这一条成功执行、且复检后身份稳定时才为真。多条 formatter 执行、读取故障或已知失败后有内容变化时,不得把全局差异猜给某条成功命令。实际修复诊断仍应在可写时以私有原子日志保存;日志写入失败不得改变修复和复检结论,也不得回退为公开原文。
5050

5151
#### Scenario: Java commands use the selected JDK
5252
- **WHEN** Java 项目计划选择 JAVA_HOME,且声明多条权威检查命令
@@ -64,6 +64,18 @@ MCP `auto_fix` 的 `fix_results` 公开面 MUST 同样只保留状态、退出
6464
- **WHEN** `auto_fix` 的 formatter 命令及 stderr 包含凭据文本
6565
- **THEN** MCP 整个修复结果不包含该文本或原始命令参数;可用时返回仅当前用户可读的诊断日志路径,日志不可用时仍不泄漏原文
6666

67+
#### Scenario: A no-op formatter exits successfully
68+
- **WHEN** formatter 退出码为 0,但修复前、修复后和复检后的目标内容身份相同
69+
- **THEN** `formatter_succeeded=true`,公开 `fix_results[].fixed=false`,并表明内容变化已验证
70+
71+
#### Scenario: Multiple formatters run but a global change cannot be attributed
72+
- **WHEN** 两条 formatter 都执行,最终只有全局文件身份变化,无法可靠分配给其中一条
73+
- **THEN** 顶层仍可报告已观察到的变化,但逐项 `fixed` 不猜测归属,逐项明确未验证
74+
75+
#### Scenario: A failed formatter partially changes a file
76+
- **WHEN** 唯一 formatter 退出非零但已改写目标文件
77+
- **THEN** 保留失败及复检证据,整体 UNVERIFIED 且不声称已确认修复
78+
6779
### Requirement: Diagnostic logs SHALL be private and atomic
6880

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

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

85-
同一语言可同时产生跳过子范围与实际 formatter 结果。CLI MUST 遍历应用返回的每条结果,而不是按语言数截断;任何实际 formatter 失败或不可验证结果 MUST 不得被同语言的 SKIPPED 提示掩盖为成功。既有逐条提示与 dry-run 行为保持可见。
97+
同一语言可同时产生跳过子范围与实际 formatter 结果。CLI MUST 遍历应用返回的每条结果,而不是按语言数截断;任何实际 formatter 失败或不可验证结果 MUST 不得被同语言的 SKIPPED 提示掩盖为成功。既有逐条提示与 dry-run 行为保持可见。formatter 退出码 0 仅证明命令执行成功;若 CLI 未采集修复前后内容身份,MUST NOT 将它呈现为已经确认文件发生修复。
8698

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

103+
#### Scenario: Formatter exits successfully without changing a file
104+
- **WHEN** CLI 对已规范的改动文件运行 formatter,进程退出码为 0,但内容保持不变
105+
- **THEN** CLI 仅报告 formatter 执行成功且文件变化未验证,不宣称 `fixed`
106+
91107
#### Scenario: No executable commands
92108
- **WHEN** 计划没有任何可执行命令
93109
- **THEN** 规划调用方返回 SKIPPED、PLANNED 或 UNVERIFIED;执行器拒绝将空计划解释为成功
94110

95111
### Requirement: MCP auto-fix SHALL observe changed files within a bounded safe scope
96112

97-
MCP `auto_fix` 在运行 formatter 之前 MUST 验证所有拟修复路径仍位于项目根内、不是符号链接或特殊文件,并以有总量预算的流式内容身份记录修复前状态,不得整份载入任意大小文件。路径逃逸、读取故障、并发替换或超预算 MUST 明确 UNVERIFIED 且不启动修复。修复后身份无法可靠采集时 MUST 保留实际修复与复检证据,但不得声称已确认 `fixed`。已确认的内容或权限变化仍按既有 `fixed` 字段呈现。
113+
MCP `auto_fix` 在运行 formatter 之前 MUST 验证所有拟修复路径仍位于项目根内、不是符号链接或特殊文件,并以有总量预算的流式内容身份记录修复前状态,不得整份载入任意大小文件。路径逃逸、读取故障、并发替换或超预算 MUST 明确 UNVERIFIED 且不启动修复。修复后身份无法可靠采集时 MUST 保留实际修复与复检证据,但不得声称已确认 `fixed`。`fixed` 只可归因于 formatter 已产生且复检后仍保留的目标文件变化;若复检本身改变这些文件,MUST 保留实际执行证据并将整体结果标为 UNVERIFIED,不可把检查器副作用当作已确认修复。已确认的内容或权限变化仍按既有 `fixed` 字段呈现。
98114

99115
#### Scenario: Changed path escapes through a parent symlink
100116
- **WHEN** Git 改动路径经父目录符号链接指向仓外普通文件
@@ -104,6 +120,10 @@ MCP `auto_fix` 在运行 formatter 之前 MUST 验证所有拟修复路径仍位
104120
- **WHEN** 改动文件超出身份预算、读取失败或被并发替换
105121
- **THEN** 修复前故障不启动 formatter;修复后故障保留已执行结果但不宣称 `fixed`
106122

123+
#### Scenario: Checker changes a repair target after formatter returns
124+
- **WHEN** formatter 返回后目标文件身份可采集,但随后的检查器又改动该文件
125+
- **THEN** `auto_fix` 保留修复与检查执行证据,整体标为 UNVERIFIED,`fixed` 不宣称已确认
126+
107127
### Requirement: Hook state SHALL preserve concurrent and session ownership
108128

109129
统计、绕过明细、冷却与审计的读改写 MUST 在进程锁内完成并原子替换文件。宿主提供 session_id 时,统计 MUST 绑定会话与当前 worktree;Stop MUST 只消费该作用域的记录,并与并发写入互斥。无 session_id 时保留旧共享状态兼容,MUST 明示不能证明跨会话隔离。去重 MUST NOT 把未完成或 UNVERIFIED 的检查当成已完成检查。

0 commit comments

Comments
 (0)