Skip to content

feat: claw parity batch — memory/compact/rules/pricing/hooks/perms#3019

Open
MoSaleh-AKB wants to merge 1 commit into
ultraworkers:mainfrom
MoSaleh-AKB:feat/claw-parity-batch-mosaleh-2026-05-08
Open

feat: claw parity batch — memory/compact/rules/pricing/hooks/perms#3019
MoSaleh-AKB wants to merge 1 commit into
ultraworkers:mainfrom
MoSaleh-AKB:feat/claw-parity-batch-mosaleh-2026-05-08

Conversation

@MoSaleh-AKB
Copy link
Copy Markdown

@MoSaleh-AKB MoSaleh-AKB commented May 11, 2026

Summary

9 distinct parity improvements committed together as a single batch. 14 new tests added; full workspace runs 527 of 528 (the 1 failure — hooks::tests::malformed_nonempty_hook_output_reports_explicit_diagnostic_with_previews — is pre-existing on main).

Area Change
/compact Now re-discovers CLAUDE.md from disk after compacting (was using stale cached prompt) — rusty-claude-cli/src/main.rs
Auto-memory Reads ~/.claude/projects/<encoded-cwd>/memory/ so memory files written by Claude Code or other tools auto-attach — runtime/src/prompt.rs
Pricing Tables for Llama / Qwen / Grok / GPT / local Ollama (zero-cost via colon-tag heuristic). Avoids silent Sonnet-tier default — runtime/src/usage.rs
Bash validation cmd1 && rm -rf / no longer bypasses; quoted strings + backslash escapes respected; new split_bash_pipeline()runtime/src/bash_validation.rs
Hook events Expanded 3 → 10 (Stop, StopFailure, UserPromptSubmit, SessionStart, SessionEnd, PostToolBatch, PermissionRequest, InstructionsLoaded) at config layer. Firing for new events is a follow-up. 3-arg RuntimeHookConfig::new() preserved for backward compat — runtime/src/hooks.rs, runtime/src/config.rs
Path-scoped rules .claude/rules/*.md and .claw/rules/*.md discovered and injected into system prompt — runtime/src/prompt.rs
Permission wildcards Trailing-* glob now matches: Bash(npm run *), Bash(git *), WebFetch(https://example.com/*). Existing :* and Any forms preserved — runtime/src/permissions.rs
Provider routing xai/<model> prefix routes to XAI lane (lets OPENAI_BASE_URL + XAI_BASE_URL coexist in one process) — api/src/providers/mod.rs

Test plan

  • `cargo build -p rusty-claude-cli` — green
  • `cargo test --workspace --lib` — 527 pass / 1 pre-existing failure
  • `claw doctor` reports config + memory file discovery
  • `claw --compact prompt "..."` round-trips against local Ollama
  • Verify on Linux / sandboxed environment
  • Verify against Anthropic + Groq cloud providers

Notes for reviewers

  • Most changes are additive — extending enums (HookEvent), adding fields (RuntimeHookConfig), adding accessors, adding match arms in matchers. Behavior change of existing inputs is minimised.
  • One semantic change worth flagging: `validate_command()` now splits compound commands. A previously-accepted `ls && rm -rf /` will now be blocked under ReadOnly mode. That's the intended fix.
  • One small behavior change: post-`/compact` system prompt is re-read from disk; if your tests cache CLAUDE.md content between turns, that's why.

Happy to split this into smaller PRs if preferred — kept as one batch to ship the parity sweep coherently.

🤖 Generated with Claude Code

9 of 17 plan tasks completed in a single session. 14 new tests added; full
workspace runs 527 of 528 (the 1 failure is pre-existing on upstream main:
hooks::tests::malformed_nonempty_hook_output_reports_explicit_diagnostic_with_previews).

T1.2  /compact + post-compact CLAUDE.md re-attachment (main.rs:5302)
T1.3  Auto-memory discovery — reads ~/.claude/projects/<encoded-cwd>/memory/
      so memory written by Claude Code flows into claw's system prompt
      (prompt.rs: discover_instruction_files + memory_dir_for_cwd)
T1.4  Pricing tables for Llama, Qwen, Grok, GPT, local Ollama (zero-cost
      heuristic via colon-tag detection); avoids the silent $75/M sonnet
      fallback for non-Anthropic models (usage.rs: pricing_for_model)
T1.5  Compound bash pipeline splitting + 9 tests. Closes the
      `cmd1 && rm -rf /` bypass; quoted strings/backslash-escapes respected
      (bash_validation.rs: split_bash_pipeline, validate_command rewrite)
T2.1  Hook events expanded 3 → 10. Stop, StopFailure, UserPromptSubmit,
      SessionStart, SessionEnd, PostToolBatch, PermissionRequest,
      InstructionsLoaded now configurable in settings.json. Firing for new
      events deferred to a follow-up. Backward-compatible: 3-arg
      RuntimeHookConfig::new() preserved (hooks.rs, config.rs).
T2.2  SKILL.md discovery confirmed already-implemented (no-op).
T2.3  AGENT.md discovery confirmed already-implemented; subagent context
      isolation deferred (no-op).
T2.4  Path-scoped rules: .claude/rules/*.md and .claw/rules/*.md discovered
      and injected. Frontmatter `paths:` glob filtering deferred
      (prompt.rs: discover_instruction_files extension).
T2.5  Permission rule wildcard suffix: Bash(npm run *), Bash(git *),
      WebFetch(https://example.com/*) now match correctly via
      PermissionRuleMatcher::Prefix. Existing colon-star and Any forms
      preserved (permissions.rs: parse_rule_matcher).

Plus an earlier session patch routing `xai/<model>` prefix through the XAI
provider lane (api/providers/mod.rs: metadata_for_model).

Plan reference: ~/.claude/plans/model-later-be-able-snug-blanket.md
Deferred: T1.1 (bash branch merge), T3.x (worktrees, /batch, Monitor,
scheduler), T4.x (ACP daemon, VS Code, JetBrains extensions).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@MoSaleh-AKB MoSaleh-AKB force-pushed the feat/claw-parity-batch-mosaleh-2026-05-08 branch from dc9b132 to cad236e Compare May 11, 2026 01:02
@MoSaleh-AKB
Copy link
Copy Markdown
Author

Closing — keeping these changes on my fork (MoSaleh-AKB/claw-code) as a personal branch. Not upstreaming for now.

@MoSaleh-AKB
Copy link
Copy Markdown
Author

Reopening to keep this open as a tracking PR — keeping the work parked here for later upstream discussion, not actively pushing for merge.

@MoSaleh-AKB MoSaleh-AKB reopened this May 11, 2026
Copy link
Copy Markdown

@yuanri007 yuanri007 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

Diff: +530 / −16 across 7 files

Overview

A 9-change parity batch: post-/compact prompt rediscovery, auto-memory ingestion, expanded pricing tables, top-level bash-pipeline splitting in the validator, 7 new hook events at config layer, .claude/rules & .claw/rules ingestion, trailing-* permission glob, xai/ provider prefix, and a CLAW_NO_TOOLS env switch. Mostly additive; one intentional semantic tightening (compound-command validation).

Strengths

  • Backward-compat care. RuntimeHookConfig::new() kept at 3 args via ..Default::default(); permission :* form preserved alongside the new general *; pre-T1.5 validate_command body lifted intact into validate_command_segment.
  • Security win. The ls && rm -rf / bypass is a real hole; the fix is targeted and the deferred-Warn / first-Block precedence is the right policy.
  • Test coverage for the new splitter is reasonable (single quotes, double quotes, escape, &&/||/;/|), plus a regression test against the original bypass.
  • Pricing test asserts no-silent-defaultpricing_unknown_returns_none is exactly the right guard.

Issues — by severity

Bugs

  1. memory_dir_for_cwd is broken on Windows. prompt.rs reads HOME (not set by default on Windows) and replaces only / (Windows paths use \). Result: auto-memory silently no-ops on Windows, and even if HOME is set, the encoded path won't match what Claude Code wrote. Use dirs::home_dir() (or home::home_dir()) and normalize the path separator — or canonicalize to / first. The whole point of T1.3 is CC↔claw memory sharing, so this needs to work cross-platform.

  2. Backtick / $() command substitutions evade the splitter. bash_validation.rs tracks in_backtick so separators inside backticks aren't split — good — but the contents of `…` and $(…) are never validated as standalone segments. echo $(rm -rf /tmp/x) produces one segment and only the outer echo is path-checked. The author's test comment acknowledges check_destructive may still catch rm -rf / via substring, but anything not in that paranoid list (e.g. curl …|sh, dd of=/dev/sda) gets through. At minimum, document this; ideally recurse into $(…) content.

  3. Speculative GPT-5 / O-series pricing. usage.rs commits $10/$30 for gpt-5 and $15/$60 for o1/o3/o4. These are best-effort guesses dressed as fact in a constant table. If the published tariff is lower, users see inflated cost estimates and lose trust; if higher, they under-budget. Either source these numbers (link in a comment), gate them behind a "best-effort" flag, or return None and surface "pricing unknown" upstream.

Style / minor

  1. canonical.contains(':') is too loose for Ollama detection. Any future cloud model with a : in the identifier (some providers already use model:version) silently goes to zero-cost. Tighten with a regex like ^[^/]+:[^/]+$ after stripping a routing prefix, or require it not to match a known cloud family.

  2. Rules loading walks every ancestor on every prompt build. read_dir runs per ancestor, twice (.claude/rules and .claw/rules). For deep trees in monorepos this is noisy. Worth a quick benchmark or at least a cache by cwd.

  3. Trailing-* matcher overlap with bare *. strip_suffix('*') on input "*" would yield prefix "". The earlier unescaped == "*" branch catches it first, so we're fine, but the precedence is load-bearing — worth a comment, or test the empty-prefix case explicitly.

  4. PR description claims "Avoids silent Sonnet-tier default", but the pre-change pricing_for_model only matched the three Anthropic families and returned None otherwise. If a Sonnet default exists, it's in a caller (UsageCostEstimate::default() perhaps). The change is good either way, but the description is misleading.

  5. Batch size. Description openly offers to split. Worth doing — the bash-validator fix is security-relevant and deserves to land on its own diff for cherry-pick / revert clarity; pricing + provider routing + memory discovery are all independent.

Risks

  • split_bash_pipeline policy change in ReadOnly mode could break existing user scripts that chain a safe inspection with a write step (git status && git commit …). The author flags this as intentional; just make sure release notes call it out, because the failure mode is "command silently blocked" not "loud error."
  • CLAW_NO_TOOLS is a quiet new env switch. Worth documenting in claw doctor / --help.

Recommendation

Request changes. Fix the Windows memory-path bug (#1) before merge — it negates one of the PR's headline parity features. Either land or remove the speculative GPT-5/O-series pricing (#3). Everything else can ship as-is or as follow-ups, but consider splitting (#8) so the bash-validator security fix has its own revertable commit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants