From ebe91fe9a104fd31a74cbf0a59a4016bd7ffe33f Mon Sep 17 00:00:00 2001 From: Raimund Andree Date: Thu, 8 Oct 2026 16:46:20 +0000 Subject: [PATCH] chore(memory-bank): record Decision 22 and the evidence of 5.0.0-rc7 Decision 22 lists the ten choices for the behavior changes of Phase 2, proposed for the maintainer's review, and the outcome of the review. progress.md and activeContext.md record the branch, the suite, the lab acceptance, and the next steps; systemPatterns.md adds patterns for writing cmdlets. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant --- .memory-bank/activeContext.md | 102 ++++++++---------- .../0022-phase-2-behavior-changes.md | 53 +++++++++ .memory-bank/progress.md | 86 +++++++-------- .memory-bank/systemPatterns.md | 18 ++++ 4 files changed, 154 insertions(+), 105 deletions(-) create mode 100644 .memory-bank/decisions/0022-phase-2-behavior-changes.md diff --git a/.memory-bank/activeContext.md b/.memory-bank/activeContext.md index c6136ce..4e01eb6 100644 --- a/.memory-bank/activeContext.md +++ b/.memory-bank/activeContext.md @@ -9,70 +9,52 @@ source: current task evidence ## Current focus -Phase 2 of the quality gate before 5.0.0 (Decision 21) is complete on the -local branch `ai/release-5.0.0-rc6`, candidate `7b0781f`. The maintainer -pushes the branch, merges the pull request after CI, and tags 5.0.0-rc6. -Then Phase 3 (live tests on more operating systems) and 5.0.0; after -5.0.0 the repository is archived in favor of WindowsAccessControl -(Decision 18). +The behavior changes that Phase 2 of the quality gate found (Decision 16) +are decided as assumptions for the maintainer's review (Decision 22) and +implemented test-first on the local branch `ai/release-5.0.0-rc7`, stacked +on #115 (5.0.0-rc6, head `be04cb7`, CI green, not merged yet). The +maintainer reviews the choices, merges #115 and tags 5.0.0-rc6, and +publishes the branch as 5.0.0-rc7. Then Phase 3 and 5.0.0; after 5.0.0 +the repository is archived in favor of WindowsAccessControl (Decision 18). ## Evidence -- 2026-10-08, Phase 2 on `ai/release-5.0.0-rc6`, 31 commits on `fcb370e` - (5.0.0-rc5); the candidate is `7b0781f`: - - The suite has 684 tests. Elevated: 662 passed and 22 skipped in - Windows PowerShell 5.1, 632 and 52 in PowerShell 7. As a basic user - through `Invoke-TestsAsBasicUser.ps1`: 590 and 94, 560 and 124. No - failure, and no test is skipped in all four configurations; CI runs - all four since this branch. - - C# coverage of all four configurations (AltCover without `--save`, - `techContext.md`): 68.1% of the lines and 44.3% of the branches on - `1b9edbb`; rc5 58.1% and 38.0%. The earlier figures counted one of - the four runs. Of the 972 points that no test ran at `e2b6b24` - (without the classes that no cmdlet calls), 400 are code that nothing - calls, 107 defensive guards, 74 need a failure of Windows, 4 need the - lab, and 387 are reachable; 51 of those ran in runs that the first - measurement missed, and the top items of the rest are in - `progress.md`, open work 7. - - Fixed test-first: `Get-NTFSSimpleAccess` (`ReadData`, the parent of a - relative path); `Copy-Item2` and `Move-Item2` (a folder at the - destination, the missing destination folder of #21, also with - `-WhatIf`); the hard-link cmdlets on shares and at folders; - `Set-NTFSSecurityDescriptor -PassThru` (R5); the error ID of - `Get-NTFSOrphanedAccess`; relative paths that start with a dot, which - every cmdlet shortened by two characters (`Remove-Item2 .x` removed - another item); comparing entries and descriptors - (`InvalidCastException`, also `Compare-Object` in PowerShell 7) and - their conversions; `InheritedFrom` with `-ExcludeExplicit` and for a - descriptor with audit entries (`ArgumentOutOfRangeException`). - `Copy-Item2` no longer creates the missing folders of a destination - for a folder (assumption, flagged for the maintainer). - - Live tests: cases 4b to 9 and accounts of `b.forest1.net`, - `forest2.net`, and `forest3.net`. The lab acceptance passed for - `acfe3af`, `1b9edbb`, and `7b0781f` (326 tests each, none failed; - `Tests/Lab/Acceptance-2026-10-08-5.0.0-rc6.md`). Baseline: the - published 5.0.0-rc5 fails only the two hard-link tests of case 8. The - fixture was removed and the removal checked after each run; three - checkpoints `ntfs-rc6-*-before-acceptance` stay on six machines. - - `Get-NTFSEffectiveAccess -ServerName` needs administrators or - Access Control Assistance Operators on the named computer (lab probe, - documented). - - Two `security-reviewer` passes approved the branch with no Blocker or - Major finding: `fcb370e..e2b6b24` (findings 1, 4, 5, 10 fixed in - `acfe3af`) and `e2b6b24..1b9edbb` (findings 1, 2, 6, 7 fixed in - `7b0781f`). Not fixed: a failed privilege disable isn't tried again, - and a non-qualified ACE could shift `InheritedFrom` (neither - reproducible); `New-NTFSHardLink` stays terminating for a folder (a - behavior change for the maintainer). +- 2026-10-08, `ai/release-5.0.0-rc7`, 11 commits on `be04cb7` (`3899228` + to `1063b29`) and two commits of records: + - Decision 22: items 1, 2, 5, 6, 7, and 8 changed, 7 and 8 breaking (the + link cmdlets require `-Path` and `-Target` and write non-terminating + errors); items 3, 4, 9, and 10 kept, 9 with an FAQ entry. New defects, + fixed with a regression test that failed first: `Move-Item2` deleted + an empty folder that it moved to another volume (AlphaFS emulated the + move); the link cmdlets failed with `GetDefaultValueFailed` for every + piped object; `Get-NTFSSimpleAccess` failed for a folder that came + after its parent folder a second time. + - One `security-reviewer` pass over `be04cb7..4ee01e5`: no Blocker or + Major. Minor 1 to 5 and Nits 7 to 9 fixed test-first in `7936d9f` to + `1063b29`; Nit 7, the warning of `Get-NTFSEffectiveAccess` for names + of this computer, was reproduced first. Nit 6 declined (Decision 22). + - Suite of `1063b29`: 712 tests. Elevated: 688 passed and 24 skipped in + Windows PowerShell 5.1, 658 and 54 in PowerShell 7. As a basic user: + 612 and 100, 582 and 130. No failure, none skipped in all four. + - Lab acceptance of `dc6e9f5` after the checkpoint + `ntfs-rc7-dc6e9f5-before-acceptance`, 16:24 to 16:40 UTC: 326 tests in + both editions, none failed, 2 skipped as in rc6 + (`Tests/Lab/Acceptance-2026-10-08-5.0.0-rc7.md`). The code of + `4ee01e5` and a first run of `dc6e9f5` without the checkpoint had the + same counts. The fixture was removed at 16:21 and 16:44 UTC, and its + removal checked each time. +- #115 passed CI in all four configurations on `be04cb7`, with the first + runs of `Invoke-TestsAsBasicUser.ps1` on GitHub runners. - #34: no reply from the tester since 2026-10-06. ## Next step -1. The maintainer pushes the branch, opens the pull request, merges it - after CI, and tags `5.0.0-rc6`; then the live tests run against the - published package (`-Version 5.0.0-rc6`). The first CI run is the first - run of `Invoke-TestsAsBasicUser.ps1` on a GitHub runner. -2. The maintainer decides the behavior changes in `progress.md`, open - work 4 (Decision 16), and the scope of Phase 3: the operating systems, - the code that nothing calls, and file servers that aren't Windows - (#34). +1. The maintainer reviews the choices of Decision 22, each its own commit, + above all the two breaking changes of the link cmdlets. +2. He pushes the branch and opens its pull request with the base + `ai/release-5.0.0-rc6`; after #115 is merged and tagged, he changes the + base to `master`, merges with a merge commit (Decision 15), and tags + `5.0.0-rc7`. The live tests then run against the published package + (`-Version 5.0.0-rc7`). +3. He decides the scope of Phase 3: the operating systems, the code that + nothing calls, and file servers that aren't Windows (#34). diff --git a/.memory-bank/decisions/0022-phase-2-behavior-changes.md b/.memory-bank/decisions/0022-phase-2-behavior-changes.md new file mode 100644 index 0000000..f59d750 --- /dev/null +++ b/.memory-bank/decisions/0022-phase-2-behavior-changes.md @@ -0,0 +1,53 @@ +--- +status: proposed +date: 2026-10-08 +last-verified: 2026-10-08 +owner: shared +source: agent choices in autopilot on 2026-10-08, for the maintainer's review +--- + +# Decision 22: The behavior changes of Phase 2 + +- Context: Decision 16 left the behavior changes that Phase 2 found to the + maintainer (`progress.md`, open work 4). On 2026-10-08 he asked to work + on them while the pull request of 5.0.0-rc6 (#115) built, in autopilot; + the agent took the recommended option for each. Every choice is an + assumption for his review. Each change is its own commit on + `ai/release-5.0.0-rc7` (`3899228` to `4ee01e5`, the label in `d17e0f7`, + the review fixes in `7936d9f` to `1063b29`). A revert can conflict where + a later commit touched the same page or test, and then needs the help + file generated again. +- Choices: + +| # | Item | Choice | +| --- | --- | --- | +| 1 | `Get-NTFSOrphanedAudit` returned nothing without the Security privilege | Changed: `ReadSecurityError`, like `Get-NTFSAudit`; a missing path keeps `ReadError` | +| 2 | `Get-NTFSSimpleAccess` left out a folder whose parent it hadn't reported | Fixed: such a folder, also a drive root, gets all entries; a repeated folder no longer fails with `ReadError` | +| 3 | Developer Mode for `New-NTFSSymbolicLink` | Kept as documented: new P/Invoke and fallback code before the archive (Decision 18) | +| 4 | `-WhatIf` names a conflict in a verbose message, not a warning (R7) | Kept, as for #108 and the missing destination folder | +| 5 | The fallback warning of `Get-NTFSEffectiveAccess` didn't name the server | Changed: it names the computer | +| 6 | `Move-Item2` can't move a folder to another volume | Kept the refusal; fixed what was found: with `CopyAllowed`, AlphaFS copied and deleted folders and lost empty ones. Now a `MoveError` that names folder and destination | +| 7 | The link cmdlets stopped with terminating errors | **Breaking:** a non-terminating error per link, and the next link | +| 8 | `-Path` and `-Target` of the link cmdlets were optional | **Breaking:** required. An omitted `-Path` failed with an index error, an omitted `-Target` meant the current location | +| 9 | Entries and descriptors are equal only as the same .NET object | Kept the equality of .NET; the FAQ shows `Compare-Object -Property` | +| 10 | `Copy-Item2` doesn't create the missing destination folders (rc6) | Kept, like `Copy-Item` and `Move-Item2` | + +- Found on the way and fixed: every object piped to the link cmdlets + failed with `GetDefaultValueFailed` (item 8). Item 6 is not the cause of + #21, whose report used `-Force` within one volume. +- Review: one `security-reviewer` pass over `be04cb7..4ee01e5` found no + Blocker or Major issue. Fixed test-first: the link cmdlets stopped for a + path with an invalid character in Windows PowerShell, named no path in + some errors, and checked `-Path` and `-Target` in different orders; + `Get-NTFSEffectiveAccess` warned for every name of this computer except + `localhost` in lowercase (reproduced, Decision 16); the tests of the + case-insensitive parent lookup and of a drive root, and the shared + administrative-share helpers. Declined: one error ID for a missing path + in the audit cmdlets (`ReadError` and `ReadFileError`), a change of + behavior for scripts that check the ID. +- Rationale: an error instead of a result that looks valid (1, 2, 6); + per-item errors, as in the other cmdlets (7); no silent default for a + path that creates something (8); no new features before the archive + (3); the conventions of .NET and PowerShell (4, 9, 10). +- Open: the maintainer accepts or reverts each choice; then this record + becomes `accepted`. diff --git a/.memory-bank/progress.md b/.memory-bank/progress.md index 435d20f..ef915bb 100644 --- a/.memory-bank/progress.md +++ b/.memory-bank/progress.md @@ -12,12 +12,13 @@ source: repository evidence 5.0.0-rc5 is on the PowerShell Gallery and in the GitHub releases, published by CI on 2026-10-08 from the tag `5.0.0-rc5` on `master` (`fcb370e`, the merge of #114; Decision 12). Phase 2 of the quality gate -(Decision 21) is complete on the local branch `ai/release-5.0.0-rc6`: the -candidate 5.0.0-rc6 (`acfe3af`) passed the suite in four configurations, -one `security-reviewer` pass, and the lab acceptance. It waits for the -maintainer to push, merge, and tag it; Phase 3 follows. The stable Gallery -version is still 4.2.6. NTFSSecurity will be archived soon; its users move -to WindowsAccessControl (Decision 18). +(Decision 21) is complete: #115 (`ai/release-5.0.0-rc6`, head `be04cb7`) +passed CI in all four configurations and waits for the maintainer to merge +it and tag 5.0.0-rc6. The behavior changes that Phase 2 found are decided +as assumptions for his review (Decision 22) on the local branch +`ai/release-5.0.0-rc7`, stacked on #115. Phase 3 follows. The stable +Gallery version is still 4.2.6. NTFSSecurity will be archived soon; its +users move to WindowsAccessControl (Decision 18). ## Recent milestones @@ -100,6 +101,15 @@ to WindowsAccessControl (Decision 18). measured again; the first measurements counted one of four runs). Two `security-reviewer` passes; the lab acceptance of `7b0781f` passed (`Tests/Lab/Acceptance-2026-10-08-5.0.0-rc6.md`). +- 2026-10-08: #115 (rc6, head `be04cb7`) passed CI in all four + configurations. On `ai/release-5.0.0-rc7` (local), the behavior changes + of Phase 2 were decided as assumptions for review (Decision 22) and + implemented test-first, two of them breaking (the link cmdlets); new + defects found on the way: `Move-Item2` deleted an empty folder that it + moved to another volume, the link cmdlets failed for every piped object, + and `Get-NTFSEffectiveAccess` warned for names of this computer. One + `security-reviewer` pass (no Blocker or Major; its findings fixed but + one, declined). Suite and lab acceptance in `activeContext.md`. ## Stable capabilities @@ -114,20 +124,21 @@ to WindowsAccessControl (Decision 18). ## Open work -1. Quality gate before 5.0.0 (Decision 21): Phase 2 is done on the branch - `ai/release-5.0.0-rc6` (`activeContext.md`); the maintainer pushes it, - merges the pull request, and tags 5.0.0-rc6, and the live tests run - against the published package. Phase 3 runs the live tests on more - operating systems. Then release - 5.0.0 through CI (Decision 12): remove the label, date `[Unreleased]` as - `[5.0.0]`, add the last prerelease to `$publishedVersions`, and tag - `5.0.0` (steps in `Docs/Contributing/05-Releasing.md`). #34 stays open - with Bug and Help Wanted until a tester with a file server that refuses - the owner confirms the fix, or until 5.0.0 ships. +1. Quality gate before 5.0.0 (Decision 21): Phase 2 is done; the + maintainer merges #115 and tags 5.0.0-rc6, reviews the choices of + Decision 22 on `ai/release-5.0.0-rc7`, and publishes them as + 5.0.0-rc7. Phase 3 runs the live tests on more operating systems. Then + release 5.0.0 through CI (Decision 12): remove the label, date + `[Unreleased]` as `[5.0.0]`, add the last prerelease to + `$publishedVersions`, and tag `5.0.0` (steps in + `Docs/Contributing/05-Releasing.md`). #34 stays open with Bug and Help + Wanted until a tester with a file server that refuses the owner + confirms the fix, or until 5.0.0 ships. 2. Issues: the rc6 branch addresses the seven items of #110 (tests); the pull request names it without a closing keyword, so the maintainer closes it after the merge. #21 (a misleading error of `Move-Item2`) got - a fix in rc6 that names the missing destination folder. #68 + a fix in rc6 that names the missing destination folder; the folder + moves to another volume that rc7 fixes are a different defect. #68 tracks `-WhatIf` and `-Confirm` for every cmdlet that changes security. The labels follow Decision 17; #16, #21, #45, and #89 wait for their reporters (Needs Info). Not planned for 5.0.0: the enhancements #22, @@ -138,32 +149,17 @@ to WindowsAccessControl (Decision 18). them the accounts filter that `RemoveFileSystemAccessRuleAll` and `RemoveFileSystemAuditRuleAll` ignore, which no cmdlet passes; of rc5, the bare `catch` in `Win32.GetEffectiveAccess`, the unchecked - `AUTHZ_ACCESS_REPLY.Error`, a fallback warning without the server name, - and hardening of the lab controller (guards in the setup blocks, - interpolated `-EncodedCommand` paths, CredSSP by IP address, the - password string in memory, disabling the role accounts after a run); of - rc6, a privilege that fails to be disabled isn't tried again by - `Dispose` (finding 2, not reproducible). -4. Behavior changes found in Phase 2, for the maintainer (Decision 16): - `Get-NTFSOrphanedAudit` returns nothing without the Security privilege, - while `Get-NTFSAudit` writes `ReadSecurityError`; - `Get-NTFSSimpleAccess` skips a folder whose parent it didn't process; - `New-NTFSSymbolicLink` could create links without the privilege in - Developer Mode (flag `SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE`, with - a fallback before Windows 10 1703); `-WhatIf` names a conflict in a - verbose message instead of a warning (R7); the fallback warning of - `Get-NTFSEffectiveAccess` doesn't name the server; `Move-Item2` can't - move a folder to another volume; `New-NTFSHardLink` stops with a - terminating error for a folder, unlike `Get-NTFSHardLink` (rc6 review, - finding 11). Taken as an assumption in rc6, for review: `Copy-Item2` - no longer creates the missing folders of a destination for a folder. - Found by the coverage report of rc6: `-Target` of the link cmdlets is - optional and means the current location when it's omitted; equality of - entries and descriptors is the identity of the wrapped .NET object, so - two reads of the same entry differ for `Compare-Object` and - `Select-Object -Unique` (value equality would be a behavior change); 400 - points of code that nothing calls besides the 244 lines of unused - classes (Phase 3). + `AUTHZ_ACCESS_REPLY.Error`, and hardening of the lab controller (guards + in the setup blocks, interpolated `-EncodedCommand` paths, CredSSP by + IP address, the password string in memory, disabling the role accounts + after a run); of rc6, a privilege that fails to be disabled isn't tried + again by `Dispose` (finding 2, not reproducible); of rc7, one error ID + for a missing path in the audit cmdlets (declined, Decision 22). +4. Behavior changes found in Phase 2 (Decision 16): decided in Decision 22 + as assumptions for the maintainer's review, on `ai/release-5.0.0-rc7`; + two of them are breaking changes of the link cmdlets. Left for Phase 3: + 400 points of code that nothing calls besides the 244 lines of unused + classes. 5. `pwsh` 7.6.1 crashed three times during test runs on the ARM64 workstation (x64 emulation), without module frames; none of the CI runs on native x64 on 2026-10-05 crashed. @@ -171,8 +167,8 @@ to WindowsAccessControl (Decision 18). GitHub authorization, restrict wiki editing to collaborators, ask `Sup3rlativ3` to delete the Read the Docs project, and delete the branch `test/transfer`. In the lab, delete the checkpoints - `ntfs-rc6-*-before-acceptance` of the six machines when they are no - longer needed. + `ntfs-rc6-*-before-acceptance` and `ntfs-rc7-*-before-acceptance` of the + six machines when they are no longer needed. 7. Reachable code that no test runs (coverage report of rc6, ranked by impact; about 300 points): `Remove-Item2` on folders (`-Recurse`, `-Force`, `DeleteError`); the owner restore after taking ownership diff --git a/.memory-bank/systemPatterns.md b/.memory-bank/systemPatterns.md index 5b9208e..4f71acb 100644 --- a/.memory-bank/systemPatterns.md +++ b/.memory-bank/systemPatterns.md @@ -76,9 +76,27 @@ Each Decision record is a file in `decisions/`; read only the relevant ones. | 19 | [Cmdlets write only the sections that they change](decisions/0019-write-only-changed-sections.md) | | 20 | [Live tests in a lab live in Tests\Lab](decisions/0020-live-tests-in-tests-lab.md) | | 21 | [A quality gate before 5.0.0](decisions/0021-quality-gate-before-5.0.0.md) | +| 22 | [The behavior changes of Phase 2 (proposed)](decisions/0022-phase-2-behavior-changes.md) | ## Patterns +### Writing cmdlets + +- A parameter that takes pipeline input needs a getter that doesn't + throw: PowerShell reads it before it binds each input object, and an + exception turns every object into `GetDefaultValueFailed` (the link + cmdlets before 5.0.0-rc7). +- An error for one item is non-terminating, so that the cmdlet goes on + with the next path or pipeline object; since 5.0.0-rc7, the link cmdlets + too. Its message names the item, and its target object is the item that + the cmdlet was asked to process. Resolving a path can throw in Windows + PowerShell for an invalid character, so that belongs inside the + per-item error handling. +- Folders move without `MoveOptions.CopyAllowed`: for another volume, + AlphaFS then copies and deletes, which lost empty folders. Windows + refuses such a move with `NotSameDeviceException` (17). Tests reach + another volume through `\\localhost\C$`, elevated only. + ### Verifying documentation - Run platyPS in Windows PowerShell 5.1 against a Release build; a copy of