Conversation
The plan summary is the screen the user reads and approves before any disk is touched, and it was the least testable thing in the product: about seventy lines of inline Write-Host in the linear body, 27 print calls, 13 branches, 28 variables, and the mode tested three times in two different shapes. The suite lifts functions out of the syntax tree and cannot reach the body, so nothing could check what a line said - only that some string sat somewhere. Format-CreationPlan now returns one object per line, carrying its text and the colour it prints in. The body assembles the answers and prints what comes back. Answers travel as a hashtable rather than an object with fields: mode-specific variables are assigned only inside the branch that asked for them, and under strict mode reading an unset variable throws. Pre-initialising them would print values nobody chose, which the repository forbids. So a key exists only where its branch asked the question. What can be asserted now, and could not be before: - a mode's plan names only what that mode does - a skipped step says it is skipped rather than being absent - the size, the label, the disk and the file are the ones answered - the write-access warning reaches the plan, line by line, in yellow - every kind of line carries the colour that kind is printed in - the keys the body sets, the function reads, and the fixture builds agree Seven existing tests anchored on the block's position and were retargeted; four became assertions on the function instead. One of them, counting calls to Format-DedupModeChoice, had never counted the fourth. Every new assertion was proved to have teeth by mutating the source in place and running the suite against it - a leaked branch, a vanished step, a hardcoded size, a dropped key, a stray key, a warning turned white, and the write-access warning removed. All seven were caught, and both files restored byte for byte. Closes #79 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
Closes #79.
What was wrong
The plan summary is the screen the user reads and approves before any disk is touched — the one place consent is given. It was also the least testable thing in the product:
Write-Hostin the linear bodyThe suite lifts functions out of the syntax tree and cannot reach the body, so nothing could check what a line said — only that some string sat somewhere near another. #68 is the precedent: a whole mode shipped broken because its decisions lived where no test could see them.
What it does now
Format-CreationPlanreturns one object per line, carrying its text and the colour it prints in. The body assembles the answers and prints what comes back:Thirteen branches became three, and all three are now about what to pass, not what to say.
Why a hashtable rather than an object with fields. Mode-specific variables —
$VhdxPath,$DriveLetter,$DiskNumber— are assigned only inside the branch that asked for them, and underSet-StrictMode -Version Latestreading an unset variable throws. Pre-initialising them would print values nobody chose, whichAGENTS.mdforbids in so many words. So a key exists only where its branch asked the question, and the function refuses a mode it has no plan for rather than falling into the physical branch.What can be asserted now, and could not be before
.vhdxpath are the ones that were answeredProved to have teeth
Each defect was reintroduced in the source and the suite run against it. Both files were restored byte for byte afterwards.
Review
An independent review raised 20 points; 19 were applied. Two of them were holes this change had opened or left open:
The write-access warning was covered by nothing. The test fixture always answered
WritePolicy = 'Allow', under which that advice is silent — so the line telling the user the drive will mount read-only and the run will stop could have been deleted and the whole suite stayed green. It is the highest-stakes line on the consent screen. There are now cases forDenyandUnknownasserting every line of the advice and its colour.One retargeted test had become vacuous. It looked for
Resolve-WriteAccessPolicyAdviceafter the "Skip BitLocker" line and found a different call entirely — the one behind the BitLocker question. Three assertions passed for the wrong reason. It was the eighth test needing retargeting and had not got it.Also applied: no test asserted a specific colour, so every warning could have turned white unnoticed; the fixture answered
GPT, the same value hardcoded in the script, so a literal would have passed for an answer; the.vhdxpath and the shrunk drive's label were never positively asserted; anIndexOfcomparison had no guard, and-1is less than everything; the call-argument assertion had weakened to checking parameter names only; the registry policy path had become a second literal in the tests, and is now read out of the script;[string]$Colouraccepted anything and is now[System.ConsoleColor], failing on the way in rather than halfway through printing.Adapted rather than applied: the suggestion to restructure the mode branches as a
switchwith a throwingdefault. A guard at the function's entrance gives the same protection — a fourth mode fails loudly instead of falling into the physical branch — for far less churn, and it has its own test.Declined, one: renaming
Format-CreationPlantoResolve-CreationPlanbecause it returns objects rather than strings. It renders the plan, and the colour is part of the rendering rather than a decision left to the caller;Format-CreationPlanis also the name #79 itself asks for. The docstring that made it sound like a decision function was reworded instead.🤖 Generated with Claude Code