diff --git a/ROADMAP.md b/ROADMAP.md index c1cb1527..7d263f09 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -7534,7 +7534,7 @@ Original filing (2026-04-18): the session emitted `SessionStart hook (completed) **Source.** Jobdori probe 2026-05-25 11:32 GMT+9 on main HEAD `c8b44878`. [SCOPE: ultraworkers/claw-code] -## Pinpoint #694. No pre-push `cargo build` gate — stale field refs (`retry_after`, `Team` variant, `config_load_error_kind`) broke main build undetected until CI +## Pinpoint #694. DONE — pre-push `cargo build` gate already exists — `.github/hooks/pre-push` runs `cargo build --manifest-path rust/Cargo.toml --workspace --locked` before every push. **Surface.** `rust/crates/api/src/providers/openai_compat.rs` referenced `ApiError::Api { retry_after: None }` (3 sites) after the field was removed from the enum. `rust/crates/commands/src/lib.rs:1475` emitted `SlashCommand::Team` after the variant was removed. `rusty-claude-cli/src/main.rs:2091` initialised `StatusContext` without `config_load_error_kind`. All three silently accumulated on `main` because (a) CI uses `cargo build` with `working-directory: rust` which was itself broken until `499125c9`, and (b) there is no local pre-push hook enforcing `cargo build --workspace`. Discovered 2026-05-25 during bulk rebase sweep. @@ -7559,7 +7559,7 @@ Original filing (2026-04-18): the session emitted `SessionStart hook (completed) 697. **`claw plugins remove ` silently returns `status:"ok"` with exit 0 when the named plugin does not exist — no `not_found` error, no non-zero exit, no indication the operation was a no-op; sibling: `claw agents ` returns `action:"help"` with exit 0 instead of a typed `unknown_subcommand` error** — dogfooded 2026-05-25 on `63a5a874`. Reproduction: `claw plugins remove nonexistent-plugin --output-format json "}` with exit 1 when the plugin is absent; (b) `agents ` must emit `{"kind":"agents","action":"error","error_kind":"unknown_subcommand","subcommand":"","supported":["list","help"]}` with exit 1 instead of falling back to help output with exit 0; (c) add regression tests proving both paths exit 1 with typed error envelopes. **Why this matters:** idempotent-but-silent remove is fine for infrastructure tools with explicit idempotency contracts; claw has no such contract, and `status:"ok"` for a name-miss means automation cannot audit whether a remove actually ran vs was a no-op. Source: Jobdori dogfood on `63a5a874`, 2026-05-25. -698. **Config deprecation warnings emit once per `ConfigLoader::load()` call, so surfaces that call `load()` multiple times in a single invocation emit duplicate `warning:` lines to stderr — `claw plugins list` and `claw mcp list` each print the same deprecation warning twice** — dogfooded 2026-05-25 on `c345ce6d`. Reproduction: `echo '{"enabledPlugins": {}}' > ~/.claw/settings.json && claw plugins list 2>&1 | grep warning` prints the same `field "enabledPlugins" is deprecated. Use "plugins.enabled" instead` line twice. Root cause: `config.rs:304` emits `eprintln!("warning: {warning}")` for every warning in every `loader.load()` call; surfaces like `plugins_command_payload_for` and `render_mcp_report_json_for` each trigger an independent `loader.load()` (one for runtime config, one inside the command handler), multiplying the stderr output. `skills list` emits only one warning because its command path calls `load()` once; `plugins` and `mcp` emit two. **Required fix shape:** (a) track already-emitted warning strings in a process-lifetime `std::sync::OnceLock>>` in `config.rs` and skip re-emitting duplicates within the same process run; or (b) collect all warnings at a single call site after all config loads are complete and emit once with dedup; or (c) change `load()` to return warnings alongside the result instead of eagerly printing them, letting call sites emit once. Option (a) is a minimal one-file fix. **Why this matters:** duplicate warnings make the CLI look buggy, cause CI log noise, and — when the deprecation warning fires on every invocation — are more likely to be `tail -f`'d away than acted on. A single clean warning per invocation is the standard. Source: Jobdori dogfood on `c345ce6d`, 2026-05-25. +698. **DONE — config warning dedup already implemented** — `emit_config_warning_once` at `config.rs:25` uses `OnceLock>>` to deduplicate warnings across multiple `load()` calls. JSON mode suppresses stderr warnings via `SUPPRESS_CONFIG_WARNINGS_STDERR`. 699. **`bootstrap-plan` and `dump-manifests` JSON/help probes fall through to prompt/auth instead of local command dispatch unless global flags are positioned just so; with normal subcommand-style argv they either hang behind the spinner or return `missing_credentials`, making local startup/manifest introspection non-local** — dogfooded 2026-05-25 on `11a6e081a` after the ROADMAP #458 envelope sweep. Reproduction with the freshly rebuilt debug binary: `./rust/target/debug/claw bootstrap-plan --output-format json 0)'` and the analogous dump-manifests/help probes must return within 1s without credentials. Source: gaebal-gajae dogfood for the 2026-05-25 07:30 Clawhip nudge.