Skip to content

fix(hooks): guard-orchestrator-writes analyses scripts created by the same command and names the tried path (#1854) - #1861

Merged
dlrivada merged 3 commits into
mainfrom
fix/guard-hook-unreadable-scripts-1854
Oct 6, 2026
Merged

dlrivada merged 3 commits into
mainfrom
fix/guard-hook-unreadable-scripts-1854

Conversation

@dlrivada

@dlrivada dlrivada commented Oct 5, 2026 •

Copy link
Copy Markdown
Owner

Summary

guard-orchestrator-writes.ps1 no longer denies, as "could not read", a probe script that the same command creates. When it does deny, it now says which path it tried.

Created by the same command. A missing script is allowed when the same command writes that exact file with literal content (Set-Content, Add-Content, Out-File or a redirection). It is still denied when:

  • the command mentions src/ or tests/;
  • the content comes from Get-Content, a download or a copy.

Denials and their messages.

Case Message now includes
Missing script the command does not create the tried path, the raw argument and the base directory
Unresolvable path (a variable) the raw argument and the base directory
Script exists but cannot be read the error type

An existing script that references src/ or tests/ and writes files is still denied.

Cause

Reproduced with reviewer payloads: an existing scratch stub run through &, and dotnet run probe.cs with a relative path, were already allowed. The denials happen when the script is absent at hook time, typically because the same command creates it. The old messages did not record the tried path, so the exact cause behind the three denials of 2026-10-05 (PR #1852 and PR #1849) cannot be confirmed. The new messages make the next case diagnosable.

Verification

  • Test-Hooks.ps1: 1125 cases, 0 failed (16 new, in the #1854 block).
  • Self-review by adversarial-reviewer found two majors, both fixed in c03f4cce with regression tests:
    • content not visible in the command text (a copy, Get-Content, a download) was allowed;
    • the pipeline form '...src...' | Set-Content x.ps1 slipped through.

Known limits

  • A path that resolves to a directory reports "does not exist".
  • String-split obfuscation of src/ is not detected; the heuristic already had this limit for existing scripts.
  • A command that both creates a stub and reads src/ is denied, and the message says to split it into two calls.

Fixes #1854

Summary by CodeRabbit

  • Seguridad
    • Se han reforzado los controles para ejecutar scripts desde comandos: se bloquean los scripts inexistentes, ilegibles o difíciles de verificar, así como los que pueden modificar archivos sensibles.
    • Se permiten scripts seguros cuando su contenido es explícito y verificable, y comandos con variables dinámicas cuando no realizan escrituras en archivos.
  • Documentación
    • Se han actualizado las indicaciones sobre los casos bloqueados y las excepciones permitidas.

…ying it as unreadable (#1854)

guard-orchestrator-writes judges a script that the same command creates from the text that command carries, and names the tried path, raw argument and base directory when it denies a missing or unresolvable script. Adds reviewer probe-script cases to Test-Hooks.ps1.
…#1854)

A script created by the same command is allowed only with literal content and no src/ or tests/ mention in the command; copies, downloads and Get-Content sources are denied. Adds pipeline-form, Get-Content and Copy-Item regression cases.
Copilot AI balanced review requested due to automatic review settings October 5, 2026 19:39
@dlrivada

dlrivada commented Oct 5, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai

coderabbitai Bot commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: dlrivada/Encina/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 08fe091a-887d-4c1d-a9a2-c1665f0c61e9
📥 Commits

Reviewing files that changed from the base of the PR and between ab4ec13 and 8313d31.

📒 Files selected for processing (5)
  • .claude/agents/README.md
  • .claude/hooks/_command-text.ps1
  • .claude/hooks/_write-targets.ps1
  • .claude/hooks/guard-orchestrator-writes.ps1
  • .claude/hooks/tests/Test-Hooks.ps1

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

El cambio amplía el análisis de comandos y escrituras para validar scripts lanzados por el guard. La validación distingue contenido literal, anexiones, rutas sin resolver y ejecutables. Se añaden pruebas para scripts permitidos y bloqueados, y se actualiza la documentación de la política.

Changes

Protección de scripts lanzados

Layer / File(s) Summary
Análisis de tokens literales y tuberías
.claude/hooks/_command-text.ps1
Split-CommandStatements añade Literal para identificar tokens formados por un único segmento literal y PipeSource para asociar el primer token tras una tubería simple con la sentencia anterior.
Detección de escrituras y ejecutables
.claude/hooks/_write-targets.ps1
Get-ShellWrites registra el contenido literal y las anexiones, reconoce Rename-Item, clasifica ejecutables e intenta resolver rutas dinámicas de scripts.
Política del guard y regresiones
.claude/hooks/guard-orchestrator-writes.ps1, .claude/hooks/tests/Test-Hooks.ps1, .claude/agents/README.md
El guard valida scripts existentes y scripts creados o modificados en el mismo comando. Las pruebas cubren rutas y contenido permitidos y bloqueados. La documentación precisa los casos de denegación.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Bug fix · Severity of issue fixed: Medium

Merge Risk: ⚪ Minimal · up to 8313d

No merge-blocking issue was identified; the change is ready for normal checks.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed El título identifica el cambio principal: analizar scripts creados en el mismo comando y mostrar la ruta intentada.
Description check ✅ Passed La descripción explica el cambio, los casos cubiertos, la causa, la verificación y los límites. Incluye «Fixes #1854». Faltan las secciones «Type of Change» y «Checklist»; la sección de integración tr…
Linked Issues check ✅ Passed #1854 solicita permitir scripts de prueba benignos, analizar el contenido literal que el mismo comando escribe y denegar contenido opaco o escrituras en src/ y tests/. guard-orchestrator-writes.ps1 …
Out of Scope Changes check ✅ Passed Los cambios en _command-text.ps1 y _write-targets.ps1 proporcionan el análisis de sentencias, contenido literal, destinos y lanzamientos que necesita #1854. Las pruebas y la documentación describe…
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai

coderabbitai Bot commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

…#1854)

guard-orchestrator-writes now trusts a script that the same command creates
or overwrites only when every write to it is a quoted or here-string literal
(Set-Content/Add-Content -Value, Out-File/Tee-Object -InputObject, New-Item
-Value, a lone literal piped in, or 'literal' > file). Every other source of
content, a wildcard target, a rename, a copy or any statement the hook cannot
name while the script is created is denied, naming the creating statement.
Literals must not reference src/ or tests/ or launch another script, and the
old text of an existing script is judged too. A & $variable launch is
unresolvable when the command also writes a file. Tokens gain Literal and
PipeSource; Rename-Item is modelled as a write. Adds the review repro cases
and false-positive cases to Test-Hooks and documents the rules.
Copilot AI balanced review requested due to automatic review settings October 5, 2026 21:37

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@dlrivada

dlrivada commented Oct 5, 2026

Copy link
Copy Markdown
Owner Author

Review findings applied in 8313d31b. A script that a command creates or overwrites is now trusted only when every write to it is a quoted or here-string literal. Any other creating statement is denied, and the message names it.

Literal content checks

  • It must not reference src/ or tests/.
  • It must not launch another script.
  • On overwrite, the hook judges both the old text and the new text.

Second-round hardening

  • Wildcard targets and invalid patterns are denied.
  • Rename, copy, move and expand onto the script are denied.
  • Curly quotes are not treated as literals.
  • & $var is denied only when the same command also writes a file.

Verification

  • Test-Hooks: 1181 cases, 0 failed (about 56 new).
  • Two adversarial self-review passes; every finding of both is fixed and has a test.

Pre-existing limits (they also exist on main; a follow-up issue will cover them):

  • bare script launches;
  • a variable write target next to an existing script;
  • a curly quote hiding a whole statement;
  • an attached redirect.

@dlrivada

dlrivada commented Oct 6, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@dlrivada
dlrivada merged commit 961b918 into main Oct 6, 2026
23 checks passed
@dlrivada
dlrivada deleted the fix/guard-hook-unreadable-scripts-1854 branch October 6, 2026 08:30
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.

[INFRA] guard-orchestrator-writes denies reviewer probe scripts it cannot read (scratch stubs through &, dotnet run probe.cs)

2 participants