Repository navigation
fix: post-release review defects, performance, NTFSSecurity migration guide, and CI upkeep - #5
Merged
Merged
Conversation
Replace the stale release-pending status: v0.3.0-preview0001 shipped on 2026-09-07. Record the restored ai/performance-refactor branch, its review findings rechecked against main, the dependabot failure cause, issue #4, the uncreated v0.2.0 changelog pull request, and FIND-002. Co-authored-by: AI Assistant <ai@example.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Eight sequential handoff prompts outside the repository now drive the triaged work. They commit to the local integration branch ai/post-release-fixes; only the final prompt touches the remote, with approval per action. Co-authored-by: AI Assistant <ai@example.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The domain-lab acceptance runner recursively deleted the payload root, its package child, and any same-version WindowsAccessControl installation on the management domain controller without checking that it had created them. The runner now marks each directory it may later replace and replaces one only when it is absent, or marked with no junction or symbolic link inside. The domain controller rejects a payload root that is not a dedicated local directory before anything changes, in every mode. Each remote step confirms its directory, because AutomatedLab reports a remote throw without stopping the calling script. Co-authored-by: AI Assistant <ai@example.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Test-WindowsTaskSchedulerSystemAce refused every candidate when the current DACL held no literal Local System ACE, so a write that restored SYSTEM was rejected. Specification 0010 requires only that each current Local System ACE stays byte-identical and that no Local System deny ACE is added. History shows no intent behind the extra refusal: it arrived with 442162a without a decision record, spec text, or test. A current descriptor whose DACL is missing or null is still refused, because neither preservation nor an exact rollback can be verified against it; the setter now says so in its own message. Co-authored-by: AI Assistant <ai@example.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Set-WindowsSmbShareSecurityDescriptor compared the description after the native SE_LMSHARE write with the value captured when the target was resolved and wrote that snapshot back whenever they differed, so an edit made after resolution was overwritten. The setter now reads the description immediately before the native write. Afterwards it restores that value only when the write cleared it, reports the restoration in the verbose stream, and leaves any other new value in place with a warning. A description that cannot be read before the write stops the command before anything is written. A failed restoration after a failed write still raises one AggregateException. Following decision 48, no step after a committed write throws: a description that cannot be checked or restored afterwards is reported as a warning naming the earlier value, and those warnings ignore a Stop or Inquire preference, because the DACL change is already live. The setter is now exercised by unit tests, so it leaves the domain-lab- only coverage list and its coverage is asserted. Co-authored-by: AI Assistant <ai@example.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Get-ADObjectCallerEffectiveAccess resolved every target, in the dispatcher's prevalidation and again in the worker, through a request for nTSecurityDescriptor that it never used. A domain controller omits that attribute for a bind without READ_CONTROL, and Get-WindowsADObjectRecord then failed with "Cannot index into a null array" instead of returning the caller's effective access. Resolve-WindowsADObjectTarget and Invoke-WindowsADCommandBatch gain an opt-out switch that only this command sets; every descriptor-dependent caller keeps requesting the descriptor, and a write target refuses the switch. When a requested descriptor is absent or has no value, Get-WindowsADObjectRecord now throws UnauthorizedAccessException naming the likely missing read-control access. Send-WindowsADSearchRequest now holds the LDAP send and its NoSuchObject translation, so unit tests can supply a directory response. The catch stays beside the native call, where $_.Exception is still the DirectoryOperationException. Get-WindowsADObjectRecord and Resolve-WindowsADObjectTarget move into asserted coverage, with unit tests for the write-target path, and the new seam is declared domain-lab-only. The domain-lab AD suite gains a restricted-caller case and a missing-object case for the next live acceptance run. Co-authored-by: AI Assistant <ai@example.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Cache immutable rights displays, filter NTFS SIDs before conversion, and streamline exact ACE comparison and batch parameter copying. Add regression cases and cross-edition benchmark evidence while preserving public contracts. Core: 1811 passed with 82.64% asserted coverage. Final focused suites: 145 passed per edition. Full Desktop retains two existing WinRM-blocked DSC checks; no host configuration or remote was changed. Ported from ai/performance-refactor onto ai/post-release-fixes. Its Memory Bank hunks resolve to the current files, and the docs/README.md row joins the current rows. The figures above are from the original 2026-09-10 run against 5991673. (cherry picked from commit a3e3152a4d6c027204d4b075da27db779852c38e) Co-authored-by: AI Assistant <ai@example.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Rewrite the release notes to lead with measured impact and the unchanged command surface instead of internal mechanism, document the descriptor benchmark on the diagnostics page, and record why the ordinal comparer is required for Base64 directory identities but only defensive for uppercase-hexadecimal private-key identities. Ported from ai/performance-refactor onto ai/post-release-fixes. Its Memory Bank hunks resolve to the current files. (cherry picked from commit 44dcc70247872a9bbb46f62265e38476a6bdc07a) Co-authored-by: AI Assistant <ai@example.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
State that the refactor diff was reviewed in the session that wrote it with no finding of the two highest severities, that independent review is still recommended, and that a later repository-wide review requested changes elsewhere that also gate acceptance. Ported from ai/performance-refactor onto ai/post-release-fixes. The original body named the second review severity by its label, which GitVersion.yml treats as a version bump keyword; this body describes the severity instead. (cherry picked from commit 5f06c03e1f894da3c5f1778b14aa86a89cf0ea30) Co-authored-by: AI Assistant <ai@example.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Pin the ArgumentException that Invoke-WindowsAccessControlBatch raises when CommandName or ObjectFamily arrives without the other, and prove that no worker ran. With the guard removed from source, both cases failed in PowerShell 7.6.6 and Windows PowerShell 5.1 because no exception was thrown; with it restored, all 14 dispatcher tests pass in both editions. Also pin that an NTFS adapter worker copies the parameters every runspace shares before it writes its target path, as the independent review asked. With the copy replaced by a reference, the shared table kept the first target in both editions; with the copy restored, all 15 tests in the file pass in both editions. Co-authored-by: AI Assistant <ai@example.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Rerun both benchmarks in fresh processes in PowerShell 7.6.6 and Windows PowerShell 5.1 against the integration branch before and after the ported perf commit, after checking module hashes and output checksums. The documented rows keep their direction: on PowerShell 7 rights rendering is 69% faster, removed-entry detection 66%, single-target batch calls 18%, and isolated private-key DACL comparison 15%. Label the 2026-09-10 sections historical, record the mixed-workload warm-up that makes one Core CNG row slower, and cite the new figures in the release notes. Record the final gates, the package hash, and the independent review, and correct the private-key key description, the cache scope, and the scope of the 256-entry figures that the review flagged. Port the durable lessons of the refactor branch into the Memory Bank and close out handoff 03. Co-authored-by: AI Assistant <ai@example.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
WinRM now runs on the development machine, so the two DSC-engine tests that need it pass, and the Windows PowerShell 5.1 gate asserts its coverage here for the first time: 1,872 passed, zero failed, two environment skips, and 80.95 percent of 8,314 commands. This session changed no host setting; the service was already running. Co-authored-by: AI Assistant <ai@example.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…iptor benchmark in the specs The user reviewed every recorded agent decision of handoffs 01 to 03. The 79-row Memory Bank decision log moves unchanged to topics/decision-log.md, and the index routes to it, which brings systemPatterns.md within its line budget. Specs 0005 and 0006 now name the descriptor-processing benchmark, its per-run checksums and module hash, and the per-instance rights cache. The tech context records that local WinRM runs, and the two lab-runner follow-ups become post-release items. Co-authored-by: AI Assistant <ai@example.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
NTFSSecurity is deprecated in favor of this module, and issue #4 asks whether this module replaces it. The documentation index pointed NTFSSecurity users at the NTFSPermission rename map, which never mentions NTFSSecurity, and the wiki Home page promised a map that did not exist. The guide maps every command of the NTFSSecurity 4.2.6 and 5.0.0-rc4 manifests, confirmed against the built module, and states the parameter and output differences and the decision behind each missing capability. Every published example ran verbatim in PowerShell 7.6.6 and Windows PowerShell 5.1. Refs #4 Co-authored-by: AI Assistant <ai@example.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The README still called certificate private keys read-only and listed mutation as out of scope, although specification 0015 superseded that boundary and the usage guide already describes the write commands, their fail-closed gates, backup and restore, and the DSC resources. Also record handoff 04 in the Memory Bank. Co-authored-by: AI Assistant <ai@example.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The three pinned actions declared node20, which GitHub now runs on Node.js 24 while warning on every job. Each pin moves to the SHA its target tag resolves to, verified with git ls-remote; all six tags are lightweight, so no peeling was needed: - actions/checkout 11d5960a -> 3d3c42e5 (v4.4.0 to v7.0.1) - actions/upload-artifact ea165f8d -> 043fb46d (v4.6.2 to v7.0.1) - actions/download-artifact d3f86a10 -> 3e5f45b2 (v4.3.0 to v8.0.1) Every release note from v4 to each target was read and checked against this workflow. Nothing it relies on changed meaning: artifact names and paths, the layout a download by name produces, hidden-file handling, if-no-files-found, retention-days, fetch-depth, and credential persistence all behave as before, and the Node.js 24 runner requirement is met by the hosted windows-latest and ubuntu-latest runners. The new checkout refusal to check out fork pull request code covers pull_request_target and workflow_run, neither of which this workflow uses. No input needed an edit, so this is seven pins and a test. One behavior does change and is kept: download-artifact v8 ends a job when a downloaded artifact's digest does not match the server, where v4 only warned. A damaged output tree must not reach the test or the publish job. A new test in tests/Unit/Build holds every uses: reference to a 40-character SHA pin with a version comment, keeps one action from being pinned to two SHAs, and requires each of the three to sit on a release line that declares node24. It failed three of its seven cases before this change. Dependabot #1 to #3 propose exactly these seven lines; they are superseded. The real proof is the pull-request CI, which is the last handoff's work. Co-authored-by: AI Assistant <ai@example.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
+semver: skip The v0.2.0 release ran Create_ChangeLog_GitHub_PR, which pushed the branch updateChangelogAfterv0.2.0 and never opened a pull request, so the version heading the pipeline writes never reached main. Everything CHANGELOG.md carried at tag v0.2.0 now sits under '## [0.2.0] - 2026-09-06', in the heading format of that unmerged branch, and the entries written since the release stay under '## [Unreleased]' in their own categories. No content line moved out or appeared twice: the multiset of non-heading, non-blank lines is identical before and after at 859 lines, the 188 entry bullets are unchanged, and the 14 new lines are 5 headings and 9 blank lines around them. Get-ChangelogData parses the result and reports one released version, 0.2.0 of 2026-09-06. CONTRIBUTING.md reserves version headings for the pipeline, so this completes the pipeline step that never landed instead of hand-writing a heading. Co-authored-by: AI Assistant <ai@example.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sampler's Create_ChangeLog_GitHub_PR wraps everything it does after creating the changelog branch in a try/catch that writes the error to the build log and returns, so Invoke-Build still exits zero and the workflow step concludes successfully. The v0.2.0 release pushed updateChangelogAfterv0.2.0 at 21:00:25 UTC, inside a step that ran from 21:00:22 to 21:00:27 and was reported as successful, yet no pull request from that branch exists in any state. Everything the task does before the pull request call only writes repository contents and demonstrably worked, so the likeliest cause is a GitHubToken secret that grants contents but not pull requests. The publish job now queries the pull requests of the changelog branch after the task has run and ends the run when there is none, naming whether the branch itself reached the remote. It runs only for a stable release tag, because UpdateChangelogOnPrerelease is false and a pre-release build of main returns before the task creates a branch. A test in tests/Unit/Build holds the step, its position, its query, its token and branch inputs, and its condition, and it runs the step's own script against a mocked API: an empty answer has to end the release. Counting that answer with '@(Invoke-RestMethod ...)' yields one element instead of none and would confirm a pull request that does not exist, so the step counts through the pipeline and the test guards that. Co-authored-by: AI Assistant <ai@example.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
FIND-002 of the 2026-09-07 security review. Each file ended with '}' and no line terminator; both now end with the CRLF that .gitattributes declares for *.ps1, and nothing else in either file changed. Their suites still pass in PowerShell 7 and Windows PowerShell 5.1. The review document now records the resolution beside the one it already carried for FIND-001. The Memory Bank records what handoff 06 changed and points at handoff 07, which needs the Hyper-V host that holds the lab; this machine has Hyper-V and AutomatedLab but no lab virtual machines. Co-authored-by: AI Assistant <ai@example.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… publication The lab host is not on this machine, so the live acceptance of the combined candidate is still owed before the next stable release. The publication steps are prepared up to the first remote action, and each of them waits for the user. Both full gates pass on 023afe9. Co-authored-by: AI Assistant <ai@example.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This was referenced Oct 7, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pull Request (PR) description
This pull request lands the work left open after
v0.3.0-preview0001. Eachpart has its own commits, so any part can be reverted on its own.
tests/Lab/Invoke-WindowsAccessControlLabAcceptance.ps1no longer deletes directories it did not create. It marks the payload root,
the package directory, and the installed module version it creates, and it
refuses unmarked targets, owned trees that contain a junction or symbolic
link, and payload roots that contain
[or](96d6671).no Local System entry; a missing or null current DACL is still refused
(
5531824).the native call, keeps an edit made in the meantime, and warns instead of
failing when the description cannot be restored after a committed write
(
618c6d5).Get-ADObjectCallerEffectiveAccessno longer requestsnTSecurityDescriptor, so a caller without read-control access still getsan answer (
8b67058).per rule (
fbced95). Re-measured in fresh processes with matching artifacthashes and output checksums: in PowerShell 7, rights display is 69 % faster,
removed-entry detection 66 %, dispatch 18 %, and isolated CNG 15 %; in
Windows PowerShell 5.1, removed-entry detection is 95 % faster. Details are in
docs/performance-refactor-2026-09-10.md.docs/migration-from-ntfssecurity.md, maps every NTFSSecurity command to itsreplacement and is linked from the README, the documentation index, and the
wiki Home page. The README section on certificate private keys now matches
specification 0015 instead of calling the family read-only (
d683f2a,add9273).actions/checkout,actions/upload-artifact, andactions/download-artifactmove to their Node 24 releases, pinned by SHA,with a test that keeps every action pinned (
a6697c3). The seven changedlines are identical to Dependabot chore(deps): bump actions/download-artifact from 4.3.0 to 8.0.1 #1, chore(deps): bump actions/upload-artifact from 4.6.2 to 7.0.1 #2, and chore(deps): bump actions/checkout from 4.4.0 to 7.0.1 #3.
CHANGELOG.mdregains the0.2.0section that thev0.2.0 release pushed to
updateChangelogAfterv0.2.0but never opened a pullrequest for (
8be6892). A stable release now ends with an error when itschangelog pull request does not exist, instead of reporting success
(
d55897f). Two test files end with a newline (023afe9). Do not mergeupdateChangelogAfterv0.2.0; this branch supersedes it.GitVersion 5.12.0, run on a simulated merge commit of this branch into
main, reports0.3.0-preview0002, so the merge publishes a preview.This Pull Request (PR) fixes the following issues
What was run, and what the result was
On
023afe9, on Windows with PowerShell 7.6.6 and Windows PowerShell5.1.26100, each step in its own process. The branch tip,
89d9c2e, adds onlya Memory Bank update on top of it.
.\build.ps1 -Tasks build.\build.ps1 -Tasks testin PowerShell 7.\build.ps1 -Tasks testin Windows PowerShell 5.1.\build.ps1 -Tasks pack(onadd9273)Invoke-ScriptAnalyzer1.25.0 over the 41 changed PowerShell filesFocused evidence for each part:
they failed for the expected reason, and the runner deleted an unmarked
payload root without an error.
that failed without it.
worker's per-target parameter copy; each failed with its guard removed.
changelog pull request test failed seven cases before the workflow change.
line lost or duplicated, and
Get-ChangelogDataparses the result.against a scratch directory in both editions.
The domain acceptance lab was not run. This change touches the SMB share,
Active Directory, and Task Scheduler families, and the performance change
touches the batching every family shares. The lab host was not available, so
the new live Active Directory cases are written but have not run. Live
acceptance of this candidate is owed before the next stable release.
Task list
CHANGELOG.md. The entry says what changed for someone using the module and
why, and references the issue being resolved (if applicable).
specs/, everyrequirement identifier it adds is unique, and each one traces to
executable evidence in
specs/0005-verification-and-traceability.md.specs/decisions/andindexed in
specs/decisions/README.md.including a synopsis, a description, an example, and every parameter.
README.mdor underdocs/.fails without the fix.
measured against a real object.
.\build.ps1 -Tasks testpasses in both supported PowerShell editions,including the coverage threshold, with no assertion weakened to get there.
Invoke-ScriptAnalyzeris clean over everything that changed, and anysuppression carries a
Justification.