Skip to content

Windows lab acceptance

Status: deferred future work; lab validation is not underway. The current priority is non-lab documentation, delivery readiness, and an optional approved prerelease. The matrix below is retained for a later resumption; fixture and harness evidence does not imply lab execution.

These checks prepare a disposable Windows client/server lab. They are not acceptance results or permission to provision or execute that lab. Development uses isolated fixtures or mocks only. Actual Windows/user roots require a separately approved disposable host and snapshot; IIS and Exchange additionally require named product/build prerequisites and remain preview-only.

Entry conditions and capability boundary

The preparation baseline is PR #35 merge 66119785413b8cd3b2004f1b9fc7f49bed504a6a. Its bounded risk inventory assigns native/platform gaps to TC-003/004; the source-line inventory retains the earlier immutable coverage baseline. The 232 remaining missed commands are not a percentage target.

Implemented capabilities are the ACL fixture below, existing Pester fixtures for both temp commands, and the separate product preview probe. There is no general actual-root or adversarial lab runner. Manual matrix cases need an approved, reviewed scenario driver and timing barriers before execution; a mock or an attempted race that never reaches its intended boundary cannot pass a native-concurrency case.

Read-only preparation observed a Windows 11 Enterprise 10.0.26200 workstation, non-elevated token, PowerShell 7.6.6, and NTFS volumes. This is development-host context only. No disposable client/server host, snapshot/restore proof, ReFS volume, alternate token, credentials, or actual-root approval was established. An existing directory named like a lab is not proof of those prerequisites. No product probe or actual-root cleaner was run.

Dimension Required acceptance lanes Missing prerequisites / stop condition
OS Each maintainer-approved supported Windows client and server edition/build/architecture; record exact patch/build Named disposable hosts, support decision, isolation owner and reset procedure. A hosted Server 2025 fixture does not cover client builds.
Runtime Windows PowerShell 5.1 and supported PS7 lines; as verified September 17, 2026: 7.4.20, 7.5.11, 7.6.6 Installations and hashes on each host; refresh against Microsoft's lifecycle before execution. Do not replace a missing lane with a skip labeled pass.
Token Elevated administrator and standard/non-elevated split token for both commands Named lab accounts, ACL control and UAC elevation evidence; never infer elevation from account membership or environment variables.
Filesystem NTFS for every applicable lane; ReFS on a supported disposable data volume Verified volume identity, filesystem/driver/build and FILE_ID_INFO behavior. ReFS-inapplicable OS/boot/root combinations need an explicit reason and maintainer disposition. Do not relocate Windows roots to manufacture a lane.
Roots Isolated fixtures first; actual current-user and Windows temp resolution in a restored, separately approved host Approved exact roots, candidate inventory, snapshot ID and successful restore rehearsal. Changing TEMP alone is not Windows-root acceptance.
Concurrency Separate, bounded helper process with named synchronization points and captured exit state Reviewed fixture-only driver, deterministic barriers, deadlines, exclusive fixture ownership, and recovery. Do not start competing cleanup against a shared root.

Expand each case below across the applicable OS/runtime/token/filesystem combinations. Allocate a separate record per combination and command. Blocked, Failed, and NotRun stay distinct; unsupported combinations carry their reason and approval. No lane is implicitly accepted by another lane's result.

Operator sequence for a later approved lab

  1. Name the host, owner, approval reference, supported OS/runtime/token/filesystem lanes, exact allowed roots, maximum duration, snapshot ID and restore procedure. Stop if any are unknown. Keep credentials out of evidence. Obtain execution approval only after this concrete plan and the scenario driver have been reviewed. This preparation stage grants none of those permissions.
  2. Revert the disposable host, prove recovery with a rehearsal, isolate it from production shares/data, and create an exclusive lab-account fixture parent. Record volume identities and all ancestor/reparse checks. Install only the reviewed commit/artifact; require a clean source tree, exact SHA and SHA-256 of scripts, module inputs, drivers, and evidence schema. Keep evidence outside cleanup roots.
  3. In a fresh -NoProfile process, record OS build, runtime/edition/architecture, token SID/elevation, privileges, filesystem/volume ID, root resolution sources, and initial module/preferences/process/service state. Run a single selected case; record its literal invocation, parameters, one UTC cutoff, and every candidate's native volume/file ID, size, attributes and timestamps. Capture errors as ID/category/target/message, never just console text.
  4. Run explicit -WhatIf and reconcile the complete preview inventory and unchanged state before a removal case. Capture actual -Confirm Y and N responses in the existing isolated child-host approach; use -Confirm:$false only for the reviewed fixture operation. A preview failure, changed identity/inventory, missing artifact or incomplete discovery stops the case.
  5. Execute only the approved case. For concurrency, save the barrier timeline, helper PID/exit/timeout and proof that the intended interleaving occurred. Run both continuing and -ErrorAction Stop variants where specified. Collect result object, error stream, post-state and an independent logical-byte/count reconciliation before recovery.
  6. Release all helper/native handles, restore process state, and record an exclusive rename/reopen probe in the disposable fixture to detect leaked handles. The ACL harness deliberately retains its child; never repair a failure using recursive icacls or deletion against an unverified path. Stop on residual or unknown state, preserve evidence, and use the approved snapshot reset. Record reset success and post-restore health separately from case success.
  7. Hash the evidence bundle, attach machine-readable records and raw artifacts to the packet, and obtain maintainer assessment. A harness Acceptance=true means only its isolated case passed; no product, complete TC packet or release gate closes automatically. A confirmed runtime defect becomes a reproduced successor blocker, not an unreviewed change during lab preparation.

Evidence contract

Use lab/acceptance-record.schema.json for the outer record (JSON Schema draft 7). JSON validity is only structural; the reviewer must verify artifact hashes, source identity, case expectations, completed interleavings and recovery. Unknown counts are null, never zero. A Failed record requires explicit failureReasons and may retain null identity/host/root metadata when the failure prevented collection; never invent those values. Record intentional error cases as expected observations, separately from assertion failures.

Every executed Passed or Failed case requires a recovery object. Blocked, NotRun and NotApplicable records can retain null metadata/recovery because no case was executed; missingPrerequisites must explain that state. Assertion evidence is a map from each planned assertion ID to { "status": "Passed", "detail": "observed evidence" } (or Failed, Skipped, NotRun). Derive totals and status counts from those entries, never from independent counters. A passing record requires at least one entry and every entry must pass. The reviewer must also compare the IDs with the complete reviewed case plan: omitting an expected assertion does not pass acceptance. Preflight failures can have an empty assertion map with explicit failure reasons; uncollected execution counts remain unknown.

Artifact group Required content
identity Exact commit and clean/dirty status, case/command, UTC start/end, literal invocation, script/module/driver SHA-256, approval reference and operator; no credentials.
host Disposable host ID, OS edition/build/architecture, full runtime and edition, token SID/elevation/privileges, volume serial and filesystem, snapshot/reset IDs.
root Approved fixture and actual requested/resolved roots, canonical/registry/native resolution sources, native identity, ancestor/reparse inventory, containment decision.
before, preview, after Complete file/directory inventories with path, identity, length, UTC last-write, attributes, ACL/access masks where relevant; candidate and noncandidate counts, content hashes when readable, outside sentinels, stable handles and timestamps. A content-read denial needs native metadata and denial evidence rather than a invented hash.
outcome Raw typed result, proposed/removed/skipped/failed files and directories, logical bytes, discovery status, stable errors with category/target, cutoff, expected versus observed assertions, unknown totals, explicit failure/skip/not-run counts.
concurrency, recovery Barrier timeline and achieved interleaving, helper lifetime, retained/closed handles, rename/reopen proof, environment restoration, residual inventory or enumeration error, retained fixture path, reset/restore outcome and health.

The ACL harness emits its own additive SchemaVersion=1 raw artifact, not the outer schema record, for case ACL-READ-DENIED: exact Commit, WorkingTreeDirty, Scope=IsolatedFixture, approved parent/root, native root/candidate identities (including the volume serial in the native key), readable-file content hash, explicit read denial for the other file, unchanged preview metadata/content and exact candidate paths, ACL masks, runtime/edition, OS caption/version/build, filesystem/drive, token SID/elevation, and result/errors. Architecture, enabled token privileges, approved host/snapshot identity and the complete lane envelope require separate operator collection. This fixture does not substantiate those acceptance lanes by itself.

Recovery is emitted after TEMP/TMP restoration and owned-handle disposal. A DELETE-capable root reopen performs no deletion or rename: it verifies the same non-reparse native identity and closes its probe handle. This checks root sharing/identity, not every possible leaked ancestor handle; the separate Pester rename probe and later lab driver cover ancestry. Reopen failures may reflect ACL/sharing/identity errors and are recorded with native error details. Acceptance requires a clean tree, observed read denial, exact rules, valid OS and NTFS/ReFS evidence, a freshly imported source module, matching preview/removal paths, two removals/six logical bytes, zero command errors, preserved preview/inventory, closed owned handles/probe, successful root reopen, restored TEMP/TMP and an empty retained root. A run failure makes Acceptance=false, preserves available metadata and residue, and requires the caller to reject the artifact. Normal execution initializes a native type and reloads the hashed source module; exit the dedicated process to end that state. It does not promise to restore all caller session state. Preflight failures throw before fixture creation. -WhatIf on the harness itself returns without setup/import/native initialization and is not a case result.

TC-003/004 acceptance matrix

All rows remain unexecuted acceptance. Pester below means an implemented isolated fixture; manual means the later lab still needs a reviewed driver. Common prerequisites and all artifact groups above apply to every row; the last column names additional requirements. Run both temp commands unless the row is explicitly command-specific. Baseline risk ownership comes from the inventory's defensive-lab and platform-lab dispositions and the risk review's native identity/post-delete section.

Case / capability Invariant and safe disposable setup Expected result Additional artifacts and missing prerequisites
ROOT-RESOLUTION / Pester + manual In a snapshotted host compare GetTempPath, canonical LocalApplicationData temp, native Windows directory and registry fallback. Supply an environment-variable decoy only inside the lab. Current-user path must remain canonical/contained; Windows root follows actual OS resolution; malformed/unavailable roots fail before discovery with unknown totals. Resolution sources, TempRootValidationFailed, registry/native values, decoy sentinels. Actual-root host/approval and controlled failure driver missing.
PATH-FORMS / Pester + manual Fixture names with literal brackets, prefix-confusable siblings; drive/root-relative, provider, device, UNC and extended/long-path forms. Never point rejection probes at valuable data. Literal names stay literal; forbidden forms fail closed; supported long paths require actual provider/policy success; no outside access/removal. Input versus comparison/traversal path, long-path policy, provider result, outside hashes. Isolated UNC share/credentials and per-host policy evidence missing.
TOKEN-ACCESS / Pester + manual Same reviewed fixture in elevated and non-elevated sessions; Windows-temp actual root only in the approved host. Report actual token; allowed work reconciles, denied discovery/removal reports stable errors and honors Stop. Token SID/elevation/privileges, ACL and result PrivilegeStatus; alternate accounts/host approval missing.
ACL-READ-DENIED / current-user ACL harness; Windows-temp manual For Clear-CurrentUserTemp, new child under exclusive canonical-temp parent, two old three-byte files; deny ReadData (1), allow Delete (65536) for one file. WhatIf preserves; actual content read is denied; both files removed without content-read permission; six logical bytes; retained empty root, state restored/handles closed. Effective ACL rules/masks, denied-read exception, both native IDs and metadata, recovery. Host/token/filesystem lanes and a Windows-temp ACL driver still missing; this harness covers only Clear-CurrentUserTemp. Dirty source cannot pass.
ACL-DISCOVERY / Pester + manual Deny enumeration on a queued fixture child after partial discovery; separately deny attribute/identity access. TempDiscoveryFailed, unknown candidate totals, no usable partial plan or mutation; Stop terminates; all handles close. Exact ACL masks and timing, error category/target, surviving sentinels, handle probe. ACL-capable driver/token lanes missing.
UTC-BOUNDARY / Pester + manual Old/exact-cutoff/recent files, local clock result, literal names and known sizes. One inclusive UTC cutoff; only eligible files; logical bytes equal successful removals. Captured clock/timezone/cutoff/precision and before metadata. Per-filesystem timestamp granularity evidence missing.
SHOULDPROCESS / Pester + manual Snapshot files, directories, preferences, module/native state and process/registry state; preview, interactive Y/N, explicit Confirm-false, noninteractive invocation. WhatIf/N preserve all state; Y has one owning-command prompt; noninteractive cannot silently approve; every mutation authorized. Transcript/prompt count/responses, state diffs, result status and preserved sentinels. Interactive/noninteractive drivers on named hosts missing.
LOCK-SHARING / Pester + manual Helper holds fixture file with separate read/write/delete-share combinations; record opened rights. Unsupported sharing yields TempFileRemovalFailed with zero removal/bytes for that file; sibling result reconciles; no abandoned handle. Handle access/share masks, helper timeline/exit, continuing/Stop errors. Bounded helper per runtime/filesystem missing.
DELETE-PENDING / manual Helper opens only fixture candidate with delete sharing and retains it across cleaner deletion request. Do not claim successful removal/bytes while the path still exists; reconcile post-delete failure conservatively and disqualify pruning. Existence/native identity before/after last handle close, error/result and pending interval. Deterministic native helper missing; attempted timing alone is not evidence.
FILE-RACE / Pester + manual After discovery, move old candidate aside (prevent file-ID reuse), create a different file or directory; separately make candidate recent or change its length/last-write. Replacement/recent objects survive and count as skips; directory never counted as removed file; native identity/metadata bind deletion and bytes. Old/new IDs, held-handle write/rename outcomes, barrier timeline, sibling/outside hashes. Physical race drivers missing; injected-plan tests are not physical replacement proof.
ROOT-RACE / Pester + manual Attempt root/ancestor rename, replacement or reparse substitution at planning/mutation barriers; no outside data. Held handles block replacement or identity revalidation fails closed (TempRootChanged); no outside mutation. Every ancestry ID/handle, actual operation errors and timeline, closed-handle probe including Stop. Reviewed hostile-timing driver missing; no claim of immunity to kernel filters.
QUEUED-DIRECTORY / Pester + manual Replace/reparse a queued child before enumeration, or fail its identity capture in a controlled fixture. Fail discovery, discard partial totals, preserve data, release ancestors; no traversal into the substitute. Queue/barrier evidence, target sentinels, stable TempDiscoveryFailed and identity failure. Physical native-interleaving driver missing.
REPARSE / Pester + manual Root/ancestor/descendant junctions and symlinks with target sentinel inside separate fixture; test attribute change while handles are held. Root/ancestry validation or traversal fails closed; links not traversed/removed; target unchanged. Reparse tag, IDs and target inventory, token privilege, native attribute-change outcome. Link rights and supported filesystem variants missing.
HARDLINK / Pester + manual Two fixture names sharing one file identity, one outside approved cleanup child; use NTFS and only filesystems supporting hard links. Only approved name removed; outside name/content remains; reported bytes are logical, not physical free space. Link count, shared identity, both path inventories and content hashes. Unsupported ReFS variant is blocked/not-applicable with reason, never a silent pass.
PRUNE-OPT-IN / Pester + manual Old-file leaf/ancestors plus unrelated empty branch, root and recent-file branch; run with/without RemoveEmptyDirectory. No directories without opt-in; with opt-in only invocation-emptied identity-matching directories/ancestors, deepest-first; preserve roots/unrelated/recent/reparse branches. Complete before/after directory graph, proposed/removed/skipped counts, parent IDs and mutation order. Host/filesystem lanes missing.
PRUNE-DISQUALIFY / Pester + manual Per-run variants: vanished/skipped/locked/failed/recent/reparse child, child made nonempty, planned directory replaced, prune access/I/O failure. A disqualified descendant blocks ancestor pruning even if another actor empties it; replacement survives; TempDirectoryRemovalFailed where applicable; Stop releases handles. Who removed each child, old/new identities, errors/category/target, ancestor survival and timeline. Native timing/ACL driver missing.
RECONCILE / Pester + manual Mix successes, missing files, preserved replacements, denied operations, and directory outcomes; separate empty versus failed discovery. Valid discovery: candidates = removed + skipped + failed for each kind; no bytes for failed/skipped files; discovery failure uses null totals, not empty success. Independent per-path outcome ledger, logical-length sum and raw result/error IDs. Delete-pending/native failure variants missing.
HANDLE-RECOVERY / Pester + manual For success, declined/WhatIf, discovery failure, removal failure and Stop, inspect owned handles and helper lifetimes; bounded rename/reopen afterward. No leaked native/helper handles; environment restored; recovery failure is recorded and blocks acceptance; residue preserved for snapshot recovery. Handle counts/closed flags, rename/reopen result, original/final environment, helper exit, residue/reset/health. Snapshot and restore proof missing.
REFS-IDENTITY / manual All applicable identity, locks, race, pruning and reconciliation rows on an approved ReFS fixture volume. Stable FILE_ID_INFO or explicit fail-closed error; no NTFS result substituted as ReFS acceptance. Volume serial, ReFS version/build, raw native error/identity behavior. Supported volume and canonical user-temp placement missing; no root-relocation automation exists.

Temp cleaners

Use the ACL harness only with an already-created exclusive disposable parent beneath that lab user's canonical LocalApplicationData temp directory. A path like C:\Disposable\TheCleanersLab outside that boundary is rejected. The cleaner targets a new GUID child only; the parent and actual temp root are never cleanup targets. These commands are a later execution recipe, not permission to run a lab:

$FixtureParent = Join-Path ([Environment]::GetFolderPath('LocalApplicationData')) 'Temp\TheCleanersLab'
# The approved operator creates and reviews this parent and C:\LabEvidence (outside cleanup roots) before invoking the harness.
$Evidence = .\lab\Invoke-TheCleanersAclFixture.ps1 -FixtureParent $FixtureParent -Confirm:$false | ConvertFrom-Json
$Evidence | ConvertTo-Json -Depth 10 | Set-Content -LiteralPath C:\LabEvidence\acl-raw.json -Encoding UTF8
if (-not $Evidence.Acceptance) { throw 'ACL fixture failed; preserve the record and retained child.' }

Exit that process. Hash acl-raw.json and reference it from the appropriate artifact groups in a separate outer case record. Collect the missing host/token/snapshot, assertion and recovery/reset evidence; validate that record against the schema and verify its artifact hashes before proposing any lab acceptance.

The exact PR #31 hosted PS5.1 job for merged commit 037c27a81234361620a633f68a33bfb370f0a03e used its isolated runner temp child and uploaded the machine-readable Windows PowerShell results. It recorded two candidates (old-readable.tmp and old-delete-without-read.tmp), 2 -> 0, FilesRemoved = 2, BytesReclaimed = 6, no failures/skips/error IDs, NTFS, elevation, and Acceptance = true. That fixture is not complete Windows client/server, broader elevated/non-elevated, ReFS, or real system-root acceptance.

IIS and Exchange preview gates

Until the release-plan gates pass, these commands remain structurally preview-only. Lab work may validate discovery and service health, but must not add a deletion call or treat a preview candidate list as authorization.

Product Required evidence before any later removal design
IIS WebAdministration availability/missing-product behavior; Web/FTP/custom format allowlists; expanded and deduplicated default/custom roots; protected inetsrv/configuration/history paths; before/after candidate inventory; IIS service health.
Exchange Exact v15 product/build and supported path matrix; MessageTracking/ETL/diagnostic patterns; mailbox database and transaction-log exclusions including custom paths; before/after candidate inventory; Exchange service health.

No 1.0 release gate is satisfied by mocked fixtures alone. Attach the lab evidence to the packet/PR and keep the preview lock until a maintainer approves the product-specific transition.

Run the read-only product probe only in a disposable product lab after recording the exact commit and product build:

.\lab\Invoke-TheCleanersProductPreviewLab.ps1 -Confirm:$false

The exact merged commit has no IIS or Exchange product/build lab record. Do not copy the earlier workstation absence probe forward as acceptance or exact-commit evidence.