diff --git a/.memory-bank/activeContext.md b/.memory-bank/activeContext.md index 21d0c3d..9385651 100644 --- a/.memory-bank/activeContext.md +++ b/.memory-bank/activeContext.md @@ -14,15 +14,15 @@ 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 +pushed: the lab `NtfsSecurityOsMatrixLab`, three fixes of the module in two commits +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 +agent's decisions of the night are D1 to D37 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 @@ -121,20 +121,27 @@ open. 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 + (run on OSFile22 and OSFile25) fails 4 elevated and 20 basic-user tests. 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. + effective-access failures of the earlier cells were not the module: in a replay + (`ab0` to `ab6`) the baseline failed two of three cells and the final candidate + one of three (not counting the warm-up `ab0`), and one model (the remote + authorization managers answer for an account name for about ten minutes after + the account was created again) fits all 43 Admin-role runs of 27 cells; the + Windows mechanism is unknown. The controller now names the account of case 3 + anew for each fixture (`1dec389`); four more cells with it (`ab7` to `ab10`) + passed, two of them where the model predicts a failure for a reused name. + Reviewed by the built-in code-review agent (custom `security-reviewer` + unavailable): approve with Minor, fixed; a second review found one Major + (record accuracy), addressed by the replay. ## Next step 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). + `ai/quality-gate-paths` and decides which of the module fixes belong to rc7 + (two commits: `962887a` holds two fixes, `fdd7a8b` one). 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 diff --git a/.memory-bank/decisions/0024-os-matrix-lab.md b/.memory-bank/decisions/0024-os-matrix-lab.md index 89eaad2..9f1d653 100644 --- a/.memory-bank/decisions/0024-os-matrix-lab.md +++ b/.memory-bank/decisions/0024-os-matrix-lab.md @@ -52,9 +52,9 @@ source: agent decisions under the maintainer's delegation of 2026-10-09 (Handoff 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 + found three defects of the module, fixed in two commits on `ai/quality-gate-lab-matrix`: `Get-NTFSInheritance -SecurityDescriptor` - and `Get-NTFSEffectiveAccess -ServerName ''` (`962887a`), and + and `Get-NTFSEffectiveAccess -ServerName ''` (`962887a`, two fixes), 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. @@ -112,16 +112,26 @@ source: agent decisions under the maintainer's delegation of 2026-10-09 (Handoff - 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. + - The matrix cells of the live controller failed in the effective-access tests + of the Admin role in the Windows Server 2022 cell (`rc7f`, `rc7h`, `rc7i`, + and `rc7j`) in cells that followed each other, where the fixture was removed + after a cell and created again with the same account names. This looked like + a regression of the module (the audit read of `962887a` was the first suspect) + until a replay of the same cells with the baseline and the final candidate + alternating (`ab0` to `ab6`) failed the baseline in two of three cells and + the final candidate in one of three (not counting the warm-up `ab0`). In a + failing cell the remote + authorization managers (the client's and the file server's) returned no + groups for the current account while the Kerberos S4U logon, the name + resolution, and the local manager were right in the same second. One model, + in which a remote manager answers for an account name for about ten minutes + after its first request, fits all 43 Admin-role runs of 27 cells; the + predictions that I wrote down before three of the replay cells held (the + weakest is `ab6`, 10.5 minutes after its entry, above the lifetimes that + fit). The mechanism in Windows isn't known. The controller now gives a new + fixture a new name for the account of case 3 (`1dec389`); four more cells + with it (`ab7` to `ab10`) passed, two of them at positions where the model + predicts a failure for a reused name. 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). @@ -130,7 +140,9 @@ source: agent decisions under the maintainer's delegation of 2026-10-09 (Handoff 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 + mismatch. The maintainer also decides which of the module fixes belong to + rc7 (two commits: `962887a` holds two fixes, `fdd7a8b` one; `fdd7a8b` reverts + cleanly on its own, `962887a` conflicts with it in `Lib.cs` and `CHANGELOG.md` + if `fdd7a8b` stays), 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 index 53c1830..8df8a94 100644 --- a/.memory-bank/deployment-notes.md +++ b/.memory-bank/deployment-notes.md @@ -18,8 +18,10 @@ order, each with a merge commit (Decision 15), ends in exactly the tree of 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 +is stacked on #118. It holds three fixes of the module in two commits (`962887a` +has two, `fdd7a8b` one). `fdd7a8b` reverts cleanly on its own; `962887a` doesn't +revert while `fdd7a8b` stays (the two conflict in `Security2/Win32/Lib.cs` and +`CHANGELOG.md`), and its two fixes go together. The branch also holds 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 @@ -124,12 +126,16 @@ Local `-ModulePath` runs are validation; the gate needs the published bytes. `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. +- An account that is deleted and created again with the same name made the + remote authorization managers (the client's and the file server's) answer for + about ten minutes as if it had no groups, so `Get-NTFSEffectiveAccess` returned + no access; when the accounts are created again within seconds, the Kerberos S4U + logons returned the old account on the domain controller and member servers for + 7 to 15 minutes. The five remedies tried (a ticket purge, `nltest /sc_reset`, a + DNS flush, a restart of the Kerberos service, and waiting) helped only by + waiting (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 aa4e478..6ab8c56 100644 --- a/.memory-bank/progress.md +++ b/.memory-bank/progress.md @@ -83,7 +83,7 @@ After 5.0.0, archive in favor of WindowsAccessControl (Decision 18). 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 + D1 to D37 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, @@ -92,10 +92,16 @@ After 5.0.0, archive in favor of WindowsAccessControl (Decision 18). 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: + in a replay of the same cells the baseline failed two of three and the final + candidate one of three (not counting the warm-up cell), and one model (the + remote authorization managers answer for an account name for about ten minutes + after the account was created again) fits all 43 Admin-role runs of 27 cells; + the Windows mechanism is unknown. 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`. A second review of the later commits found one Major (the record + called the cause settled without a baseline replay), addressed by the replay, + `9344ff7`, and `ab0d8e1`. Record: `Tests/Lab/Acceptance-2026-10-10-os-matrix.md`; nothing was pushed. ## Stable capabilities diff --git a/.memory-bank/systemPatterns.md b/.memory-bank/systemPatterns.md index 4946ca4..8372541 100644 --- a/.memory-bank/systemPatterns.md +++ b/.memory-bank/systemPatterns.md @@ -48,6 +48,7 @@ Read only task-relevant records; the index controls routing. | 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) | | 23 | [Non-Windows file servers before 5.0.0, #34 (proposed)](decisions/0023-non-windows-file-servers.md) | +| 24 | [The operating-system matrix lab (proposed)](decisions/0024-os-matrix-lab.md) | ## Patterns @@ -120,15 +121,16 @@ Read only task-relevant records; the index controls routing. 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. +- A fixture that deletes an account and creates it again with the same name can + get a wrong answer for about ten minutes: the remote authorization managers + answered `0x100000` for the current SID while the local manager and a Kerberos + logon were right in the same second, and, when the accounts are created again + within seconds, the Kerberos S4U logons returned the old account (7 to 15 + minutes). A failure that follows the order of the cells and not the version of + the module points to such state: run the baseline and the candidate in cells + that follow each other and alternate them (the replay of the record) 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 599adc9..8f896ea 100644 --- a/.memory-bank/techContext.md +++ b/.memory-bank/techContext.md @@ -221,11 +221,18 @@ source: repository and executable evidence - 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. + (`NtfsLiveSubject` and four digits). In the matrix lab, after an account was + deleted and created again with the same name, the remote authorization + managers (the client's for the default `-ServerName`, the file server's for its + name) answered for about ten minutes as if it had no groups (`0x100000`), + whichever module version asked, while the Kerberos S4U logon of the oracle, the + name resolution, and the local manager were right in the same second. A replay + with the baseline and the final candidate alternating failed the baseline in two + of three cells and the final candidate in one of three (not counting the warm-up + cell). The mechanism in Windows is unknown; a model with one lifetime (9.35 to + 10.20 minutes) fits all 43 Admin-role runs of 27 cells. When the accounts are + created again within seconds, the S4U + logon itself returns the old account for 7 to 15 minutes. A `klist purge`, + `nltest /sc_reset`, a DNS flush, and a restart of the Kerberos service didn't + help. `Probe-AccountRecreation.ps1`, `Export-CellTimeline.ps1`, and + `Test-StaleAuthzModel.ps1` show it.