@numa-tech/numa 1.13.4 → 1.14.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 (90) hide show
  1. package/README.md +140 -26
  2. package/dist/application-onboarding/client.d.ts +1 -0
  3. package/dist/application-onboarding/commands.d.ts +2 -0
  4. package/dist/application-onboarding/commands.js +41 -16
  5. package/dist/application-onboarding/commands.js.map +1 -1
  6. package/dist/application-onboarding/errors.js +1 -1
  7. package/dist/application-onboarding/errors.js.map +1 -1
  8. package/dist/application-onboarding/schemas.d.ts +8 -0
  9. package/dist/application-onboarding/schemas.js +4 -2
  10. package/dist/application-onboarding/schemas.js.map +1 -1
  11. package/dist/application-onboarding/scm-credentials.d.ts +5 -2
  12. package/dist/application-onboarding/scm-credentials.js +64 -13
  13. package/dist/application-onboarding/scm-credentials.js.map +1 -1
  14. package/dist/cli.js +4 -2
  15. package/dist/cli.js.map +1 -1
  16. package/dist/command-catalog.js +252 -15
  17. package/dist/command-catalog.js.map +1 -1
  18. package/dist/integration-bootstrap/client.d.ts +23 -0
  19. package/dist/integration-bootstrap/client.js +124 -0
  20. package/dist/integration-bootstrap/client.js.map +1 -0
  21. package/dist/integration-bootstrap/commands.d.ts +20 -0
  22. package/dist/integration-bootstrap/commands.js +129 -0
  23. package/dist/integration-bootstrap/commands.js.map +1 -0
  24. package/dist/integration-bootstrap/schemas.d.ts +422 -0
  25. package/dist/integration-bootstrap/schemas.js +216 -0
  26. package/dist/integration-bootstrap/schemas.js.map +1 -0
  27. package/dist/jenkins/commands.d.ts +10 -0
  28. package/dist/jenkins/commands.js +15 -0
  29. package/dist/jenkins/commands.js.map +1 -0
  30. package/dist/jenkins-jobs/client.d.ts +12 -12
  31. package/dist/jenkins-jobs/schemas.d.ts +96 -8
  32. package/dist/jenkins-jobs/schemas.js +2 -2
  33. package/dist/jenkins-jobs/schemas.js.map +1 -1
  34. package/dist/pipeline/client.d.ts +5 -0
  35. package/dist/pipeline/commands.js +2 -0
  36. package/dist/pipeline/commands.js.map +1 -1
  37. package/dist/pipeline/schemas.d.ts +6 -0
  38. package/dist/pipeline/schemas.js +2 -0
  39. package/dist/pipeline/schemas.js.map +1 -1
  40. package/dist/platform-build-job-replans/client.d.ts +283 -0
  41. package/dist/platform-build-job-replans/client.js +148 -0
  42. package/dist/platform-build-job-replans/client.js.map +1 -0
  43. package/dist/platform-build-job-replans/commands.d.ts +6 -0
  44. package/dist/platform-build-job-replans/commands.js +371 -0
  45. package/dist/platform-build-job-replans/commands.js.map +1 -0
  46. package/dist/platform-build-job-replans/schemas.d.ts +145 -0
  47. package/dist/platform-build-job-replans/schemas.js +150 -0
  48. package/dist/platform-build-job-replans/schemas.js.map +1 -0
  49. package/dist/platform-build-rollouts/client.d.ts +346 -0
  50. package/dist/platform-build-rollouts/client.js +153 -0
  51. package/dist/platform-build-rollouts/client.js.map +1 -0
  52. package/dist/platform-build-rollouts/commands.d.ts +98 -0
  53. package/dist/platform-build-rollouts/commands.js +465 -0
  54. package/dist/platform-build-rollouts/commands.js.map +1 -0
  55. package/dist/platform-build-rollouts/schemas.d.ts +348 -0
  56. package/dist/platform-build-rollouts/schemas.js +257 -0
  57. package/dist/platform-build-rollouts/schemas.js.map +1 -0
  58. package/dist/platform-builds/client.d.ts +147 -0
  59. package/dist/platform-builds/client.js +115 -0
  60. package/dist/platform-builds/client.js.map +1 -0
  61. package/dist/platform-builds/commands.d.ts +7 -0
  62. package/dist/platform-builds/commands.js +226 -0
  63. package/dist/platform-builds/commands.js.map +1 -0
  64. package/dist/platform-builds/schemas.d.ts +127 -0
  65. package/dist/platform-builds/schemas.js +66 -0
  66. package/dist/platform-builds/schemas.js.map +1 -0
  67. package/dist/publications/client.d.ts +30 -0
  68. package/dist/publications/client.js +6 -1
  69. package/dist/publications/client.js.map +1 -1
  70. package/dist/publications/commands.d.ts +2 -0
  71. package/dist/publications/commands.js +84 -5
  72. package/dist/publications/commands.js.map +1 -1
  73. package/dist/repositories/client.d.ts +6 -0
  74. package/dist/repositories/commands.d.ts +3 -1
  75. package/dist/repositories/commands.js +22 -8
  76. package/dist/repositories/commands.js.map +1 -1
  77. package/dist/repositories/errors.d.ts +2 -1
  78. package/dist/repositories/errors.js +4 -2
  79. package/dist/repositories/errors.js.map +1 -1
  80. package/dist/repositories/schemas.d.ts +32 -0
  81. package/dist/repositories/schemas.js +4 -0
  82. package/dist/repositories/schemas.js.map +1 -1
  83. package/package.json +4 -4
  84. package/skills/numa-create-application/SKILL.md +26 -13
  85. package/skills/numa-create-application/agents/openai.yaml +2 -2
  86. package/skills/numa-create-application/evals/evals.json +72 -12
  87. package/skills/numa-create-application/references/checklist.md +12 -5
  88. package/skills/numa-create-application/references/numa-cli.md +55 -13
  89. package/skills/numa-create-application/references/promote-workflows.md +63 -24
  90. package/skills/numa-create-application/scripts/inspect-project.mjs +1 -0
@@ -35,6 +35,7 @@ numa app options business-domain --json
35
35
  numa app options environment --json
36
36
  numa repository connection list --json
37
37
  numa repository capabilities --connection <code> --consumer application-onboarding --json
38
+ numa app scm inspect <code> --json
38
39
  numa repository namespace list --connection <code> --json
39
40
  numa repository remote list --connection <code> --search <name> --json
40
41
  numa app list --json
@@ -47,6 +48,22 @@ numa pipeline list --app <application-code> --json
47
48
  numa repository remote list --connection <connection-code> --search <repository-name> --json
48
49
  ```
49
50
 
51
+ `repository capabilities --consumer` 同时接受可复制的 `application-onboarding` 和规范
52
+ `APPLICATION_ONBOARDING`(下划线形式也保留),发送给服务端时统一为规范枚举。普通
53
+ `app scm inspect/list`、`repository connection list` 以及 capabilities 的 nested connection 都只读取
54
+ 安全布尔字段 `codeupCredentialReadinessAvailable`、`codeupAccessTokenConfigured`、
55
+ `codeupCloneCredentialConfigured`,不读取 credential。只有 availability=`true` 时才解释 configured:
56
+ 显式 `false` 是 missing;availability=`false`/缺失或 configured 缺失均是 unknown 并 fail closed。
57
+ `capabilities.executableMode` 不是 clone credential 证据。
58
+
59
+ 平台管理员交互轮换 Codeup OpenAPI AT 与 HTTPS clone 凭据时使用原生隐藏提示,不把值写入 argv、环境变量、聊天或临时 JSON:
60
+
61
+ ```bash
62
+ numa app scm rotate <connection-code> --revision <version> --credential-prompt --yes --json
63
+ ```
64
+
65
+ AT 与 clone password 隐藏输入,clone password 需二次确认;clone username 可见。提示只写 stderr,JSON 结果仍只写 stdout。GitHub App 私钥是多行材料,不允许交互粘贴,继续使用 chmod 600 文件或重定向 stdin。自动化也使用受保护文件/stdin,不用脚本拼接明文 JSON。
66
+
50
67
  团队选项可见不等于当前用户具有 `MEMBER+`。通过运行时 command catalog 找团队成员查询能力;缺失时用批准的只读平台 API,并把无法证明的成员资格标记为 `UNRESOLVED`。
51
68
 
52
69
  ## 安全输出
@@ -177,7 +194,7 @@ CLI 只从 clean Git HEAD 构造受限 bundle,输出不回显文件内容或
177
194
 
178
195
  `CREATE_NEW` 使用 `repositoryPlanRef {planNo,planHash}`;`ATTACH_EXISTING` 使用 `repositoryRef {repositoryKey,expectedHead}`。已有本地源码但无 remote 时,先锁 Repository plan,再创建 v3 parent;不要用受管模板覆盖本地项目,也不要另建第二个 `ATTACH_EXISTING` session。
179
196
 
180
- `PUBLISH_PROJECT` 必须接续 `app begin` 创建的同一会话并始终先 plan:
197
+ `PUBLISH_PROJECT` 必须接续 `app begin` 创建的同一会话并始终先 plan。v3 的 writer bootstrap 是服务端内部阶段,没有对应 CLI
181
198
 
182
199
  ```bash
183
200
  numa app onboard --session <session-no> --spec <spec-file> --plan --json
@@ -190,22 +207,45 @@ numa app first-build decide <session-no> --decision defer --idempotency-key <key
190
207
  numa pipeline inspect <application-code> --json
191
208
  ```
192
209
 
210
+ GitOps structural apply 完成后,服务端在原 session/task 内自动执行
211
+ `gitops-platform-writer-bootstrap/v2`。CLI 只用上面的 `app inspect` 续读
212
+ `GITOPS_V2_WRITER_BOOTSTRAP` 事件,不发送 bootstrap request。事件必须证明 exact 三文件
213
+ (base release、overlay values、overlay kustomization)的 contract/identity/revision/digest 都与原
214
+ Application/repository/binding/target 匹配。`PENDING` 只继续读取同一 session;`UNKNOWN` 或任何 drift
215
+ 均 fail closed,不进入 Observer/first-build,不调用 legacy migration,不新建应用/会话/绑定/
216
+ target,也不读取或修改 Secret。
217
+
218
+ `UNKNOWN` 必须先只读检查同一 session。普通 inspect/status 与 first-build 未知结果恢复不会触发
219
+ bootstrap;只有服务端把原内部步骤标记为可重入失败时,用户才显式调用现有通用 session retry:
220
+
221
+ ```bash
222
+ numa app inspect <session-no> --after-sequence <last-sequence> --json
223
+ numa app retry <session-no> --json
224
+ numa app inspect <session-no> --watch --after-sequence <last-sequence> --json
225
+ ```
226
+
227
+ `app retry` 不接收新 run/key、bootstrap/SCM/path/Secret/first-build 参数,服务端只恢复原
228
+ session/run/key。retry 后仍须读取同一 `GITOPS_V2_WRITER_BOOTSTRAP` 的 exact 成功证据;UNKNOWN/drift
229
+ 继续阻断,不重放 first-build POST、不手工修改 SCM、不创建新身份。
230
+
193
231
  Jenkins Job Control Plane 使用 `numa jenkins job plan .../apply/status/events`;默认 `scanMode=NONE`,`INDEX_ONLY` 也必须由服务端 NoTrigger 验证。`app jenkins-binding confirm` 只确认关系,不触发 build。首次 build 必须单独执行 `app first-build decide --decision trigger`;生产场景切换到 `numa-jenkins-deployment` 并提供真实审批证据。
194
232
 
195
- legacy Jenkins image writer 迁移与 rollout 是两个独立 gate。只有现有 overlay writer pointers 时才在 GitOps materialize/apply 前做 migration;普通 GitOps plan 已产生合规 pointers 时跳过。当前 `code-index` 生产 target `prd`、Jenkins instance 是 `numa`、approved shared-library commit `230e0f00444dfd1874e1ab3e624381341a0c31c5`;当前没有 service bindingmigration plan 不带 `--service-id`:
233
+ 新应用 v2 legacy writer 是两条并行路径。v2 使用同一 Application/session/repository/binding/target Job provenance replan,完成 GitOps structural apply 后再由 onboarding 自动执行上述 internal bootstrap;不运行 legacy migration。旧 v1 应用确有 pointer 缺失时才运行 migration。`code-index` 的旧 approved commit `230e0f...` 只属于 v1v2 必须使用本次新发布的 shared-library 40hex:
196
234
 
197
235
  ```bash
198
- numa gitops service legacy-image-migration plan --application code-index --target prd --profile MCI_FLUX_V1 --json
199
- numa gitops service apply <migration-plan-number> --plan-hash <64hex> --idempotency-key code-index-prd-image-migration-1 --yes --json
200
- numa jenkins gitops-rollout plan enable-platform --application code-index --instance numa --shared-library-revision 230e0f00444dfd1874e1ab3e624381341a0c31c5 --idempotency-key code-index-numa-rollout-plan-1 --yes --json
201
- numa jenkins gitops-rollout plan get <rollout-plan-no> --json
202
- numa jenkins gitops-rollout apply --plan-no <rollout-plan-no> --plan-hash <64hex> --idempotency-key code-index-numa-rollout-apply-1 --yes --json
203
- numa jenkins gitops-rollout list --application code-index --instance numa --json
204
- numa jenkins gitops-rollout get <rollout-no> --json
205
- numa jenkins gitops-rollout readiness <rollout-no> --desired-mode platform --expected-version <version> --operator-action-reference <change-record> --idempotency-key code-index-numa-readiness-1 --yes --json
236
+ numa jenkins platform-build-rollout plan enable-platform --application code-index --instance numa --shared-library-revision <approved-v2-shared-library-revision> --idempotency-key code-index-numa-v2-rollout-plan-1 --yes --json
237
+ numa jenkins platform-build-rollout plan get <rollout-plan-no> --json
238
+ numa jenkins platform-build-rollout apply --plan-no <rollout-plan-no> --plan-hash <64hex> --idempotency-key code-index-numa-v2-rollout-apply-1 --yes --json
239
+ numa jenkins platform-build-rollout list --application code-index --instance numa --json
240
+ numa jenkins platform-build-rollout get <rollout-no> --json
241
+ numa jenkins platform-build-rollout configure <rollout-no> --expected-version <version> --idempotency-key code-index-numa-v2-auto-configure-1 --yes --json
242
+ numa pipeline platform-build resolve --client-request-id <first-build-idempotency-key> --json
243
+ numa pipeline platform-build status <request-id> --watch --json
244
+ # 仅兼容旧部署/manual row 或 LEGACY rollout
245
+ numa jenkins gitops-rollout readiness <legacy-rollout-no> --desired-mode legacy --expected-version <version> --operator-action-reference <change-record> --idempotency-key code-index-numa-legacy-readiness-1 --yes --json
206
246
  ```
207
247
 
208
- migration plan 只接受 stable references,不接受 YAML/path/image/secret;READY 后复用 `gitops service apply`。rollout 所有写入要求 Idempotency-Key 与 `--yes`。`readiness` CLI GET 回传 exact tuple,固定为 `MANUAL_OPERATOR_ATTESTED`,不接受 secret/XML/env map/credential value,也不表示 Jenkins live-read。
248
+ v2 `platform-build-rollout` 所有写入要求 Idempotency-Key 与 `--yes`,且与旧 `gitops-rollout` 完全分离。automatic configure 前必须用 Project Publication CAS 发布只含 exact `@Library('mciShareLib@<approvedSharedLibraryRevision>') _` 与 `platformBuildEntry()` 的 Jenkinsfile,以及 strict `.mci/platform-build.yaml`;不能手工 Git push、改 global library、复用旧 `buildEntry()` 或使用 `mcexShareLib`。生产快照由 server-owned wrapper 执行,不加载应用 Jenkinsfile。configure 请求只含 `expectedVersion`,不接受 env/XML/Groovy/token/credential ID/value/operator attestation;v2 只要求平台 writer credential readiness,不要求 Jenkins Flux Git credential。首次 v2 build 不接受任意参数,productionReason 只留平台审计;未知 trigger 用 `platform-build resolve`,未知 stop 只读同一 request。旧 `gitops-rollout readiness` 固定为 `MANUAL_OPERATOR_ATTESTED`,不表示 Jenkins live-read。
209
249
 
210
250
  不要把数据库密码、SCM token 或其他 secret 放进 spec、delivery.parameters 或 build parameters。
211
251
 
@@ -216,6 +256,7 @@ migration plan 只接受 stable references,不接受 YAML/path/image/secret;
216
256
 
217
257
  ```bash
218
258
  numa repository status --client-request-id <original-id> --json
259
+ numa publication plan resolve --client-request-id <original-id> --json
219
260
  numa publication status --client-request-id <original-id> --json
220
261
  numa jenkins job status --client-request-id <original-id> --json
221
262
  numa app publication resolve <session-no> --client-request-id <original-id> --json
@@ -223,9 +264,10 @@ migration plan 只接受 stable references,不接受 YAML/path/image/secret;
223
264
  ```
224
265
 
225
266
  CLI 只有在写前 event cursor 之后观察到与本次 planHash/精确 intent 匹配的新持久事件时,才可能返回 `recovered_from_status=true`;既有 `WAITING_EXTERNAL` 或旧输出字段不能作为恢复证据。Repository、Publication、Jenkins 的 resolved run 还必须匹配请求 planNo 和响应中可用的稳定 workload identity。
267
+ - standalone `publication plan create` 的 500/504、连接中断或无效 2xx 只触发原 key 有界 GET resolve,POST 只发一次;恢复结果必须是同 repository 的 `STANDALONE` plan。retryable 404 `PUBLICATION_PLAN_NOT_RESOLVED` 只允许稍后继续 GET。
226
268
  - HTTP 2xx 后客户端 schema 解析失败不代表服务端失败。先 list/get 核实资源,禁止直接重放 POST。
227
- - legacy migration plan 无 Idempotency-Key/resolve-by-key,结果未知时 fail closed。Rollout plan create 也不按 key resolve;apply 必须用写前 list baseline 与写后 exact application/instance/plan mode/new version 恢复;readiness 必须用同 rollout 的 exact reference/mode/status/identity/new version 恢复。预存 READY/LEGACY 不是成功证据。
228
- - `WAITING_EXTERNAL` 使用 `resume`;可重入失败使用 `retry`;HEAD 移动使用 `reassess`。按服务端 recovery action 选择,不自行跳步骤。
269
+ - legacy migration plan 无 Idempotency-Key/resolve-by-key,结果未知时 fail closed。Rollout plan create 也不按 key resolve;apply 必须用写前 list baseline 与写后 exact application/instance/plan mode/new version 恢复;configure 未知时不重放,只 GET 同 rollout,并要求 exact identity/intent、new version、credential booleans=true、observed shared-library revision、verified source revision、Jenkinsfile/configuration digest 与 `READY/JENKINS_API_VERIFIED/VERIFIED`,否则 result unknown;source revision 不与 approved library revision 混同。旧 readiness 必须用同 rollout 的 exact reference/mode/status/identity/new version 恢复。预存 READY/LEGACY 不是成功证据。
270
+ - `WAITING_EXTERNAL` 使用 `resume`;可重入失败使用 `retry`;HEAD 移动使用 `reassess`。按服务端 recovery action 选择,不自行跳步骤。对 v3 writer bootstrap,必须先 inspect 原 session;只有显式 `app retry <same-session>` 可以触发 server-internal same-run/key recovery,普通 status/inspect 和 first-build unknown recovery 都保持纯读。
229
271
  - 生产 `pipeline build`、stop、retry 需要独立审批 ID 或具体 production reason;本 skill 默认只创建/核验流水线。
230
272
  - 不启动或遗留 `kubectl port-forward`、SSH tunnel 或后台代理来绕过网关;只读恢复仍失败时报告 profile/API origin、request ID 和上述恢复命令,等待平台恢复。
231
273
 
@@ -19,8 +19,10 @@
19
19
  | Jenkins Job plan/run | job plan/provision/status 命令 | `WAITING_EXTERNAL`,不得直接调用 Jenkins |
20
20
  | Application onboarding | v2/v3 capabilities 与 plan | 不创建 Application |
21
21
  | GitOps plan/apply | target/profile/service 命令 | 保留已完成 child,停止部署 |
22
+ | v3 writer bootstrap | 原 session status/events 中 exact `GITOPS_V2_WRITER_BOOTSTRAP` + `gitops-platform-writer-bootstrap/v2` 证据;它没有独立 CLI | `PENDING` 继续只读等待;`UNKNOWN` 先 inspect,仅显式通用 `app retry <same-session>` 可恢复原 run/key;drift fail closed |
22
23
  | Legacy image writer migration | `gitops service legacy-image-migration plan` 命令目录;不需要独立 server capability action | 保留 binding,不直写 YAML/path/image |
23
- | Jenkins GitOps rollout | `jenkins gitops-rollout plan/apply/list/get/readiness` 命令目录;readiness 必须自述 `MANUAL_OPERATOR_ATTESTED` | 保持 fail-closed gate,不触发首次 build |
24
+ | Platform build rollout v2 | `jenkins platform-build-rollout plan/apply/list/get/configure`;configure 必须自述 `JENKINS_API_VERIFIED/VERIFIED`;v2 无 manual readiness | 保持 fail-closed gate,不触发首次 build |
25
+ | Jenkins GitOps rollout v1 | `jenkins gitops-rollout plan/apply/list/get/readiness`;`MANUAL_OPERATOR_ATTESTED` 不是 live-read | 仅用于旧应用,不隐式升级 v2 |
24
26
  | Observer scope/evidence | binding/scope/evidence read API | 不把 target 或 Application 声称为 ACTIVE |
25
27
  | Pipeline deploy | confirmed binding 与生产审批 | 不触发 build |
26
28
 
@@ -42,9 +44,12 @@ Application onboarding 以 `numa app capabilities --json` 的服务端动作自
42
44
  适用于已有提交历史、clean HEAD、无任何 remote 的项目:
43
45
 
44
46
  1. 从 Jenkins `APP_NAME`、包名和目录名推断 application code;冲突时停止确认。
45
- 2. 查询 SCM connection、namespace、同名 remote、CREATE capability 和初始化限制。
47
+ 2. 查询 SCM connection、namespace、同名 remote、CREATE capability 和初始化限制。Codeup 先用
48
+ `numa app scm inspect <code> --json` 或 `numa repository connection list --json` 读取一等安全 readiness;
49
+ 只有 `codeupCredentialReadinessAvailable=true` 才解释 configured 布尔值。availability=`false`/缺失都
50
+ 保持 unknown,不从 `capabilities.executableMode` 推断 credential。
46
51
  3. 生成 Repository `CREATE` plan。仓库名默认等于稳定 application code,visibility 默认 PRIVATE。初始化方式必须来自 provider capability:Codeup 无空仓安全首次提交能力时使用受管 `README` 初始化,再由 publication CAS 更新同一 `README.md` 并创建其余清单文件;不得先建空仓再绕过控制平面推送。
47
- 4. 本地只读生成受限 publication manifest;manifest 锁定 source HEAD、mode、文件数量、总字节、每文件 digest 和整体 digest,不包含内容或凭据。若包含 `100755` 且 provider=Codeup,安全连接摘要必须证明 `codeupCloneCredentialConfigured=true`;否则以 `PUBLICATION_EXECUTABLE_MODE_UNSUPPORTED` 停止,不能把 Personal AT 当 HTTPS Git 密码。
52
+ 4. 本地只读生成受限 publication manifest;manifest 锁定 source HEAD、mode、文件数量、总字节、每文件 digest 和整体 digest,不包含内容或凭据。若包含 `100755` 且 provider=Codeup,安全连接摘要必须同时证明 `codeupCredentialReadinessAvailable=true` 与 `codeupCloneCredentialConfigured=true`;availability=`true` 下显式 false 是 missing,availability=`false`/缺失都是 unknown,二者都以 `PUBLICATION_EXECUTABLE_MODE_UNSUPPORTED` 停止。`codeupAccessTokenConfigured=true` 只证明 OpenAPI 可用,不能把 Personal AT 当 HTTPS Git 密码。
48
53
  5. 用 `app begin` 取得 session 后,在同一 session 创建 schemaVersion=3 onboarding parent plan;固定 `mode=NEW`、catalog/repository=`CREATE_NEW`、project=`PUBLISH_PROJECT`,并引用绑定该 session 的 Repository plan/ref。Repository child 完成后 parent 停在 `WAITING_EXTERNAL / ATTACH_PUBLICATION_PLAN`,此时才用 `app publication attach` 上传受控 bundle;服务端把 child consumer 固定为 `APPLICATION_ONBOARDING/<sessionNo>`,验证 parent planHash 和同一 manifest digest。客户端不能自报 consumer、remote URL、branch 或 provider credential。
49
54
  6. 远端创建或提交结果未知时复用同一 idempotency key,通过 run/events reconcile;不能直接重放成第二个仓库或第二次提交。
50
55
  7. 读回 remote HEAD/tree evidence 后继续同一个 onboarding session;不得另建 `ATTACH_EXISTING` 会话,也不得把独立 `STANDALONE` publication plan 附着到 parent。
@@ -76,8 +81,10 @@ PLAN_LEGACY_IMAGE_WRITER_MIGRATION_IF_REQUIRED
76
81
  WAIT_AUTHENTICATED_MIGRATION_APPLY
77
82
  PLAN_GITOPS_STRUCTURE
78
83
  WAIT_AUTHENTICATED_GITOPS_APPLY
84
+ WAIT_INTERNAL_GITOPS_V2_WRITER_BOOTSTRAP
79
85
  PLAN_AND_APPLY_JENKINS_GITOPS_ROLLOUT
80
- WAIT_TRUSTED_MANUAL_READINESS
86
+ VERIFY_MANAGED_JENKINSFILE_EXACT_MCI_SHARE_LIB_PIN
87
+ WAIT_JENKINS_API_VERIFIED_AUTOMATIC_CONFIGURE
81
88
  CONFIGURE_OBSERVER_SCOPE
82
89
  WAIT_FLUX_OBSERVER_ATTESTATION
83
90
  WAIT_EXPLICIT_FIRST_BUILD
@@ -88,38 +95,68 @@ COMPLETED
88
95
 
89
96
  Jenkins Job 创建、配置和 `INDEX_ONLY` scan 必须验证不会触发 build;默认 `scanMode=NONE`。首次 build 是独立 promote 决策:`DEFER` 永不触发且 parent 保持 `WAITING_EXTERNAL`,`TRIGGER` 必须使用 confirmed binding。生产 build 转入 `numa-jenkins-deployment`,要求真实审批依据。
90
97
 
91
- ### Legacy writer 与 Jenkins rollout gate
92
-
93
- 当只读证据证明现有 overlay 缺少 Jenkins writer pointers 时,migration 是受治理 GitOps materialize/apply 的前置。如果普通 GitOps plan 已生成合规 pointers,则不执行 migration。当前 `code-index`
94
- 的生产事实为 target=`prd`、Jenkins instance=`numa`、approved shared-library commit=
95
- `230e0f00444dfd1874e1ab3e624381341a0c31c5`;当前没有 service binding,因此 plan 不得猜测
96
- `--service-id`:
98
+ ### 并行 v2 writer 与 Jenkins rollout gate
99
+
100
+ 新应用 v2 不运行 legacy migration。先在原 onboarding session 内完成 v2 Job provenance replan
101
+ GitOps structural apply,随后由 onboarding v3 服务端内部自动执行
102
+ `gitops-platform-writer-bootstrap/v2`。该阶段只读写服务自己的 base release、exact overlay values 和
103
+ overlay kustomization 三个文件;不枚举、不读取也不改写 sibling raw Secret,也不新建
104
+ Application、session、binding 或 target。CLI 不提供 bootstrap 命令,只续读原 session 的
105
+ `GITOPS_V2_WRITER_BOOTSTRAP` 事件;`PENDING` 只等待,`UNKNOWN` 或 contract/identity/revision/digest
106
+ drift 都禁止 Observer/first-build。旧 v1 应用只有在确有 writer pointer 缺失时才使用 legacy migration。
107
+ `UNKNOWN` 先 inspect 原 session;只有服务端把原内部步骤标记为可重入失败时,用户才显式执行
108
+ `numa app retry <same-session> --json`。该通用恢复只让服务端续作原 run/key,不创建 bootstrap
109
+ 命令、请求或身份;status/inspect 与 first-build 未知结果恢复保持纯读。retry 后仍为 UNKNOWN 或存在
110
+ drift 时继续阻断,不重放 first-build POST,也不手工写 SCM。
111
+ `code-index` 目标仍是原 target=`prd`、Jenkins instance=`numa`;旧批准提交
112
+ `230e0f...` 是 v1,不得用于 v2 plan。v2 必须等新的 clean shared-library 40hex 发布后再执行:
97
113
 
98
114
  ```bash
99
- numa gitops service legacy-image-migration plan --application code-index --target prd --profile MCI_FLUX_V1 --json
100
- numa gitops service apply <migration-plan-number> --plan-hash <64hex> --idempotency-key code-index-prd-image-migration-1 --yes --json
101
- numa jenkins gitops-rollout plan enable-platform --application code-index --instance numa --shared-library-revision 230e0f00444dfd1874e1ab3e624381341a0c31c5 --idempotency-key code-index-numa-rollout-plan-1 --yes --json
102
- numa jenkins gitops-rollout plan get <rollout-plan-no> --json
103
- numa jenkins gitops-rollout apply --plan-no <rollout-plan-no> --plan-hash <64hex> --idempotency-key code-index-numa-rollout-apply-1 --yes --json
104
- numa jenkins gitops-rollout get <rollout-no> --json
105
- numa jenkins gitops-rollout readiness <rollout-no> --desired-mode platform --expected-version <version> --operator-action-reference <change-record> --idempotency-key code-index-numa-readiness-1 --yes --json
115
+ numa jenkins platform-build-rollout plan enable-platform --application code-index --instance numa --shared-library-revision <approved-v2-shared-library-revision> --idempotency-key code-index-numa-v2-rollout-plan-1 --yes --json
116
+ numa jenkins platform-build-rollout plan get <rollout-plan-no> --json
117
+ numa jenkins platform-build-rollout apply --plan-no <rollout-plan-no> --plan-hash <64hex> --idempotency-key code-index-numa-v2-rollout-apply-1 --yes --json
118
+ numa jenkins platform-build-rollout get <rollout-no> --json
119
+ numa jenkins platform-build-rollout configure <rollout-no> --expected-version <version> --idempotency-key code-index-numa-v2-auto-configure-1 --yes --json
120
+ # onboarding session 的 first-build action 内部触发 v2;未知时用独立只读入口恢复
121
+ numa pipeline platform-build resolve --client-request-id <first-build-idempotency-key> --json
122
+ numa pipeline platform-build status <request-id> --watch --json
123
+ # 仅兼容旧部署/manual row 或 LEGACY rollout
124
+ numa jenkins gitops-rollout readiness <legacy-rollout-no> --desired-mode legacy --expected-version <version> --operator-action-reference <change-record> --idempotency-key code-index-numa-legacy-readiness-1 --yes --json
106
125
  ```
107
126
 
108
- migration plan 请求不接受 YAML/path/image/secret/credential,CLI 也不输出文件 path/diff/pointer
109
- rollout apply 只持久化 gate,不连接 Jenkins、不改全局配置、不触发 build。readiness
110
- trusted manual attestation,不是 live-read;CLI GET 响应回传 exact tuple 与 credential reference names,
111
- 不接收 credential value、raw XML env map
127
+ rollout apply 只持久化 gate,不连接 Jenkins、不改全局配置、不触发 buildautomatic configure 前必须
128
+ 证明受管 Jenkinsfile 已由 Project Publication CAS 发布 exact
129
+ 只含 `@Library('mciShareLib@<approvedSharedLibraryRevision>') _` `platformBuildEntry()`,并同时发布 strict `.mci/platform-build.yaml`;未完成时回到 Publication plan,不能手工
130
+ Git push、改 Jenkins global library、复用旧 `buildEntry()` 或用 `mcexShareLib`。生产快照使用 server-owned wrapper,不执行应用 Jenkinsfileconfigure 请求只含 `expectedVersion`,不接收
131
+ env/XML/Groovy/token/credential ID/value/operator attestation;只输出服务端派生 public tuple、credential 配置
132
+ booleans、observed shared-library revision、verified source revision、Jenkinsfile/build-profile/configuration digest 与 `READY/JENKINS_API_VERIFIED/VERIFIED`。verified source revision 是源码快照,不要求等于 approved library revision。旧 readiness 是
133
+ trusted manual attestation compatibility,不是 live-read。
134
+
135
+ v2 platform-build 不接受任何 `--param`,生产审批依据只进入平台审计;Jenkins 只构建镜像并提交一次
136
+ image intent,不持有 Flux Git credential,不运行 kubectl。DevOps server 在 contract/build/stop 同一锁下
137
+ 执行 SCM CAS;未知结果只按原 request id GET,Observer 独立证明 Flux 运行态。旧 `pipeline build` 与
138
+ legacy writer 行为不变。
139
+
140
+ 若 migration plan 返回 `GITOPS_RAW_SECRET_FORBIDDEN`,这是 hard blocker,不是“按 recovery 处理”的泛化提示:
141
+
142
+ 1. 不读取、复制或回显 Secret value,不把 raw value 改成普通 base64,不直接删除 Secret,也不绕过 migration/GitOps plan 手改目标。
143
+ 2. 优先由 secret owner 迁到目标集群已登记的 ExternalSecret 或 SealedSecret provider,再重新生成受治理 plan。
144
+ 3. 只有目标集群确认没有任何已登记 provider 时,才可把保留现有 Secret 的动作作为显式受审两阶段桥。第一阶段必须使用 clean、受控的 Flux 仓库,为现有 Flux-managed Secret 资源增加 `kustomize.toolkit.fluxcd.io/prune: disabled`,reconcile 后用 Observer/live evidence 验证目标集群同一 Secret 的 annotation 已生效。
145
+ 4. 第二阶段使用独立变更单移除 raw Secret manifest/reference,再次 reconcile,并验证同一 Secret 仍存在且未被 prune。随后由 secret owner 轮换所有曾进入 Git 历史的值;桥接不等于已消除泄露。
146
+ 5. 两阶段及轮换分别要求明确 owner、变更单和审批,不能复用应用创建/promote 的笼统确认。本地 `mci-flux` dirty、目标 Secret 身份不唯一、annotation/live evidence 不足或任一步结果未知时均 fail closed,不能继续 migration、rollout 或首次 build。
112
147
 
113
148
  ## 安全与恢复
114
149
 
115
150
  - CLI 从不接受 SCM/Jenkins credential 参数;凭据由平台引用。
116
151
  - publication 拒绝 `.git`、凭据文件、Secret、symlink、socket/device、绝对/父路径和超限 bundle。
117
- - Codeup Personal AT 只证明 OpenAPI 能力;包含 `100755` 的 tree 还要求平台已托管独立 HTTPS clone username/password。只读检查安全 readiness boolean,缺失时以 `PUBLICATION_EXECUTABLE_MODE_UNSUPPORTED` 停止,不把 AT Git password
152
+ - Codeup Personal AT 只证明 OpenAPI 能力;包含 `100755` 的 tree 还要求平台已托管独立 HTTPS clone username/password。只读检查普通 `app scm` 或顶层 repository connection 返回的 `codeupCredentialReadinessAvailable=true` 和 `codeupCloneCredentialConfigured=true`;availability=`false`/缺失是 unknown,availability=`true` 下显式 false 才是 missing,两者都以 `PUBLICATION_EXECUTABLE_MODE_UNSUPPORTED` 停止。不要用 `codeupAccessTokenConfigured` `capabilities.executableMode` 代替,也不要读取 admin/credential
153
+ - 需要管理员补齐 Codeup credential 时,交互操作使用 `app scm rotate ... --credential-prompt` 原生隐藏输入;不要让用户通过聊天提供值,也不要生成 Python/getpass 管道。非交互操作保留 chmod 600 文件或重定向 stdin。
118
154
  - 每个 child 保存 plan/hash、run number、idempotency key、last event sequence;onboarding publication child 只能通过 session-scoped bridge 创建。
119
155
  - HTTP 2xx 后 schema 解析失败属于结果未知;先 list/status/get,不能直接重放。
120
- - legacy migration plan 没有 Idempotency-Key/resolve-by-key,未知结果必须 fail closed。Rollout plan 也不按 key resolve;apply 只在写前 baseline 之后出现 exact application/instance/plan mode 且新 version 时恢复;readiness 只在同 rollout 出现 exact reference/mode/status/identity 且新 version 时恢复。预存 READY/LEGACY 不构成证据。
121
- - 普通 profile HTTPS 网关失败时,Repository/standalone Publication/Jenkins 先按原 clientRequestId 查 `status`,普通 session action 先 `app inspect`;publication attach 必须先按原 `sessionNo/clientRequestId` 执行 `app publication resolve`。其 retryable 404 只能稍后重查,禁止自动重放 attach;不要启动或遗留 port-forward/tunnel 旁路。
156
+ - legacy migration plan 没有 Idempotency-Key/resolve-by-key,未知结果必须 fail closed。Rollout plan 也不按 key resolve;apply 只在写前 baseline 之后出现 exact application/instance/plan mode 且新 version 时恢复;configure 未知时不重放,只 GET 同 rollout,并要求 exact identity/intent、new version、credential booleans=true、observed shared-library revision、verified source revision、Jenkinsfile/configuration digest 和 `READY/JENKINS_API_VERIFIED/VERIFIED`,`STALE/DRIFTED/UNAVAILABLE` 或证据不足均 result unknown;旧 readiness 只在同 rollout 出现 exact reference/mode/status/identity 且新 version 时恢复。预存 READY/LEGACY 不构成证据。
157
+ - 普通 profile HTTPS 网关失败时,Repository/Jenkins run 按原 clientRequestId 查 `status`;standalone publication plan create 的 500/504、连接中断或无效 2xx 只按原 key 有界 GET `publication plan resolve`,校验 `STANDALONE`/repository identity,POST 只发一次,retryable 404 只稍后 GET。普通 session action 先 `app inspect`;publication attach 必须先按原 `sessionNo/clientRequestId` 执行 `app publication resolve`。其 retryable 404 只能稍后重查,禁止自动重放 attach;不要启动或遗留 port-forward/tunnel 旁路。
122
158
  - session action 的自动恢复必须以写前 event cursor 为基线,只接受 cursor 之后与本次 planHash/精确 intent 匹配的新持久事件;既有 `WAITING_EXTERNAL` 或旧 observer/build/binding 字段不是本次写成功的证据。child run resolve 必须至少匹配请求 planNo,并校验响应中可用的 repository/workload identity。
159
+ - v3 bootstrap 不是客户端写请求;只能从原 session 的 `GITOPS_V2_WRITER_BOOTSTRAP` 事件读取结果。PENDING 只读等待;UNKNOWN 先 inspect,且仅在服务端声明可重入时通过显式通用 `app retry <same-session>` 恢复原 run/key。普通 status/inspect 和 first-build recovery 都是纯读;不得重放 first-build POST、调用 legacy migration、手工写 SCM 或另建身份。retry 后仍 UNKNOWN 或 drift 时保持 fail closed。
123
160
  - Jenkins scan 不等于 build;观察到意外 build 时停止父流程并报告。
124
161
  - GitOps target 只有 topology validation 时保持 DRAFT;Jenkins attestation 最多推进 VERIFYING,只有独立 Flux Observer evidence 能推进 ACTIVE。
125
162
 
@@ -130,5 +167,7 @@ trusted manual attestation,不是 live-read;CLI 从 GET 响应回传 exact t
130
167
  - Application 只创建/接管一个,Repository 关系正确。
131
168
  - Multibranch Job 配置 digest 与计划一致,未意外触发 build。
132
169
  - Jenkins binding 为 CONFIRMED,目标 branch 可构建。
170
+ - onboarding v3 在 GitOps structural apply 后已以同一 session/task 产生 exact `GITOPS_V2_WRITER_BOOTSTRAP` 成功证据;contract 为 `gitops-platform-writer-bootstrap/v2`,三文件及 identity/revision/digest 无 drift。
171
+ - Jenkins GitOps rollout automatic configure 达到 `READY/JENKINS_API_VERIFIED/VERIFIED`,observed shared-library revision、verified source revision、Jenkinsfile/configuration digest 均完整且与各自 intent 一致;source revision 不要求等于 approved library revision。仅旧部署可记录 manual compatibility evidence。
133
172
  - GitOps service binding 和 exact Observer scope 存在;configRevision 与 observedRevision 一致后才 ACTIVE。
134
173
  - 未经独立生产授权不得触发 build;触发后必须以 Jenkins 终态和 Flux/Observer evidence 验收。
@@ -223,6 +223,7 @@ const result = {
223
223
  jenkinsfile: fileSet.has('Jenkinsfile'),
224
224
  jenkinsVariables,
225
225
  buildEntry: /\bbuildEntry\(\)/u.test(jenkins),
226
+ platformBuildEntry: /\bplatformBuildEntry\(\)/u.test(jenkins),
226
227
  dockerfile: fileSet.has('Dockerfile'),
227
228
  dockerExposedPorts: [...dockerfile.matchAll(/^EXPOSE\s+([^\r\n#]+)/gmu)].map((match) => match[1].trim()),
228
229
  hasCompose: fileSet.has('compose.yaml') || fileSet.has('docker-compose.yml')