Skip to content

fix(daemon): unify recovery hints and preserve log paths - #139227

Merged
steipete merged 2 commits into
mainfrom
codex/deslop-daemon-hints
Sep 5, 2026
Merged

steipete merged 2 commits into
mainfrom
codex/deslop-daemon-hints

Conversation

@steipete

@steipete steipete commented Sep 5, 2026 •

Copy link
Copy Markdown
Contributor

Closes #139226

Additional instructions

MUST: Keep Allow edits from maintainers enabled for this PR so maintainers
can help update the branch when needed.

What Problem This Solves

Fixes an issue where operators inspecting macOS Gateway recovery hints are directed to a nonexistent restart log when their state-directory name contains a literal backslash. The log is written successfully, but the advertised path replaces the backslash with a directory separator.

Why This Change Was Made

Recovery hints must display the path supplied by the log owner. This removes a display-only transformation introduced for a mocked Windows-path test, while retaining the existing producer behavior for native and cross-platform paths.

The same cleanup centralizes repeated GUI-session and stopped-service detail lines in the daemon hint owner. Status and doctor retain their own eligibility checks, headings, profile/container command context, installation restrictions, crash-loop guidance, and ordering. It also removes missingSupervision branches left behind after the native producer switched to stopped/unknown/GUI-session state in #123961; current source and the v2026.9.1 tag no longer produce that field.

The daemon reference also corrects an existing file-mode claim: LaunchAgent plists use 0644, while the generated environment file (0600) and wrapper (0700) remain private. This documents existing behavior; it does not change permissions.

Production changes are −71 lines; tests are −35 lines. There are no changes to configuration, schemas, service definitions, log writers, retention, or lifecycle authority.

User Impact

macOS recovery hints now identify the actual log file when a POSIX path contains a backslash. Existing status and doctor guidance—including systemd restart-limit recovery and the deliberate exit-78 exception—retains its text and behavior.

Evidence

Current head: 7c8a7424fbed0b6db6223d004a064da397888819. All 15 files from the reviewed source commit remain byte-identical; the successor only corrects the documented LaunchAgent file modes. Final-head source review is clean. Hosted CI passed, including the final CI gate; its preflight confirmed a merge of this exact head into base 84b79be0d1f5556df5f4d131525c7a04f3b81db1.

The reproduction ran on macOS 27.0 with Node v26.8.1 against source base 0e6b033d4bdb0ce6750f24fb9044bb524ddd344e. It used the actual lifecycle log writer and hint helper in a temporary fixture:

Observation Before After
Written file <fixture>/state\literal/logs/gateway-restart.log Same
Advertised file <fixture>/state/literal/logs/gateway-restart.log <fixture>/state\literal/logs/gateway-restart.log
Advertised file exists No Yes
  • The permanent regression in src/daemon/restart-logs.test.ts failed on the original source for this exact path mismatch and passes after the fix.
  • 1,944 comparison rows using the actual assembled status printer and 108 distinct doctor inputs are byte-identical before/after; each doctor result is reused across its status-matrix rows. These are platform-selected rendering cases run on macOS, covering service states, profile/container context, file-log omission, RPC outcomes, GUI failures, cached labels, systemd unavailability, crash loops, cgroup warnings, and exit 78.
  • 312 tests passed, one existing Windows-only test skipped: 290 owner/sibling cases plus 22 existing installation-policy integration cases. Tests used at most two workers. The latter cover both allowed and blocked installation advice, default/named profiles, Nix/external supervision, diagnostic-only services, and JSON after human output.
  • Own frozen dependencies were installed. Applicable trusted preinstall/postinstall validation passed; source-checkout postinstall pruning is a no-op, and shared Git-hook preparation was omitted. Formatting and the complete classified changed gate passed, including production/test type checks, full core lint, dead exports, and repository guards.
  • Fresh mandatory Codex P2 review, a separate independent source challenge, and the direct committed-head review are clean for source commit 402e3ce1b717c84a79832689ea75e1e2c5e7c1fa. The one-line documentation follow-up passed documentation checks, independent source review, and its own fresh mandatory P2 review. The direct review of final head 7c8a7424fbed0b6db6223d004a064da397888819 is also clean; hosted CI passed on that exact head.

The filesystem and assembled-rendering proof did not start, stop, install, or restart a live service. No operator configuration or state was used. The changed classifier requires core/core-test validation; no package or lazy-import boundary changed, so no full build was run.

The completed ClawSweeper review covers this exact head and reports no correctness or security findings and no Rank-up moves. Its sole checklist item is an automated data-model compatibility flag.

ClawSweeper compatibility checklist: no migration or upgrade conversion applies. src/commands/doctor-format.ts formats transient recovery guidance; it does not read or write persisted data. The removed optional GatewayServiceRuntime.missingSupervision field has no current or v2026.9.1 native producer, persisted reader, or public SDK input. Its replacement stopped/unknown/GUI-session states were already established by #123961. This PR changes no schema, stored representation, writer, retention, migration, or service definition. Current and stable producer/consumer inspection, the 312 passing tests, and the 1,944 rendering comparison rows support that unchanged compatibility contract.

@clawsweeper

clawsweeper Bot commented Sep 5, 2026 •

Copy link
Copy Markdown
Contributor

🦞👀
ClawSweeper picked this up.

Pull request received. I will update this pull request when review starts.

ClawSweeper review complete

ClawSweeper finished reviewing this revision. The review result is being finalized.

View the workflow run.

@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation gateway Gateway runtime cli CLI command changes commands Command implementations size: M maintainer Maintainer-authored PR labels Sep 5, 2026
@steipete
steipete marked this pull request as ready for review September 5, 2026 17:05
@clawsweeper

clawsweeper Bot commented Sep 5, 2026 •

Copy link
Copy Markdown
Contributor

Codex review: blocked before merge. Reviewed September 5, 2026, 1:48 PM ET / 17:48 UTC.

ClawSweeper review

What this changes

Preserves actual macOS log paths in recovery messages, shares status and doctor guidance, removes unused runtime-flag handling, and corrects documented LaunchAgent permissions.

Merge readiness

⛔ Blocked before merge - 1 item remains

This remains a useful fix for a current diagnostic defect, with no blocking findings. The earlier migration-proof warning is unsupported: the patch changes neither stored representations nor log-writing behavior.

Priority: P2
Reviewed head: 7c8a7424fbed0b6db6223d004a064da397888819

Review scores

Measure Result What it means
Overall readiness 🐚 platinum hermit (4/6) A focused, net-negative repair with relevant filesystem proof and preserved caller behavior.
Proof confidence 🐚 platinum hermit (4/6) Sufficient (live_output): The captured macOS filesystem run exercises the actual lifecycle writer and changed hint helper, showing that the advertised path identifies the existing file after the fix; assembled status/doctor comparisons supplement the refactor coverage.
Patch quality 🐚 platinum hermit (4/6) No actionable review findings were identified.

Verification

Check Result Evidence
Real behavior Verified Sufficient (live_output): The captured macOS filesystem run exercises the actual lifecycle writer and changed hint helper, showing that the advertised path identifies the existing file after the fix; assembled status/doctor comparisons supplement the refactor coverage.
Evidence reviewed 11 items Verified introduced scope: The checkout matches the pinned original head. Raw test-merge parents are the pinned base followed by that head; its comparison against the base contains only the supplied daemon, doctor, update-recovery, test, and documentation changes.
Current main still contains the defect: Fetched main applies toDarwinDisplayPath to the resolved restart-log path, replacing literal backslashes after the writer has selected its filename. The PR removes that second transformation.
Canonical filesystem boundary: The unchanged lifecycle writer uses resolveGatewayRestartLogPath directly. The revised hint now displays that same result; restart-logs.test.ts:125 exercises the actual filesystem writer with a literal-backslash state directory. This boundary uses OpenClaw daemon helpers and Node filesystem/path APIs, with no Codex runtime or protocol dependency.
Findings None None.
Security None None.

How this fits together

Daemon diagnostics turn native service state and resolved log paths into status output and doctor recovery guidance. These messages help operators inspect and recover their Gateway service.

flowchart TD
  A[Native service state] --> C[Status and doctor checks]
  B[Profile and environment] --> C
  B --> D[Canonical log paths]
  C --> E[Shared recovery hints]
  D --> E
  D --> F[Lifecycle log writer]
  E --> G[Operator diagnostics]
Loading

Before merge

  • Add data-model compatibility proof - Confirm migration or upgrade compatibility proof before merge.
Agent review details

Security

None.

PR surface

Source -71, Tests -35, Docs 0. Total -106 across 16 files.

View PR surface stats
Area Files Added Removed Net
Source 8 77 148 -71
Tests 7 36 71 -35
Docs 1 1 1 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 16 114 220 -106

Review metrics

Metric Value Why it matters
Production versus test delta Production −71 lines; tests −35 lines; documentation net 0 The repair consolidates duplicate formatting and replaces a mock-driven path expectation with filesystem regression coverage.

Stored data model

Persistent data-model change detected: unknown-data-model-change: src/commands/doctor-format.ts. Confirm migration or upgrade compatibility proof before merge.

Root-cause cluster

Relationship: fixed_by_candidate
Canonical: #139226
Summary: This PR directly repairs the linked open diagnostic-path issue; the earlier LaunchAgent state repair is related historical context.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Technical review

Best possible solution:

Keep log-path ownership in the existing resolvers and share recovery text while preserving each caller’s eligibility and policy decisions.

Do we have a high-confidence way to reproduce the issue?

Yes. Current-main source deterministically rewrites a literal backslash after resolving the written filename, matching the supplied macOS before/after evidence; this review did not execute the reproduction.

Is this the best way to solve the issue?

Yes. Removing the display-only rewrite repairs the failing boundary directly; changing the writer or migrating existing logs would unnecessarily alter correct behavior.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 3e4becea5e2c.

Labels

Label changes:

  • add P2: Incorrect recovery-log guidance affects macOS state paths containing literal backslashes; the underlying log write succeeds.
  • add proof: sufficient: Contributor real behavior proof is sufficient. The captured macOS filesystem run exercises the actual lifecycle writer and changed hint helper, showing that the advertised path identifies the existing file after the fix; assembled status/doctor comparisons supplement the refactor coverage.
  • add rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🐚 platinum hermit and patch quality is 🐚 platinum hermit.

Label justifications:

  • P2: Incorrect recovery-log guidance affects macOS state paths containing literal backslashes; the underlying log write succeeds.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🐚 platinum hermit and patch quality is 🐚 platinum hermit.
  • proof: sufficient: Contributor real behavior proof is sufficient. The captured macOS filesystem run exercises the actual lifecycle writer and changed hint helper, showing that the advertised path identifies the existing file after the fix; assembled status/doctor comparisons supplement the refactor coverage.

Evidence

What I checked:

  • Verified introduced scope: The checkout matches the pinned original head. Raw test-merge parents are the pinned base followed by that head; its comparison against the base contains only the supplied daemon, doctor, update-recovery, test, and documentation changes. (f8c12ca764de)
  • Current main still contains the defect: Fetched main applies toDarwinDisplayPath to the resolved restart-log path, replacing literal backslashes after the writer has selected its filename. The PR removes that second transformation. (src/daemon/runtime-hints.ts:26, 3e4becea5e2c)
  • Canonical filesystem boundary: The unchanged lifecycle writer uses resolveGatewayRestartLogPath directly. The revised hint now displays that same result; restart-logs.test.ts:125 exercises the actual filesystem writer with a literal-backslash state directory. This boundary uses OpenClaw daemon helpers and Node filesystem/path APIs, with no Codex runtime or protocol dependency. (src/daemon/restart-logs.ts:81, 7c8a7424fbed)
  • Removed flag has no current producer: readLaunchAgentRuntime returns stopped for an installed, unloaded plist and separately reports unknown, missing-unit, or GUI-session states. The complete current source search found no remaining missingSupervision references. The supplied merged history at fix: report stopped LaunchAgents as stopped #123961 explains the earlier producer change; it does not fix the distinct path-display defect. (src/daemon/launchd-runtime.ts:292, 3e4becea5e2c)
  • Caller and sibling behavior: Status retains missing-unit precedence and loaded/stopped eligibility; doctor retains GUI-session, systemd-unavailable, crash-loop, cgroup, and exit-78 handling. Update recovery still requires an installed, unloaded service and uses its resolved environment. The node-service caller retains its own service names and log prefix. (src/cli/daemon-cli/status.print.ts:427, 7c8a7424fbed)
  • Captured behavior proof: The supplied GitHub snapshot, sourceRevision 1c19792f1a3b1a54c8d5fb358dfc5e5735e5bffd1f300df8b07be244f0d8d579, reports macOS 27.0 / Node 26.8.1 execution of the actual writer and hint helper: advertisedExists changes from false to true while the written path remains unchanged. It also reports 1,944 assembled status comparisons, 108 doctor inputs, and 312 passing tests. The final commit changes documentation only. No live service mutation is claimed or needed to demonstrate this filename-display correction. (src/daemon/runtime-hints.ts:19, 7c8a7424fbed)

Likely related people:

  • steipete: Suggested for follow-up; no historical authorship or introduction is verified. (role: unverified routing candidate; confidence: low)
  • Masato Hoshino: Suggested for follow-up; no historical authorship or introduction is verified. (role: unverified routing candidate; confidence: low)

Rating scale

Score Internal tier Crab rank Meaning
6/6 S 🦀 challenger crab Exceptional readiness
5/6 A 🦞 diamond lobster Very strong readiness
4/6 B 🐚 platinum hermit Good normal PR; ordinary maintainer review
3/6 C 🦐 gold shrimp Useful, but confidence is limited
2/6 D 🦪 silver shellfish Proof or implementation needs work
1/6 F 🧂 unranked krab Not merge-ready
N/A NA 🌊 off-meta tidepool Rating does not apply

Overall follows the weaker of proof and patch quality.
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

Workflow

  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

History

Review history (1 earlier review cycle)
  • reviewed 2026-09-05T17:12:19.265Z sha 7c8a742 :: blocked before merge. :: none

@steipete

steipete commented Sep 5, 2026

Copy link
Copy Markdown
Contributor Author

ClawSweeper compatibility checklist: no migration or upgrade conversion applies. src/commands/doctor-format.ts formats transient recovery guidance; it does not read or write persisted data. The removed optional GatewayServiceRuntime.missingSupervision field has no current or v2026.9.1 native producer, persisted reader, or public SDK input. Its replacement stopped/unknown/GUI-session states were already established by #123961. This PR changes no schema, stored representation, writer, retention, migration, or service definition. Current and stable producer/consumer inspection, the 312 passing tests, and the 1,944 rendering comparison rows support that unchanged compatibility contract.

@steipete
steipete merged commit 925fb0c into main Sep 5, 2026
257 checks passed
@steipete
steipete deleted the codex/deslop-daemon-hints branch September 5, 2026 17:54
@steipete

steipete commented Sep 5, 2026

Copy link
Copy Markdown
Contributor Author

Merged via squash.

vincentkoc added a commit to aniruddhaadak80/openclaw that referenced this pull request Sep 5, 2026
* commit '925fb0c3353ce98f1c8d6d1f2c27bbb8472af095':
  fix(daemon): unify recovery hints and preserve log paths (openclaw#139227)
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Sep 6, 2026
…9227)

* fix(daemon): preserve log paths in shared recovery hints

* docs(daemon): correct LaunchAgent file permission guidance
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cli CLI command changes commands Command implementations docs Improvements or additions to documentation gateway Gateway runtime maintainer Maintainer-authored PR size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

macOS recovery hints rewrite literal backslashes in restart-log paths

1 participant