Deferred follow-ups from the plugin-quality audit applied in #2695 (guardrails CHANGELOG 0.28.26 records both). Session-record reachability evidence (2026-08-15): jq . f > /tmp/x && mv /tmp/x <repo plugin.json> evaded block-hook-bypass (unmodeled producer, by design) AND the Write|Edit-matched content guards, and jq silently un-escaped — sequences in two manifests — caught only by manual diff review. This meets the same reachability standard that reopened #2217. The shape is now a named residual (scope note + README); these are the two remedies deliberately not rushed into that PR:
- Narrow same-command detector lane: block a command segment whose effective stdout target (existing
set_last_stdout_target machinery) is later reused in the same command string as the SOURCE operand of mv/cp with a destination outside configured scratch roots. Path-identity keeps ordinary renames/data-pipeline moves unblocked (never-hard-block tier rule). Disclose the residuals it still cannot see: cross-tool-call staging, variable-carried paths, other movers (install, rsync, dd).
- Write-path-independent content invariants (the only fix that closes the damage class rather than one spelling): enforce what the formatters/secret scanners police at a layer no write path can skip — git pre-commit (the plugin already ships
lib/git-hooks/) or CI. Without this, the Write|Edit-matched secret-pattern and hardcoded-path guards are silently load-bearing on write-path choice (audit finding F2).
A broad any-redirect-into-repo lane was assessed and rejected (blocks legitimate data-processing redirects; violates the fleet's enforcement-tier rule).
Evidence: plugin-quality audit packet guardrails/20260815T104849Z (audit-notes.md, session a86db903), reproductions table + byte-level jq damage repro.
Deferred follow-ups from the plugin-quality audit applied in #2695 (guardrails CHANGELOG 0.28.26 records both). Session-record reachability evidence (2026-08-15):
jq . f > /tmp/x && mv /tmp/x <repo plugin.json>evadedblock-hook-bypass(unmodeled producer, by design) AND theWrite|Edit-matched content guards, and jq silently un-escaped—sequences in two manifests — caught only by manual diff review. This meets the same reachability standard that reopened #2217. The shape is now a named residual (scope note + README); these are the two remedies deliberately not rushed into that PR:set_last_stdout_targetmachinery) is later reused in the same command string as the SOURCE operand ofmv/cpwith a destination outside configured scratch roots. Path-identity keeps ordinary renames/data-pipeline moves unblocked (never-hard-block tier rule). Disclose the residuals it still cannot see: cross-tool-call staging, variable-carried paths, other movers (install,rsync,dd).lib/git-hooks/) or CI. Without this, theWrite|Edit-matched secret-pattern and hardcoded-path guards are silently load-bearing on write-path choice (audit finding F2).A broad any-redirect-into-repo lane was assessed and rejected (blocks legitimate data-processing redirects; violates the fleet's enforcement-tier rule).
Evidence: plugin-quality audit packet
guardrails/20260815T104849Z(audit-notes.md, session a86db903), reproductions table + byte-level jq damage repro.