Skip to content

Comments

Data Safety Rules + Extensible Rule System (PR #131 Part 2)#157

Open
ahundt wants to merge 225 commits intortk-ai:masterfrom
ahundt:feat/data-safety-rules-v2
Open

Data Safety Rules + Extensible Rule System (PR #131 Part 2)#157
ahundt wants to merge 225 commits intortk-ai:masterfrom
ahundt:feat/data-safety-rules-v2

Conversation

@ahundt
Copy link

@ahundt ahundt commented Feb 17, 2026

PR 131 Part 2: Data Safety Rules + Extensible Rule System

Branch: feat/data-safety-rules-v2 | Base: master (stacks on Part 1)
Tests: 673 pass | Closes: #115
Split from: PR #131
New deps: trash = "5", serde_yaml = "0.9"
PR: #157


Context

Addresses item 2 from FlorianBruniaux's split request:

Data safety rules (rm->trash, git reset --hard->stash) + rtk.*.md files -- this adds the trash and which deps

Depends on PR 1 for the hook engine (safety.rs integrates into hook.rs and exec.rs). Parallel to PR 3 (Gemini) -- zero file overlap.


Merge Sequence

After PR 1 merges: retarget feat/data-safety-rules-v2 -> master, then merge. Can merge before or after PR 3.


Summary

11 safety rules intercept destructive commands and make them recoverable.

Impact: Prevents ~20-50K token costs per data loss incident (investigate damage → restore/rewrite → regenerate → debug differences).

Rules

Pattern Action Rewrite
rm trash Move to OS trash instead of permanent delete
git reset --hard rewrite Stash first, then reset
git checkout . / git checkout -- rewrite Stash first, then checkout
git clean -f/-fd/-df rewrite Stash untracked first, then clean
git stash drop rewrite git stash pop (recoverable)
cat / head / sed block Suggest Read/Edit tools instead

Conditional rules (git reset --hard, git checkout) use when: has_unstaged_changes -- only fire when uncommitted changes exist.

Opt-out: RTK_SAFE_COMMANDS=0 disables safety rules. RTK_BLOCK_TOKEN_WASTE=0 allows cat/head/sed.

Extensible rtk.*.md rule files

Rules are markdown with YAML frontmatter. 11 built-in rules compile into the binary via include_str!(). Users override or extend by placing files in .rtk/, .claude/, .gemini/, or ~/.config/rtk/:

---
name: rm-to-trash
patterns: [rm]
action: trash
redirect: "trash {args}"
env_var: RTK_SAFE_COMMANDS
---
Safety: Moving to trash instead of permanent deletion.

Priority: CLI paths > project-local dirs > global dirs > built-in defaults. Same-name rules override by priority.

User custom rule example -- ~/.config/rtk/rtk.safety.chmod-777.md:

---
name: chmod-777
patterns: ["chmod -R 777", "chmod 777"]
action: warn
when: "git rev-parse --is-inside-work-tree 2>/dev/null"
env_var: RTK_SAFE_COMMANDS
---
Warning: chmod 777 grants full access. Consider chmod 755 or 644 instead.

Config system expansion

src/config.rs (125 lines) replaced by src/config/ module (3 files, 2419 lines):

  • mod.rs -- Config struct with precedence chain, CRUD operations
  • rules.rs -- Rule loading, regex matching, try_remap() alias expansion
  • discovery.rs -- Walk-up ancestor directory discovery

New commands: rtk config list/get/set/unset/create/export-rules


Changes

24 files changed (+3535, -148)

New: src/cmd/safety.rs (538 lines, 30 tests), src/cmd/trash_cmd.rs (76 lines, 4 tests), src/config/{mod,rules,discovery}.rs, 11 rule files in src/rules/

Modified: src/cmd/mod.rs (+safety, +trash_cmd), src/cmd/hook.rs (restore safety integration), src/cmd/exec.rs (restore safety dispatch), src/main.rs (+Config commands), Cargo.toml (+trash, +serde_yaml)

Deleted: src/config.rs (replaced by src/config/ module)


Review Guide

Focus areas:

  1. src/cmd/safety.rs + src/rules/*.md -- Rule matching and rewriting
  2. src/config/rules.rs + discovery.rs -- Rule loading, precedence, override semantics
  3. src/cmd/hook.rs + exec.rs -- Safety integration points

Not Included (Future)

  • Extended safety rules: sudo rm, docker rm, kubectl delete with confirmations
  • Analytics on which rules fire most often
  • Additional built-in predicates beyond always and has_unstaged_changes

Test Plan

  • cargo test -- 673 tests pass (safety:30, trash:4, rules:15, discovery:8, +3 restored hook tests)
  • echo '{"tool_input":{"command":"rm file"}}' | cargo run -- hook claude -- rm rewritten
  • echo '{"tool_input":{"command":"cat file.txt"}}' | cargo run -- hook claude -- cat blocked (exit 2)
  • cargo run -- hook check "git clean -fd" -- stash prepended
  • RTK_SAFE_COMMANDS=0 cargo run -- hook check "rm file" -- opt-out works
  • cargo run -- hook check "catalog show" -- NOT blocked (catalog != cat)
  • cargo run -- config list -- CRUD works

Related PRs (Split from PR #131)

Part PR Description
1 #156 Hook Engine + Chained Commands
2 #157 Data Safety Rules (this PR)
3 #158 Gemini CLI Support

Merge order: Part 1 first → retarget Parts 2 & 3 to master → merge in any order

pszymkowiak and others added 30 commits January 28, 2026 22:38
feat: add pnpm support + fix git argument parsing for modern stacks
Add Vitest test runner support with 99.6% token reduction
adding benchmark script for local performance monitoring in dev
Add installation guide for AI coding assistants
Add utils.rs with common utilities used across modern JavaScript
tooling commands:
- truncate(): Smart string truncation with ellipsis
- strip_ansi(): Remove ANSI escape codes from output
- execute_command(): Centralized command execution with error handling

These utilities enable consistent output formatting and filtering
across multiple command modules.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Add comprehensive support for modern JS/TS development stack:

Commands added:
- rtk lint: ESLint/Biome output with grouped rule violations (84% reduction)
- rtk tsc: TypeScript compiler errors grouped by file (83% reduction)
- rtk next: Next.js build output with route/bundle metrics (87% reduction)
- rtk prettier: Format checker showing only files needing changes (70% reduction)
- rtk playwright: E2E test results showing failures only (94% reduction)
- rtk prisma: Prisma CLI without ASCII art (88% reduction)

Features:
- Auto-detects package managers (pnpm/yarn/npm/npx)
- Preserves exit codes for CI/CD compatibility
- Groups errors by file and error code for quick navigation
- Strips verbose output while retaining critical information

Total: 6 new commands, ~2,000 LOC

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Document the 6 new commands and shared utils module in CHANGELOG.md.
Focuses on token reduction metrics and CI/CD compatibility.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Add benchmarks for the 6 new commands in scripts/benchmark.sh:
- tsc: TypeScript compiler error grouping
- prettier: Format checker with file filtering
- lint: ESLint/Biome grouped violations
- next: Next.js build metrics extraction
- playwright: E2E test failure filtering
- prisma: Prisma CLI without ASCII art

All benchmarks are conditional (skip if tools not available or
not applicable to current project). Tests only run on projects
with package.json and relevant configuration files.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implements heuristic calculation of monthly quota savings percentage
with support for Pro, Max 5x, and Max 20x subscription tiers.

Features:
- --quota flag displays monthly quota analysis
- --tier <pro|5x|20x> selects subscription tier (default: 20x)
- Heuristic based on ~44K tokens/5h Pro baseline
- Estimates: Pro=6M, 5x=30M, 20x=120M tokens/month
- Clear disclaimer about rolling 5-hour windows vs monthly caps

Example output for Max 20x:
  Subscription tier:        Max 20x ($200/mo)
  Estimated monthly quota:  120.0M
  Tokens saved (lifetime):  356.7K
  Quota preserved:          0.3%

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
feat: add modern JavaScript tooling support (lint, tsc, next, prettier, playwright, prisma)
Add rtk gh command for GitHub CLI operations with intelligent
output filtering:

Commands:
- rtk gh pr list/view/checks/status: PR management (53-87% reduction)
- rtk gh issue list/view: Issue tracking (26% reduction)
- rtk gh run list/view: Workflow monitoring (82% reduction)
- rtk gh repo view: Repository info (29% reduction)

Features:
- Level 1 optimizations (default): Remove header counts, @ prefix,
  compact mergeable status (+12-18% savings, zero UX loss)
- Level 2 optimizations (--ultra-compact flag): ASCII icons,
  inline checks format (+22% total savings on PR view)
- GraphQL response parsing and grouping
- Preserves all critical information for code review

Token Savings (validated on production repo):
- rtk gh pr view: 87% (24.7K → 3.2K chars)
- rtk gh pr checks: 79% (8.9K → 1.8K chars)
- rtk gh run list: 82% (10.2K → 1.8K chars)

Global --ultra-compact flag added to enable Level 2 optimizations
across all GitHub commands.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add utils.rs as Key Architectural Component
- Expand Module Responsibilities table (7→17 modules)
- Document PR rtk-ai#9 in Fork-Specific Features section
- Include token reduction metrics for all new commands
Change dtolnay/rust-action to dtolnay/rust-toolchain (correct name)
feat: add GitHub CLI integration (depends on rtk-ai#9)
feat: add quota analysis with multi-tier support
## Release automation
- Add release-please workflow for automatic semantic versioning
- Configure release.yml to only trigger on tags (avoid double-release)

## Benchmark automation
- Extend benchmark.yml with README auto-update
- Add permissions for contents and pull-requests writes
- Auto-create PR with updated metrics via peter-evans/create-pull-request
- Add scripts/update-readme-metrics.sh for CI integration

## Verification
- ✅ Workflows ready for CI/CD pipeline
- ✅ No breaking changes to existing functionality

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
feat: CI/CD automation (versioning, benchmarks, README auto-update)
…s--master--components--rtk

chore(master): release 0.3.0
## Fixes

### Lint crash handling
- Add graceful error handling for linter crashes (SIGABRT, OOM)
- Display warning message when process terminates abnormally
- Show first 5 lines of stderr for debugging context

### Grep command
- Add --type/-t flag for file type filtering (e.g., --type ts, --type py)
- Passes --type argument to ripgrep for efficient filtering

### Find command
- Add --type/-t flag for file/directory filtering
- Default: "f" (files only)
- Options: "f" (file), "d" (directory)

## Testing
- ✅ cargo check passes
- ✅ cargo build --release succeeds
- ✅ rtk grep --help shows --file-type flag
- ✅ rtk find --help shows --file-type flag with default

## Breaking Changes
None - all changes are backwards compatible additions

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…d-bugs

fix: improve command robustness and flag support
…s--master--components--rtk

chore(master): release 0.3.1
## Overview
Complete architectural documentation (1133 lines) covering all 30 modules,
design patterns, and extensibility guidelines.

## Critical Fixes (🔴)
- ✅ Module count: 30 documented (not 27) - added deps, env_cmd, find_cmd, local_llm, summary, wget_cmd
- ✅ Language: Fully translated to English for consistency with README.md
- ✅ Shared Infrastructure: New section documenting utils.rs and package manager detection
- ✅ Exit codes: Correct documentation (git.rs preserves exit codes for CI/CD)
- ✅ Database: Correct path ~/.local/share/rtk/history.db (not tracking.db)

## Important Additions (🟡)
- ✅ Global Flags Architecture: Verbosity (-v/-vv/-vvv) and ultra-compact (-u)
- ✅ Complete patterns: Package manager detection, exit code preservation, lazy static regex
- ✅ Config system: TOML format documented
- ✅ Performance: Verified binary size (4.1 MB) and estimated overhead
- ✅ Filter levels: Before/after examples with Rust code

## Bonus Improvements (🟢)
- ✅ Table of Contents (12 sections)
- ✅ Extensibility Guide (7-step process for adding commands)
- ✅ Architecture Decision Records (Why Rust? Why SQLite?)
- ✅ Glossary (7 technical terms)
- ✅ Module Development Pattern (template + 3 common patterns)
- ✅ 15+ ASCII diagrams for visual clarity

## Stats
- Lines: 1133 (+118% vs original 520)
- Sections: 12 main + subsections
- Code examples: 10+ Rust/bash snippets
- Accuracy: 100% verified against source code

Production-ready for new contributors, experienced developers, and LLM teams.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
FlorianBruniaux and others added 12 commits February 15, 2026 18:49
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…n-go-complete

docs: comprehensive v0.15.1 documentation for Python/Go support
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Add project-specific Claude Code configuration for RTK development:

- 5 agents: code-reviewer, debugger, rtk-testing-specialist, rust-rtk, technical-writer
- 2 commands: /diagnose (env checks), /test-routing (dry-run validation)
- 1 hook: pre-commit cargo fmt + clippy + test gate
- 1 rule: CLI testing methodology (snapshot, token accuracy, cross-platform)
- 3 skills: performance optimization, security audit, release workflow

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix CI validation: README referenced 0.18.0, Cargo.toml is at 0.18.1.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Generates structured repo recap with:
- Open PRs categorized (ours/reviewable/problematic)
- Open issues with priority classification
- Recent releases
- Executive summary with risks and quick wins
- Auto-copy to clipboard
- FR/EN language support via argument

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix CI validation: CLAUDE.md referenced 0.18.0, Cargo.toml is at 0.18.1.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: tee raw output to file for LLM re-read without re-run (rtk-ai#86)

When RTK filters command output, LLM agents lose failure details
(stack traces, assertions) and re-run the same command 2-3x. The tee
feature saves raw output to ~/.local/share/rtk/tee/ on failure and
prints a one-line hint so the agent can read the file instead.

- Add src/tee.rs: core module with tee_raw(), tee_and_hint(), rotation
- Add TeeConfig to config.rs: enabled, mode, max_files, max_file_size
- Integrate in 7 modules: cargo, runner, vitest, pytest, lint, tsc, go
- Default: failures only, skip <500 chars, 20 file rotation, 1MB cap
- Env overrides: RTK_TEE=0 (disable), RTK_TEE_DIR (custom directory)
- 14 unit tests, 352 total tests passing, zero regressions

Closes rtk-ai#86

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: add tee.rs to ARCHITECTURE.md module count (47 modules)

CI validate-docs requires main.rs module count == ARCHITECTURE.md count.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
chore: add Claude Code configuration (.claude)
Add opt-in audit logging to the RTK rewrite hook and a new `rtk hook-audit`
command to analyze the collected metrics. This provides verifiable data on
hook reliability (rewrite rate, skip reasons, top commands) instead of
relying on anecdotal claims.

- Add `_rtk_audit_log()` function to rtk-rewrite.sh (opt-in via RTK_HOOK_AUDIT=1)
- Log each invocation: timestamp | action | original_cmd | rewritten_cmd
- Actions: rewrite, skip:already_rtk, skip:heredoc, skip:no_match, skip:no_deps, skip:empty
- New `src/hook_audit_cmd.rs` module with log parser and stats display
- New `rtk hook-audit --since N` subcommand (default: last 7 days)
- 8 Rust unit tests + 7 hook bash tests for audit mode
- Make HOOK var overridable in test suite for repo-local testing

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Rust binary replaces 204-line bash script as Claude Code PreToolUse hook.
Adds rtk hook claude, rtk run -c, and Windows support via cfg!(windows).
Closes rtk-ai#112 (chained commands missed).

Based on updated master (0b0071d) which includes:
- Hook audit mode (rtk-ai#151)
- Claude Code agents and skills (d8b5bb0)
- tee raw output feature (rtk-ai#134)

Migrated from feat/rust-hooks (571bd86) with conflict resolution for:
- src/main.rs: Commands enum (preserved both hook audit + our hook commands)
- src/init.rs: Hook registration (integrated both approaches)

New files (src/cmd/ module):
- mod.rs: Module declarations (10 modules, excluding safety/trash/gemini for PR 1)
- hook.rs: Shared hook decision logic (21 tests, 3 safety tests removed for PR 2)
- claude_hook.rs: Claude Code JSON protocol handler (18 tests)
- lexer.rs: Quote-aware tokenizer (28 tests)
- analysis.rs: Chain parsing and shellism detection (10 tests)
- builtins.rs: cd/export/pwd/echo/true/false (8 tests)
- exec.rs: Command executor with recursion guard (22 tests, safety dispatch removed for PR 2)
- filters.rs: Output filter registry (5 tests)
- predicates.rs: Context predicates (4 tests)
- test_helpers.rs: Test utilities

Modified files:
- src/main.rs: Added Commands::Run, Commands::Hook, HookCommands enum, routing
- src/init.rs: Changed patch_settings_json to use rtk hook claude binary command
- hooks/rtk-rewrite.sh: Replaced 204-line bash script with 4-line shim (exec rtk hook claude)
- Cargo.toml: Added which = 7 for PATH resolution
- INSTALL.md: Added Windows installation section

Windows support:
- exec.rs:175-176: cfg!(windows) selects cmd /C vs sh -c for shell passthrough
- predicates.rs:26: USERPROFILE fallback for Windows home directory
- No bash, node, or bun dependency - rtk hook claude is a compiled Rust binary

Tests: All 541 tests pass
…commands

Replaces stub check_for_hook_inner with full tokenize+native-path dispatch.
Adds route_native_command() with replace_first_word/route_pnpm/route_npx
helpers to route single parsed commands to optimized RTK subcommands.

Chains (&&/||/;) and shellisms still use rtk run -c. No safety integration
(PR rtk-ai#157 adds that). Mirrors ~/.claude/hooks/rtk-rewrite.sh routing table.
Corrects shell script vitest double-run bug for pnpm vitest run flags.
ahundt added a commit to ahundt/rtk that referenced this pull request Feb 19, 2026
…commands

Replaces stub check_for_hook_inner with full tokenize+native-path dispatch.
Adds route_native_command() with replace_first_word/route_pnpm/route_npx
helpers to route single parsed commands to optimized RTK subcommands.

Chains (&&/||/;) and shellisms still use rtk run -c. No safety integration
(PR rtk-ai#157 adds that). Mirrors ~/.claude/hooks/rtk-rewrite.sh routing table.
Corrects shell script vitest double-run bug for pnpm vitest run flags.
@ahundt ahundt force-pushed the feat/data-safety-rules-v2 branch from fe612ca to c4e9ec8 Compare February 19, 2026 07:56
rtk has no `tail` subcommand — routing to "rtk tail" was silently
broken (rtk would error "unrecognized subcommand"). Remove the Route
entry so the command falls through to `rtk run -c '...'` correctly.

Move the log-tailing test cases from test_routing_native_commands
(which asserted the broken path) into test_routing_fallbacks_to_rtk_run
where they correctly verify the rtk-run-c fallback behavior.
Port tests added during the ROUTES table integration that were missing
from the v2 worktree:

registry.rs:
- 12 classify tests for Python/Go commands (pytest, go×4, ruff×2,
  pip×3, golangci-lint) that verify PATTERNS/RULES and ROUTES alignment
- 11 lookup tests (test_lookup_*, test_no_duplicate_binaries_in_routes,
  test_lookup_is_o1_consistent) that verify O(1) HashMap routing

hook.rs:
- Extend test_routing_native_commands from 20 to 47 cases covering all
  ROUTES entries: docker, kubectl, curl, eslint, tsc, prettier,
  playwright, prisma, pytest, golangci-lint, ruff, pip, gh variants
- Add test_routing_subcommand_filter_fallback (14 cases) verifying that
  Only[] subcommand filters correctly reject unmatched subcommands

Total: 545 → 569 tests (+24)
Add 11 safety rules intercepting destructive commands:
- rm → trash (cross-platform via trash crate)
- git reset --hard/clean/checkout → stash first
- cat/head/sed → blocked, suggest Read tool or Edit tool

Extensible rtk.*.md rule files with YAML frontmatter loaded from
.rtk/, .claude/, .gemini/ directories. Config system expanded from
single config.rs to config/ module with rules.rs and discovery.rs.

Env var opt-out: RTK_SAFE_COMMANDS=0 disables safety rules,
RTK_BLOCK_TOKEN_WASTE=0 allows cat/head/sed.

Config CLI expanded: rtk config get/set/list/unset/create/export-rules.

New dependencies: trash = "5", serde_yaml = "0.9"
Closes rtk-ai#115

Tests: 673 total (35 safety, 4 trash, 3 restored hook safety tests)
@ahundt ahundt force-pushed the feat/data-safety-rules-v2 branch from c4e9ec8 to c1b7685 Compare February 19, 2026 10:19
edsai pushed a commit to edsai/rtk that referenced this pull request Feb 19, 2026
…commands

Replaces stub check_for_hook_inner with full tokenize+native-path dispatch.
Adds route_native_command() with replace_first_word/route_pnpm/route_npx
helpers to route single parsed commands to optimized RTK subcommands.

Chains (&&/||/;) and shellisms still use rtk run -c. No safety integration
(PR rtk-ai#157 adds that). Mirrors ~/.claude/hooks/rtk-rewrite.sh routing table.
Corrects shell script vitest double-run bug for pnpm vitest run flags.
edsai pushed a commit to edsai/rtk that referenced this pull request Feb 19, 2026
…commands

Replaces stub check_for_hook_inner with full tokenize+native-path dispatch.
Adds route_native_command() with replace_first_word/route_pnpm/route_npx
helpers to route single parsed commands to optimized RTK subcommands.

Chains (&&/||/;) and shellisms still use rtk run -c. No safety integration
(PR rtk-ai#157 adds that). Mirrors ~/.claude/hooks/rtk-rewrite.sh routing table.
Corrects shell script vitest double-run bug for pnpm vitest run flags.
edsai pushed a commit to edsai/rtk that referenced this pull request Feb 19, 2026
…commands

Replaces stub check_for_hook_inner with full tokenize+native-path dispatch.
Adds route_native_command() with replace_first_word/route_pnpm/route_npx
helpers to route single parsed commands to optimized RTK subcommands.

Chains (&&/||/;) and shellisms still use rtk run -c. No safety integration
(PR rtk-ai#157 adds that). Mirrors ~/.claude/hooks/rtk-rewrite.sh routing table.
Corrects shell script vitest double-run bug for pnpm vitest run flags.
@ahundt
Copy link
Author

ahundt commented Feb 20, 2026

@pszymkowiak I saw a pending problem tag added to this one is there a particular technical issue? I've been running it without issue myself.

@ahundt ahundt force-pushed the feat/data-safety-rules-v2 branch from c1b7685 to e822a84 Compare February 23, 2026 03:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants