Skip to content

fix(macos): stop runtime config-health sidecar access#99039

Merged
clawsweeper[bot] merged 1 commit into
mainfrom
feature/issue-98917-macos-config-health
Jul 2, 2026
Merged

fix(macos): stop runtime config-health sidecar access#99039
clawsweeper[bot] merged 1 commit into
mainfrom
feature/issue-98917-macos-config-health

Conversation

@momothemage

@momothemage momothemage commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Closes #98917
Supersedes #98928

What Problem This Solves

Fixes an issue where users running the macOS app alongside the CLI/gateway would see recurring legacy state migration warnings because the app kept recreating ~/.openclaw/logs/config-health.json after Node core moved config-health state to the shared SQLite config_health_entries table.

The existing #98928 PR stops the legacy writer, but keeps a runtime fallback reader for the retired sidecar. This PR supersedes it by removing both the steady-state read and write paths from the macOS runtime, matching the database-first contract that legacy JSON state is only a doctor/migration input.

Why This Change Was Made

The macOS app now keeps its config observation baseline in process-local memory instead of reading or writing logs/config-health.json. That preserves in-session suspicious-read detection while letting openclaw doctor --fix own legacy JSON import/archive and preventing the app from recreating or depending on the retired sidecar.

Regression coverage now verifies both sides of the boundary: existing legacy sidecars are ignored by loadDict(), and normal plus suspicious config reads do not create logs/config-health.json.

User Impact

Mac app users should no longer get repeated [state-migrations] config-health conflict warnings on every CLI command or gateway bootstrap. Once doctor archives an existing legacy sidecar, the macOS app will not recreate it.

The only behavior intentionally lost is cross-session macOS-only config health baseline persistence; canonical config health state belongs to Node core's shared SQLite store.

Evidence

  • git diff --check origin/main...HEAD passed.
  • node scripts/run-vitest.mjs src/infra/state-migrations.test.ts passed: 1 file, 38 tests.
  • GitHub CI passed macos-swift and macos-node on PR head 8cbc4e10d3b88bdd3f99f987c06d351e62a3c2d5.
  • codex review --base origin/main reported no actionable correctness findings.
  • rg -n "configHealthFileName|configHealthStateURL|readConfigHealthState|writeConfigHealthState|config-health\\.json" apps/macos/Sources/OpenClaw/OpenClawConfigFile.swift apps/macos/Tests/OpenClawIPCTests/OpenClawConfigFileTests.swift src/infra/state-migrations.ts now finds the legacy path only in migration code and regression tests.
  • macOS before/after source-runtime smoke: compiled a temporary Swift harness around the actual OpenClawConfigFile.swift implementation from origin/main and from PR head, using real macOS filesystem state under a temp OPENCLAW_STATE_DIR. The harness ran saveDict(), deleted logs/config-health.json if present, then ran loadDict() twice. This reproduces the old sidecar recreation loop and shows the PR stops it:
RESULT variant=main afterSave=true afterDelete=false afterLoad1=true afterLoad2=true sidecarBytes=681
RESULT variant=pr-head afterSave=false afterDelete=false afterLoad1=false afterLoad2=false sidecarBytes=0

This is not a full GUI smoke, but it exercises the same macOS config file reader/writer path that the app calls (OpenClawConfigFile.loadDict / observeConfigRead) and proves the retired sidecar is no longer recreated after deletion.

  • Attempted swift test --filter OpenClawConfigFileTests in apps/macos; it is blocked locally before the touched tests run because this machine only has Command Line Tools, not full Xcode. The compile failure is ChatView+Previews.swift failing to resolve PreviewsMacros.SwiftUIView for #Preview, and xcodebuild -version reports the active developer directory is /Library/Developer/CommandLineTools. GitHub's macos-swift CI lane does have the required Xcode environment and passed.

  • AI-assisted (Codex)

@openclaw-barnacle openclaw-barnacle Bot added app: macos App: macos size: S maintainer Maintainer-authored PR labels Jul 2, 2026
@clawsweeper

clawsweeper Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Codex review: passed. Reviewed July 2, 2026, 8:20 AM ET / 12:20 UTC.

Summary
The PR removes macOS runtime reads and writes of logs/config-health.json, keeps config-health observation in process memory, and adds Swift tests for ignoring and not recreating the retired sidecar.

PR surface: Other +22. Total +22 across 2 files.

Reproducibility: yes. Current main still writes logs/config-health.json from the macOS config observation path, and the PR body includes before/after terminal output for that same Swift path.

Review metrics: 1 noteworthy metric.

  • Config-health persistence surface: 1 legacy reader removed, 1 legacy writer removed, 1 process-local cache added. This is the compatibility-sensitive part of the PR because it moves macOS config-health observation out of a cross-session sidecar.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #98917
Summary: This PR is a candidate fix for the canonical macOS config-health sidecar writer bug and supersedes an older narrower PR that removed only the writer path.

Members:

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

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🐚 platinum hermit
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • none.

Risk before merge

  • [P1] Merging intentionally removes the macOS app's cross-session JSON config-health baseline; this aligns with the SQLite-owned durable-state contract but is still a compatibility-sensitive upgrade behavior change.
  • [P1] The contributor proof exercises the actual Swift config-file path with before/after terminal output, but it is not a full signed GUI app plus CLI/gateway bootstrap smoke.

Maintainer options:

  1. Accept SQLite-Owned Durable State (recommended)
    Maintainers can merge this shape if they agree the macOS app should keep only process-local observation state while durable config-health state stays in SQLite.
  2. Request Full App Smoke
    Maintainers can ask for an additional signed macOS app plus CLI/gateway bootstrap smoke if they want proof beyond the source-runtime harness before accepting the upgrade behavior.
  3. Pause For Native Durable-State Design
    If cross-session native app config-health persistence must remain, pause this PR and design that through the canonical SQLite or gateway-owned path instead of reviving the sidecar.

Next step before merge

  • No automated repair is needed; the remaining action is maintainer acceptance or gated automerge of the compatibility tradeoff.

Security
Cleared: The diff only changes Swift config-health persistence behavior and tests; it does not add dependencies, workflows, permissions, secret handling, or code-download surfaces.

Review details

Best possible solution:

Land this sidecar-removal shape after maintainer acceptance, keeping durable config health in SQLite/doctor migration and avoiding any restored steady-state JSON fallback.

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

Yes. Current main still writes logs/config-health.json from the macOS config observation path, and the PR body includes before/after terminal output for that same Swift path.

Is this the best way to solve the issue?

Yes, pending maintainer acceptance. Removing the macOS steady-state sidecar read/write is the narrow storage-boundary fix because durable config health is already owned by config_health_entries and legacy JSON belongs to doctor migration only.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 98e97661dae4.

Label changes

Label changes:

  • add status: 🚀 automerge armed: This PR is in ClawSweeper's automerge lane. Sufficient (terminal): The PR body and follow-up comment include before/after terminal output from a macOS Swift harness exercising the actual OpenClawConfigFile path and showing the sidecar is no longer recreated.
  • remove status: 👀 ready for maintainer look: Current PR status label is status: 🚀 automerge armed.

Label justifications:

  • P2: This fixes a normal-priority macOS migration warning loop with limited functional blast radius.
  • merge-risk: 🚨 compatibility: The diff removes a persisted macOS config-health sidecar and changes upgrade behavior to process-local app state plus SQLite-owned durable state.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🐚 platinum hermit and patch quality is 🐚 platinum hermit.
  • status: 🚀 automerge armed: This PR is in ClawSweeper's automerge lane. Sufficient (terminal): The PR body and follow-up comment include before/after terminal output from a macOS Swift harness exercising the actual OpenClawConfigFile path and showing the sidecar is no longer recreated.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body and follow-up comment include before/after terminal output from a macOS Swift harness exercising the actual OpenClawConfigFile path and showing the sidecar is no longer recreated.
Evidence reviewed

PR surface:

Other +22. Total +22 across 2 files.

View PR surface stats
Area Files Added Removed Net
Source 0 0 0 0
Tests 0 0 0 0
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 2 59 37 +22
Total 2 59 37 +22

What I checked:

Likely related people:

  • steipete: Authored the merged runtime-state-to-SQLite refactor that defines legacy runtime files as migration inputs and moved durable state toward typed SQLite stores. (role: database-first feature-history owner; confidence: high; commits: f91de52f0d23; files: src/infra/state-migrations.ts, src/state/openclaw-state-schema.sql, apps/macos/Sources/OpenClaw/OpenClawConfigFile.swift)
  • vincentkoc: Current-line blame for the macOS sidecar helpers, core config-health store, and migration conflict path points to a broad recent source import, making this a routing signal rather than precise defect attribution. (role: recent current-source importer; confidence: medium; commits: 76db9a337622; files: apps/macos/Sources/OpenClaw/OpenClawConfigFile.swift, src/config/io.health-state.ts, src/infra/state-migrations.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

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.

How this review workflow works
  • 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.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. labels Jul 2, 2026
@momothemage

Copy link
Copy Markdown
Contributor Author

Updated the PR Evidence section with the requested behavior proof.

Added a macOS before/after source-runtime smoke using the actual OpenClawConfigFile.swift implementation from origin/main and PR head. The harness runs saveDict(), deletes logs/config-health.json, then runs loadDict() twice against a real temp OPENCLAW_STATE_DIR:

RESULT variant=main afterSave=true afterDelete=false afterLoad1=true afterLoad2=true sidecarBytes=681
RESULT variant=pr-head afterSave=false afterDelete=false afterLoad1=false afterLoad2=false sidecarBytes=0

Also noted that GitHub CI passed macos-swift and macos-node; local full Swift test remains blocked by missing full Xcode / PreviewsMacros on this machine.

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jul 2, 2026
@momothemage

Copy link
Copy Markdown
Contributor Author

Maintainer judgment: I would accept this storage-boundary change.

The durable config-health owner is now the shared SQLite config_health_entries table, and logs/config-health.json should be treated as legacy migration input only. Keeping a macOS runtime read fallback for that sidecar would preserve a second steady-state source of truth and leave this area vulnerable to the same migration/consistency loop again.

I am comfortable with the tradeoff that the macOS app loses a cross-session JSON baseline here. That sidecar is not a user data contract, and the app still preserves in-session anomaly detection via process-local state. Durable cross-session config health should flow through the canonical SQLite/gateway-owned path rather than reviving the retired sidecar.

The proof is sufficient for this scope: CI passed the macOS Swift and Node lanes, and the before/after Swift harness demonstrates that current main recreates the sidecar after deletion while this PR head does not. A full signed GUI smoke would be extra confidence, but I would not block this narrow fix on it.

Given that #98928 only removes the writer while keeping a legacy runtime reader, I would treat this PR as the better canonical fix and supersede #98928.

@clawsweeper approve

@clawsweeper

clawsweeper Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

🦞👀
ClawSweeper picked this up.

Command router queued. I will update this comment with the next step.

@momothemage

Copy link
Copy Markdown
Contributor Author

@clawsweeper automerge

@clawsweeper

clawsweeper Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

🦞✅
ClawSweeper merged this PR after the passing review.

Source: clawsweeper[bot]
Feedback: structured ClawSweeper verdict: pass (sha=8cbc4e10d3b88bdd3f99f987c06d351e62a3c2d5)
Merge status: merged by ClawSweeper automerge
Merged at: 2026-07-02T12:22:22Z
Merge commit: 3ae5e98bf605

What merged:

  • The PR removes macOS runtime reads and writes of logs/config-health.json, keeps config-health observation in process memory, and adds Swift tests for ignoring and not recreating the retired sidecar.
  • PR surface: Other +22. Total +22 across 2 files.
  • Reproducibility: yes. Current main still writes logs/config-health.json from the macOS config observation path, and the PR body includes before/after terminal output for that same Swift path.

Automerge notes:

  • No ClawSweeper repair was needed after automerge opt-in.

The automerge loop is complete.

Automerge progress:

  • 2026-07-02 12:16:46 UTC review queued 8cbc4e10d3b8 (queued)
  • 2026-07-02 12:21:52 UTC review passed 8cbc4e10d3b8 (structured ClawSweeper verdict: pass (sha=8cbc4e10d3b88bdd3f99f987c06d351e62a3c...)
  • 2026-07-02 12:22:24 UTC merged 8cbc4e10d3b8 (merged by ClawSweeper automerge)

@clawsweeper clawsweeper Bot added clawsweeper:automerge Maintainer opted this PR into bounded ClawSweeper-reviewed automerge status: 🚀 automerge armed This PR is in ClawSweeper's automerge lane. and removed status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Jul 2, 2026
@clawsweeper
clawsweeper Bot merged commit 3ae5e98 into main Jul 2, 2026
141 of 156 checks passed
@clawsweeper
clawsweeper Bot deleted the feature/issue-98917-macos-config-health branch July 2, 2026 12:22
LeonidasLux pushed a commit to LeonidasLux/openclaw that referenced this pull request Jul 3, 2026
Summary:
- The PR removes macOS runtime reads and writes of `logs/config-health.json`, keeps config-health observation in process memory, and adds Swift tests for ignoring and not recreating the retired sidecar.
- PR surface: Other +22. Total +22 across 2 files.
- Reproducibility: yes. Current main still writes `logs/config-health.json` from the macOS config observation path, and the PR body includes before/after terminal output for that same Swift path.

Automerge notes:
- No ClawSweeper repair was needed after automerge opt-in.

Validation:
- ClawSweeper review passed for head 8cbc4e1.
- Required merge gates passed before the squash merge.

Prepared head SHA: 8cbc4e1
Review: openclaw#99039 (comment)

Co-authored-by: momothemage <[email protected]>
Approved-by: momothemage
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 3, 2026
Summary:
- The PR removes macOS runtime reads and writes of `logs/config-health.json`, keeps config-health observation in process memory, and adds Swift tests for ignoring and not recreating the retired sidecar.
- PR surface: Other +22. Total +22 across 2 files.
- Reproducibility: yes. Current main still writes `logs/config-health.json` from the macOS config observation path, and the PR body includes before/after terminal output for that same Swift path.

Automerge notes:
- No ClawSweeper repair was needed after automerge opt-in.

Validation:
- ClawSweeper review passed for head 8cbc4e1.
- Required merge gates passed before the squash merge.

Prepared head SHA: 8cbc4e1
Review: openclaw#99039 (comment)

Co-authored-by: momothemage <[email protected]>
Approved-by: momothemage
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app: macos App: macos clawsweeper:automerge Maintainer opted this PR into bounded ClawSweeper-reviewed automerge maintainer Maintainer-authored PR merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: S status: 🚀 automerge armed This PR is in ClawSweeper's automerge lane.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Mac app still writes legacy logs/config-health.json every ~3s, permanently conflicting with the config_health_entries SQLite migration

1 participant