You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
add the missing Bash substitution and PowerShell subexpression or execution-region cases to the reviewed approval matrix
account for an opaque PowerShell script-block host argument only when ShellSyntaxTree exposes the exact known command-owned region through complete body occurrences
require the host and every body command to match approval policy independently
keep empty bodies, unknown receivers, incomplete occurrences, and unknown or future region metadata strict
synchronize the positive and fail-closed behavior into the canonical tool-approval OpenSpec
Why
ShellSyntaxTree deliberately represents a known PowerShell callback script block twice: the host clause retains the opaque authored argument, while the executable body is projected into command occurrences. Netclaw was treating the opaque host argument as unresolved even after it had independently analyzed every body occurrence. That prevented valid stored grants from being reused.
The correction is narrow. It correlates the exact parser-owned ClauseElement by reference, exempts only its joined DynamicSkip argument, and requires a complete descendant occurrence with known execution-region facts. Body commands remain separate approval units.
Evidence
The reviewed matrix grows from 225 to 244 cases:
Bash: 193 to 199
PowerShell 7: 23 to 36
Windows PowerShell 5.1: unchanged at 5
The new PowerShell cases prove that both grants are required:
host and body grants: allowed
host grant only: Remove-Item still requires approval
body grant only: ForEach-Object still requires approval
unknown receiver: remains complex and cannot reuse either grant
Validation
Release build: 0 warnings, 0 errors
full solution tests before the content-preserving rebase: 6,793 passed, 15 expected skips, 0 failed
post-rebase Netclaw.Security.Tests: 815 passed
post-rebase approval matrix: 244 passed
strict OpenSpec validation: 77 passed, 0 failed
Slopwatch strict analysis: 0 issues
copyright headers, scoped formatting, and git diff --check: passed
three adversarial review passes: all findings corrected; final disposition has no blockers
This PR is intentionally stacked on #1855 so its CI can run while the parent native smoke jobs finish. It must be retargeted to dev after #1855 merges; auto-merge will be enabled only after that retargeting.
Delivery note: I retargeted this PR to dev before #1855 merged because the required workflows only run for dev-targeted pull requests. Auto-merge remains disabled. The head contains #1855 current content, so CI tests the intended combined tree; after #1855 merges, the visible diff will collapse to the single reviewed matrix commit.
Cross-platform snapshot follow-up: the first macOS and Windows runs exposed Verify built-in temp-path scrubbing, not a policy difference. The authored Bash case intentionally contains /tmp; Linux normalized it to {TempPath}, while the other hosts preserved it. The final fix scopes VerifySettings.DisableScrubbers() to this deterministic review-table snapshot and records the literal command exactly. A broader string replacement was rejected during adversarial review because it could hide future command changes. On the rebased current head, Netclaw.Security.Tests passes 815/815 and the full shell approval matrix passes 244/244.
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
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.
Summary
Why
ShellSyntaxTree deliberately represents a known PowerShell callback script block twice: the host clause retains the opaque authored argument, while the executable body is projected into command occurrences. Netclaw was treating the opaque host argument as unresolved even after it had independently analyzed every body occurrence. That prevented valid stored grants from being reused.
The correction is narrow. It correlates the exact parser-owned
ClauseElementby reference, exempts only its joinedDynamicSkipargument, and requires a complete descendant occurrence with known execution-region facts. Body commands remain separate approval units.Evidence
The reviewed matrix grows from 225 to 244 cases:
The new PowerShell cases prove that both grants are required:
Remove-Itemstill requires approvalForEach-Objectstill requires approvalValidation
Netclaw.Security.Tests: 815 passedgit diff --check: passedDelivery sequence
This PR is intentionally stacked on #1855 so its CI can run while the parent native smoke jobs finish. It must be retargeted to
devafter #1855 merges; auto-merge will be enabled only after that retargeting.