RTK Verify Command for Hook Integrity: Implementation and Security Checks

The rtk verify command is a security meta-command that validates the SHA-256 hash of the RTK rewrite hook against a stored baseline to detect tampering, then executes inline TOML filter tests to ensure compression rules work correctly.

The rtk verify command serves as the security gatekeeper for the RTK toolchain, ensuring that the rewrite hook installed at ~/.claude/hooks/rtk-rewrite.sh has not been compromised before executing any operational commands. As implemented in the rtk-ai/rtk repository, this command performs cryptographic integrity verification by comparing runtime hashes against installation baselines established during rtk init -g, followed by optional filter validation tests embedded in the project's rtk.toml configuration.

How the RTK Verify Command Ensures Hook Integrity

The integrity verification process begins with hook path resolution and ends with a cryptographic comparison that blocks execution if tampering is detected.

Hook Path Resolution and Hash Reading

In src/hooks/integrity.rs, the verification logic first resolves the default hook location at ~/.claude/hooks/rtk-rewrite.sh and locates its companion .hash file containing the baseline SHA-256 checksum. According to the source code at lines 95-124, the system validates that both the script and its hash file exist before proceeding to the comparison phase. The baseline hash is read from disk at lines 150-169, establishing the trusted reference point against which all future modifications are measured.

Runtime Hash Verification

The core security check occurs at lines 195-227 of src/hooks/integrity.rs, where the run_verify function computes the current SHA-256 hash of the hook script and compares it to the stored baseline. This computation happens at runtime, ensuring that any modification made after the initial installation is immediately detected. When the hook is installed as a native binary command rather than a shell script, the logic gracefully detects the absence of a script file and reports that integrity checking is not applicable, avoiding false failures.

Execution Results and Exit Codes

The rtk verify command emits one of four distinct statuses based on the integrity check outcome, each with specific consequences for command execution.

Status Messages and Their Meanings

  • PASS: The computed hash matches the baseline exactly. The command emits hook integrity verified along with the SHA-256 checksum and returns exit code 0, allowing normal operation to continue.
  • WARN: Either no baseline hash exists or the hash file is orphaned (present without a corresponding script). The operation continues but prompts the user to re-run rtk init -g to establish a proper baseline.
  • FAIL: The computed hash differs from the baseline, indicating potential tampering. RTK exits with code 1 and blocks execution, displaying a detailed diff showing the expected versus actual hashes along with remediation steps.
  • SKIP: The hook is not currently installed. The command suggests running rtk init -g and continues without performing integrity checks.

Why Hook Integrity Matters in RTK

The rewrite hook (rtk-rewrite.sh) intercepts every command that passes through RTK, making it a critical security boundary. If an attacker modifies this script, they could bypass token-saving logic, inject malicious code, or exfiltrate sensitive data. RTK stores a baseline SHA-256 hash when the hook is installed via rtk init -g, and the verify command recomputes the hash at runtime to guarantee the script has not been tampered with since installation.

Inline TOML Filter Testing

After the integrity gate passes, the command proceeds to validate the inline tests embedded in the project's rtk.toml configuration file. These tests exercise the filter rules used by RTK to compress command output and verify that token reduction logic works as intended.

Running Specific Filter Tests

Located in src/hooks/verify_cmd.rs at lines 7-48, the filter testing logic accepts an optional --filter <name> argument to limit execution to a specific filter's test suite. When invoked without arguments, the command runs all available filter tests and reports the pass ratio (e.g., 3/3 tests passed). This modular approach allows developers to verify individual compression rules without executing the entire test suite.

CI Integration with --require-all

For continuous integration environments, the --require-all flag enforces that every filter defined in rtk.toml must have corresponding inline tests. If any filter lacks test coverage, the command fails with a MISSING tests for filter error and returns exit code 1. This ensures that production filter rules are always validated before deployment.

Command Dispatch Architecture

The top-level command parser in src/main.rs (lines 15-27) routes the verify sub-command through a structured enum that prioritizes security checks. The dispatch logic executes the hook integrity verification first; only if this gate passes does the system proceed to filter testing. This sequential validation ensures that a compromised hook cannot influence the results of filter tests or subsequent operations.

Practical Usage Examples

The following commands demonstrate common rtk verify usage patterns in development workflows.

Run the complete verification suite:

$ rtk verify
PASS  hook integrity verified
      sha256:3f2e… (hash omitted)
      /home/user/.claude/hooks/rtk-rewrite.sh
3/3 tests passed

Validate a specific filter's logic:

$ rtk verify --filter git
2/2 tests passed

Enforce comprehensive test coverage in CI pipelines:

$ rtk verify --require-all
FAIL  hook integrity verified
      sha256:3f2e…
      /home/user/.claude/hooks/rtk-rewrite.sh
MISSING tests for filter: cargo
error: 1 test(s) failed

Inspect the hook after a failure:

$ rtk verify
FAIL  hook integrity check FAILED

  Expected: 3f2e… (baseline)
  Actual:   a1b4… (current)

  To restore: rtk init -g --auto-patch
  To inspect: cat ~/.claude/hooks/rtk-rewrite.sh

Summary

  • The rtk verify command performs SHA-256 hash verification of the rewrite hook at ~/.claude/hooks/rtk-rewrite.sh by comparing runtime checksums against baselines stored during installation.
  • Verification logic resides primarily in src/hooks/integrity.rs, with four possible outcomes: PASS, WARN, FAIL (exit code 1), and SKIP.
  • After integrity confirmation, the command executes inline TOML filter tests defined in rtk.toml, with optional --filter targeting and --require-all enforcement for CI/CD pipelines.
  • The command dispatch in src/main.rs prioritizes security by running hook integrity checks before any filter validation, ensuring compromised hooks cannot execute.

Frequently Asked Questions

What files does the RTK verify command check?

The command validates the rewrite hook script at ~/.claude/hooks/rtk-rewrite.sh and its corresponding .hash file containing the baseline SHA-256 checksum. If the hook is installed as a native binary rather than a script, the integrity check gracefully reports that verification is not applicable.

Why does rtk verify exit with code 1 on hook tampering?

Exit code 1 on FAIL status serves as a hard security boundary that blocks execution of potentially compromised hooks. Since the rewrite hook intercepts every command processed by RTK, a modified script could bypass token-saving logic, inject malicious code, or exfiltrate data. The non-zero exit code prevents automated systems and CI pipelines from proceeding with unsafe configurations.

How do I restore a hook after integrity verification fails?

When verification fails, the command output includes remediation steps. Run rtk init -g --auto-patch to regenerate the hook and establish a new trusted baseline hash. Alternatively, inspect the current hook contents with cat ~/.claude/hooks/rtk-rewrite.sh to manually audit what changed before restoration.

Can I run filter tests without checking hook integrity?

No, the command architecture in src/main.rs enforces sequential validation where hook integrity must pass before filter tests execute. This design ensures that the testing environment itself is trustworthy. To run only filter tests, you would need to bypass the verify command entirely and use a different entry point, though this is not recommended for security-critical environments.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →