Three dead-code warnings eliminated from cargo check:
1. KNOWN_TOP_LEVEL_KEYS / DEPRECATED_TOP_LEVEL_KEYS in config.rs
- Superseded by config_validate::TOP_LEVEL_FIELDS and DEPRECATED_FIELDS
- Were out of date (missing aliases, providerFallbacks, trustedRoots)
- Removed
2. read_git_recent_commits in prompt.rs
- Private function, never called anywhere in the codebase
- Removed
3. workspace_sessions_dir in session.rs
- Public API scaffolded for session isolation (#41)
- Genuinely useful for external consumers (clawhip enumerating sessions)
- Added 2 tests: deterministic path for same CWD, different path for different CWDs
- Annotated with #[allow(dead_code)] since it is external-facing API
cargo check --workspace: 0 warnings remaining
430 runtime tests passing, 0 failing
Closes the startup-friction gap filed in ROADMAP (dd97c49).
WorkerCreate required trusted_roots on every call with no config-level
default. Any batch script that omitted the field stalled all workers at
TrustRequired with no auto-recovery path.
Changes:
- RuntimeFeatureConfig: add trusted_roots: Vec<String> field
- ConfigLoader: wire parse_optional_trusted_roots() for 'trustedRoots' key
- RuntimeConfig / RuntimeFeatureConfig: expose trusted_roots() accessor
- config_validate: add trustedRoots to TOP_LEVEL_FIELDS schema (StringArray)
- Tests: parses_trusted_roots_from_settings + trusted_roots_default_is_empty_when_unset
Callers can now set trusted_roots in .claw/settings.json:
{ "trustedRoots": ["/tmp/worktrees"] }
WorkerRegistry::spawn_worker() callers should merge config.trusted_roots()
with any per-call overrides (wiring left for follow-up).
Two real schema gaps found via dogfood (cargo test -p runtime):
1. aliases and providerFallbacks not in TOP_LEVEL_FIELDS
- Both are valid config keys parsed by config.rs
- Validator was rejecting them as unknown keys
- 2 tests failing: parses_user_defined_model_aliases,
parses_provider_fallbacks_chain
2. Deprecated keys were being flagged as unknown before the deprecated
check ran (unknown-key check runs first in validate_object_keys)
- Added early-exit for deprecated keys in unknown-key loop
- Keeps deprecated→warning behavior for permissionMode/enabledPlugins
which still appear in valid legacy configs
3. Config integration tests had assertions on format strings that never
matched the actual validator output (path:3: vs path: ... (line N))
- Updated assertions to check for path + line + field name as
independent substrings instead of a format that was never produced
426 tests passing, 0 failing.
This adds crate-level and type-level Rustdoc to the runtime crate's core exported types so downstream crates and contributors can understand the session, prompt, permission, OAuth, usage, and tool I/O primitives without spelunking every implementation file.
Constraint: The docs pass needed to stay focused on public runtime types without changing behavior
Rejected: Add blanket docs to every public item in one sweep | larger churn than needed for a targeted docs pass
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: When exporting new runtime primitives from lib.rs, add a short Rustdoc summary in the defining module at the same time
Tested: cargo build --workspace; cargo test --workspace
Not-tested: rustdoc HTML rendering beyond doc-test coverage
Validate hook arrays in each config file before deep-merging so malformed entries fail with source-path context instead of surfacing later as a merged hook parse error.
Constraint: Runtime hook config currently supports only string command arrays
Rejected: Add hook-specific schema logic inside deep_merge_objects | keeps generic merge helper decoupled from config semantics
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep hook validation source-aware before generic config merges so file-specific errors remain diagnosable
Tested: cargo build --workspace; cargo test --workspace
Not-tested: live claw --help against a malformed external user config
The worker boot registry now exposes the requested lifecycle states, emits structured trust and prompt-delivery events, and recovers from shell or wrong-target prompt delivery by replaying the last prompt. Supporting fixes keep MCP remote config parsing backwards-compatible and make CLI argument parsing less dependent on ambient config and cwd state so the workspace stays green under full parallel test runs.
Constraint: Worker prompts must not be dispatched before a confirmed ready_for_prompt handshake
Constraint: Prompt misdelivery recovery must stay minimal and avoid new dependencies
Rejected: Keep prompt_accepted and blocked as public lifecycle states | user requested the narrower explicit state set
Rejected: Treat url-only MCP server configs as invalid | existing CLI/runtime tests still rely on that shorthand
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Preserve prompt_in_flight semantics when extending worker boot; misdelivery detection depends on it
Tested: cargo build --workspace; cargo test --workspace
Not-tested: Live tmux worker delivery against a real external coding agent pane
This threads typed hook settings through runtime config, adds a shell-based hook runner, and executes PreToolUse/PostToolUse around each tool call in the conversation loop. The CLI now rebuilds runtimes with settings-derived hook configuration so user-defined Claude hook commands actually run before and after tools.
Constraint: Hook behavior needed to match Claude-style settings.json hooks without broad plugin/MCP parity work in this change
Rejected: Delay hook loading to the tool executor layer | would miss denied tool calls and duplicate runtime policy plumbing
Confidence: medium
Scope-risk: moderate
Reversibility: clean
Directive: Keep hook execution in the runtime loop so permission decisions and tool results remain wrapped by the same conversation semantics
Tested: cargo test; cargo build --release
Not-tested: Real user hook scripts outside the test harness; broader plugin/skills parity
Add typed runtime-facing MCP and OAuth configuration models on top of the existing merged settings loader so later parity work can consume validated structures instead of ad hoc JSON traversal.
This keeps the first slice bounded to parsing, precedence, exports, and tests. While validating the slice under the repo's required clippy gate, I also fixed a handful of pre-existing clippy failures in runtime file operations so the requested verification command can pass for this commit.
Constraint: Must keep scope to parity-unblocking primitives, not full MCP or OAuth flow execution
Constraint: cargo clippy --all-targets is a required verification gate for this repo
Rejected: Add a new integrations crate first | too much boundary churn for the first landing slice
Rejected: Leave existing clippy failures untouched | would block the required verification command for this commit
Confidence: medium
Scope-risk: moderate
Reversibility: clean
Directive: Keep future MCP/OAuth additions layered on these typed config surfaces before introducing transport orchestration
Tested: cargo fmt --all; cargo test -p runtime; cargo clippy -p runtime --all-targets -- -D warnings
Not-tested: workspace-wide clippy/test beyond the runtime crate; live MCP or OAuth network flows