opencode-ali-spec
v0.3.0
Published
阿里Java开发规范四层确定性约束插件:L1 规则常驻注入(项目约定化渲染)/ L3 写后 p3c 变更行检查 / L2 提交前后只读评审 / L4 CI 增量门禁;含自检、状态、存量豁免基线与 fail-loud 工具链
Maintainers
Readme
opencode-ali-spec —— 阿里Java开发规范约束插件 v0.3.0
把《阿里巴巴Java开发手册》1.3.0 终极版 + 黄山版 1.7.1 增补(共 322 条款)变成 opencode 里的四层确定性约束:可注入、可执行、可关闭、可记录、可审计。 适用:opencode v2(Bun 运行时)|技术栈:Java|工具链:p3c-pmd 2.1.1(fat jar 随包,内含 PMD 6.15,模式A)或 PMD 6.55.0(模式B,推荐/JDK 14+ 语法)+ Checkstyle 10.26.1(L4 侧)|Node ≥ 18(跑
.opencode/tools/*.mjs门禁脚本)
v0.3.0 变更摘要(试用反馈 → 根因 → 编号)
| 反馈 | 根因 | 0.3.0 对策(F 编号) |
|---|---|---|
| 接入后整体重排、修改记录被污染 | 规则方向写死(4 空格/LF),对存量 Tab/CRLF 项目全文件报错 | F-01 项目约定探测+F-02 项目化卡片+F-03 禁止存量重排+F-24 Checkstyle 模块按约定反向渲染 |
| 每轮注入 + 每次写文件检查 → 耗时与 token 上升 | 注入 8.3KB 全文 + 每次改文件起一次 JVM(且 CSV 跑两遍) | F-05 卡片瘦身(实测 8603→913 字符)+F-06 注入去重(同摘要 15 分钟不重发)+F-07 结果缓存(命中零 JVM)+F-08 触发策略/去抖+F-09 单 JVM 批量、去掉二次运行 |
| PMD 6.15(2019)对 JDK 14+ 新语法解析不可靠 | 引擎版本与项目 JDK 不匹配 | F-12 引擎双模式(A=6.15 兼容 / B=6.55 推荐 / auto 探测)+F-13 解析失败 fail-loud+F-15 JDK 支持矩阵+F-20 兼容性自检 |
| L2 不自动触发、每次全量评审 | 无变更集概念、无提交前钩子 | F-16 增量评审(git 变更 hunk)+F-17 提交前门禁(pre-commit hook)+F-26 CI 只扫变更文件 |
| Windows + Tab/CRLF 项目报 10 万+/6.9 万条 | 全局规则无视项目约定、缺存量豁免 | F-11 只判变更行+F-25 存量豁免基线+F-24 格式族模块替换(违规数由「行数」降为「文件数」)+F-28 回归夹具 |
| 规则样例本身的缺陷 | suppressions 写法错误(逗号分隔、绝对路径) | F-23 suppressions 正确样例(| 分隔、相对路径、禁 .*X$)+F-25 baseline 一键生成豁免 |
功能列表
| # | 功能 | 层 | 一句话说明 |
|---|---|---|---|
| 1 | 项目化红线注入 | L1 | 注入 .opencode/rules/00-红线项目化.md(≤1500 字符,含项目约定行;F-01/F-02/F-05);红线全表 77 条按需查阅,不再每轮铺开 |
| 2 | 全量规则文件 | L1 | 322 条款分 7 章(终极版 217 + 黄山版增补 105),判断型代码先读章文件(AGENTS.md 章节速查) |
| 3 | 写后自动检查(只判变更行) | L3 | edit/write/patch 落盘 .java → p3c-pmd → 违规分「变更行内(必须修)」与「存量(只登记)」回灌工具结果(F-03/F-11) |
| 4 | fail-loud 防护 | L3 | 工具链缺失/解析失败显式标"未检查"并给出修复命令,绝不静默跳过(F-13/F-20) |
| 5 | 一键体检 | L2 | /spec-check:默认只评审 git 变更 hunk(增量),--full 才全量(F-16) |
| 6 | 只读评审员 | L2 | @spec-reviewer:判断型条款逐条核对、L3 半可检信号误报复核;仅可写 .opencode/reports/ |
| 7 | 手动开关 | 控制 | 三层开关实时生效 + 触发策略(on-write / on-commit / manual / off,F-08) |
| 8 | 检查记录与缓存 | 审计 | history.jsonl 全量记录;内容哈希缓存 .gate-cache.json(命中零 JVM,F-07);违规全量 txt+csv;报告 TTL 治理(F-29) |
| 9 | 功能帮助 | UI | /spec-help 功能列表、/spec-status 开关/触发/引擎/约定/缓存/最近检查自查 |
| 10 | CI 门禁样例(变更文件) | L4 | maven-pmd + checkstyle(只扫本次变更 .java,F-26)+ enforcer + JaCoCo、Jenkins gate stage |
| 11 | 引擎双模式与自检 | L3 | check.engine = A\|B\|auto;spec-gate-cli.mjs selfcheck 一键体检 JDK/PMD/JAR/规则/约定(F-12/F-20) |
| 12 | 标准 suppressions 生成 | L4 | spec-gate-cli.mjs baseline 从 Checkstyle 报告生成合规 suppressions(| 分隔、相对路径、禁 .*X$,F-23/F-25) |
安装(本地)
方式 A:一键脚本(推荐,已验证机制——.opencode/plugins/ 启动自动加载)
powershell -ExecutionPolicy Bypass -File <包目录>\install.ps1 -Target D:\workspace\your-project
# 可选:-WithCi 同时装 CI 样例;-WithGithooks 装 pre-commit 增量门禁;-NoPluginJs 只装资产脚本做六件事:复制插件 JS 到 .opencode/plugins/ali-spec-gate.js → 复制 rules/commands/agents/tools → 按项目约定渲染 00-红线项目化.md 与 checkstyle-ali.xml → 写/提示合并 opencode.json(instructions 数组项 .opencode/rules/00-红线项目化.md;含 formatter 只格式化变更行配置)→ 写 AGENTS.md → 打印开关、触发策略与验证提示。
方式 B:npm 包路由(官方文档:config plugin 数组;opencode 启动时用 Bun 自动安装)
// opencode.json
{ "plugin": ["opencode-ali-spec"],
"instructions": [".opencode/rules/00-红线项目化.md"] }插件首次初始化会自动补齐缺失资产(rules/commands/agents/tools/AGENTS.md/opencode.json 模板;只补缺失、永不覆盖既有文件;{"provision": false} 可关闭自举),并按探测到的项目约定渲染卡片与 Checkstyle;instructions 数组项请按启动日志提示并入(插件不代改你的 opencode.json)。重启后 /spec-help、/spec-status 可用。
安装后三步(存量项目尤其重要)
node .opencode/tools/render-redlines.mjs --all—— 确认卡片与 checkstyle 与项目约定一致(Tab/CRLF 项目会看到属性id=ali-indent、id=ali-newline的反向规则)。node .opencode/tools/spec-gate-cli.mjs selfcheck—— 工具链自检;缺 PMD 时按提示装(bootstrap-pmd.ps1,推荐模式B = PMD 6.55.0)。node .opencode/tools/spec-gate-cli.mjs baseline——(存量项目)生成豁免基线,让存量违规不阻断,只拦新增。
配置(.opencode/spec-gate.json,全部键可省)
优先级:环境变量 > 项目配置文件 > 插件选项 > 内置默认。样例见 assets/spec-gate.sample.json。
| 键 | 默认 | 说明 |
|---|---|---|
| enabled | true | 总开关 |
| convention.indent | "auto" | auto\|tab\|space:2\|space:4\|space:8;auto 按 .editorconfig > .gitattributes > core.autocrlf > pom/gradle > 样本嗅探(F-01) |
| convention.newline | "auto" | auto\|lf\|crlf(F-01) |
| convention.scope | "changed-lines" | changed-lines\|whole-file(F-11) |
| check.trigger | "on-write" | on-write\|on-commit\|manual\|off(F-08) |
| check.budgetChars | 2000 | 单次回灌上限(0.2.x 为 8000;F-10) |
| check.changedOnly | true | 只判变更行(F-11) |
| check.cache | true | 内容哈希缓存(F-07) |
| check.engine | "auto" | A(p3c/PMD 6.15)|B(PMD 6.55)|auto(F-12) |
| check.languageVersion | "auto" | PMD 语言版本,auto 按 maven.compiler.source/.java-version 探测(F-12/F-15) |
| check.maxFilesPerPatch | 5 | 单次 patch 最多检查文件数 |
| check.digestLines | 40 | 回灌摘要行数上限 |
| review.onCommit | true | 提交前增量评审(需装钩子,F-17) |
| review.onSessionEnd | true | 会话结束前提示对未检查变更补跑(F-17) |
| reports.maxFilesPerDir | 300 | 报告目录文件数上限(F-29) |
| reports.maxAgeDays | 14 | 报告保留天数(F-29) |
| compat.legacyBehavior | "0.3" | 设 "0.2" 完全回退旧行为(排障用,D8) |
环境变量:ALI_SPEC_DISABLE=1(停用)、ALI_SPEC_JAVA、ALI_SPEC_PMD_HOME、ALI_SPEC_ENGINE=A|B、ALI_SPEC_TRIGGER=…、ALI_SPEC_SKIP_HOOK=1(绕过 pre-commit)。
发布到 opencode 插件仓库
opencode 无集中审核制"插件仓库":其插件生态 = npm 注册表(plugin 配置按包名自动安装)+ 官方 Ecosystem 页面(社区插件清单,opencode.ai/docs/ecosystem#plugins)。三条发布路径:
- 发布 npm(公共生态,覆盖面最大)
- 包名
opencode-ali-spec已核实未被占用(registry.npmjs.org 返回 404;npm view复查同样空闲); - 发布内容已
npm pack --dry-run验证(0.2.x 时 26 文件 / 7.7MB,含 jar、LICENSE、THIRD-PARTY-NOTICES.md;0.3.0 新增 tools/tests 后需复跑); - 账号注册(必须由账号所有者本人完成——需您的邮箱接收验证、实名归属与 2FA,任何工具不得代持);
- 发布(两种执行方式二选一):a. 您本机
npm login(浏览器授权)→npm publish→npm view opencode-ali-spec验证;b. 授权本会话用 Granular Token(仅本包写权限、设过期)→.npmrc引用执行npm publish,用后立即吊销; - 用户侧零手动安装:
"plugin": ["opencode-ali-spec"]→ 启动自动拉取 → 自举资产 → 重启生效。
- 包名
- 收录 Ecosystem(可选,等于"上架"):按 opencode.ai/docs/ecosystem 指引提 PR 加入社区插件清单。
- 企业内网(30 人团队更现实):私有 npm registry(Verdaccio/Nexus/Azure Artifacts,
npm publish --registry <内网源>),成员.npmrc指向内网源;无 registry 时 Git 直装。
版本纪律:semver;规则/判定字样变更沿用 kit 审查纪律(变更→审查→CHANGELOG);项目侧资产自举"只补缺失",强制更新资产需删旧文件或重跑 install.ps1;与 ali-spec-kit 版本锚点对齐登记。
验证:重启 opencode → 改一个 .java → 出现【L3·p3c 通过】或【L3·阿里规范违规 N 条(变更行内 M)】→ /spec-status 查看状态与记录。
手动开关与触发策略
| 层级 | 操作 | 场景 |
|---|---|---|
| 1. 环境变量 | ALI_SPEC_DISABLE=1(恢复:删除) | 临时排障/会话级 |
| 2. 配置文件(推荐) | .opencode/spec-gate.json 写 {"enabled": false};或 {"check":{"trigger":"on-commit"}} 改为提交前检查 | 项目级长期策略 |
| 3. 插件选项 | "plugin": ["opencode-ali-spec", {"enabled": false}] | 安装期声明(方式 B) |
关闭后钩子完全静默:不注入、不记录、不落盘。触发策略为 on-commit/manual 时,写入不再起 JVM,变更被登记进 pending.jsonl,由 pre-commit 钩子或 /spec-check 消费——交付前请自行跑 node .opencode/tools/spec-gate-cli.mjs changed。
日常使用
| 命令 | 作用 |
|---|---|
| /spec-check | 增量体检:git diff 变更 hunk → L3 机械 + L2 判断型逐条核对(默认不含存量) |
| /spec-check --full | 全量体检(存量项目慎用,结果量大) |
| /spec-status | 开关/触发/引擎/项目约定/缓存命中/最近检查 |
| node .opencode/tools/spec-gate-cli.mjs changed | 命令行:检查工作区变更 |
| node .opencode/tools/spec-gate-cli.mjs staged | 命令行:检查已 git add 的内容(pre-commit 钩子用这个) |
| node .opencode/tools/spec-gate-cli.mjs selfcheck | 工具链自检(JDK/PMD/JAR/规则/约定) |
| node .opencode/tools/spec-gate-cli.mjs baseline | 生成存量豁免基线(F-25) |
| pwsh .opencode/tools/install-githooks.ps1 | 安装 pre-commit 增量门禁 |
检查记录
- 位置:
.opencode/reports/;history.jsonl每行一个 JSON:{"ts":"...","plugin":"opencode-ali-spec/0.3.0","tool":"edit","file":"...","verdict":"pass|violation|violation-changed|toolchain-missing|error","changedLines":N,"violations":N,"changedViolations":N,"durationMs":N,"cached":false} - 待检登记:
pending.jsonl(trigger=on-commit/manual 时);缓存:.gate-cache.json(key=文件内容哈希+引擎+约定)。 - 违规时另有同时间戳全量报告
<时间戳>-<类名>.txt与规则名对照.csv。 - 治理:
powershell -File .opencode/tools/reports-ttl.ps1 -Days 14 -MaxFiles 300(含 jsonl 与缓存)。
卸载
删除 .opencode/plugins/ali-spec-gate.js(或把 spec-gate.json 设 enabled:false 停用不卸载);assets 按需清理;opencode.json 移除 instructions/plugin 数组项;pre-commit 钩子用 install-githooks.ps1 -Uninstall 移除。
已知边界
仅检查 .java 单文件(XML/SQL/pom/velocity 不在 L3 范围);patch 单次最多查 5 个 .java(超出显式告知);变更行判定依赖 git(非 git 目录退化为整文件);JDK 17/21 实测优先,模式 A(PMD 6.15)对 JDK 14+ 新语法可能解析失败——此时必须切模式B 或按提示声明"未检查";「注入不可绕过」≠「服从不可绕过」,服从性由 L2 评审与 L4 门禁兜底;强制条款机械可检上限 54.8%。完整边界见 ../P8_结项归档.md §五。
更新日志
- v0.3.0(变更行约束 + 项目约定 + 成本治理):针对真实项目试用反馈的六项根因改造。①项目约定优先:新增约定探测器(.editorconfig/.gitattributes/core.autocrlf/pom/样本)与
render-redlines.mjs,按约定反向渲染00-红线项目化.md与 Checkstyle(Tab 项目用属性id=ali-indent禁行首空格、CRLF 项目用id=ali-newline禁纯 LF 行尾),卡片 8603→913 字符;②只判变更行:git diff -U0计算变更行区间,违规分「变更行内(必须修复)」与「存量(只登记)」,禁止整文件重排;③成本治理:内容哈希缓存(命中零 JVM)、单 JVM 批量检查、去掉 CSV 二次运行、回灌预算 8000→2000 字符、触发策略 on-write/on-commit/manual/off;④引擎双模式:A=p3c-pmd 2.1.1(PMD 6.15)兼容 / B=PMD 6.55.0 推荐 / auto 探测,解析失败 fail-loud 并给出修复命令,新增selfcheck;⑤提交前门禁:install-githooks.ps1+ pre-commit 钩子(只查 staged 变更,ALI_SPEC_SKIP_HOOK=1可绕过),/spec-check默认增量;⑥存量接入:baseline生成标准 suppressions(|分隔、相对路径、禁.*X$—— 修正样例中用逗号与绝对路径的错误写法),CI 样例改为只扫变更文件;⑦新增只格式化变更行的format-changed.ps1。兼容:compat.legacyBehavior="0.2"可完全回退。 - v0.2.2(v2.0.27 事件结构适配修复):修复 v0.2.1 在 opencode v2.0.27 上的「静默失效」(加载正常但从不检查、注入不可见)。根因(v2.0.27 官方源码实证):① read/edit/write 的路径键是
input.path(无filePath),插件旧码读input.args.filePath恒空 →isJava()恒 false → 静默跳过;② 工具结果文本载体是event.result.content(string 或 Content 数组),result.output是结构化元数据(write →{operation,target,resource,existed}),写 output 既毁元数据又到不了模型;③ patch 工具在 v2 更名"patch"(input 键同为patchText)。修复:V2 适配层重写为「事件翻译 + content 注入」——path→filePath视图翻译、独立 sink 容器(V1 契约零改动)、完成后按 string/数组双形态追加result.content,绝不触碰result.output;patch 路由兼容新旧工具名。V1 路由与检查逻辑零改动。 - v0.2.1(v2 服务器兼容修复):修复 opencode v2 服务器加载失败
PluginModule.LoadError: Plugin must export a default definition with an id and an effect or setup function (SchemaError(Missing key at ["default"]))。新增 V2 默认导出{ id: "opencode-ali-spec", setup(ctx) };钩子经ctx.tool.hook("execute.after")注册(注入点event.result.output,实参event.input);V2 ctx 无 Bun$,PMD 执行改走child_process.execFile(180s 超时,GBK 兜底解码);项目根取ctx.location.project.canonical。配置建议:v2 服务器使用"plugins"键(v1 为"plugin")。 - v0.2.0(黄山版增补):基准扩展至《Java开发手册(黄山版)》1.7.1。真新增 105 条(强制 65/推荐 30/参考 10);新增 07-设计规约章;常驻红线 69→77;spec-reviewer 增 12 项核对点。差异全文见
../P9_黄山版差异解构.md。 - v0.1.0:首发。四层约束(L1 注入/L3 回灌/L2 评审/L4 CI)、三层开关、检查记录、本地与 npm 双安装路线。
