Records the result of the tests-only round in the active context, the
progress, and Decision 21: 89 It blocks, 121 cases, the suite from 1,494
to 1,615 cases per configuration with no failure, 38 of 64 parameter
sets closed, 26 with a leftover, no defect; the round is on the branch
ai/tests-round-1 and has not run on the GitHub runner.
Adds to the debugging insights the helper that waited for a child that
never started: a test-name filter with spaces broke the nested quotes of
runas, which looked like a stall under load.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Adds the report of the tests-only round of the quality gate: 89 new It
blocks that run as 121 cases per configuration, so that the suite goes
from 1,494 to 1,615 cases per configuration with no failure in Windows
PowerShell 5.1 and PowerShell 7, elevated and as a basic user.
The ParameterSets CSV has the 64 rows with the status before and after:
38 are closed (7 before), 26 have something left (16 Limit, 7
MaintainerDecision, 3 would-pin), and the report names every leftover.
The Evidence CSV lists the files outside git with size and SHA-256.
No product code, cmdlet page, or CI file changes.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Adds 15 It blocks (25 instances, Tests\ParameterSets.Inheritance.Tests.ps1) closing the budget
items of worklist-inheritance.md rows 1-16:
- The documented no-op / current-location behavior without -Path, pinned with Push-Location into
a dedicated sandbox folder, for Disable/Enable-NTFSAccessInheritance, Disable/Enable-
NTFSAuditInheritance, Set-NTFSInheritance, Get-NTFSOwner, Set-NTFSOwner, and
Get-NTFSSecurityDescriptor.
- The OpenError category for a path that does not exist, for Disable/Enable-NTFSAccessInheritance
and Set-NTFSInheritance.
- Owner unchanged after Disable-NTFSAccessInheritance -SecurityDescriptor protects the DACL; an
independent Get-Acl -Audit oracle for Set-NTFSInheritance; the -RemoveInheritedAuditRules /
-RemoveExplicitAuditRules switches on a -SecurityDescriptor with the owner and DACL confirmed
unchanged after the write.
- The Name property and a DACL protected without the module for Get-NTFSInheritance (-Path and
-SecurityDescriptor); Get-NTFSOwner on a descriptor read without its Owner section; the SACL
unchanged after Set-NTFSOwner changes the owner; the DACL unchanged and the -PassThru type for
Set-NTFSOwner -SecurityDescriptor.
- The by-property-name pipeline and the category/target of the -PassThru ReadSecurityError for
Set-NTFSSecurityDescriptor.
Every assertion reads state with an independent .NET oracle (Get-Acl, Get-Acl -Audit) or asserts an
ErrorId/category/target triple; none repeats an existing test. Items marked Limit, would-pin, or
lab in the worklist are out of scope and untouched.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Points the comment at Move-Item2.md's -Force and Notes sections, which
document the overwrite as a replace, instead of only describing the probe
that showed it. No test logic changed.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Adds pipeline/positional binding, long-path, bracket/wildcard literal-path,
drive-root, omitted-path-default, and error category/target coverage for
Copy-Item2, Get-ChildItem2, Get-Item2, Move-Item2, Remove-Item2, Test-Path2,
Get-FileHash2, and Get-DiskSpace; positional binding, FileInfo pipeline input,
and share-error category coverage for New-NTFSHardLink and Get-NTFSHardLink;
positional binding and folder LinkType/target coverage for
New-NTFSSymbolicLink; and -PassThru privilege-state coverage for
Enable-Privileges and Disable-Privileges. No product code changed.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Add 20 new It blocks (32 executed cases once the 13-scope -ForEach of
Add-NTFSAccess/SDSimple expands) to ParameterSets.Access.Tests.ps1, closing
every REMAINING item that worklist-access.md marks budget for rows 1-13:
- Add-NTFSAccess: several accounts and positional binding (PathComplex); a
Deny entry's exact rights with no auto-added Synchronize (PathComplex and
PathSimple); a denied write and a Deny entry without rights through
PathSimple; all 13 -AppliesTo scopes of a security descriptor read back
with .NET, piped and several (SDSimple); piped and several descriptors
asserted for Add itself, not only as a fixture (SDComplex).
- Remove-NTFSAccess: the -PassThru output's count against the complete
survivor list for several piped paths; several accounts and positional
binding (PathComplex); a Deny entry's rights-reduction without
-RemoveSpecific; a missing and a denied path, piped, several (PathSimple);
rights-reduction without -RemoveSpecific and disk independence until
Set-NTFSSecurityDescriptor, piped and several descriptors (SDSimple); the
on-disk write-through only after Set-NTFSSecurityDescriptor, piped and
several descriptors (SDComplex).
- Get-NTFSAccess: what the cmdlet returns without -Path, asserted on an
actual emitted object's type (Path).
- Get-NTFSOrphanedAccess: the category of ReadSecurityError after a failed
ownership retry (Path); -ExcludeInherited and an entry added to a
descriptor only in memory (SD).
- Get-NTFSSimpleAccess: the category and target of a missing path's
ReadError (Path).
- Get-NTFSEffectiveAccess: one call combining a failing and a succeeding
path (Path).
Items the REASON marks MaintainerDecision, Limit, or would-pin are left
untouched, per the group notes of the brief. No product code changed.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Closes the eight remaining 'budget' parameter-set gaps that
Quality-Gate-Unknowns-2026-10-10-ParameterSets.csv lists for the audit
cmdlets, in Tests\ParameterSets.Audit.Tests.ps1 only:
- Add-NTFSAudit PathComplex: binds -Account (several accounts) and
-AuditFlags from a single piped object's property names in one call.
- Remove-NTFSAudit PathComplex: removes for several accounts named in one
call, and leaves the empty Audit SDDL and the DACL unchanged for an item
that has no SACL.
- Remove-NTFSAudit SDSimple and SDComplex: proves the item on disk keeps
its audit section until Set-NTFSSecurityDescriptor writes the change,
and that -PassThru returns FileSystemAuditRule2 objects for both sets.
- Clear-NTFSAudit Path: asserts the cleared state of the succeeding path
that follows a missing one in the same pipeline.
- Get-NTFSAudit SD: asserts the output's type, account, rights, flags, and
inherited state directly, independent of the Path set's output.
- Get-NTFSOrphanedAudit Path: adds the OpenError category of the
ReadSecurityError without the Security privilege (PermissionDenied needs
a remote/lab target and is not in scope), and -ExcludeExplicit.
- Get-NTFSOrphanedAudit SD: adds -Account and -ExcludeInherited/
-ExcludeExplicit filters against a piped security descriptor.
Every new test reads state back with an independent oracle (Get-Acl
-Audit or the .NET SACL-only accessor), and the Set-NTFSSecurityDescriptor
cases confirm the SD cmdlets change the item only in memory. The owner
retry after access denied (Limit) and the open maintainer item on
exceptions from the SD change itself (MaintainerDecision) are left out, as
the worklist directs.
9 new It blocks (10 executed cases; one is split SDSimple/SDComplex by
-ForEach) were verified test-first: a mutated copy with one flipped
expectation per new It failed only those 10 cases in the configurations
where they run, and nothing else; three repeated runs of the real file in
all four configurations (Windows PowerShell 5.1 and PowerShell 7, elevated
and basic user) gave identical, all-green results; and
Invoke-ScriptAnalyzer reports nothing, matching the base commit's file.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
rc8 is published (tag c719197, Gallery 2026-10-20 10:40:58Z) and accepted: the
identity check, three matrix cells 1,374/0/12, the suite in 24 runs, the first
lab 245/0/1 per edition, every end state CLEAN. The Memory Bank now says so in
the active context, the progress log, Decision 21, and the deployment notes
(with the published hashes, the chain script that ran the acceptance in 68
minutes, and the lesson that the saved lab machines restore cleanly in two
waves). The tech context points to where the helpers live, because TEMP was
cleaned once, and says that the list of published versions ends at rc7. The
debugging insights get the pattern of a swallowed initialization error, its
seam-free trigger (a computer name of 32,718 characters), and the warning that
came before the error.
The older state paragraphs of the active context shrink to make room.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
The published rc8 passed the identity check (tag, CI run, Gallery hash, GitHub
zip), the three cells of the operating-system matrix (1,374 passed, 0 failed,
12 skipped, every end state CLEAN), the module's own suite on six machine
classes (24 runs, 0 failed, the same skipped tests as the host), and the first
lab with case 9 (245 passed, 0 failed, 1 skipped per edition, CLEAN). The counts
of the live controller equal those of the published rc7, and the live tests and
the controller are the same Git blobs, so the cells measure the changed module.
The record also shows that the boundary of the new GetEffectiveAccessError, a
computer name of 32,718 characters, holds on Windows Server 2019, 2022, and
2025 and on Windows 11 26H1, which backs the wording of the CHANGELOG and the
cmdlet page.
The four tables follow the record of the published rc7. The README names the
record and says that saved machines are restored first, the domain controllers
before the others.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
The cmdlet page and the CHANGELOG said that Get-NTFSEffectiveAccess warns
that the result is based on this computer only when it returns a result. With
-ExcludeNoneAccessEntries, the cmdlet warns for an account without access and
returns nothing for it, so the text now says when it calculated a result. The
help file is regenerated with platyPS 0.14.2 and differs by that paragraph.
The tests of the documentation, the help, the wiki, the release, and the
manifest pass in Windows PowerShell 5.1 and PowerShell 7, as an administrator
and as a basic user.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Set the prerelease label to rc8 and add 5.0.0-rc7, which the PowerShell
Gallery has had since 2026-10-10, to the versions that the Gallery has
(Docs/Contributing/05-Releasing.md).
A separate commit, so that it can be dropped if the changes of this branch
go into another prerelease instead.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Get-NTFSHardLink and New-NTFSHardLink -PassThru combine the root of the path
that the caller gives with names that Windows reports relative to the root of
the real volume. When the two roots differ, such as for a drive that subst
made, Get-NTFSHardLink writes a FileNotFound error for a file that exists, and
New-NTFSHardLink -PassThru creates the link and then stops with a terminating
FileNotFoundException, so the links that follow in the pipeline aren't
created. The real path, and New-NTFSHardLink without -PassThru, work.
A fix needs the real volume root of the file and a decision about the names
that a mount point returns, which changes the output of two cmdlets. The cmdlet
pages and the CHANGELOG state the limit instead. A volume that is mounted into
a folder, and a junction or symbolic link to another volume, were not run and
are called probable.
Checked in Windows PowerShell 5.1 and PowerShell 7 with a substituted drive:
the five claims of the pages hold in both editions. The help file is
regenerated with platyPS 0.14.2 and differs by the two new paragraphs.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Get-NTFSEffectiveAccess returned no access and no error when Windows refused
to start the authorization manager for the computer of -ServerName.
Win32.GetEffectiveAccess ignored what the initialization threw (an outer
catch { }), so the result looked like an account without any rights. It
reproduces on Windows Server 2025 in both editions with a name of 32,718
characters or more, which fails with error 14, where a shorter name gets RPC
server unavailable and falls back to this computer.
One try/catch now records every exception, and the cmdlet writes a
GetEffectiveAccessError. The warning that the result is based on this computer
comes only with a result now: it also preceded an error, such as for an
account that Windows can't resolve when the computer can't be reached, which
the cmdlet page and the lab tests contradict.
Two tests failed first in Windows PowerShell 5.1 and PowerShell 7, as an
administrator and as a basic user, and pass in all four configurations. The
cmdlet page, the help file, and the CHANGELOG say what changed.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
After the merge of #125 and #124, the maintainer decided on 2026-10-19:
- Decision 21, "Closing the gate": rc8 is mandatory (master is ahead of rc7 by
the seven product files of #125, and stable is accepted through the last
prerelease); rc8 carries the fix of the false "no access" of
Get-NTFSEffectiveAccess, while the hard-link names under a root that is not
the volume root stay a known limit listed in the release notes; the plain
test gaps are closed in a tests-only round until 2026-11-02; the steps from
rc8 to the stable tag.
- Decision 22 accepted: all ten behavior changes of rc7, two of them breaking.
- Decision 23: option 3, a decision date of 2026-11-02; the gate for #34 stays
open, and no risk is accepted.
- Decision 24 accepted: the operating-system matrix as it is.
The decision index, the active context, and the progress file follow. The
oldest entries of the progress file are shortened to stay under the line
budget.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
- Decision 26: Add and Remove for access and audit declare no default
parameter set, what that changes for a piped object, and what stays silent
(a value that PowerShell cannot convert to a scope is ignored and the object
is handled as one without AppliesTo).
- Debugging insights: a piped property selects a parameter set only when the
cmdlet has no default set whose mandatory parameters the object satisfies;
PowerShell resets only the parameters that the previous piped object bound,
so a field that the cmdlet writes itself reaches the next object; probe the
route that the documentation shows and each form of a value, not the one
that you tried; a sentence about what a test proves is a claim too.
- Active context and progress: the state after the fix, three independent
reviews and two checks, the acceptance of the final package in the labs, and
the open items; the remaining-path inventory is that of 2112ee3.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
The report of Handoff 5 now tells what came after the final measurement of
61e936e:
- why a piped AppliesTo was dropped for a path (the default parameter set),
the fix (93ed2c7), the defect of that fix that the third independent review
found (the scope of a piped object reached the next one, 9783d2a), and the
corrections of what the documents said about empty and unconvertible
values (7bc7925, 2112ee3);
- three independent reviews and two checks of the third reviewer, with every
finding and its resolution, including the seven Minor findings of the
second check of 7bc7925 and of this report;
- the red and green runs of the tests, among them the runs of the tests of
the CSV route on the build before the fix and on 93ed2c7;
- the measurements of 9783d2a, 7bc7925, and 2112ee3 (1,492 cases per
configuration, 3,266 of 3,668 sequence points, the same 183 unvisited
methods) on the bytes of one build;
- the acceptance of the final package in the labs: the first lab (245, 0, 1
per edition), the unit suite on the three file servers and the client (16
configurations, 1,189 cases each), and the three cells of the matrix lab
(229, 0, 2 per edition), every end state clean; and the first start of the
cells, which did nothing because the command that I had given the
maintainer did not set the module path.
The Runs, Evidence, and ParameterSets tables are regenerated. The lines that
the ParameterSets table cites are mapped to the tests of 6143545.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
A cell of the matrix did nothing when the maintainer started
Run-MatrixSequence.ps1 with Start-Process powershell.exe from a PowerShell 7
session: Windows PowerShell 5.1 inherits the PSModulePath of PowerShell 7,
cannot load Microsoft.PowerShell.Utility from it, the script stops at its
first call of Get-FileHash, and a hidden window leaves no log. The README of
the lab kit now says to start the scripts in a Windows PowerShell window, or
from PowerShell 7 to set the module path to the three WindowsPowerShell
folders first.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
The follow-up review of 7bc7925 probed the sentence "an AppliesTo that is an
empty string or not the name of a scope is ignored, and the object gets the
default scope" and found it too narrow. What the cmdlets do, in both
editions, on the package of 9783d2a and on the package before the fix
(probe p-unconvertible-appliesto.ps1):
- A value that PowerShell cannot convert to a scope, such as the empty cell
of a CSV file or a misspelled name, is ignored, and the object is handled
as one without AppliesTo: it uses its own InheritanceFlags and
PropagationFlags, or the default scope when it has none. This is the same
before and after the fix.
- A row of a CSV file with fewer fields than its header gives $null, and a
$null AppliesTo fails to bind for that object.
- An object that has both Path and SecurityDescriptor now fails with
AmbiguousParameterSet; before, the path won and the descriptor was
ignored. No cmdlet of the module produces such an object.
The changelog entry, the four cmdlet pages, and the help file say so.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
The follow-up review of 7bc7925 found that the two rows added with the fix
of the piped AppliesTo (an object with AppliesTo and InheritanceFlags,
piped to Add-NTFSAudit and to Remove-NTFSAudit) said that they change
nothing but compared the DACL, which these cmdlets never write. The older
row of the named call to Add-NTFSAudit had the same title and the same
comparison. A rejected call fails while the parameters bind, before
ProcessRecord, so the error is the behavior under test.
The three rows now say and assert the error only. The rows of the access
cmdlets compare the DACL, which is what those cmdlets write, and stay as
they are. The focused run of the two ParameterSets files on the package of
9783d2a passes in the four configurations (89 cases; 88, 88, 53, 53 passed).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
The follow-up review of 9783d2a found that "an empty AppliesTo fails to
bind", in the changelog entry and in the four cmdlet pages, holds only for
$null. A blank cell that Import-Csv reads is an empty string, which the
binder cannot convert: PathSimple does not bind, and the row gets the
default scope, as an object without the property does. An AppliesTo that
is not the name of a scope is ignored the same way (probe
p-empty-appliesto.ps1, both editions, on the package of 9783d2a and on
the baseline). Only $null fails to bind, with
ParameterArgumentValidationErrorNullNotAllowed, for that object.
The pages, the help file, and the changelog entry now say so.
The tests of the CSV route read a CSV file with Import-Csv, the route
that the documentation shows, instead of ConvertFrom-Csv of strings,
which makes a trailing blank cell $null. They pin the blank cell as the
default scope and the $null object as a binding error for that object
only, with the other objects processed.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Independent review of 93ed2c7: ProcessRecord of Add-NTFSAccess,
Remove-NTFSAccess, Add-NTFSAudit, and Remove-NTFSAudit wrote the scope
that it converts from AppliesTo into the fields behind InheritanceFlags
and PropagationFlags. PowerShell resets only the parameters that the
previous piped object bound, so the next object that had no scope, or
only one flag, took the scope of the one before it: AppliesTo
ThisFolderOnly, then none gave None/None twice, and Remove left the
InheritOnly part of every entry. Without the default set (93ed2c7) a
piped path object with AppliesTo reaches that code; for a piped
-SecurityDescriptor object it was a defect of rc7 already.
The flags of a record are locals now. The loop of the two Remove
cmdlets converted the scope a second time into the same fields; the
locals make that redundant, so it is gone.
The tests pipe objects with and without a scope, a CSV file, and
descriptor objects into the four cmdlets: red on the build of 93ed2c7
(8 of 87 cases of the two files, in every elevated configuration; 4 in
the basic-user ones, where the audit rows skip), green on this build.
An empty AppliesTo cell fails to bind for that row only; a test pins it.
The Remove-NTFSAudit PathSimple row cannot tell the sets apart (its
entry is on a file), and its comment says so. Docs/Examples.md no longer
says that a scope is needed so that PowerShell can choose the parameter
set (true before 5.0.0 only); the changelog entry names the new errors.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Add-NTFSAccess, Remove-NTFSAccess, Add-NTFSAudit, and Remove-NTFSAudit
declared PathComplex as the default parameter set. An object that had
Path, Account, and AccessRights satisfied the mandatory parameters of
the default set, so PowerShell never tried PathSimple and the cmdlet
dropped the AppliesTo property of the object. Since 4b1abc9 made
-AppliesTo mandatory in the Simple sets, the default set is redundant
for every call that names its parameters, and it masked PathSimple for
the pipeline.
Without a default set, an object that has AppliesTo binds PathSimple,
one that has InheritanceFlags or PropagationFlags binds PathComplex, and
one that has neither binds PathComplex with the default scope. An
object that has AppliesTo and InheritanceFlags now fails with
AmbiguousParameterSet, like the same two named parameters. Named calls,
-SecurityDescriptor calls without AppliesTo, and the round trip
Get-NTFSAccess | Add-NTFSAccess keep their behavior.
The tests pipe objects of each shape and fail without the change. The
cmdlet pages and the help file follow the build.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
The tr-TR test reset the culture in its own finally block, so a cmdlet
that did not restore it, or that wrote an item inside the scope of the
invariant culture, would still pass. The test now reads the culture in
the next pipeline stage for each item and once more after the call.
Both mutations fail it: writing the item inside the scope, and leaving
the scope without restoring the culture.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
The maintainer decided on 2026-10-11 that Server Core, ARM64, a localized
operating system, and non-Windows file servers are not needed by the audience
of the tool. They leave the open items, the completion matrix, and the limits
of the report, and Decision 25 records the choice (Decision 23 and #34 are not
changed).
Open item 3 of the report now gives the cause of the dropped AppliesTo for a
path: the default parameter set PathComplex wins when a piped object satisfies
its mandatory parameters. A stand-alone model with the four sets and no default
binds PathSimple for an object with AppliesTo and keeps every named call; the
real cmdlets were not changed. debugging-insights.md keeps the lesson.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
activeContext, progress, and techContext carry the final measurement (61e936e,
built at 8a625c8), the acceptance of the final build, the open items for the
maintainer, and the rule that the branch summary of the coverage tool is not
read. systemPatterns names the culture-invariant matching of Get-ChildItem2
-Filter and the Get-Acl -Audit oracle. The new debugging-insights.md keeps the
recurring defect classes of the work: culture-sensitive comparisons (including
the ones inside AlphaFS), a test oracle that is wrong on a domain member, and a
piped AppliesTo property that a path drops.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
The final commit 61e936e was built once, at 8a625c8, and measured on those
bytes: 1,459 cases per configuration, 3,258 of 3,664 sequence points, 1,090 of
1,168 explicit branch points, and the same 187 unvisited methods, all
classified. The first lab accepts the final build (245 passed, 1 skipped per
edition), the 22 files of the matrix suite pass on Windows Server 2019, 2022,
and 2025 and on Windows 11 in 16 configurations, and both labs are clean.
The report adds the second culture defect that the independent review found
(Get-ChildItem2 -Filter in tr-TR), the review and how each finding was
resolved, the probe that tells which parameter set binds for a piped
AppliesTo, and the corrected description of the branch summary of the tool,
which adds one point per method and is not read. The Runs table lists every
run, the Evidence table hashes the evidence outside git, and the ParameterSets
table cites the lines of the final tests.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Items: the comparison of Get-Privileges with whoami compares the State only
where whoami prints the English words, because the column is localized. The
rows 'as an array with an empty element' of Copy-Item2 and Move-Item2 now pass
an array: a switch unrolls @(''), so they had passed the plain empty string. The
empty-path rows of both cmdlets run in a folder of their own, so that a guard
that regressed would copy or move an empty folder and not the sandbox into
itself.
Audit: a piped AppliesTo property does not select PathSimple, the default set
PathComplex binds and the property is dropped (a descriptor object does select
SDSimple), so the rows named PathSimple bound PathComplex. The PathSimple rows
of Add-NTFSAudit and Remove-NTFSAudit now name -AppliesTo and pipe the rest,
and the Add rows use a folder and assert the scope of the new entry (None, not
the default ContainerInherit and ObjectInherit). The descriptor rows assert the
entry in the descriptor and, after Set-NTFSSecurityDescriptor, on disk.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
The class has the parameter System, so a name that starts with System resolves
to the property inside it; the build of the previous commit failed with CS0120.
The scope uses global::System, like the rest of the file.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
The change of the previous commit was necessary but not enough. AlphaFS 2.2
also matches the filter: it builds a case-insensitive regular expression from
it that takes the culture of the thread when it is created. With tr-TR the
enumeration itself returned nothing for index* in a folder with Index.txt, in
both editions (Directory.EnumerateFileSystemEntries of AlphaFS returned an
empty list, .NET returned Index.txt), so the new test still failed on a build
that had the previous change alone.
The enumeration, that is the creation of the enumerator and every MoveNext, now
runs with the invariant culture, which is restored before an item reaches the
pipeline, so that no later command sees it. No other cmdlet passes a pattern of
the user to AlphaFS.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
With the culture of the thread tr-TR, the case-insensitive WildcardPattern that
compares each name with the filter treats I and i as different letters. The
enumeration had already matched the name without regard to the culture, so the
cmdlet dropped the items whose names differ from the filter in the case of an
I: -Filter 'index*' returned nothing for Index.txt, and -Filter '*.ini' did not
return SETTINGS.INI. Both editions. The independent review of the coverage
report found it; the scan of culture-sensitive calls had not listed
WildcardPattern.
The test sets the culture of the thread to tr-TR. On the previous build it
fails in the four configurations (3 of 134 cases of ItemCmdlets.Tests.ps1:
index*, *.ini, and *.INI; INDEX* is the control). The pattern is now
WildcardOptions.CultureInvariant.
The changelog entry of the identity comparison named the operator -eq, which
tr-TR never affected (probes on the previous build: -eq, -contains, and -in
return True for every case); it now names the method Equals.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
The report gets the section on the acceptance of the fixed build in the first
lab (both editions 245 passed, 0 failed, 1 skipped), the matching row of the
completion matrix, and the bullet of the summary. The Memory Bank carries the
Handoff 5 evidence, the coverage baselines and the live-coverage method.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Get-Acl -Audit reads the SACL together with the other sections. On a domain
member (Windows Server 2019, 2022, and 2025 of the operating-system matrix)
that read reports the SACL of an item without audit entries as protected from
inheritance, where the read of the SACL alone and Get-NTFSInheritance report
it as not protected (FileSystemSecurity2 documents the same difference).
The test 'Disable-NTFSAuditInheritance -SecurityDescriptor should take two
piped descriptors ...' asserted the on-disk flag of a fresh file with
Get-Acl -Audit, and failed in all six elevated configurations of the three
file servers. Diagnostic runs on 2019 and 2025 show both reads side by side.
Four more assertions read the flag of an item that ends without audit entries
and expect "protected"; there they could not tell a written flag from none.
The five assertions now read the SACL alone through .NET, as the module does.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Handoff 5: the coverage of rc7 (fa0701b), the live tests and a domain member, the judged matrix of the 64 parameter sets and the tests that it led to, the cultures, and the final commit. The tables are the unvisited methods, the cmdlets, the reconciliation, the parameter sets, the mutations, the roles of the live suite, the cultures, and the runs. The evidence table follows with the lab acceptance of the fixed build.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Run-MatrixLocalSuite.ps1 stages the behavior test files of the repository. Add the four ParameterSets files of the quality gate (access, audit, inheritance, items), so that the next acceptance proves them on every machine, in both editions, elevated and as a basic user.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
The analyzer flags -Algorithm MD5 as a broken hash algorithm. The test compares the output of Get-FileHash2 with Get-FileHash and uses no hash for security, so the algorithm comes from a variable, like the data of FileHash.Tests.ps1.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Close the TestNeeded gaps of judged-inheritance.csv for the inheritance,
owner, and security-descriptor cmdlets (Disable/Enable-NTFSAccessInheritance,
Disable/Enable-NTFSAuditInheritance, Get/Set-NTFSInheritance, Get/Set-NTFSOwner,
Get-NTFSSecurityDescriptor) in one new file, Tests\ParameterSets.Inheritance.Tests.ps1.
20 new It blocks (48 data rows) assert, in the matrix's priority order:
- State: independent Get-Acl/Get-Acl -Audit oracles for access and audit
inheritance transitions, the -RemoveInherited/-RemoveExplicit switches
with a -SecurityDescriptor, Set-NTFSInheritance setting both flags in one
call, and Set-NTFSOwner leaving the Access entries and group unchanged.
- Error: ErrorId/category/target triples for a denied write, a missing
path, a denied read, and a refused owner, each continuing to the next
item; RestoreOwnerError for the three Path cmdlets that protect or set
access inheritance, which had none before.
- Pipeline: every -Path and -SecurityDescriptor set that no existing test
piped, including the direct, named Get-NTFSOwner -SecurityDescriptor
call the scan could not classify, and the documented Set-NTFSInheritance
round trip.
No existing test file, helper, or production source changed. Validated
test-first (each new assertion checked for a real, failable precondition)
and proven with 10 one-statement C# mutations in a separate, discarded
worktree: 9 detected, 1 honestly undetected (ValueFromPipelineByPropertyName
alone still binds Get-ChildItem2 output through its native FullName
property, so removing ValueFromPipeline from -Path is invisible to an
object-only pipeline test). All four configurations (elevated/basic user x
Windows PowerShell 5.1/PowerShell 7) pass with zero failures; audit- and
Restore-privilege-dependent rows skip in basic user and run elevated.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Adds Tests/ParameterSets.Access.Tests.ps1, closing the TestNeeded rows of
paramsets/judged-access.csv for Add-NTFSAccess, Remove-NTFSAccess,
Clear-NTFSAccess, Get-NTFSAccess, Get-NTFSOrphanedAccess,
Get-NTFSSimpleAccess, and Get-NTFSEffectiveAccess: 20 new It blocks (26
executed cases) covering pipeline binding (ValueFromPipeline and
ValueFromPipelineByPropertyName, including positional file/folder objects),
-PassThru combined with one denied and one succeeding path, error
ErrorId/category/target for read and write failures, continuation after a
per-item error, state read back with .NET (not -PassThru/Get-NTFSAccess),
SecurityDescriptor-set pipelines and memory-vs-disk behavior, and the
declared output types and PathSimple/SDSimple vs PathComplex/SDComplex
parameter-set boundaries. No row with GapKind=MaintainerDecision is pinned:
the -SecurityDescriptor sets of Add/Remove keep their open per-item error
behavior untested either way.
Finding: a plain piped object with an AppliesTo property does not steer
Add-NTFSAccess/Remove-NTFSAccess to the PathSimple/SDSimple parameter set by
itself; PowerShell resolves the ambiguity to the default set (PathComplex/
SDComplex) and silently drops the unmatched property. The proposed test for
that exact shape (notes section (b), item 2c) could not be written as
specified; the pipeline test for PathSimple instead binds -Path through the
pipeline while -AppliesTo is named explicitly, which does select the set.
Validated in all four configurations (elevated/basic user, Windows
PowerShell 5.1/PowerShell 7): 26 passed, 0 failed, 0 skipped in each. Eight
one-statement production mutations across all seven cmdlets were applied in
an isolated worktree, built, and run against this file; each was detected by
at least one new test, then the source was restored exactly and rebuilt.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Add Tests\ParameterSets.Audit.Tests.ps1, closing the TestNeeded gaps that
judged-audit.csv/judged-audit-notes.md recorded for Add-NTFSAudit,
Remove-NTFSAudit, Clear-NTFSAudit, Get-NTFSAudit, and Get-NTFSOrphanedAudit:
- Pipeline binding by value and by property name for every parameter set of
all five cmdlets, including the four sets the matrix flagged as bound only
by splat or pipe calls (Add-NTFSAudit SDSimple, Remove-NTFSAudit PathSimple
and SDSimple, Get-NTFSOrphanedAudit SD), each of which also gets a direct,
named call.
- Continuation past a failing path or a descriptor without an audit section,
asserting the ErrorId, category, and target of the error and the state or
output of the item that follows.
- State assertions beyond -PassThru: SACL/DACL SDDL before and after, the
in-memory descriptor versus the item on disk until Set-NTFSSecurityDescriptor
writes it, and the protected/unprotected SACL after Clear-NTFSAudit
-DisableInheritance.
- Narrowing of an audit entry's rights when Remove-NTFSAudit runs without
-RemoveSpecific, and the AmbiguousParameterSet error when -AppliesTo and
-InheritanceFlags are combined.
No production code, existing test file, or helper module changed. Fixture
DACLs use .NET SetAccessControl through the existing TestHelpers.psm1
helpers; no test pins the open item of the -SecurityDescriptor sets of Add
and Remove having no per-item handler around the change itself.
Verified in all four configurations (elevated/basic user x Windows
PowerShell 5.1/PowerShell 7): 0 failures. Mutation-tested with 9 one-statement
changes to the production C# in a separate, detached worktree; 8 were caught
by the new tests and one (the -AppliesTo-to-flags conversion for the Simple
sets, masked on a file target) was not, which the pre-existing
PermissionScopes.Tests.ps1 already catches on a folder target.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Add Tests\ParameterSets.Items.Tests.ps1, closing TestNeeded gaps the judged
parameter-set matrix found for Copy-Item2, Get-ChildItem2, Get-Item2,
Move-Item2, Remove-Item2, Test-Path2, Get-FileHash2, Get-DiskSpace,
New-NTFSHardLink, Get-NTFSHardLink, New-NTFSSymbolicLink, Enable-Privileges,
Disable-Privileges, and Get-Privileges:
- Pipeline input by value for Copy-Item2, Move-Item2, Get-ChildItem2,
Get-Item2, and Remove-Item2 (never exercised before), including
continuation past a missing item and AlphaFS objects piped from
Get-ChildItem2.
- An empty string, $null, a piped empty string, or an empty array element
for -Path/-Target is rejected by ValidateNotNullOrEmpty and never falls
back to the current location, for Copy-Item2, Move-Item2, Remove-Item2,
New-NTFSHardLink, and New-NTFSSymbolicLink. Verified by running against
the built module in both PowerShell editions before being pinned.
- Get-NTFSHardLink error categories, output type, and positional binding.
- Pipeline continuation (Select-Object -First 1) for New-NTFSHardLink and
New-NTFSSymbolicLink, and a successful link after an earlier failure in
the same New-NTFSSymbolicLink call.
- Enable-Privileges and Disable-Privileges error paths (SecurityError,
Security2.AdjustPriviledgeException), runnable on any token.
- Get-DiskSpace with a valid and an invalid drive letter together in either
order, and positional/lower-case binding.
- Get-Privileges compared against whoami /priv for the five privileges
that both name the same way.
- Get-FileHash2 pipeline objects with -Algorithm, and a locked path before
a valid one with its error category and a relative-path hash.
Every It asserts persisted state, an ErrorId/category/target, continuation,
or an output type; none asserts only an English message. All four runtime
configurations (elevated/basic user x Windows PowerShell 5.1/PowerShell 7)
pass with 0 failures; two symbolic-link-privilege-gated tests skip on the
basic-user configurations and run on both elevated ones. Mutation testing
against 8 one-statement changes in a separate, discarded worktree confirmed
each targeted test fails for the right reason; production sources were
restored exactly after every mutation and no production code changed here.
Does not pin the Get-ChildItem2 -Filter dot rules, the Decision 22 link and
move/copy behaviors, the PrivilegeEnabler class, or the owner-restore
handlers. A probe of Get-NTFSHardLink and New-NTFSHardLink -PassThru
through a subst-mapped drive found a pre-existing defect (reported
separately, not fixed or pinned here): both combine the apparent drive
root with the volume-relative hard-link names from Windows, which throws
FileNotFoundException once the drive's root differs from the real NTFS
volume root.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
IdentityReference2.Equals(string) lowercased both names with ToLower(), which uses the
culture of the thread. In tr-TR, I becomes U+0131, so an account whose name holds an
uppercase I (NT AUTHORITY\SYSTEM, BUILTIN\Administrators) no longer matched the same name in
another case, for example $entry.Account -eq 'nt authority\system'. Compare with
StringComparison.OrdinalIgnoreCase.
The test sets the culture of the thread to tr-TR and compares the system account with its name
in three cases. Before the fix it fails in all four configurations (elevated and basic user,
Windows PowerShell 5.1 and PowerShell 7); after it, all rows pass. The unit suite under tr-TR
did not find it, because no test compares a name that holds an uppercase I.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
The unit tests reach all 36 cmdlets and all 147 documented parameters,
and the live tests reach 34 of the cmdlets. The coverage that was
measured at 5a5d58b is 87.84% of the sequence points; the unvisited
code is classified, and 158 of its 442 points are reachable but
defensive or environment-specific. The coverage of the live tests and of
the suite on a domain member is not measured.
Record what is measured, what is not, and the two optional measurements
that would close the gaps.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
The manifest was refreshed after the final log line and the exit file
were added, so a fixed count in the record would be wrong.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>