diff --git a/bin/codeguard b/bin/codeguard index 2c3a399..459c299 100755 --- a/bin/codeguard +++ b/bin/codeguard @@ -10,6 +10,7 @@ # # 退出码: 0 通过 / 1 无法验证 / 2 存在漏洞 / 3 参数错误 # codeguard dockerfile [--json] [path] # Dockerfile 安全风险检查(hadolint + trivy config) # codeguard detect [path] # 检测项目语言 +# codeguard engine [--format human|json] # 报告由哪个引擎签发质量结论 # # 安装到 PATH: # ln -s "$(pwd)/bin/codeguard" /usr/local/bin/codeguard @@ -39,6 +40,9 @@ case "$cmd" in detect) exec python3 "$ROOT/scripts/detect_lang.py" "${1:-.}" ;; + engine) + exec python3 "$ROOT/scripts/engine_report.py" "$@" + ;; init) cat >&2 <<'EOF' [codeguard] 项目初始化引导: @@ -53,7 +57,7 @@ EOF ;; *) echo "codeguard: 未知子命令 '$cmd'" >&2 - echo "可用: check | fix | cve | dockerfile | detect | java-plan | init" >&2 + echo "可用: check | fix | cve | dockerfile | detect | java-plan | engine | init" >&2 exit 1 ;; esac diff --git a/docs/rust-cli/README.md b/docs/rust-cli/README.md index 3bec19c..6573692 100644 --- a/docs/rust-cli/README.md +++ b/docs/rust-cli/README.md @@ -1,17 +1,9 @@ -# Codeguard Rust CLI 设计文档 +# Rust 文档已迁移 -状态:设计基线,尚未实现。日期:2026-09-24。源码核对基线:`03ebb24`;后续实现必须重新核对工作树和已合并规格。 +Rust CLI 的设计文档、进行中的 OpenSpec change、任务与验收记录已整体迁至独立 [codeguard 仓库](https://github.com/full-stack-plugins/codeguard)。本页仅作导航,不维护第二份 Rust 规范或任务。 -| 文档 | 回答的问题 | -|---|---| -| [架构文档](architecture.zh-CN.md) | 产品目标、模块边界、检查流程、低误报机制、权威边界 | -| [技术方案](technical-design.zh-CN.md) | 命令、数据协议、适配器、执行器、配置、缓存、分发与兼容实现 | -| [语言迁移与验收](coverage-and-acceptance.zh-CN.md) | 57 个条目的迁移、类别覆盖、评测方法、验收证据 | -| [持久问题与修复工作流](remediation-workflow.zh-CN.md) | 项目内 codeguard 目录、问题记录、待办任务、智能体修复与复检闭环 | -| [OpenSpec proposal](../../openspec/changes/introduce-rust-codeguard-cli/proposal.md) | 为什么变更及变更范围 | -| [OpenSpec design](../../openspec/changes/introduce-rust-codeguard-cli/design.md) | 架构决策、兼容性、实施顺序和待验证事项 | -| [OpenSpec tasks](../../openspec/changes/introduce-rust-codeguard-cli/tasks.md) | 可执行任务、依赖和完成证据 | +- [中英文架构与技术方案](https://github.com/full-stack-plugins/codeguard/tree/main/docs) +- [逐指令、初始化、修复闭环、白名单与迁移设计](https://github.com/full-stack-plugins/codeguard/blob/main/docs/README.zh_CN.md) +- [唯一 OpenSpec change 与任务](https://github.com/full-stack-plugins/codeguard/tree/main/openspec/changes/introduce-rust-codeguard-cli) -本次需求的唯一规范性事实源为 `openspec/changes/introduce-rust-codeguard-cli/specs/`。这些说明文档展开设计,不创建第二套任务状态。仓库 `openspec/specs/` 与 [当前架构](../current-architecture.md) 仍描述已落地的旧运行时;本 change 未实施前不得宣称 Rust 行为已经生效。 - -本次验收记录见 [verification.md](../../openspec/changes/introduce-rust-codeguard-cli/verification.md)。文档校验成功不代表二进制、扫描器或宿主运行验收成功。 +本插件的旧运行时及宿主规范仍在本仓 `openspec/specs/`;Rust 集成接口在新仓维护,宿主实际接线仍由本插件实现和验收。迁移于 2026-09-28 在本地完成;远程链接须随两仓后续提交推送生效。 diff --git a/docs/rust-cli/architecture.zh-CN.md b/docs/rust-cli/architecture.zh-CN.md deleted file mode 100644 index 8104944..0000000 --- a/docs/rust-cli/architecture.zh-CN.md +++ /dev/null @@ -1,207 +0,0 @@ -# Codeguard Rust CLI 架构设计 - -本方案把 Codeguard 恢复为传统静态工具驱动的多语言代码质量守卫。统一入口是 Rust 二进制 `codeguard`,智能体负责调用、解释和修复,检查事实来自工具,门禁要求来自受控策略。 - -状态:待实现设计。规范性要求见 [OpenSpec change](../../openspec/changes/introduce-rust-codeguard-cli/proposal.md)。实现细节见 [技术方案](technical-design.zh-CN.md),能力与测试见 [迁移验收](coverage-and-acceptance.zh-CN.md)。 - -项目内新增 `./codeguard/` 持久工作区,保存脱敏问题、任务和修复事件;本地报告、日志、缓存默认 Git 忽略。智能体以 `next` 获取可推进任务,以 `task verify` 完成真实复检。完整设计见 [修复工作流](remediation-workflow.zh-CN.md)。 - -## 1. 产品目标与不可变约束 - -1. 覆盖已支持语言的 lint、注释规范、CVE、安全规范及构建检查;每类检查都必须有明确适用性、执行能力和结果。 -2. 优先复用语言生态的成熟工具和项目配置。Rust 统一编排与证据,不重新实现各语言编译器和静态分析器。 -3. 低误报来自准确的工具版本、规则、语言方言、构建上下文和报告解析。不能靠关闭规则、减少检查范围或默认忽略旧问题改善数字。 -4. 代码违规与执行故障分别呈现;必需检查未完成时交付门禁不通过。 -5. AI 无权自行降低质量要求。修代码、修适配器、修工具配置的过程均留下可复核的变化与复检证据。 -6. 一次检查结论绑定实际内容、有效配置、工具与规则版本。不能借用工作树的通过替代 index 或待推送内容。 -7. 单语言、单类别命令的通过只代表该请求完成;全项目交付需要完整 contract 的证据。 - -“所有语言”是可扩展的适配器体系和明确的覆盖承诺,不是任何文件后缀都会自动拥有完整分析器。当前 57 个注册条目是迁移输入;对于没有可用检查器的类别,必须报告缺口,不能生成空适配器充数。 - -## 2. 当前实现证据与设计纠偏 - -以下为 `03ebb24` 的静态观察,不是对当前误报率的统计,也不替代实机复现。 - -| 当前证据 | 影响 | 新设计 | -|---|---|---| -| [入口](../../bin/codeguard) 是 Bash 转发 Python;语言、CVE、Dockerfile 有不同协议 | 调用方容易把不同退出码当成相同状态 | Rust 统一报告;旧数字经版本化兼容层映射 | -| [verdict.py](../../scripts/codeguard/verdict.py) 有通用 rc=1/cargo=101 和环境文本归类 | 进程失败与工具发现仍可能混淆 | 每个工具版本具有专用结果契约,不在通用执行器判断违规 | -| [gate_checks.py](../../scripts/codeguard/gate_checks.py) 在最多 50 个文件时走 delta,并调用基线豁免 | 性能分支改变语义,历史发现可消失 | 全部必需义务保持不变;分批、缓存、基线只优化或分类 | -| [hook-protocol](../../openspec/specs/hook-protocol/spec.md) 规定 fail-open 与 skipGate | 未完成检查可能不阻止交付动作 | 迁移后交付入口要求完整;普通保存反馈仍不冒充交付门禁 | -| [语言表](../../scripts/languages.json) 有 54 stable、3 planned,Julia/Pascal 的 lint 为空 | 语言标签不能证明真实检测能力 | 按语言 × 类别 × 工具 × 平台验收 | -| [本地规则文件](../../linters/checkstyle/p3c-javadoc-enforced.xml) 是 Checkstyle XML | 文件名不能证明已执行官方 P3C | 官方 P3C/PMD 与 Checkstyle/Javadoc 分开建模与取证 | -| [执行内核](../../scripts/codeguard/execution.py)、Git 快照、Java 影响分析已有专门模块 | 有价值的行为与回归样本可迁移 | 迁移证据和正确性约束,不逐行翻译全部历史策略 | - -旧版本的 fail-open、默认 delta、基线豁免是本次明确要改变的行为;不能用“兼容旧行为”把它们重新带入新门禁。兼容层只在显式旧协议范围内存在,并标明不能提供新交付认证。 - -## 3. 系统边界 - -```mermaid -flowchart TB - Human[开发者 / 质量策略负责人] --> Policy[受控质量策略与规则锁] - Agent[AI 编程智能体] --> Plugin[codeguard-plugin 宿主薄入口] - Skills[codeguard-skills 调用与修复指南] --> Agent - Plugin --> CLI[codeguard 原生二进制] - Terminal[终端 / 编辑器] --> CLI - CI[受保护 CI / Git 接入] --> CLI - Policy --> CLI - CLI --> Tools[语言原生 lint / 文档 / 安全 / CVE / 构建工具] - Tools --> Report[原始证据 + 标准报告 + 覆盖账本] - Report --> Gate[完整性与违规门禁] - Gate --> Agent - Gate --> CI -``` - -| 交付物 | 所有权 | 不承担的职责 | -|---|---|---| -| `codeguard-cli` | Rust 内核、适配器、rulepack、schema、二进制发布 | 宿主专用提示词和市场目录 | -| `codeguard-plugin` | 三宿主入口、hook 事件映射、运行时版本/摘要绑定 | 复制检查逻辑、另写 verdict、默默 fallback | -| `codeguard-skills` | 使用、诊断、修复步骤的技能事实源 | 生成比工具证据更高优先级的门禁结论 | -| 项目/组织策略 | 规则、适用性、阈值、豁免审批、受保护 CI | 依赖智能体自觉执行作为唯一约束 | - -现有受管技能仍从独立技能仓经 lock/vendor 同步;不直接修改本插件受管副本。新 Rust 仓的远程地址、发布签名身份及平台 ABI 在实施任务中确定,本次不虚构已有仓库或二进制。 - -## 4. Rust workspace 与依赖方向 - -```text -codeguard-cli/ -├── Cargo.toml -├── crates/ -│ ├── codeguard-cli/ -│ ├── codeguard-core/ -│ ├── codeguard-runtime/ -│ └── codeguard-adapters/ -├── rulepacks/ -├── schemas/ -└── tests/ - ├── fixtures/ - ├── integration/ - └── acceptance/ -``` - -仓库、crate 目录和 Cargo package 使用上面的 kebab-case;模块与 `.rs` 文件使用 snake_case;类型使用 PascalCase;二进制名 `codeguard`。一类主要职责一个文件,`mod.rs` 只组织和重导出;不以 `compat.rs` 堆积领域对象,不提交 `todo!()` 适配器作为完成项。新原生实现没有 Java 对应物时,中文 doc 注释说明用途,不伪造 Java 来源。 - -```mermaid -flowchart LR - CLI[codeguard-cli] --> Core[codeguard-core] - CLI --> Runtime[codeguard-runtime] - CLI --> Adapters[codeguard-adapters] - Runtime --> Core - Adapters --> Core -``` - -这是编译依赖图,不是进程调用图。禁止 core 导入 runtime/adapters/宿主 SDK;禁止 adapters 导入 runtime。core 定义 `ExecutionPort`、`SnapshotPort`、`EvidenceStore` 等接口,runtime 实现;CLI 组合运行时与适配器并调用 core 的协调服务。 - -| crate | 主要模块 | 关键责任 | -|---|---|---| -| cli | args、commands、render、mcp、compat | 参数、入口协议、stdout/stderr、终端报告、退出码映射 | -| core | model、policy、planning、coverage、gate、remediation、ports | 检查义务、任务 DAG、结果聚合、覆盖证明、问题生命周期与修复任务;尽量纯函数 | -| runtime | process、snapshot、toolchain、cache、storage、workspace、telemetry | 操作系统进程、Git/文件观察、工具解析、有界资源、持久记录与租约 | -| adapters | java、rust、python、node、shell、… | 专用工具探测、计划、报告解析、覆盖核对、修复计划 | - -初版采用编译期适配器注册。任意脚本、动态库插件或远程规则执行不是默认扩展入口,避免将字符串命令表原样升级为新的执行系统。 - -## 5. 一次检查的完整路径 - -```mermaid -flowchart TD - Request[解析请求与入口协议] --> Resolve[定位项目与输入内容身份] - Resolve --> Contract[解析可信策略和全部必需义务] - Contract --> Discover[发现语言 / 模块 / 依赖清单 / 工具配置] - Discover --> Plan[适配器生成有依赖关系的计划] - Plan --> Ready{前置条件可验证?} - Ready -- 否 --> Incomplete[记录未完成原因与恢复动作] - Ready -- 是 --> Run[复用有效缓存或执行原生工具] - Run --> Parse[工具专用解析器保留全部有效发现] - Parse --> Coverage[核对目标覆盖 / 配置 / 输入身份] - Incomplete --> Gate[门禁聚合] - Coverage --> Gate - Gate --> Output[JSON / 人类报告 / SARIF 与私有证据] -``` - -解析、规划、执行、报告各阶段都可失败;失败必须产生具体原因及未完成义务。某个检查失败不抹掉其他已确认发现。可独立执行的任务继续;依赖失败的任务标为依赖未满足,不能被删掉。 - -`check all` 建立项目全部适用类别的义务;`lint java` 只选择 Java lint。项目没有使用某语言与某语言检查器缺失是不同事实,后者不能伪装成不适用。 - -## 6. 结果与门禁的分离 - -单个检查结果至少包含三个维度: - -- 执行完整性:`complete / incomplete / not_applicable`。 -- 发现:零条或多条带规则、位置、工具证据的 finding;不随执行失败清空。 -- 门禁影响:由有效策略判定,而不是工具退出码或模型的主观置信度决定。 - -```mermaid -flowchart LR - C[完整性] --> G[交付判定] - F[已确认违规] --> G - P[有效质量策略] --> G - G --> A[满足全部义务: allow] - G --> B[存在阻断违规: deny] - G --> I[必需义务未完成: incomplete] -``` - -`incomplete` 与 `deny` 都不满足交付要求,但反馈不同:前者修工具链、配置或证据,后者修代码或依赖。混合情况报告全部发现,顶层优先显示未完成,不能暗示“只是工具故障,没有问题”。 - -注释检查不能被格式化检查替代;`cargo fmt --check` 不等于 `clippy`;CVE 扫描不等于源代码安全检查;Maven `verify` 成功不证明未绑定的 P3C/Checkstyle/Javadoc 已执行。Maven 生命周期通过插件绑定具体目标,必须验证实际执行项。[Maven 官方生命周期说明](https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html) - -## 7. 低误报机制 - -| 误报来源 | 工程控制 | 必需证据 | -|---|---|---| -| Java/Python/SQL/Shell 方言和版本错误 | 读取项目目标版本及构建上下文,验证工具支持矩阵 | 解析依据、工具版本、命令与配置摘要 | -| 工具自身崩溃被当成代码问题 | 工具专用退出码与结构化报告契约 | 原始 rc、故障类型、有效报告片段 | -| 风格默认值与项目约定冲突 | 显式选择版本化 rulepack,解释规则来源 | effective config、规则差异及策略权威 | -| 子模块、生成代码、依赖目录误入 | 模块图、源集、批准排除与覆盖核对 | 义务清单、排除理由、扫描目标集合 | -| 重复或历史发现误处理 | 按稳定规则/位置/内容去重,基线只标 new/existing | 不消失的原始发现及归并映射 | -| CVE 包匹配或严重度不确定 | 真实解析依赖版本、来源与漏洞库元数据 | package identity、依赖路径、advisory、时间与摘要 | -| 正则对注释和安全语义误判 | 优先语言工具/AST 和可测试规则 | 正反例;无证据的语义猜测不成为确定违规 | - -无法确定的检测仍是待解决的覆盖或证据问题,不能通过“低置信度就删除”降低误报率。规则是否阻断由事先确认的策略决定,运行时不动态调低阈值。 - -注释的语法、公共 API 文档存在性、参数/返回值对应关系可用确定性工具检查;“注释是否真正解释业务动机”不能无证据宣称已验证。明确的中文注释要求可作为专用规则,但必须处理专有名词、代码片段、继承文档与生成代码,不能按单字符语言判断粗暴拦截。 - -## 8. 性能与正确性 - -Rust 可减少启动和编排开销,但总耗时通常受外部工具、构建和漏洞库影响;“性能最高”必须通过同范围、同规则、同缓存条件的测量验证。 - -性能手段是复用构建结果、任务 DAG、有界并发、精确缓存和合并相同扫描。增量执行必须证明未重跑义务的输入与配置没有变化,且适配器支持这种复用;证明不了就扩大扫描。文件数从 50 到 51 只能改变调度方式,不能改变问题是否阻断。 - -同一个 target/build 目录和不可并发工具使用资源锁。超时、输出上限、网络状态或缓存故障均不得变成 PASS。保存事件采用较短预算只提供反馈,交付入口使用完整预算;二者结果不能不加区分复用。 - -## 9. 权威与安全边界 - -```mermaid -sequenceDiagram - participant A as 智能体 - participant C as codeguard - participant P as 可信策略源 - participant T as 原生检查器 - participant G as 受保护 CI - A->>C: check all,绑定内容身份 - C->>P: 读取批准的规则与工具锁 - C->>T: 执行计划 - T-->>C: 原生报告与退出状态 - C-->>A: 发现 / 未完成原因 / 门禁状态 - A->>C: 修复代码后复检 - G->>C: 独立加载可信策略并检查待交付内容 - C-->>G: 可核对的最终证据 -``` - -不能从 agent 的“用户已经同意”文本、环境变量、Git config 或可修改的本地 JSON 得出政策授权。策略调整是独立、可审查的变更;合并后的可信修订才作为 CI 的有效版本。例外必须绑定规则、范围、内容身份、原因、批准身份和到期时间,保留原始违规与非通过检查状态;外部系统可记录“经批准例外交付”,不得显示普通 PASS。 - -CLI 与用户同权限,无法防止用户替换二进制、绕过本地 hook 或修改磁盘。完整约束依赖受保护的 CI、可信策略来源及受控状态检查。进程隔离快照不等于系统沙箱;运行项目构建脚本有实际执行能力。 - -受保护 CI 还必须隔离可信验证端与被测项目的执行区:项目脚本不能改写可信策略、工具锁、验证器或最终状态凭据。执行产物是待核验输入;可信端验证输入/规则/覆盖并独立签发结果,不能直接上传项目脚本生成的绿色收据。无法提供这种隔离的环境不宣传不可自降级保证。 - -## 10. 迁移原则 - -先固定契约与真实样本,再逐工具实现适配;先对照验证,再切换宿主;所有原 stable 条目都完成验收后,才宣布全量迁移。迁移对照必须区分“旧实现 bug 修正”和“新实现回归”,不能要求复制旧豁免结果。 - -保存、提示等反馈事件不承担完整交付认证。真正的 Git pre-commit/pre-push 和 CI 优先绑定真实输入;宿主 Shell 预测仅作有边界的前置检查,不重新建造完整 Shell 解释器。 - -现有点前缀忽略策略保持:普通扫描不检查、不逐文件报告点前缀路径;入库安全和配置发现例外不变。报告只记录生效策略及汇总覆盖,不把已排除路径重新变成告警。若未来要检测 `.github/workflows` 等内容,需要单独确认策略变更。 - -新增持久工作区只精确排除生成器拥有的运行/记录文件,改由工作区 schema 与脱敏校验;不会把整个 `codeguard/` 变成免检目录,入库安全仍覆盖这些文件。任务文件只是投影,删除任务、勾选完成或编辑历史都不能替代真实 gate。 - -所有实施任务和待验证项统一维护在 [tasks.md](../../openspec/changes/introduce-rust-codeguard-cli/tasks.md)。 diff --git a/docs/rust-cli/coverage-and-acceptance.zh-CN.md b/docs/rust-cli/coverage-and-acceptance.zh-CN.md deleted file mode 100644 index 8d17faa..0000000 --- a/docs/rust-cli/coverage-and-acceptance.zh-CN.md +++ /dev/null @@ -1,167 +0,0 @@ -# Codeguard Rust CLI 语言迁移与验收设计 - -状态:待执行。语言清单取自 `03ebb24` 的 [scripts/languages.json](../../scripts/languages.json),共 57 项:54 stable、3 planned。表中工具是旧注册声明或迁移调查入口,**不是已核验的新适配器能力**。不存在的 Rust 实现不计完成;只有 formatter 的旧 stable 也必须补足真实只读检查。 - -## 1. 每种语言的能力账本 - -每一 language/module 都生成 `lint/comments/cve/security/build` 五个槽位,分别记录 `implemented / gap / not_applicable`,并附 adapter、规则、工具版本、适用性证据及验收记录。 - -- `implemented` 只表示具备通过验收的实现;一次运行仍可能 incomplete。 -- `gap` 表示有义务但没有可靠能力,交付不能通过。 -- `not_applicable` 必须有结构性理由,例如完整依赖发现证明没有第三方组件,或配置文件语言没有独立编译步骤。缺工具、缺规则、扫描失败不能作为理由。 -- 外部 ecosystem 扫描可满足多个相关语言的 CVE 义务,但需要可追溯映射。纯 Markdown 的 build 可能不适用,其链接站点构建、文档规则仍按项目声明产生义务。 -- 宣传能力矩阵由同一注册数据生成;明确语言/类别/平台覆盖,不能只有“支持 57 种语言”的单一数字。 - -## 2. 全量迁移清单 - -波次仅是执行顺序:A 先跑通端到端,B/C 补齐现有 stable,P 保留原 planned 路线图。全量迁移必须完成 A/B/C;P 不强制虚构实现,但如果目标项目要求 P 对应能力,仍不能通过。 - -| language ID | 旧状态 | 旧 lint 声明/调查入口 | 波次 | 必须验证的差异 | -|---|---|---|---|---| -| java | stable | Maven verify | A | P3C、注释、安全、CVE 各自取证;Maven/Gradle/JDK 矩阵 | -| rust | stable | cargo clippy | A | workspace/features/targets、rustdoc、依赖审计 | -| typescript | stable | ESLint | A | JS/TS 别名、parser、tsconfig、type-aware 上下文 | -| python | stable | Ruff | A | 目标 Python、docstring 规则、依赖图 | -| go | stable | go vet | B | 多模块、build tags、依赖与文档规则 | -| csharp | stable | dotnet format --verify-no-changes | B | analyzer、solution、目标 framework、XML 文档 | -| kotlin | stable | Gradle detekt | B | Kotlin/JVM 版本、Gradle 项目与 KDoc | -| swift | stable | SwiftLint | B | Swift/Xcode 工具链、平台与文档规则 | -| php | stable | php -l | B | 语法检查不能代表完整编码规范;配置与 PHPDoc | -| ruby | stable | RuboCop | B | Ruby 版本、cop 配置、依赖与注释 | -| scala | stable | scalafmt --check | B | 格式之外的诊断义务及 Scaladoc | -| shell | stable | ShellCheck | A | sh/bash/zsh 方言分别建模;不得静默抛弃 zsh | -| dockerfile | stable | Hadolint | A | Dockerfile 变体、配置安全与镜像依赖范围 | -| yaml | stable | yamllint | B | 原生配置与 YAML 方言、模板文件 | -| elixir | stable | Credo | B | Mix project、依赖、模块文档 | -| css | stable | Stylelint | B | CSS 方言及插件,不能将任意预处理器当 CSS | -| c | stable | clang-tidy | B | compile_commands、目标平台、头文件上下文 | -| cpp | stable | clang-tidy | B | 编译数据库、模板、标准版本、头文件 | -| objc | stable | clang-tidy | B | Objective-C/Objective-C++ 与 SDK | -| dart | stable | dart analyze | B | SDK、analysis_options、pub 依赖 | -| vue | stable | ESLint | B | SFC parser、template/script/style 覆盖 | -| svelte | stable | ESLint | B | Svelte parser/plugin 与编译上下文 | -| astro | stable | ESLint | B | Astro parser/plugin、模板与内嵌语言 | -| solidity | stable | Solhint | B | pragma/compiler、静态安全和依赖 | -| terraform | stable | TFLint | B | provider/module 版本、IaC 安全与锁 | -| nix | stable | deadnix | B | dead-code 不代表完整安全;Nix 表达式和锁 | -| html | stable | HTMLHint | B | 模板方言显式适用,不能正则过滤后假装全覆盖 | -| sql | stable | SQLFluff | B | dialect、templater、项目配置 | -| graphql | stable | ESLint | B | schema/operation/plugin,上下文关联 | -| protobuf | stable | buf lint | B | module/workspace 与依赖 | -| markdown | stable | markdownlint-cli2 | B | 项目规则、代码块、MDX 等方言 | -| toml | stable | Taplo | B | TOML/schema 规则与项目归属 | -| haskell | stable | HLint | C | GHC extensions、项目依赖、文档规则 | -| ocaml | stable | ocamlformat --check | C | 原命令可执行性、Dune/opam、格式之外义务 | -| fsharp | stable | dotnet fantomas --check | C | F# 项目/工具锁与编译诊断 | -| perl | stable | Perl::Critic | C | Perl 版本、profile、POD | -| groovy | stable | npm-groovy-lint | C | Groovy/Gradle 方言与只读执行模式 | -| clojure | stable | clj-kondo | C | namespace/classpath、配置与文档元数据 | -| powershell | stable | PSScriptAnalyzer | C | PowerShell 版本、对象报告与 comment help | -| zig | stable | zig fmt --check | C | 格式与编译义务分离、Zig 版本 | -| nim | stable | nim check | C | 命令真实输入、项目入口与依赖 | -| crystal | stable | Ameba | C | Crystal 版本、shards、文档规则 | -| julia | stable | lint 为空;旧表有 format 能力 | C | 找到并验证只读检查器,不以 formatter 宣称 lint 完成 | -| elm | stable | elm-review | C | review 项目配置、依赖与锁定规则 | -| lua | stable | Luacheck | C | Lua 版本/globals、文档约定 | -| luau | stable | luau-analyze | C | Luau 类型环境,不能复用 Lua 语义 | -| pascal | stable | lint 为空;旧表有 format 能力 | C | 编译器/方言与只读检查能力补齐 | -| r | stable | lintr | C | R 版本、包项目、对象报告与文档 | -| cfml | stable | CFLint | C | CFML 引擎、模板和报告版本 | -| cobol | planned | 无 | P | 显式 capability gap,保留迁移记录 | -| vbnet | stable | dotnet format --verify-no-changes | C | VB analyzer、solution、XML 注释 | -| erlang | stable | Elvis | C | OTP/rebar、规则与文档 | -| arkts | planned | 无 | P | SDK/编译器可用性未知,不能标成功 | -| metal | planned | 无 | P | Apple SDK 能力未知,不能标成功 | -| liquid | stable | theme-check | C | 主题结构、Liquid/HTML 边界 | -| cuda | stable | clang-tidy | C | CUDA toolkit、host/device、编译数据库 | -| ansible | stable | ansible-lint | C | collections、playbook、依赖及安全规则 | - -旧表只有 lint 声明并不代表其它类别不需要做;每行必须附完整五槽位记录后才可以验收。`java`/`kotlin`/`scala` 等可共享 Maven/Gradle 依赖图,不能重复扫描造成重复 CVE,也不能漏掉另一构建根。 - -## 3. 必备场景库 - -每个新 stable adapter 至少含以下 fixture 类型;工具模拟只测执行边界,最终必须用真实二进制完成正反例。 - -| 编号 | 场景 | 验收 | -|---|---|---| -| F01 | 正确源码,正确配置与版本 | 完整、零阻断违规;实际目标非空 | -| F02 | 一条确定违规与对应最小修复 | 检出规则和正确位置;复检不再有该 finding | -| F03 | 缺命令/运行时、版本不兼容、坏配置 | incomplete,违规数不因工具故障虚增 | -| F04 | 原生非零但没有有效报告 | incomplete,不靠通用 rc 推断违规 | -| F05 | 有效违规后超时/崩溃/输出截断 | 保留 finding,同时 incomplete | -| F06 | exit 0 但空/畸形/陈旧/矛盾报告 | incomplete,不能假 PASS | -| F07 | 模块/方言/生成代码/配置继承 | 按批准规则准确覆盖;不能自行扩大或缩小 | -| F08 | 字符编码、特殊路径、空格、换行、非 UTF-8 | 身份可逆;无注入、无静默丢目标 | -| F09 | 内容或原生配置同大小同 mtime 替换 | 缓存失效;检查绑定实际输入 | -| F10 | 规则/工具/漏洞库更换 | 重新计算,不复用旧通过 | -| F11 | 50/51 文件、顺序变化、并发度变化 | findings 和 gate 等价;只有耗时变化 | -| F12 | 历史问题在未修改文件 | existing 分类,仍按相同规则阻断 | -| F13 | Agent 尝试 skipGate/env/suppression/提高阈值 | 不能获得新交付 allow,留下策略差异 | -| F14 | formatter 成功但无变化/失败后部分变化 | 分开执行成功、内容变化与已修复 | -| F15 | 原始诊断含凭据,日志目录/文件 symlink | 公共报告脱敏,目标不被意外覆盖 | -| F16 | index 与工作树不同、多 ref/non-HEAD push | 检查真实内容;不改 index | -| F17 | 所有发现为零但有一个必需类别缺能力 | exit 3,不能签发交付通过 | -| F18 | 点前缀源码/配置/.env | 普通面不扫描不逐文件报告;配置发现及入库安全例外保留 | -| F19 | Java verify 没绑定 P3C/Javadoc | 不得据 verify 成功声称全部质量义务完成 | -| F20 | 库过期/离线、模糊包匹配、未知严重度 | CVE 不伪造安全通过,也不伪称确定高危 | -| F21 | stdout/stderr 洪流、fork 子孙进程、取消 | 有界结束、清理、部分证据、无孤儿进程 | -| F22 | 同一请求 CLI/MCP/Hook/CI 输出转换 | 语义一致,协议退出码按各自表映射 | -| F23 | 多工具重复发现或同规则多次出现 | 归并可追溯,次数不丢失,不跨文件抵扣 | -| F24 | 项目脚本禁用 analyzer 或自定义命令仅 echo | 覆盖不足,不能被命令 exit 0 欺骗 | - -## 4. 误报与漏报的评测方法 - -采用两层语料:确定性合成正反例用于边界与回归;脱敏的真实项目样本用于规则适用性、方言、依赖与报告准确性。样本按语言、类别、工具版本和项目规模分层,保留独立 holdout,不能只挑工具最容易通过的项目。 - -每条裁定记录由人工或经过确认的 oracle 给出:应有 finding、规则依据、位置/依赖定位、应有执行状态、覆盖义务。争议样本单独统计,不靠模型投票充当真值。样本来源、版本、内容摘要、工具锁、裁定理由随报告归档。 - -| 指标 | 定义 | 防止指标失真 | -|---|---|---| -| Precision | TP / (TP + FP) | 附 finding 样本量;无发现时记不可估计,不能报 100% | -| False discovery rate | FP / (TP + FP) | 不与传统 FPR 混称 | -| Recall | TP / (TP + FN) | 使用已知真问题语料,保留漏报原因 | -| 工具故障误判率 | 被错误标成代码违规的故障样本 / 全部故障样本 | 单列,不与代码 FP 混在一起 | -| 完整率 | 完成且覆盖匹配的必需义务 / 全部适用必需义务 | 删除义务、增加排除会进入差异审计 | -| 假通过数 | incomplete、坏证据或已知阻断违规却 allow 的样本数 | 必须为零;未知不能算通过 | -| 稳定性 | 相同输入/工具/规则/库身份重跑结果一致比例 | 按规则定位不稳定来源 | -| 性能 | 同环境冷/热启动、p50/p95、峰值内存、缓存命中 | 对比覆盖/规则/工具完全一致 | - -建议发布门槛(目标,不是已达成指标):确定性必备场景零假通过、零工具故障误判;新增 adapter 必须检出其全部预置真问题;关键安全/CVE 回归零漏报;每个有足够裁定样本的 adapter/category 的 precision 95% Wilson 下界至少 0.98。没有足够样本的能力不得借全局平均值升级为充分验证;预览版本标明证据不足。 - -统计门槛调整属于人工可审查的验收标准变化,智能体不得为了完成任务调低。每个分层至少列出 n、TP、FP、FN、区间、规则数和项目数;CI 跑固定离线集,周期性真实工具/漏洞库运行单独跟踪,避免网络波动污染确定性回归。 - -性能先建立基线,再由维护者冻结绝对预算;本次不编造毫秒级承诺。验收首先要求优化前后发现集合、完整性、覆盖身份等价,才比较启动、扫描和缓存性能。 - -## 5. 发布与迁移验收矩阵 - -| 层次 | 证据 | 不可替代它的证据 | -|---|---|---| -| Rust 源码 | fmt/clippy/test、依赖方向、schema/fixture 测试 | 文件存在或编译成功 | -| 工具适配 | 固定工具链真实正反例、故障与修复复检 | mock 输出解析通过 | -| 全语言覆盖 | 54 stable 五槽位验收 + 3 planned 明示 | Java/Python/Rust/TS 演示 | -| Git/CI | 实际 index、多 ref push、受保护策略测试 | Shell 字符串静态识别 | -| 制品 | target triple、摘要/签名、安装及离线 doctor | Release 页面存在 | -| 插件接入 | Codex/ZCode/Kimi 每种事件真实调用新二进制 | manifest 语法正确 | -| 市场与安装 | source/lock/vendor/market/installed version/digest 对齐 | 本地单元测试通过 | -| 产品结果 | 固定语料 precision/recall/完整率与历史差异裁定 | “误报已经很低”的主观描述 | - -验收记录建议包含 `requirement_id / task_id / fixture_or_project / tool_lock / source_digest / expected / actual / artifact_refs / reviewer / date`。任务只有对应证据可定位且通过时才勾选。 - -## 6. 规范到任务追踪 - -| 规格能力 | 任务阶段 | 主要场景 | -|---|---|---| -| unified-cli-contract | S01、S02、S11 | F17、F22、CLI 错参/空输入 | -| native-tool-adapters | S05、S06、S07、S08 | F01–F08、F19、F20、F23、F24 | -| rulepack-governance | S04、S05、S12 | F07、F10、F12、F13、F18 | -| verdict-integrity | S02、S12 | F03–F06、F12、F17 | -| execution-kernel | S03、S10、S12 | F08–F11、F14–F16、F21 | -| language-gate-commands | S05–S08、S12 | F03、F07、F11、F19 | -| hook-protocol | S11、S12 | F13、F16、F22 | -| binary-distribution | S11、S13 | 摘要不匹配、无网络、版本回滚、三宿主实机 | -| remediation-workflow | S09、S10、S11、S12 | 重复发现归并、跨类别同步、attempt 预算、复检关闭/重开、租约冲突 | -| scan-scope-policy | S04、S09、S12 | 自有产物不递归扫描、用户源码仍检查、入库安全不豁免 | - -## 7. 完成边界 - -当前仅完成设计文件;上述表格无一构成适配器已实现证明。实施顺序与核对框统一位于 [OpenSpec tasks](../../openspec/changes/introduce-rust-codeguard-cli/tasks.md)。旧实现对照仅用于解释差异,不作为新系统必须复制错误的依据。 diff --git a/docs/rust-cli/remediation-workflow.zh-CN.md b/docs/rust-cli/remediation-workflow.zh-CN.md deleted file mode 100644 index 3259a19..0000000 --- a/docs/rust-cli/remediation-workflow.zh-CN.md +++ /dev/null @@ -1,214 +0,0 @@ -# Codeguard 持久问题与修复工作流 - -Codeguard 在项目根创建 `./codeguard/`,将“发现问题 → 形成任务 → 指导修复 → 原工具复检 → 关闭或重开”变为可恢复的工作流。目录既服务人,也服务智能体;检查器负责事实,工作流负责下一步,批准策略决定交付。 - -状态:待实现设计。本篇补充 [架构](architecture.zh-CN.md) 和 [技术方案](technical-design.zh-CN.md),规范为 [remediation-workflow](../../openspec/changes/introduce-rust-codeguard-cli/specs/remediation-workflow/spec.md)。已有 OpenSpec 管理 Codeguard 自身开发规格;项目内 `codeguard/tasks/` 管理被检查项目的修复任务,两者不能互相充当完成证明。 - -## 1. 为什么需要持久工作区 - -一次终端报错容易丢失上下文:智能体看不到此前尝试、修复是否改变了问题、是否缺环境,最终可能重复相同动作或绕过门禁。持久工作区应能回答六个问题: - -1. 当前还有哪些真实问题和未完成检查? -2. 这个问题来自哪个工具、规则和哪份内容? -3. 应该改源码、依赖、工具链,还是提交规则配置变更? -4. 下一步具体执行什么,允许改哪些文件? -5. 上次尝试为何失败,是否适合继续自动修复? -6. 用什么复检证据证明已解决,哪些交付义务仍未完成? - -## 2. 目录及版本控制 - -```text -project/ -├── codeguard.json # 已有配置入口,继续唯一 -├── codeguard.lock.json # 工具/adapter/rulepack 锁 -└── codeguard/ - ├── .gitignore # 忽略下面的本地运行数据 - ├── README.md # 本项目工作流说明与常用命令 - ├── workspace.json # 工作区 ID/schema/受管路径清单 - ├── findings/ - │ └── CG-/ - │ ├── finding.json # 脱敏、稳定的问题事实 - │ └── events/ - │ └── .json # 发现、尝试、复检、关闭/重开的审计事件 - ├── tasks/ - │ └── CG-.md # 面向人/智能体的修复任务投影 - ├── decisions/ - │ └── .json # 外部批准决策的引用,不是本地授权旗标 - ├── reports/ # 本地标准报告与复检报告 - ├── runs/ # 本地原始输出、进程证据 - ├── cache/ # 本地工具/扫描缓存索引 - ├── worktrees/ # 本地隔离扫描或修复副本 - └── state/ # 本地锁、领取租约、队列索引和恢复日志 -``` - -默认 `.gitignore`: - -```gitignore -/reports/ -/runs/ -/cache/ -/worktrees/ -/state/ -``` - -README、workspace manifest、脱敏 findings/events、任务文档与决策引用默认可入 Git,便于团队审查和交接;原始日志、缓存、临时源码与领取状态不提交。工具全局缓存可继续在用户缓存目录,本地 cache 只保存所需索引,不要求复制所有工具。 - -记录中不能包含密钥、原始环境、带令牌 argv 或不必要的源码片段。finding.json 保存最小定位、规则依据与不可变证据摘要;详细原文留本地私有 runs。另一台机器缺少本地证据时,可以根据稳定信息重新检查,不能凭仓库里的“已关闭”获得交付认证。 - -`workspace.json` 不是第二份质量配置。它只描述此工作区 schema、ID 和受管文件集合;质量要求仍来自 `codeguard.json` 引用的可信策略和 lock。任何普通文件中的“approved”都不构成授权。 - -项目尚未初始化时,check 的原始报告写入私有用户缓存,不自行创建未被 Git 忽略的 codeguard/runs;初始化后才按固定目录路由本地证据。现有文件进入受管范围需要精确的初始化计划,不能仅靠同名目录推定所有权。 - -### 防止 Codeguard 检查自己的运行产物 - -`codeguard/` 不是点目录,不能依赖现行点前缀规则排除。新增明确的“工具自身产物”范围契约:初始化清单绑定的 reports/runs/cache/worktrees/state 与生成 finding/task 文件不进入被测项目的普通源码发现,而由 Codeguard 自己进行 schema、路径和脱敏校验。 - -不得简单忽略所有名为 codeguard 的目录;已有 `codeguard/src/`、用户文件和未声明路径照常检查。受管路径必须来自经过校验的生成器清单,不接受 agent 任意扩张排除。入库安全检查仍覆盖拟提交的记录,不能借工具产物身份提交密钥。此新增规则须随本 change 明确更新 scan-scope-policy,现行点前缀规则保持不变。 - -## 3. 三种记录分别解决什么问题 - -| 记录 | 来源 | 用途 | -|---|---|---| -| RunReport | 一次真实检查 | 描述本次内容、执行、全部发现和未完成义务 | -| Finding/Blocker | 多次检查归并的稳定对象 | 追踪代码问题或工具环境阻塞的生命周期 | -| RepairTask | 从对象、规则修复知识和项目上下文生成 | 告诉执行者下一步、限制和验收方式 | - -代码违规创建 `kind=finding`,工具缺失/配置错误/数据库不可用创建 `kind=blocker`。blocker 可以解除后继续原检查,但不能把它伪装成“代码问题已修复”。纯运行噪声、重复日志不各自生成任务。 - -多个 findings 可由同一根因修复时生成一个任务组,逐项保留关闭条件;例如十个模块缺同一 JDK,先生成一个工具链准备任务,并使其依赖检查等待。不能为降低任务数而把不同规则的证据合并掉。 - -## 4. 状态机 - -```mermaid -stateDiagram-v2 - [*] --> open: 首次有效发现 - open --> ready: 修复目标和验收已明确 - open --> blocked: 缺环境或需人工决策 - ready --> in_progress: 领取租约 - in_progress --> awaiting_verification: 修复产物已准备 - awaiting_verification --> resolved: 绑定证据复检确认 - awaiting_verification --> ready: 同一问题仍存在 - awaiting_verification --> blocked: 复检未完成 - in_progress --> blocked: 重复失败或超出自动修复范围 - blocked --> ready: 前置条件恢复 - resolved --> open: 新内容重新检出 -``` - -`resolved` 必须有关闭原因:`code_fixed`、`dependency_fixed`、`environment_restored`、`target_removed` 或 `policy_resolved`。后两者不能被报告成代码已修复:真实删除需要 Git 内容/范围证据;规则正式变更需要可信批准修订和迁移映射。新增 ignore、移动到排除目录、未知规则映射或未验证删除不能自动关闭。 - -`accepted_exception` 是独立处置标签,保留未解决事实与例外到期条件;不是 resolved,不计入修复成功率。规则被新版批准策略移除时,旧记录可以 policy_resolved,但原证据及策略变更历史保留。没有新证据仅手工改状态、勾选 Markdown,最多表示执行者声称完成,正式状态仍 awaiting_verification。 - -任务完成与交付通过独立:关闭一项只证明那一项;`check all`/`gate` 仍需检查完整 contract,发现修复引入的新问题。全部任务被删除或勾选也不能生成 allow。 - -## 5. 稳定身份、事实源与协作 - -首次发现生成稳定 issue ID,后续使用工具/规则 ID、仓库相对路径、符号/内容锚点及类别匹配。CVE 使用 ecosystem/component/advisory/依赖定位。行号是展示信息,不能作为唯一身份。文件重命名使用 Git 关联与锚点匹配;匹配不确定时保留候选关系,不错误关闭旧问题。 - -`finding.json` 保存初始事实和身份;每次有意义的状态变化追加一个唯一 event 文件,携带 parent event ID、原内容/政策/工具身份、run evidence digest、actor、时间和变化原因。派生状态和 tasks Markdown 可以重建,不能作为新的事实权威。 - -事件文件是可审查历史,不是密码学授权或无需复检的证明。用户同权限可以修改 Git 文件,因此 CI 独立读取可信策略并复检代码。事件冲突、丢失父节点或相互矛盾的关闭事件产生 `reconciliation_required`,不采用“最后一个写入 wins”关闭问题。 - -`state/` 中使用跨进程锁和带到期的 task lease;claim/heartbeat/release 通过 CLI 完成。租约只防止同工作区重复劳动,不授权改质量规则。不同机器通过独立分支提交事件,合并后按父关系核对;远程全局调度不在初版保证内。 - -同一问题在同一内容/策略下反复扫描,只更新本地 last_seen 和 runs,不反复改 tracked finding/task 文件。发现集合、修复状态或重要上下文变化才生成持久事件,减少 Git 噪声。保存 Hook 不自动把一整份持久清单刷进用户工作树。 - -## 6. CLI 工作流 - -```bash -codeguard init . --dry-run -codeguard init . --apply - -codeguard check all . --format json -codeguard work sync . -codeguard status . -codeguard next . --format json -codeguard task show CG-abc123 . -codeguard task claim CG-abc123 . --owner agent-session-1 -codeguard task attempt start CG-abc123 . --owner agent-session-1 - -# 智能体按照任务修改源码或修复环境 -codeguard task attempt finish CG-abc123 . --owner agent-session-1 --outcome ready-to-verify -codeguard task verify CG-abc123 . --format json -codeguard task release CG-abc123 . --owner agent-session-1 -codeguard check all . --format json -``` - -`init --dry-run` 输出创建/冲突清单;`--apply` 只创建自有工作区文件,不覆盖已有目录内容或修改质量阈值。已存在同名用户目录时合并计划须精确到文件,冲突路径拒绝写入;不以 `--force` 吞掉用户文件。 - -`work sync` 消费与当前工作区绑定、schema 有效的本地报告,生成/归并记录与任务。默认按 run_id 游标幂等消费所有尚未导入的匹配报告;同一内容先 lint 再 CVE 的报告必须合并,不能只取最后一份。每份报告分别验证内容、政策、工具与检查范围;已过时的报告可保留历史,但不能导入为当前事实。部分报告只能增加有效发现/阻塞,不能据未出现自动关闭旧问题,完整报告也不能跨未覆盖范围关闭。 - -`status/next/task show` 只读;`next` 不自动领取,返回最适合推进的任务和选择理由。`claim/release/heartbeat` 只改本地 lease。`task verify` 运行该问题及受影响范围的真实检查并按证据追加事件;不等于全项目 gate。CLI 不提供无需证据的 `task close --force`。 - -`task attempt start/finish` 登记尝试 ID、动作指纹、执行者、前后内容/patch 摘要与结果;finish 的枚举是 ready-to-verify、no-change、failed、blocked,不能直接 resolved。受控 `fix` 自动写这些事件;自由源码修改由插件在修复回合前后调用。中断未 finish 的尝试在租约恢复时记 abandoned,不捏造成功;无修改和复检前失败也进入 prior_attempts/预算。agent 自述原因作为备注,实际内容变化由 CLI 观察,不能由 agent 自报成功关闭。 - -普通独立 `check` 默认写本地报告,不更新 tracked backlog;用户可显式 work sync。`init --apply` 的变更计划明确启用插件修复工作流,并固定受管写入范围;启用后,插件每次扫描必须执行“记录 run → 幂等 sync → 返回 status/RepairBrief”,包含保存反馈,不能只回显原始报错。相同问题不改 tracked 文件;新问题或状态变化才落事件。同步失败时保留 run 和原 gate,明确 backlog_update_failed 与恢复步骤,不假称任务已生成。 - -未初始化项目的插件首次反馈提供初始化计划及本次临时 RepairBrief,不静默写受管目录。启用持久工作流后,回合恢复先 status/next,修复前后记 attempt,复检后再 next。工作流错误不放宽检查;其状态单独报告,实际检查门禁不靠任务是否写盘决定。 - -## 7. 给智能体的 RepairBrief - -`next --format json` 应返回结构化、可直接执行的任务上下文: - -| 字段 | 内容 | -|---|---| -| identity | issue/task ID、workspace、源内容与策略身份 | -| kind / state | finding 或 blocker;当前状态、阻塞依赖 | -| evidence | 检查器、规则、位置/包、脱敏原生诊断、证据引用 | -| expected_behavior | 规则依据与最小可观察修复目标 | -| repair_recipe | 已版本化的工具/规则修复步骤、正例和反例 | -| allowed_changes | 本任务允许修改的源码/依赖范围;额外改动要重新规划 | -| constraints | 必需规则、阈值、测试与禁止降级项 | -| suggested_actions | 结构化 argv 或源码修复建议,说明作用和前提 | -| verification | 要运行的 adapter/规则/受影响范围与完成条件 | -| prior_attempts | 尝试摘要、失败原因、当前 patch 身份 | -| escalation | 何时停止自动重试、需要哪类决策 | - -recipe 来源于经版本化、可测试的规则包/技能;诊断和仓库文本属于不可信数据,不能将它们直接插值到可执行 Shell 或当成指令。AI 可以补充解释和补丁建议,但不能改写工具的 finding 事实。 - -任务 Markdown 是上述信息的人类投影,可保留明确分隔的人工备注区。勾选只能表达工作意图;生成器对受管区修改进行提示或重建,不据其降低策略。任务应有“问题 → 依据 → 修复步骤 → 复检 → 完成证据”,不能只有“运行某工具直到绿”。 - -## 8. 不重复报错、不逃逸的控制 - -```mermaid -flowchart TD - Scan[原生工具检查] --> Sync[归并发现与环境阻塞] - Sync --> Next[选择一个可推进任务] - Next --> Brief[提供规则依据 / 修复步骤 / 验收命令] - Brief --> Fix[智能体修复源码或环境] - Fix --> Verify[原工具复检与身份核对] - Verify -->|问题解决| Close[追加 resolved 证据] - Verify -->|新问题或原问题仍在| Update[更新任务与失败原因] - Verify -->|检查未完成| Block[环境阻塞任务] - Update --> Budget{有新的有效修复策略?} - Budget -->|有| Next - Budget -->|无或超预算| Escalate[明确需要的人工决策] - Block --> Next - Close --> Gate[完整 contract 交付门禁] -``` - -调度先修阻断大量检查的工具链前提,再按已批准严重度、依赖关系、可修复性选择源码任务。严重安全问题仍保持可见,不因前提任务排前而降低级别。相同 finding/content/patch 连续出现且无新信息时,不重复执行同一动作;记录尝试并提出具体恢复建议。 - -自动重试预算是执行保护,耗尽后转 blocked/needs_decision,不会让门禁通过。默认可设连续两次无进展后停止该任务自动重试,继续其它独立任务;预算值是运行选项,不能修改质量要求。需要用户时,问题应具体到缺失的工具安装授权、业务行为选择或有证据的规则缺陷,不能直接建议“跳过 Codeguard”。 - -“疑似误报”创建规则/adapter 缺陷调查任务,带最小复现与原生输出;在正式修复规则或批准策略变更之前,原检查状态不凭主观判断消失。工具误判可修复适配器并重新运行;不能借修改被测项目 tests 或忽略规则实现闭环。 - -## 9. 闭环验收 - -| 场景 | 必须观察到的结果 | -|---|---| -| 同一问题扫描十次 | 一个稳定 issue,运行记录可查,无十份重复任务 | -| 同内容先 lint 再 CVE 后同步 | 两份未消费报告均进入清单,重复同步幂等 | -| 缺 JDK 导致多个模块未检查 | 一个可复用前置 blocker,依赖检查完整列出 | -| 手工将任务勾为完成 | 无复检则正式状态不关闭,gate 不变 | -| 修复后工具超时 | awaiting_verification/blocked,保留原 finding,不自动关闭 | -| 未完成批次没再输出旧问题 | 不据缺失推断 resolved | -| 移动文件或新增 ignore | 无可证明等价覆盖时不能关闭旧问题 | -| 真正修复后同规则复检干净 | 记录内容/规则/工具/范围与 resolved 事件 | -| 已修问题重新出现 | 同一匹配 issue 重开,保留历史尝试 | -| 两个智能体同时领取 | 同工作区仅一份有效 lease;租约过期可恢复 | -| 修复在复检前失败或无修改 | attempt 与预算仍记录,next 不再推荐耗尽且无新信息的相同动作 | -| 不同分支出现冲突关闭事件 | reconciliation_required,不能取最后写入作为真值 | -| 删除全部 tasks/findings | 新检查仍发现真实问题;无法靠清空目录通过 | -| 受管目录含 secret 或用户源码 | secret 仍经入库安全;未声明源码正常扫描 | - -这套目录应成为智能体的修复工作台。最终判断始终回到真实内容、有效政策和原生检查器,文件记录帮助推进工作,不能替代检查本身。 diff --git a/docs/rust-cli/technical-design.zh-CN.md b/docs/rust-cli/technical-design.zh-CN.md deleted file mode 100644 index 181d0fe..0000000 --- a/docs/rust-cli/technical-design.zh-CN.md +++ /dev/null @@ -1,292 +0,0 @@ -# Codeguard Rust CLI 技术方案 - -状态:待实现;命令、字段与文件布局是目标协议,不代表当前 Python CLI 已支持。规范性事实源为 [本次 OpenSpec](../../openspec/changes/introduce-rust-codeguard-cli/proposal.md)。 - -## 1. 命令模型 - -```text -codeguard [path] - [--format human|json|sarif] [--output PATH] - [--jobs N] [--timeout DURATION] [--offline] -codeguard plan [path] -codeguard detect [path] [--format human|json] -codeguard capabilities [language] [--format human|json] -codeguard doctor [language|all] [path] [--format human|json] -codeguard rules list [--format human|json] -codeguard config [path] [--format human|json] -codeguard fix [path] --category - <--dry-run|--apply> [--format human|json] -codeguard gate [path] [--format human|json] -codeguard tools [--format human|json] -codeguard tools install --lock PATH -codeguard init [path] <--dry-run|--apply> -codeguard work sync [path] -codeguard status [path] -codeguard next [path] [--format human|json] -codeguard task [path] [--format human|json] -codeguard task [path] --owner ID -codeguard task attempt [path] --owner ID [--outcome VALUE] -codeguard mcp serve -codeguard compat legacy-v1 <旧子命令与参数> -``` - -检查命令的 language 必填,path 默认当前目录。canonical ID 沿用现有注册表,别名由同一注册表解析;`all` 是发现所有适用语言及类别,不是对所有注册语言强制安装工具。未知语言在执行前返回用法错误。 - -`gate pre-push` 接受 Git hook 的 remote 参数与 stdin ref/OID 元组;`gate ci` 接收 CI 明确提供的不可变 commit/ref 集合。实际参数 schema 在 S02 固化,禁止通过默认 HEAD 推测所有推送目标。 - -```bash -codeguard lint java . --format json -codeguard comments java . -codeguard cve all . --offline -codeguard check all . --format json --output codeguard-report.json -codeguard plan check all . -codeguard doctor java . -codeguard fix java . --category lint --dry-run -``` - -检查命令默认不修改源码、配置、Git index,也不自动修复;构建产物和工具缓存写入隔离运行区。`plan` 不执行构建、扫描、下载或安装,只读取计划所需信息;无法静态确定的部分记为待解析。`doctor` 可执行有界版本探测,但不执行安装。`tools install` 是独立显式动作,不由扫描隐式触发。 - -`check` 的类别是 lint、comments、cve、security、build;项目不适用的类别须有结构性依据。build 的测试执行是独立参数:沿用现有 Java 静态构建默认不运行测试;报告必须写明 test_execution=false,不能声称测试通过。若批准策略要求测试,必须运行,CLI 不提供自动跳过路径。 - -持久修复工作区及新增命令的写入边界见 [修复工作流](remediation-workflow.zh-CN.md)。check 写本地报告,work sync 显式更新脱敏问题/任务;next 只读并返回 RepairBrief,task verify 依据复检追加状态事件,不能手工强制关闭。 - -## 2. 退出码、请求通过与交付通过 - -| 新 CLI 退出码 | 条件 | -|---|---| -| 0 | 请求选中的全部适用义务已完成且无阻断违规 | -| 1 | 请求已完成,存在阻断违规 | -| 2 | 参数语法、未知子命令/语言等用法错误;未启动检查 | -| 3 | 必需义务未完成:缺工具、无能力、坏配置、超时、无效报告、覆盖不全等 | -| 4 | Codeguard 内部故障或无法建立可信结果 | -| 130 | 用户取消;已有结果保留为部分结果 | - -聚合优先级:取消 > 内部故障 > 未完成 > 违规 > 请求通过;用法错误只在执行前产生。单检查执行故障不等于进程原生 exit=3;`raw_exit_code` 单独保存,进程未启动或由 signal 终止时可为 null,并有 `termination_reason`。 - -`lint java` 可以 exit 0,但报告 `delivery_gate.decision=not_evaluated`、`eligible=false`。只有 `check all` 或交付入口完成整份质量 contract,且内容与可信策略匹配时才可 `allow`。完整扫描无适用对象时可以 exit 0,但结果为 `not_applicable`,不能显示“全部已验证”,也不能用空输入签发交付认证。显式 `lint java` 找不到任何 Java 目标则 exit 3,避免目录选错变绿。 - -`check java` 完成全部 Java 义务;除非计划已证明该项目整份 contract 只含 Java 且所有跨语言依赖义务也覆盖,否则不签发全项目通过。实现初版可统一限制为 `check all`/`gate` 才计算交付 allow。 - -## 3. 数据模型与协议 - -`schema_version` 使用 major.minor 字符串,初始目标为 `1.0`;二进制版本、adapter 版本、rulepack 版本分别记录。消费者必须拒绝未知 major,允许兼容 minor 的可选扩展;禁止宽松读取未知枚举后按通过处理。 - -| 对象 | 关键字段 | 不变量 | -|---|---|---| -| CheckRequest | command、selection、root、content_source、operational_options | 用户选择与批准策略分开 | -| PolicyIdentity | source、revision、digest、authority | digest 证明一致性,不单独证明授权 | -| ContentIdentity | source_kind、repository/worktree identity、commit/index/tree digest、manifest digest | 不能仅用路径/mtime/size | -| CheckObligation | id、module、language、category、required、targets、rule_ids | 先有义务,再选择工具,缺工具不能删除义务 | -| CheckPlan | obligations、tasks、dependency_edges、resource_keys、scope_digest | DAG 无环;未执行任务有解释 | -| ToolExecution | executable identity、argv、cwd、env fingerprint、times、raw rc、artifacts | 原始敏感参数只进私有证据 | -| CheckResult | obligation_id、completion、reason、findings、execution_refs、coverage | findings 与 completion 正交 | -| Finding | id、native_rule_id、category、severity、message、location、evidence_refs、baseline_state | 保留原生严重度;不能由自然语言反推规则 | -| Coverage | expected、observed、unresolved、excluded_policy_digest、proof_kind | 数量相等不等于集合相等 | -| GateDecision | decision、eligible、blocking_finding_ids、incomplete_obligation_ids、policy_digest | 未完成不能 allow | -| RunReport | version、run_id、request、policy/content identity、results、gate、summary | human/json/sarif 派生自同一对象 | - -状态域:`completion=complete|incomplete|not_applicable`;`delivery_gate.decision=allow|deny|incomplete|not_applicable|not_evaluated`。内部故障另置 `run_status=internal_error`,交付决策保持 incomplete。 - -输出示意(**字段节选,不是可直接通过 schema 的完整样本**): - -```json -{ - "schema_version": "1.0", - "request": {"command": "check", "selection": "all"}, - "results": [ - { - "obligation_id": "java:app:lint:p3c", - "completion": "complete", - "findings": [{"id": "f-1", "native_rule_id": "native-rule-id", "severity": "error"}] - }, - { - "obligation_id": "maven:app:cve", - "completion": "incomplete", - "reason": "advisory_database_unavailable", - "findings": [] - } - ], - "delivery_gate": { - "decision": "incomplete", - "eligible": false, - "blocking_finding_ids": ["f-1"], - "incomplete_obligation_ids": ["maven:app:cve"] - }, - "exit_code": 3 -} -``` - -结构化 stdout 只能有一个 JSON 文档;进度、下载提示、工具输出写 stderr 或私有日志。`--output` 成功时将相同序列化报告原子写入目标文件,stdout 仍遵守所选格式;写入失败返回 3,保留已有结果。SARIF 转换保留 tool/rule/location,并用运行通知与 invocation 成功状态表达 incomplete,禁止导出零 findings 就隐去未完成;标准 JSON 始终是完整协议。 - -源位置使用仓库相对路径;文件名含非 UTF-8 字节时保留可逆编码标识和展示名,不用有损字符串进行身份比较。多位置、跨文件数据流或依赖发现允许 primary location 缺省,但必须存在包/模块定位。归并只对同工具或经过显式规则映射的等价发现进行,保留原始记录和次数;不同工具不能只按文案去重。 - -## 4. 核心类型、接口与依赖 - -建议技术栈为 clap、Tokio、serde/serde_json、thiserror;Git 初版使用受控 argv 调用已安装 Git 并校验字节协议。依赖版本与 MSRV 在建仓时实测固定到 Cargo.lock,不在设计文档引用浮动 latest 作为构建锁。 - -领域类型放 `codeguard-core/src/model/`,每个主要类型单文件;计划、门禁、策略为纯逻辑。核心协调器通过 ports 请求 I/O。接口设计示意: - -```text -Adapter.descriptor() -> CapabilityDescriptor -Adapter.discover(observations) -> ApplicabilityEvidence -Adapter.resolve(context, policy, toolchain) -> ResolvedCheck -Adapter.plan(resolved_check) -> AdapterPlan -Adapter.parse(raw_artifacts, termination) -> ParsedEvidence -Adapter.verify_coverage(plan, evidence) -> CoverageAssessment -Adapter.plan_fix(finding_set, context) -> FixPlan - -ExecutionPort.run(process_spec, cancellation) -> ToolExecution -SnapshotPort.capture(content_request) -> SnapshotLease -EvidenceStore.persist(raw_evidence) -> EvidenceRef -CachePort.lookup(validated_identity) -> VerifiedCacheEntry | Miss -``` - -这些是逻辑签名,不是待拷贝编译的 Rust stub。runtime 做观察和执行;适配器只能解释注入的数据、提出命令,不私下 `spawn`、联网或修改文件。core 根据计划协调任务,CLI 负责依赖注入。MCP 放在 cli 的入口模块,复用同一核心 API;不得通过调用自身命令拼另一套 verdict。 - -## 5. 工具适配器协议 - -每个适配器发布描述包含:adapter ID/version、语言及方言、检查类别、平台/运行时版本范围、所需配置、输入单位、报告格式版本、原生退出语义、缓存前提、修复能力、网络要求和资源锁。 - -稳定 ID 如 `java.p3c`、`java.checkstyle`、`java.javadoc`、`rust.clippy`、`python.ruff`、`typescript.eslint`。Node 工具可复用实现,但 Vue/Svelte/Astro/GraphQL 的 parser/plugin/context 必须分别验证,不能靠同一个 eslint 二进制宣布所有能力可用。 - -优先 JSON/XML/SARIF 等结构化报告。只提供文本的工具必须固定兼容版本、locale、语法及 golden fixtures;解析失败保留原文和未完成状态。禁止通用“包含 error 就失败”或“exit 1 就违规”的策略。比如 ESLint 的退出 1 与退出 2 表达不同类别结果,适配器必须按它的契约解释。[ESLint CLI](https://eslint.org/docs/latest/use/command-line-interface#exit-codes) - -有效 findings 与环境故障可能同时存在:保留已验证 findings,completion=incomplete。工具 exit 0 也必须核对报告、执行义务、被扫描对象与 freshness;有副作用的检查器不得把改写后的通过当作原始内容通过。 - -注册表只登记有证据的能力。`format` 存在但没有只读检查能力时,不能自动算作 lint;有原生 check/diff 模式时需证明无修改且报告可解释。无成熟注释检查器的语言可实现确定性 AST 规则,但需独立 capability/正反例验收;否则明确缺口。 - -## 6. Java 专项 - -Java 是第一条端到端实现线,不代表只支持 Java。适配计划必须区分以下义务: - -| 类别 | 工具/机制候选 | 验证要点 | -|---|---|---| -| 阿里规范 | 官方 P3C PMD 规则实现 | P3C/PMD/JDK 的兼容组合和实际规则加载 | -| 格式与通用规范 | Checkstyle;项目已有格式检查目标 | XML 结构、规则版本、源码级别、只读模式 | -| 注释规范 | Checkstyle Javadoc 规则、Javadoc/doclint | 公共 API 范围、参数返回、继承文档、Lombok/record/生成代码 | -| 安全静态分析 | 项目已接入并经验证的安全分析器,例如 SpotBugs 安全规则或规则扫描器 | 所需字节码、classpath、规则清单与报告完整性 | -| CVE | 经验证的 Maven 依赖扫描适配器 | 解析实际依赖图与版本,漏洞库身份和匹配证据 | -| 构建 | Maven/Gradle 的批准生命周期和目标 | 编译及必要质量任务是否真的执行;测试执行单独声明 | - -官方 P3C 包含 PMD 实现;本仓 Checkstyle XML 不应被重命名或包装成“官方 P3C 已通过”。具体兼容版本在真实样本矩阵中确定。[P3C 官方仓库](https://github.com/alibaba/p3c) - -Java 解析顺序:项目 wrapper 与声明运行时 → effective model/启用 profile → 模块图/源集/依赖 → 已绑定质量任务 → 缺失义务的受控适配计划。读取 effective model 可能执行构建扩展,因此不是纯静态 `plan` 的隐式行为,需进入执行阶段并留证据。 - -对于未配置质量工具的项目,使用已批准、已锁定的 rulepack 构造隔离执行配置;不改用户 POM/Gradle 文件。必要集成不能可靠构造时返回 `configuration_required`,提供具体补丁建议,不能自动永久加入或删去质量插件。`java.commands` 只能提供实际命令,仍需覆盖映射,不能以 `echo ok` 满足 P3C。 - -Maven 父子模块、dependencyManagement、profile、toolchains、annotation processor、测试源集和 Gradle 动态脚本都影响结论。静态模型不完整时保守扩大范围;扩大后仍不能证明规则执行,则未完成。已有 Java 影响闭包可迁移,但版本变动不得自动以 validate/help 替代未证明等价的 lint/CVE 义务。 - -## 7. CVE、注释、安全类别 - -CVE 的单位是依赖生态和解析后的组件图,不是源码后缀。Maven/Node/Python/Rust/Go 与通用扫描器按清单能力选择;原生缺失不得偷偷 fallback 成不同覆盖的通过。多个语言共享同一依赖图可以共享证据,但每份义务必须可追溯。 - -漏洞记录保留 CVE/GHSA/OSV 等原标识、别名、包坐标或 purl、版本、传递依赖路径、匹配方式、受影响区间、修复版本、严重度来源和漏洞库时间/摘要。只有模糊 CPE 匹配时,不伪装成精确包证据;待复核项仍可导致完整性不足,不静默丢弃。 - -缺 lockfile 不必一律失败:适配器若能解析并固化实际依赖图可继续,否则未完成。漏洞库过期、网络断开或数据库未验证不能产生安全 PASS;离线只使用满足批准 freshness 的本地库。未知严重度不能映射为 LOW 或删除:若策略无法比较则未完成;批准“所有已知漏洞阻断”时可直接判违规。 - -注释规则绑定语言语法及 API 范围。规则包应明确是否允许继承文档、接口/实现重复说明、生成代码排除和 test fixture 的专用规则;这些是预先确认的语义,不是扫描失败后的临时豁免。 - -安全分为源代码规则、配置/IaC、敏感内容及入库路径策略。`.env`/`*.pem` 等命中现行禁止入库模式时报告 `repository_policy_violation`,不得仅凭文件名宣称发现私钥;内容扫描的 secret finding 另有规则和脱敏证据。公共证书等例外需要正式策略变更,AI 不可自动放行。 - -## 8. 配置、规则包和工具链锁 - -保留 `codeguard.json` 作为项目入口,通过显式 schema migration 导入新协议。新增 `codeguard.lock.json` 绑定工具、适配器与规则摘要;不读取旧字段后静默丢弃。 - -| 配置平面 | 内容 | 覆盖规则 | -|---|---|---| -| 运行参数 | jobs、终端格式、日志位置、预算 | CLI > 环境变量 > 项目默认;不足只产生未完成 | -| 质量策略 | required、rulepack、severity、源集、批准排除、freshness、测试要求 | 可信组织策略及已批准项目修订;运行参数不可弱化 | -| 工具锁 | 工具版本/摘要、JDK、adapter、rulepack、下载来源 | 按 lock 验证;不使用 latest 自动升级 | -| 项目原生配置 | eslint/ruff/checkstyle 等 | 作为实际规则输入;必须与批准策略要求对齐 | - -`config explain` 显示每一有效值的来源与覆盖原因。原生配置中已有 disable/suppressions 必须列入策略解释和数量/摘要审计;不能把原生配置当作不可审查的隐藏降级入口。PR 同时修改代码与检查配置时,CI 使用可信基线策略评估政策差异;未经批准的新策略不能给本 PR 自行签发通过。 - -规则包目录设计: - -```text -rulepacks/// - manifest.json - rules.json - tool-configs/ - compatibility.json - fixtures/ -``` - -manifest 记录来源、许可、分类、规则严重度、工具兼容约束、内容摘要和变更说明。每个 native rule ID 映射稳定的 Codeguard rule ID;删除、改义或改变默认阻断级别属于可审查规则迁移,不靠扫描时随机选择。 - -默认选择“已存在且匹配锁的项目工具 → 已验证的受管缓存 → 匹配锁的系统工具”;版本不匹配即未完成。安装需要独立 `tools install`,提供下载清单、校验和与安装范围;扫描期间不能用 npx/pip/curl 偷偷安装。可能下载依赖的构建命令须在计划中说明网络模式与锁约束,`--offline` 不得联网;在线模式也不得自动升级规则或工具。 - -`--offline` 是执行约束,不能只转发工具的 offline flag。adapter 声明可验证的离线条件,运行时使用经平台验证的网络禁止环境执行可能联网的 wrapper/扩展;无法保证时在启动前返回 `offline_isolation_unavailable`,不声称已离线。安装沙箱或容器工具仍是独立准备动作,扫描不得隐式安装。验收必须包含会主动联网的真实子进程。 - -## 9. 执行器与资源控制 - -`ProcessSpec` 包含 executable、argv、cwd、受控 env overlay、stdin 模式、deadline、输出预算、资源键、网络策略声明和预期产物。默认 stdin=null;pre-push 输入先由 CLI 读取为结构化请求,不把宿主 stdin 交给扫描器。 - -Tokio 并发读取 stdout/stderr,有界缓冲加私有文件记录;超限必须标识不完整。取消或超时先请求停止,再终止进程组/Windows Job Object 并 wait/reap;只丢弃 Child 不等于可靠结束进程。[Tokio process 文档](https://docs.rs/tokio/latest/tokio/process/) - -任务 DAG 中相互独立的检查继续收集证据;同一模块构建目录、数据库更新或非并发扫描器通过 resource key 互斥。deadline 是整次请求预算,包含排队/探测/执行/解析/清理;子进程不能各自重置全部预算。 - -检查计划只读源码:准确内容物化到隔离目录,生成产物写独立区域;执行前后检查源码身份,意外变更导致未完成。禁止跟随路径逃逸 symlink;Git symlink/gitlink/LFS 对象按类型记录,无法获得所需真实源码时不当作普通文件通过。日志私有、原子写,证据索引保留摘要与保留期限;MCP/终端不默认输出密钥或原始环境。 - -受保护 CI 的可信协调/验证进程、策略、工具锁和最终状态凭据与被测脚本执行域隔离,采用只读挂载、独立身份或等效平台机制,不把签发凭据传入构建进程。执行区仅可写临时构建输出及待核验产物;可信端重新校验内容、报告来源、执行范围和规则覆盖后生成最终结果。单纯不同目录不能满足这个保证;不具备隔离能力时报告能力限制,不宣传抗任意脚本篡改。该要求不会将普通本地模式虚构成安全沙箱。 - -重试只限可识别的瞬时 I/O 故障,固定次数并保留全部尝试;不重试真实违规以期待随机变绿,不在重试中换规则、目录或工具版本。工具内部编程错误不无限重试。 - -## 10. 内容快照、缓存及增量证明 - -| 入口 | 权威内容 | -|---|---| -| 显式 check | 本次请求冻结的工作树清单和内容,检查后复核身份 | -| Git pre-commit | Git 实际传入环境下的 index,尊重 GIT_INDEX_FILE,包括部分提交 | -| Git pre-push | stdin 各 local ref/OID 与 remote ref/OID,支持多 ref、删除 ref、非 HEAD ref | -| CI | 调用方明示且解析为不可变 OID 的待交付内容;合并结果与分支头不能混用 | -| 宿主 PreToolUse | 有边界的预测内容;不声称等价于完整 Shell 执行 | - -Git 原始路径使用 NUL 协议,校验对象数量、类型、长度、模式和哈希;SHA-1/SHA-256 按仓库对象格式处理。index 冲突、多仓、初始提交、worktree、submodule、删除/重命名以及输入并发变化均有 fixtures。预测失败阻止认证并提示真实 Git 接入或拆分动作,不扫描另一个仓库充数。 - -缓存键至少包含:协议/adapter 版本、工具二进制与运行时、规则包、有效配置、目标内容与完整依赖输入集合、模块图、content_source、任务参数、平台、locale、CVE 库身份和 freshness。字节相同但 source kind/授权上下文不同也不得直接复用交付收据。 - -只缓存完整可验证结果,PASS 和真实违规都可缓存;incomplete/取消/内部故障不提供完成证据。完整缓存记录包含报告摘要和覆盖证明;缓存损坏视为 miss。交付入口不得消费软反馈缓存,可复用满足相同严格身份和可信来源的检查结果,再独立重算交付 gate。本地可写缓存不能作为受保护 CI 的可信外部证据。 - -增量算法先生成全量义务,再为每项选择执行或复用。无依赖隔离证明的 AST/类型/构建检查扩大到模块或项目;改变规则、编译选项、锁文件或父配置使相关闭包失效。不能以“文件未变”证明依赖它的检查结果未变。 - -## 11. 修复协议 - -```mermaid -sequenceDiagram - participant U as 调用方 - participant C as Codeguard - participant F as 原生修复器 - U->>C: fix --dry-run - C-->>U: 精确目标 / 内容身份 / 补丁或计划 / 副作用说明 - U->>C: fix --apply,既有修复授权 - C->>C: 核对目标身份与授权范围 - C->>F: 在隔离副本执行支持的修复 - F-->>C: 退出状态及变化 - C->>C: 校验范围,安全应用,再按相同策略复检 - C-->>U: 执行成功 / 实际变化 / 复检结果分别报告 -``` - -`fixed=true` 需要证明目标变化与该修复有关并完成复检;formatter exit 0 不够。应用 patch 前比较前置内容哈希;并发编辑时停止应用,不能覆盖用户修改。失败有部分变化时保留补丁及真实状态;只回滚自己可证明拥有且未被后续改动的部分。 - -不自动修改 lint 配置、阈值、忽略、测试或基线来修复 finding;CVE 升级引入行为变化时将依赖变更作为独立修复计划,完整复扫和受影响验证后才声明解决。 - -## 12. 插件、MCP 与分发 - -插件 lock 绑定 CLI version、target triple、artifact digest、协议 major、rulepack lock;安装时和运行前验证绑定。原生二进制是统一入口,但 Java/Node/Python 等扫描工具仍需要各自运行时,`doctor` 必须说明。 - -初始发布候选目标:macOS arm64/x86_64、Linux x86_64/aarch64、Windows x86_64;Linux libc/最低系统版本和每工具平台能力在 S10 实测固化。未验证组合不标稳定。下载原子落盘后切换;校验失败不得使用随机 PATH 版本或静默回退 Python,报告未完成。 - -MCP 工具参数映射到相同 CheckRequest,保留旧工具名时通过显式协议适配。宿主 Hook exit=2 可能表示阻断,而新 CLI exit=2 是用法错误,必须按报告语义映射,不透传数字。取消、超时、二进制不可用也要有宿主特定测试。 - -旧通道 `compat legacy-v1` 保持各旧子命令自己的退出协议:常见 check/CVE 为通过0、未验证1、违规2、用法3;混合优先级按旧入口原约定,不把 Dockerfile/CVE/check 的历史差异硬套成一张表。新报告与旧字段同时出现时以明确 protocol 标签解释,保留所有发现。兼容通道不能被新交付 CI 当作等价认证。 - -切换流程:协议与适配器测试 → 真实仓对照 → 显式指定新二进制 → 宿主/CI 按语义接入 → 全语言与平台验收 → 旧入口弃用。回滚只能回到满足相同严格契约的已验证 Rust 版本;若只能运行旧 fail-open 通道,则交付状态保持未认证,不能为恢复可用性伪造通过。 - -## 13. 可观测性与度量 - -每次 run/obligation/task/attempt 使用关联 ID,记录工具耗时、启动/解析/快照耗时、扫描范围、缓存原因、原始退出和未完成原因。日志默认本地,不收集源码遥测;如需远程统计需单独明确采集内容。 - -低误报评价至少同时展示:finding precision、漏报率、工具故障误判率、必需义务完成率、被排除/豁免比例、各类别覆盖、p50/p95 耗时及样本数。把规则关闭后 precision 变高视为覆盖退化。指标定义和真实验收见 [coverage-and-acceptance](coverage-and-acceptance.zh-CN.md)。 - -本技术方案没有声称已达到某个误报率或性能增益;这些必须由任务中的固定语料、人工裁定与真实工具运行证明。 diff --git a/openspec/changes/introduce-rust-codeguard-cli/.openspec.yaml b/openspec/changes/introduce-rust-codeguard-cli/.openspec.yaml deleted file mode 100644 index 74e9ae7..0000000 --- a/openspec/changes/introduce-rust-codeguard-cli/.openspec.yaml +++ /dev/null @@ -1,3 +0,0 @@ -schema: spec-driven -created: 2026-09-24 -goal: 通过统一 Rust CLI 恢复全语言传统静态工具质量守卫,降低误报且禁止自动降级门禁 diff --git a/openspec/changes/introduce-rust-codeguard-cli/design.md b/openspec/changes/introduce-rust-codeguard-cli/design.md deleted file mode 100644 index 02a2df0..0000000 --- a/openspec/changes/introduce-rust-codeguard-cli/design.md +++ /dev/null @@ -1,69 +0,0 @@ -# Design:统一 Rust Codeguard CLI - -## Context - -动机见 [proposal](proposal.md)。当前运行时是 Bash/Python、57 个语言注册条目、独立技能 vendor 与多宿主 Hook。源码基线 `03ebb24`;现有 OpenSpec 仍描述旧 fail-open、skipGate、基线豁免与旧退出码。本 change 是显式契约升级,不是对旧策略做行为保持的逐行翻译。 - -完整设计见 [架构文档](../../../docs/rust-cli/architecture.zh-CN.md)、[技术方案](../../../docs/rust-cli/technical-design.zh-CN.md);覆盖和指标见 [迁移验收](../../../docs/rust-cli/coverage-and-acceptance.zh-CN.md)。这些文档展开设计,本目录 `specs/` 是规范性事实源,`tasks.md` 是唯一任务状态。 - -## Goals / Non-Goals - -**Goals**:单一二进制与领域内核;独立的执行完整性和违规证据;不可由 AI 自行降级的质量 contract;全语言逐类别覆盖;可测试的工具适配与准确内容身份;渐进替换宿主入口。 - -**Non-Goals**:本次文档交付不建立 Rust 源码仓或发布产物;不重写所有原生分析工具;不采用 LLM 作为最终裁判;不承诺本地同权限环境不可绕过;不把动态 Shell 全解析作为交付正确性的基础。 - -## Decisions - -| 决策 | 选择及理由 | 考虑过的替代 | -|---|---|---| -| D01 workspace | 使用用户确定的四 crate,core 定义 ports,runtime/adapters 单向依赖 core | 单 crate 易混职责;每工具独立 crate 初期增加发布成本 | -| D02 执行权威 | Rust 统一编排,工具提供 finding,受控策略决定 gate | AI 重判缺可复现证据;通用 rc/文本判定丢语义 | -| D03 结果模型 | findings 与 completion 正交,混合结果全部保留 | 单 PASS/FAIL/UNKNOWN 枚举容易吞掉部分真实发现 | -| D04 完整性门禁 | 必需检查未完成不能交付;基线只分类 | fail-open/默认存量豁免延续用户明确否定的方向 | -| D05 覆盖 | 先建立完整义务,再选择执行/缓存;语言 × 类别 × 工具验收 | 按文件后缀或已注册命令计数无法证明能力 | -| D06 工具管理 | 显式 provision、固定锁、兼容组合测试 | 扫描时自动安装 latest 导致不可复现与运行副作用 | -| D07 配置权威 | 运行参数与质量策略分离;CI 使用可信已批准政策 | CLI/env 覆盖一切使智能体可自行关闭门禁 | -| D08 Git | 真正 Git 事件绑定 index/ref;宿主预测有明确边界 | 继续扩充 Shell 模拟仍不能覆盖任意程序间接调用 | -| D09 发布兼容 | 新协议明确版本,旧入口具名兼容且不作为新认证 | 同一个 rc 静默改义会破坏 CI/宿主 | -| D10 初版扩展 | 编译期适配器,版本化数据规则包 | 动态任意脚本插件会扩大信任和测试边界 | -| D11 测试执行 | 保留静态构建默认等级并明确报告,策略要求时执行测试 | 自动替用户将所有 verify 改为跑测试,超出已确认范围 | -| D12 修复工作区 | `./codeguard/` 持久存储脱敏问题、事件与任务,本地日志/缓存 Git 忽略,原工具复检关闭 | 仅终端报错缺少恢复上下文;自由 Markdown 勾选会制造无证据完成 | - -修复工作区详见 [持久修复设计](../../../docs/rust-cli/remediation-workflow.zh-CN.md)。状态、任务和历史帮助执行者推进,但最终 gate 独立检查源码与可信政策;任务记录不能成为新的跳过开关。 - -## Risks / Trade-offs - -- [严格门禁暴露工具环境欠账] → `doctor` 给出具体恢复路径,先完成工具链准备;不能通过 fail-open 消除欠账。 -- [官方 P3C、PMD、JDK 版本兼容] → 固定组合并运行真实样本;不把同名 Checkstyle 配置视为替代。 -- [跨语言 comments/security 能力差异] → 缺口显式记录;可新增确定性规则,不能把缺能力标成不适用。 -- [构建脚本和原生配置可执行/可降级] → 隔离运行、身份核对、可信策略 diff;快照不等于恶意代码沙箱。 -- [全量检查较慢] → 基于等价证明缓存和增量,不改变义务;性能预算以实测设定。 -- [同一 change 涉及未来多个仓] → 当前规格暂驻插件仓;未来 CLI 仓引用此事实源,迁移事实源须独立批准,禁止双写冲突任务。 -- [已有规格很多旧行为要求] → 在 delta 中给旧运行时明确协议范围;迁移后入口受 Rust 契约管辖,并更新宿主协议说明。 - -## Migration Plan - -```mermaid -flowchart LR - S1[契约和语料 S01-S02] --> S2[运行时与治理 S03-S05] - S2 --> S3[Java及首批工具 S06-S07] - S3 --> S4[全语言补齐 S08] - S3 --> S5[修复与宿主 S10-S11] - S2 --> SW[持久修复工作区 S09] - S4 --> S6[真实验收 S12] - S5 --> S6 - SW --> S6 - S6 --> S7[发布与规格同步 S13] -``` - -对照运行保留旧/新报告与差异原因,不直接将旧结论作为真值。已确认的历史错误行为需要新规范的正反例替代旧期望,其它兼容性用具名 legacy 测试保留。切换后不因 Rust 未完成自动回落旧 Python 放行。 - -回滚以满足相同严格契约的上一 Rust release 为目标;没有这种版本时保持交付未认证,反馈入口可恢复旧工具但不得显示新门禁通过。市场、安装和真实运行证据分层记录。 - -## Open Questions - -以下是实施阶段必须验证的技术参数,不改变上述需求与任务范围:P3C/PMD/JDK 兼容版本;各罕见语言可用的只读诊断工具;平台最低 ABI/MSRV;签名发布身份和新仓远程地址;代表性语料的确切项目清单及脱敏方式;逐工具性能基线。对应任务未完成前,不将候选参数写成发布承诺。 - -## Completion Boundary - -本次完成标准仅为架构、技术方案、覆盖验收设计、OpenSpec proposal/design/specs/tasks 的一致性和校验。所有代码、真实工具、宿主、发布任务保持未完成;不执行 apply/sync/archive。 diff --git a/openspec/changes/introduce-rust-codeguard-cli/proposal.md b/openspec/changes/introduce-rust-codeguard-cli/proposal.md deleted file mode 100644 index 9ee477c..0000000 --- a/openspec/changes/introduce-rust-codeguard-cli/proposal.md +++ /dev/null @@ -1,43 +0,0 @@ -# Proposal:统一 Rust Codeguard CLI - -## Why - -Codeguard 的目标是调用传统静态工具,完成多语言代码规范、注释规范、依赖漏洞、安全和构建质量检查。当前实现把工具故障、基线豁免和宿主放行混在交付路径中,智能体容易通过降低检查要求消除报错;需要统一执行与证据契约,恢复“准确检查、完整交付”的产品边界。 - -## What Changes - -- 建立独立 Rust workspace `codeguard-cli/`,四个 crate 分别负责入口、领域契约、执行基础设施、工具适配;发布可执行文件 `codeguard`。 -- 提供 `lint/comments/cve/security/build/check `,CLI、MCP、Git 与宿主入口复用同一检查内核。 -- **BREAKING**:新 CLI 协议采用 0 通过、1 违规、2 用法错误、3 未完成、4 内部故障、130 取消;旧协议通过显式兼容入口保留,禁止根据数字猜测状态。 -- **BREAKING**:迁移后的交付门禁要求必需检查全部完成;工具故障不认定为代码违规,也不再允许被当作交付通过。 -- **BREAKING**:新流程不接受智能体自行设置 skipGate、降低阈值、增加 suppression 或使用存量基线豁免;基线仅分类问题。 -- 用版本化 rulepack、工具链锁、结构化报告、检查覆盖账本和真实样本评测降低误报;保留全部真实发现与不确定性。 -- 在项目内初始化 `./codeguard/`,将脱敏问题、环境阻塞、修复任务和复检事件持久化;原始报告与缓存由目录内 .gitignore 忽略,通过 next/task verify 指导智能体闭环修复。 -- 迁移当前注册表全部 57 个条目,逐项验收 54 个 stable 的实际能力,保留 3 个 planned 的真实状态;禁止用少数语言演示代替全量迁移。 -- 保留项目既有点前缀忽略及入库安全、配置发现例外;各检查类别明确适用条件和能力缺口。 - -## Capabilities - -### New Capabilities - -- `unified-cli-contract`:统一命令、选择范围、版本化报告、CLI/MCP 协议。 -- `native-tool-adapters`:工具适配、类别覆盖、Java 原生工具链和全语言迁移。 -- `rulepack-governance`:规则版本、可信策略、禁止自动弱化、例外和基线治理。 -- `binary-distribution`:二进制与插件版本绑定、兼容迁移、发布验收。 -- `remediation-workflow`:持久问题和待办、修复简报、任务租约、真实复检关闭与重开。 - -### Modified Capabilities - -- `verdict-integrity`:新增 Rust 双维结果和完整性交付门禁;明确旧入口的协议边界。 -- `execution-kernel`:新增 Rust crate 边界、进程生命周期、准确缓存与快照约束;显式隔离旧实现兼容要求。 -- `language-gate-commands`:区分旧流程与新 CLI 的前置条件、范围及工具故障语义。 -- `hook-protocol`:限定旧 fail-open/skipGate 契约,规定迁移后交付入口的阻断和宿主映射。 -- `scan-scope-policy`:为受管 Codeguard 产物添加精确自扫描边界,用户源码和入库安全不受影响。 - -## Impact - -未来代码归属:`codeguard-cli` 持有 Rust 内核、适配器、规则和协议;本插件持有宿主入口、运行时版本绑定;`codeguard-skills` 持有技能事实源。现有 `skills.lock.json` 管理边界不变。 - -当前交付仅为设计及执行任务,不建立 Rust 源码仓、不修改 Python 运行行为、不升级安装、不发布。正式规格以本 change 的 `specs/` 为准;实现完成前不 sync/archive。旧 OpenSpec change 的宿主副本治理另行保留,不并入或伪称已完成。 - -相关说明:[架构文档](../../../docs/rust-cli/architecture.zh-CN.md)、[技术方案](../../../docs/rust-cli/technical-design.zh-CN.md)、[语言迁移与验收](../../../docs/rust-cli/coverage-and-acceptance.zh-CN.md)。 diff --git a/openspec/changes/introduce-rust-codeguard-cli/specs/binary-distribution/spec.md b/openspec/changes/introduce-rust-codeguard-cli/specs/binary-distribution/spec.md deleted file mode 100644 index b41bd89..0000000 --- a/openspec/changes/introduce-rust-codeguard-cli/specs/binary-distribution/spec.md +++ /dev/null @@ -1,33 +0,0 @@ -## Purpose - -定义统一 Rust 二进制与宿主插件的制品绑定、兼容入口、迁移和发布证据,使源码、发布版本、实际安装和运行能力能够分别验证,避免未验证回退产生假通过。 - -## ADDED Requirements - -### Requirement: Plugin execution SHALL bind a verified runtime artifact - -插件 MUST 绑定 CLI 版本、平台、制品摘要及协议版本;不匹配或不可用时 MUST 报未完成,不得随机使用 PATH 版本或自动回退旧 Python 产生通过。doctor MUST 明示原生扫描器的 JDK/Node/Python 等外部依赖。 - -#### Scenario: Runtime checksum is invalid -- **WHEN** 安装二进制摘要不符合插件锁 -- **THEN** 拒绝将其作为可信检查器,交付未完成 - -### Requirement: Compatibility SHALL be explicit and versioned - -旧 CLI/MCP/Hook 兼容 MUST 具名并按旧入口分别映射协议;禁止透传新退出码或隐式改变旧语义。新交付门禁 MUST 不接受 legacy-v1 的 fail-open 结果作为新认证。兼容移除 MUST 有发布迁移说明。 - -#### Scenario: Legacy caller expects findings to exit two -- **WHEN** 旧调用经 legacy-v1 接入 -- **THEN** 使用该旧入口的退出约定,同时不声称已满足新门禁 - -### Requirement: Release claims SHALL require layered evidence - -stable 发布 MUST 分别提供真实工具、平台、Git/CI、宿主安装与运行验收;不以编译、mock 测试、tag 或市场清单替代。全语言完成声明 MUST 满足语言迁移要求。回滚 MUST 不降低已确认的交付契约。 - -#### Scenario: Release artifact exists but host cannot run it -- **WHEN** GitHub release 有二进制但某宿主无法启动 -- **THEN** 该宿主验收保持未完成,不宣称已交付 - -#### Scenario: Only a legacy fail-open rollback is available -- **WHEN** 新运行时故障且没有符合新契约的旧 Rust 版本 -- **THEN** 交付保持未认证,不能以旧放行行为恢复绿色门禁 diff --git a/openspec/changes/introduce-rust-codeguard-cli/specs/execution-kernel/spec.md b/openspec/changes/introduce-rust-codeguard-cli/specs/execution-kernel/spec.md deleted file mode 100644 index a24571d..0000000 --- a/openspec/changes/introduce-rust-codeguard-cli/specs/execution-kernel/spec.md +++ /dev/null @@ -1,69 +0,0 @@ -## MODIFIED Requirements - -### Requirement: Existing entry points SHALL remain compatible - -显式 legacy-v1 兼容入口 MUST 保留原 CLI 子命令、四个 MCP 工具、五类 Hook 路径/JSON/退出约定及旧 Python 导入接口,除非另有弃用发布。用户配置 MUST 经显式转换,语言注册与外部受管技能所有权不变。 - -本规范中原有 Python 模块路径、顺序遇错终止、软缓存不供硬门禁、基线豁免、Java 轻量版本检查、fail-open 和旧退出码要求 MUST 限于 legacy-v1。Rust 新入口 MUST 遵守本 change 的统一义务、缓存证明、基线仅分类、独立任务继续及严格交付契约。其余原始证据、字节校验、内容身份、隐私与不修改用户 index 等正确性要求 MUST 延续。执行内核不得导入宿主 SDK。 - -#### Scenario: Legacy script invocation -- **WHEN** 旧 manifest 从原路径执行兼容脚本 -- **THEN** 使用显式旧协议,不静默改写数字语义,也不能签发新交付认证 - -#### Scenario: Rust execution encounters an independent failed task -- **WHEN** 一个任务失败且其它任务不依赖它 -- **THEN** 仍收集其它任务证据,失败依赖项保留未完成,不继承旧顺序短路作为全批通过依据 - -## ADDED Requirements - -### Requirement: Rust execution SHALL bound and close process lifecycles - -执行 MUST 使用字面 argv、明确 cwd/env/stdin、总预算及有界输出,记录真实终止原因。超时/取消/超限 MUST 停止并回收受控进程树,保留部分证据;同一构建目录的冲突任务 MUST 互斥。工具规则解释 MUST 不属于通用进程执行层。 - -#### Scenario: Child process outlives its parent -- **WHEN** 工具创建子孙进程后发生取消 -- **THEN** 在声明的平台保证内终止并回收整棵受控进程树,不能仅丢弃句柄 - -### Requirement: Rust snapshots SHALL bind the actual delivery input - -真实 pre-commit MUST 尊重 GIT_INDEX_FILE;pre-push MUST 读取每条 ref/OID 元组,不能假定 HEAD;CI MUST 绑定明确不可变内容。字节完整性、类型、哈希、路径和执行前后身份 MUST 校验。快照失败或源内容被检查器修改 MUST 未完成,不改真实 index;宿主预测 MUST 不冒充完整 Shell 语义。 - -#### Scenario: Push targets a non HEAD ref -- **WHEN** 用户推送的 local OID 与当前 HEAD 不同 -- **THEN** 检查实际 local OID 及指定推送范围,不能用 HEAD 通过替代 - -#### Scenario: Partial commit uses an alternate index -- **WHEN** Git hook 环境含 GIT_INDEX_FILE -- **THEN** 检查该 index,保留真实工作树及 index 内容 - -### Requirement: Rust cache reuse SHALL prove obligation equivalence - -缓存 MUST 绑定内容、依赖闭包、工具/运行时、adapter、规则、配置、平台、来源和 CVE 库身份/时效。只有完整有效结果可复用;硬门禁不得直接消费软反馈缓存,必须核验严格身份和可信来源并重算 gate。缺少依赖隔离证明 MUST 扩大扫描或未完成。 - -#### Scenario: Configuration changes with identical size and time -- **WHEN** 配置等长替换且 mtime 未变 -- **THEN** 缓存不命中,不能按元数据复用旧 PASS - -### Requirement: Rust fixes SHALL preserve ownership and verify outcomes - -fix MUST 区分 dry-run 与 apply,检查目标身份及范围;应用前置条件不符 MUST 不覆盖用户编辑。执行成功、观察到变化、复检确认修复 MUST 分开报告。修复 MUST NOT 自动降低规则、阈值、忽略或修改测试期待以消除违规。 - -#### Scenario: User edits during fix planning -- **WHEN** 修复计划生成后原文件发生变化 -- **THEN** 不覆盖用户内容,重新规划或报告未完成 - -#### Scenario: Formatter succeeds without changes -- **WHEN** 原生 formatter exit 0 且内容未变 -- **THEN** 只声明执行成功,不声称 fixed=true - -### Requirement: Offline and trusted CI execution SHALL enforce their declared boundaries - -离线执行 MUST 在可验证的不联网条件下运行,包括被调工具的子进程;无法提供条件时 MUST 在执行前报告未完成。可信 CI 的策略、工具锁、验证器和状态签发凭据 MUST 与被测脚本执行区隔离;项目产物 MUST 经可信端核验,不得让项目脚本直接签发或篡改认证。普通快照目录 MUST NOT 被宣传为满足该隔离。 - -#### Scenario: Wrapper attempts network access in offline mode -- **WHEN** 被调 wrapper 主动发起网络访问 -- **THEN** 声明支持的离线环境阻止访问;无法保证的平台拒绝开始并报告能力不足 - -#### Scenario: Project script tries to rewrite policy or receipts -- **WHEN** 被测项目脚本尝试改写可信策略、工具或最终状态 -- **THEN** 受保护执行边界拒绝写入,脚本生成的收据不能直接作为 gate 认证 diff --git a/openspec/changes/introduce-rust-codeguard-cli/specs/hook-protocol/spec.md b/openspec/changes/introduce-rust-codeguard-cli/specs/hook-protocol/spec.md deleted file mode 100644 index c17f8e0..0000000 --- a/openspec/changes/introduce-rust-codeguard-cli/specs/hook-protocol/spec.md +++ /dev/null @@ -1,71 +0,0 @@ -## MODIFIED Requirements - -### Requirement: The cheat-sheet SHALL document fail-open for uncaught exceptions - -`hooks/__protocol__.md` MUST 按运行时和事件区分:legacy-v1 未捕获异常保留 stderr 诊断和 exit 0 的旧兼容行为;普通保存/提示反馈不承担交付阻断。迁移到 Rust 严格交付模式的 Git/CI/PreToolUse 入口遇到内部故障 MUST 依宿主协议阻断并说明未完成,不能 fail-open。宿主不支持可靠阻断时 MUST 明示能力边界并依赖真实 Git/CI,不得声称该宿主已提供硬门禁。 - -#### Scenario: A hook hits an unexpected exception -- **WHEN** 显式旧兼容 Hook 顶层异常 -- **THEN** 记录诊断并按旧 exit 0,不能称为新认证成功 - -#### Scenario: A migrated delivery hook hits an unexpected exception -- **WHEN** 严格交付入口内部失败 -- **THEN** 按宿主阻断协议拒绝交付并报告未完成 - -### Requirement: Soft and hard gates SHALL share the skipGate escape and neither may fall back to scanning outside a git repository - -共享 `codeguard.skipGate` 的豁免 MUST 仅存在于 legacy-v1,维持旧计数和 Stop 汇总。Rust 交付 MUST 不接受此字段作为授权,例外遵循 rulepack-governance。非 Git 目录的 Git 事件 MUST 不回退扫描整个 workspace;普通显式 CLI 项目扫描不受该 Git 前提限制。 - -#### Scenario: SkipGate set, user asks to commit -- **WHEN** legacy-v1 设置了 skipGate 且消息触发提交意图 -- **THEN** 按旧约定退出和记账,并标明不提供新认证 - -#### Scenario: SkipGate set with a secret on the commit face -- **WHEN** 仓库已设 skipGate 且用户消息触发提交意图,待提交面含敏感模式文件 -- **THEN** 软门禁注入入库安全报告(非阻断);硬门禁在同一提交面 exit 2 - -#### Scenario: Rust agent sets skipGate -- **WHEN** 新交付入口发现同名 Git config 或链式设置 -- **THEN** 不作为质量豁免,仍按完整 contract 检查 - -#### Scenario: Prompt fires outside any git repository -- **WHEN** Git 提交提示发生于非 Git cwd -- **THEN** 说明没有目标仓,不扫描整个 workspace,也不称交付已通过 - -### Requirement: Fail-open uncertainty SHALL be visible - -legacy-v1 的 PreToolUse 放行工具故障 MUST 继续通过 additionalContext 明示未验证。Rust 交付入口 MUST 根据报告的 gate decision 映射宿主动作,必需 incomplete 与 deny 均阻断;普通 UserPromptSubmit/PostToolUse 反馈 MUST 保持可见未完成,不得宣称 all passed 或承担未实现的阻断。新 CLI exit 2 是用法错误,MUST NOT 直接当作所有宿主的阻断语义透传。 - -#### Scenario: A tool cannot run at the Git gate -- **WHEN** 旧入口缺工具 -- **THEN** 按旧协议 exit 0 且明确未验证 - -#### Scenario: Tool cannot run at a migrated gate -- **WHEN** 新严格入口缺必需工具 -- **THEN** 映射为宿主阻断,说明恢复工具链所需动作,不假称代码有错 - -### Requirement: Skip-gate bypass values SHALL be parsed strictly - -legacy-v1 的 `CODEGUARD_SKIP_GATE` MUST 只认 1/true/yes(大小写不敏感);0/false/空串不豁免,提示词保持原值域与传递边界说明。Rust 新流程 MUST 不将任何该变量值解释为授权,不能仅因保留旧环境变量而失去严格门禁。 - -#### Scenario: Zero and false values do not bypass -- **WHEN** 旧入口变量为 0 或 false -- **THEN** 旧门禁照常检查 - -#### Scenario: Accepted values bypass consistently -- **WHEN** 显式旧入口变量为 1/true/yes -- **THEN** 按旧协议豁免并审计,不签发新认证 - -#### Scenario: Rust receives an accepted legacy value -- **WHEN** 新入口继承 CODEGUARD_SKIP_GATE=true -- **THEN** 仍执行完整门禁,不把变量存在当批准 - -## ADDED Requirements - -### Requirement: Migrated host surfaces SHALL share the same report semantics - -CLI、MCP、宿主 Hook、真实 Git Hook 与 CI 对相同请求和证据 MUST 得到相同核心结果;差异仅为入口展示和协议映射。绑定二进制/协议失败 MUST 未完成;核心报告 MUST 不由宿主或智能体重写。迁移 MUST 为三宿主提供真实调用证据。 - -#### Scenario: Mixed findings and incomplete evidence reach three hosts -- **WHEN** 同一标准报告包含违规及未完成项 -- **THEN** 各宿主均保留二者,严格交付入口阻断,保存反馈不冒充交付通过 diff --git a/openspec/changes/introduce-rust-codeguard-cli/specs/language-gate-commands/spec.md b/openspec/changes/introduce-rust-codeguard-cli/specs/language-gate-commands/spec.md deleted file mode 100644 index 59ff705..0000000 --- a/openspec/changes/introduce-rust-codeguard-cli/specs/language-gate-commands/spec.md +++ /dev/null @@ -1,71 +0,0 @@ -## MODIFIED Requirements - -### Requirement: Languages may declare a configuration prerequisite - -注册表 MUST 允许声明配置前置条件,避免采用不适合项目的默认规则。legacy-v1 缺配置时维持未接入/未验证且旧 Hook 放行语义。Rust 新入口 MUST 使用已批准 rulepack 或已接入的项目配置;如果不能可靠满足前置条件,必需义务为 incomplete,不能通过“未接入”自动免除。 - -#### Scenario: 已声明前置条件且项目未接入 -- **WHEN** legacy-v1 项目缺少声明配置 -- **THEN** 按旧协议说明未验证并兼容放行,不签发新认证 - -#### Scenario: Rust required configuration is missing -- **WHEN** 新入口没有项目配置且无法使用批准规则包建立可靠计划 -- **THEN** 返回 configuration_required 和未完成,不报代码违规、不满足交付门禁 - -#### Scenario: 已声明前置条件且项目已接入 -- **WHEN** 原生配置存在且满足批准策略 -- **THEN** 按有效配置执行,保留配置来源和覆盖证据 - -#### Scenario: 未声明前置条件的语言不受影响 -- **WHEN** 工具契约不要求额外配置 -- **THEN** 正常按已批准规则和工具锁执行,不凭空新增项目配置障碍 - -### Requirement: Gates in git repositories SHALL default to changed-file scope - -本条标题描述 legacy-v1:旧门禁 MUST 保留 delta 默认、gate_scope=repo、FULL_SCAN_EXCLUDES、index/预测暂存/HEAD 的历史输入规则与完整诊断;准确快照不复用旧软缓存。Rust 新门禁 MUST 建立全部适用必需义务,增量仅作为等价执行优化,不能默认豁免未修改文件中的问题。新真实 Git 入口 MUST 使用 execution-kernel 的实际 index/ref 契约。 - -#### Scenario: A committed legacy issue is untouched by a clean change -- **WHEN** legacy-v1 改动仅文档且项目检查确实不适用 -- **THEN** 明示无须执行,不伪称完成项目验证 - -#### Scenario: A new staged file introduces a problem -- **WHEN** index 内容违规但工作树已修好 -- **THEN** 检出 index 违规,不借用工作树通过 - -#### Scenario: A bad commit made outside the gate must not slip through the push -- **WHEN** 实际待推送内容违规但工作树已修好 -- **THEN** 检查待推送内容并保留违规 - -#### Scenario: Push with no resolvable upstream does not crash -- **WHEN** 旧入口没有可解析上游 -- **THEN** 保留 HEAD 全树回退,不因空基线跳过 - -#### Scenario: A chained commit-and-push takes the wider face -- **WHEN** 宿主可可靠建模同仓 commit→push -- **THEN** 覆盖拟提交内容和已有待推送内容;不可建模时明示未完成 - -#### Scenario: Rust optimization leaves an obligation unproven -- **WHEN** 增量计划没有执行某必需任务且无等价缓存证明 -- **THEN** 不能据 delta 干净签发交付 allow - -### Requirement: A toolchain crash SHALL be recorded as unverified, not as a lint failure - -检查器退出码 MUST 结合工具契约判定,工具故障 MUST 不认作代码违规。legacy-v1 保留 UNVERIFIED、CLI 1、Hook 可见放行。Rust MUST 将该义务标 incomplete、CLI 3,必需检查不满足交付;混合有效发现仍保留。不能统一把所有工具 exit 2 当配置错误,也不能把所有 exit 1 当违规。 - -#### Scenario: An npx tool crashes with exit 2 -- **WHEN** ESLint 因配置问题以 exit 2 退出 -- **THEN** 旧接口为 UNVERIFIED;新接口为 incomplete,均不能称为 lint 违规或通过 - -## ADDED Requirements - -### Requirement: Rust command plans SHALL preserve explicit build levels - -Rust build MUST 记录编译、静态检查和测试执行的区别。Java 默认静态构建保留不运行测试的等级;批准策略要求测试时 MUST 执行,智能体不得自行追加 skip。自定义命令 MUST 通过义务覆盖核对,不能只凭 exit 0 替代质量证据。 - -#### Scenario: Policy requires tests -- **WHEN** 项目批准策略要求构建时运行测试 -- **THEN** 新计划包含测试执行,运行参数不能静默排除 test - -#### Scenario: Default static build completes -- **WHEN** 默认静态构建成功但未运行测试 -- **THEN** 报告 test_execution=false,不声称测试通过 diff --git a/openspec/changes/introduce-rust-codeguard-cli/specs/native-tool-adapters/spec.md b/openspec/changes/introduce-rust-codeguard-cli/specs/native-tool-adapters/spec.md deleted file mode 100644 index 454daba..0000000 --- a/openspec/changes/introduce-rust-codeguard-cli/specs/native-tool-adapters/spec.md +++ /dev/null @@ -1,73 +0,0 @@ -## Purpose - -定义传统原生工具在 Codeguard 内的适用性、执行、结果解释与覆盖证明,使语言注册、工具安装、诊断能力和实际检查完成不再被混为同一种支持状态。 - -## ADDED Requirements - -### Requirement: Adapters SHALL publish verifiable capability contracts - -每个 adapter MUST 声明语言/方言、类别、工具和运行时兼容范围、配置前提、输入范围、报告格式及退出语义。语言每个类别 MUST 明确 implemented、gap 或有证据的 not_applicable。formatter 存在 MUST NOT 自动证明 lint/comments 能力。 - -#### Scenario: A stable legacy entry has only a formatter -- **WHEN** 迁移 Julia 或 Pascal,原 lint 命令为空 -- **THEN** 补充经过真实验收的只读检查能力前保持能力缺口,不能据旧 stable 标签通过 - -#### Scenario: Shell dialect is unsupported -- **WHEN** 项目含 zsh,而选定 ShellCheck 不支持该方言 -- **THEN** 为其保留能力缺口或选择已验证的专用适配器,不静默删除义务 - -### Requirement: Native evidence SHALL be interpreted per tool contract - -adapter MUST 根据工具版本的报告及退出语义解析结果;MUST NOT 以通用非零、exit 1、关键词或模型主观判断替代。无效、截断、陈旧、与计划不符或内部矛盾的报告 MUST 产生未完成。有效部分发现 MUST 保留。 - -#### Scenario: Valid finding precedes a crash -- **WHEN** 工具先产生有效违规,随后发生配置或进程故障 -- **THEN** 保存该 finding 并记录 incomplete,不覆盖为纯工具错误或完整违规结果 - -#### Scenario: Tool exits zero with a stale report -- **WHEN** 报告属于此前内容或当前规则未执行 -- **THEN** 拒绝将其作为本次通过证据 - -### Requirement: Java checks SHALL prove each required native obligation - -Java MUST 分别建立 P3C、通用 lint、注释、安全、依赖漏洞和构建的适用义务。官方 P3C MUST 使用经验证的 P3C PMD 实现和兼容工具链;Checkstyle 配置名 MUST NOT 充当官方 P3C 的执行证据。Maven/Gradle 生命周期成功 MUST 结合实际绑定/执行证据,不能覆盖未运行的质量任务。 - -#### Scenario: Verify succeeds without quality plugins -- **WHEN** `mvn verify` 成功但未运行所需 P3C/Javadoc 检查 -- **THEN** 对应义务仍未完成,`check java` 不能显示全部通过 - -#### Scenario: JDK and PMD are incompatible -- **WHEN** P3C 规则运行因 JDK/PMD 组合失败 -- **THEN** 报告具体工具链未完成,不记为代码违规,不自动换规则或跳过 - -### Requirement: Comment and security categories SHALL retain their own evidence - -注释检查 MUST 根据语言与规则验证其确定性要求,不得以格式化代替。源代码安全、配置安全、入库策略和 CVE MUST 分开归类;仅命中禁止文件模式 MUST 报策略违规,不得无内容证据声称检测到真实私钥。未实现的语义能力 MUST 明示。 - -#### Scenario: Public API lacks required documentation -- **WHEN** 有效规则要求文档且源码缺少对应注释 -- **THEN** 原生或经验证的确定性规则输出注释违规,普通 formatter 成功不消除该义务 - -#### Scenario: Public certificate matches a forbidden path rule -- **WHEN** 文件命中现行禁止入库模式但没有私钥内容证据 -- **THEN** 按策略违规报告,不能将文件名命中写成已确认密钥泄露 - -### Requirement: CVE checks SHALL bind actual dependency and database identity - -Rust CVE 检查 MUST 绑定实际解析的组件版本、依赖来源、advisory 标识和数据库身份/时效。无可靠组件匹配、数据库过期、离线无合格库、缺失必要严重度时 MUST 保留发现与不确定性,不产生无依据的安全通过或确定高危。原生工具缺失 MUST NOT 静默换覆盖不同的通用工具。共享扫描 MUST 可追溯到全部被满足的义务。 - -#### Scenario: Offline database is too old -- **WHEN** 离线数据库超过批准的 freshness -- **THEN** CVE 未完成,不以零匹配判安全 - -#### Scenario: Report has no comparable severity -- **WHEN** 已知漏洞没有策略阈值需要的严重度 -- **THEN** 保留 finding;无法按策略判定时未完成,不预过滤 UNKNOWN - -### Requirement: Migration SHALL account for every legacy language entry - -迁移 MUST 逐项登记基线注册表全部 57 项,包括 54 stable 和 3 planned;前者完成五类别适用性和真实 adapter 验收前 MUST NOT 宣称全量迁移完成。planned MUST 保持显式状态,不能为凑数量创建空实现。注册表变化 MUST 重新做差异核对。 - -#### Scenario: Four major languages are implemented -- **WHEN** 仅 Java/Rust/Python/TypeScript 已可用 -- **THEN** 只能声明这部分能力完成,剩余迁移任务仍未完成 diff --git a/openspec/changes/introduce-rust-codeguard-cli/specs/remediation-workflow/spec.md b/openspec/changes/introduce-rust-codeguard-cli/specs/remediation-workflow/spec.md deleted file mode 100644 index f889452..0000000 --- a/openspec/changes/introduce-rust-codeguard-cli/specs/remediation-workflow/spec.md +++ /dev/null @@ -1,93 +0,0 @@ -## Purpose - -定义项目内持久的问题、环境阻塞、修复任务和复检事件,使智能体能够恢复上下文并逐步完成修复,同时保证任务文件、人工勾选和删除记录不能替代原生工具的验收证据。 - -## ADDED Requirements - -### Requirement: Projects SHALL have an explicitly initialized remediation workspace - -Codeguard MUST 支持 `./codeguard/` 及其中的 .gitignore、工作区清单、脱敏 findings/events、任务与决策引用;原始 reports/runs/cache/worktrees/state MUST 默认 Git 忽略。初始化 MUST 提供 dry-run/apply,不覆盖已有用户文件,不创建第二份质量策略。 - -#### Scenario: User already has files under codeguard -- **WHEN** 初始化遇到同名用户目录或冲突文件 -- **THEN** 给出精确合并/冲突计划,不强制覆盖,不全目录忽略用户源码 - -### Requirement: Findings and environment blockers SHALL produce distinct actionable tasks - -持久同步 MUST 区分真实 finding 与检查未完成的 blocker,按稳定身份归并重复发现、保留原规则与证据。部分报告 MUST 只能增加有效发现/阻塞,不能因缺失旧 finding 自动关闭。任务 MUST 包含问题依据、允许改动、修复步骤、前置依赖、复检条件及历史尝试。 - -同步 MUST 按 run_id 幂等消费所有未导入且身份匹配的报告,不能仅取最新一份而丢弃其他类别发现。过时报告只能成为历史,完整报告也不得跨未覆盖范围关闭问题。 - -#### Scenario: Ten scans report the same issue -- **WHEN** 同一内容/策略下多次检出同一个问题 -- **THEN** 保留一个稳定 issue 和本地运行历史,不生成十个任务或无意义 tracked 文件变化 - -#### Scenario: Missing JDK prevents several checks -- **WHEN** 多个模块因同一 JDK 缺失未完成 -- **THEN** 生成工具链 blocker 与依赖关系,不虚构多条代码违规 - -#### Scenario: Lint and CVE reports await import -- **WHEN** 同一内容先产生 lint 报告再产生 CVE 报告 -- **THEN** 同步纳入两者,重复同步不重复创建问题或事件 - -### Requirement: Closing a task SHALL require verified resolution evidence - -正式 resolved MUST 由真实复检或有批准依据的 target_removed/policy_resolved 事件产生,并绑定问题、内容、规则/工具、策略和覆盖身份。代码修复、依赖修复、环境恢复、政策处置 MUST 分开归因。手工勾选、编辑状态、删除记录、增加忽略或未完成报告中不再出现 MUST NOT 关闭问题或改变 gate。例外 MUST 保留未解决事实。 - -#### Scenario: Agent checks a task as done without verification -- **WHEN** 任务 Markdown 被标为完成但无有效复检 -- **THEN** 正式状态仍待验证,交付判定不变 - -#### Scenario: Verification times out after a patch -- **WHEN** 修复后的原检查器超时 -- **THEN** 原 finding 保留,转为待验证/阻塞,不自动 resolved - -#### Scenario: A resolved finding recurs -- **WHEN** 新内容再次检出同一可匹配问题 -- **THEN** 重开 issue 并保留此前修复历史 - -### Requirement: Repair briefs SHALL guide bounded progress without changing authority - -`status/next/task show` MUST 提供只读视图;next MUST 返回含依据、范围、步骤、约束、验证和历史尝试的 RepairBrief。recipe MUST 有受控来源,原生诊断和仓库文本 MUST 当作不可信数据。无进展重试超预算 MUST 阻塞该任务或请求具体决策,不能降低门禁;其它独立任务仍可推进。 - -MUST 提供 attempt 开始/结束协议,受控 fix 自动登记,自由修复回合由插件登记;尝试 MUST 绑定动作和前后内容摘要、结果及租约。复检前失败、无修改和中断均进入历史与预算,next MUST 不重复推荐耗尽且无新信息的动作。 - -#### Scenario: The same failed patch is attempted repeatedly -- **WHEN** 同一问题和补丁连续无进展达到预算 -- **THEN** 停止相同自动尝试,保留阻断并给出下一步诊断,不推荐跳过规则 - -#### Scenario: Tool output contains an instruction -- **WHEN** 诊断文本要求执行 Shell 或关闭规则 -- **THEN** 仅作为证据数据展示,不升级为动作授权 - -#### Scenario: Repair fails before verification -- **WHEN** 尝试没有代码变化或在调用检查器前失败 -- **THEN** attempt 仍持久计数,不能因没有 verify 报告而无限重复 - -### Requirement: Enabled plugin workflows SHALL connect scans to actionable briefs - -显式初始化并启用工作流后,插件扫描 MUST 经过保存 run、幂等 sync、返回状态/RepairBrief 的路径;仅有重复报错而没有任务指引 MUST 不作为完成的插件接入。未初始化时 MUST 提供临时简报与初始化计划,不静默写受管目录。同步失败 MUST 保留原结果并明示恢复动作;不能假称持久任务已生成或改变质量 gate。 - -#### Scenario: Enabled save hook finds a new issue -- **WHEN** 已启用的项目保存检查产生有效 finding -- **THEN** 创建或更新相应任务并返回下一步,重复同一 finding 不制造 tracked 文件噪声 - -#### Scenario: Backlog storage is unavailable -- **WHEN** 检查已完成但持久目录不可写 -- **THEN** 保留原 finding/gate,说明 backlog_update_failed 和恢复动作,不伪造任务路径 - -### Requirement: Workflow persistence SHALL preserve collaboration and gate independence - -finding 身份、事件父关系、证据引用与工作区 schema MUST 校验。并发领取 MUST 使用带期限租约和进程锁;不同分支状态冲突 MUST 显式协调,不能最后写入覆盖关闭。任务 Markdown MUST 是可重建投影;本地历史文件 MUST 不作为可信 CI 认证。完整 gate MUST 独立检查全部义务。 - -#### Scenario: All tasks are deleted -- **WHEN** 用户或智能体删除持久任务和发现 -- **THEN** 新检查仍按源码与批准策略产生发现,不能因此获得 allow - -#### Scenario: Two agents claim the same task -- **WHEN** 同一工作区并发领取一个未分配任务 -- **THEN** 只有一个有效 lease,另一个收到当前归属与恢复信息 - -#### Scenario: Branches disagree on resolution -- **WHEN** 合并事件存在相互矛盾的关闭状态 -- **THEN** 标记 reconciliation_required 并重新核对,不能自动选最后写入关闭 diff --git a/openspec/changes/introduce-rust-codeguard-cli/specs/rulepack-governance/spec.md b/openspec/changes/introduce-rust-codeguard-cli/specs/rulepack-governance/spec.md deleted file mode 100644 index b0347a4..0000000 --- a/openspec/changes/introduce-rust-codeguard-cli/specs/rulepack-governance/spec.md +++ /dev/null @@ -1,57 +0,0 @@ -## Purpose - -定义质量策略、原生配置、工具链和规则包的权威及变更流程,确保降低误报依靠准确证据而不是智能体自行关闭检查,并保留可复核的例外与历史问题记录。 - -## ADDED Requirements - -### Requirement: Quality policy SHALL be independent from operational options - -必需检查、规则、阈值、排除、测试要求及漏洞库时效 MUST 来源于批准策略。CLI/env 运行参数 MUST NOT 弱化它们;同一 PR 的策略修改 MUST NOT 在未经批准时为自身代码签发通过。config explain MUST 显示原生配置及 suppression 的有效来源和差异。 - -#### Scenario: Agent raises the severity threshold -- **WHEN** 智能体通过参数、环境或本地配置把批准阈值提高 -- **THEN** 新交付门禁不接受该弱化,记录策略差异而非通过 - -#### Scenario: A checker disables all native rules -- **WHEN** 原生配置改为禁用必需规则或以自定义空命令替代 -- **THEN** 覆盖校验不能满足义务,不以命令成功通过 - -### Requirement: Rulepacks and toolchains SHALL be versioned and locked - -rulepack MUST 有版本、规则来源/许可、稳定规则映射、内容摘要及工具兼容范围。检查 MUST 验证工具/运行时/配置/规则锁;扫描 MUST NOT 隐式安装、升级或改写项目配置。安装 MUST 是单独显式动作,离线检查 MUST 不联网。 - -#### Scenario: Tool version differs from the lock -- **WHEN** PATH 工具与锁不匹配 -- **THEN** 未完成并给出准备动作,不自动下载 latest - -### Requirement: Historical findings SHALL remain findings - -基线 MUST 只用于 new/existing 分类和趋势,不得默认豁免存量违规。所有阻断规则 MUST 对新旧发现一致生效。基线不可读或无法比较 MUST 不删除当前发现。 - -#### Scenario: A harmless edit leaves an old violation -- **WHEN** 完整检查在未修改源码中检出已有的阻断违规 -- **THEN** 可标 existing,但仍阻断,不因历史身份或 diff 位置豁免 - -### Requirement: Exceptions SHALL require independently verifiable authority - -例外 MUST 同时绑定规则、范围、内容身份、到期时间、原因和可核验的批准身份,不能采用永久无期限例外。agent 声称获批、skipGate、可写 JSON 或普通 Git config MUST NOT 本身构成授权。例外 MUST 保留原始发现及非通过检查状态;外部批准交付必须与普通 PASS 区分。文档 MUST 明示同权限本地进程不可提供不可绕过保证。 - -#### Scenario: Agent writes a local approval flag -- **WHEN** 智能体写 `approved=true` 或 `codeguard.skipGate=true` -- **THEN** 新交付门禁不接受为授权,不改变违规或未完成状态 - -#### Scenario: A real exception expires -- **WHEN** 经批准例外超过有效期或不匹配当前范围 -- **THEN** 不应用该例外,保留完整门禁要求 - -#### Scenario: Expiry is absent or content changes -- **WHEN** 例外没有到期时间或当前内容不匹配获批身份 -- **THEN** 拒绝应用例外,不能沿用此前批准关闭问题 - -### Requirement: Existing dot-prefix scope SHALL remain explicit - -本变更 MUST 保留普通检查面点前缀默认忽略、不逐路径告警,以及入库安全和配置发现两项例外。覆盖报告 MUST 记录有效策略与汇总范围,不能宣称排除内容已检查。新增扫描或放宽禁止入库策略 MUST 经独立策略变更。 - -#### Scenario: Dot configuration and secret coexist -- **WHEN** 项目含点前缀 linter 配置、普通点前缀源码和拟入库 `.env` -- **THEN** 配置仍发现、普通源码按策略忽略、入库安全照常运行,三者不混为同一排除 diff --git a/openspec/changes/introduce-rust-codeguard-cli/specs/scan-scope-policy/spec.md b/openspec/changes/introduce-rust-codeguard-cli/specs/scan-scope-policy/spec.md deleted file mode 100644 index 3461d76..0000000 --- a/openspec/changes/introduce-rust-codeguard-cli/specs/scan-scope-policy/spec.md +++ /dev/null @@ -1,17 +0,0 @@ -## ADDED Requirements - -### Requirement: Managed remediation artifacts SHALL have a bounded self-scan policy - -初始化清单验证通过的 Codeguard 自有运行产物及生成问题/任务文件 MUST 从普通被测源码发现中排除,并接受工作区 schema、路径及脱敏校验。排除 MUST 精确到生成器拥有的路径集合,不得仅因目录名 codeguard 忽略整棵树;用户源码、未声明文件及入库安全检查 MUST 保留。此要求 MUST 不改变既有点前缀策略及两项例外。 - -#### Scenario: Managed files coexist with user code -- **WHEN** `codeguard/tasks` 有生成任务且 `codeguard/src` 有用户源码 -- **THEN** 生成任务走工作区校验,用户源码照常检测,不出现递归扫描运行副本 - -#### Scenario: A managed record contains a secret -- **WHEN** 拟提交的持久记录意外包含密钥 -- **THEN** 入库安全仍检查并阻断,受管产物不能豁免敏感内容 - -#### Scenario: Agent expands the ownership manifest -- **WHEN** agent 将普通源码路径添加进受管排除清单 -- **THEN** 生成器所有权校验不接受扩张,不能据可写 manifest 关闭扫描 diff --git a/openspec/changes/introduce-rust-codeguard-cli/specs/unified-cli-contract/spec.md b/openspec/changes/introduce-rust-codeguard-cli/specs/unified-cli-contract/spec.md deleted file mode 100644 index f95b412..0000000 --- a/openspec/changes/introduce-rust-codeguard-cli/specs/unified-cli-contract/spec.md +++ /dev/null @@ -1,57 +0,0 @@ -## Purpose - -定义 Rust Codeguard 的统一请求、语言选择、报告、退出码及多入口转换协议,使局部检查成功与完整交付认证具有明确边界,调用方无需猜测原生工具状态。 - -## ADDED Requirements - -### Requirement: Unified commands SHALL select explicit check obligations - -Rust CLI MUST 提供 `lint/comments/cve/security/build/check [path]`;`check` 包含全部适用类别。语言别名 MUST 来源于统一注册表,未知语言在执行前拒绝。部分命令 MUST 明示 selection,不得据局部通过声明项目全部通过。`plan` MUST 仅规划,不执行构建、扫描、下载、安装或修改源码。 - -#### Scenario: Java lint succeeds in a mixed project -- **WHEN** Java lint 完成,但项目仍有 Python、安全或 CVE 义务未在该请求执行 -- **THEN** 请求可成功,交付状态为 not_evaluated,不能宣称全项目通过 - -#### Scenario: User requests a plan -- **WHEN** 调用 `codeguard plan check all .` -- **THEN** 返回义务与待解析前置条件,不执行外部构建或扫描 - -#### Scenario: A language identifier is unknown -- **WHEN** 用户输入未注册的语言 ID -- **THEN** 执行前返回用法错误,列出规范 ID/别名,不启动检查器 - -### Requirement: Rust CLI SHALL expose a versioned exit contract - -Rust CLI MUST 使用 0 请求通过、1 违规、2 用法错误、3 必需义务未完成、4 内部故障、130 取消。执行后的聚合优先级 MUST 为取消、内部故障、未完成、违规、通过;已有发现 MUST 保留。原生退出码 MUST 独立记录,不直接透传作为 CLI 结论。 - -#### Scenario: Findings coexist with an unavailable scanner -- **WHEN** lint 有已确认违规且必需 CVE 工具不可用 -- **THEN** 返回 3,报告同时包含违规和未完成项 - -#### Scenario: Native tool exits with code two -- **WHEN** 工具原生退出 2 -- **THEN** 依据该工具契约生成结果,不将其直接解释成 Codeguard 用法错误 - -### Requirement: Reports SHALL preserve semantics across public formats - -报告 MUST 带 schema_version、请求选择、内容/策略/工具身份、逐项完整性、发现、覆盖及交付判定。human/JSON/SARIF/MCP MUST 来源于同一语义报告。结构化 stdout MUST 不混入进度或原始日志;公开结果 MUST 脱敏,私有原始证据单独存储。未知协议 major MUST 拒绝消费。 - -#### Scenario: SARIF contains no findings but a required task timed out -- **WHEN** 一个必需检查超时且没有有效 finding -- **THEN** SARIF 仍表达未完成,标准报告不得变成干净通过 - -#### Scenario: Tool output contains a credential -- **WHEN** 工具 argv 或诊断含凭据 -- **THEN** MCP 与公开报告不回显原文,保留可用的私有证据引用 - -### Requirement: Empty selection SHALL NOT certify delivery - -显式语言请求无目标 MUST 为未完成。全部发现后证明确无适用义务时 MAY 返回请求成功,但 MUST 标明 not_applicable,MUST NOT 生成交付 allow。缺失工具或 adapter MUST NOT 被当成无适用目标。 - -#### Scenario: Java command runs in the wrong directory -- **WHEN** 显式 `lint java` 未发现 Java 目标 -- **THEN** 返回 3 并说明无匹配目标,不能报告 Java 已通过 - -#### Scenario: Empty project has no applicable checks -- **WHEN** 完整发现证明项目无适用检查对象 -- **THEN** 标为 not_applicable 且 eligible=false,不签发交付通过 diff --git a/openspec/changes/introduce-rust-codeguard-cli/specs/verdict-integrity/spec.md b/openspec/changes/introduce-rust-codeguard-cli/specs/verdict-integrity/spec.md deleted file mode 100644 index 669c1b0..0000000 --- a/openspec/changes/introduce-rust-codeguard-cli/specs/verdict-integrity/spec.md +++ /dev/null @@ -1,37 +0,0 @@ -## MODIFIED Requirements - -### Requirement: Verdicts SHALL preserve uncertainty across interfaces - -显式 legacy-v1 入口 MUST 保持 PASS、FAIL、UNVERIFIED、SKIPPED、PLANNED 及原聚合退出约定:通常 FAIL=2、无 FAIL 但有未验证/计划项=1、已验证或无须检查=0;各旧子命令的已记录差异由兼容层保持。仅真实成功检查允许 passed=true,无法验证不得触发自动修复或 all passed。 - -Rust 新入口 MUST 使用 unified-cli-contract 的版本化协议,MUST 将执行完整性与 findings 分离;混合未完成和违规保留两者并退出 3。CLI/MCP/Hook 转换 MUST 根据协议和结构化语义,不能根据同一个数字猜测通过。此版本边界同样约束旧 CVE、Dockerfile 等结果在新入口的映射。 - -#### Scenario: Configuration error survives MCP serialization -- **WHEN** 旧入口检查器因配置错误退出且没有有效违规结论 -- **THEN** 旧 CLI 退出 1,旧 MCP 返回 passed=false、UNVERIFIED 和原因 - -#### Scenario: Configuration error survives Rust MCP serialization -- **WHEN** 新入口同一检查因配置错误未完成 -- **THEN** Rust CLI 退出 3,MCP 保留 incomplete,不能通过协议转换生成 PASS - -## ADDED Requirements - -### Requirement: Required completeness SHALL gate Rust delivery - -Rust 交付 allow MUST 同时满足全部适用必需义务完成、覆盖匹配、内容与批准策略身份有效、无阻断违规。缺工具、无实现、坏报告、超时、缓存身份失败或输入变化 MUST NOT 成为 allow。未选择的类别与有理由不适用的类别 MUST 明确区分。 - -#### Scenario: No findings but a required tool is missing -- **WHEN** 已运行检查无违规但另一必需工具缺失 -- **THEN** 交付 incomplete,不制造代码违规,也不允许交付 - -#### Scenario: Finding remains in a historical file -- **WHEN** 必需规则检出历史文件中的违规 -- **THEN** 保留 finding 并按同一策略阻断,基线分类不能改变结果 - -### Requirement: Coverage SHALL not change with scheduling strategy - -Rust MUST 在调度前建立完整义务;分批、并发、缓存和增量 MUST 保持等价覆盖与判定,未执行义务必须具有有效复用证明,否则未完成。文件数量阈值 MUST NOT 改变历史问题是否阻断。 - -#### Scenario: A clean extra file crosses a batching boundary -- **WHEN** 目标从 50 个增加至 51 个文件但已有违规未变 -- **THEN** 原违规的门禁影响不变,不能因切换扫描方式而豁免或新增归因 diff --git a/openspec/changes/introduce-rust-codeguard-cli/tasks.md b/openspec/changes/introduce-rust-codeguard-cli/tasks.md deleted file mode 100644 index e620a70..0000000 --- a/openspec/changes/introduce-rust-codeguard-cli/tasks.md +++ /dev/null @@ -1,300 +0,0 @@ -# Tasks:统一 Rust Codeguard CLI - -本文件跟踪**后续实现**,当前文档交付不勾选任何实现任务。规格事实源为本 change 的 `specs/`;设计展开在 [design](design.md)。每项完成需要关联代码、测试和实际证据,不以存在文件、编译或模拟报告替代。 - -实施按红→绿→相关回归推进;每个批次先重新检查 Git/AGENTS/现有完成度。仓库创建、分支切换、工具安装、规则权威变更和发布按当时用户授权执行,不从本任务清单推断已经授权这些动作。不得修改本插件外部受管技能副本。 - -## 1. S01 契约与工程基线 - -依赖:无。覆盖:unified-cli-contract、native-tool-adapters、binary-distribution。 - -- [ ] 1.1 核对最新旧源码与 57 项清单差异,建立“保留正确行为 / 明确纠偏 / legacy 兼容”表;验收:每条差异关联 spec 和 fixture。 -- [ ] 1.2 在获准位置建立用户指定 `codeguard-cli/` 四 crate workspace,锁定 MSRV/依赖/Cargo.lock;验收:可运行 `codeguard --version`,无空适配器充数。 -- [ ] 1.3 建立 crate 依赖方向检查;验收:core→runtime、adapters→runtime、宿主 SDK 入 core 等反例均被拒绝。 -- [ ] 1.4 创建真实语料登记、脱敏和 oracle 格式,收录当前误判/假通过最小样本;验收:源码/工具/规则身份可复现,争议样本独立标记。 -- [ ] 1.5 定义 language×category×platform 能力 schema 和生成文档入口;验收:54 stable/3 planned 全覆盖,formatter-only 不能伪装 lint。 - -## 2. S02 CLI、结果模型与门禁 - -依赖:S01。覆盖:unified-cli-contract、verdict-integrity。 - -- [ ] 2.1 实现统一命令语法、canonical ID/别名及只读 plan;验收:错参无进程副作用、plan 不运行构建/扫描。 -- [ ] 2.2 定义请求/计划/报告/工具锁 JSON schemas 与兼容版本策略,提供完整正反例;验收:未知 major/非法枚举不按 PASS 消费。 -- [ ] 2.3 实现 findings 与 completion 双维聚合及新退出码;验收:混合违规/缺工具返回 3 并保留全部发现,取消/内部异常优先级正确。 -- [ ] 2.4 实现义务账本和交付决策;验收:类别命令、空目标、缺 adapter、未执行任务均不能签发项目 allow。 -- [ ] 2.5 实现统一 human/JSON/SARIF 渲染与私有证据引用;验收:结构化 stdout 纯净、SARIF 未完成可见、公开报告不泄露凭据。 -- [ ] 2.6 建立具名 legacy-v1 协议映射表和参数测试;验收:逐旧入口验证数字/混合优先级,不把兼容通过当新认证。 - -## 3. S03 运行时、快照与缓存 - -依赖:S02。覆盖:execution-kernel、verdict-integrity。 - -- [ ] 3.1 实现字面 argv/cwd/env/stdin 的受控进程执行;验收:空格/分号/命令替换字面值无额外执行,探测不消费 stdin。 -- [ ] 3.2 实现并发流读取、总 deadline、输出预算和私有原子日志;验收:洪流/编码错误/日志 symlink 场景无假完整、无越界写。 -- [ ] 3.3 实现 Unix 进程组与 Windows Job Object 的取消/终止/回收;验收:子孙进程、超时、Ctrl-C、排队取消有平台实测。 -- [ ] 3.4 实现任务 DAG、资源锁及依赖失败传播;验收:独立任务继续、共享 build 目录互斥、失败依赖未完成可见。 -- [ ] 3.5 实现工作树/index/ref 快照与原始字节校验;验收:SHA-1/SHA-256、坏批响应、特殊文件、symlink/gitlink/LFS 均明确处理。 -- [ ] 3.6 实现 GIT_INDEX_FILE、初始提交、worktree、多 ref/non-HEAD/删除 ref push 输入;验收:真实临时 Git 仓检查准确且 index 不变。 -- [ ] 3.7 实现执行前后内容身份复核和源码副作用检测;验收:并发编辑或检查器改源码导致 incomplete。 -- [ ] 3.8 实现严格缓存及义务等价证明;验收:同 mtime/size 内容替换、规则/依赖/工具/库变化必失效,软缓存不可直接认证。 - -## 4. S04 规则与策略权威 - -依赖:S02。覆盖:rulepack-governance。 - -- [ ] 4.1 实现运行配置与批准质量策略的独立解析及 config explain;验收:CLI/env 无法弱化 required/threshold/exclude。 -- [ ] 4.2 实现旧 codeguard.json 显式迁移和原生 suppressions 差异解释;验收:未知/损坏字段不静默丢弃或按默认通过。 -- [ ] 4.3 实现 rulepack manifest、来源/许可、稳定规则 ID、摘要和兼容锁;验收:内容篡改/不兼容组合不能执行认证。 -- [ ] 4.4 实现基线仅分类 new/existing;验收:未修改文件中的存量违规仍阻断,基线失败不消除 finding。 -- [ ] 4.5 实现可信政策修订和例外输入校验;验收:agent 自写批准、无到期、过期、错内容或错范围凭据不生效,批准例外不显示普通 PASS。 -- [ ] 4.6 保留点前缀默认策略及两项例外,生成汇总覆盖;验收:F18 全部成立,无未授权的新排除。 - -## 5. S05 工具适配框架与准备 - -依赖:S03、S04。覆盖:native-tool-adapters、language-gate-commands。 - -- [ ] 5.1 实现 capability/discover/resolve/plan/parse/coverage/fix 协议与编译期注册;验收:adapter 不绕开运行时启动进程或联网。 -- [ ] 5.2 实现工具解析、二进制身份、doctor 和 tool lock 验证;验收:wrapper/受管缓存/系统工具均匹配锁,缺工具返回恢复步骤。 -- [ ] 5.3 实现独立 tools install 流程、下载清单与校验;验收:普通 check/plan/doctor 不隐式安装;真实主动联网 wrapper 在离线隔离中被阻止,无法隔离则启动前 incomplete。 -- [ ] 5.4 实现报告产物 freshness、scope/rule 执行覆盖核对;验收:陈旧或伪造空成功报告不能通过。 -- [ ] 5.5 建立 adapter conformance harness;验收:F01–F10、F17 的有效与畸形报告可独立复用,mock 与真工具证据分层。 - -## 6. S06 Java 全链路 - -依赖:S05。覆盖:native-tool-adapters、language-gate-commands。 - -- [ ] 6.1 实现 Maven/Gradle/JDK/wrapper/profile/module/source-set 观察;验收:多模块、父 POM、动态未知范围与错误 JDK 有真实样本。 -- [ ] 6.2 确定并锁定官方 P3C/PMD/JDK 兼容组合,实现原生报告解析;验收:正反例证明规则实际加载,不能用 Checkstyle 名称替代。 -- [ ] 6.3 实现 Checkstyle/Javadoc 注释检查;验收:公共 API、参数返回、inheritDoc、record/Lombok/生成代码正反例。 -- [ ] 6.4 实现 Java 安全静态检查及 CVE 依赖图适配;验收:真实安全/CVE 样本、坏报告、库过期与模糊匹配分开记录。 -- [ ] 6.5 实现 build 等级和测试执行声明;验收:默认静态构建不谎称测试通过,要求测试的策略不可自动跳过。 -- [ ] 6.6 接入 Java 完整义务与影响闭包;验收:verify 未绑定质量任务、自定义 echo、50/51 文件、未修改调用方失败均不假通过。 -- [ ] 6.7 用代表性 Java 项目完成 check java/check all/doctor/修复前后对照;验收:每条旧新差异人工裁定并有产物引用。 - -## 7. S07 首批共享生态 - -依赖:S05;可与 S06 独立推进。覆盖:native-tool-adapters。 - -- [ ] 7.1 实现 Rust lint/rustdoc/build/依赖与安全义务;验收:workspace/features/targets 和所有 F01–F10 适用场景。 -- [ ] 7.2 实现 Python(python)Ruff/注释/依赖与安全义务;验收:目标 Python/配置继承/锁缺失解析有真实样本。 -- [ ] 7.3 实现 Node/TypeScript/JavaScript(typescript)adapter 基础与依赖审计;验收:parser/tsconfig/本地插件和 monorepo 范围正确。 -- [ ] 7.4 实现 Shell(shell)方言与 Dockerfile(dockerfile)/IaC 基础;验收:zsh 不静默丢弃、Hadolint 与配置安全报告不互相掩盖故障。 -- [ ] 7.5 实现 CVE 共享生态映射、依赖归并和数据库 freshness;验收:UNKNOWN/离线/原生缺失/重复依赖均符合规格。 - -## 8. S08 全语言补齐 - -依赖:S05,复用 S06/S07 已验收基础。覆盖:native-tool-adapters、language-gate-commands。 - -每组以 [57 项清单](../../../docs/rust-cli/coverage-and-acceptance.zh-CN.md) 为边界;每个语言必须有五槽位、工具锁、正反例、故障样本、平台与真实验收产物。每个语言分别拆为能力判定、lint/comments、其余类别与验收三项;每项内部有多工具时按实际 adapter 再细拆,不将未完成工具藏在汇总完成状态中。 - -- [ ] 8.1 为 go 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.2 实现 go 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.3 完成 go 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.4 为 csharp 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.5 实现 csharp 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.6 完成 csharp 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.7 为 kotlin 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.8 实现 kotlin 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.9 完成 kotlin 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.10 为 swift 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.11 实现 swift 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.12 完成 swift 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.13 为 php 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.14 实现 php 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.15 完成 php 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.16 为 ruby 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.17 实现 ruby 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.18 完成 ruby 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.19 为 scala 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.20 实现 scala 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.21 完成 scala 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.22 为 elixir 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.23 实现 elixir 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.24 完成 elixir 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.25 为 c 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.26 实现 c 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.27 完成 c 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.28 为 cpp 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.29 实现 cpp 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.30 完成 cpp 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.31 为 objc 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.32 实现 objc 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.33 完成 objc 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.34 为 dart 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.35 实现 dart 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.36 完成 dart 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.37 为 vue 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.38 实现 vue 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.39 完成 vue 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.40 为 svelte 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.41 实现 svelte 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.42 完成 svelte 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.43 为 astro 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.44 实现 astro 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.45 完成 astro 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.46 为 css 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.47 实现 css 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.48 完成 css 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.49 为 html 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.50 实现 html 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.51 完成 html 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.52 为 graphql 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.53 实现 graphql 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.54 完成 graphql 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.55 为 solidity 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.56 实现 solidity 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.57 完成 solidity 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.58 为 terraform 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.59 实现 terraform 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.60 完成 terraform 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.61 为 nix 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.62 实现 nix 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.63 完成 nix 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.64 为 sql 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.65 实现 sql 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.66 完成 sql 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.67 为 protobuf 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.68 实现 protobuf 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.69 完成 protobuf 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.70 为 yaml 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.71 实现 yaml 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.72 完成 yaml 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.73 为 markdown 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.74 实现 markdown 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.75 完成 markdown 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.76 为 toml 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.77 实现 toml 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.78 完成 toml 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.79 为 haskell 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.80 实现 haskell 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.81 完成 haskell 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.82 为 ocaml 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.83 实现 ocaml 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.84 完成 ocaml 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.85 为 fsharp 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.86 实现 fsharp 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.87 完成 fsharp 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.88 为 perl 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.89 实现 perl 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.90 完成 perl 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.91 为 groovy 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.92 实现 groovy 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.93 完成 groovy 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.94 为 clojure 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.95 实现 clojure 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.96 完成 clojure 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.97 为 powershell 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.98 实现 powershell 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.99 完成 powershell 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.100 为 zig 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.101 实现 zig 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.102 完成 zig 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.103 为 nim 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.104 实现 nim 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.105 完成 nim 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.106 为 crystal 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.107 实现 crystal 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.108 完成 crystal 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.109 为 julia 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.110 实现 julia 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.111 完成 julia 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.112 为 elm 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.113 实现 elm 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.114 完成 elm 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.115 为 lua 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.116 实现 lua 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.117 完成 lua 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.118 为 luau 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.119 实现 luau 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.120 完成 luau 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.121 为 pascal 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.122 实现 pascal 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.123 完成 pascal 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.124 为 r 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.125 实现 r 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.126 完成 r 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.127 为 cfml 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.128 实现 cfml 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.129 完成 cfml 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.130 为 vbnet 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.131 实现 vbnet 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.132 完成 vbnet 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.133 为 erlang 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.134 实现 erlang 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.135 完成 erlang 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.136 为 liquid 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.137 实现 liquid 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.138 完成 liquid 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.139 为 cuda 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.140 实现 cuda 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.141 完成 cuda 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.142 为 ansible 固化五类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。 -- [ ] 8.143 实现 ansible 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 -- [ ] 8.144 完成 ansible 的 CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。 -- [ ] 8.145 为 cobol 保留显式 planned/gap;验收:项目要求该能力时返回未完成,不能用空实现充数。 -- [ ] 8.146 为 arkts 保留显式 planned/gap;验收:项目要求该能力时返回未完成,不能用空实现充数。 -- [ ] 8.147 为 metal 保留显式 planned/gap;验收:项目要求该能力时返回未完成,不能用空实现充数。 -- [ ] 8.148 机器核对最新注册表与全部验收条目;验收:54 个原 stable 五槽位与真实证据完整,3 planned 如实披露,无丢项/重复/别名漂移。 - -## 9. S09 持久问题与修复工作流 - -依赖:S02、S03、S04、S05;与后续修复和宿主接入共享本协议。覆盖:remediation-workflow、scan-scope-policy。 - -- [ ] 9.1 实现 init dry-run/apply 与工作区 schema/.gitignore/受管路径;验收:不覆盖用户文件,不重复建立质量配置,未初始化只用私有用户缓存存原始报告。 -- [ ] 9.2 实现自有产物精确范围规则与工作区校验;验收:运行副本不递归扫描,codeguard/src 用户源码正常检查,入库 secret 仍阻断。 -- [ ] 9.3 实现 finding/blocker 的稳定身份与重命名匹配;验收:十次相同扫描只有一个问题,行号变化不生成无意义重复,不确定匹配不误关闭。 -- [ ] 9.4 实现 run_id 游标、全量未消费报告幂等 sync;验收:先 lint 后 CVE 不丢问题,部分/过时报告不能跨范围关闭旧问题。 -- [ ] 9.5 实现 append-only 事件、父关系、状态机与可重建 Markdown 投影;验收:手改勾选无复检不关闭,缺父/分支冲突触发协调。 -- [ ] 9.6 实现任务依赖与 blocker 归并;验收:多个模块共缺 JDK 形成一个前置任务,各义务仍完整可见。 -- [ ] 9.7 实现 status/next/show 与 RepairBrief/版本化 recipe;验收:给出修复目标、范围、步骤和复检条件,诊断中的指令不可执行。 -- [ ] 9.8 实现 claim/heartbeat/release 跨进程租约;验收:同工作区只有一个有效领取者,过期和中断可恢复,不声称跨机器全局锁。 -- [ ] 9.9 实现 attempt start/finish、动作与 patch 身份、无进展预算;验收:复检前失败/no-change/abandoned 均计数,耗尽后不重复推荐同一动作。 -- [ ] 9.10 实现 task verify 的证据关闭与重开;验收:工具超时、加 ignore、移动到排除目录不自动 resolved,真修复有完整身份绑定。 -- [ ] 9.11 实现 code/dependency/environment/target/policy 的处置归因与例外标签;验收:policy_resolved 不计代码修复,例外保留未解决事实和期限。 -- [ ] 9.12 提供受控 fix 的 attempt 与验证事件接口;验收:noop、部分修改失败及并发编辑的事件样本分别记录且不生成假修复;真实 formatter 接线在 S10 完成。 -- [ ] 9.13 为插件提供启用后的 scan→sync→brief API;验收:新问题给下一步,重复无 Git 噪声,同步失败保留原 gate 并说明 backlog_update_failed。 -- [ ] 9.14 验证持久记录隐私、篡改和删除边界;验收:日志默认不入 Git,删除所有任务不影响真实 gate,跨机器无原始日志可重新复检。 - -## 10. S10 修复能力 - -依赖:S03、S05、S09 的事件/attempt 接口及对应已验收 adapter。覆盖:execution-kernel、rulepack-governance。 - -- [ ] 10.1 实现 dry-run 计划与隔离副本修复、变化清单;验收:只读请求不改源码,计划包含内容身份与副作用范围。 -- [ ] 10.2 实现前置哈希核对和受控 patch 应用;验收:用户并发编辑不被覆盖,路径逃逸不执行。 -- [ ] 10.3 实现同策略复检和修复归因;验收:noop/失败后部分修改/复检器副作用分别呈现,不虚报 fixed。 -- [ ] 10.4 将依赖升级和规则调整分开;验收:修 CVE 不自动放松阈值,修 lint 不关闭规则或更改测试真值。 - -## 11. S11 宿主与分发接入 - -依赖:S02、S03、S09,至少 S06/S07 已可真实运行。覆盖:hook-protocol、binary-distribution。 - -- [ ] 11.1 构建候选平台二进制,固化 ABI/MSRV/签名身份/校验清单;验收:各 target 运行 smoke,未测平台不标 stable。 -- [ ] 11.2 实现插件 runtime lock 和原子下载/切换;验收:摘要不符、缺二进制、离线均无静默 Python fallback。 -- [ ] 11.3 实现 MCP 相同核心 API 与版本化兼容工具;验收:F22、凭据脱敏与超时/取消正确。 -- [ ] 11.4 更新五类宿主入口及 hooks/__protocol__.md 的旧新模式表;验收:保存反馈与严格交付区分,skipGate/env 不能降级新模式。 -- [ ] 11.5 实现真实 Git pre-commit/pre-push 与 CI 入口;验收:alternate index、多 ref、非 HEAD、未知 Shell 边界正确。 -- [ ] 11.6 在独立 codeguard-skills 源仓更新调用与修复指引,再按 vendor 流程同步;验收:不直接编辑受管副本,不建议规避门禁。 -- [ ] 11.7 明确 legacy 弃用与安全回滚路径;验收:旧数字保持,但旧通过不能被新 CI 认证。 - -## 12. S12 质量评测与验收 - -依赖:S08、S09、S10、S11。覆盖:全部十个规格能力。 - -- [ ] 12.1 全量执行 F01–F24 适用矩阵与 schema/协议 golden 测试;验收:必备场景零假通过、零工具故障误判。 -- [ ] 12.2 冻结分层语料与统计门槛,执行独立 holdout;验收:按语言/类别公布 n/TP/FP/FN/区间,不用全局平均掩盖证据不足。 -- [ ] 12.3 完成真实旧新对照及人工差异裁定;验收:历史错误不作为新 oracle,兼容回归与意图纠偏分开。 -- [ ] 12.4 测量冷/热启动、p50/p95、内存和并发;验收:覆盖与 findings 等价后再比较性能,不以跳检提速。 -- [ ] 12.5 执行策略弱化、缓存污染、错误快照、报告缺项和修复越界测试;验收:本地边界如实记录,受保护 CI 不接受未批准策略;项目脚本无法改写可信政策、工具锁或签发收据。 -- [ ] 12.6 Codex/ZCode/Kimi 各做真实命令、MCP、保存与 Git 阻断流程;验收:绑定预期二进制,失效场景不能假通过。 -- [ ] 12.7 完整运行发现→同步→next→attempt→修复→verify→关闭/重开→全量 gate;验收:跨类别报告不丢失、失败可恢复、耗尽重试不逃逸、任务勾选或清空不改变真实门禁。 - -## 13. S13 发布、文档与规格收敛 - -依赖:S12 通过且获得相应发布授权。覆盖:binary-distribution、全部规格。 - -- [ ] 13.1 对照全部 requirement/scenario/tasks 建立最终证据索引;验收:缺证据的项目仍未完成,不为发布删除要求。 -- [ ] 13.2 完成 Rust fmt/clippy/tests、工具链回归、插件既有适用测试、vendor 离线与在线检查、OpenSpec strict;记录真实结果。 -- [ ] 13.3 形成 release notes、CLI/策略迁移指南和实际能力矩阵;验收:候选、stable、planned 与未验证平台表述一致。 -- [ ] 13.4 发布并逐层核对源码/tag/制品/插件 lock/market/installed runtime;验收:版本及摘要闭环,不以本地成功替代安装证据。 -- [ ] 13.5 完成受保护 CI 与已安装三宿主的最终运行复核;验收:实际检查链全部可追溯且未发生自动降级。 -- [ ] 13.6 只有全部实施验收完成后 sync/verify/archive 本 change;保留本次设计验证与后续运行验证的独立记录。 diff --git a/openspec/changes/introduce-rust-codeguard-cli/verification.md b/openspec/changes/introduce-rust-codeguard-cli/verification.md deleted file mode 100644 index f55d154..0000000 --- a/openspec/changes/introduce-rust-codeguard-cli/verification.md +++ /dev/null @@ -1,38 +0,0 @@ -# 本次设计交付验证 - -日期:2026-09-24。性质:架构与规格文档验证,**不是 Rust 实现、真实扫描器或发布验收**。 - -## 交付范围 - -- [设计文档入口](../../../docs/rust-cli/README.md):架构、技术方案、57 项语言迁移与验收、项目内持久修复工作流。 -- 本 change 的 proposal、design、10 个 capability delta 和可执行 tasks。 -- 持久工作区使用 `./codeguard/`,含自有 .gitignore;以问题、阻塞、任务和复检事件指导修复,规则和最终门禁不由任务文件决定。 - -## 实际检查 - -`openspec validate introduce-rust-codeguard-cli --strict --json --no-interactive` 已通过,无 issue。最初的校验发现 MODIFIED scenario 标题未保留,已恢复原 scenario 名称并显式限定旧协议范围,再次校验通过;未删除旧场景来绕过验证。 - -本次使用只读脚本核对 Markdown 本地链接、代码围栏、JSON 示例、语言 ID/状态、重复任务编号、proposal/spec 目录和规范任务追踪,最终退出 0、issues=[]。范围为 19 份 Markdown、40 个本地链接、57 个语言条目、10 个 capability、43 条 requirement、89 个 scenario、228 项未勾选实现任务。Mermaid 有 9 个代码块,已检查围栏与人工语法,未执行渲染器视觉验收。 - -`git diff --check` 与 `git diff --cached --check` 在本次文档路径范围均通过。任务初次语言 ID 机器核对发现三项仅写了大小写不同的展示名,已补充 canonical ID 并复核 57 项全部可追踪。 - -OpenSpec 的 planning artifacts 为 complete 只说明 proposal/design/specs/tasks 已齐备,不意味着实施完成。实现任务全部未勾选;不得据 status 的 isComplete 字段声称二进制可用。 - -## 独立读者检查 - -两轮只读审查识别并修订以下六项: - -1. 例外同时绑定范围、内容身份和到期时间,不允许无期限例外。 -2. 离线执行必须具备可验证的网络隔离条件,不能只转发参数。 -3. 可信 CI 验证端与被测脚本执行区隔离,防止项目脚本篡改策略或签发结果。 -4. work sync 幂等消费全部匹配未导入报告,不只取最后一次检查。 -5. 已启用插件工作流必须经过 scan→sync→RepairBrief;存储失败可见。 -6. attempt 开始/结束记录复检前失败和无修改尝试,避免预算失效。 - -语言任务已细分到具体 language ID;每种语言均有适用性、lint/comments、CVE/security/build 与真实工具验收要求,不用大组汇总掩盖缺项。 - -## 当前证据边界 - -源码观察基线为 `03ebb24`,读到的注册表为 54 stable/3 planned。工作过程中存在其他任务切换分支、暂存 release/manifest 文件;本次不创建或切换分支、不修改这些发布文件、不代替其他任务提交。文档最终实现基线须在实施开始时再次核对。 - -没有建立 Rust 源码仓、编译或执行新 CLI,没有安装工具、测量实际误报率、发布制品、同步市场或验收宿主;没有运行 openspec apply/sync/archive。既有代码全量测试不用于证明本次文档设计已运行。后续实现与发布证据按 tasks 逐项记录。 diff --git a/scripts/check_architecture.py b/scripts/check_architecture.py index b107bc7..cd142d6 100644 --- a/scripts/check_architecture.py +++ b/scripts/check_architecture.py @@ -20,6 +20,7 @@ "cve_check.py": "entry", "detect_lang.py": "entry", "dockerfile_security.py": "entry", + "engine_report.py": "entry", "fix.py": "entry", "gen_language_docs.py": "entry", "java_project.py": "entry", @@ -41,6 +42,8 @@ } CORE_DEPENDENCIES = { + # 引擎边界:纯数据与退出码翻译,不执行进程(探测由调用方注入)。 + "codeguard.engine": {"__future__", "dataclasses", "typing"}, "codeguard.cve_policy": {"__future__", "dataclasses"}, "codeguard.cve_reports": {"__future__", "json", "math", "codeguard.cve_policy"}, "codeguard.cve_scanners": {"__future__", "tempfile", "pathlib", "codeguard.cve_policy", diff --git a/scripts/codeguard/engine.py b/scripts/codeguard/engine.py new file mode 100644 index 0000000..31cca7b --- /dev/null +++ b/scripts/codeguard/engine.py @@ -0,0 +1,116 @@ +"""判定引擎边界:谁签发质量结论,以及各引擎退出码如何翻译成门禁动作。 + +插件自带的 Legacy Python 引擎随包发布,可以签发 PASS/FAIL。 +Rust ``codeguard`` 组件是后续统一内核,但当前对所有质量路径固定返回退出码 3 +(检查未完成),能力矩阵全部条目为 ``gap``。在它自行解除未完成状态之前, +不得用它签发任何质量结论。 + +本模块只做数据与规则,不执行进程:探测结果由调用方注入,便于在不启动外部 +工具的情况下验证门禁语义。 +""" +from __future__ import annotations + +from dataclasses import dataclass +from typing import Literal + +EngineId = Literal["legacy", "rust"] +Verdict = Literal["PASS", "FAIL", "UNVERIFIED", "INCOMPLETE"] + + +@dataclass(frozen=True) +class EngineSpec: + """一个候选判定引擎的登记信息;权威性是显式事实,不由存在性推导。""" + + id: EngineId + label: str + authoritative: bool + version_command: tuple[str, ...] + note: str + + +LEGACY = EngineSpec( + id="legacy", + label="Legacy Python 引擎(随插件发布)", + authoritative=True, + version_command=("codeguard", "detect"), + note="可签发 PASS/FAIL;fix、dockerfile、--lang、--ecosystem、--severity 仅此侧存在。", +) + +RUST = EngineSpec( + id="rust", + label="Rust codeguard 组件(独立内核)", + authoritative=False, + version_command=("codeguard", "--version"), + note=( + "对所有质量路径固定返回退出码 3(未完成),能力矩阵全部 gap;" + "只可作只读观察,命令面改用位置参数,无 fix/dockerfile/--lang/--ecosystem/--severity。" + ), +) + +ENGINES: dict[EngineId, EngineSpec] = {LEGACY.id: LEGACY, RUST.id: RUST} + + +@dataclass(frozen=True) +class GateOutcome: + """一次引擎执行翻译出的门禁动作。 + + ``blocks`` 只表示"是否挡住交付",与"是否有问题"是两件事: + UNVERIFIED 与 INCOMPLETE 都没有发现违规,但同样不允许放行。 + """ + + engine: EngineId + exit_code: int + verdict: Verdict + blocks: bool + reason: str + + +# Legacy:0 通过 / 1 无法验证 / 2 存在违规 / 3 参数错误。 +LEGACY_EXIT: dict[int, tuple[Verdict, bool]] = { + 0: ("PASS", False), + 1: ("UNVERIFIED", True), + 2: ("FAIL", True), + 3: ("UNVERIFIED", True), +} + +# Rust:0 通过 / 1 违规 / 2 参数错误 / 3 检查未完成 / 4 内部故障 / 130 用户中断。 +RUST_EXIT: dict[int, tuple[Verdict, bool]] = { + 0: ("PASS", False), + 1: ("FAIL", True), + 2: ("UNVERIFIED", True), + 3: ("INCOMPLETE", True), + 4: ("INCOMPLETE", True), + 130: ("INCOMPLETE", True), +} + +_EXIT_TABLES: dict[EngineId, dict[int, tuple[Verdict, bool]]] = { + LEGACY.id: LEGACY_EXIT, + RUST.id: RUST_EXIT, +} + + +def translate(engine_id: EngineId, exit_code: int) -> GateOutcome: + """把某引擎的退出码翻译成门禁动作;未知码一律按未验证处理。""" + spec = ENGINES[engine_id] + verdict, blocks = _EXIT_TABLES[engine_id].get( + exit_code, ("UNVERIFIED", True) + ) + reason = spec.note if not spec.authoritative else "Legacy 退出码语义" + return GateOutcome( + engine=engine_id, + exit_code=exit_code, + verdict=verdict, + blocks=blocks, + reason=reason, + ) + + +def resolve_authoritative(*, rust_available: bool) -> EngineSpec: + """选择签发质量结论的引擎。 + + Rust 二进制存在并不改变权威性:只要它仍对质量路径返回未完成,签发方就必须 + 是 Legacy。``rust_available`` 只影响调用方是否需要提示"检测到新内核"。 + """ + if rust_available and not RUST.authoritative: + return LEGACY + return LEGACY if LEGACY.authoritative else RUST diff --git a/scripts/engine_report.py b/scripts/engine_report.py new file mode 100755 index 0000000..70fb122 --- /dev/null +++ b/scripts/engine_report.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python3 +"""engine —— 报告当前由哪个引擎签发质量结论,以及是否检测到 Rust 组件。 + +这是插件侧唯一需要回答"结论是谁给的"的地方。只读,不执行任何检查: +本命令既不扫描代码,也不安装工具,更不会因为发现 Rust 内核就切换签发方。 +""" +from __future__ import annotations + +import argparse +import json +import shutil +import subprocess +import sys +from pathlib import Path + +sys.path.insert(0, str(Path(__file__).resolve().parent)) + +from codeguard.engine import ENGINES, resolve_authoritative + +PROBE_TIMEOUT = 10 + + +def probe_rust() -> dict: + """探测 PATH 上的 codeguard 是否为 Rust 组件。 + + Legacy CLI 没有 --version(会落入未知子命令并以 1 退出),Rust 组件则以 + report_type=version 的 JSON 应答。两者因此可以无歧义区分。 + """ + candidate = shutil.which("codeguard") + if not candidate: + return {"available": False, "reason": "PATH 上没有 codeguard"} + try: + proc = subprocess.run( + [candidate, "--version", "--format", "json"], + capture_output=True, text=True, timeout=PROBE_TIMEOUT, check=False, + ) + except (OSError, subprocess.SubprocessError) as exc: + return {"available": False, "reason": f"探测失败:{exc}"} + if proc.returncode != 0: + return {"available": False, + "reason": f"不是 Rust 协议(exit {proc.returncode})"} + try: + payload = json.loads(proc.stdout) + except ValueError: + return {"available": False, "reason": "版本输出不是 JSON"} + if not isinstance(payload, dict) or payload.get("report_type") != "version": + return {"available": False, "reason": "缺少 report_type=version 标记"} + return { + "available": True, + "path": candidate, + "cli_version": payload.get("cli_version"), + "target": payload.get("target"), + "build_identity": payload.get("build_identity"), + "rulepack_compatibility": payload.get("rulepack_compatibility"), + } + + +def build_report() -> dict: + rust = probe_rust() + authoritative = resolve_authoritative(rust_available=rust["available"]) + return { + "report_type": "engine", + "authoritative_engine": authoritative.id, + "authoritative_label": authoritative.label, + "engines": [ + { + "id": spec.id, + "label": spec.label, + "authoritative": spec.authoritative, + "note": spec.note, + } + for spec in (ENGINES["legacy"], ENGINES["rust"]) + ], + "rust_component": rust, + } + + +def render_human(report: dict) -> str: + lines = ["Codeguard 引擎边界", ""] + lines.append(f"质量结论签发方:{report['authoritative_label']}({report['authoritative_engine']})") + for entry in report["engines"]: + mark = "签发方" if entry["authoritative"] else "非签发方" + lines.append(f" - {entry['label']}:{mark}") + lines.append(f" {entry['note']}") + rust = report["rust_component"] + lines.append("") + if rust["available"]: + lines.append( + f"检测到 Rust 组件:{rust['path']}(cli_version={rust['cli_version']}," + f"target={rust['target']},build_identity={rust['build_identity']}," + f"rulepack_compatibility={rust['rulepack_compatibility']})" + ) + lines.append(" 它当前不签发质量结论:检测到 ≠ 可用于门禁。") + else: + lines.append(f"未检测到 Rust 组件:{rust['reason']}") + return "\n".join(lines) + + +def main(argv: list[str] | None = None) -> int: + parser = argparse.ArgumentParser( + prog="codeguard engine", + description="报告由哪个引擎签发质量结论(只读,不执行检查)", + ) + parser.add_argument("--format", choices=("human", "json"), default="human") + args = parser.parse_args(argv) + + report = build_report() + if args.format == "json": + print(json.dumps(report, ensure_ascii=False, indent=2)) + else: + print(render_human(report)) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/skills.lock.json b/skills.lock.json index a99c3a6..8919876 100644 --- a/skills.lock.json +++ b/skills.lock.json @@ -4,8 +4,8 @@ { "package": "codeguard-skills", "repo": "https://github.com/full-stack-skills/codeguard-skills.git", - "ref": "v0.1.2", - "sha": "2c0c8071f96de48dc53e11de2499c083c100e44c", + "ref": "v0.1.3", + "sha": "33d737f4cf46e5d6d1d1f8dce85d7923e4ad626f", "skills": [ "codeguard", "codeguard-ansible", @@ -78,74 +78,74 @@ ], "dest": "skills/", "sha256": { - "codeguard": "9c6810ccf82c2add76506ee16c28f6809fd6285472d5a8d7107ca354e6fe1d8e", - "codeguard-ansible": "b4d78a74ea3ce4d98c9a53a9c45e488a24f418397b554590dffc34d3ca3b1337", - "codeguard-arkts": "ae1e5c637b77f0fcd247eb47d3700ab621e2ca857d3b57785dad1ab3daaaa4c7", - "codeguard-astro": "15a7a31cac804070b825ab1677ed8cef2e7626e062ebf9112acf71f7ef86ceb4", - "codeguard-c": "1c9e6b74ea93c6b57902c4938e2107403dae81aeebcf533dbede44f66992eac6", - "codeguard-cfml": "e4d00cfd229c5e5fcdd808ceb23d5183a8a95f61c365e95937c076aa28273ffa", - "codeguard-check": "b0de6755927aab088e65f9c104ba3b5b42a31f2bb5e16e3c34a22721059723a4", - "codeguard-clojure": "6328245808d55dd11efa20e83711dce4b39c7b0f793dcde3a23cad9a3742ed8a", - "codeguard-cobol": "129b220e75e7429dfd593fff3b48fa97436370dbf892baee14bdf27c48e78bf8", - "codeguard-cpp": "e7cb2f9d2aac5279f53a26f92819376b1efd74964260a7fa01beeae4e46bd038", - "codeguard-crystal": "a73d4f07d136b81f09f2337f655eff2160b3f37ad0e3ec4d8599825ccaf0bc33", - "codeguard-csharp": "0d81c07a32d8bfc1e9b55a293a99d5e7733ee5636ba6640c323921f053f08427", - "codeguard-css": "5e38b1113fcd87d180928bdf400d9a109b5a4c88491e5d15ce8fc43851ce446b", - "codeguard-cuda": "9ee291bba0ac014140fa638a028ca5f77c09a28b49792e8c1fa96fd46e727859", - "codeguard-cve": "9db89a123c2da9228bc770618ea53eaa944ab76f87dc5a1c1ee4ce595a4b7482", - "codeguard-dart": "d40b0e9bd4810cc47101fb66d9c66ee0b816e07b75bfd1a3614c34d2c5eb1d93", + "codeguard": "d748dd00e15c4d9d2188e951835190fbbd0c8c41d682dc70ec73ca33a574c9f0", + "codeguard-ansible": "a63c35e676c13071e32f41f666fd054332cbf8cfff4f1366859f45ce1b619a33", + "codeguard-arkts": "6d3a82230e07ded3e47f4b581d71bbc1241d3cee0b7cb5b39ff8344fe16492fa", + "codeguard-astro": "0e9cb912d19c77fd91893f43b1a52331e4d77ebab6ba58e03acd3cb00a53613d", + "codeguard-c": "ea2c7e9f285f762779fbf15aa84a6cd987e6dcd62fac0e1e629c71a693909d4c", + "codeguard-cfml": "822ee8d30d28c3fbd9fe6cafa24c89d8aa3da2a57a8965c4b33c481d3e76ea2a", + "codeguard-check": "081dd38b45e56f56d774a2bd2474030549f2d1b6022edfc9b90934b5c5802c56", + "codeguard-clojure": "97ca79125de12677977a7ef786832d5245393d0ce0e30162740e90e0ae709bc1", + "codeguard-cobol": "2e47cc38704c6f4ff4063115f0c31c93c23451d4765ad3e2d003416f13a28fd6", + "codeguard-cpp": "8f8c06e105f121fd839c6ee713254dc342524af851683bd0e25e57cd34ddf386", + "codeguard-crystal": "678bd84523c51a33ef34bcd6a73da024d37a5499c27e81e4fbfe40d5693447cc", + "codeguard-csharp": "0c01e1ba88cb3240fcf114cdbce1a90b1259fa1ed3c80080b022d749462c4ecb", + "codeguard-css": "5f199f164bdbf2c688b96d5484a87ed8883540c696a98c8b7c4d8d21f598964a", + "codeguard-cuda": "52e8e7394227fb3715a00549b4c109d89d15ffc34b73c55c969af0c015aa8940", + "codeguard-cve": "12e166a536e430f2e11b3a09508f16a4bb0e1dd15dc5b9c0d60437cd6b11f4f0", + "codeguard-dart": "ab49d3412fb7c2703f168836c90a787e8aceab46709a52e220269aa8bb7496ce", "codeguard-detect": "56a6509aa250f6a508c088c421f98de623d94f15bb12f8c5067005d7d095842f", - "codeguard-dockerfile": "b95aafae842b8d474da7ddfe0c20c070080b35519c4d18b244dbb028f3f98ce0", - "codeguard-elixir": "bbac0b5691c678b2f944cb28061f05f99cd6683ce1099ced7416508aea638d72", - "codeguard-elm": "16cb94dba06adc95e6740687afcfe904297aa84ca2e7884e48c265df1f584da1", - "codeguard-erlang": "0ad262c45a3d1782c7cf18c702e973899a6f8798b54c4ddec94c868a569745cd", - "codeguard-fix": "f65ceabeda84f5c51ecac111cad059be86503be2335a48623cb2c09104c2d92e", - "codeguard-fsharp": "a8ea7769eb6b88d85b65b88e5f3aa36250a682047e8222dffb3e5737d7f3de00", + "codeguard-dockerfile": "e6f43977a3373f7ec3b5da31d4d8cf38b980c63b7b5985e46fb9e8e5494d41d1", + "codeguard-elixir": "fd70d9daf00520b0470b4721124673ff157eacd9bdc22221491c32b6db3e0b14", + "codeguard-elm": "30b2655492101b5abb9960e52cad09967251fdc8aeb9caded17a6d92176d0bfe", + "codeguard-erlang": "6753ab7a5bdf3668ea71cec8e0a1de41c4ad0dfed15845e7cb0d54597d5aef23", + "codeguard-fix": "0aa2a9ab223a9d04b0c4704c13dafbd463fecb40364c70ebe33b3e46ef34c5d9", + "codeguard-fsharp": "dc3e251b17342cfe936b1700ae008e86c6c88a60bd09d736add1ed5ab005004a", "codeguard-git-branch": "cf8c7814b2f7a0326470d87db18d37feb933f2d71c4152e57ba6f368c24f5e37", "codeguard-git-commit": "f930708f666b40361a5e82d11834bb2f9862368213ce5397d2393f342316165a", - "codeguard-go": "c45b4a657acaf67f922a7145492d5273d7e5b70fa58deb3c886ee338aa015d36", - "codeguard-graphql": "053e66e72304fb736f7115a6dad844ee3718613d09939a3abf06791848aecba4", - "codeguard-groovy": "5c80ca5d19ca3a39b6f3879a20317542334878ae7767cbf84ec87a669f66fdd9", - "codeguard-haskell": "e6ae6d01e2f7c7a31edd7b97381b612f76e235d73ae1f88b9704b2540a83a923", - "codeguard-html": "9cf8f6cb8d9411fc942a24efa507a19ef304d2db4587d1f742c48e3f9ee9abe3", + "codeguard-go": "e3eb115b65cf40f8a917fd58371ee7b5139fb7cb6749146c1c6f2a6d99c4710b", + "codeguard-graphql": "dffb6e58c135006929e75d1029d4737497dcfbb42740d79d7b86be819ef768bd", + "codeguard-groovy": "a62482c54247439a12b78bb025286927b41a71ee9b311deaad1aa47414110a57", + "codeguard-haskell": "8ac301d3ffb75140bebcd89c34f3a85b68d6623dea3efdc95eedcf1be3f7b684", + "codeguard-html": "d8b4aaf68d3232634b4f63b5afd452ec145b54e40dd49cf766e7f179c1331edd", "codeguard-init": "e76b00dea455c3354b67b060d7ef2f3ac15c6af7c2f0eed8fb944b3c26e7aea1", - "codeguard-java": "3832f00a0a26badf80de805b0b1276109343bb711ffce60e63fad127b848843c", - "codeguard-julia": "0b4a32b0bf402ae3bbd5ce79a81144bf33f6e8f5d75feab5f1aba81e7b27b6a7", - "codeguard-kotlin": "0b7ac4c541d9d5dcdfead174d19f012427202e894f07d34254b568af9664c25f", - "codeguard-liquid": "d95db9bc6f7c180f85b62a0b6a4163c29056cbcb9c0d734e68e7c6a6190c586e", - "codeguard-lua": "950ff2e34fdeb5521f6c7a5d9a9928362a1d6ffbf9742130172b667fa4bff13d", - "codeguard-luau": "c988eb250e9b543be6b979852c7acc9e3093dec6929d1d3bd30da6a10269d91e", - "codeguard-markdown": "d4af5e6e63ddfb7664f376861ecc4ccf9ab76e8d70780120267761eb4c72fb62", - "codeguard-metal": "15c7bd82c506297fe7519b21812d1c26a8cb8385a91c43c2f47752ac5c9a8b67", - "codeguard-nim": "55fe4ead57cc373cd7641b6f68595b5ab53fcb673ead7d77e9ee48e6793b1ed8", - "codeguard-nix": "fb982830a842ca705b8b2e24d2eac85cbd36f526008e6f2954d697391f422359", - "codeguard-objc": "63b6369f9fc9d00bd5f8628a6f8e5127a9e1be3a0f9d03b57a9378b0d9e5b84d", - "codeguard-ocaml": "ce45d7e4559f7db3c3f287120d210b6f88d2cb7bb1d75ad7a7dba74d0e6e2d23", - "codeguard-pascal": "13a999918191e6ad3134ef2c997f46c9ea997272f4ec914c6b2b31343ec0cd6a", - "codeguard-perl": "61fb37f073eaedfce6fce46ef4564d97a3eddbbc75b25e926fcb28ce15348d34", - "codeguard-php": "b9139ab6b11499884d743880578bc01b108edd43498accfd40c2c86c98f8d4fd", - "codeguard-powershell": "573187f67123cb4ad9c04b4017351cfd69add325fc6afb5489f81dfcc3e0246f", - "codeguard-protobuf": "2096b8c0b97df8ac007e757e4052543b98a88cc2fec40a4eab712c68205de5b1", - "codeguard-python": "3893b3b90acb45f0e96ab94a3a1407ceb6c15b1a3f8f5708f3db63fa38d78aa2", - "codeguard-r": "1df4b652585676c78bacdc0170937f7ee4dac4e137bd358c7079a6deba7dd4b5", - "codeguard-ruby": "0645355f9b1a122baa79725e4a5cf4365555447bf8728ab6c5b444292655994b", - "codeguard-rust": "455c337fa1d6395983a80d185f951c15e3e9bd7ed12ea4638f53bcb824495f82", - "codeguard-scala": "52fe5b0ec76311db87142ffedb37b3b1110c851a380c927c8d0de7a4c811fafa", + "codeguard-java": "afaa8598f69dc7aa413a10786d476942cc27e6f9e2bed0acc193703857ac13c3", + "codeguard-julia": "221490e160235a3c3a2b2e1111319fd6e1b9d100c4250282d2b474f71b64f1f0", + "codeguard-kotlin": "624dffe94d277a5da86bf60d5a4c2d08dbaeb8a7ab3918a1e0b898017976b2b0", + "codeguard-liquid": "ce67913a5ff5ba9e3057abcc25fee34bd9a5240b7485939eca73f624722b881e", + "codeguard-lua": "0bf132085334ced92317984cffd4158d2ae20861b4fc4fb1aa4cf7f87093ea37", + "codeguard-luau": "d8c271f1c39fec06d461c11444ad480a05a0d26263f1ca98b68056f6f9aa51e1", + "codeguard-markdown": "0a278b086184f39fddc550a3212e8922c754dc9e06a2e23727a5b2fb90d1a174", + "codeguard-metal": "dad3aaf2dce039406f40df31a9a747d3d0a589825d5624fc824717ae0e31c7e8", + "codeguard-nim": "0b73e7699afd322e632a846d952d5eac6c57781cb12107094823ef0e83a12ae1", + "codeguard-nix": "256bfe3aca876d4466a8c7c356446c179919e5094356da755f2b611bec1a2520", + "codeguard-objc": "b85421c89af6dfff8cfb2846f7d8895f8070ef3e2e2d00f8b73cd4dd45dc1869", + "codeguard-ocaml": "e1ba599242319aa87a51ca8920b3f5b41d9e3c2425a4cf9b54d1070ed9ac9260", + "codeguard-pascal": "5d0b2f40981d01678e7922c4f4bc8fdd901121d8e4b36619f6fdad0316b7a6d7", + "codeguard-perl": "9e1ebe246c5baa6a1851fc9ef999bec0e54418f2e474259c542508b7e2fda029", + "codeguard-php": "6b75513b49704e833bb0082a9cfed359f794661e51d11e1d629fded638b6d3ab", + "codeguard-powershell": "18a672b10c79553d21673571ad4e8c82c10974bc7be8bc3b459a36414f90e669", + "codeguard-protobuf": "917350f5c2cf88e5522f2d69a8fe240c324b16ede390c5a2684bf3d66bd1d7bd", + "codeguard-python": "d129a5b8e38dba9af141b4daacf3daf1e08ba7365b2250163bb0b68118fcb187", + "codeguard-r": "48c063277dee8132003742682b54458b75bebf50fdd4eedb06ccebdbafcdebf0", + "codeguard-ruby": "c6f02a02d7e07f09a7d01158187101ffc2e3f068055b2527ff4180d642b13c4a", + "codeguard-rust": "0b9c180351055950986286642c21a200bd2b0aeae52db8faa3d3e3846828d618", + "codeguard-scala": "ba7c20c01094c8377915b845d088f4aae3d76ca35e99d70dbf66b48d11793ac2", "codeguard-security-api": "8ee9900353bf58b80f25868829d84b047ccc6e1d8a28d53e2b88c3e822b5fbe1", - "codeguard-security-code": "7d7d82cc21f75b1ff4bbcab92b14607e652980a833ebc4a6357f28ceaba8c22d", + "codeguard-security-code": "152ede19c341e11d623973ec8951d88b335b5e30218fbf309636ab822067adc3", "codeguard-security-data": "185432d5dd2106506afe4f355108778ef9661ebf3e0ec253c35129b5d373cb38", - "codeguard-shell": "413477839e8748bd32d38646d00828470a7f2b168dedc2f2f4917cdfe053225a", - "codeguard-solidity": "8750aa66c12b02ce4c7a7096bf9c9fabe034cc7aeb8f6a0e5e4a0f94ffb97d54", - "codeguard-sql": "f4bc3f1b3e6f737b895f2cb018edfe68de386536b200879e0459b218ea336887", - "codeguard-svelte": "fbd6d282527f209c507229336fcc0c834ec03481a4835beaeff0bb071c19da5e", - "codeguard-swift": "b96e08a9442ca22ed6252f73622f267e38b5d9d8f08b85f401768c1220a8e255", - "codeguard-terraform": "bad531ce883507dd92fdd77c388b7f5d456507bfdd86dfb002e0bb2b410651e8", - "codeguard-toml": "93e66e8d97a15f436bb097438e04f011c49404c680a1d29d3f497eec6b8d7bab", - "codeguard-typescript": "c86714abd36b2e46b52ab4071d1936ceeb8f76f178d2497b05e498a8c82581bf", - "codeguard-vbnet": "d1f62359f13d2f581b446e39a7fecd34db4f8a085644a3ab5b906d5c55c35f55", - "codeguard-vue": "0df651c06a4a3b468027b1c3ad913c2808682c90890ddd109a9fe5632d064b9c", - "codeguard-yaml": "66b65f6aec5114d2a726726c03c39234fc13bd06ebb398277d22325a3e35af13", - "codeguard-zig": "329fdce6062c1b6e6d2889b1b36c0d50e6b29e384bb9794a3bc879d8df7c3d6a" + "codeguard-shell": "dc40f0312b2ee97d55d78d5c858267354f75b93f9293b050ff8bec32b85ce757", + "codeguard-solidity": "d4888e0bcc462f63377d1bd564e5e15cb261751515590ec831cc2764a3d96eea", + "codeguard-sql": "14058cc8dc6f10137dc652944c17e9c84d3dfc38c805059bbab330e6fa7df2a9", + "codeguard-svelte": "51bbf35bd53f8f7c7841dee25b26d28ae19181ccbb0bbc457943d65124b023e0", + "codeguard-swift": "5b9d7abf41c6ba2973b8f35a2d78b7b6eae0f0092b55ad034762a2fbff1beb43", + "codeguard-terraform": "f5aceb158af7d889cf6732b4b415b44e7e4c5d20e896d3f272309d6eab3b230b", + "codeguard-toml": "3a712fe2f2005e1360376d5874a3d22c3d513214cf9d0ba2a8c73c4a6d89008e", + "codeguard-typescript": "451d5e29d21c232015c71fdecd785166083efe3027a3a914709360ca09ab76ee", + "codeguard-vbnet": "b6bd8495c5ae68bc883ef327ca1f205266d02133275ed6c3db21ee470023e95c", + "codeguard-vue": "776bf9805e5af115253a75aa651a6594f8c44f515e8b3e0a6479ad7ad3b8e31b", + "codeguard-yaml": "bae3b43f8f4849ab4743d2aee381a0f4845fb1f54994015cb44c1e45da4830cd", + "codeguard-zig": "c736d678429fb44847f9fe5e3de0029102ea4c684f6a70aa80280ba88f744126" } } ] diff --git a/skills/codeguard-ansible/SKILL.md b/skills/codeguard-ansible/SKILL.md index 23e41d9..d52ee8b 100644 --- a/skills/codeguard-ansible/SKILL.md +++ b/skills/codeguard-ansible/SKILL.md @@ -138,7 +138,10 @@ Ansible Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — 当前条目标记为 planned;不得把 YAML 通道的结果冒充 Ansible 语义门禁。 + +### 领域陷阱与修复 + +1. **领域陷阱** — 当前条目标记为 planned;不得把 YAML 通道的结果冒充 Ansible 语义门禁。 ## 信息不足时 diff --git a/skills/codeguard-arkts/SKILL.md b/skills/codeguard-arkts/SKILL.md index cf6ee88..1eb074b 100644 --- a/skills/codeguard-arkts/SKILL.md +++ b/skills/codeguard-arkts/SKILL.md @@ -138,7 +138,10 @@ ArkTS (HarmonyOS) Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — 当前条目标记为 planned;需要 HarmonyOS/DevEco 官方诊断证据后才能升级。 + +### 领域陷阱与修复 + +1. **领域陷阱** — 当前条目标记为 planned;需要 HarmonyOS/DevEco 官方诊断证据后才能升级。 ## 信息不足时 diff --git a/skills/codeguard-astro/SKILL.md b/skills/codeguard-astro/SKILL.md index 7c50385..d1f1534 100644 --- a/skills/codeguard-astro/SKILL.md +++ b/skills/codeguard-astro/SKILL.md @@ -148,7 +148,10 @@ Astro Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — Astro 文件需要专用 parser;只检查脚本区不能代表整个组件通过。 + +### 领域陷阱与修复 + +1. **领域陷阱** — Astro 文件需要专用 parser;只检查脚本区不能代表整个组件通过。 ## 信息不足时 diff --git a/skills/codeguard-c/SKILL.md b/skills/codeguard-c/SKILL.md index efcae2f..b57e06a 100644 --- a/skills/codeguard-c/SKILL.md +++ b/skills/codeguard-c/SKILL.md @@ -148,7 +148,10 @@ C Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — clang-tidy 需要可靠的编译参数;复杂项目优先提供 `compile_commands.json`。 + +### 领域陷阱与修复 + +1. **领域陷阱** — clang-tidy 需要可靠的编译参数;复杂项目优先提供 `compile_commands.json`。 ## 信息不足时 diff --git a/skills/codeguard-cfml/SKILL.md b/skills/codeguard-cfml/SKILL.md index 3b85eab..c8fa100 100644 --- a/skills/codeguard-cfml/SKILL.md +++ b/skills/codeguard-cfml/SKILL.md @@ -148,7 +148,10 @@ CFML (ColdFusion) Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — CFML 方言与引擎差异会影响 CFLint 结果;需注明 Adobe CF 或 Lucee。 + +### 领域陷阱与修复 + +1. **领域陷阱** — CFML 方言与引擎差异会影响 CFLint 结果;需注明 Adobe CF 或 Lucee。 ## 信息不足时 diff --git a/skills/codeguard-check/SKILL.md b/skills/codeguard-check/SKILL.md index 7efd12e..634b8e4 100644 --- a/skills/codeguard-check/SKILL.md +++ b/skills/codeguard-check/SKILL.md @@ -1,7 +1,7 @@ --- name: codeguard-check license: Apache-2.0 -description: 对 Codeguard 支持的仓库执行只读 lint 门禁并解释结果;当用户说 check、跑检查、lint 报告、提交前检查,或 CI 的 Codeguard 检查失败时使用。必须区分 PASS、FAIL、UNVERIFIED 与 PLANNED。 +description: 对 Codeguard 支持的仓库执行只读 lint 门禁并解释结果;当用户说 check、跑检查、lint 报告、提交前检查,或 CI 的 Codeguard 检查失败时使用。必须区分 PASS、FAIL、UNVERIFIED、INCOMPLETE 与 PLANNED,并写明结果由 legacy 还是 rust 引擎签发。 compatibility: 需要 Codeguard CLI 和目标语言工具链;默认不修改源码、不安装工具。 --- @@ -11,13 +11,27 @@ compatibility: 需要 Codeguard CLI 和目标语言工具链;默认不修改 ## 30 秒开始 +先判定引擎(`codeguard --version --format json`),再选择命令面。完整对照见 `codeguard` 技能的 `references/operations/engine-contract.md`。 + +Legacy Python 引擎: + ```bash bin/codeguard detect . bin/codeguard check . bin/codeguard check --lang java,python --timeout 60 . ``` -执行前记录工作目录、当前分支、目标模块和工具版本。若 `bin/codeguard` 不存在,不要猜测命令或声称通过;改用仓库的权威 CI/lint 命令或报告 `UNVERIFIED`。 +Rust 组件(当前对质量路径固定返回未完成): + +```bash +codeguard detect . --format json +codeguard plan check all . +codeguard check all . --format json +``` + +Rust 侧的 `check` 只接受位置参数 `all|java`,没有 `--lang`;`--timeout` 接受 duration(如 `30m`)而非裸秒数。Rust 组件返回退出码 3,只能表述为局部原生观察或未完成,**不能作为门禁通过结论**。 + +执行前记录工作目录、当前分支、目标模块和工具版本,并写明结果由哪个引擎签发。若 `bin/codeguard` 不存在,不要猜测命令或声称通过;改用仓库的权威 CI/lint 命令或报告 `UNVERIFIED`。 ## 能力边界 @@ -25,8 +39,8 @@ bin/codeguard check --lang java,python --timeout 60 . 1. 自动检测项目语言,一次跑多语言 lint。 2. 表格化报告每种语言的命令、退出码、耗时和状态。 -3. 使用 `--lang` 和 `--timeout` 缩小故障范围。 -4. 区分代码违规、配置错误、工具缺失和执行器错误。 +3. Legacy 下用 `--lang` 和 `--timeout` 缩小故障范围;Rust 下先用 `plan` 看只读计划。 +4. 区分代码违规、配置错误、工具缺失、未完成和执行器错误。 5. 为修复与 CI 复现产出结构化证据。 ### ⚠️ Prerequisites @@ -62,13 +76,22 @@ bin/codeguard check --lang java,python --timeout 60 . ## 命令契约 +Legacy Python 引擎: + ```bash bin/codeguard check # 全量 bin/codeguard check --lang java,python # 限定语言 -bin/codeguard check --timeout 60 path/ # 指定项目与超时 +bin/codeguard check --timeout 60 path/ # 指定项目与超时(裸秒数) +``` + +Rust 引擎(`--lang` 不存在,`--timeout` 用 duration,退出码 3 表示未完成): + +```bash +codeguard check all path/ --timeout 30m --format json +codeguard check java path/ --format json ``` -实际 CLI 参数以 `bin/codeguard check --help` 为准。技能包只提供操作知识,不假装包含 Codeguard 运行时。 +实际 CLI 参数以 `bin/codeguard check --help`(Legacy)或 `codeguard --help`(Rust)为准。技能包只提供操作知识,不假装包含 Codeguard 运行时。 ## 状态语义 @@ -77,6 +100,7 @@ bin/codeguard check --timeout 60 path/ # 指定项目与超时 | `PASS` | 权威检查命令在明确范围内退出 0 | 可报告该 lint 门禁通过 | | `FAIL` | 工具成功运行并发现违规 | 按格式/规则/配置分类修复 | | `UNVERIFIED` | 工具、配置、权限、版本、超时或环境不足 | 补齐前置条件,不得写通过 | +| `INCOMPLETE` | 检查按契约未跑完(Rust 引擎退出码 3、必需检查缺失、部分模块未覆盖) | 列出未完成项,**不得写通过**,也不得表述为零违规 | | `PLANNED` | 注册表仅有识别能力,没有可执行门禁 | 列出待接入工具与验收条件 | ## 标准 Workflow @@ -113,7 +137,7 @@ bin/codeguard check --timeout 60 path/ # 指定项目与超时 ### Step 7:输出结果 -按语言列出 PASS/FAIL/UNVERIFIED/PLANNED,并将 lint、test、build、security 证据分开。 +按语言列出 PASS/FAIL/UNVERIFIED/INCOMPLETE/PLANNED,并将 lint、test、build、security 证据分开。 ## Rules @@ -127,13 +151,15 @@ bin/codeguard check --timeout 60 path/ # 指定项目与超时 ```text Codeguard check 结果 +- 引擎: - 范围: - 检测语言: - 命令: - 工具: -- 结果: PASS/FAIL/UNVERIFIED/PLANNED> +- 结果: PASS/FAIL/UNVERIFIED/INCOMPLETE/PLANNED> - 发现: - 未验证: +- 未完成: ``` ## Gotchas diff --git a/skills/codeguard-clojure/SKILL.md b/skills/codeguard-clojure/SKILL.md index dac67da..08def1f 100644 --- a/skills/codeguard-clojure/SKILL.md +++ b/skills/codeguard-clojure/SKILL.md @@ -148,7 +148,10 @@ Clojure Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — clj-kondo cache 与 classpath 会影响宏分析;宏项目需提供导出配置。 + +### 领域陷阱与修复 + +1. **领域陷阱** — clj-kondo cache 与 classpath 会影响宏分析;宏项目需提供导出配置。 ## 信息不足时 diff --git a/skills/codeguard-cobol/SKILL.md b/skills/codeguard-cobol/SKILL.md index d98321e..8fd6837 100644 --- a/skills/codeguard-cobol/SKILL.md +++ b/skills/codeguard-cobol/SKILL.md @@ -138,7 +138,10 @@ COBOL Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — 当前条目标记为 planned;依赖具体编译器/IDE,不能虚构通用 CLI。 + +### 领域陷阱与修复 + +1. **领域陷阱** — 当前条目标记为 planned;依赖具体编译器/IDE,不能虚构通用 CLI。 ## 信息不足时 diff --git a/skills/codeguard-cpp/SKILL.md b/skills/codeguard-cpp/SKILL.md index e5c8c42..57f5cd7 100644 --- a/skills/codeguard-cpp/SKILL.md +++ b/skills/codeguard-cpp/SKILL.md @@ -148,7 +148,10 @@ C++ Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — 模板、宏和条件编译高度依赖真实编译数据库;不要凭单文件默认参数宣布通过。 + +### 领域陷阱与修复 + +1. **领域陷阱** — 模板、宏和条件编译高度依赖真实编译数据库;不要凭单文件默认参数宣布通过。 ## 信息不足时 diff --git a/skills/codeguard-crystal/SKILL.md b/skills/codeguard-crystal/SKILL.md index 08026d8..6303f45 100644 --- a/skills/codeguard-crystal/SKILL.md +++ b/skills/codeguard-crystal/SKILL.md @@ -148,7 +148,10 @@ Crystal Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — Ameba 配置和 Crystal 版本需匹配;格式化不替代 `crystal spec`。 + +### 领域陷阱与修复 + +1. **领域陷阱** — Ameba 配置和 Crystal 版本需匹配;格式化不替代 `crystal spec`。 ## 信息不足时 diff --git a/skills/codeguard-csharp/SKILL.md b/skills/codeguard-csharp/SKILL.md index 63135f5..4c474c4 100644 --- a/skills/codeguard-csharp/SKILL.md +++ b/skills/codeguard-csharp/SKILL.md @@ -148,7 +148,10 @@ C# Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **项目配置优先** — 工具默认值不能覆盖仓库已提交的规则和版本约束。 + +### 领域陷阱与修复 + +1. **项目配置优先** — 工具默认值不能覆盖仓库已提交的规则和版本约束。 ## 信息不足时 diff --git a/skills/codeguard-css/SKILL.md b/skills/codeguard-css/SKILL.md index 49dc82c..f84f06b 100644 --- a/skills/codeguard-css/SKILL.md +++ b/skills/codeguard-css/SKILL.md @@ -148,7 +148,10 @@ CSS / SCSS / Sass / LESS Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — Stylelint glob 必须覆盖 SCSS/Sass/LESS 时显式扩展,默认 `**/*.css` 不会自动覆盖全部预处理器。 + +### 领域陷阱与修复 + +1. **领域陷阱** — Stylelint glob 必须覆盖 SCSS/Sass/LESS 时显式扩展,默认 `**/*.css` 不会自动覆盖全部预处理器。 ## 信息不足时 diff --git a/skills/codeguard-cuda/SKILL.md b/skills/codeguard-cuda/SKILL.md index 4123ab7..960aea3 100644 --- a/skills/codeguard-cuda/SKILL.md +++ b/skills/codeguard-cuda/SKILL.md @@ -148,7 +148,10 @@ CUDA Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — CUDA 文件同时受主机编译器与 nvcc 约束;clang-tidy 不能替代真实 CUDA 构建。 + +### 领域陷阱与修复 + +1. **领域陷阱** — CUDA 文件同时受主机编译器与 nvcc 约束;clang-tidy 不能替代真实 CUDA 构建。 ## 信息不足时 diff --git a/skills/codeguard-cve/SKILL.md b/skills/codeguard-cve/SKILL.md index 4bbb27d..990151e 100644 --- a/skills/codeguard-cve/SKILL.md +++ b/skills/codeguard-cve/SKILL.md @@ -32,6 +32,10 @@ compatibility: 需要目标生态的锁文件、扫描工具及可用漏洞数 ## 命令 +先判定引擎,两套命令面不同。Rust `codeguard` 组件的 `cve` 用位置参数选择生态,且没有 `--severity` / `--fix` / `--json`;它对质量路径固定返回未完成(退出码 3),不能用来签发"无漏洞"结论。 + +**Legacy Python 引擎:** + ```bash bin/codeguard cve # 全生态扫描 bin/codeguard cve --ecosystem node # 只扫 node @@ -40,6 +44,16 @@ bin/codeguard cve --severity MEDIUM # 门禁阈值调到中危(发版 bin/codeguard cve --json path/ # 结构化输出 ``` +**Rust 组件(局部原生观察,结论保持未完成):** + +```bash +codeguard cve typescript [path] --node-tool ABS_PATH --npm-entry ABS_PATH --npm-version VERSION +codeguard cve rust [path] --cargo-audit-tool ABS_PATH --db ABS_PATH +codeguard cve python [path] --pip-audit-tool ABS_PATH --pip-audit-version VERSION +``` + +引擎判定与两套命令面对照见 `codeguard` 技能的 `references/operations/engine-contract.md`。 + ## 三态语义(门禁必须遵守) | 退出码 | 含义 | 门禁动作 | @@ -47,6 +61,7 @@ bin/codeguard cve --json path/ # 结构化输出 | 0 | 全部通过 | 允许提交 | | 1 | 无法验证(工具缺失/超时) | **不视为通过**——先装工具 | | 2 | 发现漏洞 | 必须修复(升级/替换/登记缓解),禁止只报告不处理 | +| 3 | 检查未完成(Rust 组件当前对所有质量路径返回) | **不视为通过**——只能表述为未完成或局部观察 | ## Workflow @@ -78,7 +93,7 @@ bin/codeguard cve --json path/ # 结构化输出 ### Step 3:执行只读扫描 -优先 `bin/codeguard cve --json ` 保存结构化证据,不在首次扫描时带 `--fix`。 +优先 `bin/codeguard cve --json ` 保存结构化证据,不在首次扫描时带 `--fix`。Rust 引擎下改用 `--format json` 的 `cve <生态>` 调用,并如实标注该结果为未完成。 ### Step 4:确认可利用性与引入路径 @@ -103,6 +118,7 @@ bin/codeguard cve --json path/ # 结构化输出 3. 不只复制 scanner 标题;必须确认依赖路径和可用修复版本。 4. 缓解不等于修复,必须写明残余风险与追踪日期。 5. 报告必须记录扫描日期和数据库新鲜度。 +6. 必须写明本次扫描由哪个引擎签发;Rust 组件的未完成结果不得表述为零漏洞。 ## 输出模板 diff --git a/skills/codeguard-dart/SKILL.md b/skills/codeguard-dart/SKILL.md index 1bb459d..61fc88d 100644 --- a/skills/codeguard-dart/SKILL.md +++ b/skills/codeguard-dart/SKILL.md @@ -148,7 +148,10 @@ Dart / Flutter Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — `dart analyze` 与 Flutter widget/integration tests 是不同证据层级。 + +### 领域陷阱与修复 + +1. **领域陷阱** — `dart analyze` 与 Flutter widget/integration tests 是不同证据层级。 ## 信息不足时 diff --git a/skills/codeguard-dockerfile/SKILL.md b/skills/codeguard-dockerfile/SKILL.md index 5be86ba..9a9cdf7 100644 --- a/skills/codeguard-dockerfile/SKILL.md +++ b/skills/codeguard-dockerfile/SKILL.md @@ -148,7 +148,10 @@ Dockerfile Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — Hadolint 通过不证明镜像安全;仍需检查基础镜像摘要、SBOM 与漏洞扫描结果。 + +### 领域陷阱与修复 + +1. **领域陷阱** — Hadolint 通过不证明镜像安全;仍需检查基础镜像摘要、SBOM 与漏洞扫描结果。 ## 信息不足时 diff --git a/skills/codeguard-elixir/SKILL.md b/skills/codeguard-elixir/SKILL.md index f930a97..ff640d2 100644 --- a/skills/codeguard-elixir/SKILL.md +++ b/skills/codeguard-elixir/SKILL.md @@ -148,7 +148,10 @@ Elixir Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **项目配置优先** — 工具默认值不能覆盖仓库已提交的规则和版本约束。 + +### 领域陷阱与修复 + +1. **项目配置优先** — 工具默认值不能覆盖仓库已提交的规则和版本约束。 ## 信息不足时 diff --git a/skills/codeguard-elm/SKILL.md b/skills/codeguard-elm/SKILL.md index 1ea51bc..5524841 100644 --- a/skills/codeguard-elm/SKILL.md +++ b/skills/codeguard-elm/SKILL.md @@ -148,7 +148,10 @@ Elm Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — elm-review 依赖项目 review 配置;未初始化时应报告不可验证。 + +### 领域陷阱与修复 + +1. **领域陷阱** — elm-review 依赖项目 review 配置;未初始化时应报告不可验证。 ## 信息不足时 diff --git a/skills/codeguard-erlang/SKILL.md b/skills/codeguard-erlang/SKILL.md index 7559767..89b16f5 100644 --- a/skills/codeguard-erlang/SKILL.md +++ b/skills/codeguard-erlang/SKILL.md @@ -148,7 +148,10 @@ Erlang Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — Elvis 与 erlfmt 依赖 rebar 项目上下文;OTP 版本也会改变可用语法。 + +### 领域陷阱与修复 + +1. **领域陷阱** — Elvis 与 erlfmt 依赖 rebar 项目上下文;OTP 版本也会改变可用语法。 ## 信息不足时 diff --git a/skills/codeguard-fix/SKILL.md b/skills/codeguard-fix/SKILL.md index 60a3be8..fcf29cf 100644 --- a/skills/codeguard-fix/SKILL.md +++ b/skills/codeguard-fix/SKILL.md @@ -23,12 +23,16 @@ compatibility: 需要 Codeguard CLI、对应 formatter/linter 和可写工作树 ## 命令 +`fix` 只在 Legacy Python 引擎下存在。Rust `codeguard` 组件当前没有自动修复命令,探测到 Rust 引擎时不要凭空构造 `codeguard fix`。 + ```bash bin/codeguard fix --dry-run # 预览(不实际修改) bin/codeguard fix # 执行修复 bin/codeguard fix --lang python # 只修 Python ``` +引擎判定与两套命令面对照见 `codeguard` 技能的 `references/operations/engine-contract.md`。 + ## Workflow 1. `bin/codeguard check` 确认失败项 @@ -112,6 +116,7 @@ Codeguard fix 结果 ## 按需加载资源 +- 判定当前引擎与可用命令时读取 **`codeguard`** 技能的 `references/operations/engine-contract.md`。安装:`npx skills add full-stack-skills/codeguard-skills --skill codeguard`。 - 判断是否可自动修复时读取 `references/rules/autofix-boundary.md`。 - 设计分批修复时读取 `references/operations/recheck-playbook.md`。 - 根据用户场景只读取 `examples/` 中的对应示例。 diff --git a/skills/codeguard-fsharp/SKILL.md b/skills/codeguard-fsharp/SKILL.md index 518bcc2..b15f8e2 100644 --- a/skills/codeguard-fsharp/SKILL.md +++ b/skills/codeguard-fsharp/SKILL.md @@ -148,7 +148,10 @@ F# Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — Fantomas 主要处理格式,不替代编译器、测试与 analyzers。 + +### 领域陷阱与修复 + +1. **领域陷阱** — Fantomas 主要处理格式,不替代编译器、测试与 analyzers。 ## 信息不足时 diff --git a/skills/codeguard-go/SKILL.md b/skills/codeguard-go/SKILL.md index 0740cf2..4df4a3e 100644 --- a/skills/codeguard-go/SKILL.md +++ b/skills/codeguard-go/SKILL.md @@ -148,8 +148,11 @@ Go Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — `gofmt` 只处理格式;`go vet` 与 `go test` 仍需独立运行。 -8. **领域陷阱** — 多模块仓库可能包含多个 `go.mod`,从错误根目录执行会漏检。 + +### 领域陷阱与修复 + +1. **领域陷阱** — `gofmt` 只处理格式;`go vet` 与 `go test` 仍需独立运行。 +2. **领域陷阱** — 多模块仓库可能包含多个 `go.mod`,从错误根目录执行会漏检。 ## 信息不足时 diff --git a/skills/codeguard-graphql/SKILL.md b/skills/codeguard-graphql/SKILL.md index c124311..ef763fc 100644 --- a/skills/codeguard-graphql/SKILL.md +++ b/skills/codeguard-graphql/SKILL.md @@ -148,7 +148,10 @@ GraphQL Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — GraphQL lint 依赖 schema;无 schema 时只能验证有限的文档规则。 + +### 领域陷阱与修复 + +1. **领域陷阱** — GraphQL lint 依赖 schema;无 schema 时只能验证有限的文档规则。 ## 信息不足时 diff --git a/skills/codeguard-groovy/SKILL.md b/skills/codeguard-groovy/SKILL.md index e895122..c0b807e 100644 --- a/skills/codeguard-groovy/SKILL.md +++ b/skills/codeguard-groovy/SKILL.md @@ -148,7 +148,10 @@ Groovy Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — Groovy 动态特性使静态 lint 覆盖有限;Gradle/Jenkins DSL 需结合宿主验证。 + +### 领域陷阱与修复 + +1. **领域陷阱** — Groovy 动态特性使静态 lint 覆盖有限;Gradle/Jenkins DSL 需结合宿主验证。 ## 信息不足时 diff --git a/skills/codeguard-haskell/SKILL.md b/skills/codeguard-haskell/SKILL.md index 02af3c0..cc3146e 100644 --- a/skills/codeguard-haskell/SKILL.md +++ b/skills/codeguard-haskell/SKILL.md @@ -148,7 +148,10 @@ Haskell Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — HLint 建议不总是语义等价;涉及 strictness 或性能时禁止盲目批量应用。 + +### 领域陷阱与修复 + +1. **领域陷阱** — HLint 建议不总是语义等价;涉及 strictness 或性能时禁止盲目批量应用。 ## 信息不足时 diff --git a/skills/codeguard-html/SKILL.md b/skills/codeguard-html/SKILL.md index d7afbed..ba173a9 100644 --- a/skills/codeguard-html/SKILL.md +++ b/skills/codeguard-html/SKILL.md @@ -148,7 +148,10 @@ HTML Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — 模板文件可能包含服务端语法;HTMLHint 解析失败时先确认是否应交给模板专用工具。 + +### 领域陷阱与修复 + +1. **领域陷阱** — 模板文件可能包含服务端语法;HTMLHint 解析失败时先确认是否应交给模板专用工具。 ## 信息不足时 diff --git a/skills/codeguard-java/SKILL.md b/skills/codeguard-java/SKILL.md index d0a480e..10ad0ee 100644 --- a/skills/codeguard-java/SKILL.md +++ b/skills/codeguard-java/SKILL.md @@ -148,8 +148,11 @@ Java Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — `mvn compile` 不执行 Javadoc 门禁;发布链失败时必须单独运行 `mvn javadoc:jar`。 -8. **领域陷阱** — JDK 版本会改变 doclint 严格度;本地和 CI 必须使用同一主版本。 + +### 领域陷阱与修复 + +1. **领域陷阱** — `mvn compile` 不执行 Javadoc 门禁;发布链失败时必须单独运行 `mvn javadoc:jar`。 +2. **领域陷阱** — JDK 版本会改变 doclint 严格度;本地和 CI 必须使用同一主版本。 ## 信息不足时 diff --git a/skills/codeguard-julia/SKILL.md b/skills/codeguard-julia/SKILL.md index 5ebf465..247e733 100644 --- a/skills/codeguard-julia/SKILL.md +++ b/skills/codeguard-julia/SKILL.md @@ -148,7 +148,10 @@ Julia Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — 只有 formatter 时必须明确标为 format-only,不能把它当作语义 lint 通过。 + +### 领域陷阱与修复 + +1. **领域陷阱** — 只有 formatter 时必须明确标为 format-only,不能把它当作语义 lint 通过。 ## 信息不足时 diff --git a/skills/codeguard-kotlin/SKILL.md b/skills/codeguard-kotlin/SKILL.md index 20f9882..59ddf5e 100644 --- a/skills/codeguard-kotlin/SKILL.md +++ b/skills/codeguard-kotlin/SKILL.md @@ -148,7 +148,10 @@ Kotlin Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — Detekt 与 ktlint 是不同门禁;Gradle wrapper 版本和插件配置必须以项目为准。 + +### 领域陷阱与修复 + +1. **领域陷阱** — Detekt 与 ktlint 是不同门禁;Gradle wrapper 版本和插件配置必须以项目为准。 ## 信息不足时 diff --git a/skills/codeguard-liquid/SKILL.md b/skills/codeguard-liquid/SKILL.md index ccef77c..ac60cf8 100644 --- a/skills/codeguard-liquid/SKILL.md +++ b/skills/codeguard-liquid/SKILL.md @@ -148,7 +148,10 @@ Liquid (Shopify) Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — Shopify Theme Check 面向 Shopify Liquid;其他 Liquid 方言需单独确认。 + +### 领域陷阱与修复 + +1. **领域陷阱** — Shopify Theme Check 面向 Shopify Liquid;其他 Liquid 方言需单独确认。 ## 信息不足时 diff --git a/skills/codeguard-lua/SKILL.md b/skills/codeguard-lua/SKILL.md index 7e9d228..f5bf88d 100644 --- a/skills/codeguard-lua/SKILL.md +++ b/skills/codeguard-lua/SKILL.md @@ -148,7 +148,10 @@ Lua Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — Lua 版本和宿主环境差异大;Luacheck globals 必须与运行时一致。 + +### 领域陷阱与修复 + +1. **领域陷阱** — Lua 版本和宿主环境差异大;Luacheck globals 必须与运行时一致。 ## 信息不足时 diff --git a/skills/codeguard-luau/SKILL.md b/skills/codeguard-luau/SKILL.md index 3bf04f9..6ba29a1 100644 --- a/skills/codeguard-luau/SKILL.md +++ b/skills/codeguard-luau/SKILL.md @@ -148,7 +148,10 @@ Luau Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — Luau 与标准 Lua 类型/语法不同,禁止用普通 Lua linter 代替。 + +### 领域陷阱与修复 + +1. **领域陷阱** — Luau 与标准 Lua 类型/语法不同,禁止用普通 Lua linter 代替。 ## 信息不足时 diff --git a/skills/codeguard-markdown/SKILL.md b/skills/codeguard-markdown/SKILL.md index b436166..cc6cdd8 100644 --- a/skills/codeguard-markdown/SKILL.md +++ b/skills/codeguard-markdown/SKILL.md @@ -148,7 +148,10 @@ Markdown Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — Markdown 方言和文档生成器规则不同;先读取 `.markdownlint*` 与站点配置。 + +### 领域陷阱与修复 + +1. **领域陷阱** — Markdown 方言和文档生成器规则不同;先读取 `.markdownlint*` 与站点配置。 ## 信息不足时 diff --git a/skills/codeguard-metal/SKILL.md b/skills/codeguard-metal/SKILL.md index f77f21d..5c8181e 100644 --- a/skills/codeguard-metal/SKILL.md +++ b/skills/codeguard-metal/SKILL.md @@ -138,7 +138,10 @@ Metal Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — 当前条目标记为 planned;需要 Xcode/metal 编译链证据后才能升级。 + +### 领域陷阱与修复 + +1. **领域陷阱** — 当前条目标记为 planned;需要 Xcode/metal 编译链证据后才能升级。 ## 信息不足时 diff --git a/skills/codeguard-nim/SKILL.md b/skills/codeguard-nim/SKILL.md index 16396c5..d2ae243 100644 --- a/skills/codeguard-nim/SKILL.md +++ b/skills/codeguard-nim/SKILL.md @@ -148,7 +148,10 @@ Nim Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — `nim check` 仍依赖项目 defines 与搜索路径;单文件默认上下文可能误报。 + +### 领域陷阱与修复 + +1. **领域陷阱** — `nim check` 仍依赖项目 defines 与搜索路径;单文件默认上下文可能误报。 ## 信息不足时 diff --git a/skills/codeguard-nix/SKILL.md b/skills/codeguard-nix/SKILL.md index 8932f64..0164e1a 100644 --- a/skills/codeguard-nix/SKILL.md +++ b/skills/codeguard-nix/SKILL.md @@ -148,7 +148,10 @@ Nix Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — deadnix 发现未使用表达式,nixpkgs-fmt 只格式化;仍需执行 flake/check 或真实构建。 + +### 领域陷阱与修复 + +1. **领域陷阱** — deadnix 发现未使用表达式,nixpkgs-fmt 只格式化;仍需执行 flake/check 或真实构建。 ## 信息不足时 diff --git a/skills/codeguard-objc/SKILL.md b/skills/codeguard-objc/SKILL.md index 0caca34..5451bc9 100644 --- a/skills/codeguard-objc/SKILL.md +++ b/skills/codeguard-objc/SKILL.md @@ -148,7 +148,10 @@ Objective-C Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — Objective-C++ 的 `.mm` 文件必须使用匹配的 SDK 与编译参数,单独 clang-tidy 结果可能失真。 + +### 领域陷阱与修复 + +1. **领域陷阱** — Objective-C++ 的 `.mm` 文件必须使用匹配的 SDK 与编译参数,单独 clang-tidy 结果可能失真。 ## 信息不足时 diff --git a/skills/codeguard-ocaml/SKILL.md b/skills/codeguard-ocaml/SKILL.md index 450b451..7720dc7 100644 --- a/skills/codeguard-ocaml/SKILL.md +++ b/skills/codeguard-ocaml/SKILL.md @@ -148,7 +148,10 @@ OCaml Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — ocamlformat 版本是格式契约的一部分;不同版本可能产生大面积无意义 diff。 + +### 领域陷阱与修复 + +1. **领域陷阱** — ocamlformat 版本是格式契约的一部分;不同版本可能产生大面积无意义 diff。 ## 信息不足时 diff --git a/skills/codeguard-pascal/SKILL.md b/skills/codeguard-pascal/SKILL.md index 1a79722..5c58936 100644 --- a/skills/codeguard-pascal/SKILL.md +++ b/skills/codeguard-pascal/SKILL.md @@ -148,7 +148,10 @@ Pascal / Delphi Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — 只有格式化能力时不得声称完成静态检查;仍需编译器或 IDE 诊断。 + +### 领域陷阱与修复 + +1. **领域陷阱** — 只有格式化能力时不得声称完成静态检查;仍需编译器或 IDE 诊断。 ## 信息不足时 diff --git a/skills/codeguard-perl/SKILL.md b/skills/codeguard-perl/SKILL.md index 35f3b63..6fde78d 100644 --- a/skills/codeguard-perl/SKILL.md +++ b/skills/codeguard-perl/SKILL.md @@ -148,7 +148,10 @@ Perl Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — Perl::Critic profile 决定严重级别;必须读取项目 `.perlcriticrc`。 + +### 领域陷阱与修复 + +1. **领域陷阱** — Perl::Critic profile 决定严重级别;必须读取项目 `.perlcriticrc`。 ## 信息不足时 diff --git a/skills/codeguard-php/SKILL.md b/skills/codeguard-php/SKILL.md index 2424ee1..898034d 100644 --- a/skills/codeguard-php/SKILL.md +++ b/skills/codeguard-php/SKILL.md @@ -148,7 +148,10 @@ PHP Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — `php -l` 只验证语法,不覆盖类型、风格或框架规则;不要把语法通过写成质量全绿。 + +### 领域陷阱与修复 + +1. **领域陷阱** — `php -l` 只验证语法,不覆盖类型、风格或框架规则;不要把语法通过写成质量全绿。 ## 信息不足时 diff --git a/skills/codeguard-powershell/SKILL.md b/skills/codeguard-powershell/SKILL.md index 066d3b1..b003f1d 100644 --- a/skills/codeguard-powershell/SKILL.md +++ b/skills/codeguard-powershell/SKILL.md @@ -148,7 +148,10 @@ PowerShell Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — Windows PowerShell 与 PowerShell 7 规则/模块不同,先确认目标运行时。 + +### 领域陷阱与修复 + +1. **领域陷阱** — Windows PowerShell 与 PowerShell 7 规则/模块不同,先确认目标运行时。 ## 信息不足时 diff --git a/skills/codeguard-protobuf/SKILL.md b/skills/codeguard-protobuf/SKILL.md index 11a54d3..77ba250 100644 --- a/skills/codeguard-protobuf/SKILL.md +++ b/skills/codeguard-protobuf/SKILL.md @@ -148,7 +148,10 @@ Protobuf Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — Buf lint 通过后仍应检查 breaking changes;风格合规不等于 wire compatibility。 + +### 领域陷阱与修复 + +1. **领域陷阱** — Buf lint 通过后仍应检查 breaking changes;风格合规不等于 wire compatibility。 ## 信息不足时 diff --git a/skills/codeguard-python/SKILL.md b/skills/codeguard-python/SKILL.md index f87b2c2..a90b369 100644 --- a/skills/codeguard-python/SKILL.md +++ b/skills/codeguard-python/SKILL.md @@ -148,8 +148,11 @@ Python Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — Ruff 的 `check --fix` 与 `format` 职责不同;需要格式化时两者应分别执行。 -8. **领域陷阱** — 先读取 `pyproject.toml` 的 target-version 与 per-file-ignores,不能用全局默认覆盖项目契约。 + +### 领域陷阱与修复 + +1. **领域陷阱** — Ruff 的 `check --fix` 与 `format` 职责不同;需要格式化时两者应分别执行。 +2. **领域陷阱** — 先读取 `pyproject.toml` 的 target-version 与 per-file-ignores,不能用全局默认覆盖项目契约。 ## 信息不足时 diff --git a/skills/codeguard-r/SKILL.md b/skills/codeguard-r/SKILL.md index c5af0b2..283ef52 100644 --- a/skills/codeguard-r/SKILL.md +++ b/skills/codeguard-r/SKILL.md @@ -148,7 +148,10 @@ R Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — R 包项目与普通脚本目录的 lint 范围不同;包项目还需 R CMD check。 + +### 领域陷阱与修复 + +1. **领域陷阱** — R 包项目与普通脚本目录的 lint 范围不同;包项目还需 R CMD check。 ## 信息不足时 diff --git a/skills/codeguard-ruby/SKILL.md b/skills/codeguard-ruby/SKILL.md index 0801c3d..2e3a380 100644 --- a/skills/codeguard-ruby/SKILL.md +++ b/skills/codeguard-ruby/SKILL.md @@ -148,7 +148,10 @@ Ruby Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **项目配置优先** — 工具默认值不能覆盖仓库已提交的规则和版本约束。 + +### 领域陷阱与修复 + +1. **项目配置优先** — 工具默认值不能覆盖仓库已提交的规则和版本约束。 ## 信息不足时 diff --git a/skills/codeguard-rust/SKILL.md b/skills/codeguard-rust/SKILL.md index 15f8b73..2ad1e37 100644 --- a/skills/codeguard-rust/SKILL.md +++ b/skills/codeguard-rust/SKILL.md @@ -148,8 +148,11 @@ Rust Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — `cargo fmt` 通过不代表 Clippy 通过;格式和语义 lint 是两条独立门禁。 -8. **领域陷阱** — Workspace 必须从根 `Cargo.toml` 执行,否则可能漏掉成员 crate。 + +### 领域陷阱与修复 + +1. **领域陷阱** — `cargo fmt` 通过不代表 Clippy 通过;格式和语义 lint 是两条独立门禁。 +2. **领域陷阱** — Workspace 必须从根 `Cargo.toml` 执行,否则可能漏掉成员 crate。 ## 信息不足时 diff --git a/skills/codeguard-scala/SKILL.md b/skills/codeguard-scala/SKILL.md index 279bf93..74275fb 100644 --- a/skills/codeguard-scala/SKILL.md +++ b/skills/codeguard-scala/SKILL.md @@ -148,7 +148,10 @@ Scala Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **项目配置优先** — 工具默认值不能覆盖仓库已提交的规则和版本约束。 + +### 领域陷阱与修复 + +1. **项目配置优先** — 工具默认值不能覆盖仓库已提交的规则和版本约束。 ## 信息不足时 diff --git a/skills/codeguard-security-code/SKILL.md b/skills/codeguard-security-code/SKILL.md index 1b4f260..e6334e3 100644 --- a/skills/codeguard-security-code/SKILL.md +++ b/skills/codeguard-security-code/SKILL.md @@ -50,12 +50,22 @@ AI 行为:**禁止**把密钥/密码写死进代码或提交;发现已泄露 ### 统一入口(推荐) +先判定引擎:`codeguard --version --format json`。对照见 `codeguard` 技能的 `references/operations/engine-contract.md`。 + +Legacy Python 引擎: + ```bash codeguard cve # 自动检测生态并扫描(maven/node/python/rust) codeguard cve --fix # 允许自动修复(npm audit fix) codeguard cve --severity MEDIUM # 失败阈值调到中危 ``` +Rust 引擎用位置参数选生态,且没有 `--fix` / `--severity`;它当前对质量路径返回未完成(退出码 3),不能用来签发"无漏洞"结论: + +```bash +codeguard cve typescript [path] # / cve rust / cve python +``` + ### 各生态原生命令 ```bash diff --git a/skills/codeguard-shell/SKILL.md b/skills/codeguard-shell/SKILL.md index ecbffd8..691c44f 100644 --- a/skills/codeguard-shell/SKILL.md +++ b/skills/codeguard-shell/SKILL.md @@ -148,7 +148,10 @@ Shell Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — ShellCheck 必须匹配脚本 shebang;bash、sh、zsh 的语义不能混用。 + +### 领域陷阱与修复 + +1. **领域陷阱** — ShellCheck 必须匹配脚本 shebang;bash、sh、zsh 的语义不能混用。 ## 信息不足时 diff --git a/skills/codeguard-solidity/SKILL.md b/skills/codeguard-solidity/SKILL.md index 09dcb79..2ffd5ec 100644 --- a/skills/codeguard-solidity/SKILL.md +++ b/skills/codeguard-solidity/SKILL.md @@ -148,7 +148,10 @@ Solidity Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — Solhint 是风格/静态检查,不替代 Slither、Foundry 测试或合约审计。 + +### 领域陷阱与修复 + +1. **领域陷阱** — Solhint 是风格/静态检查,不替代 Slither、Foundry 测试或合约审计。 ## 信息不足时 diff --git a/skills/codeguard-sql/SKILL.md b/skills/codeguard-sql/SKILL.md index 93b030c..e61ed7a 100644 --- a/skills/codeguard-sql/SKILL.md +++ b/skills/codeguard-sql/SKILL.md @@ -148,7 +148,10 @@ SQL Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — SQLFluff 必须设置正确 dialect;未指定方言的通过结果不能用于数据库兼容性结论。 + +### 领域陷阱与修复 + +1. **领域陷阱** — SQLFluff 必须设置正确 dialect;未指定方言的通过结果不能用于数据库兼容性结论。 ## 信息不足时 diff --git a/skills/codeguard-svelte/SKILL.md b/skills/codeguard-svelte/SKILL.md index 8854eb8..452e8a0 100644 --- a/skills/codeguard-svelte/SKILL.md +++ b/skills/codeguard-svelte/SKILL.md @@ -148,7 +148,10 @@ Svelte Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — Svelte parser 与 ESLint 主版本需要兼容;解析失败不能降级为跳过。 + +### 领域陷阱与修复 + +1. **领域陷阱** — Svelte parser 与 ESLint 主版本需要兼容;解析失败不能降级为跳过。 ## 信息不足时 diff --git a/skills/codeguard-swift/SKILL.md b/skills/codeguard-swift/SKILL.md index 1d4c826..40889ea 100644 --- a/skills/codeguard-swift/SKILL.md +++ b/skills/codeguard-swift/SKILL.md @@ -148,7 +148,10 @@ Swift Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — SwiftLint 的规则来自仓库配置;不得用个人全局配置覆盖团队 `.swiftlint.yml`。 + +### 领域陷阱与修复 + +1. **领域陷阱** — SwiftLint 的规则来自仓库配置;不得用个人全局配置覆盖团队 `.swiftlint.yml`。 ## 信息不足时 diff --git a/skills/codeguard-terraform/SKILL.md b/skills/codeguard-terraform/SKILL.md index 79d3378..3dcd39a 100644 --- a/skills/codeguard-terraform/SKILL.md +++ b/skills/codeguard-terraform/SKILL.md @@ -148,7 +148,10 @@ Terraform / OpenTofu Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — `terraform fmt`、`terraform validate` 与 TFLint 是三类门禁,不能互相替代。 + +### 领域陷阱与修复 + +1. **领域陷阱** — `terraform fmt`、`terraform validate` 与 TFLint 是三类门禁,不能互相替代。 ## 信息不足时 diff --git a/skills/codeguard-toml/SKILL.md b/skills/codeguard-toml/SKILL.md index cf036c2..f3743dd 100644 --- a/skills/codeguard-toml/SKILL.md +++ b/skills/codeguard-toml/SKILL.md @@ -148,7 +148,10 @@ TOML Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — Taplo 格式化会重排布局;先确认生成文件和锁文件是否允许修改。 + +### 领域陷阱与修复 + +1. **领域陷阱** — Taplo 格式化会重排布局;先确认生成文件和锁文件是否允许修改。 ## 信息不足时 diff --git a/skills/codeguard-typescript/SKILL.md b/skills/codeguard-typescript/SKILL.md index 97487c7..78dcb8d 100644 --- a/skills/codeguard-typescript/SKILL.md +++ b/skills/codeguard-typescript/SKILL.md @@ -148,8 +148,11 @@ TypeScript / JavaScript Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — 坚持 `npx --no-install`,避免检查过程静默下载与改变依赖树。 -8. **领域陷阱** — ESLint flat config 与旧 `.eslintrc` 的解析规则不同,先确认项目实际采用哪一套。 + +### 领域陷阱与修复 + +1. **领域陷阱** — 坚持 `npx --no-install`,避免检查过程静默下载与改变依赖树。 +2. **领域陷阱** — ESLint flat config 与旧 `.eslintrc` 的解析规则不同,先确认项目实际采用哪一套。 ## 信息不足时 diff --git a/skills/codeguard-vbnet/SKILL.md b/skills/codeguard-vbnet/SKILL.md index 44342ad..781e8a1 100644 --- a/skills/codeguard-vbnet/SKILL.md +++ b/skills/codeguard-vbnet/SKILL.md @@ -148,7 +148,10 @@ Visual Basic .NET Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — dotnet format 需要解析 solution/project;只有散落 `.vb` 文件时不可宣布通过。 + +### 领域陷阱与修复 + +1. **领域陷阱** — dotnet format 需要解析 solution/project;只有散落 `.vb` 文件时不可宣布通过。 ## 信息不足时 diff --git a/skills/codeguard-vue/SKILL.md b/skills/codeguard-vue/SKILL.md index 3f0f572..ca251cc 100644 --- a/skills/codeguard-vue/SKILL.md +++ b/skills/codeguard-vue/SKILL.md @@ -148,7 +148,10 @@ Vue Codeguard 结果 4. **占位符不是字面参数** — `{file}` 必须替换为真实、已授权路径。 5. **自动修复可能扩大 diff** — 修复后先审查 diff,再运行回归门禁。 6. **生成与 vendor 目录需显式策略** — 不得随意全仓扫描或修改第三方内容。 -7. **领域陷阱** — Vue SFC 需要匹配 Vue 版本的 parser/plugin;普通 ESLint 配置可能跳过 `