Browse Source

docs(memory-bank): close out the rc9 work with the head, the final suite, and the open work

Record that the branch ai/rc9 is complete at de67883 (32 commits over d0cb57c,
2,116 cases per configuration, 0 failed), what the two review rounds found,
that the maintainer chose to reject a list for -AccessType and -AppliesTo, and
what is left before the stable pull request (push, pull request, merge, and tag
of rc9 by the maintainer, then the lab acceptance of the published bytes).
Lessons for the next agent: PowerShell combines the numbers of a list for an
enumeration that is not a flags enumeration bit by bit, and code that opens a
one-element collection needs a depth limit.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
pull/132/head
Raimund Andree 1 week ago
parent
commit
90e04c6081
  1. 266
      .memory-bank/activeContext.md
  2. 16
      .memory-bank/debugging-insights.md
  3. 24
      .memory-bank/decisions/0027-open-items-before-5.0.0.md
  4. 90
      .memory-bank/progress.md
  5. 38
      .memory-bank/systemPatterns.md
  6. 6
      .memory-bank/techContext.md

266
.memory-bank/activeContext.md

@ -9,30 +9,53 @@ source: current task evidence
## Current focus ## Current focus
State at 2026-10-21: 5.0.0-rc8 is published and accepted. The State at 2026-10-21: 5.0.0-rc8 is published and accepted (tag `c719197`, CI run
maintainer merged #126 (the decisions of 2026-10-19) and #127 (`c719197`: the `39408140862`, Gallery 2026-10-20 10:40:58Z, GitHub 10:41:07Z, identity check
fix of the false "no access" of `Get-NTFSEffectiveAccess`, the known limit of passed; lab acceptance of the published bytes 10:38 to 11:47Z, record
the hard-link cmdlets in the pages and the CHANGELOG, and the label `rc8`) and `Tests/Lab/Acceptance-2026-10-20-published-rc8.md`, #128). `master` is
tagged `5.0.0-rc8` at about 10:28Z. The CI run `39408140862` passed, and the `d0cb57c`: the maintainer merged #128 (2026-10-21 05:48Z), the tests-only round
Gallery has rc8 since 10:40:58Z, GitHub since 10:41:07Z. The identity check #129 (08:24Z), and the Memory Bank #130 (08:47Z).
passed. The lab acceptance of the published bytes passed in one detached driver
(68 minutes, 10:38 to 11:47Z): three cells 1,374/0/12, the suite in 24 runs on The last prerelease before the stable 5.0.0 is rc9 (Decision 27). The branch
six machine classes, the first lab 245/0/1 per edition, every end state CLEAN `ai/rc9` (base `d0cb57c`, 32 commits, head `de67883`) is complete and
(record `Tests/Lab/Acceptance-2026-10-20-published-rc8.md`, #128). The boundary validated; it is local until the maintainer pushes it, opens the pull request
of the new error, a computer name of 32,718 characters, holds on Server 2019, (body: `C:\Temp\ntfs-rc9\final-msgs\pr-rc9-body.md`, temporary), merges it, and
2022, 2025, and Windows 11 26H1. He merged the record, #128, on 2026-10-21 at tags `5.0.0-rc9`. It contains: the five piped parameters of `Add-` and
05:48Z, the tests-only round for the plain gaps (#129, 08:24Z; Next step 6), `Remove-NTFSAccess` and `-NTFSAudit` are `object`, converted in the cmdlet
and this Memory Bank (#130, 08:47Z); `master` is `d0cb57c`. The new tests gave (`ParameterConversion`), so a typo for `Deny` no longer creates an Allow entry;
the same counts on the runner (three CI runs) and on six machine classes of the a list for `-AccessType` and `-AppliesTo` is rejected; the `-SecurityDescriptor`
labs (24 runs, 0 failed). A probe found that a typo in a piped `AccessType` sets report a failing descriptor and go on; the 17 owner-restore handlers pass
silently creates an Allow entry. He decided (Decision 27) that rc9 fixes that on what a later command raises; `Get-ChildItem2 -Filter` has one matcher with
family and the items 3 to 7 of its sheet, with a review, and chose the the Windows PowerShell 5.1 rules; the library fixes 3.1 to 3.3 and 3.10;
designs. Four work items run in worktrees under `C:\Temp\ntfs-rc9` (branch `Get-NTFSOrphanedAccess` writes an error; `-SecurityDescriptor` of
`ai/rc9-before-stable`; specs in the session folder `files\rc9\specs`). Open `Set-NTFSSecurityDescriptor` at position 1; tests that bind four parameters by
before the stable pull request: rc9 (integration, validation, review, property name; label `rc9`.
acceptance of about 70 minutes), his decision on #34 on 2026-11-02, and his
check of `PSGALLERY_API_KEY`. The stable change then touches only the label, Validation of `de67883`: the full suite in the four CI configurations, 2,116
the CHANGELOG, and `$publishedVersions`. 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);
PSScriptAnalyzer reports nothing in the 11 changed scripts; the public surface
differs from rc8 by 16 `object` properties, 5 completer classes, 1 protected
method, and 1 parameter position, and equals the candidate of round 1; a
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).
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
minutes, `Chain-Published.ps1`); his decision on #34 on 2026-11-02; his check of
`PSGALLERY_API_KEY`. The stable change then touches only the label, the
CHANGELOG, and `$publishedVersions` (add `5.0.0-rc9`). The Memory Bank of this
work is a separate pull request (branch `ai/memory-bank-merged`).
State at 2026-10-10: the maintainer integrated the release-gate stack into State at 2026-10-10: the maintainer integrated the release-gate stack into
`master` (#116, #120, #118, #119, #121; `fa0701b`, CI green; GitHub closed #117 `master` (#116, #120, #118, #119, #121; `fa0701b`, CI green; GitHub closed #117
@ -45,155 +68,66 @@ Decisions 22 and 24 on 2026-10-19 and decides 23 on 2026-11-02.
## Evidence ## Evidence
- rc6 Release run `37839669028`, attempt 2, succeeded; GitHub prerelease with - Evidence of rc9 is outside git, in the session folder
zip appeared 2026-10-09 07:01:34 UTC. The first attempt proves HTTP 409 `816cf47d-2f80-4eba-8ac9-41702c49560b\files\rc9`: the specs and review briefs,
after Gallery publication, not the earlier assumed retry chronology. `suite-full1` (first integration), `suite-final`, `suite-final2`,
- Integration on 2026-10-10 (UTC): #116 merged 09:10, #117 closed unmerged `suite-final3`, and `suite-final4` (the head `de67883`), the probes (`p-*.ps1`,
09:10:16 (events `base_ref_deleted`, `closed`), #120 merged 10:50, #118 `fixb-probe`, `shapes-r2`, `Run-Oracle.ps1`, `Run-Pathological.ps1`), the
11:12, #119 11:28, head branches deleted 11:34, CI on `master` at `fa0701b` published rc8 (`rc8-published`), and the analyzer and surface results. The
green 11:40. A `git merge-tree` simulation of the chain was conflict-free and review probes of the reviewers are in `C:\Temp\ntfs-rc9\review*-probes-*`
ended in the tree of the matrix branch. (temporary). The worktrees under `C:\Temp\ntfs-rc9` are temporary too.
- rc7 on 2026-10-10: tag at `fa0701b` about 12:20Z, CI run `38051611526` - Milestones of earlier gates (rc6 and rc7 releases, handoff 1, the operating
green, Gallery 12:30:57Z, GitHub 12:31:09Z. `Test-PublishedRelease.ps1` system matrix, handoff 5, the rc7 and rc8 acceptances) are in `progress.md`
(12:33Z): tag commit on `master`, Gallery SHA-512 matches the nupkg, 11 and in the records and reports under `Tests/Lab` and `Tests/Coverage`.
module files identical in nupkg and zip, manifest `5.0.0-rc7`; hashes in the
deployment notes, evidence in the session folder `published-rc7`.
- Gate 3 on the published rc7, 14:29 to 15:30 UTC (one detached driver; record
`Tests/Lab/Acceptance-2026-10-10-published-rc7.md`, evidence `gate3-rc7` with
a manifest): the three matrix cells (OSFile19, 22, 25 with OSWin11E, both
editions) 1,374 passed, 0 failed, 12 skipped, `LIVE_RESULT_VERIFIED` and
CLEAN in each; the suite in 24 runs on six machine classes without a failure
and with the host's skipped tests; the first lab with case 9 245 / 0 / 1 per
edition, CLEAN in four domains and on both machines. Each controller run
downloaded the package of the identity check (nupkg and DLL hashes equal).
Same counts as the final local candidate; no checkpoint was taken.
- Handoff 1 (paths), measured at `5a5d58b` (frozen Release, four configurations,
CI wrappers, then AltCover): 1,310 cases per configuration, zero failures
(baseline `3442194`: 914 cases); coverage 3,192/3,634 sequence points
(87.84%) and 1,273/1,978 branches (64.36%), against 74.21% and 50.39%. All 231
methods with 442 unvisited points are classified: 223 explained, 8 open for
the maintainer. Skip eligibility was checked by row: all 578 skipped rows
(137 distinct tests) are executed in two other configurations.
- Eleven defects were fixed, ten with a guard that is red before the fix and
green after it (a red/green matrix over ten states of the branch: 76 rows
red at the base `f11ff41`, none after the last fix; the leak of a native
buffer has no guard). Mutation rounds at `5a5d58b`: 25 of 26 detected, M25
(the check by type) an equivalent mutant. The matrix doesn't show that a test
preceded its fix: each fix commit carries both. Report:
`Tests/Coverage/Quality-Gate-Paths-2026-10-09.md`.
- Reviews: the custom `security-reviewer` can't start (its model is - Reviews: the custom `security-reviewer` can't start (its model is
unavailable; no override). The built-in `code-review` agent made nine static unavailable; no override); the built-in `code-review` agent reviewed the paths
passes of the paths work (no Blocker or Major) and four rounds on the matrix work, the matrix, rc8, and rc9; the built-in `security-review` agent found no
(one Major, record accuracy, resolved by the replay; Minors corrected); the exploitable vulnerability and two LOW items for the maintainer (Next step 5).
built-in `security-review` agent found no exploitable vulnerability and two - Raw evidence of the older gates is outside git: the session folder
LOW items left for the maintainer (Next step 5).
- Live candidate of 2026-10-09 (09:20 to 09:51 UTC): 330 passed, 0 failed, 2
expected skips; published rc6: 326 passed, 4 expected failures, 2 skips; the
11 tested files match the ZIP. Independent probes verified the fixture
removal on six machines (`Tests/Lab/Acceptance-2026-10-09-quality-gate.md`).
- Six checkpoints report Standard even after a successful ProductionOnly probe;
policy restored, no restore performed: don't claim verified Production
rollback evidence.
- Lab acceptance of the paths fixes, 2026-10-09 20:41 to 21:42 UTC: candidate
`83149ee` against its base `f11ff41`, the same 244 tests per edition (78
new): 486 passed, 0 failed, 2 expected skips against 338 passed, 148 failed
(each green on the candidate); fixture removal verified. Record:
`Tests/Lab/Acceptance-2026-10-09-quality-gate-paths.md`.
- Operating-system matrix, 2026-10-10 (record
`Tests/Lab/Acceptance-2026-10-10-os-matrix.md` with CSV tables): the suite of
the final candidate `fdd7a8b` passes on OSFile19/22/25, OSWin11E, OSWin11, and
the host (24 runs, no failure; the baseline `83149ee` fails 4 elevated and 20
basic-user tests on OSFile22 and OSFile25); the live controller passes in
three cells (1,374 passed, 0 failed, 12 skipped) and in the first lab with
case 9 (245 passed, 0 failed, 1 skipped per edition; fixture removed and
verified). The Admin-role effective-access failures in earlier cells were
stale account state, not the module: in a replay the baseline failed two of
three cells and the candidate one, and one lifetime of about ten minutes fits
43 runs of 27 cells (the Windows mechanism is unknown). The controller names
the case-3 account anew for each fixture (`1dec389`); four more cells with it
passed. A dry run of `Run-MatrixSequence.ps1 -Version 5.0.0-rc6` showed that
the published-package path works. Labs at 07:50 UTC on 2026-10-10: no fixture
or probe residue; `OSWin11E` shuts itself down an hour after its start.
- Handoff 5, the coverage unknowns, 2026-10-10 to 11 (report
`Tests/Coverage/Quality-Gate-Unknowns-2026-10-10.md`; raw evidence in the
session folder `816cf47d-2f80-4eba-8ac9-41702c49560b\files\qg-unknowns`
with a hash manifest). rc7 measured at `fa0701b` (four frozen
configurations, AltCover): 3,198/3,649 sequence points (87.64%), 1,090/1,168
explicit branch points; 232 unvisited methods, all classified. Live suite on
an instrumented copy (first lab and three cells) and unit suite on
`OSFile25`: together +9 sequence and +4 explicit branch points (the code of
`fdd7a8b`); no test or probe reaches the audit ownership retry or the audit
read denial. 101 new `It` blocks; 7 of 64 parameter sets closed, 51 partly,
1 open, 4 left to the maintainer. Cultures `de-DE` and `tr-TR`: two defects,
fixed. The piped
`AppliesTo` (Decision 26, debugging insights): fixed in `93ed2c7`; the
independent reviews then found a carry-over of the scope between piped
objects (`9783d2a`; rc7 had it for descriptor objects) and two false
sentences of the documents about empty values (`7bc7925`, `2112ee3`). Final
commit `2112ee3`, product code of `9783d2a` (its help file differs from the
package that the labs accepted): 1,492 cases per configuration, 3,266/3,668
points, 183 unvisited methods, all classified. The labs accepted the package
(`ap7`, `ap8`): first lab 245/0/1 per edition; the 22 files on
`OSFile19/22/25` and `OSWin11` 1,189/0 in 16 configurations; the three cells
229/0/2 per edition; all end states clean at 13:45Z. The first start of the
cells did nothing: a `powershell.exe` that PowerShell 7 starts inherits its
`PSModulePath` (lab README). Server Core, ARM64, a localized system, and
non-Windows servers are out of scope (Decision 25).
- rc8, 2026-10-20: fix (b) test-first on `ai/fix-effective-access-init-errors`.
A `-ServerName` of 40,000 characters gave `Synchronize` and no error before
and gives an error now; two tests were red and are green in four
configurations, and the suite has 1,494 cases per configuration, 0 failed.
The independent review (`code-review`) found one Minor, the warning "based on
this computer" before the error (fixed, with tests), and three Nits. The
acceptance evidence is `rc8-published` in the session folder
`816cf47d-2f80-4eba-8ac9-41702c49560b\files\qg-unknowns` (430 files, with a
manifest); the published hashes are in the deployment notes.
- Raw evidence is outside git: the session folder
`4b12e2f4-d4c7-4a5d-883a-ddb7421c4848\files` (`qg-paths`, the matrix runs, the `4b12e2f4-d4c7-4a5d-883a-ddb7421c4848\files` (`qg-paths`, the matrix runs, the
night log) and night log), `26f151b6-e46f-49bd-9398-b27e20603949\files\quality-gate-3442194-20261009`,
`26f151b6-e46f-49bd-9398-b27e20603949\files\quality-gate-3442194-20261009`. and `816cf47d-2f80-4eba-8ac9-41702c49560b\files\qg-unknowns` (430 files of
`rc8-published`, with a manifest; the published hashes are in the deployment
notes).
- Six checkpoints of the lab report Standard even after a successful
ProductionOnly probe; policy restored, no restore performed: don't claim
verified Production rollback evidence.
## Next step ## Next step
1. Gate 3 is done for the published rc7 and rc8 (the records). The stable build 1. The maintainer pushes `ai/rc9`, creates the pull request, merges it after
is accepted through rc8 (Decision 21, "Closing the gate"). Open: keep or CI, and tags `5.0.0-rc9` (commands in the reply of 2026-10-21; every release
replace the matrix VMs (about 60 GB, saved between runs) and the evaluation step is his). Then run `Chain-Published.ps1 -Version 5.0.0-rc9 -Tag 5.0.0-rc9
client (it shuts down every hour; `OSWin11E` is off), and a domain cell for -Evidence <dir>` from the session files (about 70 minutes, detached, with the
Windows 11 26H1, whose client loses the secure channel to the Server 2025 heartbeat; save the labs afterwards) and write the acceptance record
domain controller. `Chain-Published.ps1` in the session files runs the whole `Tests/Lab/Acceptance-<date>-published-rc9.md`. A defect that it finds needs
sequence (not in the kit; deployment notes). rc10.
2. The stable pull request: no `Prerelease`, `## [5.0.0] - <date>` with an empty 2. The stable pull request: no `Prerelease`, `## [5.0.0] - <date>` with an empty
`[Unreleased]` and the links, and `5.0.0-rc8` in `$publishedVersions` (the `[Unreleased]` and the links, and `5.0.0-rc9` in `$publishedVersions` (the
list ends at rc7 now). The maintainer checks the expiry of list ends at rc7 now; rc8 comes with the rc9 pull request). The maintainer
`PSGALLERY_API_KEY` first, merges, and tags. Every release step is his. checks the expiry of `PSGALLERY_API_KEY` first, merges, and tags.
3. Decision 27 (2026-10-21): rc9 changes the library-only items, the dot 3. #34 waits for a tester until 2026-11-02 (Decision 23, option 3; checklist:
patterns of `Get-ChildItem2 -Filter`, the 17 owner-restore handlers, the
errors of the descriptor sets, and three inconsistencies; the designs are
chosen, four work items are in progress. Decisions 22 and 24 are accepted.
4. #34 waits for a tester until 2026-11-02 (Decision 23, option 3; the
follow-up went up on 2026-10-19, no reply yet; checklist:
`Tests/Lab/Non-Windows-File-Server-Test.md`). On that date the maintainer `Tests/Lab/Non-Windows-File-Server-Test.md`). On that date the maintainer
chooses between waiting longer and accepting the untested risk with a chooses between waiting longer and accepting the untested risk with a
release-note caveat. No agent can accept it. release-note caveat. No agent can accept it.
5. Of the two LOW findings of the security review (record, Limits), the 4. Open housekeeping: keep or replace the matrix VMs (about 60 GB, saved between
swallowed initialization errors of `GetEffectiveAccess` are fixed in rc8 runs) and the evaluation client (it shuts down every hour; `OSWin11E` is
(`25fe775`, #127): an error instead of a false "no access", and the warning off); a domain cell for Windows 11 26H1, whose client loses the secure
only with a result. He still decides the other: the ACL of the stage channel to the Server 2025 domain controller; the cleanup list before the
folders under `C:\` in the lab kit (they inherit Authenticated Users: archive (AppVeyor, Read the Docs, wiki, `test/transfer`, old checkpoints) is
Modify; protecting them is a design change of the controller and needs a new the maintainer's. The tests-round report still says that the new tests "have
acceptance). rc9 adds to the help that a local standard user who asks about not run on Windows Server 2019/2022/Windows 11"; the 24 lab runs of
a domain account still gets "Access is denied" (Decision 27). 2026-10-21 changed that (fix in a later documentation pull request).
6. Handoff 5 is done and merged (Evidence). Decided on 2026-10-19 (Decision 5. Of the two LOW findings of the security review, the swallowed initialization
21): the hard-link names under another root stay a known limit; the pages errors of `GetEffectiveAccess` are fixed in rc8; he still decides the other:
and the CHANGELOG say so since rc8. The tests-only round for the plain items the ACL of the stage folders under `C:\` in the lab kit (they inherit
(68 `budget` mentions) ran on 2026-10-20: four implementers, one Authenticated Users: Modify; protecting them is a design change of the
`ParameterSets.*` file each, merged as #129: 89 `It` blocks, 121 cases, the controller and needs a new acceptance).
suite 1,494 to 1,615 per configuration, 0 failed; 38 of 64 sets closed, 26 6. Known limits after rc9, for the archive (Decision 27): `Get-FileHash2
with a leftover (16 Limit, 7 MaintainerDecision, 3 would-pin), no defect; -Algorithm` keeps the silent default for a piped value that does not convert;
report `Tests/Coverage/Quality-Gate-Test-Round-2026-10-20.md`. The runner's three settings still read their value with an unchecked cast;
counts equal the local run in three CI runs. No plain gap is left. A defect `PrivilegeEnabler` is not disposed in some paths; `Get-NTFSEffectiveAccess`
that a test finds needs his decision and rc9. Decision 27 settles the rest: fails with an `ArgumentOutOfRangeException` on a FAT32 volume or an item with
rc9 fixes the 10 rows and the piped optional parameters (designs to a NULL DACL (older than rc9); 9 of the 17 owner-restore handlers and the
follow); the audit paths over SMB are accepted (#34); the tests for the 8 error branch of `Get-NTFSOrphanedAccess` cannot be pinned by a test.
getters follow rc9.
7. Do not release stable 5.0.0 or equate a percentage with gate closure. 7. Do not release stable 5.0.0 or equate a percentage with gate closure.

16
.memory-bank/debugging-insights.md

@ -36,6 +36,11 @@ fails without it (Decision 16).
both: two mutations proved it), and is proved red on the previous build and both: two mutations proved it), and is proved red on the previous build and
green on the new one in all four configurations green on the new one in all four configurations
(`Tests/ItemCmdlets.Tests.ps1`, `Tests/ObjectApis.Tests.ps1`). (`Tests/ItemCmdlets.Tests.ps1`, `Tests/ObjectApis.Tests.ps1`).
- The argument completers of rc9 had the same flaw (`WildcardPattern` with
`IgnoreCase` only: `THISFOLDERO<Tab>` found nothing under `tr-TR`); the
second review found it, not the scan. A Turkish test word must put a capital
`I` against a lowercase `i` of the name: `NOPROPAGATEINH` faces the capital
`I` of `Inherit` and passes without the fix, so prove every row red first.
## A test oracle that is wrong on a domain member ## A test oracle that is wrong on a domain member
@ -148,6 +153,17 @@ fails without it (Decision 16).
completion of the names has to be rebuilt (quotes, wildcards, declaration completion of the names has to be rebuilt (quotes, wildcards, declaration
order); help shows `Object`. Probe every form of a value before you write a order); help shows `Object`. Probe every form of a value before you write a
claim, and ask a reviewer for the negative space. claim, and ask a reviewer for the negative space.
- PowerShell accepts a comma list or an array for an enumeration that is not
`[Flags]` and combines the numbers bit by bit (a logical or):
`-AppliesTo 'ThisFolderOnly,FilesOnly'` made a `FilesOnly` entry and
`-AccessType 'Allow,Deny'` a `Deny` entry (4.2.6 and rc8 alike). The
conversion rejects a list for such an enumeration, in whatever kind of
collection it comes; a single name and a one-element collection stay valid.
A matrix of valid shapes, run on the published build and on the new one,
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.
- PowerShell calls the getter of a by-property-name parameter once per - 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 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 that must visit it pipes an object that has the property. A property getter

24
.memory-bank/decisions/0027-open-items-before-5.0.0.md

@ -164,6 +164,30 @@ decided; the rest is to be chosen. Recommended defaults are the agent's.
folder). The findings became follow-up commits, and the branch `ai/rc9` was folder). The findings became follow-up commits, and the branch `ai/rc9` was
rebuilt with `git cherry-pick` in the order of each chain, so every fix sits rebuilt with `git cherry-pick` in the order of each chain, so every fix sits
in the commit of its item and any item can still be dropped. in the commit of its item and any item can still be dropped.
- Round 2 (brief `rc9\REVIEW-BRIEF-2.md`): two reviewers read the final tree
(scope A the four add and remove cmdlets, scope B everything else), then
checked the fixes of their own findings. No Blocker and no Major; nine Minor
findings: five wrong or incomplete statements in the pages and the CHANGELOG
(a script block "was silently ignored" when it was evaluated per object;
`-AppliesTo $null` keeps the binder's error; the carry-over of the scope
affected only objects with one flags property; the descriptor sets that go
on after a failing descriptor are a breaking change; the PowerShell 7 list of
patterns was too narrow), the trailing blank and `..` of the filter
(documented, not changed), a stale header of two test files, the completers
without `CultureInvariant` (fixed), and a list for `-AccessType` and
`-AppliesTo` whose numbers PowerShell combines bit by bit (the maintainer
chose on 2026-10-21 to reject it in rc9; older than rc9, the same in
4.2.6). Two more checks of the fixes found that the rejection could be
bypassed through other kinds of collection (a hash set, a queue, the keys of
a dictionary, a LINQ result, a one-element collection that holds a comma
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.
What the review found: What the review found:

90
.memory-bank/progress.md

@ -17,51 +17,31 @@ merged #125 (Handoff 5) and #124 (Dependabot) and decided the path to stable
(Decision 21, "Closing the gate"); on 2026-10-20 he merged #126 (the decisions) (Decision 21, "Closing the gate"); on 2026-10-20 he merged #126 (the decisions)
and #127 (the rc8 fix and label) and tagged rc8; on 2026-10-21 he merged #128 and #127 (the rc8 fix and label) and tagged rc8; on 2026-10-21 he merged #128
(the rc8 record), #129 (tests), and #130 (this file). The published rc7 and (the rc8 record), #129 (tests), and #130 (this file). The published rc7 and
rc8 passed their lab acceptance in the matrix and in the first lab. Stable rc8 passed their lab acceptance in the matrix and in the first lab. rc9
Gallery version: 4.2.6. After 5.0.0, archive in favor of WindowsAccessControl (Decision 27) is built on the local branch `ai/rc9` and waits for his push,
(Decision 18). pull request, merge, and tag. Stable Gallery version: 4.2.6. After 5.0.0,
archive in favor of WindowsAccessControl (Decision 18).
## Recent milestones ## Recent milestones
- 2026-10-02 to 2026-10-06: documentation/help aligned with source, CI and - 2026-10-02 to 2026-10-09: documentation and help aligned with the source, CI
wiki moved to GitHub Actions, versioning/release automation established, and wiki on GitHub Actions, release automation, and rc1 to rc6 published
and prereleases rc1 to rc4 published. Earlier detail is in git, (rc5: the remote effective-access fallback, Decision 20; rc6 and the rc7
`CHANGELOG.md`, `Docs/Version-History.md`, and Decisions 1 to 19. candidate: Phase 2 and the behavior changes of Decision 22). #114 (`fcb370e`)
- 2026-10-07: lab comparison of rc2/rc4 reproduced #34 over SMB and proved and #115 (`b51d970`) merged. The rc6 release run failed with HTTP 409 after
changed-section writes preserve the owner. Remote effective-access Gallery publication and attempt 2 succeeded (GitHub prerelease 2026-10-09
fallback returned no result; fixed test-first for rc5 (Decision 20). 07:01:34Z); the log does not establish the earlier assumed timeout cause.
- 2026-10-08: #114 merged (`fcb370e`), rc5 published and live-tested. Detail: git, `CHANGELOG.md`, `Docs/Version-History.md`, Decisions 1 to 22.
Decision 21 established the quality gate. Corrected four-run coverage: - 2026-10-09: the autonomous follow-up (#117, then #120, through `3442194`) and
rc5 58.1% sequence points/38.0% branches, not the initial one-run result. handoff 1 (#118) took the suite from 202 cases above rc7 to 1,310 per
- 2026-10-08: rc6 Phase 2 (basic-user CI, parameter-set and error tests, configuration with zero failures and 3,192/3,634 sequence points (87.84%;
expanded domain/SMB cases, fixes for privilege cleanup, path resolution, 74.21% before); publication recovery verifies the exact SHA-512 identity.
ownership retries, item conflicts, output equality, inherited flags; suite Eleven defects were fixed, ten with a guard that is red before the fix (76
677, 68.14% sequence/44.32% branches; lab acceptance of `7b0781f` passed; rows red at the base), among them a later command's exception that cmdlets
two review passes) and rc7 (Decision 22: breaking link binding and error swallowed (a `throw` made `Remove-Item2` remove the next item) and a privilege
changes, SimpleAccess traversal, cross-volume folder preservation, named left enabled. Lab acceptance, `83149ee` against `f11ff41`: 486 passed, 0
effective-access warnings; suite 712; one review without Blocker or Major; failed against 338 passed, 148 failed. Report in `Tests/Coverage`; record
lab candidate `dc6e9f5`: 326 passed, 2 skipped, cleanup verified). `Tests/Lab/Acceptance-2026-10-09-quality-gate-paths.md`.
- 2026-10-08: #115 merged (`b51d970`) and tagged rc6. Release run
`37839669028` failed with HTTP 409 after Gallery publication. The log
does not establish the previously assumed initial timeout/retry cause.
Published rc6 live tests differed only in rc7's warning expectation.
- 2026-10-09: release attempt 2 succeeded; rc6 GitHub prerelease and zip
appeared at 07:01:34 UTC. #116 passed CI on `d25647d`.
- 2026-10-09: autonomous follow-up on `ai/quality-gate-coverage` (#117, then
#120), through `3442194`: 202 cases above rc7; fixed rooted result paths and
the first-hidden-item omission; publication recovery verifies the exact
SHA-512 identity, not merely the version. Suite: 914 per configuration, zero
failures; 2,641/3,559 sequence points (74.21%), 974/1,933 branches (50.39%).
Live comparison: candidate 330 passed, 0 failed, 2 expected skips (`7594e0c`).
- 2026-10-09: handoff 1 (#118): suite 914 to 1,310 per configuration, zero
failures; 3,192/3,634 sequence points (87.84%), 1,273/1,978 branches; all 231
unvisited methods classified (223 explained, 8 open). Eleven defects fixed,
ten with a guard that is red before the fix and green after it (76 rows red
at the base), among them a later command's exception that cmdlets swallowed
(a `throw` made `Remove-Item2` remove the next item) and a privilege left
enabled. Lab acceptance, `83149ee` against `f11ff41`: 486 passed, 0 failed, 2
expected skips against 338 passed, 148 failed. Report in `Tests/Coverage`;
record `Tests/Lab/Acceptance-2026-10-09-quality-gate-paths.md`.
- 2026-10-09 to 10: handoffs 2 to 4 under the maintainer's delegation (decisions - 2026-10-09 to 10: handoffs 2 to 4 under the maintainer's delegation (decisions
D1 to D47 in the night log of the session files). The matrix lab D1 to D47 in the night log of the session files). The matrix lab
`NtfsSecurityOsMatrixLab` (Server 2019, 2022, 2025, a Windows 11 Enterprise `NtfsSecurityOsMatrixLab` (Server 2019, 2022, 2025, a Windows 11 Enterprise
@ -139,6 +119,19 @@ Gallery version: 4.2.6. After 5.0.0, archive in favor of WindowsAccessControl
creates an Allow entry); Decision 27 sets the scope of rc9, the designs were 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 chosen on 2026-10-21, and four work items started (branch
`ai/rc9-before-stable`). `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
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.
## Stable capabilities ## Stable capabilities
@ -152,12 +145,13 @@ Gallery version: 4.2.6. After 5.0.0, archive in favor of WindowsAccessControl
## Open work ## Open work
1. Decision 21 gate: the published rc7 and rc8 are accepted in the matrix and 1. Decision 21 gate: the published rc7 and rc8 are accepted in the matrix and
the first lab (records); stable follows rc8 (Decision 21, "Closing the the first lab (records); stable follows rc9 (Decision 27): after his push,
gate"). Do not release 5.0.0 until the other gates close: rc9 (Decision pull request, merge, and tag of rc9 the agent runs the lab acceptance of
27), the decision on #34 on 2026-11-02, and the key check. Release steps: the published bytes (about 70 minutes). Do not release 5.0.0 until the other
`Docs/Contributing/05-Releasing.md`; remove the prerelease label, date gates close: that acceptance, the decision on #34 on 2026-11-02, and the key
`[5.0.0]`, add the last prerelease (rc8) to `$publishedVersions` (never the check. Release steps: `Docs/Contributing/05-Releasing.md`; remove the
version of the manifest), tag through CI. prerelease label, date `[5.0.0]`, add the last prerelease (rc9) to
`$publishedVersions` (never the version of the manifest), tag through CI.
2. Issues: #110's seven items were addressed by rc6, but #115 deliberately 2. Issues: #110's seven items were addressed by rc6, but #115 deliberately
used no closing keyword. #34 stays open for non-Windows owner feedback used no closing keyword. #34 stays open for non-Windows owner feedback
or maintainer acceptance. #16, #21, #45, #89 await reporters. #68 tracks or maintainer acceptance. #16, #21, #45, #89 await reporters. #68 tracks

38
.memory-bank/systemPatterns.md

@ -1,6 +1,6 @@
--- ---
status: current status: current
last-verified: 2026-10-19 last-verified: 2026-10-21
owner: active-agent owner: active-agent
source: repository and regression evidence source: repository and regression evidence
--- ---
@ -15,13 +15,10 @@ source: repository and regression evidence
| `NTFSSecurity.Init.ps1` | Loads Security2/privilege assemblies and prepends formatting | | `NTFSSecurity.Init.ps1` | Loads Security2/privilege assemblies and prepends formatting |
| `NTFSSecurity.dll` | 36 PowerShell cmdlets; BaseCmdlet path/privilege behavior | | `NTFSSecurity.dll` | 36 PowerShell cmdlets; BaseCmdlet path/privilege behavior |
| `Security2.dll` | DACL/SACL objects, owners, inheritance, effective access, Win32 | | `Security2.dll` | DACL/SACL objects, owners, inheritance, effective access, Win32 |
| AlphaFS | Long-path files/directories/links | | AlphaFS, PrivilegeControl, ProcessPrivileges | Long-path files/directories/links; token privilege operations |
| PrivilegeControl / ProcessPrivileges | Token privilege operations |
| `en-US/NTFSSecurity.dll-Help.xml` | Committed help generated from cmdlet Markdown | | `en-US/NTFSSecurity.dll-Help.xml` | Committed help generated from cmdlet Markdown |
## Decisions ## Decisions (read only the task-relevant records; the index routes)
Read only task-relevant records; the index controls routing.
| # | Decision | | # | Decision |
| --- | --- | | --- | --- |
@ -51,6 +48,7 @@ Read only task-relevant records; the index controls routing.
| 24 | [The operating-system matrix lab](decisions/0024-os-matrix-lab.md) | | 24 | [The operating-system matrix lab](decisions/0024-os-matrix-lab.md) |
| 25 | [Four environments are out of scope for the tests](decisions/0025-out-of-scope-environments.md) | | 25 | [Four environments are out of scope for the tests](decisions/0025-out-of-scope-environments.md) |
| 26 | [No default parameter set for Add and Remove (access, audit)](decisions/0026-no-default-parameter-set-add-remove.md) | | 26 | [No default parameter set for Add and Remove (access, audit)](decisions/0026-no-default-parameter-set-add-remove.md) |
| 27 | [The open items before 5.0.0 and the piped optional parameters (rc9)](decisions/0027-open-items-before-5.0.0.md) |
## Patterns ## Patterns
@ -67,36 +65,38 @@ Read only task-relevant records; the index controls routing.
attempts all cleanup, and preserves explicit enables. Dispose has no stream. attempts all cleanup, and preserves explicit enables. Dispose has no stream.
- Pipeline getters never throw; per-item errors name input and allow continuation. - Pipeline getters never throw; per-item errors name input and allow continuation.
- Folder moves never use CopyAllowed; preserve cross-volume source folders. - Folder moves never use CopyAllowed; preserve cross-volume source folders.
- Apply implied Hidden/Force before deciding to emit, including the first item. Apply implied Hidden/Force before deciding to emit, including the first item.
- A catch-all for one item's failures passes on what a later command raises - A catch-all for one item's failures passes on what a later command raises
through a Write call (`IsFromLaterCommand`, `PipelineControl`; see through a Write call (`IsFromLaterCommand`, `BaseCmdlets.cs`); add a row to
`BaseCmdlets.cs`); add a row to `Tests/PipelineControl.Tests.ps1` for a new `Tests/PipelineControl.Tests.ps1` for a new cmdlet. Record an enabled
cmdlet. Record an enabled privilege before the next write. privilege before the next write.
- `Get-ChildItem2 -Filter` matches culture invariant; `*.*` means `*`. - `Get-ChildItem2 -Filter`: one matcher, 5.1 DOS wildcard rules (Decision 27).
- Optional by-name pipeline parameters are `object` + `ParameterConversion` (Decision 27).
### Tests and documentation ### Tests and documentation
- Tests import Release in isolated processes, both editions and privilege - Tests import Release in isolated processes, both editions and privilege
modes, with guarded sandboxes; a skip needs an eligible counterpart. modes, with guarded sandboxes; a skip needs an eligible counterpart.
- Assert persisted state, errors/targets, continuation, and no failed - Assert persisted state, errors/targets, continuation, and no failed PassThru
PassThru output. Prove new characterization guards with bounded mutations output. Prove characterization guards with bounded mutations (together only
(one round together only if no guard can fail because of another); restore if no guard can fail because of another); restore source and rebuild before
source exactly and rebuild before green validation or packaging. A retry green runs or packaging. A retry test asserts its precondition (the plain
test asserts its precondition (the plain write is denied). write is denied).
- CI scripts and focused runs set `Stop`: a test that needs a non-terminating - CI scripts and focused runs set `Stop`: a test that needs a non-terminating
error names `-ErrorAction Continue`. Don't name a test variable like an error names `-ErrorAction Continue`. Don't name a test variable like an
automatic variable (`$foreach`): Pester runs the block inside a foreach. automatic variable (`$foreach`): Pester runs the block inside a foreach.
- Fixture DACLs use .NET SetAccessControl, not Set-Acl's unintended SACL writes. - Fixture DACLs use .NET SetAccessControl, not Set-Acl's unintended SACL writes.
- Scope/descendant expectations are independent of the production converter. - Scope/descendant expectations are independent of the production converter.
- Desktop platyPS: generate help, rebuild, round-trip unchanged, check links; - Desktop platyPS: generate help, rebuild, round-trip unchanged, check links;
platyPS 0.14.2 turns paired asterisks into emphasis, even in backticks. 0.14.2 turns paired asterisks into emphasis, even in backticks, and
`Update-MarkdownHelp` reads `Position` from the committed help file.
- Live tests use only approved lab targets, SMB then independent server state; - Live tests use only approved lab targets, SMB then independent server state;
Get/SetFileSecurity preserves stored DACLs; rights oracles use S4U tokens. Get/SetFileSecurity preserves stored DACLs; rights oracles use S4U tokens.
- A suite that is green on the host and CI misses defects that need a domain - A suite that is green on the host and CI misses defects that need a domain
member or another token (the matrix found three): also run a domain member, member or another token (the matrix found three): also run a domain member,
other builds, and a basic user; a failure that follows cell order points to other builds, and a basic user; a failure that follows cell order points to
stale account state (Decision 24). Oracles differ there too: `Get-Acl -Audit` stale account state (Decision 24). `Get-Acl -Audit` reads an item without
reads an item without audit entries as SACL-protected; read the SACL alone. audit entries as SACL-protected; read the SACL alone.
### CI, publication, and integration ### CI, publication, and integration

6
.memory-bank/techContext.md

@ -42,9 +42,9 @@ source: repository and executable evidence
## Constraints ## Constraints
- Manifest: ModuleVersion 5.0.0, prerelease rc8, published 2026-10-20 (tag at - Manifest: ModuleVersion 5.0.0, prerelease rc8 (tag at `c719197`; `ai/rc9`
`c719197`). Latest stable 4.2.6. `$publishedVersions` ends at rc7; the reuse sets rc9). Latest stable 4.2.6. `$publishedVersions` ends at rc7; the reuse
test fails if it holds the manifest's version, so the stable change adds rc8. test fails if it holds the manifest's version, so rc9 adds rc8, stable rc9.
- Changed-section writes preserve unchanged owner/group/DACL/SACL (19). - Changed-section writes preserve unchanged owner/group/DACL/SACL (19).
Roots use root-folder APIs, not AlphaFS device security (#41). Roots use root-folder APIs, not AlphaFS device security (#41).
- CHANGELOG contains user-visible changes only (7); tests and CI-only fixes - CHANGELOG contains user-visible changes only (7); tests and CI-only fixes

Loading…
Cancel
Save