feat(runtime-host): add managed update reconciliation - #3720
Conversation
me2seeks
left a comment
There was a problem hiding this comment.
Reviewed the 4d8efd8 reconciliation layer on top of #3687. The core shape is clean: state-free manual, one policy snapshot under a reconciliation lock, delegation to the verified selected-update transaction, and no second scheduler/updater state machine. I found two recovery-contract gaps in the inline comments below.
One scope/wording boundary: the persisted record is currently bound to clientDataRoot plus {serviceId, rootPath, rootId}. That is a useful exact managed-service target fence, but it is not yet the positive durable local-owner identity and transfer protocol tracked by #3709. This PR does not need to solve #3709; describing the current result as managed-service-target-bound or installation-scoped would avoid implying that the local owner gate is already closed.
简体中文
我按 #3687 之上的增量审查了 4d8efd8。整体形状很干净:manual 不保存冗余状态、reconciliation lock 内只读取一次 policy snapshot、复用已验证的 selected-update transaction,并且没有创建第二套 scheduler/updater 状态机。下面两条行内评论是仍需闭合的恢复契约问题。
另有一个范围与术语边界:当前持久记录实际绑定的是 clientDataRoot 与 {serviceId, rootPath, rootId}。这能为 managed service 提供精确 target fence,但还不是 #3709 所跟踪的 durable local owner 正向身份与 transfer protocol。本 PR 不需要顺手解决 #3709;将当前能力表述为 managed-service target binding 或 installation-scoped,可以避免让人误以为 local owner gate 已经闭合。
4d8efd8 to
c819f54
Compare
EnglishThanks for the scope distinction. I changed the PR wording from owner-bound to installation-scoped; this PR does not claim the durable local-owner identity or transfer protocol tracked by #3709. I did not retain the separate reconciliation lock after tracing its actual authority. It covered policy resolution and network work without making the full operation atomic, while duplicating the deployment transaction's concurrency boundary. Policy mutations and uninstall now use the existing deployment lock; reconciliation reads one atomic policy snapshot and delegates the exact {version, integrity} deployment to the existing transaction. This keeps one mutation authority without introducing a third lock domain. The same pass also fixed two independent contract gaps: JSON reconciliation now emits exactly one terminal JSON document, and uninstall revokes automatic policy before destructive lifecycle work. 简体中文感谢指出范围差异。我已将 PR 中的 owner-bound 改为 installation-scoped;本 PR 不宣称已经实现 #3709 跟踪的 durable local-owner identity 或 transfer protocol。 在追踪实际 authority 后,我没有保留独立的 reconciliation lock。它覆盖了 policy 解析与网络工作,却不能让完整操作具备原子性,同时又重复了 deployment transaction 的并发边界。现在 policy mutation 与 uninstall 复用现有 deployment lock;reconciliation 读取一份原子 policy snapshot,再把精确的 {version, integrity} deployment 交给现有 transaction。这样只保留一个 mutation authority,不新增第三个锁域。 同一轮还修复了两个独立契约缺口:JSON reconciliation 现在只输出一个 terminal JSON document;uninstall 会在破坏性 lifecycle 操作前撤销自动更新 policy。 |
f6b0edd to
962453a
Compare
962453a to
49f8dc6
Compare
Persist one owner-bound update policy and resolve it to an exact, verified deployment before delegating to the existing update transaction. Keep manual mode state-free, serialize policy changes with reconciliation and uninstall, and expose bounded machine outcomes for future schedulers and clients. Generated-by: Codex
Make policy removal crash-durable and revoke unattended update authority before destructive uninstall work begins. Reuse the deployment lock for policy mutations and route update frames through one sink so JSON reconciliation emits one terminal document. Generated-by: Codex
Revalidate the selected managed-update policy inside the deployment lock before reading or mutating service state. This lets a newer manual or fixed policy revoke an in-flight unattended reconciliation without introducing another lock or scheduler state machine. Generated-by: Codex
Store automatic update authority with the managed deployment so uninstall and legacy cleanup remove it together. Validate the selected target before revocation, preserve truthful commit uncertainty, and keep reconciliation on one output and equality path. Generated-by: Codex
edde381 to
d0ac9d0
Compare
Astro-Han
left a comment
There was a problem hiding this comment.
I reviewed this head and found no blocking issues.
Managed update policy adds atomic file-backed policy store with optimistic revalidation, correctly handling concurrent modifications, persistence failures, and schema validation. No concurrency or authority gaps beyond a minor maintainability note.
Minor note: adds moderate new surface (4 files + frame extensions) for declarative update management — valuable for hosted operations, well isolated, no daemon required.
Checks on d0ac9d0683 are pending — code side GO.
简体中文
该头未发现阻断,增熵可接受。
Astro-Han
left a comment
There was a problem hiding this comment.
I reviewed this head and found a blocking issue.
[P2] Corrupt config + external uninstall leaves update authority alive
runtime-host-service-manager.ts:403-407 looks for the managed deployment via parsed config or current cliPath. When the service config is corrupt, the first is null; the documented npx ... service uninstall from an external CLI is not in the managed deployment, so the second is also undefined. Uninstall still succeeds without revoking the automatic latest/fixed policy. Reinstall then reuses the deterministic deployment root and the old policy is immediately valid again.
Repro uses real storage root ID with an external CLI path: policy survives uninstall, reinstall target validation passes.
Fix: fail closed when the deployment cannot be located due to invalid config, or keep an authoritative deployment identity outside the corruptible config; cover external-CLI corrupt-config uninstall → reinstall.
Checks on d0ac9d0683 are test: success.
简体中文
损坏配置+外部卸载后自动更新权限未回收,需闭合。Treat automatic update policy revocation as a separate uninstall authority from deleting the managed deployment. A safely validated deterministic deployment can revoke policy when service configuration is corrupt, while destructive cleanup still requires stronger ownership evidence.\n\nGenerated-by: Codex
EnglishConfirmed and fixed in The fix separates two authorities that uninstall previously conflated:
The deterministic fallback is inspected as a real, non-redirected directory before policy mutation. If the config is corrupt and revocation cannot be confirmed, uninstall now fails closed before stopping the service. The regression covers corrupt config + external CLI uninstall + reinstall and verifies that the old automatic policy cannot revive. The CLI suite passes with 450 tests, together with format, lint, typecheck, and ASF header checks. 简体中文已确认并在 修复将 uninstall 之前混在一起的两种 authority 分开:
在修改 policy 前,deterministic fallback 必须被验证为真实、未重定向的目录。若 config 已损坏且无法确认策略已撤销,uninstall 会在停止 service 前 fail closed。回归测试覆盖了“损坏 config + 外部 CLI uninstall + reinstall”,并确认旧自动更新策略不会复活。 CLI 450 项测试以及 format、lint、typecheck 和 ASF header 检查均已通过。 |
Astro-Han
left a comment
There was a problem hiding this comment.
Update on 3c8b08278c:
The previous P2 (corrupt config + external CLI uninstall leaving policy alive) is now closed. The manager now resolves the deterministic deployment root, validates it, revokes the policy, and fail-closes if the deployment cannot be confirmed before backend uninstall. External-CLI + reinstall is now covered and the old policy no longer resurrects.
No remaining P0-P2. Minor maintainability note remains non-blocking.
Checks on 3c8b08278c are test: success.
English
Summary
manual | fixed | latest | nextupdate policy, with state-freemanualas the defaultThe current deployment is reused when it is already selected, avoiding an unnecessary package download on no-op reconciliation.
Fixes #3717
Refs #3228
Refs #3709
Verification
npm run format:checknpm run lintnpm run typechecknpm run check:asf-headersnpm --workspace packages/cli run test:dist— 450 passedmanualand reconciliation returnsdisabledAI use
Select exactly one:
Tool(s) and scope: OpenAI Codex implemented and tested the change under maintainer direction. Human review is still required before this Draft becomes ready.
Checklist
Does this PR entail a change in behavior?
简体中文
摘要
manual | fixed | latest | next,默认manual且不保存冗余状态目标已是当前 deployment 时直接复用它,避免 no-op reconciliation 重复下载 package。
修复 #3717
关联 #3228
关联 #3709
验证
npm run format:checknpm run lintnpm run typechecknpm run check:asf-headersnpm --workspace packages/cli run test:dist— 450 项通过manual,reconciliation 返回disabled依赖
AI 使用
OpenAI Codex 在维护者指导下实现并测试了本次变更;Draft 转为 Ready 前仍需要人工审查。
Checklist