release-skill 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/plugins/marketplace.json +23 -0
- package/.claude-plugin/marketplace.json +16 -0
- package/.claude-plugin/plugin.json +10 -0
- package/.codex-plugin/plugin.json +26 -0
- package/CHANGELOG.md +68 -0
- package/CODE_OF_CONDUCT.md +76 -0
- package/CONTRIBUTING.md +49 -0
- package/INSTALL.md +182 -0
- package/LICENSE +21 -0
- package/NOTICE +25 -0
- package/README.md +501 -0
- package/README.zh-CN.md +463 -0
- package/SECURITY.md +48 -0
- package/adapters/claude/.claude-plugin/marketplace.json +16 -0
- package/adapters/claude/.claude-plugin/plugin.json +10 -0
- package/adapters/claude/skills/release-assess/SKILL.md +52 -0
- package/adapters/claude/skills/release-help/SKILL.md +60 -0
- package/adapters/claude/skills/release-prepare/SKILL.md +71 -0
- package/adapters/claude/skills/release-publish/SKILL.md +55 -0
- package/adapters/claude/skills/release-reconcile/SKILL.md +73 -0
- package/adapters/claude/skills/release-verify/SKILL.md +70 -0
- package/adapters/codex/.codex-plugin/plugin.json +26 -0
- package/adapters/codex/skills/release-assess/SKILL.md +52 -0
- package/adapters/codex/skills/release-help/SKILL.md +60 -0
- package/adapters/codex/skills/release-prepare/SKILL.md +71 -0
- package/adapters/codex/skills/release-publish/SKILL.md +55 -0
- package/adapters/codex/skills/release-reconcile/SKILL.md +73 -0
- package/adapters/codex/skills/release-verify/SKILL.md +70 -0
- package/bin/release-skill.mjs +743 -0
- package/native/safe-write/binding.gyp +40 -0
- package/native/safe-write/prebuilds.json +4 -0
- package/native/safe-write/src/safe_write.cc +2023 -0
- package/package.json +75 -0
- package/references/.render-manifest.json +33 -0
- package/references/00-target-state.md +124 -0
- package/references/01-state-machine.md +155 -0
- package/references/02-project-config.md +217 -0
- package/references/03-readme-quality.md +136 -0
- package/references/04-supply-chain.md +147 -0
- package/references/05-evidence-and-errors.md +164 -0
- package/references/06-adapter-contract.md +178 -0
- package/schemas/.render-manifest.json +37 -0
- package/schemas/approval-record.schema.json +115 -0
- package/schemas/artifact-lock.schema.json +111 -0
- package/schemas/artifact-plan.schema.json +52 -0
- package/schemas/artifact-policy.schema.json +76 -0
- package/schemas/evidence-event.schema.json +89 -0
- package/schemas/release-plan.schema.json +369 -0
- package/schemas/release-project.schema.json +359 -0
- package/schemas/release-run.schema.json +195 -0
- package/skills/release-assess/SKILL.md +52 -0
- package/skills/release-help/SKILL.md +60 -0
- package/skills/release-prepare/SKILL.md +71 -0
- package/skills/release-publish/SKILL.md +55 -0
- package/skills/release-reconcile/SKILL.md +73 -0
- package/skills/release-verify/SKILL.md +70 -0
- package/skills-src/release-assess/SKILL.md +52 -0
- package/skills-src/release-help/SKILL.md +60 -0
- package/skills-src/release-prepare/SKILL.md +71 -0
- package/skills-src/release-publish/SKILL.md +55 -0
- package/skills-src/release-reconcile/SKILL.md +73 -0
- package/skills-src/release-verify/SKILL.md +70 -0
- package/src/adapters/contract.mjs +214 -0
- package/src/adapters/git-github.mjs +214 -0
- package/src/adapters/npm.mjs +947 -0
- package/src/adapters/plugin-marketplace.mjs +1365 -0
- package/src/adapters/push-snapshot.mjs +216 -0
- package/src/artifacts/adoption.mjs +743 -0
- package/src/artifacts/artifact-plan.mjs +162 -0
- package/src/artifacts/entry.mjs +240 -0
- package/src/artifacts/git-authority.mjs +637 -0
- package/src/artifacts/graph.mjs +189 -0
- package/src/artifacts/inspect.mjs +520 -0
- package/src/artifacts/inventory.mjs +192 -0
- package/src/artifacts/merge/binary.mjs +77 -0
- package/src/artifacts/merge/entry-merge.mjs +228 -0
- package/src/artifacts/merge/json.mjs +641 -0
- package/src/artifacts/merge/markdown.mjs +246 -0
- package/src/artifacts/merge/regions.mjs +156 -0
- package/src/artifacts/merge/text.mjs +432 -0
- package/src/artifacts/merge/tree.mjs +202 -0
- package/src/artifacts/merge/yaml.mjs +669 -0
- package/src/artifacts/path-key.mjs +94 -0
- package/src/artifacts/policy.mjs +319 -0
- package/src/artifacts/producer-registry.mjs +439 -0
- package/src/artifacts/project-lock.mjs +732 -0
- package/src/artifacts/resolution.mjs +658 -0
- package/src/artifacts/safe-fs-backend-internal.mjs +680 -0
- package/src/artifacts/safe-fs.mjs +72 -0
- package/src/artifacts/state.mjs +495 -0
- package/src/artifacts/transaction-journal.mjs +983 -0
- package/src/artifacts/transaction.mjs +1361 -0
- package/src/commands/approve.mjs +280 -0
- package/src/commands/artifacts.mjs +627 -0
- package/src/commands/assess.mjs +838 -0
- package/src/commands/prepare.mjs +1377 -0
- package/src/commands/publish.mjs +883 -0
- package/src/commands/reconcile.mjs +1255 -0
- package/src/commands/verify.mjs +915 -0
- package/src/core/approval.mjs +332 -0
- package/src/core/baseline.mjs +272 -0
- package/src/core/blackbox-hard-gates.mjs +142 -0
- package/src/core/config.mjs +448 -0
- package/src/core/digest.mjs +90 -0
- package/src/core/errors.mjs +113 -0
- package/src/core/evidence.mjs +167 -0
- package/src/core/hooks.mjs +241 -0
- package/src/core/node-version.mjs +64 -0
- package/src/core/plan.mjs +735 -0
- package/src/core/previous-public-baseline.mjs +204 -0
- package/src/core/run.mjs +681 -0
- package/src/core/state-machine.mjs +76 -0
- package/src/core/version-consistency.mjs +111 -0
- package/src/producers/build-adapters.mjs +231 -0
- package/src/producers/render-public-assets.mjs +152 -0
- package/src/producers/sync-skills.mjs +96 -0
- package/src/readme/contract.mjs +297 -0
- package/src/readme/examples.mjs +288 -0
- package/src/readme/parity.mjs +122 -0
- package/src/snapshot/export.mjs +99 -0
- package/src/snapshot/frozen.mjs +401 -0
- package/src/snapshot/manifest.mjs +207 -0
- package/src/snapshot/public-map.mjs +1459 -0
- package/src/snapshot/public-path.mjs +110 -0
- package/src/snapshot/scan.mjs +419 -0
package/package.json
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "release-skill",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Safe preparation and frozen GitHub/npm production publishing with full happy end verification",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/mzdbxqh/release-skill.git"
|
|
8
|
+
},
|
|
9
|
+
"homepage": "https://github.com/mzdbxqh/release-skill#readme",
|
|
10
|
+
"bugs": {
|
|
11
|
+
"url": "https://github.com/mzdbxqh/release-skill/issues"
|
|
12
|
+
},
|
|
13
|
+
"type": "module",
|
|
14
|
+
"bin": {
|
|
15
|
+
"release-skill": "./bin/release-skill.mjs"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
".agents/",
|
|
19
|
+
".claude-plugin/",
|
|
20
|
+
".codex-plugin/",
|
|
21
|
+
"bin/",
|
|
22
|
+
"src/",
|
|
23
|
+
"skills/",
|
|
24
|
+
"skills-src/",
|
|
25
|
+
"adapters/",
|
|
26
|
+
"references/",
|
|
27
|
+
"schemas/",
|
|
28
|
+
"native/",
|
|
29
|
+
"!native/safe-write/build/",
|
|
30
|
+
"README.md",
|
|
31
|
+
"README.zh-CN.md",
|
|
32
|
+
"CHANGELOG.md",
|
|
33
|
+
"CODE_OF_CONDUCT.md",
|
|
34
|
+
"CONTRIBUTING.md",
|
|
35
|
+
"INSTALL.md",
|
|
36
|
+
"LICENSE",
|
|
37
|
+
"NOTICE",
|
|
38
|
+
"SECURITY.md"
|
|
39
|
+
],
|
|
40
|
+
"scripts": {
|
|
41
|
+
"build": "node --check src/**/*.mjs",
|
|
42
|
+
"test": "node --test test/*.test.mjs",
|
|
43
|
+
"test:no-dogfood": "node --test $(ls test/*.test.mjs | grep -v -E 'dogfood|artifacts-safe-fs-native-seam')",
|
|
44
|
+
"typecheck": "node --check src/**/*.mjs bin/*.mjs",
|
|
45
|
+
"sync:skills": "node scripts/sync-skills.mjs",
|
|
46
|
+
"sync:skills:check": "node scripts/sync-skills.mjs --check",
|
|
47
|
+
"build:adapters": "node scripts/build-adapters.mjs",
|
|
48
|
+
"build:adapters:check": "node scripts/build-adapters.mjs --check",
|
|
49
|
+
"native:build": "node-gyp rebuild --directory native/safe-write",
|
|
50
|
+
"native:build:test": "GYP_DEFINES='test_seam=1' node-gyp rebuild --directory native/safe-write",
|
|
51
|
+
"native:test": "npm run native:build:test && node --expose-gc --test test/artifacts-safe-fs-native-seam.test.mjs && npm run native:build && RELEASE_SKILL_NATIVE_DEV=1 node --test test/artifacts-safe-fs.test.mjs test/artifacts-transaction-native.test.mjs && node --input-type=module -e \"import {createRequire} from 'node:module';const a=createRequire(import.meta.url)('./native/safe-write/build/Release/safe_write.node');const k=Object.keys(a).sort();const e=['abortTemp','chmod','close','createTemp','fsync','mkdir','openDir','openRoot','readEntry','readFile','rename','rmdir','unlink'];if(k.length!==e.length||k.some((v,i)=>v!==e[i])){console.error('Production exports mismatch:',k);process.exit(1)}console.log('Production exports verified:',k.length,'functions')\""
|
|
52
|
+
},
|
|
53
|
+
"dependencies": {
|
|
54
|
+
"ajv": "8.20.0",
|
|
55
|
+
"ajv-formats": "3.0.1",
|
|
56
|
+
"libnpmpublish": "11.1.0",
|
|
57
|
+
"npm-registry-fetch": "18.0.2",
|
|
58
|
+
"yaml": "2.9.0"
|
|
59
|
+
},
|
|
60
|
+
"devDependencies": {
|
|
61
|
+
"node-gyp": "12.3.0"
|
|
62
|
+
},
|
|
63
|
+
"engines": {
|
|
64
|
+
"node": ">=22.0.0"
|
|
65
|
+
},
|
|
66
|
+
"keywords": [
|
|
67
|
+
"release",
|
|
68
|
+
"publish",
|
|
69
|
+
"governance",
|
|
70
|
+
"skill",
|
|
71
|
+
"claude-code",
|
|
72
|
+
"codex"
|
|
73
|
+
],
|
|
74
|
+
"license": "MIT"
|
|
75
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"source": "standards",
|
|
3
|
+
"files": {
|
|
4
|
+
"00-target-state.md": {
|
|
5
|
+
"digest": "d66f8c33b2df2bbcb235ce123f786c18c19b3a797197495793d9af566618099d",
|
|
6
|
+
"bytes": 6335
|
|
7
|
+
},
|
|
8
|
+
"01-state-machine.md": {
|
|
9
|
+
"digest": "4004aece5729059397ef5eeac554827afc16a468ae4c6180da12fdd29228ed95",
|
|
10
|
+
"bytes": 7770
|
|
11
|
+
},
|
|
12
|
+
"02-project-config.md": {
|
|
13
|
+
"digest": "6c8d6262e5fe9c034ad961b01b8fed684adb6272a7ce4c0e4dd87bfb061519ac",
|
|
14
|
+
"bytes": 7017
|
|
15
|
+
},
|
|
16
|
+
"03-readme-quality.md": {
|
|
17
|
+
"digest": "d74e41052592443ebbd450d0ace5f9b9b19c7a94db50f952b17c1c5a4c5dc230",
|
|
18
|
+
"bytes": 4977
|
|
19
|
+
},
|
|
20
|
+
"04-supply-chain.md": {
|
|
21
|
+
"digest": "c3ef50a4b27c049c118d8c51c0d35cfb2b0f5a35ccc2c9bfa7fda4018ead0a1c",
|
|
22
|
+
"bytes": 4682
|
|
23
|
+
},
|
|
24
|
+
"05-evidence-and-errors.md": {
|
|
25
|
+
"digest": "63987751b6d3a74f02033d4e23daa1f3c30d299827de9d8242b425887607b2ac",
|
|
26
|
+
"bytes": 6658
|
|
27
|
+
},
|
|
28
|
+
"06-adapter-contract.md": {
|
|
29
|
+
"digest": "f727bfbdcd2bd6f95edc144a4fd61732ecaac2a49ffda296dbf6923f14a0c2f1",
|
|
30
|
+
"bytes": 6890
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# 00 -- 目标状态
|
|
2
|
+
|
|
3
|
+
本文档定义 release-skill 发布治理系统的目标拓扑、组件边界、设计原则和明确不做清单。所有规范性规则仅在此出现一次;关联领域的细节通过交叉引用指向对应标准。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. 发布链路拓扑
|
|
8
|
+
|
|
9
|
+
首版支持以下发布链路:
|
|
10
|
+
|
|
11
|
+
```text
|
|
12
|
+
父工程
|
|
13
|
+
-> 一个或多个公开 GitHub 子仓库
|
|
14
|
+
-> GitHub Release
|
|
15
|
+
-> 可选 npm publish
|
|
16
|
+
-> Claude Code / Codex 插件 marketplace 校验
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
PyPI、Cargo、Docker 等发布目标不在首版范围内,但 registry adapter 必须可以扩展。
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 2. 仓库架构与组件边界
|
|
24
|
+
|
|
25
|
+
```text
|
|
26
|
+
release-skill/
|
|
27
|
+
├── standards/ # 通用发布规范的唯一权威来源
|
|
28
|
+
├── research/ # 开源项目与本地项目调研证据
|
|
29
|
+
├── schemas/ # 项目配置、发布计划、执行证据 schema
|
|
30
|
+
├── packages/release-skill/ # 可公开发布的插件子工程
|
|
31
|
+
│ ├── skills/
|
|
32
|
+
│ ├── scripts/
|
|
33
|
+
│ ├── references/
|
|
34
|
+
│ └── adapters/
|
|
35
|
+
├── fixtures/ # 不同成熟度项目和负向场景
|
|
36
|
+
├── scripts/ # 父工程渲染、泄漏审计、公开发布
|
|
37
|
+
├── docs/ # 设计、计划、评审和迁移报告
|
|
38
|
+
└── public-release.json # 本项目自身 dogfooding 配置
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### 2.1 规范层
|
|
42
|
+
|
|
43
|
+
`standards/` 是状态机(见 `01-state-machine.md`)、授权、配置(见 `02-project-config.md`)、版本、公开快照、文档质量(见 `03-readme-quality.md`)、供应链安全(见 `04-supply-chain.md`)、错误分类与恢复协议(见 `05-evidence-and-errors.md`)和 adapter 契约(见 `06-adapter-contract.md`)的唯一权威来源。
|
|
44
|
+
|
|
45
|
+
公开插件需要的 reference 从该目录确定性渲染,禁止人工维护两个规范副本。
|
|
46
|
+
|
|
47
|
+
### 2.2 确定性事务内核
|
|
48
|
+
|
|
49
|
+
内核负责读取配置、归一化 profile、生成和校验发布计划、构建公开快照、运行验证门、查询远端状态、执行发布检查点并写入结构化证据。内核不得依赖 Agent 自由拼接 shell 命令。
|
|
50
|
+
|
|
51
|
+
### 2.3 Skill 族
|
|
52
|
+
|
|
53
|
+
首版至少提供以下公开 Skill:
|
|
54
|
+
|
|
55
|
+
- `release-help`:用户可发现入口;完成依赖和环境检查、能力说明、最小示例、只读诊断、dry-run 和故障诊断引导。
|
|
56
|
+
- `release-assess`:识别项目拓扑,评估公开文档、配置、供应链和发布流程距目标状态的差距。
|
|
57
|
+
- `release-prepare`:补齐已授权的本地配置与文档,运行发布门并冻结发布计划,但不产生外部写操作。
|
|
58
|
+
- `release-publish`:只读取已批准且未过期的发布计划,执行外部发布检查点。
|
|
59
|
+
- `release-reconcile`:查询远端实际状态,处理部分成功、安全重试和发布后验证。
|
|
60
|
+
|
|
61
|
+
入口 Skill 保持轻量,只编排确定性脚本和指向细分 Skill,不复制业务执行协议。默认不执行破坏性操作,写入前遵守用户授权并保护已有文件。
|
|
62
|
+
|
|
63
|
+
### 2.4 Adapter 与 profile
|
|
64
|
+
|
|
65
|
+
标准 adapter 包括:
|
|
66
|
+
|
|
67
|
+
- Git 与公开 GitHub 子仓库
|
|
68
|
+
- GitHub Release
|
|
69
|
+
- npm registry
|
|
70
|
+
- Claude Code plugin marketplace
|
|
71
|
+
- Codex plugin manifest/marketplace
|
|
72
|
+
|
|
73
|
+
首版 profile 包括:
|
|
74
|
+
|
|
75
|
+
- `skill-plugin`
|
|
76
|
+
- `npm-package`
|
|
77
|
+
- `split-public-repos`
|
|
78
|
+
- `hybrid-plugin-npm`
|
|
79
|
+
|
|
80
|
+
profile 只提供默认配置,最终必须归一化为同一 schema(见 `02-project-config.md`),不能包含另一套发布流程。
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## 3. 设计原则
|
|
85
|
+
|
|
86
|
+
以下八条原则贯穿 release-skill 全部组件,各标准文档通过交叉引用遵守而不再重复全文。
|
|
87
|
+
|
|
88
|
+
| 编号 | 原则 | 约束 |
|
|
89
|
+
|---|---|---|
|
|
90
|
+
| P-1 | 发布计划显式化 | 版本、发布单元、目标仓库、tag、包、验证命令和外部写操作必须进入可审阅、可冻结的发布计划(见 `01-state-machine.md` PREPARED 阶段)。 |
|
|
91
|
+
| P-2 | 准备与发布分离 | 任何用户都可以安全运行只读诊断和 dry-run;外部写操作只接受绑定到冻结计划的明确授权(见 `01-state-machine.md` APPROVED 阶段、`06-adapter-contract.md` 授权门)。 |
|
|
92
|
+
| P-3 | 确定性内核优先 | Agent 负责诊断、解释、生成计划和引导恢复;文件导出、hash、远端冲突检查、发布检查点和证据写入由脚本完成(见 `05-evidence-and-errors.md`)。 |
|
|
93
|
+
| P-4 | 项目声明差异 | 通用流程不理解某个项目的业务规则,项目只声明发布单元、版本来源、命令 hooks 和增量安全要求(见 `02-project-config.md`)。 |
|
|
94
|
+
| P-5 | 最小权限与可追溯性 | GitHub Actions 权限按 job 收紧;npm 优先 trusted publishing 和 provenance;第三方 Action 固定到 commit SHA(见 `04-supply-chain.md`)。 |
|
|
95
|
+
| P-6 | 部分成功可恢复 | GitHub、Git 和 npm 无法构成原子事务,系统必须保留检查点并从实际远端状态继续,不得盲目回滚或从头重跑(见 `01-state-machine.md` PARTIAL 状态、`06-adapter-contract.md` 幂等重试)。 |
|
|
96
|
+
| P-7 | README 是产品界面 | README 的可理解性、可操作性和命令新鲜度是发布硬门,不是"文件存在"检查(见 `03-readme-quality.md`)。 |
|
|
97
|
+
| P-8 | 保护既有工作 | 不得 reset、clean、restore、checkout 或 stash 用户变更;跨项目评估默认只读。 |
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## 4. 明确不做
|
|
102
|
+
|
|
103
|
+
以下事项在 release-skill v1 中明确排除:
|
|
104
|
+
|
|
105
|
+
1. 不在本轮修改四个参考项目(artifact-graph、agent-method-registry、loop-agent、flow-architect)的工作树。
|
|
106
|
+
2. 不在本轮实际发布 GitHub/npm 资源。
|
|
107
|
+
3. 不首版实现 PyPI、Cargo、Docker adapter。
|
|
108
|
+
4. 不要求所有项目采用 Conventional Commits。
|
|
109
|
+
5. 不让项目 hook 覆盖通用安全门(见 `02-project-config.md` overlay 限制、`04-supply-chain.md`)。
|
|
110
|
+
6. 不把父工程私有路径、调研过程或本机绝对路径发布到公开插件。
|
|
111
|
+
7. 配置及生成产物不得包含 `<project-root>/...` 等本机绝对路径。
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## 5. 交叉引用索引
|
|
116
|
+
|
|
117
|
+
| 领域 | 标准文档 |
|
|
118
|
+
|---|---|
|
|
119
|
+
| 状态与转换 | `01-state-machine.md` |
|
|
120
|
+
| 配置 schema、hooks、profile、overlay、waiver | `02-project-config.md` |
|
|
121
|
+
| README 质量门 | `03-readme-quality.md` |
|
|
122
|
+
| 供应链安全 | `04-supply-chain.md` |
|
|
123
|
+
| 错误码、证据格式、脱敏 | `05-evidence-and-errors.md` |
|
|
124
|
+
| Adapter 接口与授权门 | `06-adapter-contract.md` |
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# 01 -- 状态机
|
|
2
|
+
|
|
3
|
+
本文档定义 release-skill 发布生命周期的全部状态、合法转换、禁止转换和异常处理规则。设计原则见 `00-target-state.md`。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. 状态定义
|
|
8
|
+
|
|
9
|
+
发布生命周期包含 7 个主状态和 3 个异常状态,共计 10 个状态。
|
|
10
|
+
|
|
11
|
+
### 1.1 主状态
|
|
12
|
+
|
|
13
|
+
| 状态 | 含义 | 进入条件 |
|
|
14
|
+
|---|---|---|
|
|
15
|
+
| **DISCOVERED** | 系统首次识别到一个可发布项目 | 通过配置文件发现或用户指定项目根目录 |
|
|
16
|
+
| **ASSESSED** | 项目拓扑、配置、文档、供应链和发布流程已完成只读评估 | `assess` 命令成功退出 |
|
|
17
|
+
| **PREPARED** | 发布门全部通过,发布计划已冻结写入磁盘 | `prepare` 命令成功退出,所有门均通过,计划 schema 验证通过 |
|
|
18
|
+
| **APPROVED** | 人工审阅并批准了冻结的发布计划 | 批准记录绑定到发布计划 hash,且未过期 |
|
|
19
|
+
| **PUBLISHING** | 外部写操作正在按检查点依次执行 | `publish` 命令读取已批准计划并开始执行 |
|
|
20
|
+
| **PUBLISHED** | 所有发布检查点均已成功完成 | 最后一个检查点的 `observe` 验证通过 |
|
|
21
|
+
| **VERIFIED** | 发布后验证全部通过 | `verify` 命令在全新环境中完成安装、调用、泄漏审计和远端一致性校验 |
|
|
22
|
+
|
|
23
|
+
### 1.2 异常状态
|
|
24
|
+
|
|
25
|
+
| 状态 | 含义 | 进入条件 |
|
|
26
|
+
|---|---|---|
|
|
27
|
+
| **NEEDS_INPUT** | 缺少会改变发布结果的用户选择或授权 | 配置中存在歧义、版本来源未确定或需要额外授权 |
|
|
28
|
+
| **BLOCKED** | 认证、权限、验证门或外部服务阻止继续,且没有安全的本地替代路径 | 认证缺失(AUTH_MISSING)、远端服务不可达或权限不足 |
|
|
29
|
+
| **PARTIAL** | 至少一个外部检查点已经成功,但发布单元尚未全部完成 | `publish` 在中途失败且已有检查点成功 |
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## 2. 合法转换
|
|
34
|
+
|
|
35
|
+
以下表格列出全部合法的状态转换。不在表中的转换均为禁止转换。
|
|
36
|
+
|
|
37
|
+
| 源状态 | 目标状态 | 触发条件 |
|
|
38
|
+
|---|---|---|
|
|
39
|
+
| DISCOVERED | ASSESSED | `assess` 成功完成 |
|
|
40
|
+
| DISCOVERED | NEEDS_INPUT | 发现歧义或缺失用户输入 |
|
|
41
|
+
| ASSESSED | PREPARED | `prepare` 所有门通过且计划冻结 |
|
|
42
|
+
| ASSESSED | NEEDS_INPUT | 评估发现需要用户输入 |
|
|
43
|
+
| ASSESSED | BLOCKED | 认证缺失或外部服务阻止 |
|
|
44
|
+
| PREPARED | APPROVED | 人工批准记录创建,且计划 hash、tree hash、目标版本和远端冲突状态均未变化 |
|
|
45
|
+
| PREPARED | NEEDS_INPUT | 计划需要补充信息 |
|
|
46
|
+
| APPROVED | PUBLISHING | `publish` 读取未过期批准并开始执行 |
|
|
47
|
+
| APPROVED | PREPARED | 批准过期或计划变更导致批准失效,回退到重新准备 |
|
|
48
|
+
| PUBLISHING | PUBLISHED | 所有检查点成功 |
|
|
49
|
+
| PUBLISHING | PARTIAL | 至少一个检查点成功但后续失败 |
|
|
50
|
+
| PUBLISHING | BLOCKED | 外部服务阻断且无法继续 |
|
|
51
|
+
| PUBLISHED | VERIFIED | `verify` 全部通过 |
|
|
52
|
+
| PUBLISHED | POST_PUBLISH_VERIFY_FAILED | 发布后验证失败(保留 PUBLISHED 事实但标记验证失败) |
|
|
53
|
+
| NEEDS_INPUT | DISCOVERED | 用户提供输入后重新开始评估 |
|
|
54
|
+
| NEEDS_INPUT | ASSESSED | 用户提供输入后恢复评估 |
|
|
55
|
+
| BLOCKED | ASSESSED | 阻断因素解除后重新评估 |
|
|
56
|
+
| BLOCKED | PUBLISHING | 阻断因素解除后从检查点恢复 |
|
|
57
|
+
| PARTIAL | PUBLISHING | `reconcile` 从记录的检查点恢复执行 |
|
|
58
|
+
| PARTIAL | VERIFIED | `reconcile` 补齐剩余步骤且 `verify` 通过 |
|
|
59
|
+
| VERIFIED | DISCOVERED | 新版本周期开始 |
|
|
60
|
+
|
|
61
|
+
### 2.1 自动转换规则
|
|
62
|
+
|
|
63
|
+
以下转换在条件满足时自动触发,无需人工干预:
|
|
64
|
+
|
|
65
|
+
- APPROVED -> PREPARED:当批准记录的计划 hash 与当前冻结计划不匹配时,批准自动失效。
|
|
66
|
+
- APPROVED -> PREPARED:当 plan digest、Git tree hash、workspace digest、目标版本或已批准 action 列表变化时,批准自动失效。
|
|
67
|
+
- PUBLISHING -> PARTIAL:当任一检查点成功后下一检查点失败时,自动计算 PARTIAL 状态。
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## 3. 禁止转换
|
|
72
|
+
|
|
73
|
+
以下转换在任何条件下均不允许:
|
|
74
|
+
|
|
75
|
+
| 禁止转换 | 原因 |
|
|
76
|
+
|---|---|
|
|
77
|
+
| DISCOVERED -> PREPARED | 必须先完成评估 |
|
|
78
|
+
| DISCOVERED -> APPROVED | 必须先评估再准备再批准 |
|
|
79
|
+
| DISCOVERED -> PUBLISHING | 未评估未准备不能发布 |
|
|
80
|
+
| ASSESSED -> APPROVED | 必须先通过 prepare 生成冻结计划 |
|
|
81
|
+
| ASSESSED -> PUBLISHING | 必须先准备并获得批准 |
|
|
82
|
+
| PREPARED -> PUBLISHING | 未获批准不能发布 |
|
|
83
|
+
| PREPARED -> VERIFIED | 不能跳过发布直接验证 |
|
|
84
|
+
| APPROVED -> VERIFIED | 不能跳过发布直接验证 |
|
|
85
|
+
| APPROVED -> PUBLISHED | 不能跳过发布执行直接到已发布 |
|
|
86
|
+
| PUBLISHING -> VERIFIED | 发布完成后必须先到 PUBLISHED |
|
|
87
|
+
| PUBLISHING -> APPROVED | 发布进行中不能回退到批准 |
|
|
88
|
+
| PUBLISHING -> PREPARED | 发布进行中不能回退到准备 |
|
|
89
|
+
| PUBLISHED -> PUBLISHING | 已发布的不能重新发布同一计划 |
|
|
90
|
+
| PUBLISHED -> APPROVED | 不能从已发布回退到批准 |
|
|
91
|
+
| VERIFIED -> PUBLISHING | 已验证的不能重新发布 |
|
|
92
|
+
| VERIFIED -> PUBLISHED | 已验证的不能回退到已发布 |
|
|
93
|
+
| NEEDS_INPUT -> PUBLISHING | 缺少输入不能发布 |
|
|
94
|
+
| BLOCKED -> PUBLISHING(非恢复路径) | 阻断状态只能通过 `reconcile` 恢复 |
|
|
95
|
+
| PARTIAL -> VERIFIED(非 reconcile 路径) | 部分成功必须经过 `reconcile` 补齐 |
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## 4. 异常处理
|
|
100
|
+
|
|
101
|
+
### 4.1 NEEDS_INPUT 处理
|
|
102
|
+
|
|
103
|
+
- 系统必须明确列出缺失的输入项、影响范围和可选方案。
|
|
104
|
+
- NEEDS_INPUT 不能被静默转换为 VERIFIED。
|
|
105
|
+
- 用户提供输入后,系统从 DISCOVERED 或 ASSESSED 重新开始。
|
|
106
|
+
|
|
107
|
+
### 4.2 BLOCKED 处理
|
|
108
|
+
|
|
109
|
+
- 系统必须记录阻断原因、相关错误码(见 `05-evidence-and-errors.md`)和建议的解除方式。
|
|
110
|
+
- BLOCKED 不能被静默转换为 VERIFIED。
|
|
111
|
+
- 阻断因素解除后,系统从 ASSESSED 重新评估或从 PUBLISHING 恢复。
|
|
112
|
+
|
|
113
|
+
### 4.3 PARTIAL 处理
|
|
114
|
+
|
|
115
|
+
- 系统必须保留至少一个已成功的外部检查点记录,不得丢失。
|
|
116
|
+
- PARTIAL 状态在任何后续操作前必须被显式处理。
|
|
117
|
+
- 恢复路径通过 `reconcile` 命令执行:查询远端实际状态,跳过已一致的步骤,仅重试安全且未完成的步骤。
|
|
118
|
+
- 系统不得自动删除远端 tag、覆盖 GitHub Release、unpublish npm 包或从头重跑。
|
|
119
|
+
- 远端状态与冻结计划不一致时(REMOTE_CONFLICT),停止并要求人工决策。
|
|
120
|
+
|
|
121
|
+
### 4.4 批准失效
|
|
122
|
+
|
|
123
|
+
批准记录绑定到发布计划 hash。以下任何变化均导致批准自动失效:
|
|
124
|
+
|
|
125
|
+
- 发布计划内容变化(plan digest 不匹配)。
|
|
126
|
+
- Git tree hash 变化。
|
|
127
|
+
- 工作区 digest 变化。
|
|
128
|
+
- 目标版本变化。
|
|
129
|
+
- 已批准的 action 列表变化。
|
|
130
|
+
|
|
131
|
+
远端冲突状态(如 tag 已存在、npm 版本冲突等)不在 approval 绑定字段中;它在 publish/reconcile 的 preflight 阶段阻断执行并要求人工决策。
|
|
132
|
+
|
|
133
|
+
失效后系统回退到 PREPARED 状态,要求重新批准。
|
|
134
|
+
|
|
135
|
+
### 4.5 发布检查点失败
|
|
136
|
+
|
|
137
|
+
发布按以下检查点顺序执行(详见 `06-adapter-contract.md`):
|
|
138
|
+
|
|
139
|
+
1. 推送父工程版本提交(若配置管理该步骤)。
|
|
140
|
+
2. 更新并推送公开子仓库快照。
|
|
141
|
+
3. 创建并推送签名或可追溯 tag。
|
|
142
|
+
4. 发布 npm 包。
|
|
143
|
+
5. 创建 GitHub Release。
|
|
144
|
+
6. 写入远端 URL、commit、tag、包版本、integrity 和执行结果。
|
|
145
|
+
|
|
146
|
+
任一步失败都停止后续动作,保存检查点并进入 PARTIAL。已完成的检查点通过 `observe` 验证后在 `reconcile` 中幂等跳过。
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## 5. 跨标准引用
|
|
151
|
+
|
|
152
|
+
- 配置中的状态声明和 hook 参数约束见 `02-project-config.md`。
|
|
153
|
+
- 错误码与证据格式见 `05-evidence-and-errors.md`。
|
|
154
|
+
- Adapter 的 preflight/execute/observe/verify 接口和授权门见 `06-adapter-contract.md`。
|
|
155
|
+
- 发布计划冻结和批准界面内容要求见本文档第 4.4 节和 `06-adapter-contract.md` 第 3 节。
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
# 02 -- 项目配置
|
|
2
|
+
|
|
3
|
+
本文档定义 `.release-skill/project.yaml` 的 schema 规范、hooks 参数约束、profile 归一化、overlay 限制和 waiver 边界。状态机见 `01-state-machine.md`,安全要求见 `04-supply-chain.md`,错误码见 `05-evidence-and-errors.md`。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. 配置文件位置与格式
|
|
8
|
+
|
|
9
|
+
项目使用 `.release-skill/project.yaml` 声明发布事实。
|
|
10
|
+
|
|
11
|
+
- 格式:YAML 1.2,兼容 JSON。
|
|
12
|
+
- 编码:UTF-8,无 BOM。
|
|
13
|
+
- 不得包含 YAML alias(`*anchor`)或重复键。
|
|
14
|
+
- 不得包含 `<project-root>/...` 等本机绝对路径。
|
|
15
|
+
- 配置摘要(SHA-256)基于规范化 JSON 计算:递归排序对象键、保持数组顺序、序列化为 UTF-8 JSON。
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 2. 顶层 schema
|
|
20
|
+
|
|
21
|
+
```yaml
|
|
22
|
+
apiVersion: release-skill/v1
|
|
23
|
+
kind: ReleaseProject
|
|
24
|
+
|
|
25
|
+
project:
|
|
26
|
+
name: <string> # 项目标识,必填
|
|
27
|
+
defaultBranch: <string> # 默认分支,必填
|
|
28
|
+
|
|
29
|
+
releaseUnits: # 发布单元数组,至少 1 个
|
|
30
|
+
- id: <string> # 唯一标识
|
|
31
|
+
source: <string> # 源码相对路径(相对项目根目录)
|
|
32
|
+
publicRepo: <string> # 公开仓库 owner/repo
|
|
33
|
+
version:
|
|
34
|
+
source: <string> # 版本来源,如 "package.json"
|
|
35
|
+
tagTemplate: <string> # tag 模板,如 "artifact-graph-v{version}"
|
|
36
|
+
distributions: # 分发渠道数组
|
|
37
|
+
- type: <string> # "npm" | "claude-plugin" | "codex-plugin"
|
|
38
|
+
package: <string> # npm 包名(type 为 npm 时必填)
|
|
39
|
+
publicFiles: # 公开源码镜像的显式闭世界映射
|
|
40
|
+
- from: <string> # 项目根相对路径
|
|
41
|
+
to: <string> # 公开仓库中的发布单元相对路径
|
|
42
|
+
mode: preserve # 保留源内容和可执行位
|
|
43
|
+
requiredPublicFiles: # 本发布单元不可缺失的目标路径
|
|
44
|
+
- <string>
|
|
45
|
+
previousPublicBaseline: # 必填;每个 unit 独立声明
|
|
46
|
+
mode: none # none | bound
|
|
47
|
+
# bound 时还必须提供 repo/ref/commit,可选 tree/manifestDigest
|
|
48
|
+
|
|
49
|
+
hooks: # 可选,命令 hooks
|
|
50
|
+
docs: <hook>
|
|
51
|
+
build: <hook>
|
|
52
|
+
test: <hook>
|
|
53
|
+
typecheck: <hook>
|
|
54
|
+
lint: <hook>
|
|
55
|
+
|
|
56
|
+
policy: # 可选,安全策略
|
|
57
|
+
forbiddenPaths: [<string>]
|
|
58
|
+
forbiddenContentPatterns: [<string>]
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## 3. 公开源码镜像与分发包
|
|
64
|
+
|
|
65
|
+
`releaseUnits[].publicFiles` 定义 GitHub 公开源码镜像的显式、闭世界 allowlist。每个映射都必须可审阅;未列出的文件不会因为目录扫描、模板重生成或历史惯例而被自动加入。`releaseUnits[].requiredPublicFiles` 只约束同一发布单元,不能借用其他单元的目标路径。
|
|
66
|
+
|
|
67
|
+
公开源码镜像与 distribution pack 是两条不同边界:前者决定公开仓库快照,后者由 npm `files`、插件 manifest 等渠道合同决定安装内容。发布前必须分别冻结、比较并验证两条边界;distribution pack 中的必需路径必须由该发布单元的公开映射覆盖。
|
|
68
|
+
|
|
69
|
+
持续发布只复制已批准 mapping 指向的冻结源快照,不生成 README、slogan 或其他人工内容,也不以模板重新覆盖它们。人工修改一旦进入权威源,就作为下一轮迭代的输入保留。若公开目标仓库与冻结计划出现差异,系统停止写入并等待人工选择 merge、adopt 或 reject;不得静默采用任一侧,也不得从头生成文件。
|
|
70
|
+
|
|
71
|
+
### 3.1 前序公开基线与人工权威源
|
|
72
|
+
|
|
73
|
+
每个 `releaseUnits[]` 必须显式声明 `previousPublicBaseline`:
|
|
74
|
+
|
|
75
|
+
- 确认从未发布过公开版本时使用 `mode: none`。它不是跳过冲突检查的开关;publish
|
|
76
|
+
仍会在任何 execute 前检查目标 branch、tag、GitHub Release 和 npm version 唯一性。
|
|
77
|
+
- 已有公开版本时使用 `mode: bound`,并填写精确的 `repo`、不可变 `ref` 和
|
|
78
|
+
`commit`。生产 prepare 必须使用 `--online --production`,逐 unit 观察
|
|
79
|
+
ref→commit mapping;offline production 不得冻结未观察的 bound 基线。
|
|
80
|
+
|
|
81
|
+
本地 human-owned 文件是下一轮发布内容的权威源;前序公开基线是冲突检测输入;
|
|
82
|
+
冻结 snapshot 是本轮审批和发布的唯一字节来源。默认 Git observer 只调用
|
|
83
|
+
`git ls-remote` 取得 ref→commit 映射,因此 commit 不一致时可提供 mapping diff,
|
|
84
|
+
但没有下载远端文件,必须把 content diff 明确标记为 unavailable,不能声称已经比较内容。
|
|
85
|
+
|
|
86
|
+
出现漂移时由人工选择:`merge`(合并双方修改)、`adopt`(采用远端修改)或
|
|
87
|
+
`reject`(拒绝远端修改)。无论选择 merge 还是 adopt,决定采用的内容都必须先合并回
|
|
88
|
+
human-owned 权威源,然后重新 prepare、审阅并 approve;后续环节只复制和冻结这些
|
|
89
|
+
字节,不重新生成或覆盖 README、slogan 及其他人工修改。
|
|
90
|
+
|
|
91
|
+
旧的 `policy.requiredPublicFiles` 已不支持。加载器必须返回 `CONFIG_INVALID`,并引导迁移到各自的 `releaseUnits[].requiredPublicFiles`。
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## 4. Hooks 参数约束
|
|
96
|
+
|
|
97
|
+
每个 hook 必须是对象,包含以下属性:
|
|
98
|
+
|
|
99
|
+
| 属性 | 类型 | 必填 | 约束 |
|
|
100
|
+
|---|---|---|---|
|
|
101
|
+
| `command` | 字符串数组 | 是 | 至少 1 个元素;每个元素为字符串;第一个元素为可执行文件路径或名称;**不接受 shell 字符串** |
|
|
102
|
+
| `cwd` | 字符串 | 否 | 相对路径,不得以 `/` 开头,不得包含 `..` |
|
|
103
|
+
| `timeoutMs` | 整数 | 否 | 最小 1000,最大 7200000(2 小时) |
|
|
104
|
+
| `envAllowlist` | 字符串数组 | 否 | 每个元素匹配 `^[A-Z_][A-Z0-9_]*$`;无重复元素 |
|
|
105
|
+
|
|
106
|
+
hook 执行规则:
|
|
107
|
+
|
|
108
|
+
- 使用 `execFile`,不使用 `exec` 或 `{ shell: true }`。
|
|
109
|
+
- 通过 `realpath` 解析 cwd,拒绝逃逸到项目根目录之外。
|
|
110
|
+
- 超时后杀死子进程,返回 `HOOK_TIMEOUT` 错误码。
|
|
111
|
+
- 进程环境仅包含 `PATH`、平台必需进程变量和 allowlist 中声明的变量。
|
|
112
|
+
|
|
113
|
+
示例:
|
|
114
|
+
|
|
115
|
+
```yaml
|
|
116
|
+
hooks:
|
|
117
|
+
test:
|
|
118
|
+
command: [pnpm, test]
|
|
119
|
+
cwd: .
|
|
120
|
+
timeoutMs: 300000
|
|
121
|
+
envAllowlist: [CI]
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## 5. Profile(规划中)
|
|
127
|
+
|
|
128
|
+
> **当前状态:** Profile 尚未实现,`project.yaml` 不支持 `profile` 字段。
|
|
129
|
+
> 以下为设计规划,不可写入当前配置文件。
|
|
130
|
+
|
|
131
|
+
profile 是预设的默认配置模板,提供常见发布拓扑的开箱配置。
|
|
132
|
+
|
|
133
|
+
### 5.1 首版 profile 列表
|
|
134
|
+
|
|
135
|
+
| profile | 适用场景 |
|
|
136
|
+
|---|---|
|
|
137
|
+
| `skill-plugin` | 纯 Claude/Codex 插件发布 |
|
|
138
|
+
| `npm-package` | 纯 npm 包发布 |
|
|
139
|
+
| `split-public-repos` | 父工程 + 多公开子仓库 |
|
|
140
|
+
| `hybrid-plugin-npm` | 插件与 npm 包混合发布 |
|
|
141
|
+
|
|
142
|
+
### 5.2 归一化规则
|
|
143
|
+
|
|
144
|
+
- profile 只提供默认配置值。
|
|
145
|
+
- 最终必须归一化为同一 schema,不能包含另一套发布流程。
|
|
146
|
+
- 项目显式声明的字段覆盖 profile 默认值。
|
|
147
|
+
- 归一化后的配置摘要必须稳定:相同的项目声明和 profile 组合产生相同的摘要。
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## 6. Overlay 限制(规划中)
|
|
152
|
+
|
|
153
|
+
> **当前状态:** Overlay 尚未实现,`project.yaml` 不支持 `overlay` 字段。
|
|
154
|
+
> 以下为设计规划,不可写入当前配置文件。
|
|
155
|
+
|
|
156
|
+
项目 overlay 可以收紧通用规则(增加更严格的要求),但不能:
|
|
157
|
+
|
|
158
|
+
- 关闭 secret 扫描。
|
|
159
|
+
- 关闭发布计划摘要校验。
|
|
160
|
+
- 关闭显式授权门。
|
|
161
|
+
- 关闭发布后验证。
|
|
162
|
+
- 使 hook 接受 shell 字符串。
|
|
163
|
+
- 使用本机绝对路径。
|
|
164
|
+
|
|
165
|
+
违反上述限制的 overlay 在配置加载时拒绝,返回 `CONFIG_INVALID` 错误码。
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## 7. Waiver 边界(规划中)
|
|
170
|
+
|
|
171
|
+
> **当前状态:** Waiver 尚未实现,`project.yaml` 不支持 `waiver` 字段。
|
|
172
|
+
> 以下为设计规划,不可写入当前配置文件。
|
|
173
|
+
|
|
174
|
+
当需要绕过某项安全门时,必须使用 waiver 机制:
|
|
175
|
+
|
|
176
|
+
### 7.1 Waiver 必填字段
|
|
177
|
+
|
|
178
|
+
| 字段 | 说明 |
|
|
179
|
+
|---|---|
|
|
180
|
+
| `rule` | 被豁免的规则标识 |
|
|
181
|
+
| `reason` | 豁免理由,不得为空 |
|
|
182
|
+
| `responsible` | 责任人,不得为空 |
|
|
183
|
+
| `expiresAt` | 失效日期,不得为空,不得晚于 30 天 |
|
|
184
|
+
|
|
185
|
+
### 7.2 展示要求
|
|
186
|
+
|
|
187
|
+
- Waiver 在批准界面必须显著展示。
|
|
188
|
+
- 过期的 waiver 自动失效,对应的规则恢复强制执行。
|
|
189
|
+
- Waiver 不适用于以下不可豁免项:secret 扫描、计划摘要校验、显式授权、发布后验证。
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## 8. 配置验证
|
|
194
|
+
|
|
195
|
+
配置加载时执行以下验证:
|
|
196
|
+
|
|
197
|
+
1. YAML 语法正确,无 alias 和重复键。
|
|
198
|
+
2. `apiVersion` 为 `release-skill/v1`。
|
|
199
|
+
3. `kind` 为 `ReleaseProject`。
|
|
200
|
+
4. `project.name` 非空。
|
|
201
|
+
5. `releaseUnits` 至少包含 1 个元素。
|
|
202
|
+
6. 每个 `releaseUnit.id` 全局唯一。
|
|
203
|
+
7. 每个 `releaseUnit.source` 路径在项目中存在。
|
|
204
|
+
8. 所有 hook 的 `command` 为数组且第一个元素非空。
|
|
205
|
+
9. 所有 hook 的 `cwd` 不包含绝对路径前缀和 `..`。
|
|
206
|
+
10. 所有路径字段不包含 `<project-root>/` 前缀。
|
|
207
|
+
|
|
208
|
+
验证失败返回 `CONFIG_INVALID` 错误码,附带具体失败原因。
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## 9. 跨标准引用
|
|
213
|
+
|
|
214
|
+
- 状态机中的状态定义和转换规则见 `01-state-machine.md`。
|
|
215
|
+
- 供应链安全中的最小权限和 Action 固定要求见 `04-supply-chain.md`。
|
|
216
|
+
- 错误码定义见 `05-evidence-and-errors.md`。
|
|
217
|
+
- Adapter 接口见 `06-adapter-contract.md`。
|