Surfaced by an automated review sweep. Structurally verified against origin/master by the reconcile loop (the call sites below all exist as described). Neither end-to-end failure has been reproduced yet; a fix owes failing-then-passing tests.
Two related defects in how the wizard's question lanes persist state. Both are asymmetries with a sibling lane that gets it right, so each fix has a working model in-tree.
1. deferWrite does not cover the lanes that write their own state (medium)
src/core/cli/wizard/index.js:476 sets deferWrite: true so the config write happens after the question lanes, on the stated grounds that "a cancel at the sync lane leaves the existing config untouched".
But those lanes are not themselves deferred:
runWizardSyncScope calls writeClientSyncEntries at sync_scope.js:112
runWizardFolderAsk calls writeFolderAskMode at folder_ask.js:135
Both fire as soon as the lane is answered. If commitWizardPickedConfig then returns { ok: false } (the user answers n to Continue? [Y/n], or --force is absent on a non-interactive commit), the wizard prints "keeping existing config at ..." and exits 1 -- while this run's local-only opt-outs and new-folder mode are already persisted to the state dir.
The user is told nothing changed while two policy stores did. Local-only opt-outs are a privacy control, so a false "nothing changed" here is worse than an ordinary state leak.
2. The express gate resets a standing ask preference (medium)
folder_ask.js:86, the auto-accept (express gate) branch, records DEFAULT_FOLDER_ASK_MODE ('sync') rather than before. The asked branch on the same file deliberately uses default: before, with the comment "a re-run defaults to the standing answer, so re-entering the wizard round-trips the preference instead of resetting it".
Concrete failure: a user sets hyp policy folders ask (or picks "Ask me about each new folder" in an earlier run), later re-runs hyp init on the same enrolled machine, and accepts the express gate. Their standing ask is overwritten with sync, and the per-folder session-start question stops firing.
The sibling lane on the same express path gets this right: sync_scope.js auto-accept returns { optedOut: [...optedOutBefore].sort() }, preserving prior state. The two lanes disagree about what "accept the default" means for an existing answer.
Acceptance
Two tests, each failing on current master:
- Answer the sync and folder lanes, then decline the commit confirm, and assert neither policy store changed on disk.
- Set the folder-ask mode to
ask, run the wizard through the express gate, and assert the mode is still ask afterwards.
Surfaced by an automated review sweep. Structurally verified against
origin/masterby the reconcile loop (the call sites below all exist as described). Neither end-to-end failure has been reproduced yet; a fix owes failing-then-passing tests.Two related defects in how the wizard's question lanes persist state. Both are asymmetries with a sibling lane that gets it right, so each fix has a working model in-tree.
1.
deferWritedoes not cover the lanes that write their own state (medium)src/core/cli/wizard/index.js:476setsdeferWrite: trueso the config write happens after the question lanes, on the stated grounds that "a cancel at the sync lane leaves the existing config untouched".But those lanes are not themselves deferred:
runWizardSyncScopecallswriteClientSyncEntriesatsync_scope.js:112runWizardFolderAskcallswriteFolderAskModeatfolder_ask.js:135Both fire as soon as the lane is answered. If
commitWizardPickedConfigthen returns{ ok: false }(the user answersntoContinue? [Y/n], or--forceis absent on a non-interactive commit), the wizard prints "keeping existing config at ..." and exits 1 -- while this run's local-only opt-outs and new-folder mode are already persisted to the state dir.The user is told nothing changed while two policy stores did. Local-only opt-outs are a privacy control, so a false "nothing changed" here is worse than an ordinary state leak.
2. The express gate resets a standing
askpreference (medium)folder_ask.js:86, the auto-accept (express gate) branch, recordsDEFAULT_FOLDER_ASK_MODE('sync') rather thanbefore. The asked branch on the same file deliberately usesdefault: before, with the comment "a re-run defaults to the standing answer, so re-entering the wizard round-trips the preference instead of resetting it".Concrete failure: a user sets
hyp policy folders ask(or picks "Ask me about each new folder" in an earlier run), later re-runshyp initon the same enrolled machine, and accepts the express gate. Their standingaskis overwritten withsync, and the per-folder session-start question stops firing.The sibling lane on the same express path gets this right:
sync_scope.jsauto-accept returns{ optedOut: [...optedOutBefore].sort() }, preserving prior state. The two lanes disagree about what "accept the default" means for an existing answer.Acceptance
Two tests, each failing on current
master:ask, run the wizard through the express gate, and assert the mode is stillaskafterwards.