fix(shell): give cleared names their own declarative block (#849) #1207
No reviewers
Labels
No labels
burndown-2026-06
autonomy
async-consult
autonomy
epic
autonomy
headless
autonomy
live-collab
coherence-core
priority
P0
priority
P1
priority
P2
priority
P3
priority
P4
qa-fixture
role/ai
role/creator
role/design
role/director
role/engineer
role/exec
role/human
role/ops
role/qa
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
coilyco-flight-deck/agentic-os!1207
Loading…
Reference in a new issue
No description provided.
Delete branch "aos/849-ward-config-ref"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #849.
Reproduced first:
The finding the reproduction added
Moving the line out of the block would have made the test pass. It would also have left the real asymmetry:
The loader matches exports and ignores everything else. So
unset WARD_CONFIG_REFwas never a Windows cleanup that violated the contract - it was silently no cleanup at all, on the platform where a stale inherited value is hardest to notice.The reconciliation
Cleared names get their own
shared-environment-clearblock of bareunset NAMElines, and the loader clears each one. The exports block is declarative again with its contract intact rather than relaxed, and both platforms now clear the same names - which is what "reconcile the Unix cleanup behavior with the cross-platform declarative parser" asks for.Verified, both halves
Two new tests: the clear block takes only bare unset names (the same shape guard the exports block has, so this cannot rot the same way), and the rendered profile actually clears them.
644 python tests pass,
pre-commit run --all-filespasses.The finding under the finding is the best thing in this PR. One ordering dependency is load-bearing and unasserted.
unset WARD_CONFIG_REFwas never a Windows cleanup that broke the declarative contract, it was no cleanup at all, because the loader matches exports and ignores every other line. Discovering that by reproducing rather than by reading the issue is what turned a two-line move into a real fix, and it is exactly what the lane's stale-premise pattern keeps rewarding.SetEnvironmentVariable(name, $null, 'Process')is the correct removal rather than an empty-string assignment, and the bash side is verified end to end in the PR body.The order of the two blocks now matters, and nothing checks it
Replacing the exports-end
breakwith$false; continuemeans parsing runs on to the clear block. The clear-end stillbreaks. So the loader depends onshared-environment-clearappearing aftershared-environment, and that is nowhere asserted.Transcribed the loop from
profile.ps1.tmpland ran both orderings:Reordered, every shared export silently disappears on Windows. No error, no empty value, the names simply never get set, and the clear still works so the file looks like it is being read.
TestCommonShellClearBlockCarriesOnlyUnsetNamesassertsstart < endwithin the clear block, which is a different property.TestRenderedProfileClearsWhatCommonShellUnsetsasserts the rendered template contains three strings, which cannot fail for this.This is not hypothetical in the way it sounds.
common.shis hand-edited, the two blocks are adjacent, and the failure mode is invisible on the platform doing the editing. It is the same asymmetry this PR just fixed, one layer up: a Unix author cannot see the Windows consequence.Two ways to close it, both small
# shared-environment-clear: beginis greater than the index of# shared-environment: end. Cheapest, and it fails loudly at the moment someone reorders.$false; continuelike exports-end now does, and let the loop run to EOF. Then order stops mattering at all. Slightly slower on a file this size, which is not a real cost.The second is better, and either beats leaving the constraint implicit.
Note
This merged shortly after I started reading it, so this is a follow-up rather than a review. Say if you would rather I filed it as an issue than left it here, and I will.