feat: close the PowerShell diagnostics gaps from the 2026-08-05 incident session - #111
Merged
Conversation
…sion A recorded 3DEXPERIENCE/SQL Server incident session logged every command the validator rejected. Four were real gaps: - Format-Table -Wrap: without it long Message fields truncate mid-sentence, forcing the far more verbose Format-List. - Get-ChildItem -Include: -Filter takes one Win32 glob; searching for crash dumps, heap dumps, and javacores took three passes. - Select-String -Context: the grep -B/-A equivalent. - net accounts: the only reader for lockout/password policy; the Get-* cmdlets the denial pointed to cannot show it. net accounts is allowed via subcommand dispatch so bare net, net.exe, and every other net subcommand stay denied. The same slash switches that display the policy also set it when given values, and they reach the validator as positionals - so this adds no_positional_args, a manifest field that rejects every positional argument, keeping only the bare read-only form. positional_allowlist cannot express that: an empty values list is rejected at load time as a likely manifest bug. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The old message said "Script blocks are not supported", which stopped being true when the safe-expression grammar landed. The incident session showed the cost: the agent never attempted calculated properties or Where-Object blocks because the first rejection primed it to avoid every construct with braces. Name what blocks do support and what they don't. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The connect hint still said "no $ or {} or ;" - stale since the
safe-expression grammar landed, and agents obey it completely. In the
2026-08-05 incident session the agent documented WorkingSet64 as
unreachable and skipped jstack entirely, both because of this hint,
while the validator would have accepted both.
The hint now names what works: $_ in script blocks, calculated
properties, [math]::/[datetime]:: calls, FilterHashtable time bounds,
the JVM tools, and net accounts - plus what still doesn't.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
Summary
A recorded 3DEXPERIENCE/SQL Server incident session kept a log of every command the validator rejected. Replaying that log against v0.9.6 split it in two:
Real gaps (fixed here):
Format-Table -Wrap— without it longMessagefields truncate mid-sentence, forcing the much more verboseFormat-ListGet-ChildItem -Include—-Filtertakes one Win32 glob; finding crash dumps + heap dumps + javacores took three passesSelect-String -Context— thegrep -B/-Aequivalentnet accounts— the only reader for lockout/password policy; allowed bare-only via subcommand dispatch and a newno_positional_argsmanifest field (the same slash switches that display policy also set it when given values, and they reach the validator as positionals). Barenet,net.exe, and every othernetsubcommand stay denied.False negatives (fixed by correcting what we tell the agent): the session never attempted
$_, calculated properties,Where-Objectblocks,jps/jstack, time-bounded-FilterHashtable,Get-NetFirewallRule, orGet-Counter— all of which v0.9.6 already accepts. The agent self-censored because the WinRM connect hint still says "no $ or {} or ;", stale since the safe-expression grammar landed, and the script-block parse error claims blocks are unsupported outright. Both messages now describe the actual safe subset.Test plan
validator/windows_diagnostics_test.gocovers each formerly-rejected command, plus guards:net accounts /forcelogoff:30,net user eve /add,net localgroup, and barenetall stay rejectedserver/hint_test.gopins the connect hint to advertise$_,[math]::,jps,jstack,FilterHashtableand rejects the stale claimgo test ./...passes exceptTestLocalExecutor_Persistent_RoundTrip, which fails identically on unmodifiedmainin this environment (zsh bracketed-paste escape codes in PTY output) — pre-existing, unrelated🤖 Generated with Claude Code