Skip to content

test(lab): record the lab acceptance and test every lab-only command - #6

Merged
raandree merged 12 commits into
mainfrom
ai/record-post-release-publication
Oct 8, 2026
Merged

raandree merged 12 commits into
mainfrom
ai/record-post-release-publication

Conversation

@raandree

@raandree raandree commented Oct 8, 2026

Copy link
Copy Markdown
Owner

Pull Request (PR) description

This pull request lands the domain-lab acceptance of v0.3.0-preview0002:
its records, the tests it added, and the one module change it asked for. Each
part has its own commits, so any part can be reverted on its own.

  • Active Directory. Get-WindowsADRootDse and
    Get-WindowsADEffectiveAccessRecord now read through
    Send-WindowsADSearchRequest, the directory search function that every
    other directory read already uses, so unit tests reach their four response
    checks without a domain controller. Both files leave
    CodeCoverage.DomainLabOnlySourcePath in build.yaml, so their commands
    count toward the asserted coverage now (4096d02).
  • Behavior change. An object deleted between target resolution and the
    effective-access read of Get-ADObjectCallerEffectiveAccess now fails with
    an ItemNotFoundException naming it, like the family's other reads, instead
    of a MethodInvocationException from the LDAP call. Specification 0018
    states it in its output contract, and CHANGELOG.md records it under
    Changed (4096d02).
  • Live tests. Every command in the declared domain-lab-only files now has
    a test. New live cases cover the Task Scheduler repair of a protected DACL
    without Local System; the SMB share description that the native write
    clears, that is edited concurrently, or that cannot be read before the
    write; five SMB share guards, including the confirmation prompt in a session
    without a user interface; two injected enrichment failures; and a directory
    object deleted inside the effective-access read. Each case failed against a
    build with its guard removed and passed against the candidate (6ea9d7e,
    938bdff, bad1302).
  • Lab harness. Arming member coverage no longer leaves a member session
    stopping on every error. Enter-WindowsAccessControlMemberCoverage runs its
    remote body in a child scope, so the Stop preference it sets ends with the
    call (a572d3d, changelog Fixed).
  • Documentation. Specification 0009 and the SMB share usage page name both
    windows in which a share DACL write can still replace a concurrent
    description edit (6ea9d7e, changelog Fixed). Specifications 0005, 0009,
    0010, and 0018 name the new evidence.
  • Acceptance records. docs/lab-acceptance-2026-10-07.md and
    docs/lab-acceptance-2026-10-08.md record the acceptance runs, and the
    Memory Bank records the publication of v0.3.0-preview0002 and the
    acceptance (ce22f00, a18e52c, 69dbfcd, 6f6bd0b, c1c53cf,
    300e937, a95321c).

No commit message on this branch matches a GitVersion bump pattern.
GitVersion 5.12.0, run on a simulated merge commit of this branch into
main, reports 0.3.0-preview0003, so the merge publishes a preview.

This Pull Request (PR) fixes the following issues

  • n/a

What was run, and what the result was

On a95321c, on Windows with PowerShell 7.6.6 and Windows PowerShell
5.1.26100, each step in its own process. No domain-lab coverage document was
present, so the coverage figures are the ones CI computes.

Command Result
.\build.ps1 -Tasks build Succeeded: 7 tasks, 0 errors, 0 warnings
.\build.ps1 -Tasks test in PowerShell 7 1,938 passed, 0 failed, 2 skipped; asserted coverage 83.19 % (6,946 of 8,350 commands, threshold 80 %); 10 tasks, 0 errors, 2 warnings from the lab-runner failure-path tests
.\build.ps1 -Tasks test in Windows PowerShell 5.1 1,893 passed, 0 failed, 2 skipped; asserted coverage 80.95 % (6,759 of 8,350 commands, threshold 80 %); 10 tasks, 0 errors, 2 warnings from the same lab-runner tests; 11 min 42 s, with local WinRM running for the two DSC-engine tests
Invoke-ScriptAnalyzer 1.25.0 over the 9 changed PowerShell files 0 findings

The two skipped tests are the documented environment cases: no mounted volume
on the host, and no privilege to read the audit section.

The domain acceptance lab ran on 2026-10-07 and 2026-10-08:

  • 2026-10-07, docs/lab-acceptance-2026-10-07.md: main at 2ebb3a5,
    built as 0.3.0-preview0002 and byte-identical to the Gallery package. The
    Desktop DSC-engine gate passed 5 of 5, four full passes (built module and
    installed package, Desktop and Core) passed 97 of 97 each, and both
    lab-runner ownership refusals were proven against decoys. A follow-up added
    four live cases, each red against the code before its change, and repeated
    the four passes at 101 of 101.
  • 2026-10-08, docs/lab-acceptance-2026-10-08.md: candidate bad1302.
    The DSC-engine gate passed 5 of 5, and four passes of 109 cases each passed
    with eight ready cleanup entries. With the fresh lab coverage merged, the
    local gates passed 1,937 tests in PowerShell 7 at 91.26 % asserted coverage
    and 1,892 in Windows PowerShell 5.1 at 90.53 %; domain-lab-only coverage is
    100 % (154 of 154 commands). The harness correction a572d3d, with the
    module bytes unchanged, passed a built pass of 109 of 109 in both editions
    with line-identical lab coverage, and the local gates passed 1,938 and 1,893
    tests at the same coverage. a95321c changes only records.

Task list

  • Added an entry to the change log under the Unreleased section of the file
    CHANGELOG.md. The entry says what changed for someone using the module and
    why, and references the issue being resolved (if applicable).
  • The behavior change starts in a specification under specs/, every
    requirement identifier it adds is unique, and each one traces to
    executable evidence in specs/0005-verification-and-traceability.md.
  • A durable architectural choice is recorded under specs/decisions/ and
    indexed in specs/decisions/README.md.
  • Comment-based help added or updated for every new or changed command,
    including a synopsis, a description, an example, and every parameter.
  • Documentation added or updated in README.md or under docs/.
  • Unit tests added or updated, and a bug fix keeps a regression test that
    fails without the fix.
  • Integration or live tests added or updated where the behavior can only be
    measured against a real object.
  • .\build.ps1 -Tasks test passes in both supported PowerShell editions,
    including the coverage threshold, with no assertion weakened to get there.
  • Invoke-ScriptAnalyzer is clean over everything that changed, and any
    suppression carries a Justification.

raandree and others added 12 commits October 7, 2026 13:33
Pull request #5 merged as 2ebb3a5, and the release run published
v0.3.0-preview0002 to GitHub and the PowerShell Gallery with the wiki
updated. The record keeps only what is still open: live lab acceptance
before the next stable release, the changelog token permission, and the
recorded follow-ups. Both files end well under their line budget.

Co-authored-by: AI Assistant <ai@example.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The development machine has no lab VMs, so handoff 07 runs on the
Hyper-V host that holds WindowsAccessControlLab. The handoff folder
travels there with a git bundle of main, its tags, and this record
branch, and the record now names the development machine explicitly so
it reads correctly on the lab host.

Co-authored-by: AI Assistant <ai@example.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Live domain-lab acceptance of main 2ebb3a5, published as
v0.3.0-preview0002, on the Hyper-V lab host. The release-equivalent build
from GitVersion 5.12.0 matches the Gallery package byte-for-byte. Four lab
passes ran 97 cases each with eight ready cleanup entries, the isolated
Desktop DSC engine gate ran 5 of 5, and both local gates passed with the
new lab coverage merged. The lab-runner ownership refusals were proven
against decoys, and a byte and ACL inventory proves the restoration.

Records the evidence in docs/lab-acceptance-2026-10-07.md, indexes it, and
updates the Memory Bank with the lab state, open work, and lessons.

Co-authored-by: AI Assistant <ai@example.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Four live cases reach the paths that only unit tests covered. A disposable
Task Scheduler folder and task, whose protected DACLs lack Local System,
accept an unrelated ACE, refuse a Local System deny without writing, and
get Local System back. Around an SMB share DACL write, a raw native write
shows that the description is cleared, and the command restores and
reports it; a native watcher's concurrent edit is kept with a warning; and
an injected failure of the setter's own description read stops the command
before anything is written. Each case fails against the builds of 96d6671
and 5531824 for the reason its change names, and passes on the candidate.

The specifications, the traceability table, the checklist, and the lab
guide name the new evidence. The SMB usage page and specification 0009 now
describe both windows in which a concurrent description edit can still be
replaced.

Co-authored-by: AI Assistant <ai@example.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The 2026-10-07 acceptance record now holds the follow-up: the four live
cases, their red results against the parent builds, all four passes
repeated with them, the final lab coverage and local gates, and three
observations. The Memory Bank records the lab state, the open work, and the
lessons from reaching each guard live.

Co-authored-by: AI Assistant <ai@example.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…h seam

Get-WindowsADRootDse and Get-WindowsADEffectiveAccessRecord sent their
LDAP requests straight to the connection, so no unit test could reach
their response checks and both files were declared domain-lab-only for
coverage. Both now go through Send-WindowsADSearchRequest, like every
other directory read. Unit tests replace the request at that seam and
prove that a RootDSE or effective-access response without exactly one
entry is refused, that a RootDSE without a root domain naming context
reports none, and that an absent sDRightsEffective reports zero. The two
files leave the domain-lab-only list, so the local coverage gate now
asserts them.

An object deleted between target resolution and the effective-access
read now fails with an ItemNotFoundException naming it instead of a
MethodInvocationException from the LDAP call. Specification 0018 and the
changelog say so.

Co-authored-by: AI Assistant <ai@example.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Eight live cases reach the SMB share and Active Directory paths that no
test executed. On the member server, an SDDL without a DACL is refused
before anything is written, -PassThru returns the stored descriptor, a
rule copy that was not read from the share and a rule whose canonical
target names another server are refused with the grant left in place,
and a share DACL write without -Confirm:$false asks for confirmation and
writes nothing when the caller cannot answer. That last case opens its
own session from a runspace without a user interface, because a remote
prompt goes to the host that opened the session, and it arms member
coverage there under its own name.

In the directory suite, a module-scope mock fails the inheritance-source
or schema-name lookup after the real descriptor read, and the rules are
still reported with a non-terminating error. The calls state the default
Continue preference because the runner stops on every error. A
disposable organizational unit deleted inside the effective-access
request is reported as not found.

Each case fails against a build with its guard removed and passes on the
candidate. The checklist, the traceability table, and specification 0009
name the new evidence.

Co-authored-by: AI Assistant <ai@example.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The Desktop coverage pass of 938bdff stopped at the confirmation case. A
session opened from a runspace without a user interface starts with
remote debugging off, so the coverage breakpoints could not be armed in
it; the focused runs had no coverage armed and could not show this. The
case now enables remote debugging on that session before arming
coverage, and a focused Desktop run with member coverage armed records
the confirmation's throttle line.

Arming member coverage also leaves the session stopping on every error,
because the harness sets the preference in a script block that the
session runs at its top level. The case therefore states the default
Continue preference under which the refusal is reported.

Co-authored-by: AI Assistant <ai@example.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The 2026-10-08 record names the 17 commands that no test executed in the
declared domain-lab-only files, how each now gets a test, the red evidence
against a build with each guard removed, and the passes of bad1302: the
DSC gate, four passes of 109 cases, and both local gates, with the
domain-lab-only coverage at 100 percent. It also records why the first
built pass of 938bdff stopped, the remote-prompt and error-preference
behavior the cases rely on, and the cleanup. The 2026-10-07 record and the
documentation index link to it, and the Memory Bank records the state, the
open harness defect, and the lessons.

Co-authored-by: AI Assistant <ai@example.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Removing the older lab checkpoint with Remove-LabVMSnapshot also deleted
the newer one that the maintainer had asked to keep, on ten of the
thirteen VMs, because AutomatedLab removes a checkpoint with all its
children. With the maintainer's agreement a new checkpoint,
wac07-after-bad1302-9d9776ca, now covers all thirteen VMs, and the old
checkpoints on the other three were merged away one at a time. The record,
the Memory Bank lab state, and the lessons say so.

Co-authored-by: AI Assistant <ai@example.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…erage

Enter-WindowsAccessControlMemberCoverage armed the member module through
Invoke-Command -Session, which runs its script block at the top level of the
persistent member session. The $ErrorActionPreference = 'Stop' it set there
outlasted the call, so in the Desktop coverage pass the SMB share,
certificate private-key, Task Scheduler, and foreign-principal suites stopped
at their first non-terminating error, while every other pass continued.

The arming body now runs in a child scope that receives its values as
parameters; the global breakpoint list still outlives the call. A unit case
runs the remote block in a separate runspace and asserts the armed count and
the unchanged preference; it failed with 'Stop' against the previous harness.
A live probe from F1ADC1 into an F1AFile1 member session showed 'Stop' and a
call ended by a non-terminating error with the previous harness, and
'Continue' with the next statement reached after this change, in both
editions, with all 8,504 locations armed.

The SMB confirmation case keeps stating -ErrorAction Continue; its comment no
longer cites the leak. The changelog and specification 0005 record the
behavior.

Co-authored-by: AI Assistant <ai@example.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The 2026-10-08 acceptance record gains a Harness correction section for
a572d3d: the unit and live red/green evidence, the candidate hashes with the
unchanged root module, the built pass of 109 cases in both editions with
line-identical lab coverage, both local gates (Core 1,938 at 91.26 percent
and Desktop 1,893 at 90.53 percent asserted, domain-lab-only 100 percent),
and the restoration. The observation and the retention paragraph no longer
call the leak open work, and the docs index names the correction.

The Memory Bank records the correction, drops the leak from the open work,
states the snapshot-removal lesson as the checkpoint subtree, and moves the
four oldest 2026-10-06 progress entries behind a git show pointer to stay
within the line budget.

Co-authored-by: AI Assistant <ai@example.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@raandree
raandree merged commit 323928b into main Oct 8, 2026
4 checks passed
@raandree
raandree deleted the ai/record-post-release-publication branch October 8, 2026 11:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant