fix(#736): boot_preflight doctor details[] null-value entries: add double-space separator to Required binary, Last failed boot, MCP/Plugin eligible format strings

This commit is contained in:
YeonGyu-Kim
2026-05-26 14:33:18 +09:00
parent b3242e8c04
commit ad982d20c2
2 changed files with 19 additions and 6 deletions

View File

@@ -7637,3 +7637,5 @@ Original filing (2026-04-18): the session emitted `SessionStart hook (completed)
734. **`agents show <name>` and `plugins show <name>` error envelopes had no `message` field when the target was not found — `skills show` had `"message": "skill 'X' not found"` but the other two omitted it, leaving callers with only `error_kind` and `requested` and no human-readable explanation in the same field shape** — dogfooded 2026-05-26 on `cc86f54d`. Added `"message": "agent 'X' not found"` to the `agent_not_found` branch in `commands/src/lib.rs` and `"message": "plugin 'X' not found"` to the `plugin_not_found` branch in `rusty-claude-cli/src/main.rs`; both now match the `skills show` shape. Source: Jobdori dogfood on `cc86f54d`, 2026-05-26.
735. **`claw /compact --output-format json` (and other interactive-only slash commands invoked outside a session) emitted `error_kind:"unknown"` instead of `error_kind:"interactive_only"``classify_error_kind` matched `"is a slash command"` and `"interactive_only:"` prefix but missed the `"slash command /X is interactive-only"` sentence pattern emitted by the interactive-only guard; automation branching on `error_kind` got `"unknown"` and couldn't distinguish "you called an interactive command outside a session" from a genuine unknown failure** — dogfooded 2026-05-26 on `d4494a8a`. Added `message.starts_with("slash command") && message.contains("interactive-only")` branch to `classify_error_kind` alongside the existing two matchers. Source: Jobdori dogfood on `d4494a8a`, 2026-05-26.
736. **`claw doctor --output-format json` `boot_preflight` check `details[]` had `value: null` for `Required binary`, `Last failed boot`, `MCP eligible`, and `Plugin eligible` entries — all four used format strings with no double-space separator, so the prose-splitter that builds `{key, value}` objects (introduced in #701) could not split key from value and emitted the entire string as `key` with `value: null`** — dogfooded 2026-05-26 on `b3242e8c`. Fix: insert the two-space separator between the label and its value in each format string: `"Required binary {} available={}"``key="Required binary claw"` / `value="available=true"`; `"Last failed boot {}"``key="Last failed boot"` / `value="<none>"`; MCP/Plugin eligible compound values use `" · "` intra-value separator since `splitn(2, " ")` splits only on the first double-space run. Source: Jobdori dogfood on `b3242e8c`, 2026-05-26.

View File

@@ -2760,16 +2760,26 @@ fn check_boot_preflight_health(context: &StatusContext) -> DiagnosticCheck {
.map_or("unknown".to_string(), |v| v.to_string())
),
format!("Trusted roots {}", preflight.trusted_roots_count),
// #736: keep compound values readable but use " · " as intra-value separator
// so the two-space prose splitter yields key="MCP eligible" value="true · servers 0"
format!(
"MCP eligible {} · servers {}",
preflight.mcp_startup_eligible, preflight.mcp_servers_configured
"MCP eligible {}",
format!(
"{} · servers {}",
preflight.mcp_startup_eligible, preflight.mcp_servers_configured
)
),
format!(
"Plugin eligible {} · configured {}",
preflight.plugin_startup_eligible, preflight.plugins_configured
"Plugin eligible {}",
format!(
"{} · configured {}",
preflight.plugin_startup_eligible, preflight.plugins_configured
)
),
format!(
"Last failed boot {}",
// #736: use two-space separator so the detail_entries prose splitter
// can extract key="Last failed boot" value="<none>|<reason>"
"Last failed boot {}",
preflight
.last_failed_boot_reason
.as_deref()
@@ -2778,7 +2788,8 @@ fn check_boot_preflight_health(context: &StatusContext) -> DiagnosticCheck {
];
details.extend(preflight.required_binaries.iter().map(|binary| {
format!(
"Required binary {} available={}",
// #736: two-space separator → key="Required binary <name>" value="available=true|false"
"Required binary {} available={}",
binary.name, binary.available
)
}));