Compare commits

..
10 Commits
19 changed files with 468 additions and 225 deletions
@@ -0,0 +1,3 @@
d23bb1ec24a7f49359314e04cd2c04c8f38876e45f25a701506499d1b34f270f MANIFEST-AIOS-V2R1-HERMES-LIFECYCLE-20260721.json
5ce2894fdf8a22622954a1a10fb09fbab74af04f0260b249615c70236ff31731 RESULT-AIOS-V2R1-HERMES-LIFECYCLE-20260721.md
ca2ab3c22c2b2b33bbc03e59f1206b999ad1271de3e1938fd3a0b4234c613eef ../../../docs/aios-v2/AIOS-V2R1-HARDENING-GATE-A-REPORT.md
@@ -0,0 +1,44 @@
{
"schema_version": "aios.evidence.manifest.v1",
"generated_at": "2026-07-21T05:50:00Z",
"branch": "patch/chatgpt/AIOS-V2R1-HERMES-LIFECYCLE-20260721",
"validated_oid": "95d2e52cb55c7b913e89bc6bed2bcdacf67512d4",
"evidence_root": "/var/lib/aios-gitops/acceptance/aios-v2r1-hermes-lifecycle-20260721T054205Z",
"evidence_hashes": {
"steps.tsv": "b2ad20585ba7f576e85657827a0b1db6f252887bbd73bcd718df38623e9d95cf",
"final-live-gate.log": "82040c674759dacf587658c5e936c313a1f50e8e2425be48ad891927befdf4fa",
"16R.log": "641246927a372ebaa9e6dde8b018b88275b2ba15a442473759b23fb1f215d9cf",
"15.log": "b0a474e2a74164f560c4f7572091911f32011c75faccd37a3c7315046275011e",
"13.log": "b9f637cca6e97ed893bf38530e05cd33b78e324c5e8865d4c602dfeac22a7710",
"12R2.log": "0c431f5f5f1c1b17acda160c917b08c7f4036485016c23e1236b9b6f4a78de67"
},
"validation": {
"candidate_tests": {"passed": 49, "failed": 0},
"hermes_lifecycle": {"passed": 17, "failed": 0},
"gate_b": {"passed": 10, "failed": 0},
"offline_acceptance": {"passed": 8, "failed": 0, "expected_warnings": 1},
"openclaw_real_http": "PASS",
"restart_recovery": "PASS",
"rollback_forward": "PASS",
"state_preservation": "PASS",
"final_health_corrected_16R": "PASS"
},
"git_gate": {
"oid_match": true,
"candidate_clean": true,
"active_controller_clean": true,
"locked": 0,
"prunable": 0,
"worktree_total": 88,
"worktree_dirty": 10,
"global_worktree_clean": false
},
"resolved_blockers": [],
"active_blockers": [
"BLK-LIVE-HERMES-FULL-LIFECYCLE-EVIDENCE-MISSING",
"BLK-GLOBAL-WORKTREE-CLEANLINESS"
],
"overall": "PARTIAL / BLOCKED_GLOBAL_WORKTREE_CLEANLINESS",
"release_decision": "STOP_PREPRODUCTION",
"secrets_recorded": false
}
@@ -0,0 +1,16 @@
# AIOS V2R1 Hermes Lifecycle Result
- Branch: `patch/chatgpt/AIOS-V2R1-HERMES-LIFECYCLE-20260721`
- Validated OID: `95d2e52cb55c7b913e89bc6bed2bcdacf67512d4`
- Evidence root: `/var/lib/aios-gitops/acceptance/aios-v2r1-hermes-lifecycle-20260721T054205Z`
- Hermes blocker: `EVIDENCE_COMPLETE / FORMAL_CLOSURE_BLOCKED`
- Overall: `PARTIAL / BLOCKED_GLOBAL_WORKTREE_CLEANLINESS`
- Release decision: `STOP_PREPRODUCTION`
Hermes lifecycle `17/17`, candidate `49/49`, Gate B `10/10`, offline acceptance `8/0/1`, OpenClaw real HTTP, restart recovery, rollback/forward, state preservation and corrected final health all passed at the validated OID. The Owner acceptance contract nevertheless forbids formally closing the Hermes blocker until every global gate also passes.
The candidate worktree and active Controller worktree are clean; local, worktree and Gitea OIDs match; locked/prunable are zero. The global authority currently has 10 dirty worktrees out of 88, so the Owner hard gate requiring every worktree to be clean fails.
No RC, Tag Approval Request, Tag, main mutation, force push, production traffic switch or secret disclosure was performed.
See `MANIFEST-AIOS-V2R1-HERMES-LIFECYCLE-20260721.json` and `docs/aios-v2/AIOS-V2R1-HARDENING-GATE-A-REPORT.md`.
@@ -0,0 +1,12 @@
# V2R1C1 Cleanup Closure
- `CLEANUP_REVIEW=PASS`
- `ARCHIVE_VALIDATION=PASS`
- `GLOBAL_WORKTREE_CLEAN=true`
- `global_dirty_count=0`
- `locked=0`
- `prunable=0`
- Portal Archive OID: `99671cc14d2631f989e0763dc882e4001c50a1ea`
- Spark Archive OID: `d97cd3642528bd3373fe4cf5161a5d99c0b9285f`
Closure evidence: `/var/lib/aios-gitops/acceptance/aios-v2r1c1-blocker-clear-20260721T075647Z`.
@@ -0,0 +1,57 @@
{
"schema_version": "aios.v2r1c1.deployment-manifest.v1",
"vrc": "V2R1C1",
"release_branch": "release/AIOS-V2R1C1-20260721",
"old_release_oid": "80c4cbde03a82c30648a09b817bc2f03d5402936",
"validated_release_parent_oid": "0778a31ec073e7c90003ef091f1d093c16bf22e5",
"product_baseline_oid": "fb739f6e8ff9c031d319221ace68dce157694086",
"companion": {
"branch": "patch/openclaw/AIOS-V2R1C1-COMMAND-V2-COMPANION-20260721",
"source_oid": "83f8f878c7da5dd8263f2af2efa80750492e5cb3",
"oid": "12d1c13170e0c5a691d67a9408e739e7a17064a3",
"plugin_version": "2.1.0-rc.4",
"contract_version": "aios.openclaw.command.v2",
"signature_algorithm": "Ed25519",
"verification_key_id": "openclaw-v2r1-candidate-ed25519",
"artifact_sha256": "aadd5f3cfa0d8e796a21f6368f5c95e8c60e9063d6e9fcd9c4947cfa0c013671"
},
"isolated_validation": {
"service": "aios-v2r1c1-openclaw-companion.service",
"account": "aios-v2r1c1-openclaw",
"listen": "127.0.0.1:28789",
"accept_v2": true,
"accept_v1": false,
"public_key_only": true,
"production_traffic_switched": false,
"result": "PASS"
},
"previous_plugin": {
"source_oid": "83f8f878c7da5dd8263f2af2efa80750492e5cb3",
"plugin_version": "2.1.0-rc.3",
"artifact_sha256": "d0fd11be4aec03eee9ca24bf1585d9ef3597254ad4b1db0d0137eab4456b5737"
},
"rollback": {
"production_plugin_unchanged": true,
"failed_isolated_attempts_rolled_back": true,
"previous_plugin_evidence": "/var/lib/aios-gitops/acceptance/aios-v2r1c1-openclaw-v2-companion-20260721T094442Z/00-baseline",
"previous_oid": "b158041b8633e658c34ce182f3c8aa97b4bf5f9a",
"isolated_rollback_forward": "PASS",
"production_symlink_modified": false
},
"release_validation": {
"gate_a": "PASS",
"gate_b": "PASS",
"openclaw_v2_live": "PASS",
"openclaw_negative_live": "PASS",
"hermes_live": "PASS",
"restart_recovery": "PASS",
"rollback_forward": "PASS",
"final_health": "PASS",
"secret_violations": 0,
"global_dirty_count": 0,
"sync_status": "fully_synced"
},
"tag_status": "ABSENT",
"preproduction_status": "NOT_STARTED",
"production_status": "NOT_STARTED"
}
@@ -0,0 +1,55 @@
{
"schema_version": "aios.v2r1c1.release-evidence.v2",
"vrc": "V2R1C1",
"semver": "2.1.0-rc.1",
"product_baseline_oid": "fb739f6e8ff9c031d319221ace68dce157694086",
"old_release_oid": "80c4cbde03a82c30648a09b817bc2f03d5402936",
"validated_release_parent_oid": "0778a31ec073e7c90003ef091f1d093c16bf22e5",
"release_branch": "release/AIOS-V2R1C1-20260721",
"release_evidence_root": "/var/lib/aios-gitops/acceptance/aios-v2r1c1-release-20260721",
"companion_evidence_root": "/var/lib/aios-gitops/acceptance/aios-v2r1c1-openclaw-v2-companion-20260721T094442Z",
"openclaw_companion": {
"branch": "patch/openclaw/AIOS-V2R1C1-COMMAND-V2-COMPANION-20260721",
"source_oid": "83f8f878c7da5dd8263f2af2efa80750492e5cb3",
"companion_oid": "12d1c13170e0c5a691d67a9408e739e7a17064a3",
"plugin_version": "2.1.0-rc.4",
"contract_version": "aios.openclaw.command.v2",
"signature_algorithm": "Ed25519",
"verification_key_id": "openclaw-v2r1-candidate-ed25519",
"artifact_sha256": "aadd5f3cfa0d8e796a21f6368f5c95e8c60e9063d6e9fcd9c4947cfa0c013671"
},
"step13": {
"original_result": "FAIL_HTTP_401",
"original_diagnosis_manifest_sha256": "320017cbfc0f31392b4d0fb5996d0e32709982a967d102592ac45efdbdaad91f",
"remediated_result": "PASS",
"online_negative_evidence_sha256": "57ab8efd19d3bf659a65cbeda830785f6cea9172925a3cac9e027b9b842e644f",
"remediated_evidence_sha256": "5db59096c0586fcc0a51851d9a25d0a0b94f2bade45063fab16cc2a729f23130",
"task_state": "COMPLETED",
"dispatch_state": "COMPLETED",
"task_dispatch_audit_consistency": "PASS"
},
"release_validation": {
"static_revalidation": "PASS",
"static_evidence_sha256": "c33ffaf9a0f509d6e78bdfdc0848940c166b8a800940e259b7196adab04ec604",
"gate_a": "PASS",
"gate_b": "PASS",
"documentation_sync": "PASS",
"secret_scan_violations": 0,
"release_metadata": "PASS",
"hermes_live": "PASS",
"hermes_evidence_sha256": "e6553c99db55c3cdf9e16a4c1e6712064e00c41dc9965d0d179b6b1a2a1ad3ac",
"restart_recovery": "PASS",
"restart_evidence_sha256": "6031c92cd890dffd1de28ba75d81bed908e7da11a24aa129bcfde8efb23f0149",
"rollback_forward": "PASS",
"rollback_evidence_sha256": "f3d49c54e3f722facf68df2da3d82a9c82eb576f2c7c8dacb0f62c424d25737c",
"final_health": "PASS",
"final_health_evidence_sha256": "121cd52c0a4852b818e06be69211ae18b9fcccf976fa064e2a09c54eb8a01300",
"global_dirty_count": 0,
"sync_status": "fully_synced"
},
"validation_status": "PASS",
"tag_status": "ABSENT",
"preproduction_status": "NOT_STARTED",
"production_status": "NOT_STARTED",
"secrets_recorded": false
}
@@ -0,0 +1,52 @@
# V2R1C1 Validation Result
Status: `RELEASE_VALIDATION_PASS / FINAL_METADATA_COMMIT_REVALIDATION_REQUIRED`
Release decision: `STOP_PREPRODUCTION`
## OpenClaw Command v2 Companion
- Source OID: `83f8f878c7da5dd8263f2af2efa80750492e5cb3`
- Companion OID: `12d1c13170e0c5a691d67a9408e739e7a17064a3`
- Plugin version: `2.1.0-rc.4`
- Contract: `aios.openclaw.command.v2`
- Signature: `Ed25519`
- Artifact SHA256: `aadd5f3cfa0d8e796a21f6368f5c95e8c60e9063d6e9fcd9c4947cfa0c013671`
- Companion unit/contract tests: `PASS`
- V1 fallback: `REJECTED`
- Isolated Gateway health: `PASS`
- Online positive/negative contract: `PASS`
- AIOS -> OpenClaw real HTTP: `PASS`
- Task state: `COMPLETED`
- Dispatch state: `COMPLETED`
- Task/Dispatch/Audit consistency: `PASS`
## Evidence linkage
- Original failed Release OID: `80c4cbde03a82c30648a09b817bc2f03d5402936`
- Original HTTP 401 diagnosis: `/var/lib/aios-gitops/acceptance/aios-v2r1c1-release-20260721/pass1-80c4cbde/13-diagnosis`
- Original manifest SHA256: `320017cbfc0f31392b4d0fb5996d0e32709982a967d102592ac45efdbdaad91f`
- Companion evidence root: `/var/lib/aios-gitops/acceptance/aios-v2r1c1-openclaw-v2-companion-20260721T094442Z`
- Validated Release parent OID: `0778a31ec073e7c90003ef091f1d093c16bf22e5`
- Online negative evidence SHA256: `57ab8efd19d3bf659a65cbeda830785f6cea9172925a3cac9e027b9b842e644f`
- Remediated Step 13 evidence SHA256: `5db59096c0586fcc0a51851d9a25d0a0b94f2bade45063fab16cc2a729f23130`
## Release validation closure
- Gate A: `PASS`
- Gate B: `PASS`
- Documentation sync: `PASS`
- Secret violations: `0`
- Release Metadata: `PASS`
- Hermes live: `PASS`
- Restart recovery: `PASS`
- Previous ↔ V2R1C1 isolated rollback/forward: `PASS`
- Final health: `PASS`
- Global dirty / locked / prunable: `0 / 0 / 0`
- OID sync: `fully_synced`
- Production traffic switched: `false`
- Tag: `ABSENT`
## Remaining mandatory validation
本次最终元数据闭环提交将形成新的 Release OID。必须针对该最终 OID 再次复验 Gate A、Gate B、文档同步、Secret Scan、Release Metadata 和 OpenClaw 第 13 步正向/负向验证。复验通过前不得创建 Tag 或部署预生产/生产。
+8
View File
@@ -0,0 +1,8 @@
# Changelog
## V2R1C1 - 2.1.0-rc.1
- 固定发布基线为 `fb739f6e8ff9c031d319221ace68dce157694086`。
- 收口 Hermes 生命周期、Grant 隔离、Dispatch 恢复、运行证据和回滚/前滚验证。
- Portal Adapter 与 Spark Provisioning 仅保留在 Archive,不属于产品发布图。
- Future Incubator 保持隔离,不属于 V2R1C1 发布输入。
+1 -1
View File
@@ -1 +1 @@
V1R4C6 V2R1C1
@@ -337,6 +337,8 @@ class HermesAdapter:
lease_seconds: int | None = None, lease_seconds: int | None = None,
) -> HermesJob: ) -> HermesJob:
duration = int(lease_seconds or self.default_lease_seconds) duration = int(lease_seconds or self.default_lease_seconds)
if duration < 5:
raise ValueError("lease_seconds must be >= 5")
with self.store.lock: with self.store.lock:
self._requeue_expired_locked() self._requeue_expired_locked()
current = self._owned_job_locked(job_id, tenant_id, worker_id) current = self._owned_job_locked(job_id, tenant_id, worker_id)
+15
View File
@@ -191,6 +191,14 @@ class CandidateApplication:
if not ({"runtime", "platform_admin"} & set(context.roles)): if not ({"runtime", "platform_admin"} & set(context.roles)):
raise Unauthorized("runtime reconciliation role is required") raise Unauthorized("runtime reconciliation role is required")
@staticmethod
def _require_control_plane_cancel(context: RequestContext) -> None:
required = {"runtime", "platform_admin"}
if not required.issubset(set(context.roles)):
raise Unauthorized(
"Hermes cancellation requires trusted AIOS control-plane authority"
)
@staticmethod @staticmethod
def _required_identity(payload: Mapping[str, Any], name: str) -> str: def _required_identity(payload: Mapping[str, Any], name: str) -> str:
value = str(payload.get(name) or "").strip() value = str(payload.get(name) or "").strip()
@@ -459,6 +467,13 @@ class CandidateApplication:
int(expected_revision) if expected_revision is not None else None int(expected_revision) if expected_revision is not None else None
) )
if action == "cancel": if action == "cancel":
self._require_control_plane_cancel(context)
if payload.get("worker_id") is not None:
raise Unauthorized("Hermes workers may observe but not initiate cancel")
if payload.get("cancellation_source") != "aios-control-plane":
raise ValueError(
"cancellation_source must be aios-control-plane"
)
result = self.hermes.cancel( result = self.hermes.cancel(
job.job_id, job.job_id,
tenant_id=job.tenant_id, tenant_id=job.tenant_id,
View File
+18 -6
View File
@@ -8,12 +8,28 @@ STATE_DIR="${AIOS_V2_STATE_DIR:-/var/lib/aios-v2}"
BACKUP_ROOT="${AIOS_V2_BACKUP_ROOT:-/var/backups/aios-v2}" BACKUP_ROOT="${AIOS_V2_BACKUP_ROOT:-/var/backups/aios-v2}"
TARGET_RELEASE="${1:-}" TARGET_RELEASE="${1:-}"
RESTORE_STATE="${AIOS_V2_RESTORE_STATE:-0}" RESTORE_STATE="${AIOS_V2_RESTORE_STATE:-0}"
HEALTH_RETRIES="${AIOS_V2_ROLLBACK_HEALTH_RETRIES:-30}"
HEALTH_RETRY_DELAY="${AIOS_V2_ROLLBACK_HEALTH_RETRY_DELAY:-1}"
fail() { fail() {
echo "ERROR: $*" >&2 echo "ERROR: $*" >&2
exit 1 exit 1
} }
run_healthcheck() {
local release="$1"
local attempt
for ((attempt = 1; attempt <= HEALTH_RETRIES; attempt++)); do
if AIOS_V2_SERVICE="$SERVICE" \
AIOS_V2_STATE_DIR="$STATE_DIR" \
"$release/deploy/aios-v2/healthcheck/check.sh"; then
return 0
fi
[[ "$attempt" -lt "$HEALTH_RETRIES" ]] && sleep "$HEALTH_RETRY_DELAY"
done
return 1
}
[[ "${EUID}" -eq 0 ]] || fail "rollback must run as root" [[ "${EUID}" -eq 0 ]] || fail "rollback must run as root"
[[ -n "$TARGET_RELEASE" ]] || fail "usage: $0 <release-name-or-absolute-path>" [[ -n "$TARGET_RELEASE" ]] || fail "usage: $0 <release-name-or-absolute-path>"
@@ -53,9 +69,7 @@ mv -Tf "${CURRENT_LINK}.next" "$CURRENT_LINK"
systemctl daemon-reload systemctl daemon-reload
systemctl start "$SERVICE" systemctl start "$SERVICE"
if AIOS_V2_SERVICE="$SERVICE" \ if run_healthcheck "$TARGET_PATH"; then
AIOS_V2_STATE_DIR="$STATE_DIR" \
"$TARGET_PATH/deploy/aios-v2/healthcheck/check.sh"; then
echo "ROLLBACK_COMPLETE target=$TARGET_PATH backup=$BACKUP_DIR" echo "ROLLBACK_COMPLETE target=$TARGET_PATH backup=$BACKUP_DIR"
exit 0 exit 0
fi fi
@@ -78,9 +92,7 @@ systemctl daemon-reload
systemctl start "$SERVICE" || true systemctl start "$SERVICE" || true
if [[ -n "$PREVIOUS_PATH" && -x "$PREVIOUS_PATH/deploy/aios-v2/healthcheck/check.sh" ]]; then if [[ -n "$PREVIOUS_PATH" && -x "$PREVIOUS_PATH/deploy/aios-v2/healthcheck/check.sh" ]]; then
AIOS_V2_SERVICE="$SERVICE" \ run_healthcheck "$PREVIOUS_PATH" || true
AIOS_V2_STATE_DIR="$STATE_DIR" \
"$PREVIOUS_PATH/deploy/aios-v2/healthcheck/check.sh" || true
fi fi
fail "rollback target failed; previous release restored; evidence=$BACKUP_DIR" fail "rollback target failed; previous release restored; evidence=$BACKUP_DIR"
+6
View File
@@ -349,6 +349,8 @@ signature
- 过期、未来时间超差、签名错误、Key ID 或 Fingerprint 不匹配时拒绝。 - 过期、未来时间超差、签名错误、Key ID 或 Fingerprint 不匹配时拒绝。
- Fingerprint 使用恒定时间比较。 - Fingerprint 使用恒定时间比较。
- `key_id` 只引用密钥,不包含密钥材料。 - `key_id` 只引用密钥,不包含密钥材料。
- Candidate 组合层必须把 `AIOS_OPENCLAW_SIGNING_KEY_ID` 原样传入 Orchestrator,
不得在已有批准 Key ID 时回落为默认值。
### 11.2 OpenClawResult ### 11.2 OpenClawResult
@@ -587,6 +589,10 @@ POST /api/v2/tasks/{id}/fail -> 403
- 默认只回滚代码。 - 默认只回滚代码。
- 状态恢复需独立 Rollback Grant 和显式批准。 - 状态恢复需独立 Rollback Grant 和显式批准。
- 回滚后必须执行 Healthcheck 与恢复验证。 - 回滚后必须执行 Healthcheck 与恢复验证。
- Release Archive 必须保留 `rollback.sh` 与 `healthcheck/check.sh` 的 executable bit;
验收测试必须阻止非执行模式进入候选包。
- `systemctl start` 后的回滚健康检查必须执行有界 readiness 重试,默认最多 30 次、
每次间隔 1 秒;不得因服务尚未监听的一次瞬时拒绝误判目标 Release 失败。
## 18. 契约变更规则 ## 18. 契约变更规则
+77 -217
View File
@@ -1,244 +1,104 @@
# AIOS V2R1 加固与实际验收刷新报告 # AIOS V2R1 Hermes 生命周期最终验证报告
- 报告版本:`V2R1-hermes-lifecycle-refresh-20260721.2` - 报告版本:`V2R1-hermes-lifecycle-20260721.3`
- 日期:`2026-07-21` - 日期:`2026-07-21`
- 分支:`patch/chatgpt/AIOS-V2R1-HERMES-LIFECYCLE-20260721` - 分支:`patch/chatgpt/AIOS-V2R1-HERMES-LIFECYCLE-20260721`
- 总体状态:`PARTIAL / BLOCKED_EVIDENCE_REQUIRED` - 固定验证 OID:`95d2e52cb55c7b913e89bc6bed2bcdacf67512d4`
- 总体状态:`PARTIAL / BLOCKED_GLOBAL_WORKTREE_CLEANLINESS`
- 发布决策:`STOP_PREPRODUCTION` - 发布决策:`STOP_PREPRODUCTION`
- Gate A:`PASS`(执行方报告 `0 errors / 0 warnings`)
- Gate B:`PASS`(执行方报告 `10/10`)
- 离线 Acceptance:`PASS_WITH_EXPECTED_WARNING`(`8 passed / 0 failed / 1 expected warning`)
- 生产发布:`NOT_APPROVED` - 生产发布:`NOT_APPROVED`
> 2026-07-21 当前分支已实现默认关闭的内部 Hermes Worker 生命周期 API、 ## 1. 执行结论
> `SQLiteHermesStore`、Audit/Event/Evidence 写入和严格 Dispatch/Result Binding;真实
> localhost HTTP 专项测试为 `17/17`。在提交后的 16 步验证、持久 Evidence 和独立 Reviewer
> 完成前,发布决策仍保持 `STOP_PREPRODUCTION`,不得把实现存在等同于最终验收放行。
## 1. 证据来源与可信度说明 `BLK-LIVE-HERMES-FULL-LIFECYCLE-EVIDENCE-MISSING` 的 Hermes 功能与证据子条件已在固定 OID 上全部通过。候选实现复用现有 Hermes Adapter、Queue、Lease、Task 与 Orchestrator 状态机,新增持久 SQLite Store 和默认关闭的受保护内部生命周期接口。Hermes 完整生命周期 `17/17`、候选测试 `49/49`、Gate A、Gate B `10/10`、离线 Acceptance `8/0/1`、真实 OpenClaw HTTP、重启恢复、双向回滚和最终健康检查均通过。
本报告依据执行方提供的实际执行结论、OID、同步状态、验收统计和日志路径刷新。当前 GitOps 工具可以提交和读取仓库内容,但不能直接读取所列主机绝对路径下的日志,因此: 但 Owner 指令规定只有全部 Acceptance 条件同时满足时才允许正式解除该 Blocker。由于“所有 Worktree clean”失败,本报告不得把它标记为正式 `RESOLVED`;准确状态是 `EVIDENCE_COMPLETE / FORMAL_CLOSURE_BLOCKED`。
- 本报告将这些结果标记为“执行方已实际验证并提供证据路径”。 最终发布门禁仍失败:权威 Bare Repo 登记的 88 个 worktree 中有 10 个脏 worktree。候选 worktree 和活动 Controller worktree 均 clean,且无 locked/prunable;但 Owner 的验收条件要求所有 worktree clean,因此不得准备 RC、不得发起 Tag Approval Request、不得进入预生产评审。
- 本会话未独立重放或读取日志内容。
- Merge、Tag、生产部署和风险接受仍需 AIOS Owner 独立批准。
- 任何与原始日志不一致的情况,应以不可变日志、退出码和签名 Evidence 为准。
主要证据路径: ## 2. 关键实现
- `/var/lib/aios-gitops/acceptance/aios-v2r1-20260721T0325Z/online-runtime-openclaw-final4.log` - `SQLiteHermesStore` 持久保存 Job、Result、Idempotency 与 Worker Heartbeat。
- `/var/lib/aios-gitops/acceptance/aios-v2r1-20260721T0325Z/restart-recovery.log` - 现有 `HermesAdapter` 保持唯一 Queue/Lease 状态机,支持指定 Job claim、租约到期 requeue、重启恢复与严格终态冲突。
- `/var/lib/aios-gitops/acceptance/aios-v2r1-20260721T0325Z/rollback-drill-final3.log` - 生命周期身份绑定覆盖 tenant、task、trace、principal、provenance、run、dispatch、job、cell、profile。
- start/heartbeat/complete/fail 强制 Lease Owner;complete/fail/cancel 通过 `ExecutionOrchestrator.reconcile_hermes` 更新 Task 与 Dispatch。
- cancel 仅允许同时具备 `runtime` 与 `platform_admin` 的 AIOS Control Plane,要求 `cancellation_source=aios-control-plane`,并拒绝携带 `worker_id`,Worker 只能观察取消。
- 所有成功生命周期操作写入 Audit/Event/Execution Evidence;接口由 `AIOS_HERMES_LIFECYCLE_API_ENABLED` 控制,默认关闭。
## 2. 权威版本与仓库状态 ## 3. 固定 OID 验证
| 项目 | 刷新值 | 状态 | | 项目 | 结果 |
|---|---|---|
| 权威 Bare Repo | `/data/aios-gitops/repo.git` | 已报告可用 |
| Candidate OID | `ba7669c3b49f98cf3500af6ea966ba0db472ff3b` | 已同步 |
| OpenClaw Task/Gitea OID | `0be3ba09e42b4f6db56461e3ca3a3fcc0a487f31` | `local_oid == gitea_oid` |
| Codex Task/Gitea OID | `6b0db21a852928106600914075ca50114cb07def` | `local_oid == gitea_oid` |
| 活动隔离 Release OID | `b158041b8633e658c34ce182f3c8aa97b4bf5f9a` | 当前验收 Release |
| Controller 修复 OID | `6188da26453505dacde9d6d298191437164c8d27` | detached、clean、fully synced |
| OpenClaw Runtime 插件 | `2.1.0-rc.3` | 已用于在线验收 |
| OpenClaw 包含最新 Candidate | 是 | 通过 |
| OpenClaw/Codex Worktree | clean | 通过 |
| Worktree 锁 | `0` | 通过 |
| Prunable Worktree | `0` | 通过 |
| `main` 修改 | 无 | 通过 |
| Tag 创建 | 无 | 通过 |
| Force Push | 无 | 通过 |
| 生产流量切换 | 无 | 通过 |
## 3. 原始五项高风险 Blocker
以下五项均已解除,当前未发现回退:
| Blocker | 刷新状态 | 证据摘要 |
|---|---|---|
| `BLK-OPENCLAW-PLAINTEXT-SECRETS` | `RESOLVED` | `plaintext/unresolved/shadowed/legacy = 0`;Gateway Token 已轮换;未记录 Secret 值 |
| `BLK-AIOS-V2-SIGNING-MATERIAL-MISSING` | `RESOLVED` | Ed25519 Key ID `openclaw-v2r1-candidate-ed25519`;`aios:aios 0600`;sign/verify、篡改拒绝通过 |
| `BLK-CANDIDATE-NOT-MERGED` | `RESOLVED` | OpenClaw 包含最新 Candidate;三分支本地与 Gitea OID 一致 |
| `BLK-OPENCLAW-RUN-PROVENANCE-MISSING` | `RESOLVED` | 已实现 Workflow Provenance、持久 Store、最小权限 Child Grant、Scoped Writer、Dispatch/Result 严格绑定及相关测试 |
| `BLK-CONTROLLER-LEGACY-GITEA-CHECK` | `RESOLVED` | 活跃代码清除旧 `aios-v23` 硬编码;Controller 12/12;Token 降权为 `read:repository` 并通过 systemd `LoadCredential` 注入 |
### 3.1 Run Provenance 刷新说明
旧状态认为插件只有进程内 `runId/sender` Map,缺少 Owner-signed schema、持久 Store 和专用 Writer。当前加固实现已经提供:
- 无操作权限的父 Workflow Provenance;
- Ed25519 签名与公钥验证;
- SQLite WAL Provenance/Grant/Usage/Event Store;
- Runtime、Evidence、Git、Deployment、Rollback、Audit、Code Change 独立 Child Grant;
- GitOperation 级别限制;
- 服务级 Scoped Writer 与 CLI 单 Grant 授权;
- 撤销、过期、重放和上下文绑定;
- 持久 Dispatch 与 Runtime Result 严格 Reconcile。
因此,`BLK-OPENCLAW-RUN-PROVENANCE-MISSING` 不再成立。
## 4. 安全验证结果
### 4.1 Secret 与凭据
| 检查 | 结果 |
|---|---| |---|---|
| 原明文 Secret 发现 | `3` | | Python syntax/import | PASS |
| 当前明文 Secret | `0` | | 全部 candidate tests | `49/49` |
| unresolved | `0` | | Grant isolation | `11/11` |
| shadowed | `0` | | Dispatch recovery | `1/1` |
| legacy | `0` | | Hermes lifecycle | `17/17` |
| Gateway Token 轮换 | 通过 | | Docs code gate / Gate A | `0 errors / 0 warnings` |
| OneAPI 实际 Agent 调用 | 通过 | | Secret scan | `547 tracked files / 0 violations` |
| Controller Token 权限 | `read:repository` | | SQLite quick_check | `2/2 ok` |
| Controller Token 注入 | systemd `LoadCredential` | | Gate B | `10/10` |
| Secret 值写入记录 | 否 | | Offline Acceptance | `8 passed / 0 failed / 1 expected warning` |
| OpenClaw real HTTP | `COMPLETED` |
| Hermes full live rerun | `17/17` |
| Restart recovery | `2/2` |
| Previous → Current rollback/forward | PASS |
| State preservation | `STATE_PRESERVED_EXACTLY=PASS` |
| Corrected final health (`16R`) | PASS,三服务 active |
### 4.2 Signing Material 原 `16.log` 由非服务用户执行健康脚本,打印 state-dir 权限失败后被外层脚本错误覆盖为退出码 0,因此不作为通过证据。纠错后的 `16R.log` 使用受控 `sudo env`,子 shell 保留失败码,所有健康项实际 PASS 且 `EXIT_CODE=0`。原文件保留用于审计。
| 检查 | 结果 | 回滚日志中的短暂 connection-refused 发生于 systemd 重启窗口内,受 `AIOS_V2_ROLLBACK_HEALTH_RETRIES=30` 与 1 秒间隔限制;前后两次均在界限内达到健康、输出 `ROLLBACK_COMPLETE`,并完成状态文件精确哈希对账。
|---|---|
| 文件存在 | 是 |
| Key ID | `openclaw-v2r1-candidate-ed25519` |
| 所有者/权限 | `aios:aios 0600` |
| 合同 | 真实 Ed25519,`aios.openclaw.command.v2` |
| sign/verify | 通过 |
| 篡改拒绝 | 通过 |
| 过期拒绝 | 通过 |
| 跨租户拒绝 | 通过 |
## 5. Gate 与 Acceptance 刷新 ## 4. Evidence
| Gate/验收项 | 实际结果 | 刷新状态 | - 根目录:`/var/lib/aios-gitops/acceptance/aios-v2r1-hermes-lifecycle-20260721T054205Z`
- `steps.tsv` SHA256:`b2ad20585ba7f576e85657827a0b1db6f252887bbd73bcd718df38623e9d95cf`
- `final-live-gate.log` SHA256:`82040c674759dacf587658c5e936c313a1f50e8e2425be48ad891927befdf4fa`
- `16R.log` SHA256:`641246927a372ebaa9e6dde8b018b88275b2ba15a442473759b23fb1f215d9cf`
- `15.log` SHA256:`b0a474e2a74164f560c4f7572091911f32011c75faccd37a3c7315046275011e`
- `13.log` SHA256:`b9f637cca6e97ed893bf38530e05cd33b78e324c5e8865d4c602dfeac22a7710`
- `12R2.log` SHA256:`0c431f5f5f1c1b17acda160c917b08c7f4036485016c23e1236b9b6f4a78de67`
证据只记录身份、状态、命令、时间、退出码与 Hash,不记录 Secret 值。
## 5. Git 与运行态门禁
| 门禁 | 当前值 | 结果 |
|---|---|---| |---|---|---|
| Gate A | `0 errors / 0 warnings` | `PASS` | | Bare/Gitea/Candidate OID | 全部 `95d2e52cb55c7b913e89bc6bed2bcdacf67512d4` | PASS |
| Gate B | `10/10` | `PASS` | | Candidate worktree | clean | PASS |
| 离线 Acceptance | `8 passed / 0 failed / 1 expected warning` | `PASS_WITH_EXPECTED_WARNING` | | Active Controller | `6188da26453505dacde9d6d298191437164c8d27`,detached、clean | PASS |
| OpenClaw 在线 Health | 通过 | `PASS` | | Locked worktree | `0` | PASS |
| OpenClaw Execute | 通过 | `PASS` | | Prunable worktree | `0` | PASS |
| OpenClaw Status | 通过 | `PASS` | | 全局 worktree clean | `10 dirty / 88 total` | FAIL |
| OpenClaw Cancel | 通过 | `PASS` | | 当前隔离 Release | `b158041b8633e658c34ce182f3c8aa97b4bf5f9a` | 已恢复 |
| OpenClaw Timeout | 通过 | `PASS` | | AIOS/OpenClaw/Controller services | active | PASS |
| OpenClaw 幂等 | 通过 | `PASS` |
| OpenClaw 篡改拒绝 | 通过 | `PASS` |
| OpenClaw 过期拒绝 | 通过 | `PASS` |
| OpenClaw 跨租户拒绝 | 通过 | `PASS` |
| AIOS → OpenClaw 真实 HTTP | `COMPLETED` | `PASS` |
| AIOS/Hermes 基础 enqueue/reconcile | 通过 | `PASS` |
| OpenClaw 跨重启幂等 | 通过 | `PASS` |
| AIOS Tenant/Agent/Task/Audit/Idempotency/Evidence 恢复 | 通过 | `PASS` |
| SQLite `PRAGMA quick_check` | `ok` | `PASS` |
| 受控双向回滚 | Previous `2a2b702…` ↔ Current `b158041…` | `PASS` |
| 回滚业务状态保护 | 未覆盖业务状态 | `PASS` |
| Live Hermes 完整生命周期 | 真实 localhost HTTP `17/17`;待提交后全序验证与 Reviewer | `MITIGATED_PENDING_REVIEW` |
## 6. Controller Health 10 个脏 worktree 均不属于本任务允许清理的范围:
| 检查 | 结果 | 1. `chatgpt/TASK-V2R1-PERSONAL-WEIXIN-GOLDEN-CONTRACT-R2-20260715`(36)
|---|---| 2. `chatgpt/TASK-V2R1-PERSONAL-WEIXIN-PORTAL-ADAPTER-20260715`(2)
| 活跃修复 OID | `6188da26453505dacde9d6d298191437164c8d27` | 3. `chatgpt/TASK-WORKTREE-CONCURRENCY-CHATGPT-20260715T055106UTC8`(2)
| 旧 `aios-v23` 硬编码 | 活跃代码中已清除 | 4. `codex`(56)
| Controller 测试 | `12/12` | 5. `codex/TASK-CODEX-AIOS-SPARK-RUNNER-PROVISIONING-20260717T103500UTC8`(6)
| Controller Worktree | detached;本轮初检发现 Runtime audit/state 生成 11 项脏文件,待 Controller 门禁修复或可信清理 | 6. `controller`(11)
| Gitea | `true` | 7. `openclaw`(5)
| local_sync | `synced` | 8. `openclaw/TASK-OPENCLAW-V2R1-PERSONAL-WEIXIN-B3-EVIDENCE-HARDEN-20260716T133000UTC8`(3)
| gitea_sync | `synced` | 9. `openclaw/TASK-V2R1-OPENCLAW-WEIXIN-WEB-LOGIN-CONTRACT-20260715`(20)
| oid_match | `true` | 10. `openclaw/TASK-WORKTREE-CONCURRENCY-OPENCLAW-20260715T055106UTC8`(3)
| branch_sync | `true` |
| sync_status | `fully_synced` |
| 首次部署失败回滚 | 已实际触发并验证 |
## 7. 当前唯一发布阻塞 ## 6. Reviewer
### `BLK-LIVE-HERMES-FULL-LIFECYCLE-EVIDENCE-MISSING` 独立 Spark Reviewer 首先发现 cancel 权限边界不够明确;该问题已在 `95d2e52` 修复并新增三条 HTTP 断言。纠错后 Reviewer 确认代码安全边界、16 步证据与有界回滚均 PASS。对发布门禁的最终布尔复核为:`DIRTY_WORKTREE_COUNT=10` 且 `GLOBAL_WORKTREE_CLEAN=false`,所以全局门禁 FAIL,不能进入预生产评审。
Live AIOS 当前只暴露 Hermes `enqueue/reconcile`,没有可调用或可观测的完整在线 Worker 生命周期端点,因此以下场景尚无完整在线证据: ## 7. Blocker 与发布决策
- `claim` - 功能与证据子条件通过、正式关闭受阻:`BLK-LIVE-HERMES-FULL-LIFECYCLE-EVIDENCE-MISSING`
- `start` - 直接阻断条件:`BLK-GLOBAL-WORKTREE-CLEANLINESS`
- `heartbeat` - 状态:`BLOCKED_EVIDENCE_REQUIRED`
- `fail` - 决策:`STOP_PREPRODUCTION`
- `cancel`
- `lease expiry`
- `worker crash recovery`
- `Cell/Profile rejection`
- `invalid-result rejection`
这不是 Run Provenance 缺失,也不是基础 Hermes Adapter 失效;它是在线验收可观测面和完整生命周期证据不足。 本轮未修改 `main`、未创建 Tag、未 Force Push、未切换生产流量、未部署新 RC、未输出 Secret。
### 7.1 解除条件 下一步唯一允许动作:由各 worktree Owner 审查并提交、归档或可信清理上述 10 个脏 worktree,然后重新执行全局 Git 门禁。只有全局 dirty 数量降为 0 后,才允许准备 RC 与 Tag Approval Request。
必须在隔离预发布环境中实际完成并保存:
1. Worker claim/start/heartbeat 正向链路;
2. Worker fail/cancel 终态链路;
3. Lease 到期重新排队或重新领取;
4. Worker 进程崩溃后的恢复;
5. 错误 Cell/Profile 的拒绝;
6. 非 Lease Owner 或上下文不匹配 Result 的拒绝;
7. Dispatch、Task、Audit、Evidence、Grant Receipt 的一致性;
8. 服务重启后继续 Reconcile;
9. 完整命令、时间、退出码、日志路径和 Artifact Hash;
10. Owner/Reviewer 对证据的独立复核。
### 7.2 不接受的替代证据
以下不能解除本 Blocker:
- 仅有单元测试文件;
- 仅有离线 Hermes enqueue/reconcile;
- 仅证明 OpenClaw 在线链路;
- 仅修改状态文档;
- 仅提供无退出码或无日志路径的口头结论;
- 通过手工修改 Task 状态伪造 Worker 生命周期。
## 8. 发布决策
### 8.1 当前决策
```text
Overall: PARTIAL / VALIDATION_IN_PROGRESS
Gate A: PASS
Gate B: PASS
Offline: PASS_WITH_EXPECTED_WARNING
OpenClaw Live: PASS
Hermes Basic: PASS
Hermes Full: 17/17 ISOLATED LIVE; PENDING FINAL REVIEW
Preproduction: STOP
Production: NOT APPROVED
```
### 8.2 允许事项
- 继续在当前非 `main` 加固分支修复与补证据;
- 在隔离 Release/预发布环境增加 Hermes 生命周期端点或受控验收驱动;
- 运行在线负向测试、重启恢复和回滚演练;
- 更新 `.agent` Evidence、Acceptance 日志与本报告;
- 提交 Reviewer 可复核的 Evidence Manifest。
### 8.3 禁止事项
- 不得修改 `main`;
- 不得创建生产 Tag;
- 不得 Force Push;
- 不得切换生产流量;
- 不得因 Gate A/B 和 OpenClaw 已通过而忽略 Hermes 完整在线证据;
- 不得把当前状态描述为“全部完成”或“可放行预生产”。
## 9. 后续最小执行计划
1. 按固定提交 OID 执行 16 步验证并保存命令、时间、退出码、日志和 Hash。
2. 解决或可信隔离 Controller Worktree 的 Runtime dirty 漂移,恢复 detached/clean 门禁。
3. 将 Evidence 写入租户隔离 `.agent` 路径并提交非 `main` 分支。
4. 由独立 Reviewer 复核 Result/Dispatch/Task/Audit/Evidence/Grant Receipt 一致性。
5. 全部通过后刷新为 `READY_FOR_PREPRODUCTION_REVIEW`;最终放行仍需 Owner 批准。
## 10. 最终结论
五项原始高风险 Blocker 已全部解除,Gate A、Gate B、离线 Acceptance、OpenClaw 在线链路、基础 Hermes、重启恢复、SQLite 完整性和双向回滚均已有执行方报告的实际通过结果。
Hermes 完整 Worker 生命周期实现与 `17/17` 隔离在线测试已经完成,但固定 OID 的完整验证、
Controller clean、持久 Evidence 和独立 Reviewer 尚未完成。因此本次刷新结论为:
> **AIOS V2R1 Hermes 生命周期阻塞已实现层面缓解,当前处于固定 OID 全量验证阶段。
> 继续停止预生产放行,直到 16 步证据、Controller clean、OID 同步和独立 Reviewer 全部通过。**
+25
View File
@@ -0,0 +1,25 @@
# AIOS V2R1C1 Release Notes
- VRC: `V2R1C1`
- SemVer: `2.1.0-rc.1`
- 固定产品基线: `fb739f6e8ff9c031d319221ace68dce157694086`
- 当前状态: `RELEASE_VALIDATION_PASS / FINAL_METADATA_COMMIT_REVALIDATION_REQUIRED`
- 发布决策: `STOP_PREPRODUCTION`
OpenClaw Command v2 Companion:
- 分支: `patch/openclaw/AIOS-V2R1C1-COMMAND-V2-COMPANION-20260721`
- 源 OID: `83f8f878c7da5dd8263f2af2efa80750492e5cb3`
- Companion OID: `12d1c13170e0c5a691d67a9408e739e7a17064a3`
- 插件版本: `2.1.0-rc.4`
- 合同: `aios.openclaw.command.v2` / `Ed25519`
- Artifact SHA256: `aadd5f3cfa0d8e796a21f6368f5c95e8c60e9063d6e9fcd9c4947cfa0c013671`
- 隔离验证: `AIOS -> OpenClaw V2 PASS`,正向与负向在线合同均通过。
旧 Release OID `80c4cbde03a82c30648a09b817bc2f03d5402936` 保留为原始 HTTP 401 失败诊断基线。Release OID `0778a31ec073e7c90003ef091f1d093c16bf22e5` 已实际完成 Gate A/B、文档同步、Secret Scan、Release Metadata、OpenClaw 第 13 步正负向、Hermes、重启恢复、隔离回滚/前滚和最终健康门禁,全部通过。
本次最终元数据闭环仍只修改五个允许的 Release 元数据文件;提交后形成的最终 OID 必须再次执行 Gate A/B、文档同步、Secret Scan、Release Metadata 和 OpenClaw 第 13 步正负向复验。复验通过前 Tag 保持不存在,生产流量保持未切换。
本分支只包含发布元数据。Personal Weixin Portal Adapter、Spark 专有 Provisioning、Future Incubator、Worktree 并发实验和长期 Agent 工作目录均未进入发布图。
只有最终 Release OID 的全部复验和步骤 14–17 通过后,才允许创建不可变 `V2R1C1` Tag。
@@ -1,5 +1,7 @@
from __future__ import annotations from __future__ import annotations
import os
import stat
import sys import sys
import tempfile import tempfile
import unittest import unittest
@@ -28,6 +30,7 @@ from aios_v2 import (
) )
from aios_v2.dispatch_store import DispatchState, SQLiteDispatchRepository from aios_v2.dispatch_store import DispatchState, SQLiteDispatchRepository
from aios_v2.gateway import GatewayApplication from aios_v2.gateway import GatewayApplication
from aios_v2.app import build_application
from aios_v2.persistence import DurableControlPlaneService, SQLiteSnapshotRepository from aios_v2.persistence import DurableControlPlaneService, SQLiteSnapshotRepository
@@ -68,6 +71,47 @@ def bootstrap(service: ControlPlaneService, tenant_id: str = "tenant-a"):
class CandidateFlowTests(unittest.TestCase): class CandidateFlowTests(unittest.TestCase):
def test_rollback_entrypoints_are_executable_in_release_archive(self) -> None:
for relative in (
"deploy/aios-v2/rollback/rollback.sh",
"deploy/aios-v2/healthcheck/check.sh",
):
mode = (REPO_ROOT / relative).stat().st_mode
self.assertTrue(mode & stat.S_IXUSR, relative)
def test_rollback_waits_for_bounded_service_readiness(self) -> None:
script = (REPO_ROOT / "deploy/aios-v2/rollback/rollback.sh").read_text()
self.assertIn("AIOS_V2_ROLLBACK_HEALTH_RETRIES", script)
self.assertIn("run_healthcheck", script)
self.assertIn("HEALTH_RETRY_DELAY", script)
def test_build_application_propagates_openclaw_signing_key_id(self) -> None:
with tempfile.TemporaryDirectory() as temp_dir:
material_path = Path(temp_dir) / "signing-material.bin"
material_path.write_bytes(OPENCLAW_PRIVATE_SEED)
material_path.chmod(0o600)
values = {
"AIOS_V2_STATE_DIR": temp_dir,
"AIOS_OPENCLAW_URL": "http://127.0.0.1:18789",
"AIOS_OPENCLAW_SIGNING_MATERIAL_FILE": str(material_path),
"AIOS_OPENCLAW_SIGNING_KEY_ID": "openclaw-v2r1-candidate-ed25519",
"AIOS_OPENCLAW_CREDENTIAL_REF": "secretref:test",
}
previous = {key: os.environ.get(key) for key in values}
try:
os.environ.update(values)
application = build_application()
finally:
for key, value in previous.items():
if value is None:
os.environ.pop(key, None)
else:
os.environ[key] = value
self.assertEqual(
application.orchestrator.openclaw_key_id,
"openclaw-v2r1-candidate-ed25519",
)
def test_http_identity_headers_are_case_insensitive(self) -> None: def test_http_identity_headers_are_case_insensitive(self) -> None:
request_context = GatewayApplication.context_from_headers( request_context = GatewayApplication.context_from_headers(
{ {
@@ -260,7 +260,25 @@ class HermesLiveLifecycleTests(unittest.TestCase):
def test_06_cancel(self) -> None: def test_06_cancel(self) -> None:
dispatch = self._dispatch("cancel") dispatch = self._dispatch("cancel")
status, payload = self._lifecycle("cancel", self._identity(dispatch)) identity = self._identity(dispatch)
runtime_only = self._headers(**{"X-AIOS-Roles": "runtime"})
status, _ = self._request(
"POST",
"/api/v2/internal/runtime/hermes/lifecycle/cancel",
{**identity, "cancellation_source": "aios-control-plane"},
headers=runtime_only,
)
self.assertEqual(status, 401)
status, _ = self._lifecycle(
"cancel",
identity,
worker_id="worker-must-not-cancel",
cancellation_source="aios-control-plane",
)
self.assertEqual(status, 401)
status, payload = self._lifecycle(
"cancel", identity, cancellation_source="aios-control-plane"
)
self.assertEqual(status, 200) self.assertEqual(status, 200)
self.assertEqual(payload["task"]["state"], "CANCELLED") self.assertEqual(payload["task"]["state"], "CANCELLED")
+14
View File
@@ -0,0 +1,14 @@
{
"vrc": "V2R1C1",
"semver": "2.1.0-rc.1",
"product_baseline_oid": "fb739f6e8ff9c031d319221ace68dce157694086",
"release_branch": "release/AIOS-V2R1C1-20260721",
"old_release_oid": "80c4cbde03a82c30648a09b817bc2f03d5402936",
"validated_release_parent_oid": "0778a31ec073e7c90003ef091f1d093c16bf22e5",
"openclaw_companion_oid": "12d1c13170e0c5a691d67a9408e739e7a17064a3",
"openclaw_plugin_version": "2.1.0-rc.4",
"openclaw_artifact_sha256": "aadd5f3cfa0d8e796a21f6368f5c95e8c60e9063d6e9fcd9c4947cfa0c013671",
"validation_status": "PASS",
"deployment_status": "NOT_STARTED",
"previous_oid": "b158041b8633e658c34ce182f3c8aa97b4bf5f9a"
}