Skip to content

fix(desktop): stop stale ephemeral Host at startup - #4781

Merged
M4n5ter merged 1 commit into
mainfrom
fix/stale-ephemeral-host-recovery
Sep 4, 2026
Merged

fix(desktop): stop stale ephemeral Host at startup#4781
M4n5ter merged 1 commit into
mainfrom
fix/stale-ephemeral-host-recovery

Conversation

@M4n5ter

@M4n5ter M4n5ter commented Sep 4, 2026

Copy link
Copy Markdown
Member

Summary

English

When an incompatible local ephemeral Runtime Host still owns the State Root, startup only offered Wait, Copy Diagnostics, or Cancel. Users were told to find and terminate a PID outside Maka even though Desktop can safely recover this case itself.

This change adds an explicit Stop Host and Continue choice while retaining Wait and Cancel Startup. It never silently terminates an unknown process. Desktop first records an OS-owned identity for the exact process lifetime, then connects to the registered endpoint and validates the Host/root/epoch handshake. After the user confirms, it rereads the complete registration, current Desktop authority, and process-lifetime identity immediately before signaling the exact root PID. Any changed or unavailable evidence fails closed.

The process identity comes from the operating system rather than a flattened command line: macOS uses proc_pidinfo start time, Windows uses GetProcessTimes, and Linux uses boot ID plus /proc/<pid>/stat start ticks. Arguments and workspace paths therefore cannot impersonate the identity. This support lives in the already-shipped Runtime Host native addon; Linux retains a procfs fallback when the addon is unavailable.

Owned Host shutdown remains on the existing process-tree path. Managed services, remote Hosts, unknown lifecycle registrations, older native addons without the identity API, and failed identity queries keep the existing non-destructive Wait/Cancel behavior.

中文

本地旧版临时 Runtime Host 仍占用工作区时,启动窗口以前只有“等待”“复制诊断信息”和“取消启动”。问题发生在 Maka 里,用户却只能自己去系统进程管理器查 PID、结束进程。

本次增加了明确的 “停止 Host 并继续”,同时保留 “等待”“取消启动”。Maka 不会只凭一个 PID 就结束进程:它会先记录该 PID 对应的操作系统进程实例,再连接注册端点并完成 Host、State Root 和 epoch 校验。用户确认后,真正发信号前还会重新核对完整注册信息、当前 Desktop 是否仍拥有这次操作的授权,以及 PID 是否仍是刚才那个进程实例。任何证据缺失或发生变化,操作都会安全停止。

进程身份直接来自操作系统,不再解析容易歧义的命令行文本:macOS 使用 proc_pidinfo 的启动时刻,Windows 使用 GetProcessTimes,Linux 使用 boot ID 与 /proc/<pid>/stat 的启动 tick。即使工作区路径里恰好包含类似命令行参数的文字,也不可能被误认成身份。实现复用了产品已经随包发布的 Runtime Host 原生模块;Linux 在原生模块不可用时仍可直接读取 procfs。

Desktop 自己启动的 Host 仍走原有的进程树退出路径。托管服务、远程 Host、无法确认生命周期的注册、缺少新身份能力的旧原生模块,以及身份查询失败的情况,都继续只提供非破坏性的等待或取消,不会冒险结束进程。

Verification

  • npm run lint
  • npm run format:check
  • npm run build
  • npm run typecheck
  • npx knip --workspace apps/desktop
  • npx knip --workspace packages/ui
  • cargo fmt --all --manifest-path native/runtime-host-peer/Cargo.toml -- --check
  • cargo clippy --locked --all-targets --manifest-path native/runtime-host-peer/Cargo.toml -- -D warnings
  • cargo test --locked --manifest-path native/runtime-host-peer/Cargo.toml — 31 passed
  • Affected Desktop and Runtime Host suites — 65 passed
  • Native macOS smoke check confirmed a stable identity for a live PID and no identity for a missing PID
  • Parallel deep-code-review and simplify-audit converged with no findings

AI use

Select exactly one:

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

Tool(s) and scope: OpenAI Codex diagnosed the unsafe stale-process recovery boundary, implemented the OS process-lifetime fence and Desktop recovery action, added regression coverage, and performed parallel correctness and simplification audits.

Checklist

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

Does this PR entail a change in behavior?

  • Yes — described under Summary above
  • No

@github-actions github-actions Bot added the effort/M Under 500 readable lines label Sep 4, 2026

@jackwener jackwener left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Approved at exact head 162b5096cd07a8c690ca633d10e94007de673fa7 at the explicit direction of M4n5ter. No technical review was performed as part of this action; M4n5ter requested the approval and accepts responsibility for subsequent handling.


Review notice: This approval was submitted by an automated review agent operated by jackwener and is published at the direction of M4n5ter, who requested this action and is the human accountable for it.

@M4n5ter
M4n5ter force-pushed the fix/stale-ephemeral-host-recovery branch from 162b509 to 2529dec Compare September 4, 2026 14:12
Offer an explicit recovery action when an incompatible local ephemeral Runtime Host still owns the State Root. Bind the action to a validated Host handshake and an OS process-lifetime identity, then revalidate the registration and live Desktop intent immediately before signaling; managed, remote, and unverifiable Hosts fail closed.

Generated-by: OpenAI Codex
@M4n5ter
M4n5ter force-pushed the fix/stale-ephemeral-host-recovery branch from 2529dec to 4c55017 Compare September 4, 2026 14:44
@M4n5ter
M4n5ter merged commit ece69ab into main Sep 4, 2026
15 checks passed
@M4n5ter
M4n5ter deleted the fix/stale-ephemeral-host-recovery branch September 4, 2026 15:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/M Under 500 readable lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants