openxiangda 1.0.244 → 1.0.245
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/README.md +1 -1
- package/lib/cli.js +74 -6
- package/openxiangda-skills/SKILL.md +2 -2
- package/openxiangda-skills/skills/openxiangda-core/SKILL.md +1 -1
- package/package.json +2 -1
- package/templates/openxiangda-react-spa/.cursor/rules/openxiangda.mdc +1 -0
- package/templates/openxiangda-react-spa/.qoder/rules/openxiangda.md +1 -0
- package/templates/openxiangda-react-spa/AGENTS.md +2 -0
- package/templates/sy-lowcode-app-workspace/.cursor/rules/openxiangda.mdc +1 -0
- package/templates/sy-lowcode-app-workspace/.qoder/rules/openxiangda.md +1 -0
- package/templates/sy-lowcode-app-workspace/AGENTS.md +1 -0
package/README.md
CHANGED
|
@@ -107,7 +107,7 @@ openxiangda app snapshot APP_XXXX --profile dev --json
|
|
|
107
107
|
|
|
108
108
|
User tokens are stored in `~/.openxiangda/profiles.json` with `0600` permissions. Shared workspace environment values, including `APP_OSS_*`, can live in `~/.openxiangda/.env` and are inherited by new workspaces. Project `.env` files still work and override the global defaults. Project state is stored in `.openxiangda/state.json` and contains only durable profile-specific resource IDs and environment bindings; volatile candidate/deployment progress lives in the private `.openxiangda/releases/` journal so a release does not dirty the reviewed Git state. Durable CLI writes use a workspace lock plus atomic merge/rename so concurrent processes do not truncate another profile's state.
|
|
109
109
|
|
|
110
|
-
An environment-managed workspace keeps one logical application with independent `preproduction` and `production` targets. Each target owns its own `appType`, resource IDs, release heads, data, and side-effect policy; IDs must never be copied across targets. `release ship` always executes the same ordered candidate → preproduction → production protocol. The normal first invocation seals the candidate, deploys only to preproduction, and stops at `awaiting_production_confirmation`; a later invocation with `--confirm-production` promotes it. For an explicitly authorized emergency, supplying `--confirm-production` on the first invocation runs both phases in one command without bypassing preproduction, CAS, evidence, or production confirmation. Candidate sealing covers source, `public/`, build controls/scripts, stable environment/resource bindings, and target-specific hashed Runtime artifacts. Both deployments upload those artifacts with `--no-build`; each deployment is completed with evidence and reaches terminal `succeeded`, so it cannot leave the target slot blocked. Unrelated commits may land on authoritative mainline between phases only while the sealed commit remains an ancestor and every sealed input/binding/artifact still validates. Real human acceptance remains the recommended default and `--acceptance-note` records it. For audited historical-lineage adoption or reviewed Backend manifest replacement, the existing paired flags and exact-scope gates remain mandatory. Supported configuration resources use exact `resourceSelectors`; unknown, wildcard, destructive, and genuinely unscoped generic resources remain blocked. Lower-level candidate/deploy/test/promote commands are recovery primitives. Direct `release publish` is retained only for legacy unmanaged workspaces.
|
|
110
|
+
An environment-managed workspace keeps one logical application with independent `preproduction` and `production` targets. Each target owns its own `appType`, resource IDs, release heads, data, and side-effect policy; IDs must never be copied across targets. `release ship` always executes the same ordered candidate → preproduction → production protocol. The normal first invocation seals the candidate, deploys only to preproduction, and stops at `awaiting_production_confirmation`; a later invocation with `--confirm-production` promotes it. For an explicitly authorized emergency, supplying `--confirm-production` on the first invocation runs both phases in one command without bypassing preproduction, CAS, evidence, or production confirmation. Candidate sealing covers source, `public/`, build controls/scripts, stable environment/resource bindings, and target-specific hashed Runtime artifacts. Both deployments upload those artifacts with `--no-build`; each deployment is completed with evidence and reaches terminal `succeeded`, so it cannot leave the target slot blocked. Unrelated commits may land on authoritative mainline between phases only while the sealed commit remains an ancestor and every sealed input/binding/artifact still validates. Real human acceptance remains the recommended default and `--acceptance-note` records it. For audited historical-lineage adoption or reviewed Backend manifest replacement, the existing paired flags and exact-scope gates remain mandatory. Supported configuration resources use exact `resourceSelectors`; unknown, wildcard, destructive, and genuinely unscoped generic resources remain blocked. Lower-level candidate/deploy/test/fail/promote commands are recovery primitives. `release fail` requires an explicit preproduction target, deployment ID, and audit message; it verifies the deployment belongs to that preproduction environment before writing optional code/details to the platform failure audit. Direct `release publish` is retained only for legacy unmanaged workspaces.
|
|
111
111
|
|
|
112
112
|
Exact, non-destructive configuration selectors such as Data Views and permission groups are now sequenced automatically inside the same ship journal instead of requiring separate SDD changes. New forms are idempotently ensured per environment before their immutable FormRelease is staged. Unscoped resources and destructive configuration deletes remain fail-closed.
|
|
113
113
|
|
package/lib/cli.js
CHANGED
|
@@ -336,7 +336,7 @@ Usage:
|
|
|
336
336
|
openxiangda retry <runId> [--environment preproduction|production] [--json]
|
|
337
337
|
openxiangda rollback <preproduction|production> --to <appReleaseId> [--json]
|
|
338
338
|
openxiangda release publish|begin|status|integration-status|renew|end [--change id] [--profile name] [--watch] [--json]
|
|
339
|
-
openxiangda release ship|candidate|deploy|test|promote|rollback [--candidate id] [--environment target] [--replace-manifest] [--allow-runtime-rollback --reason text] [--adopt-online-baseline --adoption-reason text] [--json]
|
|
339
|
+
openxiangda release ship|candidate|deploy|reconcile|test|fail|promote|rollback [--candidate id] [--deployment id] [--environment target] [--replace-manifest] [--allow-runtime-rollback --reason text] [--adopt-online-baseline --adoption-reason text] [--confirm-production] [--json]
|
|
340
340
|
openxiangda task status --change <id> [--profile name] [--watch] [--json]
|
|
341
341
|
openxiangda release backend-head|backend-list|backend-detail|backend-diff|backend-rollback|backend-abort|backend-retry [releaseId] [--profile name] [--json]
|
|
342
342
|
openxiangda release app-capture|app-head|app-list|app-detail|app-diff|app-prepare|app-verify|app-activate|app-finalize|app-rollback|app-abort [releaseId] [--staged-resources-json <JSON|file>] [--activate-staged-children] [--break-glass-adopt-verified-root --reason text] [--force-activate-without-validation] [--profile name] [--json]
|
|
@@ -5006,6 +5006,65 @@ async function runApplicationEnvironmentReleaseCommand(
|
|
|
5006
5006
|
return { deployment: reconciled, reconciled: true };
|
|
5007
5007
|
}
|
|
5008
5008
|
|
|
5009
|
+
if (subcommand === 'fail') {
|
|
5010
|
+
if (target.environmentKind !== 'preproduction') {
|
|
5011
|
+
fail(
|
|
5012
|
+
'RELEASE_FAIL_PREPRODUCTION_ONLY: release fail 只允许 preproduction target,禁止用于 production deployment'
|
|
5013
|
+
);
|
|
5014
|
+
}
|
|
5015
|
+
const deploymentId =
|
|
5016
|
+
readStringFlag(flags, 'deployment') ||
|
|
5017
|
+
readStringFlag(flags, 'deployment-id');
|
|
5018
|
+
const message = readStringFlag(flags, 'message');
|
|
5019
|
+
const failureCode = readStringFlag(flags, 'code');
|
|
5020
|
+
const detailsInput = readStringFlag(flags, 'details-json');
|
|
5021
|
+
if (!deploymentId || !message) {
|
|
5022
|
+
fail(
|
|
5023
|
+
'release fail 必须显式提供 --deployment <id> 和 --message <text>'
|
|
5024
|
+
);
|
|
5025
|
+
}
|
|
5026
|
+
const details = detailsInput
|
|
5027
|
+
? readJsonInput(detailsInput, 'details-json')
|
|
5028
|
+
: null;
|
|
5029
|
+
const deployment = await requestWithAuth(
|
|
5030
|
+
config,
|
|
5031
|
+
target.profileName,
|
|
5032
|
+
applicationDeploymentApiPath(logicalApp.code, deploymentId)
|
|
5033
|
+
);
|
|
5034
|
+
if (
|
|
5035
|
+
deployment?.id !== deploymentId ||
|
|
5036
|
+
deployment?.targetEnvironmentId !== target.environmentId
|
|
5037
|
+
) {
|
|
5038
|
+
fail(
|
|
5039
|
+
`RELEASE_FAIL_DEPLOYMENT_ENVIRONMENT_MISMATCH: deployment ${deploymentId} 不属于当前预发环境 ${target.targetName}(${target.environmentId}),未写入失败状态`
|
|
5040
|
+
);
|
|
5041
|
+
}
|
|
5042
|
+
const failed = await requestWithAuth(
|
|
5043
|
+
config,
|
|
5044
|
+
target.profileName,
|
|
5045
|
+
applicationDeploymentApiPath(
|
|
5046
|
+
logicalApp.code,
|
|
5047
|
+
deploymentId,
|
|
5048
|
+
'fail'
|
|
5049
|
+
),
|
|
5050
|
+
{
|
|
5051
|
+
method: 'POST',
|
|
5052
|
+
body: {
|
|
5053
|
+
...(failureCode ? { code: failureCode } : {}),
|
|
5054
|
+
message,
|
|
5055
|
+
...(details ? { details } : {}),
|
|
5056
|
+
},
|
|
5057
|
+
}
|
|
5058
|
+
);
|
|
5059
|
+
if (failed?.status !== 'failed') {
|
|
5060
|
+
fail(
|
|
5061
|
+
`DEPLOYMENT_FAILURE_NOT_CONFIRMED: deployment ${deploymentId} 标记失败后状态为 ${failed?.status || 'unknown'}`
|
|
5062
|
+
);
|
|
5063
|
+
}
|
|
5064
|
+
rememberTargetDeployment(target, failed);
|
|
5065
|
+
return { deployment: failed, failed: true };
|
|
5066
|
+
}
|
|
5067
|
+
|
|
5009
5068
|
if (['deploy', 'promote'].includes(subcommand)) {
|
|
5010
5069
|
assertManagedRuntimeRollbackFlags(flags);
|
|
5011
5070
|
}
|
|
@@ -5131,7 +5190,7 @@ async function release(args) {
|
|
|
5131
5190
|
if (wantsSubcommandHelp(subcommand, flags)) {
|
|
5132
5191
|
print([
|
|
5133
5192
|
'用法: openxiangda release publish|begin|status|explain|integration-status|renew|end [--change id] [--profile name] [--json]',
|
|
5134
|
-
' openxiangda release ship|candidate|deploy|reconcile|test|promote|rollback [--candidate id] [--environment target] [--replace-manifest] [--allow-runtime-rollback --reason text] [--adopt-online-baseline --adoption-reason text] [--confirm-production] [--json]',
|
|
5193
|
+
' openxiangda release ship|candidate|deploy|reconcile|test|fail|promote|rollback [--candidate id] [--deployment id] [--environment target] [--replace-manifest] [--allow-runtime-rollback --reason text] [--adopt-online-baseline --adoption-reason text] [--confirm-production] [--json]',
|
|
5135
5194
|
' openxiangda release backend-head|backend-list|backend-detail|backend-diff|backend-rollback|backend-abort|backend-retry [releaseId] [--profile name] [--json]',
|
|
5136
5195
|
' openxiangda release app-capture|app-head|app-list|app-detail|app-diff|app-post-commit|app-retry|app-prepare|app-verify|app-activate|app-finalize|app-rollback|app-abort [releaseId] [--staged-resources-json <JSON|file>] [--activate-staged-children] [--break-glass-adopt-verified-root --reason text] [--force-activate-without-validation] [--profile name] [--json]',
|
|
5137
5196
|
'常用流程:',
|
|
@@ -5141,6 +5200,7 @@ async function release(args) {
|
|
|
5141
5200
|
' openxiangda release ship --change <id> --profile <name> --allow-runtime-rollback --reason "已审计并批准 Runtime 源码基线回退"',
|
|
5142
5201
|
' # 确认预发结果后;可选 --acceptance-note 留下人工验收记录:',
|
|
5143
5202
|
' openxiangda release ship --change <id> --profile <name> --confirm-production',
|
|
5203
|
+
' openxiangda release fail --deployment <id> --message "UAT 未通过" --code UAT_FAILED --details-json <JSON|file> --environment preproduction --profile <name>',
|
|
5144
5204
|
' openxiangda release publish --change <id> --profile <name>',
|
|
5145
5205
|
' openxiangda release begin --change <id> --profile <name>',
|
|
5146
5206
|
' openxiangda resource publish function --only <code> --change <id> --profile <name>',
|
|
@@ -5157,6 +5217,7 @@ async function release(args) {
|
|
|
5157
5217
|
' - 已合入主线但线上来自多次历史 lineage 的精确非删除恢复可显式使用 --adopt-online-baseline 与 --adoption-reason;预发冻结后,正式确认会从 ship.json 自动复用同一意图,仍保留冻结 Head、CAS、租约、staged children 和单次 App finalize。',
|
|
5158
5218
|
' - ship 的 --replace-manifest 与 --reason 必须成对,只透传给精确 Backend Function/Automation stage;正式确认必须复用与预发完全相同的参数。',
|
|
5159
5219
|
' - --allow-runtime-rollback 与 --reason 必须成对,只透传给 runtime-stage;ship 会冻结并在正式确认自动复用该审计意图,app-finalize 不会收到这些参数。',
|
|
5220
|
+
' - release fail 只允许显式选择 preproduction target,并会先核对 deployment 的 targetEnvironmentId;message 必填,code/details 会一并写入平台审计。',
|
|
5160
5221
|
' - ship 当前不支持 --dry-run;任何未声明参数都会在 candidate/deployment 写入前 fail-closed。需要只读检查时使用 environment status/diff 与 release status。',
|
|
5161
5222
|
' - publish 默认等待租约并按私有执行日志恢复;上次写结果不确定时必须只读核对后显式 --resume-after-review。',
|
|
5162
5223
|
' - app-head 默认只输出紧凑 head 摘要;需要完整 manifest 时显式追加 --full。',
|
|
@@ -5182,9 +5243,16 @@ async function release(args) {
|
|
|
5182
5243
|
flags
|
|
5183
5244
|
);
|
|
5184
5245
|
if (
|
|
5185
|
-
[
|
|
5186
|
-
|
|
5187
|
-
|
|
5246
|
+
[
|
|
5247
|
+
'ship',
|
|
5248
|
+
'candidate',
|
|
5249
|
+
'deploy',
|
|
5250
|
+
'reconcile',
|
|
5251
|
+
'test',
|
|
5252
|
+
'fail',
|
|
5253
|
+
'promote',
|
|
5254
|
+
'rollback',
|
|
5255
|
+
].includes(subcommand)
|
|
5188
5256
|
) {
|
|
5189
5257
|
const result = await runApplicationEnvironmentReleaseCommand(
|
|
5190
5258
|
config,
|
|
@@ -16496,7 +16564,7 @@ async function commands(args) {
|
|
|
16496
16564
|
'design gates|template|review [--topic code]',
|
|
16497
16565
|
'sdd init|migrate|propose|quick|bundle|approve|status|context|verify|sync|archive',
|
|
16498
16566
|
'environment init|attach|bind|swap|policy update|list|status|diff|use',
|
|
16499
|
-
'release ship|candidate|deploy|test|promote|rollback|publish|begin|status|integration-status|renew|end|backend-head|backend-list|backend-detail|backend-diff|backend-rollback|backend-abort|backend-retry|app-capture|app-head|app-list|app-detail|app-diff|app-prepare|app-verify|app-activate|app-finalize|app-rollback|app-abort',
|
|
16567
|
+
'release ship|candidate|deploy|reconcile|test|fail|promote|rollback|publish|begin|status|integration-status|renew|end|backend-head|backend-list|backend-detail|backend-diff|backend-rollback|backend-abort|backend-retry|app-capture|app-head|app-list|app-detail|app-diff|app-prepare|app-verify|app-activate|app-finalize|app-rollback|app-abort',
|
|
16500
16568
|
'studio [--no-open] [--port 0]',
|
|
16501
16569
|
'env',
|
|
16502
16570
|
'workspace init|bind|cleanup|plan|check|publish [--app-name] [--apply|--changed|--since|--form|--page|--only|--dry-run|--force|--resources|--skip-resources|--prune]',
|
|
@@ -127,7 +127,7 @@ openxiangda release ship --change <release-change> --profile <name> \
|
|
|
127
127
|
--confirm-production
|
|
128
128
|
```
|
|
129
129
|
|
|
130
|
-
For a workspace registered by `environment init` or connected by `environment attach`, production is never a direct publish target. `release ship` always executes candidate → preproduction → production. The normal first invocation stops after preproduction; a later `--confirm-production` promotes the same candidate. If the user explicitly authorizes an emergency, putting `--confirm-production` on the first invocation runs both phases in one command without skipping preproduction, evidence, CAS, or confirmation. The sealed candidate contains source/build/public/script inputs, stable environment/resource bindings, and hashed target-specific Runtime artifacts; deployment uploads those exact artifacts with no rebuild and closes each server deployment as `succeeded`. Human acceptance remains recommended and may be recorded with `--acceptance-note`. Lower-level candidate/deploy/test/promote commands are recovery primitives. Keep preproduction and production identities isolated, and retain the existing authorization/CAS rules for environment swap and policy changes. Use `openxiangda studio` for bindings, drift, evidence, and safe next actions.
|
|
130
|
+
For a workspace registered by `environment init` or connected by `environment attach`, production is never a direct publish target. `release ship` always executes candidate → preproduction → production. The normal first invocation stops after preproduction; a later `--confirm-production` promotes the same candidate. If the user explicitly authorizes an emergency, putting `--confirm-production` on the first invocation runs both phases in one command without skipping preproduction, evidence, CAS, or confirmation. The sealed candidate contains source/build/public/script inputs, stable environment/resource bindings, and hashed target-specific Runtime artifacts; deployment uploads those exact artifacts with no rebuild and closes each server deployment as `succeeded`. Human acceptance remains recommended and may be recorded with `--acceptance-note`. Lower-level candidate/deploy/test/fail/promote commands are recovery primitives. `release fail` is preproduction-only: pass an explicit deployment and audit message, and the CLI verifies the deployment belongs to the selected preproduction environment before it writes optional code/details. Keep preproduction and production identities isolated, and retain the existing authorization/CAS rules for environment swap and policy changes. Use `openxiangda studio` for bindings, drift, evidence, and safe next actions.
|
|
131
131
|
|
|
132
132
|
A sealed candidate may be promoted from a later clean, pushed authoritative mainline commit only when the candidate commit remains its Git ancestor and every sealed candidate input file still has the exact recorded hash. This permits unrelated parallel merges without allowing stale candidate inputs to overwrite newer work. Do not edit private candidate metadata to bypass `CANDIDATE_INPUTS_CHANGED`. The CLI waits for both the app lease and target deployment slot; each target permits only one running or evidence-pending deployment. Emergency fixes stay on the same candidate → preproduction → production path with a narrow L1 scope. `--wait-seconds 0` is fail-fast, not a binding-contract, CAS, or production-confirmation bypass.
|
|
133
133
|
|
|
@@ -139,7 +139,7 @@ When the sealed Runtime source intentionally does not descend from the active Ru
|
|
|
139
139
|
|
|
140
140
|
`resource plan` and publish dry-runs are strictly GET/HEAD-only. `READ_ONLY_AUTH_REQUIRED` means the access token expired; run `openxiangda auth refresh --profile <name>` or log in again before retrying. Never add an automatic refresh POST inside a plan.
|
|
141
141
|
|
|
142
|
-
`release publish` is the default promotion entrypoint only for legacy unmanaged workspaces. It verifies without rewriting reviewed `change.json`/`release.json`, waits for the app lease, freezes the App capture after ownership is acquired, executes deterministic exact staged steps, resumes from `.openxiangda/releases/<change>/execution.json`, atomically finalizes, verifies mainline integration, and releases the lease. Environment-managed applications use the two-phase `release ship`; candidate/deploy/test/promote, `release begin`, and child commands remain recovery/diagnostic primitives.
|
|
142
|
+
`release publish` is the default promotion entrypoint only for legacy unmanaged workspaces. It verifies without rewriting reviewed `change.json`/`release.json`, waits for the app lease, freezes the App capture after ownership is acquired, executes deterministic exact staged steps, resumes from `.openxiangda/releases/<change>/execution.json`, atomically finalizes, verifies mainline integration, and releases the lease. Environment-managed applications use the two-phase `release ship`; candidate/deploy/test/fail/promote, `release begin`, and child commands remain recovery/diagnostic primitives.
|
|
143
143
|
|
|
144
144
|
Reviewed bundle commands may retain `<profile>` as a template. The explicit real `release publish --profile <name>` value is bound to actual child argv without rewriting tracked SDD. React SPA page codes are logical coverage targets and activate through one Runtime child; they do not require PageRelease. `release app-head` and `runtime releases` are compact by default; use `--full` only when the complete manifest is required.
|
|
145
145
|
|
|
@@ -140,7 +140,7 @@ An environment-managed release may intentionally replace complete Function/Autom
|
|
|
140
140
|
|
|
141
141
|
For an audited Runtime source rollback, managed `release ship`, recovery `release deploy`, and `release promote` accept `--allow-runtime-rollback --reason "..."` with a reason of at least 8 characters. This pair is scoped only to `runtime-stage` and never reaches resource stages or `app-finalize`. Ship freezes it in `ship.json`; production confirmation inherits it automatically. The default remains fail closed.
|
|
142
142
|
|
|
143
|
-
`release publish` is the normal whole-app entrypoint for legacy unmanaged workspaces: it verifies SDD without mutating reviewed files, waits for the promotion lease, freezes one App capture, stages the exact Form/Backend/Runtime children, resumes from a private execution journal, finalizes once, and releases the lease. Managed applications use two-phase `release ship` and its deployment-scoped journal. Individual candidate/deploy/test/promote commands are recovery/diagnostic primitives.
|
|
143
|
+
`release publish` is the normal whole-app entrypoint for legacy unmanaged workspaces: it verifies SDD without mutating reviewed files, waits for the promotion lease, freezes one App capture, stages the exact Form/Backend/Runtime children, resumes from a private execution journal, finalizes once, and releases the lease. Managed applications use two-phase `release ship` and its deployment-scoped journal. Individual candidate/deploy/test/fail/promote commands are recovery/diagnostic primitives. `release fail --deployment <id> --message <text> [--code <code>] [--details-json <JSON|file>] --environment preproduction` records an audited UAT failure only after verifying the deployment belongs to the selected preproduction environment; production targets and mismatched deployment identities fail before the write.
|
|
144
144
|
|
|
145
145
|
Reviewed bundle commands may retain `<profile>` as a template. The explicit real `release publish --profile <name>` value is bound to actual child argv without rewriting tracked SDD. React SPA page codes remain logical coverage targets and activate through the single Runtime child; they do not require PageRelease. If local lease state disappears, `release end --change <id>` reconciles a self-owned remote lease from the private execution journal and never reports inactive while a remote lease is active.
|
|
146
146
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openxiangda",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.245",
|
|
4
4
|
"description": "OpenXiangda CLI, workspace build tools, runtime SDK, and form components.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"bin": {
|
|
@@ -123,6 +123,7 @@
|
|
|
123
123
|
"test:app-release-cli": "node scripts/app-release-cli-smoke.mjs",
|
|
124
124
|
"test:application-environments": "node scripts/application-environments-smoke.mjs",
|
|
125
125
|
"test:release-ship": "node scripts/release-ship-gate-smoke.mjs",
|
|
126
|
+
"test:release-fail": "node scripts/release-fail-cli-smoke.mjs",
|
|
126
127
|
"test:environment-swap": "node scripts/environment-swap-cli-smoke.mjs",
|
|
127
128
|
"test:environment-policy": "node scripts/environment-policy-cli-smoke.mjs",
|
|
128
129
|
"test:developer-center": "node scripts/developer-center-smoke.mjs",
|
|
@@ -31,6 +31,7 @@ This is an OpenXiangda React SPA workspace using Delivery V2. See [DELIVERY.md](
|
|
|
31
31
|
- Before platform writes, run `release begin` from a clean local main/master that exactly equals the authoritative remote tip. Feature branches and unpushed mainline commits fail before any write. A clone primary may be canonicalized to the frozen repository ID only when that ID is already in `repoAliases`; otherwise release prepare fails closed. After activation, run `integration-status` and `release end`; no post-release merge is needed.
|
|
32
32
|
- Managed preproduction and production targets own independent app/resource/data identities and side-effect policy. Existing workspaces use `environment attach`; only an appType-matching legacy binding may seed preproduction and production starts empty. Never direct-publish or copy IDs across them; use `openxiangda studio` to inspect candidate, evidence, and drift state. Only an explicitly authorized commissioning reclassification may use `environment swap --reason "..." --confirm-production`; it preserves app data/Release Heads and keeps side effects restricted by default.
|
|
33
33
|
- Managed `release ship` always runs candidate → preproduction → production. Normally confirmation is a later invocation; an explicitly authorized emergency may put `--confirm-production` on the first invocation to run both phases in one command. The candidate seals environment/resource bindings and target-specific Runtime artifacts; deployment uses no rebuild and must finish each server deployment as `succeeded`.
|
|
34
|
+
- Record a failed preproduction UAT with `release fail --deployment <id> --message "..." [--code <code>] [--details-json <JSON|file>] --environment preproduction`; the CLI verifies target ownership before the audited write and rejects production or mismatched deployments.
|
|
34
35
|
- Change one target's side-effect policy only with `environment policy update <preproduction|production> --side-effect-policy-json <JSON|file> --reason "..."`: run `--dry-run` first, add `--confirm-production` for production, and never use `environment swap` for this. Patch mode validates only supplied fields and preserves unrecognized historical fields; `--full-replace` validates the supplied complete target and intentionally removes omissions. `organizationWrites=explicit_capability_only` removes the environment deny but still requires `app:organization:manage`. Keep release hard gates to explicit scope/profile/target, authorization, clean pushed mainline, immutable identity, CAS/lease, and production confirmation; prose and human acceptance notes are advisory unless strict mode is configured.
|
|
35
36
|
- Account/role/permission/RBAC/organization-account/query-param authorization work must run `openxiangda design gates --topic permissions --json`, choose `managed-platform-account`, `existing-platform-user-assignment`, `static-role-permission`, or `query-param-context`, and write the permission matrix.
|
|
36
37
|
- Roles that create roles, assign members, grant API permissions, maintain permission groups, or manage organization accounts must declare `apiPermissionCodes`, such as `app:role:manage`, `app:page-permission-group:manage`, `app:form-permission-group:manage`, and `app:organization:manage`.
|
|
@@ -35,6 +35,7 @@ This is an OpenXiangda React SPA workspace using Delivery V2. Read [DELIVERY.md]
|
|
|
35
35
|
- 环境托管 `release ship --adopt-online-baseline --adoption-reason "..."` 会把审计意图冻结进私有 ship journal,后续 `--confirm-production` 自动复用;显式传入不同参数会在任何请求前失败。
|
|
36
36
|
- 环境托管 `release ship --replace-manifest --reason "..."` 必须成对、reason 至少 8 字符且仅限精确 Backend selector;正式确认复用与预发完全相同的参数,不透传 Form/Workflow/Runtime/配置或全量步骤。
|
|
37
37
|
- `release ship` 始终顺序执行 candidate → 预发 → 生产。日常分两次确认;明确授权紧急发布时首条命令可带 `--confirm-production` 一次完成,但不跳过预发/证据/CAS。candidate 封存环境/资源绑定及两目标 Runtime 哈希产物,部署不重建且每条服务端 deployment 必须闭环为 `succeeded`。
|
|
38
|
+
- 预发 UAT 失败使用 `release fail --deployment <id> --message "..." [--code <code>] [--details-json <JSON|file>] --environment preproduction` 写审计;CLI 先校验 deployment 属于所选预发环境,禁止 production 或环境不匹配写入。
|
|
38
39
|
- 托管发布完成后运行 `release integration-status --change <change> --profile <name> --check`;CLI 从私有 `ship.json` 或其引用的 production/preproduction deployment execution 日志恢复血缘,无法恢复时指出实际缺失的文件或字段。
|
|
39
40
|
- 多 target 的托管工作区执行 `function invoke` 必须显式传 `--environment <target>`,并先核对 stderr 回显的最终 target 再判断响应。
|
|
40
41
|
- Promotion 必须持有 `release begin/end` 租约;`release begin` 只接受与权威远端 tip 完全一致的 clean main/master。feature branch 或未 push 主线在任何写入前失败。clone primary 只有在冻结仓库 ID 已存在于 `repoAliases` 时才会 canonicalize;无交集在 Release prepare 前失败关闭。激活后直接运行 `integration-status` 和 `release end`,不再补做发布后合并。
|
|
@@ -60,6 +60,8 @@ openxiangda commands --json
|
|
|
60
60
|
|
|
61
61
|
工作区一旦通过 `environment init` 登记或 `environment attach` 接入,`release publish` 即不再是入口。`release ship` 始终按 candidate → preproduction → production 执行:日常首条命令在预发停止,后续 `--confirm-production` 晋级;用户明确授权紧急发布时,首条命令可直接携带 `--confirm-production`,在一个命令内顺序执行两阶段,但不跳过预发、证据、CAS 或确认。candidate 封存源码、public、构建配置/脚本、稳定环境/资源绑定和两目标 Runtime 哈希产物;部署不再现场构建,并将两条服务端 deployment 都闭环为 `succeeded`。两套环境身份仍完全隔离,人工验收默认建议且可用 `--acceptance-note` 留痕;swap、policy 和权限规则保持不变。`openxiangda studio` 用于查看绑定、漂移、候选、部署和证据。
|
|
62
62
|
|
|
63
|
+
预发 UAT 未通过时,使用 `release fail --deployment <id> --message "..." [--code <code>] [--details-json <JSON|file>] --environment preproduction --profile <name>` 留下平台审计记录。CLI 会先核对 deployment 属于所选预发环境;禁止对 production target 或不匹配的 deployment 使用。
|
|
64
|
+
|
|
63
65
|
托管发布完成后运行 `release integration-status --change <change> --profile <name> --check`。CLI 会从私有 `ship.json` 恢复血缘,必要时自动沿 production/preproduction deployment ID 查找对应 `execution.json`;失败信息必须指出实际缺失的日志或字段。
|
|
64
66
|
|
|
65
67
|
只有已审计代码早已进入权威主线、而精确非删除目标在线上来自多次历史发布且无法对应单一 Git 基线时,第一次 `release ship` 才可增加 `--adopt-online-baseline --adoption-reason "..."`。该意图会冻结进私有 `ship.json`,后续 `--confirm-production` 自动复用;它不会放松冻结 online heads、change/lease、删除/全量拒绝、服务端 CAS、staged children 或单次 App finalize 原子激活。
|
|
@@ -39,6 +39,7 @@ This is a `sy-lowcode-app-workspace` managed by the `openxiangda` CLI. See [AGEN
|
|
|
39
39
|
- After managed promotion, run `release integration-status --change <change> --profile <name> --check`; it recovers lineage from private `ship.json` or its referenced production/preproduction deployment execution journal, and names the missing file or field when recovery is impossible.
|
|
40
40
|
- Before platform writes, run `release begin` only from clean main/master exactly equal to the authoritative remote tip. Feature branches and unpushed mainline commits fail before writes. A clone primary may be canonicalized to the frozen repository ID only when that ID is already in `repoAliases`; otherwise release prepare fails closed. After activation, run `integration-status` and `release end`; no post-release merge is needed.
|
|
41
41
|
- Environment-managed workspaces never publish directly. Use `release ship`: normally stop after preproduction and confirm later; for an explicitly authorized emergency, put `--confirm-production` on the first invocation to run both ordered phases. The candidate seals bindings and target-specific Runtime artifacts, deployments do not rebuild, and each server deployment must close as `succeeded`. Keep app/resource/data IDs isolated.
|
|
42
|
+
- Record a failed preproduction UAT with `release fail --deployment <id> --message "..." [--code <code>] [--details-json <JSON|file>] --environment preproduction`; the CLI verifies target ownership before the audited write and rejects production or mismatched deployments.
|
|
42
43
|
- Change one target's side-effect policy only with `environment policy update <preproduction|production> --side-effect-policy-json <JSON|file> --reason "..."`: run `--dry-run` first, add `--confirm-production` for production, and never use `environment swap` for this. Patch mode validates only supplied fields and preserves unrecognized historical fields; `--full-replace` validates the supplied complete target and intentionally removes omissions. `organizationWrites=explicit_capability_only` removes the environment deny but still requires `app:organization:manage`. Keep release hard gates to explicit scope/profile/target, authorization, clean pushed mainline, immutable identity, CAS/lease, and production confirmation; prose and human acceptance notes are advisory unless strict mode is configured.
|
|
43
44
|
- Routine edits should plan and publish exact change targets: `workspace plan --profile <name> --change <change> --changed`, then `workspace publish --profile <name> --change <change> --only pages/a,forms/b --dry-run`.
|
|
44
45
|
- Account/role/permission/RBAC/organization-account/query-param authorization work must choose a mode first: `managed-platform-account`, `existing-platform-user-assignment`, `static-role-permission`, or `query-param-context`, then write the permission matrix.
|
|
@@ -37,6 +37,7 @@ This is a `sy-lowcode-app-workspace` managed by the `openxiangda` CLI. Read [AGE
|
|
|
37
37
|
- 相同 change 的 staged FormRelease 只有经服务端重新核验 immutable/inactive/non-aborted、identity/hash、冻结 schema/formType、finalized 资源、parent/base revision 与当前 Form Head 后,才可重挂接新 baseline/session。`schemaSyncedAt` 不是发布证据;禁止伪造、直发 schema 或提前激活 Form 绕过 Workflow 校验。
|
|
38
38
|
- 环境托管 `release ship --replace-manifest --reason "..."` 必须成对、reason 至少 8 字符且仅限精确 Backend selector;正式确认复用与预发完全相同的参数,不透传 Form/Workflow/Runtime/配置或全量步骤。
|
|
39
39
|
- `release ship` 始终顺序执行 candidate → 预发 → 生产。日常分两次确认;明确授权紧急发布时首条命令可带 `--confirm-production` 一次完成,但不跳过预发/证据/CAS。candidate 封存环境/资源绑定及两目标 Runtime 哈希产物,部署不重建且每条服务端 deployment 必须闭环为 `succeeded`。
|
|
40
|
+
- 预发 UAT 失败使用 `release fail --deployment <id> --message "..." [--code <code>] [--details-json <JSON|file>] --environment preproduction` 写审计;CLI 先校验 deployment 属于所选预发环境,禁止 production 或环境不匹配写入。
|
|
40
41
|
- 托管发布完成后运行 `release integration-status --change <change> --profile <name> --check`;CLI 从私有 `ship.json` 或其引用的 production/preproduction deployment execution 日志恢复血缘,无法恢复时指出实际缺失的文件或字段。
|
|
41
42
|
- 写入平台前只从与权威远端 tip 完全一致的 clean main/master 执行 `release begin`。feature branch 或未 push 主线在任何写入前失败;clone primary 只有在冻结仓库 ID 已存在于 `repoAliases` 时才会 canonicalize,无交集在 Release prepare 前失败关闭;激活后直接运行 `integration-status` 和 `release end`,无需发布后再合并。
|
|
42
43
|
- 环境托管工作区禁止直发:已有工作区先用 `environment attach` 接入,旧映射只能迁移到 appType 相同的预发 target,正式 target 必须为空。然后执行 `release candidate`、`release deploy --environment preproduction`、`release test`,最后将同一 candidate 用 `release promote --environment production --confirm-production` 晋级。两套环境的 appType、资源 ID 和数据不可互拷;用 `openxiangda studio` 查看状态。只有用户明确授权的投产前重分类可执行 `environment swap --reason "..." --confirm-production`;它不移动应用数据或 Release Head,且默认不放开副作用。
|
|
@@ -65,6 +65,7 @@ Delivery V2 自动从期望状态计算精确资源范围,封存内容寻址 A
|
|
|
65
65
|
- ✅ 未登记环境的旧工作区,正式 promotion 先聚合 mainline bundle 并 commit/push,再运行 `release publish --change <id> --profile <name>`。
|
|
66
66
|
- ✅ 旧工作区已有 Root、且操作者明确授权无条件恢复时,可执行 `release app-activate <releaseId> --force-activate-without-validation --profile <name>`。该命令不读取 detail/capture,不要求 change、租约、baseline、源码 lineage、状态、parent、hash、resource head 或环境发布门禁;服务端直接在目标 tenant/appType 内以单事务切换 Root 与可识别的 staged children。
|
|
67
67
|
- ✅ 已通过 `environment init` 或 `environment attach` 接入的工作区使用 `release ship`,始终按 candidate → preproduction → production 执行。日常首条命令在预发停止,后续 `--confirm-production` 晋级;用户明确授权紧急发布时,首条命令可携带 `--confirm-production` 在一个命令内顺序完成两阶段,但不跳过预发、证据、CAS 或确认。candidate 封存源码、public、构建配置/脚本、稳定环境/资源绑定和两目标 Runtime 哈希产物;部署不现场重建,并将两条服务端 deployment 闭环为 `succeeded`。两套环境身份仍完全隔离,人工验收建议和 swap/policy/权限门禁保持不变。
|
|
68
|
+
- ✅ 预发 UAT 未通过时,使用 `release fail --deployment <id> --message "..." [--code <code>] [--details-json <JSON|file>] --environment preproduction --profile <name>` 写入平台审计。CLI 会先核对 deployment 属于所选预发环境;production target 或不匹配的 deployment 必须在写入前拒绝。
|
|
68
69
|
- ✅ 托管发布完成后运行 `release integration-status --change <change> --profile <name> --check`。CLI 会从私有 `ship.json` 恢复血缘,必要时自动沿 production/preproduction deployment ID 查找对应 `execution.json`;失败信息必须指出实际缺失的日志或字段。
|
|
69
70
|
- ✅ 只有已审计目标早已进入权威主线、线上却由多次历史 lineage 组成且无法对应单一 Git 基线时,第一次 `release ship` 才可增加 `--adopt-online-baseline --adoption-reason "..."`;该意图冻结进私有 `ship.json` 并由后续 `--confirm-production` 自动复用。仅允许精确非删除 selectors,冻结 Head、change/lease、服务端 CAS、staged children 与单次 App finalize 仍是硬门禁。
|
|
70
71
|
- ✅ 环境托管发布需要完整替换 Function/Automation manifest 时,`release ship` 可成对增加 `--replace-manifest --reason "..."`;reason 至少 8 字符,只透传精确 Backend selector,正式确认必须复用同一对参数,不扩散到 Form/Workflow/Runtime/配置或全量范围。
|