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

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 8cbc4e10d3.
- Required merge gates passed before the squash merge.

Prepared head SHA: 8cbc4e10d3
Review: https://github.com/openclaw/openclaw/pull/99039#issuecomment-4864550335

Co-authored-by: momothemage <niuzhengnan@163.com>
Approved-by: momothemage
This commit is contained in:
Momo
2026-07-02 20:22:21 +08:00
committed by GitHub
parent 98e97661da
commit 3ae5e98bf6
2 changed files with 59 additions and 37 deletions
@@ -5,8 +5,8 @@ import OpenClawProtocol
enum OpenClawConfigFile {
private static let logger = Logger(subsystem: "ai.openclaw", category: "config")
private static let configAuditFileName = "config-audit.jsonl"
private static let configHealthFileName = "config-health.json"
private static let fileLock = NSRecursiveLock()
private nonisolated(unsafe) static var configHealthState: [String: Any] = [:]
private static func withFileLock<T>(_ body: () throws -> T) rethrows -> T {
self.fileLock.lock()
@@ -477,39 +477,6 @@ enum OpenClawConfigFile {
.appendingPathComponent(self.configAuditFileName, isDirectory: false)
}
private static func configHealthStateURL() -> URL {
self.stateDirURL()
.appendingPathComponent("logs", isDirectory: true)
.appendingPathComponent(self.configHealthFileName, isDirectory: false)
}
private static func readConfigHealthState() -> [String: Any] {
let url = self.configHealthStateURL()
guard let data = try? Data(contentsOf: url),
let root = try? JSONSerialization.jsonObject(with: data) as? [String: Any]
else {
return [:]
}
return root
}
private static func writeConfigHealthState(_ root: [String: Any]) {
guard JSONSerialization.isValidJSONObject(root),
let data = try? JSONSerialization.data(withJSONObject: root, options: [.prettyPrinted, .sortedKeys])
else {
return
}
let url = self.configHealthStateURL()
do {
try FileManager().createDirectory(
at: url.deletingLastPathComponent(),
withIntermediateDirectories: true)
try data.write(to: url, options: [.atomic])
} catch {
// best-effort
}
}
private static func configHealthEntry(state: [String: Any], configPath: String) -> [String: Any] {
let entries = state["entries"] as? [String: Any]
return entries?[configPath] as? [String: Any] ?? [:]
@@ -672,7 +639,7 @@ enum OpenClawConfigFile {
private static func observeConfigRead(data: Data, root: [String: Any]?, configURL: URL, valid: Bool) {
let observedAt = ISO8601DateFormatter().string(from: Date())
let current = self.configFingerprint(data: data, root: root, configURL: configURL, observedAt: observedAt)
var state = self.readConfigHealthState()
var state = self.configHealthState
let entry = self.configHealthEntry(state: state, configPath: configURL.path)
let lastKnownGood = entry["lastKnownGood"] as? [String: Any]
let suspicious = self.observeSuspiciousReasons(
@@ -688,7 +655,7 @@ enum OpenClawConfigFile {
]
if !self.sameFingerprint(lastKnownGood, current) || entry["lastObservedSuspiciousSignature"] != nil {
state = self.setConfigHealthEntry(state: state, configPath: configURL.path, entry: nextEntry)
self.writeConfigHealthState(state)
self.configHealthState = state
}
return
}
@@ -750,7 +717,7 @@ enum OpenClawConfigFile {
var nextEntry = entry
nextEntry["lastObservedSuspiciousSignature"] = signature
state = self.setConfigHealthEntry(state: state, configPath: configURL.path, entry: nextEntry)
self.writeConfigHealthState(state)
self.configHealthState = state
}
private static func appendConfigWriteAudit(_ fields: [String: Any]) {
@@ -266,6 +266,58 @@ struct OpenClawConfigFileTests {
}
}
@MainActor
@Test
func `load dict ignores legacy config health sidecar`() async throws {
let stateDir = FileManager().temporaryDirectory
.appendingPathComponent("openclaw-state-\(UUID().uuidString)", isDirectory: true)
let configPath = stateDir.appendingPathComponent("openclaw.json")
let auditPath = stateDir.appendingPathComponent("logs/config-audit.jsonl")
let configHealthPath = stateDir.appendingPathComponent("logs/config-health.json")
defer { try? FileManager().removeItem(at: stateDir) }
try FileManager().createDirectory(
at: configHealthPath.deletingLastPathComponent(),
withIntermediateDirectories: true)
let legacyHealth = """
{
"entries": {
"\(configPath.path)": {
"lastKnownGood": {
"bytes": 4096,
"gatewayMode": "local",
"hasMeta": true
}
}
}
}
"""
try legacyHealth.write(to: configHealthPath, atomically: true, encoding: .utf8)
let updateOnlyConfig = """
{
"update": {
"channel": "beta"
}
}
"""
try updateOnlyConfig.write(to: configPath, atomically: true, encoding: .utf8)
try await TestIsolation.withEnvValues([
"OPENCLAW_STATE_DIR": stateDir.path,
"OPENCLAW_CONFIG_PATH": configPath.path,
]) {
try OpenClawConfigFile.withTestingFileLock {
let loaded = OpenClawConfigFile.loadDict()
let update = loaded["update"] as? [String: Any]
#expect(update?["channel"] as? String == "beta")
#expect(!FileManager().fileExists(atPath: auditPath.path))
let persistedHealth = try String(contentsOf: configHealthPath, encoding: .utf8)
#expect(persistedHealth == legacyHealth)
}
}
}
@MainActor
@Test
func `load dict audits suspicious out-of-band clobbers`() async throws {
@@ -273,6 +325,7 @@ struct OpenClawConfigFileTests {
.appendingPathComponent("openclaw-state-\(UUID().uuidString)", isDirectory: true)
let configPath = stateDir.appendingPathComponent("openclaw.json")
let auditPath = stateDir.appendingPathComponent("logs/config-audit.jsonl")
let configHealthPath = stateDir.appendingPathComponent("logs/config-health.json")
defer { try? FileManager().removeItem(at: stateDir) }
@@ -293,6 +346,7 @@ struct OpenClawConfigFileTests {
],
])
_ = OpenClawConfigFile.loadDict()
#expect(!FileManager().fileExists(atPath: configHealthPath.path))
let clobbered = """
{
@@ -305,6 +359,7 @@ struct OpenClawConfigFileTests {
let loaded = OpenClawConfigFile.loadDict()
#expect((loaded["gateway"] as? [String: Any]) == nil)
#expect(!FileManager().fileExists(atPath: configHealthPath.path))
let rawAudit = try String(contentsOf: auditPath, encoding: .utf8)
let lines = rawAudit