Skip to content

Adopt rtk-ai/rtk#2965: hooks - don't rewrite pipe-feeding segments whose filter changes shape - #16

Merged
kylehgc merged 3 commits into
developfrom
claude/issue-13-adopt-2965
Jul 17, 2026
Merged

kylehgc merged 3 commits into
developfrom
claude/issue-13-adopt-2965

Conversation

@kylehgc

@kylehgc kylehgc commented Jul 17, 2026

Copy link
Copy Markdown
Owner

Closes #13.

Adopts rtk-ai/rtk#2965 (cherry-pick, authorship preserved) plus one fork-authored amendment and one lockfile chore.

Commits

  • 9d678b1 chore: complete Cargo.lock entry for windows-sys dependency — housekeeping from the fix(core): decode process output using Windows console code page rtk-ai/rtk#2717 adoption (PR Adopt rtk-ai/rtk#2717: core - decode process output using Windows console code page #15): the upstream lock hunk omitted windows-sys from rtk's dependency list; cargo build re-resolved it.
  • e95207d fix(hooks): don't rewrite pipe-feeding segments whose filter changes output shape — cherry-pick of upstream bc0f568, author XU Pengfei (@xuing). Generalizes the find/fd pipe-skip (Trouble running xargs as second bash command. rtk-ai/rtk#439) into a PIPE_INCOMPATIBLE list (find, fd, grep, rg, ls, head, tail, cat) + is_pipe_incompatible() helper, with 6 new tests. Byte-for-byte faithful: git diff pr-2965 HEAD -- src/discover/registry.rs was empty at cherry-pick time.
  • e1e37fd fix(hooks): make pipe-skip normalization match the rewrite path — amendment: the helper's env-prefix heuristic missed sudo/env/quoted env values and absolute binary paths, so sudo grep … | wc -l and /usr/bin/grep … | wc -l were still rewritten (found by pre-PR review, confirmed empirically). Now reuses the same strip_disabled_prefix (ENV_PREFIX) + basename normalization as rewrite_segment, so skip detection and rewriting can never disagree. +4 tests.

Adoption checklist

  • Sync: no-op — upstream/develop is already an ancestor of fork develop
  • Staleness re-check: develop @ 337bdda still had only the inline find/fd carve-out in rewrite_compound; grep/ls/head/tail/cat/rg pipe-feeders were still rewritten
  • Repro on pre-cherry-pick binary (below)
  • Cherry-pick preserving authorship; fixed behavior confirmed with real output (below)
  • Quality gate: cargo fmt --all clean, cargo clippy --all-targets zero warnings, cargo test --all 2466 passed / 0 failed
  • Amendment as separate fork-authored commit

Repro (real output, this machine)

Before (develop @ 337bdda):

$ rtk rewrite "head -50 Cargo.toml | wc -l"
rtk read Cargo.toml --max-lines 50 | wc -l   (exit 3 — rewritten)

$ head -50 Cargo.toml | wc -l                 # raw pipeline
50
$ rtk read Cargo.toml --max-lines 50 | wc -l  # what the hook actually ran
25

wc -l reports 25 for 50 real lines — rtk read elides half the lines. (The installed hook even rewrote one of this session's own verification pipelines mid-investigation, live-demonstrating the corruption.)

After (this branch):

$ rtk rewrite "head -50 Cargo.toml | wc -l"    → exit 1 (passthrough, no rewrite)
$ rtk rewrite "grep -n use src/main.rs | wc -l" → exit 1 (passthrough)
$ rtk rewrite "ls -t | head -1"                 → exit 1 (passthrough)
$ rtk rewrite "sudo grep -n x f.txt | wc -l"    → exit 1 (passthrough — amendment)
$ rtk rewrite "/usr/bin/grep -n x f.txt | wc -l" → exit 1 (passthrough — amendment)
$ rtk rewrite "grep -rn TODO src"               → rtk grep -rn TODO src (exit 3 — savings preserved)
$ rtk rewrite "head -50 Cargo.toml"             → rtk read Cargo.toml --max-lines 50 (exit 3 — savings preserved)
$ rtk rewrite "sudo grep -rn TODO src"          → sudo rtk grep -rn TODO src (exit 3 — savings preserved)

Review

Two-axis review (standards + spec) run pre-PR.

  • Spec: faithful cherry-pick, list is exactly the 8 claimed names, all 6 claimed tests present and passing, &&/; segment isolation and quoted-| safety verified in code. One confirmed generalization gap (env-prefix parity claim not actually met for sudo/env/quoted values) — fixed by the amendment.
  • Standards: no hard violations; the one Duplicated Code finding (helper reimplementing env-prefix skipping instead of reusing strip_disabled_prefix) is resolved by the amendment, which deletes the duplicate heuristic. Known ceiling: transparent prefixes (e.g. builtin wrapper prefixes the rewrite path strips recursively) are not mirrored in the skip check — same trade-off as upstream, noted for a future ticket if it bites.

🤖 Generated with Claude Code

kylehgc and others added 3 commits July 17, 2026 17:16
cargo build re-resolved the lock after the rtk-ai#2717 adoption;
the upstream lock hunk omitted windows-sys from rtk's dependency list.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…output shape

The pipe-left rewrite fed rtk's summarized formats into downstream
programs: 'grep -n X f | wc -l' counted rtk grep's header and elision
lines (measured 28 for 60 real matches), '$(ls -t | head -1)' captured a
size-decorated name, and head's rtk-read mapping leaked '[N more lines]'
markers to whatever parsed the file. find/fd already had this exact
carve-out (rtk-ai#439) — generalize it to a PIPE_INCOMPATIBLE list covering the
other shape-changing rewrites (grep, rg, ls, head, tail, cat). Segments
without a pipe, and non-pipeline segments of the same compound command,
keep their rewrites.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Amendment to the adopted rtk-ai#2965: is_pipe_incompatible used its
own env-prefix heuristic (skip words containing =), which missed sudo,
env, and quoted env values, and did not normalize absolute binary paths
-- so sudo grep ... | wc -l and /usr/bin/grep ... | wc -l were still
rewritten and miscounted downstream. Reuse the same strip_disabled_prefix
(ENV_PREFIX) + basename normalization the rewrite path applies, so skip
detection and rewriting can never disagree.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@kylehgc
kylehgc merged commit 1018b8b into develop Jul 17, 2026
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.

Adopt upstream #2965: hooks - don't rewrite pipe-feeding segments whose filter changes shape

2 participants