diff --git a/openspec/changes/2026-09-21-repair-markdown-gate-and-doc-sync/.openspec.yaml b/openspec/changes/archive/2026-09-21-repair-markdown-gate-and-doc-sync/.openspec.yaml similarity index 100% rename from openspec/changes/2026-09-21-repair-markdown-gate-and-doc-sync/.openspec.yaml rename to openspec/changes/archive/2026-09-21-repair-markdown-gate-and-doc-sync/.openspec.yaml diff --git a/openspec/changes/2026-09-21-repair-markdown-gate-and-doc-sync/design.md b/openspec/changes/archive/2026-09-21-repair-markdown-gate-and-doc-sync/design.md similarity index 100% rename from openspec/changes/2026-09-21-repair-markdown-gate-and-doc-sync/design.md rename to openspec/changes/archive/2026-09-21-repair-markdown-gate-and-doc-sync/design.md diff --git a/openspec/changes/2026-09-21-repair-markdown-gate-and-doc-sync/proposal.md b/openspec/changes/archive/2026-09-21-repair-markdown-gate-and-doc-sync/proposal.md similarity index 100% rename from openspec/changes/2026-09-21-repair-markdown-gate-and-doc-sync/proposal.md rename to openspec/changes/archive/2026-09-21-repair-markdown-gate-and-doc-sync/proposal.md diff --git a/openspec/changes/2026-09-21-repair-markdown-gate-and-doc-sync/specs/language-gate-commands/spec.md b/openspec/changes/archive/2026-09-21-repair-markdown-gate-and-doc-sync/specs/language-gate-commands/spec.md similarity index 100% rename from openspec/changes/2026-09-21-repair-markdown-gate-and-doc-sync/specs/language-gate-commands/spec.md rename to openspec/changes/archive/2026-09-21-repair-markdown-gate-and-doc-sync/specs/language-gate-commands/spec.md diff --git a/openspec/changes/2026-09-21-repair-markdown-gate-and-doc-sync/specs/language-registry-doc-sync/spec.md b/openspec/changes/archive/2026-09-21-repair-markdown-gate-and-doc-sync/specs/language-registry-doc-sync/spec.md similarity index 100% rename from openspec/changes/2026-09-21-repair-markdown-gate-and-doc-sync/specs/language-registry-doc-sync/spec.md rename to openspec/changes/archive/2026-09-21-repair-markdown-gate-and-doc-sync/specs/language-registry-doc-sync/spec.md diff --git a/openspec/changes/2026-09-21-repair-markdown-gate-and-doc-sync/tasks.md b/openspec/changes/archive/2026-09-21-repair-markdown-gate-and-doc-sync/tasks.md similarity index 89% rename from openspec/changes/2026-09-21-repair-markdown-gate-and-doc-sync/tasks.md rename to openspec/changes/archive/2026-09-21-repair-markdown-gate-and-doc-sync/tasks.md index 7e82248..75efb74 100644 --- a/openspec/changes/2026-09-21-repair-markdown-gate-and-doc-sync/tasks.md +++ b/openspec/changes/archive/2026-09-21-repair-markdown-gate-and-doc-sync/tasks.md @@ -43,13 +43,13 @@ ## 7. 上游收口(跨仓,本变更不修改锁定内容) - [x] 7.1 在 `full-stack-skills/codeguard-skills` 修 `skills/**` 下 80 条 markdown:66 `MD029/ol-prefix`、13 `MD056/table-column-count`、1 `MD037`。 -- [ ] 7.2 发布不可变 tag。 -- [ ] 7.3 插件侧更新 `skills.lock.json` 的 ref 并重跑 vendor。 -- [ ] 7.4 确认本仓 markdown 门禁转绿(此时 `npx --no-install markdownlint-cli2 "**/*.md"` 应为 0 问题)。 +- [x] 7.2 发布不可变 tag。 +- [x] 7.3 插件侧更新 `skills.lock.json` 的 ref 并重跑 vendor。 +- [x] 7.4 确认本仓 markdown 门禁转绿(此时 `npx --no-install markdownlint-cli2 "**/*.md"` 应为 0 问题)。 ## 8. 发布 -- [ ] 8.1 运行 `python3 scripts/vendor/skill_vendor.py check --offline` 与在线 `check`。 -- [ ] 8.2 按 AGENTS.md 执行 `node scripts/bump-plugin.mjs codeguard minor`(含行为变更)。 -- [ ] 8.3 同步市场仓 `full-stack-plugins` 的 catalog 版本并重新生成三平台清单。 -- [ ] 8.4 提交并推送插件仓与市场仓。 +- [x] 8.1 运行 `python3 scripts/vendor/skill_vendor.py check --offline` 与在线 `check`。 +- [x] 8.2 按 AGENTS.md 执行 `node scripts/bump-plugin.mjs codeguard minor`(含行为变更)。 +- [x] 8.3 同步市场仓 `full-stack-plugins` 的 catalog 版本并重新生成三平台清单。 +- [x] 8.4 提交并推送插件仓与市场仓。 diff --git a/openspec/changes/2026-09-21-wire-cve-universal-fallback/.openspec.yaml b/openspec/changes/archive/2026-09-21-wire-cve-universal-fallback/.openspec.yaml similarity index 100% rename from openspec/changes/2026-09-21-wire-cve-universal-fallback/.openspec.yaml rename to openspec/changes/archive/2026-09-21-wire-cve-universal-fallback/.openspec.yaml diff --git a/openspec/changes/2026-09-21-wire-cve-universal-fallback/design.md b/openspec/changes/archive/2026-09-21-wire-cve-universal-fallback/design.md similarity index 100% rename from openspec/changes/2026-09-21-wire-cve-universal-fallback/design.md rename to openspec/changes/archive/2026-09-21-wire-cve-universal-fallback/design.md diff --git a/openspec/changes/2026-09-21-wire-cve-universal-fallback/proposal.md b/openspec/changes/archive/2026-09-21-wire-cve-universal-fallback/proposal.md similarity index 100% rename from openspec/changes/2026-09-21-wire-cve-universal-fallback/proposal.md rename to openspec/changes/archive/2026-09-21-wire-cve-universal-fallback/proposal.md diff --git a/openspec/changes/2026-09-21-wire-cve-universal-fallback/specs/cve-dependency-scan/spec.md b/openspec/changes/archive/2026-09-21-wire-cve-universal-fallback/specs/cve-dependency-scan/spec.md similarity index 100% rename from openspec/changes/2026-09-21-wire-cve-universal-fallback/specs/cve-dependency-scan/spec.md rename to openspec/changes/archive/2026-09-21-wire-cve-universal-fallback/specs/cve-dependency-scan/spec.md diff --git a/openspec/changes/2026-09-21-wire-cve-universal-fallback/tasks.md b/openspec/changes/archive/2026-09-21-wire-cve-universal-fallback/tasks.md similarity index 92% rename from openspec/changes/2026-09-21-wire-cve-universal-fallback/tasks.md rename to openspec/changes/archive/2026-09-21-wire-cve-universal-fallback/tasks.md index 01e6720..716d722 100644 --- a/openspec/changes/2026-09-21-wire-cve-universal-fallback/tasks.md +++ b/openspec/changes/archive/2026-09-21-wire-cve-universal-fallback/tasks.md @@ -42,7 +42,7 @@ ## 7. 发布 -- [ ] 7.1 运行 `python3 scripts/vendor/skill_vendor.py check --offline` 与在线 `check`(技能目录若有改动)。 -- [ ] 7.2 按 AGENTS.md 执行 `node scripts/bump-plugin.mjs codeguard minor`(新增能力,非破坏性)。 -- [ ] 7.3 同步市场仓 `full-stack-plugins` 的 catalog 版本并重新生成三平台市场清单。 -- [ ] 7.4 提交并推送插件仓与市场仓。 +- [x] 7.1 运行 `python3 scripts/vendor/skill_vendor.py check --offline` 与在线 `check`(技能目录若有改动)。 +- [x] 7.2 按 AGENTS.md 执行 `node scripts/bump-plugin.mjs codeguard minor`(新增能力,非破坏性)。 +- [x] 7.3 同步市场仓 `full-stack-plugins` 的 catalog 版本并重新生成三平台市场清单。 +- [x] 7.4 提交并推送插件仓与市场仓。 diff --git a/openspec/specs/cve-dependency-scan/spec.md b/openspec/specs/cve-dependency-scan/spec.md new file mode 100644 index 0000000..6f134ee --- /dev/null +++ b/openspec/specs/cve-dependency-scan/spec.md @@ -0,0 +1,95 @@ +# cve-dependency-scan Specification + +## Purpose +定义 `codeguard cve` 的生态覆盖边界:哪些生态必须给出可验证结论、无原生扫描器时如何兜底、生态标识如何被接受与报告、严重级别阈值如何统一作用于每个扫描器,以及「通过 / 存在漏洞 / 无法验证」三类结果如何判定与退出。 +## Requirements +### Requirement: Universal fallback for ecosystems without a native scanner + +当项目被识别到的语言不属于任何已有原生扫描器的生态时,系统 SHALL 使用通用扫描器给出结论,而不是报告「无可扫描生态」。 + +#### Scenario: 检测到无原生扫描器的生态 + +- **WHEN** 项目被识别为无原生扫描器的语言(例如 Go、PHP、Ruby),且未显式指定 `--ecosystem` +- **THEN** 通用扫描器运行,结果以独立的生态标识报告,且 `--severity` 阈值对其生效 + +#### Scenario: 通用扫描器未安装 + +- **WHEN** 走通用兜底但通用扫描器未安装 +- **THEN** 该生态结果标记为「无法验证」并给出安装提示,退出状态为「无法验证」而非「存在漏洞」 + +#### Scenario: 无任何可扫描内容 + +- **WHEN** 既无原生生态可扫,也无通用兜底可扫的内容 +- **THEN** 报告「无可扫描生态」,退出状态为「无法验证」,且该信息不得与生态标识非法混用同一文案 + +### Requirement: Native scanner precedence and explicit selection + +当项目属于已有原生扫描器的生态时,系统 SHALL 只使用该原生扫描器;通用兜底 SHALL NOT 与之并行运行。显式选择生态时,选择 SHALL 为替换而非追加。 + +#### Scenario: 原生扫描器优先 + +- **WHEN** 项目被识别为 java、node、python 或 rust +- **THEN** 只运行对应原生扫描器,通用扫描器不运行,结果中不出现重复生态 + +#### Scenario: 显式指定通用扫描 + +- **WHEN** 用户显式指定 `--ecosystem universal` +- **THEN** 只运行通用扫描器,不追加原生扫描器 + +#### Scenario: 原生工具缺失 + +- **WHEN** 原生生态已识别但对应扫描工具未安装 +- **THEN** 结果保持「无法验证」,不回退到通用扫描器替代原生生态 + +### Requirement: Ecosystem identifier canonicalization + +命令行接受的生态标识、扫描前置条件判定使用的标识、结果中报告的标识,SHALL 来自同一份权威映射,不得由多处各自维护。 + +#### Scenario: 别名被接受 + +- **WHEN** 用户传入已声明的别名(例如以 `java` 指代 `maven`) +- **THEN** 归一化到规范标识后正常扫描,结果中报告规范标识 + +#### Scenario: 未知标识被拒绝 + +- **WHEN** 用户传入未声明的生态标识 +- **THEN** 在任何扫描器启动前拒绝,错误信息列出全部可接受标识及其别名,且输出中不得出现「无可扫描生态」或「存在漏洞」 + +#### Scenario: 参数错误状态可区分 + +- **WHEN** 因生态标识非法而拒绝执行 +- **THEN** 退出状态既不等于「存在漏洞」(2)也不等于「无法验证」(1),使调用方不会把拼写错误误判为安全告警 + +### Requirement: Severity threshold means threshold-and-above + +`--severity` 指定的阈值 SHALL 被解释为「该级别及以上」,且 SHALL 以等价形式传达给每个扫描器。 + +#### Scenario: 降低阈值 + +- **WHEN** 用户传入 `--severity LOW` 或 `--severity MEDIUM` +- **THEN** 通用扫描器收到包含全部更高级别的完整严重级别集合,而不是只含该级别与最高级别的子集 + +#### Scenario: 默认与最高阈值无回归 + +- **WHEN** 阈值为默认的 `HIGH`,或为 `CRITICAL` +- **THEN** 实际下发给扫描器的级别集合与阈值语义一致 + +### Requirement: Result classification + +每个被扫描的生态 SHALL 恰好落入「通过」「存在漏洞」「无法验证」三类之一,三者在文本与 JSON 输出中均可区分,「无法验证」SHALL NOT 被计入「存在漏洞」。 + +#### Scenario: 三类结果混合 + +- **WHEN** 一次运行中同时存在通过、存在漏洞与无法验证的生态 +- **THEN** 摘要分别列出三类,退出状态以「存在漏洞」优先于「无法验证」 + +#### Scenario: 存在无法验证的生态 + +- **WHEN** 无生态存在漏洞,但至少一个生态无法验证 +- **THEN** 退出状态为「无法验证」,且输出明确声明该结果不能视为通过 + +#### Scenario: 全部通过 + +- **WHEN** 所有被扫描生态均通过且无无法验证的生态 +- **THEN** 退出状态为通过 + diff --git a/openspec/specs/language-gate-commands/spec.md b/openspec/specs/language-gate-commands/spec.md new file mode 100644 index 0000000..1a4f289 --- /dev/null +++ b/openspec/specs/language-gate-commands/spec.md @@ -0,0 +1,56 @@ +# language-gate-commands Specification + +## Purpose +定义语言注册表中每个条目所声明命令的可执行性要求:`lint` / `format` / `probe` 必须能以声明的方式真正运行,需要路径或文件参数时必须以显式占位符或 glob 表达;并定义语言声明配置前置条件的能力,使「项目未接入」与「检查失败」不再混为一谈。 +## Requirements +### Requirement: Declared commands must be runnable as written + +注册表声明的 `lint` / `format` / `probe` 命令 SHALL 能按声明形式直接执行;需要文件或路径参数的 SHALL 以 `{file}` 占位符或显式 glob 表达,不得依赖调用方补全。 + +#### Scenario: 缺少必需参数 + +- **WHEN** 某语言的 `lint` 命令在无参数调用下返回工具用法错误(而非 lint 结论) +- **THEN** 门禁不得把它作为「lint 失败」上报,因为该结果与仓库内容无关 + +#### Scenario: markdown 的 lint 命令 + +- **WHEN** 门禁在已接入 markdown 的项目上运行 +- **THEN** markdownlint 实际检查文件并以 lint 结论作为退出码,而不是返回用法错误 + +### Requirement: Probe must not confirm availability through a misinterpreted argument + +`probe` 命令 SHALL 使用目标工具真实支持的可用性查询方式。当命令中的 flag 不被工具识别、因而被解释为路径或 glob 参数时,SHALL NOT 据此判定工具可用。 + +#### Scenario: 无效 flag 被当成路径 + +- **WHEN** probe 命令包含该工具不认识的 flag,导致其被当作文件或 glob 处理并仍然成功退出 +- **THEN** 该探测结果不得被用作「工具已安装且可用」的证据 + +### Requirement: Auto-fix command must be executable and scoped + +`format` 命令 SHALL 可通过注册表声明的入口直接执行,包括在工具未全局安装时经包管理器解析;且 SHALL 明确其作用范围是单文件还是整个项目,不得使调用方无从判断影响面。 + +#### Scenario: 工具未全局安装 + +- **WHEN** `format` 命令引用一个未全局安装的工具 +- **THEN** 自动修复 SHALL 经包管理器解析执行,而不是以 command not found 失败 + +### Requirement: Languages may declare a configuration prerequisite + +注册表 SHALL 允许为语言声明 `requiresConfig`。对以风格偏好为主、其默认规则会大面积误报的工具(如 markdown、yaml),SHALL 声明该前置条件。 + +#### Scenario: 已声明前置条件且项目未接入 + +- **WHEN** 项目缺少该语言声明的配置文件 +- **THEN** 该语言判定为未接入 / 未验证,安全跳过且不阻塞提交,并在结果中说明未验证的原因 + +#### Scenario: 已声明前置条件且项目已接入 + +- **WHEN** 项目存在该语言声明的配置文件 +- **THEN** 门禁按该配置正常检查,结论作为 lint 结果上报 + +#### Scenario: 未声明前置条件的语言不受影响 + +- **WHEN** 某语言未声明 `requiresConfig` +- **THEN** 其行为与现状一致,不被本要求改变 + diff --git a/openspec/specs/language-registry-doc-sync/spec.md b/openspec/specs/language-registry-doc-sync/spec.md new file mode 100644 index 0000000..2e929d5 --- /dev/null +++ b/openspec/specs/language-registry-doc-sync/spec.md @@ -0,0 +1,51 @@ +# language-registry-doc-sync Specification + +## Purpose +定义 `docs/LANGUAGES.md` 与注册表之间的可复现关系:文档的全部内容都应由注册表与生成器产生,重跑生成器在注册表未变更时不得产生差异,且任一方向的不一致都必须可被检出,而不是静默存在。 +## Requirements +### Requirement: Documentation must be fully reproducible from the registry + +`docs/LANGUAGES.md` SHALL 能由注册表与生成器完全复现。生成器 SHALL 覆盖文档的全部内容;若存在有意手工维护的区段,该区段 SHALL 在文档中明确标注,且 SHALL 由生成器原样保留。 + +#### Scenario: 注册表未变更时重跑生成器 + +- **WHEN** 注册表自上次生成以来未发生变更 +- **THEN** 重跑生成器不产生任何差异 + +#### Scenario: 手工维护区段被保留 + +- **WHEN** 文档中存在已声明为手工维护的区段 +- **THEN** 重跑生成器后该区段内容保持不变 + +### Requirement: Documented commands must match the registry field by field + +文档中每个语言条目的 `lint` 与 `format` 命令 SHALL 与注册表逐字段一致,包括占位符与参数顺序。 + +#### Scenario: 表格行与注册表不一致 + +- **WHEN** 任一语言行的命令文本与注册表对应字段不同 +- **THEN** 校验报告该行,并指出两侧的实际取值 + +### Requirement: Drift must be detectable in both directions + +文档与注册表之间的不一致 SHALL 有检查手段可检出,且该检查 SHALL 同时覆盖「文档落后于注册表」与「文档领先于注册表」两种方向。 + +#### Scenario: 文档落后 + +- **WHEN** 注册表已更新而文档未重新生成 +- **THEN** 漂移检查失败并列出不一致条目 + +#### Scenario: 文档被手工前移 + +- **WHEN** 文档被手工修改,其内容为生成器无法产生 +- **THEN** 漂移检查同样失败,使该修改必须回落到注册表或生成器 + +### Requirement: Drift check must run in the existing gate + +漂移检查 SHALL 纳入既有的测试入口,与其余回归一起执行,无需额外的独立命令。 + +#### Scenario: 常规回归被执行 + +- **WHEN** 运行既有测试入口 +- **THEN** 文档与注册表的漂移检查包含在其中,且失败会以非零状态体现 +