Skip to content

feat(Native): import NukeNul with dry-run and extended shell-artifact matchers - #63

Open
David-Martel wants to merge 10 commits into
mainfrom
feat/import-nukenul
Open

feat(Native): import NukeNul with dry-run and extended shell-artifact matchers#63
David-Martel wants to merge 10 commits into
mainfrom
feat/import-nukenul

Conversation

@David-Martel

Copy link
Copy Markdown
Owner

Imports NukeNul into Native/NukeNul/ with full history preserved (git subtree add), alongside the existing Native/pcai_core Rust crate.

What NukeNul is

A hybrid Rust cdylib + C# CLI that deletes Windows filenames standard tools cannot remove — reserved device names (nul, con, prn), and stray shell artifacts produced when PowerShell syntax reaches a bash shell.

It previously lived as an untracked source tree in C:\codedev\nukenul with no version control at all. It was git-initialized on 2026-08-06, extended, and is imported here.

Why it matters

A live sweep of C:\codedev on 2026-08-06 found 25 such artifacts: 9 literal $null files, 5 $variable directories ($runDir, $out, $local, $archiveDir, $oldLink), 4 ;C path-mangle directories, and a 771 MB cargo cache created by cargo build --target-dir $target with the variable unexpanded. agent-bus/.gitignore already carried a literal $target/ entry — the symptom had been gitignored rather than fixed, which is how it accumulated invisibly.

Enhancements included in this import

Feature Purpose
--dry-run / -n Preview only, zero delete calls. Previously the tool deleted on sight with no preview.
--include-dirs Removes matching empty directories via RemoveDirectoryW, whose non-empty refusal is the safety mechanism. Never recursive.
Zero-byte content gate $null / $-prefixed files delete only at zero bytes by default; --allow-nonempty opts in and logs size + a 200-byte content preview.
--path-mangle Narrow ;<letter>[:] matcher, no regex dependency.
--dollar-prefix Leading-$ artifacts other than $null.
Composable families + --all Families combine; JSON reports deleted[] / would_delete[] / skipped[] with per-entry path, family, kind, reason, size.

Verification

  • cargo test21 passed, 0 failed
  • cargo clippy --all-targets -- -D warningsclean
  • cargo fmt --all -- --checkclean
  • dotnet build -c Release0 warnings, 0 errors
  • End-to-end: ran the built binary --all --include-dirs --dry-run against a fixture; $zeroByte and an empty mangled;C dir reported as would_delete, a non-empty $notEmpty/ and non-empty $hasContent correctly skipped, normal.txt untouched, and the fixture was byte-identical afterwards.

Known gaps (environment, not code)

  • Native AOT publish failsdotnet publish -r win-x64 --self-contained errors MSB3073 exit 123 with a mangled link.exe path resolving into VS "18 Insiders" MSVC. dotnet build -c Release compiles clean; the IL build is what was run-verified.
  • build.ps1 checks a hardcoded nuker_core\target\release\nuker_core.dll that does not match this machine's CargoTools-centralised T:\RustCache\cargo-target\release\. Pre-existing, unrelated to these changes.

Safety note for reviewers

vcpkg contains legitimate $-prefixed files — $cfghdrs_tup.in (jemalloc autotools) and $PLUGINSDIR (NSIS convention). The --dollar-prefix family keeps its content gate specifically so a sweep cannot destroy vendored build inputs. Do not relax that gate without adding a vendored-path skip list.

David-Martel and others added 10 commits August 6, 2026 10:32
NukeNul existed as an untracked source tree in C:\codedev with no version
control, putting the hybrid Rust/C# implementation at risk. Track sources
only; .gitignore already excludes bin/, obj/, target/, and native binaries.

Agent: claude
Co-authored-by: Claude <noreply@anthropic.com>
…e matching

Replaces the single-mode scan_and_delete engine with a new nuke_files_ex FFI
entry point that composes three independent match families (reserved device
names, literal $null, path-mangle artifacts ending in `;<letter>[:]`), adds
--dry-run/--include-dirs/--allow-nonempty semantics, and returns an auditable
JSON payload (deleted/would_delete/skipped, each with path/family/kind/reason
and, for non-empty $null files, size + a 200-byte content preview) instead of
bare counts. $null files now delete only when zero-byte by default, per the
workspace policy that discovery hooks may only remove zero-byte matches.

The legacy nuke_reserved_files/nuke_dollar_null_files symbols are preserved
(now implemented on top of the new engine) so the existing extern "C" ABI
keeps working for any other callers of nuker_core.dll.

16 new/updated unit tests cover the path-mangle regexless matcher, the
zero-byte gate, family composability, and the extended-path helpers.

Agent: claude
Co-authored-by: Claude <noreply@anthropic.com>
--dry-run was reporting every matched directory as a would-delete candidate
without checking whether RemoveDirectoryW would actually succeed. A directory
containing files (found via manual smoke-testing --all --include-dirs against
a populated sandbox) showed up under would_delete when it would really be
skipped as not-empty on a real run, making the preview inaccurate for exactly
the case --include-dirs exists to guard.

Adds dir_is_empty(), a lightweight std::fs::read_dir check that mirrors
RemoveDirectoryW's real behavior without attempting the delete, and routes
dry-run directory candidates through it so would_delete/skipped match what a
non-dry-run pass would actually do. Two new tests exercise it against real
scratch directories (empty and non-empty).

Agent: claude
Co-authored-by: Claude <noreply@anthropic.com>
…all flags

Rewrites Program.cs's CLI surface and P/Invoke layer to call the new
nuke_files_ex FFI entry point instead of the two single-mode legacy
functions. New flags: --reserved, --path-mangle, --all, --include-dirs,
--dry-run/-n, --allow-nonempty, composable with the existing
--dollar-null-only (which keeps its historical "only this family" behavior
when passed alone, per the family-default resolution documented in Main).

The engine's JSON (deleted/would_delete/skipped, each with path/family/kind/
reason/size/content_preview) is deserialized via new AOT-safe source-gen DTOs
(EngineOutput/EngineCounts/EngineActionEntry) and folded into the existing
top-level ScanResult shape, adding a top-level "dry_run" flag and per-entry
audit detail to "results" instead of bare counts. Root path is now marshaled
as UTF-8 (LPUTF8Str) rather than ANSI, and the returned JSON string is always
freed via nuke_free_string in a finally block.

Functionally smoke-tested end to end against a hand-built sandbox containing
a real reserved-name file (created via the same \\?\ extended-path mechanism
the tool itself relies on), zero- and non-empty $null files, and path-mangle
files/directories (including a non-empty one to confirm the not-empty skip
path): bare invocation, --dollar-null-only alone, --dollar-null-only
--path-mangle, --allow-nonempty, --dry-run --all --include-dirs, and error
paths (unknown flag, missing target) all produced the expected JSON and left
disk state exactly as reported. Native AOT publish could not be verified in
this environment (see PR/task notes) - this was exercised via `dotnet build`
+ direct execution of the resulting IL assembly against a freshly rebuilt
nuker_core.dll.

Agent: claude
Co-authored-by: Claude <noreply@anthropic.com>
…ior change

Adds the new CLI reference table, an example of the new auditable JSON shape
(deleted/would_delete/skipped entries with path/family/kind/reason/size/
content_preview), the new nuke_files_ex FFI signature, and a prominently
called-out "Behavior change" section explaining that --dollar-null-only now
deletes only zero-byte $null files by default (previously any size) per the
workspace's zero-byte discovery-hook policy. Updates Limitations and Future
Enhancements to match what shipped.

Agent: claude
Co-authored-by: Claude <noreply@anthropic.com>
The $null-only matcher was too narrow for the actual defect class. A live
sweep of C:\codedev on 2026-08-06 found four mangled directories the existing
matchers would have missed entirely -- $runDir, $out, $local and $archiveDir --
all produced by PowerShell variable names surviving into a bash context, the
same root cause as the $null files.

Adds a DollarPrefix family matching leaf names that start with '$' other than
'$null' itself, sharing the zero-byte content gate with the $null family since
both are stray shell-variable artifacts. Covered by unit tests, including one
asserting the family excludes '$null' and its lookalikes so the two families
stay disjoint.

nuker_core: 21 tests passing, clippy --all-targets -D warnings clean,
cargo fmt --check clean.

Known gap: Program.cs does not yet expose a --dollar-prefix flag, so this
family is reachable through the FFI but not from the CLI.

Agent: claude
Co-authored-by: Claude <noreply@anthropic.com>
Wires the DollarPrefix match family added in c369d3b through to the CLI so
it is reachable without going via the FFI directly. --dollar-prefix joins
--reserved, --dollar-null-only and --path-mangle as a composable family flag,
and is covered by --all.

The leading-$ family shares the zero-byte content gate with $null, so
--allow-nonempty governs both.

Verified: dotnet build -c Release succeeds with 0 warnings, 0 errors.
nuker_core: 21 tests passing, clippy --all-targets -D warnings clean.

Native-AOT publish remains blocked in this environment by an unrelated
VS-18-Insiders link.exe path-resolution failure (MSB3073 code 123); the
IL build is what was compile- and run-verified.

Agent: claude
Co-authored-by: Claude <noreply@anthropic.com>
Extends the CLI reference table, feature list, behavior-change notice,
NukeOptions struct listings (Rust + C#), and JSON entry schema description to
cover the leading-$ shell-variable-artifact family added in c369d3b/7b622b4,
and adds a usage example.

Agent: claude
Co-authored-by: Claude <noreply@anthropic.com>
Brings in the six-enhancement extension developed 2026-08-06:
--dry-run, --include-dirs (empty-only), zero-byte content gate with
--allow-nonempty, --path-mangle, --dollar-prefix, composable families,
and path-level auditable JSON output.

nuker_core: 21 tests passing, clippy -D warnings clean, fmt clean.
dotnet build -c Release: 0 warnings, 0 errors.

Agent: claude
Co-authored-by: Claude <noreply@anthropic.com>
…cebc63'

git-subtree-dir: Native/NukeNul
git-subtree-mainline: 2bb8fe0
git-subtree-split: 6765c50
Copilot AI lite review requested due to automatic review settings August 6, 2026 16:04
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

Copilot AI left a comment

Copy link
Copy Markdown

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.

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.

2 participants