@agile-team/wl-skills-gate 0.9.1 → 0.11.0

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.
Files changed (64) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +20 -27
  3. package/bin/wl-quality-setup.js +18 -0
  4. package/bin/wl-skills-gate.js +24 -5
  5. package/docs/06-gitlab.md +21 -32
  6. package/docs/07-jenkins.md +48 -43
  7. package/docs/16-project-ci-integration.md +6 -6
  8. package/docs/17-onboarding.md +39 -11
  9. package/docs/19-nine-dimension-review.md +7 -1
  10. package/docs/README.md +2 -2
  11. package/fixtures/onboarding/managed-assets-0.10.0/java-unit.mjs +84 -0
  12. package/fixtures/onboarding/managed-assets-0.10.0/project-actions.mjs +266 -0
  13. package/lib/automation.js +87 -11
  14. package/lib/ci-prepare.js +91 -0
  15. package/lib/control-service.js +20 -7
  16. package/lib/deployment.js +4 -4
  17. package/lib/governance-notifications.js +7 -0
  18. package/lib/governance.js +27 -2
  19. package/lib/onboard-complete.js +35 -3
  20. package/lib/onboard-config.js +138 -12
  21. package/lib/onboard-registry.js +8 -2
  22. package/lib/onboard.js +2 -1
  23. package/lib/release-input.js +135 -0
  24. package/lib/release-review.js +120 -0
  25. package/lib/release-set.js +57 -8
  26. package/lib/setup-central.js +369 -0
  27. package/lib/setup-modes.js +84 -0
  28. package/lib/setup.js +160 -0
  29. package/lib/workspace-init.js +307 -0
  30. package/package.json +3 -2
  31. package/scripts/lib-tests/automation.test.mjs +7 -1
  32. package/scripts/lib-tests/ci-prepare.test.mjs +24 -0
  33. package/scripts/lib-tests/control-service.test.mjs +14 -0
  34. package/scripts/lib-tests/deployment.test.mjs +6 -4
  35. package/scripts/lib-tests/onboard-complete.test.mjs +4 -2
  36. package/scripts/lib-tests/onboard-registry.test.mjs +33 -1
  37. package/scripts/lib-tests/onboard.test.mjs +1 -0
  38. package/scripts/lib-tests/prevention-ci-chain.test.mjs +139 -0
  39. package/scripts/lib-tests/prevention-full-system.test.mjs +133 -0
  40. package/scripts/lib-tests/prevention-governance-chain.test.mjs +198 -0
  41. package/scripts/lib-tests/prevention-project-chain.test.mjs +395 -0
  42. package/scripts/lib-tests/release-input.test.mjs +186 -0
  43. package/scripts/lib-tests/setup-central.test.mjs +239 -0
  44. package/scripts/lib-tests/setup.test.mjs +71 -0
  45. package/scripts/lib-tests/workspace-init.test.mjs +271 -0
  46. package/scripts/test-support/release-review-fixture.mjs +32 -0
  47. package/templates/ci/Jenkinsfile +38 -1
  48. package/templates/ci/Jenkinsfile.release-sign +1 -0
  49. package/templates/ci/gitlab-backend.yml +6 -1
  50. package/templates/ci/gitlab-frontend.yml +6 -2
  51. package/templates/launchers/setup.cmd +8 -0
  52. package/templates/launchers/setup.command +8 -0
  53. package/templates/launchers/setup.sh +8 -0
  54. package/templates/onboarding/automation/ide-tasks.json +70 -8
  55. package/templates/onboarding/automation/project-actions.mjs +43 -7
  56. package/templates/onboarding/automation/workspace-setup.mjs +72 -0
  57. package/templates/onboarding/backend/java-unit.mjs +1 -1
  58. package/templates/onboarding/backend/quality-tools.package.json +1 -1
  59. package/templates/onboarding/legacy/managed-assets.json +36 -0
  60. package/templates/platform/README.md +8 -2
  61. package/templates/platform/deployment-config.json +8 -2
  62. package/templates/platform/release-input-config.json +54 -0
  63. package/templates/platform/release-review-trust.json +46 -0
  64. package/templates/quality/rules.lock.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## [0.11.0] — 2026-10-16
2
+
3
+ - 修复早期warning摘要未被常驻任务消费、首次来源失联/回流异常静默及旧环境复验可复用的断链,增加可靠执行异常与恢复提醒。
4
+ - 正式构建前自动按SHA选择中央最新九维Review并重查CI;组合签发与部署强制重验真实签名、独立授权及原件,旧组合需补证重新生成。
5
+ - CI按中央批准工作副本清单/锁准备依赖,禁任意生命周期脚本,仅用固定必要适配;质量报告与Review失败均保留原件。
6
+ - 已接项目按受管资产摘要批准升级,保留自定义策略、必测与POM;复用已提交自有版本锁并由实际首扫核验,修复当前Review草稿入口路径。
7
+
8
+ ## [0.10.0] — 2026-10-15
9
+
10
+ - 新增可启动的质量接入菜单和跨系统启动器,首次接入逐阶段展示、确认、执行、复扫与HTML反馈,不再要求人工传递计划摘要。
11
+ - 新增已接项目工作副本清单与独立初始化:固定锁安装、恢复本机Hook、实际正反验收,保留项目自定义策略;IDE打开任务只读预检。
12
+ - 新增中央接线预检与受控启动,核对配置、来源、身份、凭据存在性、密钥/状态绑定与回流;默认不联网、不启动、不发送,独立Review签发保持分离。
13
+ - 新增组合发布输入生成器,从可信采集原件生成并固定实际字节摘要,确认前后及签发前复核漂移,不代替业务决策、Review授权或部署。
14
+
1
15
  ## [0.9.1] — 2026-10-15
2
16
 
3
17
  - 重写 README:按实际能力梳理定位、接入步骤、使用场景与验证入口,完整细节保留在对应手册。
package/README.md CHANGED
@@ -33,44 +33,35 @@ Gate 是质量执行与裁决层,复用项目已有检查器和适用的 WL
33
33
 
34
34
  ## 快速接入
35
35
 
36
- 由技术经理在**实际 Git 项目根目录**接入一次。准备 Node.js ≥22.12、项目固定的包管理器和原有构建工具;安装源使用团队批准的 HTTPS registry。
36
+ 技术经理拿到批准的 Gate 完整包后,打开 `templates/launchers/setup.command`(macOS)、`setup.cmd`(Windows)或 `setup.sh`(Linux),按菜单选择任务。先提供 Node.js ≥22.12、项目固定的包管理器及原有构建工具。
37
37
 
38
- ### 1. 预览项目接入计划
38
+ | 任务 | 人只需做什么 | 脚本完成什么 |
39
+ | --- | --- | --- |
40
+ | 首次接入项目 | 选择 Git 项目根、批准安装源,确认各阶段差异 | 识别范围、安装固定依赖、同步规则、Hook、POM/锁、首扫及提交说明正反验证 |
41
+ | 新成员初始化 | 选择已接项目,在安装与激活计划上确认 | 按仓库已提交清单恢复本机环境,保留项目策略,再验真实 Hook |
42
+ | 运维接线 | 选择批准配置目录,预检后选择启动 | 核对配置/身份/凭据存在性/旧状态,启动中央采集与操作入口;消息默认预览 |
43
+ | 组合发布输入 | 选择批准配置,确认组件与输出 | 从真实采集原件生成输入,核验来源、SHA、制品与兼容证据 |
44
+
45
+ 也可用一个命令启动相同交互流程;进入后无需复制计划摘要或拼接后续命令:
39
46
 
40
47
  ```bash
41
- npx --yes @agile-team/wl-skills-gate@latest onboard \
42
- --root . --complete --registry https://registry.npmjs.org
48
+ npx --yes --ignore-scripts --registry https://registry.npmjs.org/ \
49
+ --@agile-team:registry=https://registry.npmjs.org/ \
50
+ @agile-team/wl-skills-gate@0.11.0 setup project
43
51
  ```
44
52
 
45
- 查看识别的项目类型、依赖版本、文件差异、Hook 和阻断项。脚本与模板随 Gate 包交付,无需从文档复制拼装。
46
-
47
53
  | 项目 | 依赖装在哪里 | 业务构建 |
48
54
  | --- | --- | --- |
49
- | PC Vue 管理端,如 `wl-ui-produce` | 项目 `package.json`:Gate / Kit / UI | 保留原前端构建 |
50
- | Java/Maven,如 `wl-produce` | `quality-tools/package.json`:Gate / BD | 保留 Maven,Node 工具不进入 jar |
51
-
52
- `quality-tools/` 只是 Java 仓库里的 Node 工具依赖目录。内置后端配套针对 `wl-produce` PL 模块;其他 Maven 项目先由负责人配置模块与必测。移动端、UniApp 不套用 PC 配套。
53
-
54
- ### 2. 确认并应用这份计划
55
+ | PC Vue 管理端,如 `wl-ui-produce` | 根 `package.json`:Gate / Kit / UI | 保留原前端构建 |
56
+ | Java/Maven,如 `wl-produce` | `quality-tools/package.json`:Gate / BD | Maven;Node 工具不进入 jar |
55
57
 
56
- ```bash
57
- npx --yes @agile-team/wl-skills-gate@latest onboard \
58
- --root . --complete --registry https://registry.npmjs.org \
59
- --apply --plan-hash "<本次返回的 planHash>" --confirm
60
- ```
58
+ `quality-tools/` 是 Java 仓库内的 Node 工具依赖目录。内置后端配套针对 `wl-produce` PL;其他 Maven 项目先由负责人配置模块与必测。移动端、UniApp 不套用 PC 配套。
61
59
 
62
- 程序按计划安装固定依赖、同步规则、配置 Hook、执行首扫与提交说明正反验证。首次安装后如出现原生规则或 POM 新差异,会返回新的待确认阶段;用同一入口重新预览、确认后续跑。
60
+ 已接项目升级仍选同一接入任务:识别旧受管脚本并展示差异,保留项目自定义策略、必测和 POM。
63
61
 
64
- ### 3. 验证本地与远端效果
62
+ 首次接入反馈在 `quality-reports/setup/<sessionId>/result.html`,质量报告在 `quality-reports/quality-report.html`。只有真实首扫及 Hook 正反验证通过,才返回 `local-validated-awaiting-remote-acceptance`。GitLab/Jenkins 强制检查、独立 Review、真实到群及部署另做现场验收。
65
63
 
66
- | 验收点 | 成功依据 |
67
- | --- | --- |
68
- | 本地接入 | 返回 `local-validated-awaiting-remote-acceptance`;首扫通过、合规提交说明通过、违规说明被拦截 |
69
- | 首份质量报告 | 打开 `quality-reports/quality-report.html`;结构化结果在 `quality-summary.json` |
70
- | 接入执行记录 | `quality-reports/onboarding/execution.json` 显示本次实际阶段与结果 |
71
- | 远端强制检查 | 按下节接线,在真实 MR / 构建中验证失败拒绝、通过放行与消息送达 |
72
-
73
- 本地接入通过后,再完成 CI、Review、通知和部署验收。完整步骤与状态说明见 [接入指南](./docs/17-onboarding.md)。
64
+ 接线配置、非交互任务参数与失败处理见 [接入指南](./docs/17-onboarding.md)。
74
65
 
75
66
  ## 日常怎么用
76
67
 
@@ -97,6 +88,8 @@ npx --yes @agile-team/wl-skills-gate@latest onboard \
97
88
  | 真实 CI 证据、身份与 Review | [可信 CI 采集](./docs/18-ci-source.md) · [九维 Review](./docs/19-nine-dimension-review.md) | 旧报告、缺证据、自审与过期批准被拒绝 |
98
89
  | 飞书通知、认领、超时与复验 | [中央执行接线](./templates/platform/README.md) | 实际送达、失败重试、认领和独立关闭均留记录 |
99
90
 
91
+ 流水线按批准的工作副本清单和依赖锁准备环境,不运行任意生命周期脚本。构建前自动匹配本次 SHA 的正式 Review 并重查 CI;组合与部署再次核验签名及原件,缺失就阻断。普通警告按周期汇总,首次采集故障、持续异常和恢复也有提醒。
92
+
100
93
  项目检查作业与受控签发、部署、通知作业隔离。Hook 提供早反馈;服务端强制检查负责防绕过。
101
94
 
102
95
  ## 按需深入
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ import { createInterface } from "node:readline/promises";
3
+ import { runSetupCli } from "../lib/setup.js";
4
+
5
+ try {
6
+ let args = process.argv.slice(2);
7
+ if (!args.length) {
8
+ if (!process.stdin.isTTY || !process.stdout.isTTY) throw new Error("启动菜单需要交互终端;自动任务请明确指定 project/workspace/central/release-input 及其预览/确认参数");
9
+ console.log("\nWL · WORLD LEADING | 质量工程接入\n\n1 首次接入项目\n2 初始化已接项目的本机环境\n3 运维接线预检\n4 启动中央采集与操作入口(消息预览)\n5 生成组合发布输入\nEnter 退出\n");
10
+ const prompt = createInterface({ input: process.stdin, output: process.stdout });
11
+ const choice = (await prompt.question("请选择:")).trim(); prompt.close();
12
+ const modes = { "1": ["project"], "2": ["workspace"], "3": ["central"], "4": ["central", "--start", "--watch"], "5": ["release-input"] };
13
+ if (!choice) process.exit(0);
14
+ if (!modes[choice]) throw new Error("请选择1到5");
15
+ args = modes[choice];
16
+ }
17
+ process.exitCode = await runSetupCli(args);
18
+ } catch (error) { console.error(`[quality-setup] ${error.message}`); process.exitCode = 2; }
@@ -18,7 +18,7 @@ function options(allowed) {
18
18
  const name = rest[i];
19
19
  if (!name.startsWith("--")) { out.positional.push(name); continue; }
20
20
  if (!allowed.includes(name) || Object.hasOwn(out, name)) throw new Error(`未知或重复参数: ${name}`);
21
- if (FLAGS.has(name)) { out[name] = true; continue; }
21
+ if (FLAGS.has(name) || command === "ci-prepare" && name === "--apply") { out[name] = true; continue; }
22
22
  const value = rest[++i];
23
23
  if (!value || value.startsWith("--")) throw new Error(`参数 ${name} 缺少值`);
24
24
  out[name] = value;
@@ -76,6 +76,25 @@ try {
76
76
  } else if (command === "onboard") {
77
77
  const { runOnboardCli } = await import("../lib/onboard.js");
78
78
  process.exitCode = await runOnboardCli(rest);
79
+ } else if (command === "setup") {
80
+ const { runSetupCli } = await import("../lib/setup.js");
81
+ process.exitCode = await runSetupCli(rest);
82
+ } else if (command === "ci-prepare") {
83
+ const o = options(["--root", "--apply", "--confirm", "--expect-workspace-hash", "--expect-lock-hash"]);
84
+ if (o.positional.length || !o["--apply"] && o["--confirm"]) throw new Error("ci-prepare 默认只读;执行需 --apply --confirm 及中央批准清单/锁摘要");
85
+ const { planCiPreparation, prepareCiDependencies } = await import("../lib/ci-prepare.js");
86
+ const result = o["--apply"] ? prepareCiDependencies({ root: o["--root"], confirm: !!o["--confirm"], expectWorkspaceHash: o["--expect-workspace-hash"], expectLockHash: o["--expect-lock-hash"] }) : planCiPreparation({ root: o["--root"] });
87
+ process.stdout.write(JSON.stringify(result, null, 2) + "\n");
88
+ process.exitCode = result.status === "blocked" ? 2 : 0;
89
+ } else if (command === "verify-release-review") {
90
+ const o = options(["--config", "--project", "--sha", "--record", "--evidence-root", "--publication-dir", "--out-dir"]);
91
+ if (o.positional.length) throw new Error("verify-release-review 不接受位置参数");
92
+ for (const key of ["--config", "--project", "--sha"]) if (!o[key]) throw new Error(`verify-release-review 缺少 ${key}`);
93
+ if (o["--publication-dir"] && (o["--record"] || o["--evidence-root"]) || !o["--publication-dir"] && (!o["--record"] || !o["--evidence-root"])) throw new Error("选择中央 --publication-dir 自动匹配本次SHA;或维护者明确提供 --record 与 --evidence-root,两种方式不能混用");
94
+ const review = await import("../lib/release-review.js");
95
+ if (o["--out-dir"] && !o["--publication-dir"]) throw new Error("--out-dir 仅用于自动选择后的本次CI重查证据");
96
+ const result = o["--publication-dir"] ? await review.selectReleaseReview({ configFile: o["--config"], project: o["--project"], sha: o["--sha"], publicationDir: o["--publication-dir"], outDir: o["--out-dir"] }) : review.verifyReleaseReview({ configFile: o["--config"], project: o["--project"], sha: o["--sha"], recordFile: o["--record"], evidenceRoot: o["--evidence-root"] });
97
+ process.stdout.write(JSON.stringify(Object.fromEntries(["status", "project", "sha", "reviewId", "reviewerId", "authorId", "recordHash", "reviewDigest", "bodyDigest", "evidenceDigest", "sourceDigest", "trustHash", "liveVerified", "liveCheckDirectory"].filter((key) => result[key] !== undefined).map((key) => [key, result[key]])), null, 2) + "\n");
79
98
  } else if (command === "doctor") {
80
99
  const o = options(["--root", "--kind", "--out"]);
81
100
  if (o.positional.length) throw new Error("doctor 不接受位置参数");
@@ -126,11 +145,11 @@ try {
126
145
  const result = collectReviewEvidence({ configFile: o["--config"], sourceFile: o["--source"], inputFile: o["--input"], recordFile: o["--record"], evidenceRoot: o["--evidence-root"], outDir: o["--out"] });
127
146
  process.stdout.write(JSON.stringify(result, null, 2) + "\n");
128
147
  } else if (command === "release-set") {
129
- const operation = rest.shift(), o = options(["--input", "--evidence-root", "--expect-input-hash", "--private-key", "--issuer", "--out", "--release-set", "--public-key", "--expect-issuer", "--expect-release-set-hash", "--env"]);
148
+ const operation = rest.shift(), o = options(["--input", "--evidence-root", "--expect-input-hash", "--private-key", "--issuer", "--out", "--release-set", "--public-key", "--expect-issuer", "--expect-release-set-hash", "--env", "--review-config"]);
130
149
  if (o.positional.length) throw new Error("release-set 不接受位置参数");
131
150
  const { createReleaseSet, verifyReleaseSet } = await import("../lib/release-set.js"); let result;
132
- if (operation === "create") { protectOutput(o["--out"], [o["--input"], o["--private-key"]]); result = createReleaseSet({ inputFile: o["--input"], evidenceRoot: o["--evidence-root"], expectInputHash: o["--expect-input-hash"], privateKeyFile: o["--private-key"], issuer: o["--issuer"], outFile: o["--out"] }); }
133
- else if (operation === "verify") result = verifyReleaseSet({ releaseSetFile: o["--release-set"], publicKeyFile: o["--public-key"], expectIssuer: o["--expect-issuer"], expectReleaseSetHash: o["--expect-release-set-hash"], env: o["--env"] });
151
+ if (operation === "create") { protectOutput(o["--out"], [o["--input"], o["--private-key"], o["--review-config"]]); result = createReleaseSet({ inputFile: o["--input"], evidenceRoot: o["--evidence-root"], expectInputHash: o["--expect-input-hash"], privateKeyFile: o["--private-key"], issuer: o["--issuer"], outFile: o["--out"], reviewConfigFile: o["--review-config"] }); }
152
+ else if (operation === "verify") result = verifyReleaseSet({ releaseSetFile: o["--release-set"], publicKeyFile: o["--public-key"], expectIssuer: o["--expect-issuer"], expectReleaseSetHash: o["--expect-release-set-hash"], env: o["--env"], reviewConfigFile: o["--review-config"] });
134
153
  else throw new Error("release-set 子命令 create/verify");
135
154
  process.stdout.write(JSON.stringify(result, null, 2) + "\n");
136
155
  } else if (command === "deployment") {
@@ -293,5 +312,5 @@ try {
293
312
  if (rest.length) throw new Error("self-test 不接受额外参数");
294
313
  const { runAllFixtures } = await import("../scripts/run-fixtures.mjs");
295
314
  process.exitCode = await runAllFixtures();
296
- } else throw new Error("用法: wl-skills-gate <onboard|run|doctor|automation|control|collect-ci|review-facts|review-ci|review-collect|review-publish|lifecycle-build|lifecycle-review|governance|inspect|cost|fix|validate-report|commit-message|manifest|attest|attest-collected|release-set|deployment|review-draft|review-sign|verify-artifact|promote|promote-apply|self-test>,详见 docs/README.md");
315
+ } else throw new Error("用法: wl-skills-gate <setup|onboard|ci-prepare|verify-release-review|run|doctor|automation|control|collect-ci|review-facts|review-ci|review-collect|review-publish|lifecycle-build|lifecycle-review|governance|inspect|cost|fix|validate-report|commit-message|manifest|attest|attest-collected|release-set|deployment|review-draft|review-sign|verify-artifact|promote|promote-apply|self-test>,详见 docs/README.md");
297
316
  } catch (e) { console.error(`[${command || "wl-skills-gate"}] ${e.message}`); process.exitCode = 2; }
package/docs/06-gitlab.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # 06 GitLab 接线
2
2
 
3
- 对应 B1~B6;当前为接线说明/模板,平台权限和实际 Runner 尚待验收。本包配置为公共 npm 发布;使用须先取得 AGILE TEAM 书面授权,见 [LICENSE](../LICENSE)。以下 registry 是可选内网镜像/托管接线示例,不代表本包已发布到该地址;使用内网地址时须另行核验实际镜像版本与访问权限。
3
+ 包内候选、独立 Review、签发、条件更新和采集程序已交付;GitLab 权限与实际 Runner 另做现场验收。本包配置为公共 npm 发布;使用须先取得 AGILE TEAM 书面授权,见 [LICENSE](../LICENSE)。以下 registry 是可选内网镜像/托管接线示例,不代表本包已发布到该地址;使用内网地址时须另行核验实际镜像版本与访问权限。
4
4
 
5
5
  ## 发布到内网 registry
6
6
 
@@ -15,33 +15,22 @@
15
15
 
16
16
  ## 只读检查作业
17
17
 
18
- 前端中央模板示意;hash 由批准登记表下发,不能从候选文件现算后当批准:
19
-
20
- ```yaml
21
- wl-quality-check:
22
- stage: test
23
- image: node:22
24
- script:
25
- - corepack enable
26
- - pnpm install --frozen-lockfile --prod=false
27
- - >-
28
- pnpm exec wl-skills-gate run
29
- --profile standard --sha "$CI_COMMIT_SHA"
30
- --expect-policy-hash "$WL_APPROVED_POLICY_HASH"
31
- --expect-rules-hash "$WL_APPROVED_RULES_HASH"
32
- artifacts:
33
- when: always
34
- paths: [quality-reports/]
35
- reports:
36
- codequality: quality-reports/code-quality/gl-code-quality-report.json
37
- # junit: quality-reports/junit/*.xml # 真实测试生产者已接入后启用
38
- ```
18
+ 从固定 Gate 包提取 [前端模板](../templates/ci/gitlab-frontend.yml) 或 [后端模板](../templates/ci/gitlab-backend.yml),冻结到统一 CI 仓库;项目 include 固定 tag/commit,合并实际 stages/workflow/rules,保留所有业务必需作业。质量作业不得 allow_failure 或用 `|| true` 吞错。
19
+
20
+ | 受控项 | 用途 |
21
+ |---|---|
22
+ | `WL_APPROVED_QUALITY_IMAGE` / `WL_APPROVED_JAVA_QUALITY_IMAGE` | 固定前端 / Java 检查镜像,包含批准 Node ≥22.12、项目固定包管理器及 JDK/Maven |
23
+ | `WL_APPROVED_BOOTSTRAP_GATE_CLI` | 镜像预装的固定 Gate,先于项目依赖执行 `ci-prepare` |
24
+ | `WL_APPROVED_WORKSPACE_HASH`、`WL_APPROVED_DEPENDENCY_LOCK_HASH` | 已审阅提交的工作副本清单与对应依赖锁真实字节摘要 |
25
+ | `WL_APPROVED_POLICY_HASH`、`WL_APPROVED_RULES_HASH`、`WL_APPROVED_BASELINE_HASH`、`WL_APPROVED_WAIVERS_HASH` | 技术经理/运维批准登记的四类摘要,不能从候选现算后自封批准 |
26
+
27
+ 模板按锁安装并关闭任意生命周期,只运行固定 Gate 内的必要准备适配。包管理器不符、未知 prepare/postinstall、锁或源码漂移均阻断;不使用 corepack 隐式下载另一版本。准备成功后,前端执行根工程 Gate,后端执行 quality-tools 内 Gate 与实际 Maven 检查。模板自动生成 Review 事实并 always 归档报告,不把准备阶段当质量通过。
39
28
 
40
- 这个 job 假定项目已固定安装 Gate 0.9.0 并提交锁文件,不持有签发/晋级/部署/通知凭据。`node:22` 仅为版本系列示意,正式接线固定实际 Node 22.12+ 镜像版本/摘要与项目 pnpm 版本。Kit/UI/BD 当前要求 Node ≥22,不能沿用组合检查的 Node 20 示例。后端使用受控 Node+项目 JDK+Maven 镜像,先真实接线 wl-quality profile/检查器;若 Gate 由中央镜像提供,使用其固定 CLI,不与项目本地解析路径混用。详细接入见 [16 项目与 CI](16-project-ci-integration.md)。
29
+ 检查 Runner 不持有签发、晋级、部署或通知凭据。Gate 与项目清单固定同一批准版本;升级时重新审阅清单、依赖锁和批准摘要。详细入口见 [17 统一接入](17-onboarding.md)。
41
30
 
42
31
  上述采用全量 standard,不依赖 MR。若增加增量,分别处理 push/MR/候选/定时场景、首次 push 全零 SHA 与浅克隆缺历史,head 与 checkout 相同。MR 专属变量只在实际 MR pipeline 使用。[GitLab 变量说明](https://docs.gitlab.com/ci/variables/predefined_variables/#predefined-variables-for-merge-request-pipelines)。
43
32
 
44
- 普通 include 锁 tag 用于复用,项目仍能覆盖/删除,不能作为不可绕过证明。[include 合并规则](https://docs.gitlab.com/ci/yaml/includes/#override-included-configuration-values)。硬门来自平台强制策略或独立受控晋级作业与受保护共享分支。
33
+ 普通 include 锁 tag 用于复用,项目仍能覆盖/删除,不能作为不可绕过证明。[include 合并规则](https://docs.gitlab.com/ci/yaml/includes/#override-included-configuration-values)。硬门来自服务端强制策略或独立受控晋级作业与受保护共享分支。
45
34
 
46
35
  ## 候选检查:无特权 Runner
47
36
 
@@ -49,14 +38,14 @@ wl-quality-check:
49
38
  wl-skills-gate promote --source "$SOURCE_BRANCH" --target "$TARGET_BRANCH" \
50
39
  --expect-policy-hash "$WL_APPROVED_POLICY_HASH" \
51
40
  --expect-rules-hash "$WL_APPROVED_RULES_HASH" \
52
- --prepare-command 'pnpm install --frozen-lockfile'
41
+ --prepare-command "$WL_APPROVED_CANDIDATE_PREPARE_COMMAND"
53
42
  ```
54
43
 
55
- 后端改为其真实依赖准备命令。输出在 quality-reports/promotion-<id>/:候选检查、unsigned 结果、promotion-record.json、candidate.bundle。失败也保留记录/报告。这个作业只能读源/目标,不更新共享分支;归档 bundle 供控制器导入。
44
+ 候选工作树使用中央固定的 `WL_APPROVED_CANDIDATE_PREPARE_COMMAND`,从候选根调用同一 `ci-prepare`,带入批准清单/锁摘要;不让作者提供任意安装命令或生命周期。Java 业务准备和实际检查由批准适配执行。输出在 quality-reports/promotion-<id>/:候选检查、unsigned 结果、promotion-record.json、candidate.bundle。失败也保留记录/报告。这个作业只能读源/目标,不更新共享分支;归档 bundle 供控制器导入。
56
45
 
57
46
  ## 独立 Review、签发和更新
58
47
 
59
- 1. 平台保存候选 SHA、源/目标 HEAD 与作业 ID;授权非作者 Reviewer 检查候选,逐项处理阻断问题。
48
+ 1. 受控作业保存候选 SHA、源/目标 HEAD 与作业 ID;授权非作者 Reviewer 检查候选,逐项处理阻断问题。
60
49
  2. 自动生成九维草稿,补齐适用证据,非作者逐维确认;独立身份服务签发绑定正文/证据/候选的授权receipt。Review作业用固定身份公钥/issuer校验后review-sign,使用与身份服务分离的Review密钥;见[19 九维Review](19-nine-dimension-review.md)。
61
50
  3. 签发作业权威查询检查来源和成功状态,再 attest:standard 档、固定期望、源 job ID,使用 --promotion-record 绑定该候选记录。
62
51
  4. 受控更新作业执行:
@@ -75,9 +64,9 @@ wl-skills-gate promote-apply signed-proof.json \
75
64
  --out controller-audit
76
65
  ```
77
66
 
78
- 若有基线/例外,补其批准摘要。控制器在新 bare 仓库核验签名、Review、候选父提交、最新远端源/目标 HEAD,核验父提交后以批准的旧 HEAD 条件更新;不运行候选代码/项目 Hook。平台对同一目标分支串行化(例如 resource_group),配合保护分支和禁止普通写入;晚到候选需重新生成和 Review。
67
+ 若有基线/例外,补其批准摘要。控制器在新 bare 仓库核验签名、Review、候选父提交、最新远端源/目标 HEAD,核验父提交后以批准的旧 HEAD 条件更新;不运行候选代码/项目 Hook。运维对同一目标分支串行化(例如 resource_group),配合保护分支和禁止普通写入;晚到候选需重新生成和 Review。
79
68
 
80
- 更新前先落审计记录,审计目录不可写则拒绝更新;所有尝试保留控制器审计。若更新已成功但最终审计写入失败,返回 `promoted-audit-failed` 和非零退出码;平台必须核对远端实际 HEAD 并补齐记录,不能当作未更新而盲目重试。临时 bare 仓库在失败和成功后均清理。
69
+ 更新前先落审计记录,审计目录不可写则拒绝更新;所有尝试保留控制器审计。若更新已成功但最终审计写入失败,返回 `promoted-audit-failed` 和非零退出码;运维必须核对远端实际 HEAD 并补齐记录,不能当作未更新而盲目重试。临时 bare 仓库在失败和成功后均清理。
81
70
 
82
71
  B2/B3 分支保护与服务端接收控制仍由管理员配置,不能用本地 Hook 宣称“服务端拒绝接收”。
83
72
 
@@ -85,12 +74,12 @@ B2/B3 分支保护与服务端接收控制仍由管理员配置,不能用本
85
74
 
86
75
  B6/D1~D4 与样板同步建设:失败按项目/指纹幂等建单,分派主备,消息包含问题/报告/流水线认证链接,认领和复验回写主台账,定时升级无人认领/逾期。通知任务使用独立凭据并重试;通知失败不覆盖原门禁退出码。对账发现未运行或配置/权限漂移,不仅监听失败事件。
87
76
 
88
- ## 0.5.1 接线补充
77
+ ## 摘要、并发与失败处理
89
78
 
90
- 有 baseline/waivers 文件时,检查、promote、attest、promote-apply、release/verify-artifact 各环节都传同一批准摘要;它们来自平台审批登记,而不是在候选里自行计算并批准。候选依赖准备结果保存 dependency-prepare.json(退出码、耗时、超时/截断、脱敏输出),promotion-record.preparation 引用日志;prepare 失败不丢失网络/仓库错误上下文。日志脱敏是辅助措施,仍须限制访问与保留期,禁止把凭据直接写进命令。
79
+ 有 baseline/waivers 文件时,检查、promote、attest、promote-apply、release/verify-artifact 各环节都传同一批准摘要;它们来自中央审批登记,而不是在候选里自行计算并批准。候选依赖准备结果保存 dependency-prepare.json(退出码、耗时、超时/截断、脱敏输出),promotion-record.preparation 引用日志;prepare 失败不丢失网络/仓库错误上下文。日志脱敏是辅助措施,仍须限制访问与保留期,禁止把凭据直接写进命令。
91
80
 
92
81
  控制器使用 `--force-with-lease=refs/heads/<target>:<批准旧SHA>` 原子核对目标 HEAD,同时强制候选恰有批准的目标/源两个父提交,因此只允许批准旧 HEAD 的快进。此处不开放任意强推/回退功能。上线必须实测当前 GitLab 保护分支与受控账号接受这一条件更新,并保持禁止一般强推的保护策略;不能为了适配而放开任意强推。[Git push 显式 lease 语义](https://git-scm.com/docs/git-push)。
93
82
 
94
- 该条件更新保护目标分支;源分支最后核对与目标更新不是多引用原子事务。如果团队要求“更新瞬间源分支也必须最新”,由服务端接收校验、固定源引用或平台锁补充实现,不能将本地 HEAD 检查写成全局原子保证。
83
+ 该条件更新保护目标分支;源分支最后核对与目标更新不是多引用原子事务。如果团队要求“更新瞬间源分支也必须最新”,由服务端接收校验、固定源引用或受控锁补充实现,不能将本地 HEAD 检查写成全局原子保证。
95
84
 
96
85
  台账准入不得简单使用“项目只要有未关闭问题就禁止所有发布”。修复发布可凭绑定本次修复 SHA/范围的有效质量、Review 和回归证据,在授权范围内进入目标环境复验,再关闭;原事故的恢复与根因整改分开记录。具体准入参见 12 与落地执行附录 C。
@@ -1,62 +1,67 @@
1
1
  # 07 Jenkins 构建、签发与部署
2
2
 
3
- 对应 C1~C5;命令代码已测,真实作业/权限/制品和双仓组合待验收。
3
+ 使用包内 [CI 模板](../templates/ci/),由米传汇智和运维冻结实际作业、SCM/ref、镜像、脚本、凭据与修改权限。项目作者不能替换或跳过受控作业;真实环境另做验收。
4
4
 
5
- ## 作业拆分
5
+ ## 一次接好五类作业
6
6
 
7
- - 检查/构建作业可执行项目源码,不能挂签发/部署凭据。
8
- - 签发作业仅下载权威查询核验的报告和 manifest,在无项目代码的受控工作区执行固定版本 Gate;持有签发私钥。
9
- - 部署作业固定公钥、目标环境、来源作业和批准策略,验证真实制品后部署;不重新构建。
7
+ | 顺序 | 模板 | 自动执行与成功条件 |
8
+ |---:|---|---|
9
+ | 1 | [Jenkinsfile](../templates/ci/Jenkinsfile) | checkout → 按实际 SHA 选择正式 Review、重查当前 CI → 固定依赖准备 → release 全量检查 → 实际构建 → manifest |
10
+ | 2 | [Jenkinsfile.attest](../templates/ci/Jenkinsfile.attest) | 独立查询成功作业、下载原始报告/清单/制品,再签组件证明;不执行项目代码 |
11
+ | 3 | [Jenkinsfile.release-sign](../templates/ci/Jenkinsfile.release-sign) | 消费助手生成且已另行批准的组合输入;核验两仓正式 Review、组件证明、实际制品与兼容依据,签固定组合 |
12
+ | 4 | [Jenkinsfile.deployment](../templates/ci/Jenkinsfile.deployment) | 核验组合、当前环境与固定适配器 → 自动登记计划 → 登录后独立授权 deploy → 执行并交付原始记录 |
13
+ | 5 | 同一部署模板的 smoke / recover | 各自生成新计划、取得对应动作授权;独立验证人授权 smoke,恢复依据已批准的旧组合和恢复约束 |
10
14
 
11
- 先盘点 Jenkins 实际触发、脚本维护位置、作业修改/启动权限和凭据;受控共享库/配置版本化。不把作者可改 Jenkinsfile 当最终权限边界。
15
+ [Review 签发模板](../templates/ci/Jenkinsfile.review-sign)独立消费认证页面的九维确认授权,产生正式记录与交付 manifest。它与构建、组件/组合签发、部署分别运行,不把私钥授给项目检查 Runner。
12
16
 
13
- ## 检查与构建
17
+ ## 构建前检查什么
14
18
 
15
- 在确定 checkout HEAD、安装真实依赖之后:
19
+ `verify-release-review --publication-dir` 从中央固定目录自动选择本次 checkout SHA 的当前正式记录,不要求人复制动态报告路径。固定信任配置核验 Review 与身份授权公钥、issuer、复核名单、九维/机器策略和原始证据;随后重新查询当前 CI。缺证据、自审、错误 SHA、被替代的 Review、重试后的失败/新作业均阻断。
16
20
 
17
- ```bash
18
- wl-skills-gate run --profile release --sha "$CHECKED_SHA" --env "$TARGET_ENV" \
19
- --expect-policy-hash "$WL_APPROVED_POLICY_HASH" --expect-rules-hash "$WL_APPROVED_RULES_HASH"
20
- # 在同一不可变源码/受控环境中执行真实构建,成功后:
21
- wl-skills-gate manifest --project "$WL_PROJECT" --env "$TARGET_ENV" \
22
- --artifacts dist --out quality-reports/artifact-manifest.json
23
- ```
21
+ 中央 Review 原件可只读挂载。当前 CI 复验记录写入本机 `quality-reports/release-review-live/<uuid>/`,结果和失败原因写入 `release-review-verification.json/.log`,随 `post always` 归档。
24
22
 
25
- 后端 artifacts 指向实际 JAR/制品;配置、迁移脚本按实际分发路径用 --configs 纳入清单。post always 归档报告和对应工件。多个环境重新构建时重新出清单/证明,旧证明不跨环境使用。
23
+ `ci-prepare` 使用中央预装固定 Gate,核对已提交 `quality/workspace.json` 与依赖锁的批准字节摘要,按锁安装且关闭任意生命周期;必要准备仅用固定适配。未知脚本、版本不符、锁或源码漂移均停止。它不在 CI 激活 Hook,也不代替后续质量检查。
26
24
 
27
- ## 受控签发
25
+ 实际构建脚本来自批准作业配置。前端 manifest 纳入真实 dist,后端纳入真实 JAR;分发配置和数据脚本用 `WL_CONFIG_PATHS` 纳入。部署只消费这些不可变制品,不重新构建。
28
26
 
29
- 平台先查询批准的具体质量/构建作业,核验模板/Runner/身份、真实 SHA、成功状态、工具/覆盖、工件完整性,再在独立签发工作区:
27
+ ## 组合与授权
30
28
 
31
- ```bash
32
- wl-skills-gate attest --summary evidence/quality-summary.json \
33
- --profile release --project "$WL_PROJECT" --sha "$CHECKED_SHA" --env "$TARGET_ENV" \
34
- --expect-policy-hash "$WL_APPROVED_POLICY_HASH" --expect-rules-hash "$WL_APPROVED_RULES_HASH" \
35
- --manifest evidence/artifact-manifest.json \
36
- --private-key "$WL_SIGNING_KEY_FILE" --issuer "$WL_GATE_ISSUER" \
37
- --pipeline-id "$WL_VERIFIED_PIPELINE_ID" --job-id "$WL_VERIFIED_JOB_ID" \
38
- --out evidence/signed-proof.json
39
- ```
29
+ 发布负责人从接入助手选择“生成组合发布输入”。固定 [输入配置](../templates/platform/release-input-config.json)引用真实采集/签发原件与 `reviewPublicationDir`,程序按两仓实际 SHA 自动选 Review,展示作者、复核人、作业、部署顺序和 schema。确认只授权生成输入;组合签发与部署另行批准。
40
30
 
41
- 有基线/例外时必须补其批准摘要。签名认证签发者和绑定内容,不能替代平台来源查询;issuer/jobId 字符串本身不是查询。这个查询连接需按真实 GitLab/Jenkins API、身份与授权实施,当前包不自动配置。
31
+ [release-review-trust.json](../templates/platform/release-review-trust.json)固定中央公钥、人员、摘要、证据根、collector 和 catalog。[deployment-config.json](../templates/platform/deployment-config.json)通过 `reviewConfigFile` 绑定同份信任。`release-set create/verify --review-config` 与部署消费都会重验正式 Review 及归档原件;直接给旧 formal 文件也不能绕过当前版本。旧组合缺 Review 归档须重新生成。
42
32
 
43
- ## 部署前验证
33
+ 普通新发布要求当前有效 Review。smoke/recover 对已签组合按其签发时点核验历史 Review,仍须核验原签名、实际制品/环境和新的独立动作授权,不因此取得新发布或关闭权限。
44
34
 
45
- ```bash
46
- wl-skills-gate verify-artifact evidence/signed-proof.json \
47
- --summary evidence/quality-summary.json --project "$WL_PROJECT" \
48
- --sha "$CHECKED_SHA" --env "$TARGET_ENV" \
49
- --public-key "$WL_GATE_PUBLIC_KEY" --expect-issuer "$WL_GATE_ISSUER" \
50
- --expect-pipeline-id "$WL_VERIFIED_PIPELINE_ID" --expect-job-id "$WL_VERIFIED_JOB_ID" \
51
- --expect-policy-hash "$WL_APPROVED_POLICY_HASH" --expect-rules-hash "$WL_APPROVED_RULES_HASH" \
52
- --manifest evidence/artifact-manifest.json --artifact-root artifact-staging \
53
- --max-age-minutes 1440
54
- ```
35
+ `run release`、`attest`、`verify-artifact` 是机器事实接口,单独通过不能代替正式 Review、组合准入、部署授权或问题关闭。构建成功也不关闭问题;必要环境独立复验后,再由认证处理页执行关闭。
55
36
 
56
- artifact-staging 中保持 manifest 相对路径。任何非零退出停止 Deploy。固定公钥/期望值/来源 ID 从平台控制配置和查询取得,不接受作者上传的公钥、passed 字符串或自行计算的批准值。
37
+ ## 固定变量与凭据
57
38
 
58
- 验证后部署只读不可变工件,发布记录写入证明、制品、配置和实际环境。冒烟失败停止后续环境晋级、按恢复方案处理并建单;扫描或部署成功不自动关闭线上缺陷。
39
+ 下表配置在受控作业/凭据库,不能由作者临时提交或覆盖。路径/摘要由批准资产与真实采集结果交接,生成值由作业传递,发布操作者不逐次抄填。
59
40
 
60
- ## 保留待接入
41
+ | 作业 | 固定变量或输入 |
42
+ |---|---|
43
+ | 全部 Jenkins 模板 | `WL_APPROVED_GATE_CLI`:批准镜像/安装包中的固定 CLI;Node、项目包管理器、JDK/Maven 和镜像摘要另行固定 |
44
+ | 检查/构建 | `WL_PROJECT`、`WL_TARGET_ENV`;`WL_APPROVED_REVIEW_TRUST_CONFIG`、`WL_APPROVED_REVIEW_PUBLICATION_DIR`;`WL_APPROVED_WORKSPACE_HASH`、`WL_APPROVED_DEPENDENCY_LOCK_HASH`;`WL_APPROVED_POLICY_HASH`、`WL_APPROVED_RULES_HASH`、`WL_APPROVED_BASELINE_HASH`、`WL_APPROVED_WAIVERS_HASH`;`WL_APPROVED_BUILD_SCRIPT`、`WL_ARTIFACT_PATHS` |
45
+ | 构建可选项 | `WL_CONFIG_PATHS`:实际分发配置/脚本;`WL_APPROVED_REVIEW_BASE_SHA`:批准的差异基点 |
46
+ | 组件签发 | `WL_APPROVED_GATE_ROOT`、`WL_FIXED_CI_SOURCE_CONFIG`、`WL_CENTRAL_CI_REQUEST`、`WL_NEW_COLLECTED_DIRECTORY`、`WL_FIXED_COMPONENT_SIGN_REQUEST`;请求绑定本次实际来源、候选/环境、清单、四类策略摘要和输出 |
47
+ | 正式 Review 签发 | `WL_REVIEW_PUBLISH_CONFIG`:隔离签发配置 |
48
+ | 组合签发 | `WL_APPROVED_RELEASE_INPUT`、`WL_APPROVED_RELEASE_INPUT_HASH`、`WL_CENTRAL_EVIDENCE_ROOT`、`WL_APPROVED_REVIEW_TRUST_CONFIG`、`WL_RELEASE_ISSUER`、`WL_NEW_RELEASE_SET_FILE` |
49
+ | 部署/复验 | `WL_DEPLOYMENT_CONFIG`、`WL_DEPLOYMENT_CONFIG_ID`、`WL_SELECTED_RELEASE_SET`、`WL_SELECTED_RELEASE_SET_HASH`、`WL_FIXED_ENVIRONMENT_STATE`、`WL_CONTROL_DATA_DIR`、`WL_CONTROL_ORIGIN` |
50
+ | 中央调度 | `WL_CENTRAL_AUTOMATION_CONFIG`;Jenkins 定时作业与 systemd/常驻循环择一 |
61
51
 
62
- 双仓 release-manifest 组合核验(前后端 SHA/契约/脚本/批准)、生产恢复演练、现场冒烟、紧急通道及事后补检仍须平台实现和留证,不能因为单仓 verify-artifact 通过而标为完成。
52
+ | 凭据 ID / 环境变量 | 只授给谁 |
53
+ |---|---|
54
+ | `wl-ci-review-readonly-token` → `WL_GITLAB_READ_TOKEN` | 构建前 Review 重查与独立 Review 签发;构建模板仅在校验阶段绑定 |
55
+ | 来源配置的 `tokenEnv` / `userEnv` | 对应查询作业;Jenkins 来源另按配置注入 `WL_JENKINS_READ_USER`、`WL_JENKINS_READ_TOKEN`,不授源码执行阶段 |
56
+ | `wl-component-proof-signing-key` → `WL_COMPONENT_KEY` | 独立组件签发 |
57
+ | `wl-review-signing-key` → `WL_REVIEW_PRIVATE_KEY_FILE` | 独立正式 Review 签发 |
58
+ | `wl-release-set-signing-key` → `WL_RELEASE_KEY` | 独立组合签发 |
59
+ | `wl-deployment-execution-key` → `WL_EXECUTOR_KEY` | 受控部署/复验执行;实际部署 API 凭据由固定适配配置的 `secretEnv` 注入 |
60
+
61
+ `WL_CHECKED_SHA` 来自实际 checkout。`ACTION` 是 deploy/smoke/recover 选项;`WL_CURRENT_PLAN_ID`、`WL_NEW_DEPLOYMENT_PLAN`、`WL_NEW_EXECUTION_DIRECTORY` 由模板生成。Jenkins 提供的 `JOB_NAME/BUILD_NUMBER/BUILD_URL` 必须与部署配置匹配;不以人工 SHA 参数代替真实 SCM revision。
62
+
63
+ 中央飞书、身份与事件签名凭据由[中央接线配置](../templates/platform/README.md)引用并隔离,不放入检查/构建作业。运行前创建受控持久目录、输入队列和归档目录;通知失败保留原始检查/部署结果,并由待发箱与独立监控反馈。
64
+
65
+ ## 验收
66
+
67
+ 至少演练:正常完整组合、缺/旧 Review、当前 CI 失败或重试、错 SHA、替换制品/配置、错环境、无授权/重放、冒烟失败与显式恢复。成功与失败都保留原始报告和作业 ID;真实 Jenkins 权限、实际部署/冒烟与群投递另留现场证据。
@@ -19,8 +19,8 @@
19
19
  | 层 | 完成条件 |
20
20
  |---|---|
21
21
  | 项目 | 固定执行器/锁/受管资产,正确根目录,统一命令,轻量 Hook,检查不改源码 |
22
- | 流水线 | 对真实 SHA 执行批准范围、实际测试与构建,保留完整原生报告;blocked/invalid 均不晋级 |
23
- | 统一质量服务 | 共享分支保护、批准策略、真实候选、独立 Review/签发/制品验证;删 Hook/job 也不能绕过 |
22
+ | 流水线 | 按批准工作副本清单/锁准备环境,关闭任意生命周期;对真实 SHA 检查/测试;构建前正式 Review 与当前 CI 重验;失败留原件并阻断 |
23
+ | 统一质量服务 | 共享分支保护、真实候选、九维独立授权/签发;组合与部署重验当前 Review、实际制品和对应动作授权 |
24
24
  | 治理 | 可信事件、幂等主台账、主备/复核、认证跳转、可靠待发箱、SLA/对账、独立关闭 |
25
25
 
26
26
  “共享实现已验证”“业务项目已接入”“已接项目准入已验收”“业务问题已关闭”分别登记。模拟和隔离验证不能代替真实接线证据。本轮只完善共享资产,业务项目/test-qa 不改动,不发送真实消息。
@@ -33,12 +33,12 @@
33
33
 
34
34
  BD 的 verify:quality-codecc 等属于源码包维护者夹具验证。业务项目执行自己的 POM、源码和真实测试。PMD 7 与 P3C/PMD 6 分开调用和保存输出。
35
35
 
36
- ## 本轮新增共享资产
36
+ ## 共享入口与资产
37
37
 
38
38
  | 资产 | 使用位置与边界 |
39
39
  |---|---|
40
- | onboard complete | 包内统一识别、差异确认、固定安装、规则/POM/锁与Hook首扫;项目差异和远端验收独立留证 |
41
- | 九维Review | 标准/发布检查后自动草稿,逐维证据、正文/摘要/候选和独立身份授权;正式晋级重验 |
40
+ | setup project / workspace | 首次接入编排差异确认、固定安装、规则/POM/锁与 Hook 首扫;新克隆按已提交清单恢复,不重写策略 |
41
+ | 九维Review | 自动草稿、非作者逐维授权、独立签发;构建按 SHA 自动选择当前正式版本并重查 CI,组合/部署再验原件 |
42
42
  | collect-ci与分类卡片 | 真实GitLab/Jenkins API与原始工件、构建/Review事实、同源卡片/待发箱,默认不真实发送 |
43
43
  | doctor | 只读盘点前后端的依赖/资产/策略/POM 准备度,不执行项目测试或安装;CI/Jenkins 作业另由统一质量服务核验 |
44
44
  | JUnit 多报告与共享 producer | 显式 files/reportDirs/requiredSuites/requiredTests,真实同轮生产,全量 XML 与 testcase 校验 |
@@ -61,4 +61,4 @@ BD 的 verify:quality-codecc 等属于源码包维护者夹具验证。业务项
61
61
  - [14 低 token 执行](14-low-token-execution.md):唯一生产者、摘要阅读与成本。
62
62
  - [质量服务配置与样例](../templates/platform/README.md):可信 receipt、事件/动作/对账及消息预览。
63
63
 
64
- 实际文件名以包目录为准。团队操作手册只呈现一次接入、自动检查、确认后脚本修复、复扫反馈、构建部署与关闭验收;资产、CLI/POM/CI参数和来源移入明细附录。Gate 的 templates/onboarding 已纳入固定 npm 包,统一入口为 onboard;工作区 quality-onboarding-examples 保留历史适配与兼容入口。已复制脚本仍须经升级计划审核同步。先验前后端各一个模块与一条真实告警,再扩面;正式准入从开始就拒绝确定缺陷、必测失败和证据失效。
64
+ 实际文件名以包目录为准。团队操作手册只呈现一次接入、自动检查、确认后脚本修复、复扫反馈、构建部署与关闭验收;资产、CLI/POM/CI参数和来源移入明细附录。Gate 的 templates/onboarding 已纳入固定 npm 包,统一操作入口为 setup,底层首次接入契约为 onboard --complete;工作区 quality-onboarding-examples 保留历史适配与兼容入口。已复制脚本仍须经升级计划审核同步。先验前后端各一个模块与一条真实告警,再扩面;正式准入从开始就拒绝确定缺陷、必测失败和证据失效。
@@ -13,19 +13,40 @@
13
13
 
14
14
  ## 技术经理一次接入,开发者由 Hook 自动检查
15
15
 
16
- 完整接入使用 `--complete`,从已批准的固定 Gate 产物运行预览。下例 `$GATE_ROOT` 指该完整包目录,`$PROJECT_ROOT` 指实际 Git 仓库根;前后端使用同一入口。
16
+ 负责人从批准的完整包打开 `templates/launchers/setup.command` / `setup.cmd` / `setup.sh`,选择任务即可。首次项目接入使用 `setup project` 交互向导:选择真实 Git 根和批准 HTTPS 安装源,查看文件、依赖、Hook 与固定安装 argv,确认当前阶段。脚本管理本阶段计划摘要,出现安装后的新差异再展示确认。
17
17
 
18
- ```bash
19
- node "$GATE_ROOT/bin/wl-skills-gate.js" onboard --root "$PROJECT_ROOT" --complete --registry "$APPROVED_NPM_REGISTRY"
20
- ```
18
+ | 入口 | 自动执行 | 成功反馈 |
19
+ |---|---|---|
20
+ | `setup project` | 预检→批准配置/依赖安装→原生规则/POM/锁→doctor→真实Hook首扫和提交说明正反验证 | `quality-reports/setup/<sessionId>/result.html`;阶段原件与执行回执可追溯 |
21
+ | `setup workspace` | 按已提交 `quality/workspace.json` 与依赖锁安装,恢复本机 Hook,实际验收 | `quality-reports/onboarding/workspace-execution.json`;不覆盖项目策略 |
22
+ | `setup central` | 中央配置、来源、身份、凭据存在性、旧状态及部署回流预检 | 逐项状态、责任人和下一步;预检不联网、不启动、不发送 |
23
+ | `setup release-input` | 核验固定来源原件、签名、摘要、兼容证据,确认后生成组合输入 | `configHash` / `inputHash` 与实际输入文件;不代替授权或签发 |
21
24
 
22
- 接入界面可直接消费此 JSON,展示项目判定、每个文件的修改前后内容、依赖版本变化、Hook 激活、冲突与剩余验收。技术经理确认**这份具体计划**后,界面传回其实际摘要:
25
+ 非交互入口默认只读。`setup project --root PATH --registry URL --preview --json` 可用于预检;项目首次写入由交互逐阶段批准,自动任务可继续使用下文底层 `onboard` 契约。
23
26
 
24
- ```bash
25
- node "$GATE_ROOT/bin/wl-skills-gate.js" onboard --root "$PROJECT_ROOT" --complete --registry "$APPROVED_NPM_REGISTRY" --apply --plan-hash "$ONBOARD_PLAN_HASH" --confirm
26
- ```
27
+ ### 已接项目的新克隆
28
+
29
+ 首次接入完成后,将生成的工作副本清单、依赖锁、Hook、脚本与 IDE 任务一并审阅提交。新成员在 VS Code/Cursor 中选择 **wl-quality:初始化本机质量环境**。缺少本地 Gate 时入口先展示清单固定版本和批准源,确认后获取引导工具;随后展示项目初始化计划,确认后安装与验收。不得重跑首次接入来覆盖已经批准的项目策略。
30
+
31
+ **wl-quality:打开项目检查接入状态** 在允许自动任务的受信工作区打开时执行,只读、不联网、不安装。IDE 的 Workspace Trust 与自动任务许可由用户环境控制;Git clone 自身不会执行仓库脚本。首次初始化成功后,日常仍由 Hook 自动检查。
32
+
33
+ ### 已接项目升级
34
+
35
+ 先提交已批准的配置、清单和受管脚本。同一项目接入任务展示固定依赖和已登记受管资产的升级差异,确认后继续;0.10.0旧脚本通过包内固定摘要识别。自定义policy、九维适用范围、必测与POM原文保留;未提交策略、自改脚本或未登记旧版先审阅适配。升级后审阅提交供新clone使用,不删文件绕过冲突。
36
+
37
+ ### 运维与发布输入
27
38
 
28
- 安装源必须是明确批准的 HTTPS URL;URL 不含凭据,认证由受控环境注入。完整接入计划依次展示固定 argv 安装(关闭生命周期脚本)、原生规则实际预览与同步、后端 POM 精确补丁、实际版本锁、doctor、真实 Git Hook 首扫、提交说明正反演练。两个入口命令只给接入负责人或接入界面使用。开发者正常提交/推送时,Hook 自动检查;IDE 提供“查看报告 / 预览机械修复 / 确认应用并复扫”操作,不要求输入质量命令。修复需要本人预览和确认。
39
+ GitLab/Jenkins模板用中央预装固定Gate调用`ci-prepare`,中央登记`quality/workspace.json`和依赖锁的真实字节摘要;按锁安装时关闭任意生命周期,必要准备仅用内置固定适配,不激活CI Hook。准备通过不等于质量检查通过。
40
+
41
+ pnpm预检和安装同时禁用pnpmfile执行;发现项目或全局pnpmfile声明会停止,由工程工具维护者提供固定摘要、允许目录和幂等验证适配。`--ignore-scripts`本身不覆盖pnpmfile,[pnpm说明](https://pnpm.io/id/11.x/pnpmfile)可供维护者核对。
42
+
43
+ Jenkins在准备和构建前调用`verify-release-review --publication-dir`,以checkout SHA自动选最新正式Review并重查当前CI,记录放本机quality-reports,不写只读中央原件。发布输入配置固定`reviewConfigFile`和组件`reviewPublicationDir`;组合及部署强制重验同候选Review签名、独立授权和原件。旧组合缺该证据需重新生成,不接受布尔批准。
44
+
45
+ 中央输入队列(正式Review交付、部署回流)首次由运维在受控持久卷创建;运行中缺失视为异常并提醒,不能自动造空目录。普通warning当周期汇总,首次/持续采集故障与恢复通过同一可靠待发箱反馈;配置或台账本身不可用由独立监控兜底。
46
+
47
+ 中央交互先询问配置目录及独立Review签发是否分机,默认分机,不读取独立私钥。只预检时使用 `setup central`;经批准启动时使用 `setup central --start --watch`,消息仍只预览。真实发送另加 `--send`,启动确认会明确显示发送范围。非交互启动要求 `--config-dir DIR --start --watch --confirm --plan-hash HASH`;分机时加 `--separate-review-signer`。服务以前台受控任务运行,SIGINT/SIGTERM 清理本任务启动的服务,不安装系统服务、不改GitLab/Jenkins权限或密钥、不启动独立签发。
48
+
49
+ 发布负责人维护 `templates/platform/release-input-config.json` 的项目副本。`setup release-input --config FILE` 展示实际组件、SHA、作业和输出,确认后生成输入。非交互生成需 `--confirm --config-hash HASH --input-hash HASH`;原件变化会使旧确认失效。作者映射、兼容性结论、恢复方案仍由对应负责人批准。生成后的原件摘要在签发前再次复核。
29
50
 
30
51
  - 默认计划将尚未配置的本地 `core.hooksPath` 指向生成的 `.githooks`;应用后生效。已有仓库内 Hook 路径直接复用,`.husky/_` 映射到用户 `.husky` 文件。既有Husky9转发器通过计划中独立、固定资产的激活阶段生成,不执行整个自定义prepare脚本;未知版本或路径明确阻断。
31
52
  - 既有脚本与检查保留。发现旧 Hook 自动写源码或重复检查时列出迁移项;不会擅自删除或跳过。
@@ -33,7 +54,14 @@ node "$GATE_ROOT/bin/wl-skills-gate.js" onboard --root "$PROJECT_ROOT" --complet
33
54
  - 计划、项目 HEAD、文件、模板、接入实现或选择变化后,旧摘要失效。冲突、路径越界、符号链接均拒写;写入有备份、独占锁与失败回滚。
34
55
  - `--no-activate-hooks` 可显式只生成文件;此时不能登记自动检查已生效。预览与应用必须使用相同选项。
35
56
 
36
- ## 实际差异出现时,再确认同一入口
57
+ ## 底层自动任务契约与阶段确认
58
+
59
+ 交互向导自动调用以下同一底层契约;脚本集成者才需要管理摘要。
60
+
61
+ ```bash
62
+ node "$GATE_ROOT/bin/wl-skills-gate.js" onboard --root "$PROJECT_ROOT" --complete --registry "$APPROVED_NPM_REGISTRY"
63
+ node "$GATE_ROOT/bin/wl-skills-gate.js" onboard --root "$PROJECT_ROOT" --complete --registry "$APPROVED_NPM_REGISTRY" --apply --plan-hash "$ONBOARD_PLAN_HASH" --confirm
64
+ ```
37
65
 
38
66
  首次尚未安装固定包时,无法提前知道它们的真实规则差异。确认首份计划后只完成本地配置与固定清单安装,结果为 `native-approval-required`;接入界面重新调用同一预览,显示实际 Kit/UI/BD 差异和新摘要,负责人确认后继续。BD 刚同步而 POM 模板首次出现时,以 `pom-approval-required` 展示完整 before/after,再确认同一入口。后续不需要技术经理拼装多个 update、Maven、版本查询或 Hook 命令。
39
67
 
@@ -67,7 +95,7 @@ GitLab/Jenkins 权限、可信中央模板、候选/独立 Review、构建/部
67
95
 
68
96
  ## 维护单源
69
97
 
70
- - 唯一公共入口:`lib/onboard.js`;唯一配置引擎:`lib/onboard-config.js`;完整任务编排:`lib/onboard-complete.js`。
98
+ - 交互入口:`lib/setup.js` / `lib/setup-modes.js`;底层首次接入:`lib/onboard.js` / `lib/onboard-config.js` / `lib/onboard-complete.js`;新克隆:`lib/workspace-init.js`;中央预检:`lib/setup-central.js`;发布输入:`lib/release-input.js`。
71
99
  - 包内交付源:`templates/onboarding/{frontend,backend,automation}`。`templates/scripts-quality/run.mjs` 与 schema 同包核验。
72
100
  - 文档目录旧 `automation/configure.mjs` 仅兼容转发;不得再次复制实现。文档配套文件是审阅用样例副本,维护时与包内交付源核对摘要。
73
101
  - 本模块测试覆盖真实 Git Hook 拒绝、前后端位置、旧 Hook 复用、幂等、漂移拒绝、完整包独立交付;不把隔离测试计为业务项目或远端验收。
@@ -11,10 +11,16 @@
11
11
  | 汇总草稿 | `buildReviewInput` 自动取本轮原始 Gate 报告;其他采集器补提交、分支、diff、交互、测试、CI 和责任证据 | 固定九维 `review.md`、`review-draft.json`;永远 `pending-confirmation` |
12
12
  | 人工确认 | 受控身份服务核对实际登录身份、非作者、候选和九维结论,再签发 `review-authorization` receipt | 仅 `review-publish`,绑定当前正文/证据/候选;不是修复或发布权限 |
13
13
  | 正式签发 | `signReviewRecord` / `review-sign`:独立身份公钥、固定 issuer、受控规则摘要与 Review 私钥 | 严格 v2 `review-record`,签名覆盖正文和证据摘要、逐维确认及授权 receipt |
14
- | 使用前重验 | `verifyReview`;`promote-apply` 已实际调用此验证 | 重验原始文件、正文、九维完整性、当前 Gate 报告、授权签名/时效与候选,任一不符即拒绝 |
14
+ | 候选使用前重验 | `verifyReview`;`promote-apply` 实际调用 | 重验原始文件、正文、九维完整性、Gate 报告、授权签名/时效与候选;源/目标 HEAD 另由晋级控制器核对 |
15
+ | 构建与新发布 | `verify-release-review --publication-dir`;`release-set create/verify --review-config`;`deployment` | 固定信任核验当前正式版本;构建前另重查真实 CI;组合归档 Review 签名/正文/必要原件,部署再验 |
16
+ | 历史组合复验/恢复 | `deployment` 的 smoke / recover | 按原组合签发时点核验历史 Review,仍验证原件、制品、环境和新的独立动作授权;不授予新发布或关闭权限 |
15
17
 
16
18
  草稿不能放行。只上传扫描报告只能覆盖部分编码/扫描事实,其余维度明确显示 `pending-evidence`。正式签发必须九维齐全;不适用项须已批准的策略写明事实,再由非作者逐项确认。Code Review 和扫描门禁不能标成 N/A。
17
19
 
20
+ 生产发布信任使用固定 [release-review-trust.json](../templates/platform/release-review-trust.json),绑定公钥、授权 issuer、复核名单、九维/机器策略、证据根、collector 和 catalog。中央登记新 Review 时更新当前版本索引;旧入口重复登记不回滚索引。同 SHA 新增待确认补证后,旧正式记录也不能用于构建、组合签发或新部署;直接传旧 formal 文件同样被拒绝。旧目录没有当前版本索引时,触发批准质量流水线的新运行并登记新入口,不修改旧记录或伪造批准。
21
+
22
+ 构建任务从固定正式交付目录自动匹配本次 SHA,再用固定只读 CI 凭据重新查询必需作业和原件,重试/失败/变化即停止。中央原件可以只读;本轮复验与失败记录写入本机构建报告目录。实际接线、变量与凭据分工见 [Jenkins 指南](07-jenkins.md),开发者无需抄报告路径或编写授权 JSON。
23
+
18
24
  ## 文件契约
19
25
 
20
26
  采集作业把本轮所需文件下载到独立的 `evidenceRoot`,从真实来源 API 核对项目、候选、作业终态和访问权限。每项证据写明 `id/type/source/project/candidateSha/file/dimensionIds`;文件仅接受根目录内的明确相对路径,不接受链接或越界路径。
package/docs/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # wl-skills-gate 技术手册索引
2
2
 
3
- 当前版本 0.9.0;对照团队落地执行 V3.4。技术宣贯基线仍为 V3.1;团队具体操作单源见 [16 项目与运维入口](16-project-ci-integration.md),本索引提供工具契约与参数参考。
3
+ 当前版本 0.11.0;对照团队落地执行 V3.4。技术宣贯基线仍为 V3.1;团队具体操作单源见 [16 项目与运维入口](16-project-ci-integration.md),本索引提供工具契约与参数参考。
4
4
 
5
5
  授权声明见 [LICENSE](../LICENSE);公开获取不授予使用、复制、修改或再分发授权,申请入口为 [仓库 Issues](https://github.com/ChenyCHENYU/wl-skills-gate/issues)。
6
6
 
7
- 状态分开登记:**共享实现已验证 / 项目已接入 / 平台已验收 / 业务闭环已验收**。每个状态须有自己的实际证据;以下手册不将本地自测、模板或签名通过标成生产接线完成。
7
+ 状态分开登记:**共享实现已验证 / 项目已接入 / 远端接线已验收 / 业务闭环已验收**。每个状态须有自己的实际证据;以下手册不将本地自测、模板或签名通过标成生产接线完成。
8
8
 
9
9
  | 手册 | 对应要求 | 内容 |
10
10
  |---|---|---|