diff --git a/.memory-bank/activeContext.md b/.memory-bank/activeContext.md index 2e06b75..ba9f45c 100644 --- a/.memory-bank/activeContext.md +++ b/.memory-bank/activeContext.md @@ -17,7 +17,7 @@ passed; lab acceptance of the published bytes 10:38 to 11:47Z, record #129 (08:24Z), and the Memory Bank #130 (08:47Z). The last prerelease before the stable 5.0.0 is rc9 (Decision 27). The branch -`ai/rc9` (base `d0cb57c`, 32 commits, head `de67883`) is complete and +`ai/rc9` (base `d0cb57c`, 36 commits, head `696ac38`) is complete and validated; it is local until the maintainer pushes it, opens the pull request (body: `C:\Temp\ntfs-rc9\final-msgs\pr-rc9-body.md`, temporary), merges it, and tags `5.0.0-rc9`. It contains: the five piped parameters of `Add-` and @@ -31,7 +31,7 @@ the Windows PowerShell 5.1 rules; the library fixes 3.1 to 3.3 and 3.10; `Set-NTFSSecurityDescriptor` at position 1; tests that bind four parameters by property name; label `rc9`. -Validation of `de67883`: the full suite in the four CI configurations, 2,116 +Validation of `696ac38`: the full suite in the four CI configurations, 2,162 cases each, 0 failed (rc8: 1,615; skipped 27, 359, 58, and 390, so every new case runs where it can); the pages and the help file are a fixpoint (0 drift, 0 broken links; the help file is identical after a second generation); @@ -42,13 +42,16 @@ matrix of valid shapes of the five parameters, run on the published rc8 and on this build in both editions, differs in exactly the 9 list rows of `Add-NTFSAccess`. Two review rounds (Decision 27, "Built in rc9"): round 1 on the first integration found a Blocker (the last-dot rule of the filter) and two -Major findings; round 2 on the final tree and three checks of its fixes found -only Minor findings (wrong statements in the pages, completers that were not -culture invariant, the list for `-AccessType` and `-AppliesTo`, ways around -that rejection, a collection that holds itself); all are fixed with a test -that is red without the fix, or decided. A blank, `$null`, or `DBNull` value of -the other parameter group is `AmbiguousParameterSet` (documented, not -restructured). +Major findings; round 2 on the final tree and five checks of its fixes found +only Minor findings and Nits (wrong statements in the pages, completers that +were not culture invariant, the list for `-AccessType` and `-AppliesTo`, ways +around that rejection, a collection that holds itself, a message formatter that +threw, an enumerator that fails in `Dispose`); all are fixed with a test that +is red without the fix, or decided, and both reviewers closed their last +findings with "no finding" on `696ac38`. A collection that holds itself still +ends the host through the three flags parameters, as in rc8 (known limit). A +blank, `$null`, or `DBNull` value of the other parameter group is +`AmbiguousParameterSet` (documented, not restructured). Open before the stable pull request: the pull request, merge, and tag of rc9 (maintainer); the lab acceptance of the published rc9 (agent, about 70 @@ -71,7 +74,8 @@ Decisions 22 and 24 on 2026-10-19 and decides 23 on 2026-11-02. - Evidence of rc9 is outside git, in the session folder `816cf47d-2f80-4eba-8ac9-41702c49560b\files\rc9`: the specs and review briefs, `suite-full1` (first integration), `suite-final`, `suite-final2`, - `suite-final3`, and `suite-final4` (the head `de67883`), the probes (`p-*.ps1`, + `suite-final3`, `suite-final4`, `suite-final5`, `suite-final6-b436423`, and + `suite-final7-696ac38` (the head), the probes (`p-*.ps1`, `fixb-probe`, `shapes-r2`, `Run-Oracle.ps1`, `Run-Pathological.ps1`), the published rc8 (`rc8-published`), and the analyzer and surface results. The review probes of the reviewers are in `C:\Temp\ntfs-rc9\review*-probes-*` diff --git a/.memory-bank/debugging-insights.md b/.memory-bank/debugging-insights.md index f0fc6d0..0bc4942 100644 --- a/.memory-bank/debugging-insights.md +++ b/.memory-bank/debugging-insights.md @@ -163,7 +163,31 @@ fails without it (Decision 16). showed that exactly the 9 list rows changed. Code that opens a one-element collection needs a depth limit: an array that holds itself hung the first version (the binder of rc8 ends the host with a stack overflow on it), so - the conversion opens at most 32 levels and reads at most two elements. + the conversion opens at most 32 levels and reads at most two elements. The + three flags parameters still hand such a collection to PowerShell's own + conversion, which ends the host with a stack overflow, as in rc8; not fixed + (no real input builds one, and a test would end the Pester process too). +- The message of a bad value is built inside a catch block, and a formatter + there must not throw: `Describe` called `ToString` of the one element outside + a guard, so an element whose `ToString` throws (a script method) ended a + piped command with an `ExtendedTypeSystemException` instead of one error for + that item (found by the last delta check of the second review; the version + before named a collection by its type and never formatted an element). Wrap + the whole formatter and fall back to the type name, in the short form + (`Type.ToString`; `FullName` spells out the assembly of every generic + argument). A test that pins a limit (ten elements named, two elements read) + is green on the code that it guards: prove it with a mutant of the limit (no + limit: 4 rows red; a limit of nine: 6 rows red). +- A loop that stops early runs `Dispose` of the enumerator, and `Dispose` can + fail: the catch of `TakeOneValue` returned the collection to PowerShell's + conversion, which combines a list bit by bit, so a sequence whose enumerator + throws in `Dispose` let a list through. The first patch (`isList = count > + 1` in the catch) fixed the reported shape (two elements) and left its + sibling (one element that holds a comma list); the closing check found it. + Fix the root: read with an explicit enumerator and release it in its own + guard, so that a failing release never changes what was read. The test needs + a compiled stand-in (`Add-Type`, as `PipelineControl.Tests.ps1` does); no + built-in enumerator fails in `Dispose`. - PowerShell calls the getter of a by-property-name parameter once per command, when a piped object first binds it (`p-getter-calls.ps1`). A test that must visit it pipes an object that has the property. A property getter diff --git a/.memory-bank/decisions/0027-open-items-before-5.0.0.md b/.memory-bank/decisions/0027-open-items-before-5.0.0.md index 8b01854..784d1dc 100644 --- a/.memory-bank/decisions/0027-open-items-before-5.0.0.md +++ b/.memory-bank/decisions/0027-open-items-before-5.0.0.md @@ -183,11 +183,23 @@ decided; the rest is to be chosen. Recommended defaults are the agent's. string), that a collection that holds itself never returned (the binder of rc8 ends the host with a stack overflow on it), and that the message named the type, not the typo: fixed in `e39aeed` and `da41a8e`, each with tests - that were red first (32 and 28 rows). Final suite on `de67883`: 2,116 cases - per configuration, 0 failed in four configurations (rc8: 1,615); the pages - and the help file are a fixpoint; PSScriptAnalyzer finds nothing in the 11 - changed scripts; the public surface equals the validated candidate; a matrix - of valid shapes differs from the published rc8 in exactly 9 list rows. + that were red first (32 and 28 rows). The last two checks found four Nits in + code that those fixes added or kept: the formatter of the message threw when + the text of an element throws (a terminating error that stopped a piped + command), its fallback named a generic type with the assembly of every type + argument, and an enumerator that throws in `Dispose` turned a list into a + value that PowerShell converts (first for two elements, then for one element + that holds a list): fixed in `ec58a18`, `ce34395`, `b436423`, and `696ac38`, + with 24, 2, 4, and 8 rows that were red first, and the pins of the limits + proved with two mutants. The last commit fixes the root, + not the shape: the collection is read with an explicit enumerator that is + released in its own guard, so a failing release changes nothing of what was + read. Final suite on `696ac38`: 2,162 cases per configuration, 0 failed in + four configurations (rc8: 1,615); the pages and the help file are a + fixpoint; PSScriptAnalyzer finds nothing in the 11 changed scripts; the + public surface equals the validated candidate; a matrix of valid shapes + differs from the published rc8 in exactly 9 list rows; both reviewers closed + their findings with "no finding". What the review found: @@ -219,3 +231,12 @@ Known limits, kept and to be stated to the maintainer: stays undisposed, a known limit of the .NET API. - In PowerShell 7, the case folding of `-Filter` differs from NTFS for a few exotic letters (finding F7 of the review; not fixed). +- A collection that holds itself, given to `-InheritanceFlags`, + `-PropagationFlags`, or `-AuditFlags`, ends the host with a stack overflow + inside PowerShell's own conversion, exactly as in rc8 (both reviewers + reproduced it in both editions, without the module too: any typed parameter + or cast does it). `-AccessType` and `-AppliesTo` reject it. Not fixed: no + real input builds such an object, a guard for the flags parameters would + need a visited-set walk of every argument, and a regression test would end + the Pester process before the fix. Named in the pull request text, not in + the CHANGELOG (user-visible changes only). diff --git a/.memory-bank/progress.md b/.memory-bank/progress.md index f0e3360..045b56c 100644 --- a/.memory-bank/progress.md +++ b/.memory-bank/progress.md @@ -119,19 +119,20 @@ archive in favor of WindowsAccessControl (Decision 18). creates an Allow entry); Decision 27 sets the scope of rc9, the designs were chosen on 2026-10-21, and four work items started (branch `ai/rc9-before-stable`). -- 2026-10-21: rc9 built and reviewed (Decision 27; branch `ai/rc9`, 32 commits - over `d0cb57c`, head `de67883`, local until he pushes). Four implementers +- 2026-10-21: rc9 built and reviewed (Decision 27; branch `ai/rc9`, 36 commits + over `d0cb57c`, head `696ac38`, local until he pushes). Four implementers worked test-first in worktrees (the five piped parameters, the 17 handlers and three inconsistencies, the library items, the filter); the chains were cherry-picked in order, so every fix sits in the commit of its item. Round 1 (three read-only reviewers) found a Blocker (the last-dot rule of the filter) and two Major findings (a named `$null`; a blank value of the other - parameter group, documented); round 2 (two reviewers, three checks) found - only Minor findings, among them completers that were not culture invariant - (`tr-TR`) and a list for `-AccessType` or `-AppliesTo`, which PowerShell - combines bit by bit; he chose to reject it. Final suite on `de67883`: 2,116 - cases per configuration, 0 failed in four configurations (rc8: 1,615); docs - fixpoint; analyzer clean; valid shapes differ from rc8 in 9 list rows only. + parameter group, documented); round 2 (two reviewers, five checks) found + only Minor findings and Nits, among them completers that were not culture + invariant (`tr-TR`) and a list for `-AccessType` or `-AppliesTo`, which + PowerShell combines bit by bit; he chose to reject it. Final suite on + `696ac38`: 2,162 cases per configuration, 0 failed in four configurations + (rc8: 1,615); docs fixpoint; analyzer clean; valid shapes differ from rc8 in + 9 list rows only; both reviewers: no finding. ## Stable capabilities