diff --git a/ROADMAP.md b/ROADMAP.md index a748325f..ee19ca54 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -2188,7 +2188,7 @@ ear], /color [scheme], /effort [low|medium|high], /fast, /summary, /tag [label], **Source.** Jobdori dogfood 2026-04-18 against `/tmp/cdK` on main HEAD `8db8e49` in response to Clawhip pinpoint nudge at `1494751832399024178`. A partial regression of ROADMAP #39 / #54 — the filter was applied to the primary slash-command listing and to REPL completions, but the `--help` Resume-safe one-liner was overlooked. New stubs added to `STUB_COMMANDS` since those filings keep propagating to this section. Sibling to #78 (`claw plugins` CLI route wired but never constructed): both are "surface advertises something that doesn't work at runtime" gaps in `--help` / parser coverage. Distinct from the truth-audit / discovery-overreach / reporting-surface clusters — this is a self-contradicting help surface, not a runtime-state or config-hygiene bug. -97. **`--allowedTools ""` and `--allowedTools ",,"` silently yield an empty allow-set that blocks every tool, with no error, no warning, and no trace of the active tool-restriction anywhere in `claw status` / `claw doctor` / `claw --output-format json` surfaces — compounded by `allowedTools` being a *rejected unknown key* in `.claw.json`, so there is no machine-readable way to inspect or recover what the current active allow-set actually is** — dogfooded 2026-04-18 on main HEAD `3ab920a` from `/tmp/cdL`. `--allowedTools "nonsense"` correctly returns a structured error naming every valid tool. `--allowedTools ""` silently produces `Some(BTreeSet::new())` and all subsequent tool lookups fail `contains()` because the set is empty. Neither `status` JSON nor `doctor` JSON exposes `allowed_tools`, so a claw that accidentally restricted itself to zero tools has no observable signal to recover from. +97. **DONE — `--allowedTools ""` and `--allowedTools ",,"` silently yield an empty allow-set that blocks every tool, with no error, no warning, and no trace of the active tool-restriction anywhere in `claw status` / `claw doctor` / `claw --output-format json` surfaces — compounded by `allowedTools` being a *rejected unknown key* in `.claw.json`, so there is no machine-readable way to inspect or recover what the current active allow-set actually is** — dogfooded 2026-04-18 on main HEAD `3ab920a` from `/tmp/cdL`. `--allowedTools "nonsense"` correctly returns a structured error naming every valid tool. `--allowedTools ""` silently produces `Some(BTreeSet::new())` and all subsequent tool lookups fail `contains()` because the set is empty. Neither `status` JSON nor `doctor` JSON exposes `allowed_tools`, so a claw that accidentally restricted itself to zero tools has no observable signal to recover from. **Concrete repro.** ``` diff --git a/rust/crates/rusty-claude-cli/src/main.rs b/rust/crates/rusty-claude-cli/src/main.rs index 6a3640a9..cc2021c1 100644 --- a/rust/crates/rusty-claude-cli/src/main.rs +++ b/rust/crates/rusty-claude-cli/src/main.rs @@ -3131,6 +3131,17 @@ fn parse_system_prompt_args( "missing_flag_value: missing value for --cwd.\nUsage: --cwd ".to_string() })?; cwd = PathBuf::from(value); + // #99: validate --cwd path exists and is a directory + if !cwd.exists() { + return Err(format!( + "invalid_cwd: path '{value}' does not exist.\nUsage: claw system-prompt --cwd " + )); + } + if !cwd.is_dir() { + return Err(format!( + "invalid_cwd: path '{value}' is not a directory.\nUsage: claw system-prompt --cwd " + )); + } index += 2; } "--date" => { @@ -3138,9 +3149,22 @@ fn parse_system_prompt_args( "missing_flag_value: missing value for --date.\nUsage: --date " .to_string() })?; + // #99: validate --date is a plausible date string (no newlines, reasonable length) + if value.contains('\n') || value.contains('\r') { + return Err(format!( + "invalid_flag_value: --date value contains invalid characters.\nUsage: --date " + )); + } + if value.len() > 20 { + return Err(format!( + "invalid_flag_value: --date value is too long ({len} chars, expected YYYY-MM-DD).\nUsage: --date ", + len = value.len() + )); + } date.clone_from(value); index += 2; } + other => { // #152: hint `--output-format json` when user types `--json`. // #790: use unknown_option: prefix + \n hint so classify_error_kind returns