Skip to content

fix(macos): a sourced augur could not enumerate its own shares - #165

Merged
h1d3mun3 merged 1 commit into
mainfrom
fix/macos-share-roots-unbound
Aug 3, 2026
Merged

fix(macos): a sourced augur could not enumerate its own shares#165
h1d3mun3 merged 1 commit into
mainfrom
fix/macos-share-roots-unbound

Conversation

@h1d3mun3

@h1d3mun3 h1d3mun3 commented Aug 3, 2026

Copy link
Copy Markdown
Owner

The latent defect behind the make e2e incident while validating #163/#164.

macos_share_roots reads $MACOS_SHARE on its first line, but the assignment
lived in the dispatch tail, 54 lines below the AUGUR_SOURCE_ONLY early
return. augur runs set -euo pipefail, so every context reaching the script
through this project's own test seam — AUGUR_SOURCE_ONLY=1 source ./augur, what
every tests/NN_*.sh uses — died there with MACOS_SHARE: unbound variable.

An executed up --macos was never affected

Worth stating up front, because the incident makes it look worse than it is: the
assignment runs before dispatch, and the refresher is a plain ( … ) & subshell
rather than a re-exec, so it inherits the binding. Nothing shipped sources the
file. The damage was to what could be tested, and to what could be
diagnosed.

Two consequences

The sweep was structurally untestable offline. _refresh_macos_shares_locked
calls macos_share_roots, and every offline test reaches it through the seam — so
no test could execute the sweep at all. That is why nothing caught this.

A refresher started from a sourcing context ran dead while looking healthy. The
roots are consumed by done < <(macos_share_roots …) — a process substitution
so the unbound-variable death killed only the producer subshell. The while read
loop got no input, n stayed 0, and the function took its n == 0 early return,
which promoted the marker and reported NOWORK. The loop survived, the pidfile
stayed live, share_refresher_running reported healthy, and nothing was ever
msynced.

Measured on an Apple Silicon host: 31 hours of exactly that, 1.1 MB of the same
error in the refresher log, while start_share_refresher's idempotence
(share_refresher_running && return 0) made every later up --macos leave the
live pidfile alone. The live E2E arm "a host edit became visible in the running
guest"
failed for its full 30 s budget. With the stale refresher cleared, the same
arm passes in 5 s.

The fix

1. Bind MACOS_SHARE above the seam, so a sourced augur can reach the sweep.
Verified safe rather than assumed: workspace_slug reads only $WORKSPACE_DIR
(set at augur:12), and nothing between the two positions reassigns it.

2. macos_share_roots refuses with a named error when MACOS_SHARE or
WORKSPACE_DIR is empty, instead of dying anonymously inside a process
substitution the caller cannot observe. Presence check only, deliberately: a
mismatched-but-set pair is legitimate (tests/41 pairs workspace-testslug with
its own root on purpose).

3. Stop conflating "nothing changed" with "nothing was scanned." n == 0 had
two meanings and only one was good news.

Important

The failure path does not promote the marker. Promoting it would put every
host edit made during the broken window permanently past find -newer, so those
edits would never be swept even after the bug was fixed. The genuine no-work
path is unchanged — quiet, and it still promotes.

The warn also names which of the two happened, so the next occurrence is one
line to diagnose rather than a log dig.

Tests

tests/41 gains a section that executes the sweep through the seam — literally
impossible before this commit — plus arms pinning both marker outcomes. They assert
the marker's own state, not just the message.

Mutation-checked, twice, independently:

mutant result
predicate roots instead of scanned 3 arms red
failure path promotes the marker anyway 3 arms red, incl. the skipped edit is swept by the next sweep

That second one is the property that matters: it fails precisely when edits made
during a broken window would be lost.

tests/36, tests/38 and tests/e2e_macos_vm.sh carried comments describing the
old ordering as load-bearing. Those are corrected — comments only, no code.

Verified / not verified

Verified here, on this branch rebased onto 4cf2a60 (so alongside #163 and #164):
make offline-tests ALL GREEN (30 scripts), make shellcheck clean,
bash -n augur OK, both mutants above, and:

$ bash -c 'AUGUR_SOURCE_ONLY=1 source ./augur; macos_share_roots testvm'
workspace-seam	/Volumes/My Shared Files/workspace-augur/.claude/worktrees/seam
claude-projects	/Users/admin/.augur/claude-projects/testvm
claude-agents	/Users/admin/.augur/claude-agents/testvm
claude-profile	/Users/admin/.augur/claude-profile
rc=0

which died with MACOS_SHARE: unbound variable before this change.

Not verified here: the live macOS E2E, which needs an Apple Silicon host. Since
an executed up --macos was never on the broken path, this is not expected to
change any live arm — but main is the release gate, so it is worth one run.

🤖 Generated with Claude Code

`macos_share_roots` reads `$MACOS_SHARE` on its first line, but the
assignment lived in the dispatch tail, 54 lines BELOW the
`AUGUR_SOURCE_ONLY` early return. augur runs `set -euo pipefail`, so in
every context that reaches the script through the project's own test seam
-- `AUGUR_SOURCE_ONLY=1 source ./augur`, which every `tests/NN_*.sh` uses
-- that first line died with `MACOS_SHARE: unbound variable`.

An EXECUTED `augur up --macos` was never affected: the assignment runs
before dispatch, and the refresher is a plain `( … ) &` subshell rather
than a re-exec, so it inherits the binding. Nothing shipped sources the
file. The damage was to what could be TESTED and to what could be
diagnosed.

TWO CONSEQUENCES.

The sweep was structurally untestable offline. `_refresh_macos_shares_locked`
calls `macos_share_roots`, and every offline test reaches it through the
seam, so no test could execute the sweep at all. That is why nothing
caught this.

And a refresher started from a sourcing context ran dead in a way that
looked healthy. The roots are consumed by `done < <(macos_share_roots …)`,
a process substitution, so the unbound-variable death killed only the
producer subshell. The `while read` loop got no input, `n` stayed 0, and
the function took its `n == 0` early return -- which promoted the marker
and reported NOWORK. The loop survived, the pidfile stayed live,
`share_refresher_running` reported healthy, and nothing was ever msynced.
Measured on an Apple Silicon host: 31 hours of it, 1.1 MB of the same
error in the refresher log, while `start_share_refresher`'s idempotence
(`share_refresher_running && return 0`) made every later `up --macos`
leave the live pidfile alone. The live E2E arm "a host edit became visible
in the running guest" failed for the full 30 s budget; with the stale
refresher cleared, the same arm passes in 5 s.

THE FIX, in three parts.

`MACOS_SHARE` is bound above the seam, so a sourced augur can reach the
sweep. Verified safe: `workspace_slug` reads only `$WORKSPACE_DIR`, which
is set at augur:12, and nothing between the two positions reassigns it.

`macos_share_roots` now refuses with a named error when `MACOS_SHARE` or
`WORKSPACE_DIR` is empty, instead of dying anonymously inside a process
substitution the caller cannot see. It is a presence check only, and
deliberately so: a mismatched-but-set pair is legitimate (tests/41 pairs
`workspace-testslug` with its own root on purpose).

The sweep stops conflating "nothing changed" with "nothing was scanned".
`n == 0` had two meanings and only one was good news. The failure path now
warns, names which of the two happened, and -- the part that matters --
does NOT promote the marker. Promoting it would put every host edit made
during the broken window permanently past `find -newer`, so the edits
would never be swept even after the bug was fixed. The genuine no-work
path is unchanged: quiet, and it still promotes.

Tests. tests/41 gains a section that executes the sweep through the seam,
which was impossible before this commit, plus arms pinning both marker
outcomes -- and they assert the marker's own state, not just the message.
Mutation-checked: making the predicate `roots` instead of `scanned`, and
making the failure path promote the marker anyway, each turn three arms
red. tests/36, tests/38 and tests/e2e_macos_vm.sh carried comments that
described the old ordering as load-bearing; those are corrected, no code.

Verified: `make offline-tests` ALL GREEN (30 scripts), `make shellcheck`
clean, `bash -n augur` OK, and
`bash -c 'AUGUR_SOURCE_ONLY=1 source ./augur; macos_share_roots testvm'`
now prints the four share rows and exits 0. Not verified here: the live
macOS E2E, which needs an Apple Silicon host.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown

🧭 Egress drift reminder

This PR changes the egress core (augur / augur-proxy/ / gvproxy/ / augur.conf / augur-vm/) but does not touch docs/security-reviews/.

If this change alters the egress posture, please:

  • run /egress-survey (the bounded drift audit), and
  • if it drifted: add a new dated snapshot under docs/security-reviews/ and/or update docs/security-reviews/INVARIANTS.md.

Non-blocking reminder. It does not verify correctness (that is the egress fail-closed E2E + swift test). If no doc update is needed, ignore this.

@h1d3mun3
h1d3mun3 merged commit 2582bf3 into main Aug 3, 2026
3 checks passed
@h1d3mun3
h1d3mun3 deleted the fix/macos-share-roots-unbound branch August 3, 2026 13:19
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