From d5bfa37f6145908cb5aef3f9852e8be2c453f34d Mon Sep 17 00:00:00 2001 From: Raimund Andree Date: Sat, 10 Oct 2026 04:22:10 +0000 Subject: [PATCH] chore(memory-bank): record the operating-system matrix and Decision 24 Decision 24 (proposed): the matrix lab, what its deployment and the runs showed, and what the maintainer decides. The context, patterns, progress, and deployment notes carry the lessons: the Authz regime of a domain member, the stale Kerberos S4U state of a re-created account, the evaluation client, and the integration of the stacked branches. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant --- .memory-bank/activeContext.md | 64 ++++++--- .memory-bank/decisions/0024-os-matrix-lab.md | 136 +++++++++++++++++++ .memory-bank/deployment-notes.md | 135 ++++++++++++++++++ .memory-bank/progress.md | 29 +++- .memory-bank/systemPatterns.md | 16 +++ .memory-bank/techContext.md | 44 ++++++ 6 files changed, 402 insertions(+), 22 deletions(-) create mode 100644 .memory-bank/decisions/0024-os-matrix-lab.md create mode 100644 .memory-bank/deployment-notes.md diff --git a/.memory-bank/activeContext.md b/.memory-bank/activeContext.md index 5a6e2c5..21d0c3d 100644 --- a/.memory-bank/activeContext.md +++ b/.memory-bank/activeContext.md @@ -1,6 +1,6 @@ --- status: current -last-verified: 2026-10-09 +last-verified: 2026-10-10 owner: active-agent source: current task evidence --- @@ -9,11 +9,24 @@ source: current task evidence ## Current focus -Handoff 1 of the quality gate is finished on `ai/quality-gate-paths`, from the -reviewed head `f11ff41` of #117: 28 commits, which the maintainer pushed as -draft #118 (CI green on `83149ee`). Both -stacked PRs stay open and green; rc6 remains the latest published -candidate and 4.2.6 the stable Gallery version. Every C# method that no test +The maintainer asked on 2026-10-09 at 21:21 UTC to continue with the release-gate +handoffs and to decide and report later. Handoff 1 (paths) is draft #118 +(`83149ee`, CI green; stacked on #117 and #116, all open; rc6 is the latest +published candidate, 4.2.6 the stable Gallery version). Handoff 2 (operating-system +matrix) is the local branch `ai/quality-gate-lab-matrix`, stacked on #118 and not +pushed: the lab `NtfsSecurityOsMatrixLab`, three fixes of the module that the +matrix found (`962887a`, `fdd7a8b`), the kit, the controller changes, and the +record `Tests/Lab/Acceptance-2026-10-10-os-matrix.md` (Decision 24, proposed). +The final local candidate `fdd7a8b` passes the module's suite on five operating +systems and the host (24 runs, no failure) and the live controller in three +cells (1,374 passed, 0 failed, 12 skipped). Handoff 3: Decision 22 was confirmed +under the delegation and stays proposed; nothing is published. Handoff 4: +Decision 23 (the #34 dossier); the risk acceptance is the maintainer's. The +agent's decisions of the night are D1 to D26 in +`decisions-night-2026-10-09.md` of the session files. Stable 5.0.0 stays gated. + +The earlier state of handoff 1, from the reviewed head `f11ff41` of #117: 28 +commits, which the maintainer pushed as draft #118. Every C# method that no test visits is classified (223 explained, 8 open for the maintainer), and the other paths have behavior tests. Eleven defects were fixed, ten of them with a regression guard that is red before the fix and green after it (owner @@ -104,24 +117,39 @@ open. media present, OS detection cache empty. #34 has no reply since Oct 6. - Full evidence: session artifact `quality-gate-3442194-20261009`; repository report `Tests/Lab/Acceptance-2026-10-09-quality-gate.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` on OSFile19, + OSFile22, OSFile25, OSWin11E, OSWin11, and the host, four configurations each, + zero failures, skipped tests identical to the host's; the baseline `83149ee` + fails 4 elevated and 20 basic-user tests on the domain machines. Live: run + `rc7l`, three cells, 1,374 passed, 0 failed, 12 skipped. The Admin-role + effective-access failures of the earlier cells came from re-creating the + accounts under the same names (stale Kerberos S4U state, probe in the record), + not from the module; the controller now names the account of case 3 anew for + each fixture (`1dec389`). Reviewed by the built-in code-review agent (custom + `security-reviewer` unavailable): approve with Minor, fixed. ## Next step -1. The maintainer reviews and integrates `ai/quality-gate-paths` (stacked on - #117; no remote change was made here) and decides the open items listed - in the report: `FileSecurity` conversions, `RemoveAll` account filters, - lazy path overloads, abandoned `PrivilegeEnabler`, dot patterns of - `Get-ChildItem2 -Filter`, the 17 owner-restore handlers without the - later-command check, unused classes (Decisions 21/22). -2. Gate 3: the affected live acceptance of the paths fixes is repeated (record - above). Accept the published package again before the next candidate counts - as accepted; no local upload. -3. Retain stacked-PR order (15): #116, then #117, then #118; a local merge +1. The maintainer pushes `ai/quality-gate-lab-matrix` as a draft PR with base + `ai/quality-gate-paths` and decides which of the three module fixes belong to + rc7 (each is its own commit). He reviews and integrates the stack: #116, then + #117, then #118, then the matrix branch (Decision 24). +2. He decides the open items listed in the paths report: `FileSecurity` + conversions, `RemoveAll` account filters, lazy path overloads, abandoned + `PrivilegeEnabler`, dot patterns of `Get-ChildItem2 -Filter`, the 17 + owner-restore handlers without the later-command check, unused classes + (Decisions 21/22). +3. Gate 3: accept the published package in the first lab and in every cell of + the matrix (`Run-MatrixSequence.ps1 -Version`) before the candidate counts as + accepted; no local upload. The paths fixes were accepted locally (record + above). +4. Retain stacked-PR order (15): #116, then #117, then #118; a local merge in that order gives exactly the tree of #118. Confirm or change Decision 22. -4. #34 stays open (Decision 23): the maintainer chooses between waiting for a +5. #34 stays open (Decision 23): the maintainer chooses between waiting for a test of the published candidate on the NetApp, EMC, and IBM ESS servers of the reporters (checklist: `Tests/Lab/Non-Windows-File-Server-Test.md`) and accepting the untested risk with a release-note caveat. No agent can accept it. -5. Do not release stable 5.0.0 or equate a percentage with gate closure. +6. Do not release stable 5.0.0 or equate a percentage with gate closure. diff --git a/.memory-bank/decisions/0024-os-matrix-lab.md b/.memory-bank/decisions/0024-os-matrix-lab.md new file mode 100644 index 0000000..89eaad2 --- /dev/null +++ b/.memory-bank/decisions/0024-os-matrix-lab.md @@ -0,0 +1,136 @@ +--- +status: proposed +date: 2026-10-09 +last-verified: 2026-10-10 +owner: shared +source: agent decisions under the maintainer's delegation of 2026-10-09 (Handoff 2); the scope follows Decision 21, phase 3 +--- + +# Decision 24: The operating-system matrix lab + +- Context: Decision 21 requires the live tests on more operating systems, + "such as a Windows 11 client and Server 2019 and 2022 file servers", and the + published package must pass them. Every machine of `WindowsAccessControlLab` + is Server 2025. Handoff 2 asks for the maintainer's approval of scope and + topology before new VMs. On 2026-10-09 at 21:21 UTC the maintainer, going to + bed, wrote "you can do whatever is required with the lab" and told the agent + to decide and report later. The agent took that as the approval for the + minimal matrix below and for nothing broader. It is the agent's decision, so + the status stays `proposed` until the maintainer confirms it. +- Choice: + 1. Cells: a Windows 11 client with each file server (Server 2019 Datacenter + 10.0.17763.1217, Server 2022 Datacenter 10.0.20348.4773, Server 2025 + Datacenter 10.0.26100.32690), the module in Windows PowerShell 5.1 and + PowerShell 7 in every cell. The client was planned as Windows 11 Pro + 26H1 (10.0.28000.1836). It cannot keep a secure channel to the Server 2025 + domain controller (see "What the deployment showed"), so the domain client + is `OSWin11E`, Windows 11 Enterprise Evaluation 22H2 (10.0.22621.525), and + the 26H1 machine `OSWin11` stays in the lab outside the domain for runs of + the module's own tests. The reference cell of Decision 20 (Server 2025 + client and file server in `WindowsAccessControlLab`) stays as it is. + Server 2019 and 2022 as clients are extra cells, to run the module on the + older .NET Framework builds (Server 2019 has 4.7.2). + 2. Topology: a separate AutomatedLab lab `NtfsSecurityOsMatrixLab` with its + own internal switch (`192.168.12.0/24`) and its own forest `osmatrix.net`: + `OSDC1` (Server 2025, root domain controller), `OSFile19`, `OSFile22`, + `OSFile25`, `OSWin11E`, and `OSWin11`. `Deploy-OsMatrixLab.ps1` deploys it + with the maintainer's AutomatedLab and the VM path `V:\AutomatedLab-VMs`; + `Add-OsMatrixMachine.ps1` adds a machine to the deployed lab; the + payloads of the existing lab (PowerShell 7.6.3 and Pester 5.7.1 from the + host, because the VMs have no internet) come from + `Complete-OsMatrixLab.ps1`. + 3. Case 9 (accounts of other domains and forests) needs trusts to the + forests of the existing lab, so the matrix cells run with + `-ForeignDomainController @()`; the existing lab keeps that case. + 4. The controller of the repository runs in every cell with `-LabName`, + `-DomainController`, `-FileServer`, and `-Client`. The matrix showed three + defects of its setup and removal, fixed in `7d47316`: a recursive delete + fails with "The directory is not empty" on Windows Server 2019 (and the + stderr line ended the script before any retry, because `2>&1` under `Stop` + is terminating in Windows PowerShell 5.1), `Get-LocalGroupMember` fails on + an orphaned SID, and a vanished profile failed the client cleanup. + 5. The module's own behavior tests run on every machine as well + (`Run-MatrixLocalSuite.ps1`), elevated and as a basic user, in both + editions, as scheduled tasks so that the token matches a CI runner. This + found three defects of the module, each fixed in its own commit on + `ai/quality-gate-lab-matrix`: `Get-NTFSInheritance -SecurityDescriptor` + and `Get-NTFSEffectiveAccess -ServerName ''` (`962887a`), and + `Get-NTFSEffectiveAccess` for a user who isn't an administrator on a + computer in a domain (`fdd7a8b`, with a live test for the ServerAdmin + role). The maintainer decides which of them belong to rc7. +- Why a separate lab: AutomatedLab 5.61 refuses to add machines to an + imported lab, and defining a lab under an existing name would overwrite the + metadata of its 13 machines. A separate lab leaves every shared machine, + switch, domain, and account untouched, which Handoff 2 requires. Inside the + new lab, a machine can be added with `Import-LabDefinition`, + `Add-LabMachineDefinition`, and `Export-LabDefinition`, followed by the steps + that `Install-Lab` runs for one machine; `Add-OsMatrixMachine.ps1` does this + after it copies the lab metadata. +- Cost and rollback: six VMs (4 GB for the domain controller and both clients, + 3 GB for each file server), four new base images, measured at 17.8 GB for + the differencing disks and 42.4 GB for the base images (about 60 GB on `V:`; + my first estimate of 100 GB was too high). The deployment added twelve lines + to the hosts file of the host, which `Remove-Lab` removes. To remove the + matrix, run `Remove-Lab -Name NtfsSecurityOsMatrixLab` from AutomatedLab; + nothing else depends on it. No existing machine, checkpoint, or lab was + changed. A copy of the lab metadata from before the sixth machine is in + `C:\ProgramData\AutomatedLab\Backups` (administrators only). +- What the deployment showed (the agent's decisions D11 to D23 of the night + log, each reversible): + - The base image of a Server 2019 or a Windows 11 22H2 machine had an empty + EFI system partition: the `bcdboot` of the Server 2025 host fails with + exit code 193 on their boot files, and AutomatedLab ignores the exit code, + so the generation 2 machine fails with Hyper-V event 18603. The images of + Server 2022 and Windows 11 26H1 are fine. `Repair-OsMatrixBoot.ps1` runs + the `bcdboot` of the image itself on the differencing disk of the one + machine and starts it. + - The AutomatedLab driver sat in its file-server job wait with idle remote + runspaces after all features were installed, so I stopped it and ran the + rest by script. + - Windows 11 26H1 (10.0.28000.1836) joins the domain but cannot keep the + Netlogon secure channel to the Server 2025 domain controller + (10.0.26100.32690). The client calls `NetrLogonGetCapabilities` with query + level 2, which the protocol document describes as a check of the flags the + client sent; the controller answers `STATUS_ACCESS_DENIED` (level 1 and + `NetrServerAuthenticate` succeed), and the client denies the channel + (`NlConfirmRequestedCapabilities: denying access ... 0xc0000022`). + `Test-ComputerSecureChannel -Repair` can't help. Windows 11 22H2 against the + same controller works (secure channel, Kerberos, readiness). This is an + environment finding about two Microsoft builds, not about NTFSSecurity; the + maintainer may want to know it for his own labs. + - The Windows 11 Enterprise Evaluation 22H2 image (`OSWin11E`) is in + notification mode from its first day and shuts down an hour after every + start (`wlms.exe`, 0xC004F009 "grace time expired"): its install time was + recorded on a clock about seven hours ahead, which was then corrected. One + of its two rearms didn't help. After an unplanned shutdown its machine + account password no longer matched (domain logons fail with 0xC000018D, + `nltest /sc_verify` says `ERROR_INVALID_PASSWORD`); + `Test-ComputerSecureChannel -Repair` with the lab account fixed it, and + `/sc_verify` kept showing the old status afterwards, so test a domain + session instead. A run on this machine has to stay under an hour from its + start. + - A profile of an account that a probe's scheduled task used stayed loaded on + one server until it restarted; the probe now uses a new account name for + every run. + - The fixture of the live controller deleted its accounts after a cell and + created them again with the same names for the next. Windows then returns + the SID and the groups of the deleted account for a Kerberos S4U logon on + the domain controller and the file server for more than seven minutes, so + `Get-NTFSEffectiveAccess` returned no access for the new account in some + cells (Windows Server 2022, Admin role), for the baseline and the final + candidate alike. This looked like a regression of the module until a loop + probe showed both builds failing the same way. The controller now gives a + new fixture a new name for the account of case 3 (`1dec389`); the record + has the evidence. +- Result: [the record](../../Tests/Lab/Acceptance-2026-10-10-os-matrix.md). The + final candidate (`fdd7a8b`) passes the module's suite on all five machines + and the host in all four configurations, and the live cells (see the record). +- Open: the maintainer confirms or changes the matrix and decides whether to + keep the VMs after 5.0.0. Local `-ModulePath` runs are validation; the gate + needs the published package in every cell (Handoff 3, stage D). The newest + Windows 11 build that can join a Server 2025 domain here is 22H2; a domain + cell with 26H1 needs a newer domain controller build or a fix of the + mismatch. The maintainer also decides which of the three module fixes belong + to rc7 (each is its own commit, `git revert` removes it), and whether the + evaluation client stays (it needs a start shortly before every run) or is + replaced by a client with a license that doesn't expire. diff --git a/.memory-bank/deployment-notes.md b/.memory-bank/deployment-notes.md new file mode 100644 index 0000000..53c1830 --- /dev/null +++ b/.memory-bank/deployment-notes.md @@ -0,0 +1,135 @@ +--- +status: current +last-verified: 2026-10-10 +owner: software-engineer +source: release gates of 5.0.0 (lab acceptance, OS matrix, publication plan), repository evidence +--- + +# Deployment notes + +## Publish the next prerelease (rc7) + +State on 2026-10-09: #116 (rc7, head `d25647d`, base `master`), #117 (head +`f11ff41`, base `ai/release-5.0.0-rc7`), and #118 (draft, head `83149ee`, +base `ai/quality-gate-coverage`) are open and green. A local merge in that +order, each with a merge commit (Decision 15), ends in exactly the tree of +#118 (`b1dc006`), without conflicts. The manifest says `5.0.0` with +`Prerelease = 'rc7'`, and `$publishedVersions` in `Tests/Repository.Tests.ps1` +lists the versions up to rc6, as it must before rc7 is published. + +The branch `ai/quality-gate-lab-matrix` (local until the maintainer pushes it) +is stacked on #118. It holds three fixes of the module (`962887a`, `fdd7a8b`; +each is its own commit and `git revert` removes it), the kit of the +operating-system matrix, the changes of the live controller, and the record +(Decision 24). rc7 contains the module fixes only if the branch is merged after +#118 and before the tag; otherwise they go to the next prerelease. The +maintainer decides; open it as a draft with base `ai/quality-gate-paths`. + +1. Merge #116, then #117, then #118 into `master`, each with **Create a merge + commit**. Deleting the merged head branch makes GitHub retarget the next + pull request to `master`; otherwise change its base. Wait for green CI on + the retargeted pull request. +2. Tag the merge commit on `master` with `5.0.0-rc7` and push the tag. The + `release` job checks the tag against the manifest and builds nothing new: + it publishes the package that the `build` job tested. Approve the + deployment of the `powershell-gallery` environment if it asks. +3. After the publication, add `5.0.0-rc7` to `$publishedVersions` with the + next change that goes to `master`. + +## Accept a published package + +Local `-ModulePath` runs are validation; the gate needs the published bytes. + +1. `Tests/Lab/Acceptance/Test-PublishedRelease.ps1 -Version + -OutputPath ` (read-only): tag and commit on `master`, the CI run + of the tag, the Gallery's SHA-512 against the downloaded nupkg (ordinal, + case-sensitive base64), the nupkg against the GitHub zip file by file, and + the identity of the manifest. Dry run on rc6: all checks passed. +2. `Tests/Lab/Invoke-NTFSSecurityLabTest.ps1 -Version ` in the + existing lab, both editions, and `Tests/Lab/Acceptance/Run-MatrixSequence.ps1 + -Version ` for each cell of the matrix (Decision 24). Check every + role from the result files with `Validate-LabResults.ps1`, never from the + marker `DONE` of the controller. +3. Remove the fixture and check the end state independently with + `Test-MatrixCleanup.ps1`, which takes the lab name and the machine names + (`-LabName WindowsAccessControlLab -DomainController F1ADC1, F1BDC1, F2DC1, + F3DC1 -Machine F1AFile1, F1AFile2` for the existing lab). +4. If the published binary changes, repeat the cells; never combine runs of + different binaries into one matrix. + +## Lab lessons + +- AutomatedLab 5.61 can't add machines to an imported lab (`Add-LabMachineDefinition` + throws "Lab is already imported"), and `New-LabDefinition` under an existing + name overwrites its metadata. New machines go into a new lab with its own + switch and domain, and `-LabName` of the controller selects it. +- `Install-Lab -NetworkSwitches -BaseImages` creates the switch and the base + images first; the base images of Server 2019, Server 2022, and Windows 11 Pro + took about two to four minutes each from the ISO files. AutomatedLab + adds records to the hosts file of the host, which `Remove-Lab` removes. +- The VMs have no internet: take PowerShell 7 and Pester 5.7.1 from the host + (`Copy-LabFileItem`, `Install-LabSoftwarePackage`). +- AutomatedLab ignores the exit code of `bcdboot` when it builds a base image. + The Server 2019 image that it built on this Server 2025 host got an empty + EFI system partition: the `bcdboot` of the host fails with exit code 193, + "Failure when attempting to copy boot files", on the 2019 boot files, and the + VM failed to boot (Hyper-V event 18603, "failed to boot an operating + system"; no memory demand, no IP, heartbeat `NoContact`). Check the EFI + system partition of a new base image before the first VM: mount the image + read-only (`Mount-DiskImage -Access ReadOnly`) and look for + `EFI\Microsoft\Boot\bootmgfw.efi` (the images of Server 2022 and Windows 11 + Pro had 140 and 149 files). Repair a VM, not the base: stop the VM, mount its + own differencing disk, run the `bcdboot.exe` of the image (`D:\Windows\System32\bcdboot.exe + D:\Windows /s H: /f UEFI`), copy `bootmgfw.efi` to `EFI\Boot\bootx64.efi`, + dismount, and start the VM. A changed base image would invalidate its + differencing disks. +- The tool output of the agent masks text that looks like a secret, such as + `-Password $password`, in what it shows. Test such a line by parsing the + file, and don't repair it from the displayed text. +- A script that a detached process runs needs its own log, an exit marker, and + an end-state check of its own; verify cleanup from the end state, not from + its marker. +- Extend a deployed lab with one machine like this: in a process that never ran + `Import-Lab`, call `Import-LabDefinition`, `Add-LabMachineDefinition`, and + `Export-LabDefinition`, then `New-LabBaseImages` and `New-LabVM -Name `. + `Install-Lab` has no per-machine selector, and `Add-LabMachineDefinition` + throws as soon as `Get-Lab` returns a lab. `Add-OsMatrixMachine.ps1` does it + after it copies the lab metadata to `C:\ProgramData\AutomatedLab\Backups`. +- Windows 11 22H2 (10.0.22621) has the empty EFI system partition problem too + (`bcdboot` exit code 193 on the host); `Repair-OsMatrixBoot.ps1` repairs it. + After `Mount-VHD` the host gives the NTFS partition a letter on its own; don't + assign a second one. +- Run AutomatedLab processes one after the other. Two `Import-Lab` calls at the + same time corrupt each other (XML errors, "No machines imported"). +- Check the secure channel of every domain client before the first run + (`Test-MatrixReadiness.ps1`). Windows 11 26H1 (10.0.28000.1836) joins a + Server 2025 domain (10.0.26100.32690) but loses the channel: the client asks + `NetrLogonGetCapabilities` for query level 2, the domain controller answers + `0xC0000022`, and the client denies the channel. Rejoining doesn't help. +- A process that starts from a remoting session has every privilege enabled + and no credentials of its own, so tests that expect disabled privileges fail + (eight per edition). Run the suite of a VM as a scheduled task with a batch + logon at the highest run level (`Register-ScheduledTask -RunLevel Highest + -User -Password`): that token matches a CI runner. A restricted token (a basic + user) can't run Pester's NUnit export, because it asks WMI for the + environment, so write the JSON summary first. +- In Windows PowerShell 5.1, `$PSScriptRoot` is empty in a parameter default of a + script that runs with `-File`; compute it in the body. `-File` passes an array + as one string, so split on commas. With `$ErrorActionPreference = 'Stop'`, a + line that a native command writes to stderr and that `2>&1` redirects is a + terminating error; let the command write its errors to stdout. +- `Get-LocalGroupMember` fails with "Failed to compare two elements in the array" + when the group holds an orphaned SID. Add members with `Add-LocalGroupMember` + and ignore `MemberExistsException`; read and remove members with + `net localgroup ` and `net localgroup /delete`. The SIDs + of a deleted account can't be found afterwards, so keep `fixture-sids.json` + from before the removal of the organizational unit. +- An account that is deleted and created again with the same name keeps its old + SID and groups in Kerberos S4U logons on the domain controller and member + servers for more than seven minutes, and nothing flushes it (see + `techContext.md`). The controller names the account of case 3 anew for each + new fixture; a script of your own that recreates accounts needs unique names + too. +- Restart the evaluation client (`OSWin11E`) right before a sequence or a suite, + not before several: it shuts down an hour after each start. The restart takes + about two and a half minutes and may need the repair of the secure channel. diff --git a/.memory-bank/progress.md b/.memory-bank/progress.md index fd5745d..aa4e478 100644 --- a/.memory-bank/progress.md +++ b/.memory-bank/progress.md @@ -14,7 +14,10 @@ recovered in attempt 2 on 2026-10-09. #116 (rc7, `d25647d`, base `master`) is open and green, not merged or published. Further quality-gate work is `ai/quality-gate-coverage` (#117) and `ai/quality-gate-paths` (draft #118), which classifies every remaining unvisited path; the open items are the -maintainer's decisions. Stable Gallery version: 4.2.6. +maintainer's decisions. The local branch `ai/quality-gate-lab-matrix` (stacked +on #118, not pushed) holds the operating-system matrix, three fixes of the +module found by it, and the controller changes (Decision 24, proposed). +Stable Gallery version: 4.2.6. After 5.0.0, archive in favor of WindowsAccessControl (Decision 18). ## Recent milestones @@ -79,6 +82,21 @@ After 5.0.0, archive in favor of WindowsAccessControl (Decision 18). 486 passed, 0 failed, 2 expected skips; baseline 338 passed, 148 failed, all 148 green on the candidate; fixture removed and verified clean on six machines. 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 + D1 to D26 in the night log of the session files). The matrix lab + `NtfsSecurityOsMatrixLab` (Server 2019, 2022, and 2025 file servers, Windows 11 + Enterprise 22H2 client, Windows 11 26H1 suite only) found three defects of the + module, fixed in `962887a` and `fdd7a8b`: audit inheritance by descriptor, + `Get-NTFSEffectiveAccess -ServerName ''`, and the same cmdlet for a user who + isn't an administrator on a domain member. The final candidate passes the + module's suite on every machine (24 runs, no failure) and the live controller + in three cells (1,374 passed, 0 failed, 12 skipped). The failures of the + effective-access tests in the Server 2022 cell were not a defect of the module: + Windows returns the SID and the groups of a deleted account for a Kerberos S4U + logon for more than seven minutes, and the controller names the account of + case 3 anew for each fixture (`1dec389`). A read-only built-in review of the + kit and the fixes approved with Minor findings, fixed in `db04ef2`. Record: + `Tests/Lab/Acceptance-2026-10-10-os-matrix.md`; nothing was pushed. ## Stable capabilities @@ -128,9 +146,12 @@ After 5.0.0, archive in favor of WindowsAccessControl (Decision 18). tests and exact artifact SHA-512 verification. Original upload errors remain errors for missing/different/unverifiable outcomes. Not deployed until the maintainer merges/pushes; no publication was performed here. -9. Phase 3: choose OS scope (proposed Windows 11 client/2019/2022 servers), - detect ISO editions, provision without repurposing shared VMs, then run - published-package acceptance. #34 has no new reply since 2026-10-06. +9. Operating-system matrix (Decision 24, proposed): the lab and the cells exist + and the final local candidate passes them. Open: the acceptance of the + published rc7 in every cell, keeping or replacing the VMs (about 60 GB) and + the evaluation client (it shuts down every hour), which module fixes go to + rc7, and a domain cell for Windows 11 26H1. #34 has no new reply since + 2026-10-06. 10. Lab rollback evidence: new checkpoints exist but report Standard even after a successful temporary ProductionOnly probe. Classification is unresolved; original VM policy restored, no checkpoint restored. Do diff --git a/.memory-bank/systemPatterns.md b/.memory-bank/systemPatterns.md index 284db7d..4946ca4 100644 --- a/.memory-bank/systemPatterns.md +++ b/.memory-bank/systemPatterns.md @@ -113,6 +113,22 @@ Read only task-relevant records; the index controls routing. example code blocks, and check the generated XML. - Live tests use only approved lab targets, SMB then independent server state; Get/SetFileSecurity preserves stored DACLs; rights oracles use S4U tokens. +- A suite that is green on the development host and on CI says little about a + feature that the environment lacks. The matrix found three defects that every + earlier run had missed because the host is outside a domain and the CI + runner's token differs: run the suite on a domain member, on other builds, and + as a basic user before a release, and classify a failure by a probe under the + real tokens (elevated, filtered, local standard, domain standard) before + calling it a defect or a design. +- A fixture that deletes an account and creates it again with the same name + gets the old SID and groups from Kerberos S4U logons (the oracle of the live + tests, and the Authz functions behind `Get-NTFSEffectiveAccess`) on the + domain controller and on member servers for more than seven minutes, and no + cache flush helped (a ticket purge renews only the session's own token). A + failure that follows the order of the cells and not the version of the + module points to such state: run a loop probe with the baseline and the + candidate side by side before blaming the code. The controller names the + account of case 3 anew for each new fixture. ### CI results and publication diff --git a/.memory-bank/techContext.md b/.memory-bank/techContext.md index 15990e4..599adc9 100644 --- a/.memory-bank/techContext.md +++ b/.memory-bank/techContext.md @@ -175,6 +175,12 @@ source: repository and executable evidence - Remote Authz answers administrators and Access Control Assistance Operators (S-1-5-32-579); other accounts get access denied. Check firewall when remote resource-manager RPC fails. Expected rights use S4U tokens. + A computer in a domain offers the remote interface to every caller, so the + denial also hit the default `-ServerName localhost` for a user who isn't an + administrator; a computer outside a domain doesn't offer it, which is why the + tests passed on the development host and on CI. Since `fdd7a8b`, the local + manager answers for a name of this computer when the remote one refuses; the + denial stays for another computer (live test of the Delegate role). - A live test is evidence of a fix only when it fails on the build without the fix: run the same tests, controller, and lab against the candidate and the base of the branch, a new process per edition, and join both result @@ -185,3 +191,41 @@ source: repository and executable evidence in the CSV became `System.String[]`. - RemoveFixture after the run; verify OUs/accounts, share, folders, local memberships, and test profiles removed. Credentials must never be printed. + +### Operating-system matrix (Decision 24) + +- Lab `NtfsSecurityOsMatrixLab`: OSDC1 (Server 2025), OSFile19/22/25 (Server + 2019/2022/2025), OSWin11E (Windows 11 Enterprise Evaluation 22H2, the domain + client), OSWin11 (Windows 11 Pro 26H1, suite only). Kit: `Tests\Lab\Acceptance`; + record: `Tests\Lab\Acceptance-2026-10-10-os-matrix.md`. +- Run the module's own suite on every machine class before the controller + (`Run-MatrixLocalSuite.ps1`, elevated and basic, both editions, as scheduled + tasks with a batch logon at the highest run level): a child of a remoting + session has every privilege enabled and fails eight tests that expect them + disabled. Skipped lists are compared as multisets against the host. +- AutomatedLab: one `Import-Lab` at a time, and none while a controller + sequence runs (it re-imports the lab); `Wait-LabVM` waits for a heartbeat that + a client may not report, so retry `New-LabPSSession`. The host's `bcdboot` + leaves the ESP of a Server 2019 or Windows 11 22H2 base image empty. +- Windows PowerShell 5.1: `$PSScriptRoot` is empty in a parameter default under + `-File`; `2>&1` on a native command under `Stop` makes its stderr line + terminating; `Get-LocalGroupMember` fails on an orphaned SID; `net localgroup + /delete` refuses the SID of a name that its cache still + resolves (use `Remove-LocalGroupMember -SID`). +- Windows 11 26H1 (28000.1836) loses the secure channel to a Server 2025 domain + controller (`NetrLogonGetCapabilities` level 2, 0xC0000022): suite only. + The 22H2 evaluation client shuts down every hour (license grace expired) and + can lose its machine password after an unplanned shutdown: keep a run under + an hour from its start, test a domain session (not `nltest /sc_verify`, which + stays stale), repair with `Test-ComputerSecureChannel -Repair`. +- Builds are not byte-reproducible (two unchanged assemblies differ per build): + hash each candidate and its package separately. +- The fixture's account for case 3 gets a new name for each new fixture + (`NtfsLiveSubject` and four digits). After an account is deleted and created + again with the same name, a Kerberos S4U logon returns the old SID and groups + for more than seven minutes on the domain controller and the file server + (`WindowsIdentity` with a UPN, the Authz functions behind + `Get-NTFSEffectiveAccess`), whichever module version asks; a `klist purge` + renews only the session's own token, and `nltest /sc_reset`, a DNS flush, and + a restart of the Kerberos service change nothing. `Probe-AccountRecreation.ps1` + shows it.