Skip to content

feat(runtime-host): schedule managed update reconciliation - #3747

Merged
Astro-Han merged 5 commits into
apache:mainfrom
M4n5ter:feat/runtime-host-update-scheduler
Aug 25, 2026
Merged

feat(runtime-host): schedule managed update reconciliation#3747
Astro-Han merged 5 commits into
apache:mainfrom
M4n5ter:feat/runtime-host-update-scheduler

Conversation

@M4n5ter

@M4n5ter M4n5ter commented Aug 25, 2026

Copy link
Copy Markdown
Member
English

Summary

  • install a periodic systemd user timer for Linux and a periodic LaunchAgent for macOS as derived resources of each Maka-managed Runtime Host deployment
  • invoke the stable managed operator launcher and reuse feat(runtime-host): add managed update reconciliation #3720's bounded reconcile-update command without moving policy or update authority into the platform adapters
  • make install, repair, verification, and uninstall converge the scheduler desired state; replacement validates the scheduler before cutover but leaves it running so a scheduled update cannot terminate itself
  • keep manual as the default effective policy: periodic reconciliation returns disabled before package discovery or network access

Refs #3228

Verification

  • npm --workspace maka-agent test — 453 passed
  • npm run format:check
  • npm run lint
  • npm run typecheck for all built dependencies and CLI; Desktop typecheck passed after building @maka/ui and @maka/computer-use
  • npm run check:asf-headers

AI use

Select exactly one:

  • No generative tool made a substantive contribution
  • Generative tooling made a substantive contribution

Tool(s) and scope: OpenAI Codex designed, implemented, and tested the change under maintainer direction. Human review is still required before this Draft becomes ready.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and the affected suites pass locally

Does this PR entail a change in behavior?

  • Yes — described under Summary above
  • No
简体中文

摘要

  • 将 Linux 的 systemd user timer 与 macOS 的周期 LaunchAgent 作为 Maka 受管 Runtime Host deployment 的派生资源安装
  • 调用稳定的 managed operator launcher,复用 feat(runtime-host): add managed update reconciliation #3720 的有界 reconcile-update 命令,不把 policy 或更新 authority 移入平台 adapter
  • 让 install、repair、verification 与 uninstall 收敛 scheduler desired state;replacement 在 cutover 前验证 scheduler,但不重载它,避免定时更新终止自身
  • 保持 manual 为默认有效策略:周期 reconciliation 会在 package discovery 与网络访问前返回 disabled

关联 #3228

验证

  • npm --workspace maka-agent test — 453 项通过
  • npm run format:check
  • npm run lint
  • npm run typecheck:已构建依赖与 CLI 通过;构建 @maka/ui@maka/computer-use 后 Desktop typecheck 通过
  • npm run check:asf-headers

AI 使用

OpenAI Codex 在维护者指导下设计、实现并测试了本次变更;Draft 转为 Ready 前仍需要人工审查。

Checklist

  • 测试覆盖新增行为,并能在缺少实现时失败
  • lint、format、typecheck 与受影响测试均已在本地通过
  • 本 PR 会改变行为,具体见上方摘要

@M4n5ter
M4n5ter force-pushed the feat/runtime-host-update-scheduler branch 2 times, most recently from 9e9d1ce to 34ccd23 Compare August 25, 2026 04:06
Install platform-native periodic triggers as derived resources of Maka-managed Runtime Host deployments. Both adapters invoke the stable one-shot reconciler, repair drift idempotently, and remove scheduling with the service without duplicating update policy authority.\n\nGenerated-by: Codex
Keep scheduled reconciliation alive while it replaces or recovers the Runtime Host process, while user lifecycle actions continue to control the whole managed deployment. Explicit repair now owns scheduler drift and fails closed on systemd drop-in overrides.

Generated-by: Codex
@M4n5ter
M4n5ter force-pushed the feat/runtime-host-update-scheduler branch from 34ccd23 to c303ea7 Compare August 25, 2026 04:07
Treat scheduler presence as derived desired state and separate definition validation from runtime state. Quiesce systemd timer and worker together, and compensate failed deployment starts before reporting failure.

Generated-by: Codex

@me2seeks me2seeks left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reviewed c303ea7994 and found no blocking issues.

The current head has the cleaner lifecycle split: explicit service stop controls the whole managed deployment, while replacement uses retire() to stop only the Host process and preserve the scheduler that may be driving the update. The stable operator path, rollback boundary, and effective systemd fragment/drop-in verification are consistent with #3720 and #3228. I also traced managed-to-global replacement: the existing config boundary requires uninstall first, so a stale managed scheduler cannot survive a supported direct conversion.

Minor operational note: LaunchAgent logs append update stdout/stderr after two Host tails that may each consume half of RUNTIME_HOST_SERVICE_LOG_MAX_BYTES; the service manager then truncates the combined prefix to that same total budget, so scheduler diagnostics can disappear completely. The combined systemd journalctl --lines=200 query can similarly be saturated by Host entries. Reserving a bounded scheduler share (or placing scheduler diagnostics first) would keep update failures observable without changing lifecycle authority.

Checks on c303ea7994 are test: success.

简体中文

该 head 未发现阻断。service stop 管整个 managed deployment、replacement 通过 retire() 只停 Host 的 lifecycle 划分是正确的;稳定 operator、rollback 与 effective systemd/drop-in 校验也符合 #3720/#3228。另已确认 managed → global 不能直接转换,必须先 uninstall,因此受支持路径不会遗留旧 scheduler。

一个非阻断的可观测性问题:LaunchAgent 先拼接两段最多各占一半总预算的 Host 日志,再追加 scheduler 日志,而 service manager 随后按同一总预算截断前缀,可能完全丢掉 scheduler diagnostics;systemd 合并查询最后 200 行也可能被 Host 日志占满。建议为 scheduler 预留有界预算或优先放置 scheduler diagnostics。

Admit a wholly absent derived scheduler during upgrades, then install or restart it inside the replacement transaction without reloading an active scheduler. Keep forced recovery scoped to the Host process and reserve diagnostic space for every Host and scheduler log source.

Generated-by: Codex

@Astro-Han Astro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reviewed this head and found no blocking issues.

The manager reconciles managed updates via a derived scheduler (systemd/LaunchAgent) invoking the managed operator, correctly handling disabled-before-discovery and replacement preconditions. No authority drift, and cross-platform tests are solid.

Minor note: scheduler log share can be truncated when service logs are large — observability only.

Checks on 040b8086c8 are test: success.

简体中文该头未发现阻断。

Astro-Han
Astro-Han previously approved these changes Aug 25, 2026

@Astro-Han Astro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@Astro-Han
Astro-Han dismissed their stale review August 25, 2026 06:44

Hold pending Kabi P1/P2 — new head findings

@Astro-Han Astro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hold — new Kabi review reports 1×P1 + 1×P2, pending full evidence; previous GO on hold.

@Astro-Han Astro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update: blocking issue found.

[P2] Active Host + exact scheduler definition + inactive scheduler falsely accepted as already_current

Both platform start() paths start Host then scheduler, so a crash between them is a valid recovery path. However verifyDeployment() verifies the scheduler without requiring loaded/active (:193). The already_current shortcut at runtime-host-update-command.ts:237-260 therefore returns early without reaching backend replace() that repairs the scheduler. Probe: replacements=0, schedulerStillInactive=true, outcome=already_current.

Fix: when Host is active, readiness verification must also require scheduler loaded/active; otherwise go through the repaired replace path.

Checks on 040b8086c8 are test: success dependent on exact-head run, but this issue is independent of CI.

简体中文存在活跃 Host 下调度器未验证导致的假已是最新。

Keep static deployment validation independent of process state, but require scheduler readiness before an active exact deployment can be accepted as current. This routes partial startup recovery through the existing repair transaction.

Generated-by: Codex
@M4n5ter

M4n5ter commented Aug 25, 2026

Copy link
Copy Markdown
Member Author
English

Confirmed and fixed in 4d044ceb7.

Static deployment verification remains independent of process state. Runtime readiness now explicitly requires the configured scheduler to be active/loaded, so an active exact-version Host with an inactive scheduler enters the existing repaired replacement path instead of returning already_current.

The systemd and LaunchAgent tests now verify all three boundaries: a stopped scheduler still passes static deployment validation, fails readiness validation, and becomes ready after replacement. The complete CLI suite passes (453 tests).

简体中文

该问题已确认,并在 4d044ceb7 中修复。

静态部署验证仍与进程运行状态解耦;运行态 readiness 现在明确要求已配置的 scheduler 处于 active/loaded 状态。因此,当精确版本的 Host 正在运行但 scheduler 未运行时,会进入既有 repaired replacement 路径,而不会错误返回 already_current

systemd 与 LaunchAgent 测试现已覆盖三个边界:scheduler 停止时仍可通过静态部署验证、不能通过 readiness 验证,并在 replacement 后恢复 ready。完整 CLI 套件 453 项测试全部通过。

@me2seeks me2seeks left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I re-reviewed the 21a8d36a..040b8086 delta and independently confirmed the blocking recovery gap reported above. My earlier review of c303ea7994 is superseded by this finding.

runManagedRuntimeHostUpdateCli() treats an active exact-target Host as already_current when verifyRuntimeHostManagedServiceReady() succeeds (runtime-host-update-command.ts:237-260). That readiness function delegates deployment verification to the backend, but both current backends explicitly verify scheduler definition with operational state disabled:

  • systemd: verifySystemdUpdateSchedulerDesiredState(..., false) at runtime-host-systemd-service.ts:193;
  • LaunchAgent: verifyLaunchAgentUpdateSchedulerDesiredState(..., false) at runtime-host-launch-agent-service.ts:193.

The service start() paths start the Host before starting/loading the scheduler, so interruption between those operations leaves a real recoverable state: exact active Host + exact scheduler files + inactive/unloaded scheduler. The update command then cleans up and returns already_current without entering replace(), even though the scheduler remains unable to perform future reconciliation.

One implementation caution: verifyDeployment() is also used for definition-only discovery and stopped deployments, so globally changing it to require an active scheduler would conflate persisted definition with operational readiness. The narrow fix is to make the active-Host Ready/already_current path verify scheduler operational state, while retaining definition-only verification where an inactive deployment is valid.

Please add both platform regressions with an active, Ready exact-target Host and:

  • an installed/enabled but inactive systemd timer;
  • an exact scheduler plist that is not loaded.

Each should enter repair exactly once, return repaired, and leave the scheduler active/loaded. I found no additional blocker in this delta.

简体中文

我独立确认了这个阻断。Active exact-target Host 的 Ready 检查最终调用两个 backend 的 verifyDeployment(),但 systemd 与 LaunchAgent 都以 false 验证 scheduler,不要求 timer active / plist loaded,因此可能错误返回 already_current 并跳过 repair。

不要把所有 verifyDeployment() 全局改成要求 scheduler active,因为 discovery 与 stopped deployment 仍需要“只验证持久定义”。应只在 active Host 的 Ready/already_current 路径验证 scheduler operational state,并为 systemd inactive timer、LaunchAgent exact plist 未 loaded 各加一条回归测试:必须只 repair 一次、返回 repaired,最终 scheduler active/loaded。

本次 delta 未发现其他 blocker。

@me2seeks me2seeks left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved on exact head 4d044ceb7.

The new commit closes the inactive-scheduler recovery gap without broadening definition-only deployment verification:

  • verifyRuntimeHostManagedServiceReady() now explicitly requests scheduler readiness;
  • systemd requires the exact enabled timer to be active;
  • LaunchAgent requires the exact scheduler job to be loaded;
  • ordinary discovery and stopped-deployment verification retain their previous definition-only semantics;
  • manual policy still requires scheduler absence.

This makes an active, Ready exact-target Host with an inactive scheduler fail the already_current shortcut and enter the existing repair path. The backend regressions cover both platform states before and after replace().

Local verification on this exact head:

  • dependency packages and maka-agent build passed;
  • 37 focused LaunchAgent, service-manager, setup, and update-reconciliation tests passed.

No blocking findings remain in the 040b8086..4d044ceb fix delta. This approval supersedes my preceding confirmation of the pre-fix issue.

简体中文

已在精确 head 4d044ceb7 复核通过。Ready 路径现在明确要求 scheduler 可运行:systemd timer 必须 active,LaunchAgent scheduler 必须 loaded;definition-only discovery、stopped deployment 与 manual-policy scheduler-absent 语义均保持不变。因此 active exact-target Host + inactive scheduler 不会再误报 already_current,而会进入既有 repair 路径。

本地依赖与 CLI 构建通过,37 项相关测试全部通过;该修复 delta 未发现剩余 blocker。本 approval 取代上一条对修复前问题的确认。

@Astro-Han Astro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I verified the previous blocking issue is now closed.

verifyRuntimeHostManagedServiceReady now requires scheduler ready even for active targets, so an exact but inactive timer/unloaded agent no longer returns already_current and correctly goes through replacement convergence.

No remaining P0-P3. Checks on 4d044ceb78 are test: success.

简体中文该阻断已在该头闭合。

@Astro-Han Astro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

APPROVE — 4d044ce, P2 closed, test success.

@Astro-Han
Astro-Han merged commit d413895 into apache:main Aug 25, 2026
1 check passed
@M4n5ter
M4n5ter deleted the feat/runtime-host-update-scheduler branch August 25, 2026 07:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants