Skip to content

Commit eb5b638

Browse files
authored
Merge pull request #59 from full-stack-plugins/fix/dot-dir-commit-policy
fix: 提交安全检查默认忽略点前缀目录
2 parents 3c54128 + e9cde18 commit eb5b638

18 files changed

Lines changed: 420 additions & 15 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.15"
12+
"ref": "v0.15.0"
1313
},
1414
"policy": {
1515
"installation": "AVAILABLE",
1616
"authentication": "ON_USE"
1717
},
1818
"category": "Developer Tools",
19-
"version": "0.14.15",
19+
"version": "0.15.0",
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.15/assets/official-logo.png",
21+
"icon": "https://cdn.jsdelivr.net/gh/full-stack-plugins/codeguard-plugin@v0.15.0/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.15/assets/official-logo.png"
25+
"logo": "https://cdn.jsdelivr.net/gh/full-stack-plugins/codeguard-plugin@v0.15.0/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.15+codex.20260923",
3+
"version": "0.15.0+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.15",
8+
"version": "0.15.0",
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.",

‎AGENTS.md‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ git add -A && git commit -m "release: <插件id> <版本>" && git push
4545

4646
### 硬性禁令
4747

48+
- **`.` 开头的目录与文件默认忽略**(检查/保存/发现/全量扫描面):不扫描、不检查、不报告;
49+
两个例外照常生效——入库安全检查照拦密钥模式(`.env`/`*.pem` 等),linter 配置发现
50+
(`requiresConfig`/`linter_config_files`)照常匹配点文件
4851
- 禁止改代码不 bump 版本(「小版本也要发」)
4952
- 禁止手改 catalog.json 的 version 以外的生成产物、或手改三份市场清单——
5053
它们只能由 `scripts/bump-plugin.mjs` 与 `plugins/scripts/sync-marketplaces.mjs` 生成

‎docs/current-architecture.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ flowchart TD
2626
Entry -. 会话与去重 .-> State[storage / hook_state / cache]
2727
```
2828

29+
检查作用域默认忽略项目根下任一以 `.` 开头的目录与文件(PostToolUse 保存面、delta 门禁面、语言发现面与全量扫描的 ruff/`find` 型通道;项目根本身位于点前缀父目录下不构成命中);入库安全检查与 linter 配置发现不受此影响——密钥模式照拦,点前缀配置文件照常判定接入。
2930
`execution` 只记录进程证据,不把非零退出自动认定为代码违规;stdout/stderr 合计按默认 16 MiB 捕获预算并发读取,超限终止执行、保留预算内诊断且返回 `output_limit`/UNVERIFIED,不把片段当成完整日志。`verdict`、CVE 与 Dockerfile 报告解析决定 PASS、FAIL 或 UNVERIFIED;入口仅按各自协议呈现和聚合退出码。Git 提交检查使用 index 或预测暂存快照,推送检查使用 HEAD;保存钩子只给反馈。计划、未执行和未验证不能宣传为通过。
3031
Git 准确快照复用统一执行器的原始字节模式:路径列表默认最多捕获 16 MiB,`cat-file --batch-check` 按对象数分配响应预算;通过大小响应确认对象总量不超过 256 MiB 后,`--batch` 才按总 blob 大小和逐项头部预算读取。stdout/stderr 合计超限时及时终止 Git,抛出 `SnapshotError`,不交付截断内容。预测暂存的工作树覆盖层只列举一次,并以同一集合决定 `changed` 和物化内容;最多 20,000 项、单文件 32 MiB、实际复制总量 256 MiB,以 64 KiB 块流式读取。打开时使用非阻塞与不跟随末级链接的可用平台标志,避免类型检查后变成 FIFO 时卡住。特殊文件、读取期间变化和超限不交付临时树,文件↔目录转换按父路径先处理。随后严格解析 index/HEAD 对象列表的 NUL 帧、模式、ID、类型/阶段和唯一文件名,并与独立路径列举核对;`cat-file` 两阶段响应再逐项核对 ID、blob 类型、大小与边界,按 SHA-1/SHA-256 blob 对象格式复算内容哈希。缺项、截断、尾部脏数据或同长度内容替换均不交付临时树,而是明确标记 Git UNVERIFIED。原始 index 不在观察过程中改写。该校验不是恶意 Git 进程沙箱或完整 Git/Shell 模拟。
3132
`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` 目录为链接或不可写时不返回虚假日志路径,也不覆盖检查结论。终止命令仍决定既有状态、退出码和旧字段;未运行的计划命令不进入证据。

‎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.15",
3+
"version": "0.15.0",
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"
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# 2026-09-23-dot-prefix-default-skip
2+
3+
## Why
4+
5+
用户指令(2026-09-23):codeguard 要默认忽略 `.` 开头的目录和文件,且这套硬性约束必须**既在代码中也在提示词中**。
6+
7+
实测背景:插件仓发版时 `.agents/plugins/marketplace.json` 与 `.codex-plugin/plugin.json` 被提交安全检查判成「不应入库」阻断发版(入库面已由 `0f284ee` 修复);但**检查/保存/发现/全量扫描**四类面仍会把点前缀路径当检查对象——宿主工具目录(`.cursor/`、`.claude/`、`.mimosa/` 快照等新点目录不在 `FULL_SCAN_EXCLUDES` 枚举内)、点前缀配置文件(`.eslintrc.js`)会被 lint 报与仓库内容无关的问题,且枚举永远追不上新宿主目录。
8+
9+
## What Changes
10+
11+
- 单一谓词 `path_policy.is_dot_prefixed(path, root)`:相对项目根任一路径段 `.` 开头(`.`/`..` 段除外)即点前缀。
12+
- 检查面四通道接入默认忽略:PostToolUse 保存面、提交门禁 delta 面(`changed_files`)、全量扫描的 ruff 与 `find` 型 gate 注入。
13+
- 语言发现面(`detect_languages`)不再计入点前缀文件。
14+
- **两个例外面不受影响**:入库安全检查照拦密钥模式(`.env`/`*.pem`/`.DS_Store`),linter 配置发现(`requiresConfig`/`linter_config_files`)照常匹配点文件。
15+
- 提示词面声明约束:SessionStart「codeguard 项目记忆」上下文与 `AGENTS.md` 硬性禁令写明该规则,并以测试锚定。
16+
17+
## Capabilities
18+
19+
### New Capabilities
20+
21+
- `scan-scope-policy`:检查作用域的点前缀默认忽略规则、例外面边界与提示词声明要求。
22+
23+
### Modified Capabilities
24+
25+
无。既有 `gate-trigger-policy`、`verdict-integrity` 等行为契约不变。
26+
27+
## Impact
28+
29+
- `scripts/codeguard/path_policy.py`(新谓词)、`scripts/scope.py`(delta 过滤 + ruff/find 注入)、`scripts/codeguard/save_application.py`、`scripts/codeguard/discovery.py`、`scripts/codeguard/startup_application.py`(提示词)。
30+
- `AGENTS.md`、`docs/current-architecture.md`(提示词/文档面)。
31+
- 行为变更:检查面默认忽略点前缀路径——此前会被检查的 `.eslintrc.js`、`.github/` 下文件等不再进入检查面;入库安全与配置发现行为不变。`0f284ee` 的入库面行为一并纳入规格固化。
32+
- 不改动受管技能内容、不改 `FULL_SCAN_EXCLUDES` 枚举本体。
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# scan-scope-policy:检查作用域与点前缀默认忽略
2+
3+
## Purpose
4+
5+
定义 codeguard 检查作用域的点前缀默认忽略规则:哪些路径面默认不检查、哪些例外面必须照常生效,以及该约束在提示词面的声明要求,使「宿主工具目录与配置文件不再产生与仓库内容无关的结论」成为可测试契约。
6+
7+
## ADDED Requirements
8+
9+
### Requirement: Check and save faces MUST skip dot-prefixed paths by default
10+
11+
相对项目根,任一路径段以 `.` 开头(`.`、`..` 段除外)的目录与文件为点前缀路径,默认忽略:不扫描、不检查、不报告。适用于 PostToolUse 保存面、提交门禁 delta 面、语言发现面,以及全量扫描的 ruff 与 `find` 型 gate 通道。项目根本身位于点前缀父目录下(如 `~/.config/proj/`)不构成点前缀命中。
12+
13+
#### Scenario: PostToolUse skips dot-prefixed files
14+
15+
- **WHEN** AI 保存 `.cursor/rules.py` 或 `.eslintrc.js`
16+
- **THEN** 保存面静默跳过,不触发 lint、不产生告警
17+
18+
#### Scenario: Delta gate face excludes dot-prefixed paths
19+
20+
- **WHEN** 本次提交同时改动 `.github/workflows/ci.yml` 与 `src/main.py`
21+
- **THEN** 门禁检查面只含 `src/main.py`
22+
23+
#### Scenario: Language discovery ignores dot-prefixed files
24+
25+
- **WHEN** 项目根仅有 `.eslintrc.js` 与 `main.py`
26+
- **THEN** 发现面只计入 python,不因 `.eslintrc.js` 计入 javascript
27+
28+
#### Scenario: Full-scan channels exclude dot-prefixed subtrees
29+
30+
- **WHEN** 全量扫描执行 ruff 或 `find` 型 gate
31+
- **THEN** ruff 命令带点前缀排除参数,`find` 表达式注入 `-not -path '*/.*'`,`.agents/` 等子树不产生结论
32+
33+
#### Scenario: Project under a dot-prefixed parent is not skipped
34+
35+
- **WHEN** 项目根为 `~/.config/proj/` 且检查 `main.py`
36+
- **THEN** 不因父目录点前缀跳过,正常检查
37+
38+
### Requirement: Commit safety face MUST NOT be weakened by dot-prefix skipping
39+
40+
点前缀默认忽略只作用于检查面。入库安全检查独立收集拟入库路径:密钥/凭据类文件模式(`.env`、`*.pem`、`.DS_Store` 等)无论点前缀与否照常拦截;点前缀目录(宿主插件清单与第一方配置)照常可入库。
41+
42+
#### Scenario: Secret files remain blocked
43+
44+
- **WHEN** 拟提交 `.env` 或 `id_rsa`
45+
- **THEN** 入库安全检查照常给出违规与修复指令
46+
47+
#### Scenario: Host manifest dirs remain committable
48+
49+
- **WHEN** 拟提交 `.agents/plugins/marketplace.json`
50+
- **THEN** 不因目录点前缀被判「不应入库」
51+
52+
### Requirement: Config discovery MUST keep matching dot-prefixed config files
53+
54+
linter 配置发现(`requiresConfig`、`linter_config_files` 项目级匹配)不受点前缀忽略影响:点前缀配置文件照常使语言判定为已接入。
55+
56+
#### Scenario: requiresConfig matches dot files
57+
58+
- **WHEN** 项目根存在 `.markdownlint-cli2.jsonc` 且 markdown 声明 `requiresConfig` 含该文件名
59+
- **THEN** markdown 判定为已接入,进入正常检查流程
60+
61+
### Requirement: Prompt surfaces MUST state the constraint
62+
63+
点前缀默认忽略规则 MUST 出现在提示词面:SessionStart「codeguard 项目记忆」上下文与 `AGENTS.md` 硬性禁令,且须同时声明两个例外面(入库安全照拦、配置发现照常),并有测试锚定提示词包含该声明。
64+
65+
#### Scenario: SessionStart context states the rule
66+
67+
- **WHEN** SessionStart 生成项目记忆文本
68+
- **THEN** 文本含默认忽略声明及例外说明
69+
70+
#### Scenario: AGENTS.md hard rules state the rule
71+
72+
- **WHEN** 读取 `AGENTS.md` 硬性禁令
73+
- **THEN** 含点前缀默认忽略条目
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Tasks: 2026-09-23-dot-prefix-default-skip
2+
3+
## 1. 单一谓词
4+
5+
- [x] 1.1 `path_policy.is_dot_prefixed(path, root)`:相对 root 判段,`.`/`..` 段豁免;root 外或无法相对化时返回 False(多检查不漏检查)
6+
- [x] 1.2 路径分隔符统一 `/`(沿用 `is_build_artifact` 的 Windows 兼容写法,不用 `lstrip('./')`)
7+
8+
## 2. 检查面四通道接入
9+
10+
- [x] 2.1 `scope.changed_files` 返回前过滤点前缀路径(delta 门禁面 + push 面同时生效)
11+
- [x] 2.2 `scope._inject_find_excludes` 注入 `-not -path '*/.*'`(幂等,OR 组括号前提不变)
12+
- [x] 2.3 `scope.scope_cmd` ruff 分支 full_excludes 时追加 `--exclude '.*'` 与 `--exclude '**/.*'`
13+
- [x] 2.4 `save_application.should_skip` 点前缀文件静默跳过(root 由 `find_project_root` 兜底推导)
14+
15+
## 3. 发现面
16+
17+
- [x] 3.1 `discovery.detect_languages` 的 include 不计入点前缀文件
18+
19+
## 4. 例外面回归锚定(不许被忽略吞掉)
20+
21+
- [x] 4.1 入库安全:`.env`/`*.pem` 照拦;`.agents/`/`.codex-plugin/` 等点目录照常可入库(固化 `0f284ee`)
22+
- [x] 4.2 配置发现:`requiresConfig` 匹配 `.markdownlint-cli2.jsonc` 等点文件仍判已接入
23+
24+
## 5. 提示词面
25+
26+
- [x] 5.1 `startup_application` 项目记忆文本声明默认忽略规则与两个例外
27+
- [x] 5.2 `AGENTS.md` 硬性禁令补该条
28+
- [x] 5.3 `docs/current-architecture.md` 行为段落补一句
29+
30+
## 6. 测试与发版
31+
32+
- [x] 6.1 `tests/test_dot_prefix_default_skip.py` 锚定 1–5 全部场景(含「项目根本身在点目录下不误伤」陷阱)
33+
- [x] 6.2 全量回归(run_all + unittest discover)通过
34+
- [x] 6.3 按仓规 bump minor、市场仓同步、PR/CI 合并、两仓推送

‎scripts/check_architecture.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
"codeguard.registry_schema": {"__future__", "re"},
5353
"codeguard.registry": {"__future__", "json", "pathlib", "typing", "codeguard.registry_schema"},
5454
"codeguard.config": {"__future__", "json", "re", "pathlib", "codeguard.registry"},
55-
"codeguard.discovery": {"__future__", "fnmatch", "re", "pathlib", "codeguard.config", "codeguard.registry"},
55+
"codeguard.discovery": {"__future__", "fnmatch", "re", "pathlib", "codeguard.config", "codeguard.path_policy", "codeguard.registry"},
5656
"codeguard.toolchain": {"__future__", "pathlib", "threading", "codeguard.execution"},
5757
"codeguard.language_check": {"__future__", "pathlib", "codeguard.config", "codeguard.discovery",
5858
"codeguard.execution", "codeguard.models", "codeguard.planning",

0 commit comments

Comments
 (0)