diff --git a/Tests/Coverage/Quality-Gate-Test-Round-2026-10-20-Evidence.csv b/Tests/Coverage/Quality-Gate-Test-Round-2026-10-20-Evidence.csv new file mode 100644 index 0000000..e544efc --- /dev/null +++ b/Tests/Coverage/Quality-Gate-Test-Round-2026-10-20-Evidence.csv @@ -0,0 +1,71 @@ +"Path","Bytes","Sha256" +"round1\access\commit-diff.txt","34024","A3C896BBCBEE3A647621641160901BD8D5D7A99B51C828DAB7BA362474634348" +"round1\access\Run-Configuration.ps1","790","0C7E8394C041DCFA184ED73E43F75EB507BF6349D1DC2F6F55BF65BB4C59EF80" +"round1\access\source-pin.txt","42","770F2639B486ACC92430CE8C57A94A7E32706A050B0FBEAF369A73AB9B02F1FA" +"round1\audit\Run-Configuration.ps1","790","0C7E8394C041DCFA184ED73E43F75EB507BF6349D1DC2F6F55BF65BB4C59EF80" +"round1\audit\source-pin.txt","42","770F2639B486ACC92430CE8C57A94A7E32706A050B0FBEAF369A73AB9B02F1FA" +"round1\IMPLEMENTER-BRIEF.md","9366","55F78935F9E86BF47382574D25A144A791828E376C0C372B5775442E979D5066" +"round1\inheritance\commit-diff.txt","19909","B3A692CC065DB21264F03D15E7235F16E31F8AAC9E77BEBAA52A7176053DD851" +"round1\inheritance\Run-Configuration.ps1","790","0C7E8394C041DCFA184ED73E43F75EB507BF6349D1DC2F6F55BF65BB4C59EF80" +"round1\inheritance\source-pin.txt","42","770F2639B486ACC92430CE8C57A94A7E32706A050B0FBEAF369A73AB9B02F1FA" +"round1\items\commit-diff.txt","44797","F6917B0C3EF401E912E839200E00469591ADED382864AB18AE6EC625DF91FFE5" +"round1\items\Run-Configuration.ps1","790","0C7E8394C041DCFA184ED73E43F75EB507BF6349D1DC2F6F55BF65BB4C59EF80" +"round1\items\source-pin.txt","42","770F2639B486ACC92430CE8C57A94A7E32706A050B0FBEAF369A73AB9B02F1FA" +"round1\reports\report-access.md","6276","846716AE313AFC1E7FDED5C18DB0E2F80696EDFBBD8CED610AB82E9C125B3D13" +"round1\reports\report-audit.md","3947","65A985538611285DD1E2F1BDF746202B0179C605E784E0DA4DB3A28D9A1785B4" +"round1\reports\report-inheritance.md","3844","2A7F0957303F85FCC98FB88EC018A27B3225A7E68671B54554DE831DC3874176" +"round1\reports\report-items.md","6340","BE637FF086957BD39F64A255A10EF7C348631C22748F11A72AAB98B2A16D5B34" +"round1\suite\delta-four-vs-baseline.txt","23778","F61CE9884D911EDEED17AD9D167FA9FF2A006DCE092CF0AB5DE8C4B740321E34" +"round1\suite\rc8suite-20261020-093109\basic-Core-summary.md","150","937D42060174BCAF155579CF13C4A54962BE5CCA247585807470041D6FBEEF33" +"round1\suite\rc8suite-20261020-093109\basic-Core.log","206918","631DE1955CF31FC21F4C4DDFC9F6DBCFDA4F38630EEB97D4DE0A0F5F72A7DBB8" +"round1\suite\rc8suite-20261020-093109\basic-Core.xml","687469","DDF641D20A51C4CC799B58077E09B1C43A8570AF19C9A50E450335495127D17A" +"round1\suite\rc8suite-20261020-093109\basic-Desktop-summary.md","153","035C555E8D942092D7E5CAC4E62C0409A09D79903E6C14D45DCC7F2EC24955EE" +"round1\suite\rc8suite-20261020-093109\basic-Desktop.log","202259","9B71B28B124FB19C1C40287B54E4362550C0595638AFA7529CEB584000A527D5" +"round1\suite\rc8suite-20261020-093109\basic-Desktop.xml","687457","F6B826458A38E632912EC0F1AD1C23D215868E733850E109FFC5BFFD12E629AA" +"round1\suite\rc8suite-20261020-093109\driver.log","807","5429FCF0357252AE5AA69E710C9AE84BFC4C6299A11DFB87F98C1503E6D8BA6A" +"round1\suite\rc8suite-20261020-093109\elevated-Core-summary.md","152","673EFCBF03E5999462903567AD47AF4B26BA6062C3BD45A47CD18BB1CDF1844C" +"round1\suite\rc8suite-20261020-093109\elevated-Core.log","210466","A73178F81F7F42468C8BD6BA27EFB7CC6350604C9C01EFF2EE721BCD494EF627" +"round1\suite\rc8suite-20261020-093109\elevated-Core.xml","674273","04B0D4A7DB2D1251900D26E0853130CC586A00D5EFCF2E4B523C508E2AFA396B" +"round1\suite\rc8suite-20261020-093109\elevated-Desktop-summary.md","155","0BFBB63374A3B3E34AC5A460BBA47538FB30B391631B7CB221BE4A0EC09663AE" +"round1\suite\rc8suite-20261020-093109\elevated-Desktop.log","205681","DCF221A80D16FB8F9DB32E9CD50148E26CB4E6A880AA2399B2E53FA5EA5A8371" +"round1\suite\rc8suite-20261020-093109\elevated-Desktop.xml","674209","F877226807362A96058478928DBAE8EF42788347A1E89CA7A8DE683EEC5EA1BE" +"round1\suite\round1-four-20261020-142909\basic-Core-summary.md","150","829CED285CFB1647BCD4C062CD8A382C2D4FC4F0FB26D387F15FA0AB8D451E80" +"round1\suite\round1-four-20261020-142909\basic-Core.log","228078","11D26E7B9BBE3916BE1DD36F89ED61612EBAA9A59EBE0562246CC3D54BF0FF6F" +"round1\suite\round1-four-20261020-142909\basic-Core.xml","757177","B163017A9E2698BCE44BAA7AAA6342289DC357EBF81DFD9D7C89FCF98FB6BA81" +"round1\suite\round1-four-20261020-142909\basic-Desktop-summary.md","153","BA62973E006C65CA33B6C06CC7959EB987E56E70716E64CF46CEAB7B4235BEBD" +"round1\suite\round1-four-20261020-142909\basic-Desktop.log","223489","3A9702207D84749428AB3EF73DC534D9A97AFA5B53DF774ECAA0B65A44D40ABF" +"round1\suite\round1-four-20261020-142909\basic-Desktop.xml","757159","40D4DDA8902C47356CF79C20A113ED9A10159906DC97F357012656B0CE7176CC" +"round1\suite\round1-four-20261020-142909\driver.log","813","E38C08218416F558878F334C3783E7F21E11FDF079F3925211558232E5EA1487" +"round1\suite\round1-four-20261020-142909\elevated-Core-summary.md","152","DA662B842A82A70C3208D9B84007450C04EC79CB1FBCCC45B858BD32A8633AE8" +"round1\suite\round1-four-20261020-142909\elevated-Core.log","231606","844FBE7F8F525B642BB53D904E0FEF837D86BB00CE264C0262C9FBEDC2909433" +"round1\suite\round1-four-20261020-142909\elevated-Core.xml","743554","CB186B76C368DFE6406464418D8D96A5FD7431FB76900989EED9296C8EF6DDD8" +"round1\suite\round1-four-20261020-142909\elevated-Desktop-summary.md","155","91CBE39CDBCEB88C46D3F520951C146BE88B42471D2EC4FFC0E7D50735E2E575" +"round1\suite\round1-four-20261020-142909\elevated-Desktop.log","226871","E10752CDF65F39FB788F3628715B82060A90E8703BE76D0719B79D4BE334F990" +"round1\suite\round1-four-20261020-142909\elevated-Desktop.xml","743500","C2D2C2F0E41EECDC99B23A7C08EF5BA839A57704D21374732A4A4F4213C68017" +"round1\suite\round1-three-20261020-141224\basic-Core-summary.md","150","17E28A3615C92DF659CE87818D685E62427523D214B825C115CD26B480C1FB3A" +"round1\suite\round1-three-20261020-141224\basic-Core.log","223236","D17FA2C0736B858A5091DDEE20030780E90761769902F0A5E05FE28D07540A69" +"round1\suite\round1-three-20261020-141224\basic-Core.xml","740324","0F184A9E7558675A4C6BCA53BB47E0C107C90F153440D3E9129744AD924B8011" +"round1\suite\round1-three-20261020-141224\basic-Desktop-summary.md","153","AD762C7E8820A7BE7D63A5E8E946F369E9CDCBC89AF65936C0C619A7BD7E01F1" +"round1\suite\round1-three-20261020-141224\basic-Desktop.log","218670","33DFF2FCD2E39764BEA73D28749AAD411974766460625AAF4CCAAF64BFD2B3C0" +"round1\suite\round1-three-20261020-141224\basic-Desktop.xml","740333","68555C14A0C8750EDF40548808C857F9904CB96D2D190125CE24B2FB78C8A557" +"round1\suite\round1-three-20261020-141224\driver.log","815","963EE2B5522054245B524D911887FB61A6923E0078CD3C6F64C3FFD30A5AF3FB" +"round1\suite\round1-three-20261020-141224\elevated-Core-summary.md","152","74AFDE9B42E11C15290750FB5AF2F3EA2E14C07899334B5B033EFFA073201484" +"round1\suite\round1-three-20261020-141224\elevated-Core.log","226943","5ECEA749651F57FC35B1BBFA4F39941B255DC32417EE1868FBAECCA3FEF5DEB9" +"round1\suite\round1-three-20261020-141224\elevated-Core.xml","727012","1EE6DB5535A0AB681C5C5FC576FC79283C36FF9F5C22A78EBF38785B83D76FE0" +"round1\suite\round1-three-20261020-141224\elevated-Desktop-summary.md","155","3304B0A67528DEB418424848E623401B0B69E35FD289CF0A9763FA048B552A21" +"round1\suite\round1-three-20261020-141224\elevated-Desktop.log","222407","F171888AEE1BCA0719987878B730A6CAAE658BA69B0FCBC0C4CC6D0AEF0F30B5" +"round1\suite\round1-three-20261020-141224\elevated-Desktop.xml","726954","46DC96B84FD78F89313E62BC4701E644396384D203EA9E93DDC66CDAEEBD57C9" +"round1\tables-draft\Quality-Gate-Test-Round-2026-10-20-ParameterSets.csv","21329","2F08E25C342A84B59F48073A3B319231C9EE3D4C8534859A69F0D675E58EFE6F" +"round1\worklist-access.md","17983","4EDD989E5BF768D55EEE0E4516D474B18BB88AE2815D8D4DBEA62C50EDF323C4" +"round1\worklist-audit.md","10359","89EC64925D8967155702BA8142893DB358238CA37D612E34D70CD468C3DFF995" +"round1\worklist-inheritance.md","21757","6E63991DBB5EBD23D224BE49527934D6100C637AA47779D1011519C3A2AEB28B" +"round1\worklist-items.md","21105","F75D51717D2E58BCD6AE1D6CB8E016B911F656900704EDE491719C1506F77D42" +"scripts\Build-RoundTables.ps1","13770","74B872588366710E4B19A5E75C8495EE769935BD59CE334FFBE7AA6D431F53A8" +"scripts\Build-Worklists.ps1","3205","F431154F04CE7E914261F9EC407A7E8A2E98B2C96FDD16782EA4FD9195636B2E" +"scripts\Invoke-Build.ps1","1405","80EFE654633A72259F9F16105679B5C1E16937AA2E56B7C9A0FDE08E22FDDDC3" +"scripts\Invoke-RoundJob.ps1","4294","B6BDB86E2700CC5BE227B2810DD788AFBA8D16E944CD2600F5D9C16E873F6C0A" +"scripts\Measure-RoundSuiteDelta.ps1","3646","4728FD11D2FBBE483E5116BDBFF194638F0B4C9BB7110423F6EB4CB0BCBF90E9" +"scripts\Run-CiConfiguration.ps1","886","76D0EADA53B289D8E2A144748467EC8025C0A0A9F14AC8F133219AE823A3ACB4" +"scripts\Run-FocusedPester.ps1","2742","123E771081872881ECF2043E67B71896F518C2DDEBB15C5A1099912E0BE2685C" +"scripts\Run-FullSuite.ps1","4203","79F7E8484130A59CA9BEA87AAD39585E317A0276F35E791E90F25C2D226F27E9" +"scripts\Start-FocusedRuns.ps1","4735","0F9FB2247940BB94AB03BCB536CA4E747A73716DD96DB9FB34BD34FF2DA30620" diff --git a/Tests/Coverage/Quality-Gate-Test-Round-2026-10-20-ParameterSets.csv b/Tests/Coverage/Quality-Gate-Test-Round-2026-10-20-ParameterSets.csv new file mode 100644 index 0000000..d56a8e9 --- /dev/null +++ b/Tests/Coverage/Quality-Gate-Test-Round-2026-10-20-ParameterSets.csv @@ -0,0 +1,65 @@ +"Group","Cmdlet","ParameterSet","StatusBefore","StatusAfter","NewTestCount","NewTests","LeftKind","Left" +"access","Add-NTFSAccess","PathComplex","Partly","Closed","2","ParameterSets.Access.Tests.ps1:288 Should add an explicit allow entry for each of several accounts bound positionally, with the default scope | ParameterSets.Access.Tests.ps1:306 Should write a Deny entry through -Path with exactly the requested rights and no Synchronize","","" +"access","Add-NTFSAccess","PathSimple","Partly","Closed","3","ParameterSets.Access.Tests.ps1:329 Should report AddAceError by category and target for a denied write scoped by -AppliesTo, and leave the item unchanged | ParameterSets.Access.Tests.ps1:345 Should write an AddAceError for a Deny entry without rights through the PathSimple set, and change nothing | ParameterSets.Access.Tests.ps1:358 Should write a Deny entry scoped by -AppliesTo with exactly the requested rights and no Synchronize","","" +"access","Add-NTFSAccess","SDSimple","MaintainerDecision","MaintainerDecision","1","ParameterSets.Access.Tests.ps1:374 Should add an entry with the scope to each of several descriptors bound through the pipeline, read back with .NET, and leave the items unchanged on disk","MaintainerDecision","MaintainerDecision: the terminating error of a failing change (a deny entry without rights) is not pinned" +"access","Add-NTFSAccess","SDComplex","MaintainerDecision","MaintainerDecision","1","ParameterSets.Access.Tests.ps1:396 Should add the entry to each of several descriptors bound through the pipeline, read back with .NET, and leave the items unchanged on disk","MaintainerDecision","MaintainerDecision: the terminating error of a failing descriptor is not pinned" +"access","Remove-NTFSAccess","PathComplex","Partly","Closed","2","ParameterSets.Access.Tests.ps1:539 Should return exactly the surviving entries with -PassThru for each of several paths bound through the pipeline in one call | ParameterSets.Access.Tests.ps1:567 Should remove the entries of several accounts bound positionally, leaving another account untouched","","" +"access","Remove-NTFSAccess","PathSimple","Partly","Closed","2","ParameterSets.Access.Tests.ps1:592 Should take only the requested rights from a Deny entry scoped by -AppliesTo without -RemoveSpecific, and keep its flags | ParameterSets.Access.Tests.ps1:608 Should report a missing path's and a denied path's errors by category and target, and still scope the surviving paths' entries, all bound through the pipeline","","" +"access","Remove-NTFSAccess","SDSimple","MaintainerDecision","MaintainerDecision","2","ParameterSets.Access.Tests.ps1:644 Should take only the requested rights from an entry scoped by -AppliesTo on a descriptor without -RemoveSpecific, keep its flags, and leave the item on disk unchanged until Set-NTFSSecurityDescriptor | ParameterSets.Access.Tests.ps1:669 Should remove the matching entry from each of several descriptors bound through the pipeline for the Simple parameter set, leaving the items unchanged on disk","MaintainerDecision","MaintainerDecision: the terminating error of a failing removal is not pinned" +"access","Remove-NTFSAccess","SDComplex","MaintainerDecision","MaintainerDecision","2","ParameterSets.Access.Tests.ps1:693 Should remove an on-disk entry from a descriptor in memory only, and write the change through only when Set-NTFSSecurityDescriptor runs | ParameterSets.Access.Tests.ps1:711 Should remove the matching entry from each of several descriptors bound through the pipeline for the Complex parameter set, leaving the items unchanged on disk","MaintainerDecision","MaintainerDecision: the terminating error of a failing removal is not pinned" +"access","Clear-NTFSAccess","Path","Closed","Closed","0","","","" +"access","Clear-NTFSAccess","SD","Closed","Closed","0","","","" +"access","Get-NTFSAccess","Path","Partly","Partly","1","ParameterSets.Access.Tests.ps1:865 Should return the entries of the current location as actual Security2.FileSystemAccessRule2 objects when -Path is omitted","would-pin","would-pin: the category of the ReadSecurityError after a failed ownership retry (WriteError there, OpenError from the generic catch) is not asserted, so as not to cement the inconsistency" +"access","Get-NTFSAccess","SD","Partly","Partly","0","","Limit","no failing descriptor is tested for this set (no per-item handler)" +"access","Get-NTFSOrphanedAccess","Path","Partly","Partly","1","ParameterSets.Access.Tests.ps1:977 Should write a ReadSecurityError categorized as ReadError after a failed ownership retry, and still return the next path's orphaned entry","would-pin","would-pin: the choice of a warning, not an error, for a read failure other than access denied" +"access","Get-NTFSOrphanedAccess","SD","Partly","Closed","1","ParameterSets.Access.Tests.ps1:1021 Should return the explicit entry with -ExcludeInherited and still report an entry added to the descriptor only in memory","","" +"access","Get-NTFSSimpleAccess","Path","Partly","Closed","1","ParameterSets.Access.Tests.ps1:1077 Should report a missing path's error by category and target and still report the next folder's entries","","" +"access","Get-NTFSSimpleAccess","SD","Partly","Partly","0","","Limit","no failing descriptor is tested for this set (no per-item handler)" +"access","Get-NTFSEffectiveAccess","Path","Partly","Partly","1","ParameterSets.Access.Tests.ps1:1149 Should write nothing for a missing path and only the succeeding path's result in the same call","Limit","Limit: the ReadEffectivePermissionError handler is unreachable (the library records the failure); remote and group-based results need the lab (the live tests cover them)" +"access","Get-NTFSEffectiveAccess","SecurityDescriptor","Partly","Partly","0","","Limit","a mix of a failing and a succeeding descriptor in one call" +"audit","Add-NTFSAudit","PathComplex","Partly","Partly","1","ParameterSets.Audit.Tests.ps1:163 Should add one audit entry for each account that the piped object names, with the AuditFlags it also names","Limit","Limit: the owner retry after access denied needs a lab or a remote server" +"audit","Add-NTFSAudit","PathSimple","Closed","Closed","0","","","" +"audit","Add-NTFSAudit","SDSimple","Partly","Partly","0","","MaintainerDecision","exceptions from the change itself (open item 1)" +"audit","Add-NTFSAudit","SDComplex","Partly","Partly","0","","MaintainerDecision","exceptions from the change itself (open item 1)" +"audit","Remove-NTFSAudit","PathComplex","Partly","Partly","2","ParameterSets.Audit.Tests.ps1:501 Should remove the audit entry of each account that -Account names in one call, and leave another account alone | ParameterSets.Audit.Tests.ps1:524 Should leave the empty Audit SDDL and the DACL unchanged","Limit","Limit: the owner retry after access denied needs a lab or a remote server" +"audit","Remove-NTFSAudit","PathSimple","Closed","Closed","0","","","" +"audit","Remove-NTFSAudit","SDSimple","Partly","Closed","1","ParameterSets.Audit.Tests.ps1:577 Should remove the entry from the descriptor only in memory, until Set-NTFSSecurityDescriptor writes it, and return audit rule objects with -PassThru","","" +"audit","Remove-NTFSAudit","SDComplex","Partly","MaintainerDecision","1","ParameterSets.Audit.Tests.ps1:577 Should remove the entry from the descriptor only in memory, until Set-NTFSSecurityDescriptor writes it, and return audit rule objects with -PassThru","MaintainerDecision","MaintainerDecision: exceptions from the change itself (open item 1 of the report of Handoff 5)" +"audit","Clear-NTFSAudit","Path","Partly","Partly","1","ParameterSets.Audit.Tests.ps1:626 Should clear the audit entries of the path that follows a missing one, and write only a ReadFileError for the missing one","Limit","Limit: the owner retry after access denied needs a lab or a remote server" +"audit","Clear-NTFSAudit","SD","Closed","Closed","0","","","" +"audit","Get-NTFSAudit","Path","Partly","Partly","0","","Limit","the PermissionDenied category branch of ReadSecurityError" +"audit","Get-NTFSAudit","SD","Partly","Closed","1","ParameterSets.Audit.Tests.ps1:777 Should return the entries of a security descriptor with the expected type, account, rights, flags, and inherited state","","" +"audit","Get-NTFSOrphanedAudit","Path","Partly","Closed","2","ParameterSets.Audit.Tests.ps1:823 Should write a ReadSecurityError with category OpenError and the path as target | ParameterSets.Audit.Tests.ps1:837 Should return only the inherited orphaned entry with -ExcludeExplicit","","" +"audit","Get-NTFSOrphanedAudit","SD","Partly","Closed","1","ParameterSets.Audit.Tests.ps1:895 Should filter the orphaned entries of a piped descriptor by -Account, -ExcludeExplicit, and -ExcludeInherited","","" +"inheritance","Disable-NTFSAccessInheritance","Path","Partly","Closed","2","ParameterSets.Inheritance.Tests.ps1:804 should do nothing without -Path, not even to the current location | ParameterSets.Inheritance.Tests.ps1:880 should report ReadFileError with category OpenError for a path that does not exist, and continue with the next path","","" +"inheritance","Disable-NTFSAccessInheritance","SecurityDescriptor","Partly","Closed","1","ParameterSets.Inheritance.Tests.ps1:897 Disable-NTFSAccessInheritance -SecurityDescriptor should leave the owner unchanged once Set-NTFSSecurityDescriptor writes the protected DACL","","" +"inheritance","Enable-NTFSAccessInheritance","Path","Partly","Closed","2","ParameterSets.Inheritance.Tests.ps1:804 should do nothing without -Path, not even to the current location | ParameterSets.Inheritance.Tests.ps1:880 should report ReadFileError with category OpenError for a path that does not exist, and continue with the next path","","" +"inheritance","Enable-NTFSAccessInheritance","SecurityDescriptor","Closed","Closed","0","","","" +"inheritance","Disable-NTFSAuditInheritance","Path","Partly","Partly","1","ParameterSets.Inheritance.Tests.ps1:804 should do nothing without -Path, not even to the current location","Limit","Limit: a successful ownership retry or RestoreOwnerError of a SACL write needs a lab or a remote server" +"inheritance","Disable-NTFSAuditInheritance","SecurityDescriptor","Partly","Closed","1","ParameterSets.Inheritance.Tests.ps1:940 -SecurityDescriptor should change the in-memory audit entries per -:, applied to the item only after Set-NTFSSecurityDescriptor writes it, leaving the owner and DACL unchanged","","" +"inheritance","Enable-NTFSAuditInheritance","Path","Partly","Partly","1","ParameterSets.Inheritance.Tests.ps1:804 should do nothing without -Path, not even to the current location","Limit","Limit: a successful ownership retry or RestoreOwnerError of a SACL write needs a lab or a remote server" +"inheritance","Enable-NTFSAuditInheritance","SecurityDescriptor","Partly","Closed","1","ParameterSets.Inheritance.Tests.ps1:940 -SecurityDescriptor should change the in-memory audit entries per -:, applied to the item only after Set-NTFSSecurityDescriptor writes it, leaving the owner and DACL unchanged","","" +"inheritance","Get-NTFSInheritance","Path","Partly","Partly","2","ParameterSets.Inheritance.Tests.ps1:860 should report the current location when no -Path is given, not an empty result | ParameterSets.Inheritance.Tests.ps1:982 Get-NTFSInheritance should name the item in the Name property and report a DACL protected without the module","Limit","Limit: a successful ownership-retry read needs a lab or a remote server" +"inheritance","Get-NTFSInheritance","SecurityDescriptor","Partly","Closed","1","ParameterSets.Inheritance.Tests.ps1:993 Get-NTFSInheritance -SecurityDescriptor should return a typed object for a descriptor protected without the module","","" +"inheritance","Set-NTFSInheritance","Path","Partly","Closed","3","ParameterSets.Inheritance.Tests.ps1:804 should do nothing without -Path, not even to the current location | ParameterSets.Inheritance.Tests.ps1:880 should report ReadFileError with category OpenError for a path that does not exist, and continue with the next path | ParameterSets.Inheritance.Tests.ps1:914 Set-NTFSInheritance should set the SACL protected flag and audit-rule counts for enabled=, read independently with Get-Acl -Audit","","" +"inheritance","Set-NTFSInheritance","SecurityDescriptor","Closed","Closed","0","","","" +"inheritance","Get-NTFSOwner","Path","Partly","Closed","1","ParameterSets.Inheritance.Tests.ps1:846 Get-NTFSOwner should return nothing without -Path, not even for the current location","","" +"inheritance","Get-NTFSOwner","SecurityDescriptor","Partly","Closed","1","ParameterSets.Inheritance.Tests.ps1:1004 Get-NTFSOwner -SecurityDescriptor should return the real owner of a descriptor that was read without its Owner section","","" +"inheritance","Set-NTFSOwner","Path","Partly","Closed","2","ParameterSets.Inheritance.Tests.ps1:829 Set-NTFSOwner should do nothing without -Path, not even to the current location | ParameterSets.Inheritance.Tests.ps1:1019 Set-NTFSOwner should leave the SACL unchanged after it changes the owner","","" +"inheritance","Set-NTFSOwner","SecurityDescriptor","Partly","Closed","1","ParameterSets.Inheritance.Tests.ps1:1035 Set-NTFSOwner -SecurityDescriptor should change only the owner on disk once Set-NTFSSecurityDescriptor writes it, leaving the DACL unchanged, and -PassThru should return a FileSystemOwner object","","" +"inheritance","Get-NTFSSecurityDescriptor","__AllParameterSets","Partly","Partly","1","ParameterSets.Inheritance.Tests.ps1:860 should report the current location when no -Path is given, not an empty result","Limit","Limit: a successful ownership-retry read needs a lab or a remote server" +"inheritance","Set-NTFSSecurityDescriptor","__AllParameterSets","None","Partly","2","ParameterSets.Inheritance.Tests.ps1:1061 Should take a descriptor by property name through the pipeline, not only by value | ParameterSets.Inheritance.Tests.ps1:1082 Should report the PassThru ReadSecurityError with category ReadError and the item as target","would-pin","would-pin: positional binding at Position 2 (the sibling cmdlets use Position 1), an undecided inconsistency" +"items","Copy-Item2","__AllParameterSets","Partly","Closed","6","ParameterSets.Items.Tests.ps1:604 should treat a path with brackets in the name as a literal file name | ParameterSets.Items.Tests.ps1:747 Copy-Item2 should copy the file to a short destination and leave the source in place | ParameterSets.Items.Tests.ps1:811 Copy-Item2 should copy a file to the root of the mapped drive | ParameterSets.Items.Tests.ps1:963 Should replace an existing file directly with -Force, with PassThru=<_> | ParameterSets.Items.Tests.ps1:987 Should write DestinationFileAlreadyExists with its category and target for a file that exists at the destination | ParameterSets.Items.Tests.ps1:1003 -PassThru should return the output type for a file and for a folder, and write nothing without -PassThru","","" +"items","Get-ChildItem2","__AllParameterSets","Partly","Closed","9","ParameterSets.Items.Tests.ps1:728 Get-ChildItem2 should list the content of the folder | ParameterSets.Items.Tests.ps1:801 Get-ChildItem2 should list the content at the root of the mapped drive | ParameterSets.Items.Tests.ps1:857 Get-ChildItem2 should list the content of the current location | ParameterSets.Items.Tests.ps1:895 Should resolve a relative -Path against the current location | ParameterSets.Items.Tests.ps1:908 Should return only the folder when -Directory and -File are given together | ParameterSets.Items.Tests.ps1:919 Should return the same matches for -Attributes regardless of -Force, -Hidden, -System, and -ReadOnly () | ParameterSets.Items.Tests.ps1:932 Should have no effect without -Recurse | ParameterSets.Items.Tests.ps1:940 Should list the same items through the dir2 alias | ParameterSets.Items.Tests.ps1:946 Should write AttributesEmpty with its category and target for an empty -Attributes value","","" +"items","Get-Item2","__AllParameterSets","Partly","Closed","4","ParameterSets.Items.Tests.ps1:604 should treat a path with brackets in the name as a literal file name | ParameterSets.Items.Tests.ps1:717 Get-Item2 should return the file and its folder | ParameterSets.Items.Tests.ps1:794 Get-Item2 should return a DirectoryInfo object for the root of the mapped drive | ParameterSets.Items.Tests.ps1:844 Get-Item2 should return the folder of the current location","","" +"items","Move-Item2","__AllParameterSets","Partly","Closed","7","ParameterSets.Items.Tests.ps1:604 should treat a path with brackets in the name as a literal file name | ParameterSets.Items.Tests.ps1:657 should not expand an asterisk in a path as a wildcard and should report FileNotFound | ParameterSets.Items.Tests.ps1:759 Move-Item2 should move the file to a short destination and remove the source | ParameterSets.Items.Tests.ps1:823 Move-Item2 should move a file to the root of the mapped drive | ParameterSets.Items.Tests.ps1:1021 Should move a non-empty folder tree to a new destination | ParameterSets.Items.Tests.ps1:1041 Should rename an item in place on the same volume | ParameterSets.Items.Tests.ps1:1060 Should replace an existing folder outright with -Force, not merge it, and write no error","","" +"items","Remove-Item2","__AllParameterSets","Partly","Closed","7","ParameterSets.Items.Tests.ps1:604 should treat a path with brackets in the name as a literal file name | ParameterSets.Items.Tests.ps1:657 should not expand an asterisk in a path as a wildcard and should report FileNotFound | ParameterSets.Items.Tests.ps1:1085 Should do nothing when -Path is omitted | ParameterSets.Items.Tests.ps1:1105 Should remove the file through the alias | ParameterSets.Items.Tests.ps1:1116 Should write FileNotFound with its category and target for a path that does not exist | ParameterSets.Items.Tests.ps1:1127 Should write nothing for a successful removal without -PassThru | ParameterSets.Items.Tests.ps1:1143 Should write DeleteError with category NotSpecified when a Deny ACE refuses the delete","","" +"items","Test-Path2","__AllParameterSets","Open","Closed","4","ParameterSets.Items.Tests.ps1:807 Test-Path2 should find the root of the mapped drive as a container | ParameterSets.Items.Tests.ps1:1163 Should accept several piped objects and bind -PathType by property name for each | ParameterSets.Items.Tests.ps1:1177 Should find an item whose name contains brackets | ParameterSets.Items.Tests.ps1:1185 Should find an item through a UNC path of the administrative share","","" +"items","Get-FileHash2","__AllParameterSets","Partly","Partly","2","ParameterSets.Items.Tests.ps1:737 Get-FileHash2 should hash the file and match an independent SHA256 read through AlphaFS | ParameterSets.Items.Tests.ps1:1194 Should hash with the algorithm bound by property name from the pipeline","Limit","Limit: the success path of the ownership retry (elevated only; the set-up of a DACL and an owner that gives it is not buildable in a sandbox)" +"items","Get-DiskSpace","__AllParameterSets","Partly","Closed","2","ParameterSets.Items.Tests.ps1:1210 Should report free-space values close to an independent .NET read for the system drive | ParameterSets.Items.Tests.ps1:1228 Should write the validation error for a bad -DriveLetter with its category, and no target object","","" +"items","New-NTFSHardLink","__AllParameterSets","Partly","Closed","3","ParameterSets.Items.Tests.ps1:1245 Should bind -Path and -Target positionally | ParameterSets.Items.Tests.ps1:1261 Should accept a FileInfo object piped by value for -Target | ParameterSets.Items.Tests.ps1:1275 -PassThru should write GetHardLinkError with category ReadError and the link path as target on a network share","","" +"items","Get-NTFSHardLink","__AllParameterSets","Partly","Partly","1","ParameterSets.Items.Tests.ps1:1295 Should write GetHardLinkError with category ReadError for a file on a network share","Limit","Limit: the UnauthorizedAccessException handler is structurally unreachable (Windows lists hard-link names without opening the file)" +"items","New-NTFSSymbolicLink","__AllParameterSets","Partly","Closed","2","ParameterSets.Items.Tests.ps1:1309 Should bind -Path and -Target positionally | ParameterSets.Items.Tests.ps1:1323 Should set LinkType and the resolved target for a link to a folder","","" +"items","Enable-Privileges","__AllParameterSets","Partly","Closed","1","ParameterSets.Items.Tests.ps1:1344 Should report Enabled for TakeOwnership, Restore, Backup, and Security in -PassThru, matching whoami /priv","","" +"items","Disable-Privileges","__AllParameterSets","Partly","Partly","1","ParameterSets.Items.Tests.ps1:1364 Should report Disabled for TakeOwnership, Restore, and Backup in -PassThru after a successful disable","Limit","Limit: the warning when a privilege cannot be disabled needs a race with another command" +"items","Get-Privileges","__AllParameterSets","Partly","Partly","0","","Limit","Limit: the Removed value of PrivilegeState is unreachable: a removed privilege leaves the list of the token instead of showing the value (a probe before and after confirmed it)" diff --git a/Tests/Coverage/Quality-Gate-Test-Round-2026-10-20.md b/Tests/Coverage/Quality-Gate-Test-Round-2026-10-20.md new file mode 100644 index 0000000..d503b42 --- /dev/null +++ b/Tests/Coverage/Quality-Gate-Test-Round-2026-10-20.md @@ -0,0 +1,230 @@ +# Quality gate, the tests-only round, 2026-10-20 + +The maintainer decided on 2026-10-19 (Decision 21, "Closing the gate") that the +plain test gaps of the quality gate are closed in a round of tests only, until +2026-11-02, and that this report lists what is left. The gaps are the items that +the ParameterSets table of the +[report of Handoff 5](Quality-Gate-Unknowns-2026-10-10.md) calls `budget`: plain +test work that needs no decision and no lab, 68 mentions in 51 of its 64 +parameter sets. Nothing in the shipped module, the cmdlet pages, or the CI +changed; rc8 stays the candidate of the stable build. The round closes the plain +gaps; it does not close the gate (#34 and the check of the Gallery API key are +open), and a closed row says that its plain gaps are tested, not that the +cmdlet is. + +## Result in short + +- **The tests.** 89 new `It` blocks, which run as 121 cases per configuration, + in the four `ParameterSets.*.Tests.ps1` files. 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 parameter sets.** 38 of 64 are closed (7 before). 31 sets changed to + closed, among them the one that was open (`Test-Path2`). The one set that had + no judgement, `Set-NTFSSecurityDescriptor`, is now partly closed. 26 sets have + something left, and every leftover is named in the table below: 16 are limits + (no test can reach it, or it needs a lab or a remote server), 7 wait for the + maintainer, and 3 would pin an inconsistency. +- **No defect.** None of the 121 new cases found a behavior of a cmdlet that + contradicts its page or common sense. Four expectations of the implementers + were wrong at first and were corrected in the tests, and my own helper script + had a defect (see "What the tests showed"). +- **No product change, so no new prerelease.** The package of rc8 is the one + that the labs accepted on 2026-10-20. A defect that a test had found would + have needed the maintainer's decision and rc9. + +## The tests + +Four implementer agents each worked in a worktree of `master` at `715c254` and +changed one test file, so that the batches could not conflict. Each had the +same brief: pin observable behavior through the public surface, read state back +with an oracle that is independent of the cmdlet under test (.NET `Get-Acl` and +`FileSecurity`, SDDL, `[IO.File]`, `Get-Item`, `icacls`), assert concrete +values, build every fixture in the sandbox, make sure that at least one of the +four configurations runs each test, and leave out what the reason column of its +worklist calls `would-pin`, `Limit`, `MaintainerDecision`, or `lab`. A defect +was to be reported, not fixed. + +| Group | Test file | New `It` | New cases | Sets closed | Negative check | +| --- | --- | ---: | ---: | ---: | --- | +| access | `ParameterSets.Access.Tests.ps1` | 20 | 32 | 6 | 20 flipped, the 32 cases failed | +| audit | `ParameterSets.Audit.Tests.ps1` | 9 | 10 | 4 | 9 flipped, the 10 cases failed | +| inheritance | `ParameterSets.Inheritance.Tests.ps1` | 15 | 25 | 11 | 15 flipped, 25 failed elevated, 16 as a basic user (9 skip) | +| items | `ParameterSets.Items.Tests.ps1` | 45 | 54 | 10 | 45 flipped, 51 failed elevated, 39 as a basic user (12 skip); the other 3 flipped later | +| Total | | 89 | 121 | 31 | | + +The negative check is a copy of the file in which each new `It` has one +expectation flipped (a value, a count, a category, a type). Every flipped case +failed in each configuration where it runs, and no other case failed. In the +items batch, 3 of the 54 cases had not been flipped: the Move-Item2, Get-Item2, +and Remove-Item2 rows of the test for a path with brackets, which share one +`It` with the Copy-Item2 row that was flipped. I flipped them afterwards in a +copy, and all three failed in all four configurations while the Copy-Item2 row +stayed green. So each of the 121 new cases is known to fail when what it pins +changes. + +Each batch also ran three times in all four configurations with identical +results, and `Invoke-ScriptAnalyzer` reports no finding on any of the four +files. The four diffs add 1,781 lines and delete none: no existing test was +changed, renamed, or moved. + +A new case skips where the token lacks what it needs, and runs in the other +configurations. These are the 30 new cases that skip as a basic user, in both +editions: + +| Needs | Cases | Where | +| --- | ---: | --- | +| the Security privilege (the SACL, audit entries) | 17 | audit 9, inheritance 8 | +| a drive mapping | 5 | items | +| the administrative share | 3 | items | +| the symbolic-link privilege | 2 | items | +| an elevated token, for the privilege states | 2 | items | +| an owner other than the user (a basic user owns the new items) | 1 | inheritance | + +One new case skips when elevated: the `Get-NTFSOrphanedAudit` error without the +Security privilege runs only as a basic user. So each new case runs in at least +two configurations, and none skips in all four. The skipped counts moved +accordingly: elevated 26 to 27 (Windows PowerShell) and 57 to 58 (PowerShell +7); as a basic user 291 to 321 and 322 to 352. + +## The suite + +The suite is the CI test step, run in four configurations on the host (Windows +Server 2025), against a Release build of the branch. The counts are those of the +NUnit result files of the run, and the new cases per file are the differences of +the counts per test file between this run and the last run before the round +(`Measure-RoundSuiteDelta.ps1`, in the evidence). + +| Configuration | Executed | Skipped | Failed | Total | +| --- | ---: | ---: | ---: | ---: | +| Windows PowerShell 5.1, elevated | 1,588 | 27 | 0 | 1,615 | +| Windows PowerShell 5.1, basic user | 1,294 | 321 | 0 | 1,615 | +| PowerShell 7, elevated | 1,557 | 58 | 0 | 1,615 | +| PowerShell 7, basic user | 1,263 | 352 | 0 | 1,615 | + +`master` has 1,494 cases per configuration, with 26, 291, 57, and 322 skipped. +An earlier run with the audit, access, and items batches (1,590 cases) was also +green in all four configurations. The CI of the pull request runs the same +steps on a GitHub runner; I did not run that. + +## What is left + +Every parameter set that is not closed, with the kind of what is left. The +table of all 64 sets, with the status before and after, the new tests of each +(file, line, and name), and what is left, is +[the CSV of this round](Quality-Gate-Test-Round-2026-10-20-ParameterSets.csv). + +| Kind | Cmdlet / parameter set | What is left | +| --- | --- | --- | +| MaintainerDecision | `Add-NTFSAccess` / SDSimple | the terminating error of a failing change (a deny entry without rights) is not pinned | +| MaintainerDecision | `Add-NTFSAccess` / SDComplex | the terminating error of a failing descriptor is not pinned | +| MaintainerDecision | `Remove-NTFSAccess` / SDSimple | the terminating error of a failing removal is not pinned | +| MaintainerDecision | `Remove-NTFSAccess` / SDComplex | the terminating error of a failing removal is not pinned | +| MaintainerDecision | `Add-NTFSAudit` / SDSimple | exceptions from the change itself (open item 1 of Handoff 5) | +| MaintainerDecision | `Add-NTFSAudit` / SDComplex | exceptions from the change itself (open item 1 of Handoff 5) | +| MaintainerDecision | `Remove-NTFSAudit` / SDComplex | exceptions from the change itself (open item 1 of Handoff 5) | +| would-pin | `Get-NTFSAccess` / Path | the category of the `ReadSecurityError` after a failed ownership retry (WriteError there, OpenError from the generic catch) is not asserted, so as not to cement the inconsistency | +| would-pin | `Get-NTFSOrphanedAccess` / Path | the choice of a warning, not an error, for a read failure other than access denied | +| would-pin | `Set-NTFSSecurityDescriptor` / all sets | positional binding at Position 2 (the sibling cmdlets use Position 1), an undecided inconsistency | +| Limit | `Get-NTFSAccess` / SD | no failing descriptor is tested for this set (no per-item handler) | +| Limit | `Get-NTFSSimpleAccess` / SD | no failing descriptor is tested for this set (no per-item handler) | +| Limit | `Get-NTFSEffectiveAccess` / Path | the `ReadEffectivePermissionError` handler is unreachable (the library records the failure); remote and group-based results need the lab (the live tests cover them) | +| Limit | `Get-NTFSEffectiveAccess` / SecurityDescriptor | a mix of a failing and a succeeding descriptor in one call | +| Limit | `Add-NTFSAudit` / PathComplex | the owner retry after access denied needs a lab or a remote server | +| Limit | `Remove-NTFSAudit` / PathComplex | the owner retry after access denied needs a lab or a remote server | +| Limit | `Clear-NTFSAudit` / Path | the owner retry after access denied needs a lab or a remote server | +| Limit | `Get-NTFSAudit` / Path | the PermissionDenied category branch of `ReadSecurityError` | +| Limit | `Disable-NTFSAuditInheritance` / Path | a successful ownership retry or `RestoreOwnerError` of a SACL write needs a lab or a remote server | +| Limit | `Enable-NTFSAuditInheritance` / Path | a successful ownership retry or `RestoreOwnerError` of a SACL write needs a lab or a remote server | +| Limit | `Get-NTFSInheritance` / Path | a successful ownership-retry read needs a lab or a remote server | +| Limit | `Get-NTFSSecurityDescriptor` / all sets | a successful ownership-retry read needs a lab or a remote server | +| Limit | `Get-FileHash2` / all sets | the success path of the ownership retry (elevated only; the DACL and owner that give it can't be built in a sandbox) | +| Limit | `Get-NTFSHardLink` / all sets | the `UnauthorizedAccessException` handler is structurally unreachable (Windows lists hard-link names without opening the file) | +| Limit | `Disable-Privileges` / all sets | the warning when a privilege cannot be disabled needs a race with another command | +| Limit | `Get-Privileges` / all sets | the `Removed` value of `PrivilegeState` is unreachable: a removed privilege leaves the list of the token instead of showing the value (a probe before and after confirmed it) | + +The 7 decisions and the 3 pins are the maintainer's, as in the report of +Handoff 5; nothing here decides them. The dot patterns of +`Get-ChildItem2 -Filter` are also still his (the row is closed because its +plain gaps are tested, not because the patterns are decided). The "ownership +retry" limits are the paths that run when a cmdlet has to take an owner to read +or write a security descriptor. The report of Handoff 5 explains why no unit +test reaches them (and lists `AUDIT-OWNER-RETRY` as open), so they stay +explained, not tested. + +## What the tests showed + +- **No defect.** The four implementers found no behavior that contradicts the + cmdlet page or common sense, and their `defects` folders are empty. +- **`Get-Privileges` and `Removed`.** The `Removed` value of `PrivilegeState` + can't appear in the output: after a privilege is removed from a token, the + token's list no longer has it. A probe before and after showed it. The row + is a limit, not a test gap. +- **`Move-Item2 -Force` onto a non-empty folder replaces it**, with no merge and + no error. `Docs/Cmdlets/Move-Item2.md` documents the replace, and the new test + pins it. +- **Four expectations were wrong at first and were corrected in the tests**, + none of them a defect: + - `Get-NTFSOrphanedAudit` without the Security privilege reports the category + `OpenError`, as `Get-NTFSAudit` does, not `PermissionDenied` (that category + is the limit above). + - After `Disable-NTFSAuditInheritance` without `-RemoveInheritedAuditRules` + and a plain enable, an item has two audit entries, not one: the disable + copies the inherited entry into the SACL as an explicit one, and the cmdlet + page says so. + - `-PassThru` of `Copy-Item2` and `Move-Item2` is a `Boolean` that needs a + value, not a switch, as their pages say. + - The access-denied test of `Remove-Item2` needs a deny entry on the parent + folder (`DeleteSubdirectoriesAndFiles`) and one on the file (`Delete`), + because NTFS grants a delete through either. +- **A defect of my helper script, not of the module.** The inheritance + implementer reported that its basic-user runs stalled for about 30 minutes, + twice, and took it for an effect of the load of four agents at once; another + group's job stuck the same way. The cause was the helper that runs the + configurations of a batch: a test-name filter with spaces did not survive the + nested quotes of `runas`, the child never started, and the helper waited for + its whole timeout. The filter now travels as base64, and the helper gives up + after a minute without a runner. The suite numbers above come from the run of + the four CI configurations, which takes no name filter and did not stall. + +## Checks not run, and limits + +- The CI on a GitHub runner did not run these tests yet; the pull request does. + Cases that need a drive mapping, an administrative share, or a symbolic link + skip where the token lacks them and can behave differently on a runner. +- No lab run: the product bytes did not change. The acceptance of rc8 of + 2026-10-20 stands for them. +- No independent review agent ran on the four batches. I read the diffs of all + four commits (the added lines, the oracles, and the places where a test + touches the system). A review of the 1,781 added lines is still possible + before the merge. +- The mutated copies of the negative checks were deleted. The per-batch results + rest on the reports of the implementers (in the evidence); only the three + bracket rows of the items batch were flipped and run again by me. +- The negative checks flip one expectation of a test; they are not a mutation + test of the product. The mutations of the product were not run again; the + last ones are in `Quality-Gate-Unknowns-2026-10-10-Mutations.csv`. +- The code coverage was not measured again; the numbers of Handoff 5 remain the + last measurement. +- The leftovers marked `Limit` are explained from source and from a probe; an + explanation is not a test. + +## Evidence outside git + +The raw evidence is in the session folder +`C:\Users\install\.copilot\session-state\816cf47d-2f80-4eba-8ac9-41702c49560b\files\qg-unknowns` +(`E`). [The Evidence CSV](Quality-Gate-Test-Round-2026-10-20-Evidence.csv) +lists its files with size and SHA-256; the four worktrees of the implementers +are not in it. The commits of the batches are `7c3de81` (audit), `472003e` +(access), `e32e36a` and `9a2a809` (items), and `404ceca` (inheritance) of the +branch `ai/tests-round-1`. + +| Path in `E` | Content | +| --- | --- | +| `round1\IMPLEMENTER-BRIEF.md`, `round1\worklist-*.md` | the brief of the implementers and the four worklists (the rows with their remaining items, reasons, and key tests) | +| `round1\reports\report-*.md` | the final reports of the four implementers, verbatim, with the counts, the negative checks, and the follow-up on the three unflipped rows of the items batch | +| `round1\\commit-diff.txt`, `source-pin.txt` | the diff of the access, inheritance, and items batches (the audit batch has none) and, for each group, the commit that its worktree started from (`715c254`) | +| `round1\suite\rc8suite-20261020-093109` | the last run of the four CI configurations before the round (1,494 cases per configuration) | +| `round1\suite\round1-three-20261020-141224`, `round1\suite\round1-four-20261020-142909` | the runs with three and with all four batches (1,590 and 1,615 cases), each with the NUnit file, the log, and the summary of the four configurations | +| `round1\suite\delta-four-vs-baseline.txt` | the output of `Measure-RoundSuiteDelta.ps1`: the new cases per file and configuration, and the 30 and 1 that skip | +| `round1\tables-draft` | the draft of the ParameterSets CSV | +| `scripts` | `Build-Worklists.ps1`, `Build-RoundTables.ps1` (the CSV of this round), `Invoke-RoundJob.ps1`, `Invoke-Build.ps1`, `Run-FocusedPester.ps1`, `Start-FocusedRuns.ps1` (the helper with the quoting defect, fixed), `Run-FullSuite.ps1`, `Run-CiConfiguration.ps1`, `Measure-RoundSuiteDelta.ps1` |