Skip to content

Commit 8339371

Browse files
Merge pull request #476 from ScriptedAlchemy/codex/doctor-response-handle
fix(doctor): use compact daemon health snapshot
2 parents 5c3ffd4 + 7baa3d8 commit 8339371

2 files changed

Lines changed: 58 additions & 14 deletions

File tree

src/doctor.rs

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -251,15 +251,35 @@ async fn daemon_project_status(project_path: &Path) -> crate::errors::Result<ser
251251
)?;
252252
let result = crate::daemon::call_default_tool(
253253
&handshake,
254-
"tracedecay_status",
254+
"tracedecay_runtime",
255255
serde_json::json!({ "format": "json" }),
256256
)
257257
.await?;
258-
daemon_tool_json(&result)
258+
daemon_runtime_status(&result)
259259
}
260260

261-
fn daemon_tool_json(result: &serde_json::Value) -> crate::errors::Result<serde_json::Value> {
262-
crate::daemon::tool_json_payload(result, "tracedecay_status")
261+
fn daemon_runtime_status(result: &serde_json::Value) -> crate::errors::Result<serde_json::Value> {
262+
let runtime = crate::daemon::tool_json_payload(result, "tracedecay_runtime")?;
263+
let mut storage =
264+
runtime
265+
.get("database")
266+
.cloned()
267+
.ok_or_else(|| crate::errors::TraceDecayError::Config {
268+
message: "daemon runtime response omitted database telemetry".to_string(),
269+
})?;
270+
let storage =
271+
storage
272+
.as_object_mut()
273+
.ok_or_else(|| crate::errors::TraceDecayError::Config {
274+
message: "daemon runtime database telemetry was not an object".to_string(),
275+
})?;
276+
if let Some(pid) = runtime.pointer("/process/pid").cloned() {
277+
storage.insert("daemon_owner_pid".to_string(), pid);
278+
}
279+
if let Some(version) = runtime.get("tracedecay_version").cloned() {
280+
storage.insert("daemon_version".to_string(), version);
281+
}
282+
Ok(serde_json::json!({ "storage_health": storage }))
263283
}
264284

265285
fn check_database(dc: &mut DoctorCounters, status: &serde_json::Value) -> bool {
@@ -423,12 +443,23 @@ fn check_stale_stores(dc: &mut DoctorCounters, status: Option<&serde_json::Value
423443
.get("daemon_owner_pid")
424444
.and_then(serde_json::Value::as_u64)
425445
.map_or_else(|| "unknown".to_string(), |pid| pid.to_string());
426-
let generation = storage
446+
let identity = storage
427447
.get("daemon_generation")
428448
.and_then(serde_json::Value::as_str)
429-
.unwrap_or("unknown");
449+
.map_or_else(
450+
|| {
451+
storage
452+
.get("daemon_version")
453+
.and_then(serde_json::Value::as_str)
454+
.map_or_else(
455+
|| "identity=unknown".to_string(),
456+
|version| format!("version={version}"),
457+
)
458+
},
459+
|generation| format!("generation={generation}"),
460+
);
430461
dc.pass(&format!(
431-
"Registry/database inspection delegated to daemon owner pid={owner}, generation={generation}"
462+
"Registry/database inspection delegated to daemon owner pid={owner}, {identity}"
432463
));
433464
} else {
434465
dc.warn("Registry diagnostics unavailable because the daemon owner did not answer; doctor did not open the global DB");

src/doctor/tests.rs

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -842,13 +842,13 @@ fn plain_orphan_still_warns_with_update_remediation() {
842842
}
843843

844844
#[test]
845-
fn daemon_status_parser_extracts_storage_health() {
846-
let parsed = super::daemon_tool_json(&serde_json::json!({
845+
fn daemon_runtime_parser_extracts_storage_health_and_owner() {
846+
let parsed = super::daemon_runtime_status(&serde_json::json!({
847847
"content": [
848848
{"type": "text", "text": "daemon notice"},
849849
{
850850
"type": "text",
851-
"text": r#"{"storage_health":{"quick_check_ok":true,"daemon_generation":"run-7"}}"#
851+
"text": r#"{"tracedecay_version":"0.0.66","process":{"pid":1234},"database":{"canonical_db_path":"/tmp/project.db","quick_check_ok":true,"dirty_marker":{"exists":false}}}"#
852852
}
853853
]
854854
}))
@@ -859,13 +859,26 @@ fn daemon_status_parser_extracts_storage_health() {
859859
Some(&serde_json::Value::Bool(true))
860860
);
861861
assert_eq!(
862-
parsed.pointer("/storage_health/daemon_generation"),
863-
Some(&serde_json::Value::String("run-7".to_string()))
862+
parsed.pointer("/storage_health/daemon_owner_pid"),
863+
Some(&serde_json::json!(1234))
864+
);
865+
assert_eq!(
866+
parsed.pointer("/storage_health/daemon_version"),
867+
Some(&serde_json::json!("0.0.66"))
864868
);
865869
}
866870

867871
#[test]
868-
fn daemon_status_parser_rejects_missing_json_payload() {
869-
let error = super::daemon_tool_json(&serde_json::json!({ "content": [] })).unwrap_err();
872+
fn daemon_runtime_parser_rejects_missing_json_payload() {
873+
let error = super::daemon_runtime_status(&serde_json::json!({ "content": [] })).unwrap_err();
870874
assert!(error.to_string().contains("returned no JSON payload"));
871875
}
876+
877+
#[test]
878+
fn daemon_runtime_parser_rejects_missing_database_telemetry() {
879+
let error = super::daemon_runtime_status(&serde_json::json!({
880+
"content": [{"type": "text", "text": r#"{"process":{"pid":1234}}"#}]
881+
}))
882+
.unwrap_err();
883+
assert!(error.to_string().contains("omitted database telemetry"));
884+
}

0 commit comments

Comments
 (0)