fix(approvals): scope trailing-slash directory globs to their parent - #4
Closed
Aaronontheweb wants to merge 1 commit into
Closed
fix(approvals): scope trailing-slash directory globs to their parent#4Aaronontheweb wants to merge 1 commit into
Aaronontheweb wants to merge 1 commit into
Conversation
A glob that ends in a slash (foo/*/) matches only directories. It adds no descendant path segment. Every match is still a direct child of the covering directory foo. Since 0.25.3 the approval gate read the trailing slash as an unresolved descendant scope. So a command like `ls -d .../immovlan/*/` degraded to a one-shot "complex command" prompt. HasUnresolvedDescendantScope now strips trailing slashes before the descendant-segment test. A real segment after the wildcard (foo/*/x, foo/*/*) still fails closed. The covering-directory symlink scan does not change. So foo/*/ gets the same persistable, symlink-checked scope that the leaf glob foo/* already has. Tests: - Matcher corpus: trailing-slash globs resolve a covering directory and are not messy. Real descendant segments and symlink children stay one-shot. - Disposition corpus: an in-project directory list auto-allows as a safe verb, an external scope offers a persistent grant, and the reported pipeline is no longer complex. - Harden the external-glob case to an isolated temp subdir. A symlink child of shared /tmp (for example an IDE socket) no longer flakes the scan.
Owner
Author
|
Superseded by netclaw-dev#1785 (retargeted to upstream netclaw-dev/netclaw). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Since 0.25.3, a directory-list glob that ends in a slash — for example
ls -d /home/netclaw/.netclaw/workspaces/immovlan/*/— is flagged as a"complex command — only one-shot approval available". The operator cannot grant
it persistently, so the agent re-prompts on every call. This causes approval
fatigue.
Root cause
The approval gate marks a glob as an unresolved descendant scope when a
/follows the first wildcard character (
HasUnresolvedDescendantScope). A trailingslash (
foo/*/) is a directory-only type filter, not a descendant path segment —every match is still a direct child of the covering directory
foo. The predicatedid not tell the two apart, so
foo/*/failed closed to one-shot only. Thisbehavior arrived with the parser-based approval analysis (netclaw-dev#1753) and the
descendant-scope rule (netclaw-dev#1768); 0.25.2 did not have it.
Fix
HasUnresolvedDescendantScopenow strips trailing slashes before the"is there a
/after the wildcard" test. One helper feeds all three consumers(
HasDynamicSyntax, the covering-directory guard, andIsMessy), so they cannotdrift.
foo/*/normalizes to the leaffoo/*. It resolves the covering directoryfoo, so it is persistable and symlink-checked.foo/*/x,foo/*/*) keeps its separatorand stays one-shot.
Behavior change (blast radius)
The predicate is used only by the approval matcher. The hard-deny /
protected-path policy does not read it and runs first regardless. Net effect for
the
foo/*/shape:auto-allows, the same as the leaf glob
ls foo/*today.the covering directory, instead of one-shot only.
foo/*/argument, not justthe reported one.
Unchanged and verified: hard-deny, external and protected paths still prompt,
symlink globs still fail closed, real descendant globs stay one-shot, Windows
(legacy tokenizer path), and non-shell matchers.
Tests
ShellApprovalMatcherPathExtractionTests): trailing-slashglobs resolve a covering directory and are not messy; real descendant segments
and symlink children stay one-shot.
ShellApprovalCases): an in-project directory listauto-allows as a safe verb, an external scope offers a persistent grant, and
the reported pipeline is no longer complex.
external-glob-does-not-reuse-project-grantcase toan isolated temp subdirectory, so a symlink child of the shared system temp
(for example an IDE socket) no longer flakes the covering-directory scan.
dotnet slopwatch analyze: 0 issues. Copyright headers verified.