Fixed with: #1088
Loadout and [session] patch sources that fail to resolve are dropped silently — the session comes up without the file and nothing tells the user.
Two paths, one symptom. Both make docs/guide/agents.md's credential-passthrough story fail open.
1. A literal source that is a symlink is dropped with no message at all
docs/reference/loadouts.md:198-200 scopes symlink handling to glob enumeration:
By default the walker does not follow symlinks while enumerating glob matches; see follow_symlinks and the client config.
A literal (non-glob) source that happens to be a symlink is also dropped, and nothing in the doc predicts it:
$ ln -s /private/tmp/qamin/src.txt /tmp/qamin/link.txt
# loadout: patches = [ { dest = "FROMLINK.txt", source = "/private/tmp/qamin/link.txt" } ]
$ RUST_LOG=warn min … session activate -n symsrc --loadout symsrc --sync none --no-prompt .
Applying loadouts: symsrc
019fae8f-ea40-7fb1-89f4-2f6fc8ce8a44
# inside that session — no file, and no warning was emitted at any log level:
root@symsrc:/workbench# ls -la ~
total 4
drwxr-xr-x 2 root root 4096 Jul 29 15:48 .
drwxr-xr-x 11 root root 280 Jul 29 15:48 ..
Adding follow_symlinks = true to the same loadout makes it land, which pins the cause:
root@symfollow:/workbench# ls -la ~
-rw-r--r-- 1 root root 9 Jul 29 15:48 FROMLINK.txt
Control — the same source as a regular file lands correctly under all three dest shapes, so nothing else about the patch is at fault:
root@desttest:/workbench# find / -name 'REL.txt' -o -name 'TILDE.txt' -o -name 'NESTED.txt'
/home/TILDE.txt
/home/REL.txt
/home/sub/NESTED.txt
2. A missing source does warn, but below the default log level
docs/reference/loadouts.md:187-189:
A source path that does not exist on the host is dropped with a warning at activation rather than failing it
The warning exists but the user does not see it:
$ min … session activate -n missingsrc --loadout missingsrc --sync none --no-prompt .
Applying loadouts: missingsrc
019fae8f-ea49-7383-b7ae-8e4634bdf6b3
<- nothing
$ RUST_LOG=warn min … session activate -n missing2 --loadout missingsrc --sync none --no-prompt .
Applying loadouts: missingsrc
WARN sessions::core::enumerate: patch source not found on host filesystem; dropping
source_pattern=/private/tmp/qamin/does-not-exist.txt
walk_root=/private/tmp/qamin/does-not-exist.txt
missing_path=Some("/private/tmp/qamin/does-not-exist.txt")
019fae90-281f-77b2-a209-2f54d303df46
Applying loadouts: reaches stderr on the same run, so the channel is not the problem — the crate's default filter is.
Why this matters more than the individual cases
docs/guide/agents.md:45-49 and docs/guide/dev-shell.md:58-62 both teach exactly the shape that fails:
patches = [
{ source = "~/.gitconfig", dest = "~/.gitconfig" },
{ source = "~/.ssh", dest = "~/.ssh" },
]
On this machine ~/.gitconfig is a symlink into a dotfiles repo — the single most common way people keep dotfiles, and loadouts.md:277 explicitly courts that audience ("Turn on when your dotfile tree is a symlink farm (stow, chezmoi)"). The agent starts, has no credentials, and the user gets no signal at the moment it matters.
Suggested fix
- Surface every dropped patch source on stderr at activation, alongside
Applying loadouts: — both the missing-file case and the symlink case. Failing open is a reasonable default; failing open silently is not.
- Emit a warning for the symlink drop, which currently produces none at any level.
- Document that
follow_symlinks gates literal symlink sources too, not just glob enumeration — or make literal sources follow by default, since a user naming one file explicitly has already expressed the intent a glob walk cannot infer.
Item 1 is the one that matters; 2 and 3 fall out of it.
Not duplicates
gominimal/minimal#196 (leading ~ expansion) and #384 ($VAR expansion) are both closed and concern expanding source patterns, not what happens when an expanded path fails to resolve.
Environment
min 0.5.0-rc3.dev.35.gdcdeec68, macOS arm64 (Apple Silicon)
- Checkout
gominimal/minimal main @ c1d466c; installed binary from dcdeec68 (1 commit apart, scripts/-only)
- All runs against an isolated
--minimal-dir/--config-dir. Found during a documentation QA sweep; related epic gominimal/inbox#271.
Loadout and
[session]patch sources that fail to resolve are dropped silently — the session comes up without the file and nothing tells the user.Two paths, one symptom. Both make
docs/guide/agents.md's credential-passthrough story fail open.1. A literal source that is a symlink is dropped with no message at all
docs/reference/loadouts.md:198-200scopes symlink handling to glob enumeration:A literal (non-glob) source that happens to be a symlink is also dropped, and nothing in the doc predicts it:
Adding
follow_symlinks = trueto the same loadout makes it land, which pins the cause:Control — the same source as a regular file lands correctly under all three dest shapes, so nothing else about the patch is at fault:
2. A missing source does warn, but below the default log level
docs/reference/loadouts.md:187-189:The warning exists but the user does not see it:
Applying loadouts:reaches stderr on the same run, so the channel is not the problem — the crate's default filter is.Why this matters more than the individual cases
docs/guide/agents.md:45-49anddocs/guide/dev-shell.md:58-62both teach exactly the shape that fails:On this machine
~/.gitconfigis a symlink into a dotfiles repo — the single most common way people keep dotfiles, andloadouts.md:277explicitly courts that audience ("Turn on when your dotfile tree is a symlink farm (stow, chezmoi)"). The agent starts, has no credentials, and the user gets no signal at the moment it matters.Suggested fix
Applying loadouts:— both the missing-file case and the symlink case. Failing open is a reasonable default; failing open silently is not.follow_symlinksgates literal symlink sources too, not just glob enumeration — or make literal sources follow by default, since a user naming one file explicitly has already expressed the intent a glob walk cannot infer.Item 1 is the one that matters; 2 and 3 fall out of it.
Not duplicates
gominimal/minimal#196 (leading
~expansion) and #384 ($VARexpansion) are both closed and concern expanding source patterns, not what happens when an expanded path fails to resolve.Environment
min 0.5.0-rc3.dev.35.gdcdeec68, macOS arm64 (Apple Silicon)gominimal/minimalmain@c1d466c; installed binary fromdcdeec68(1 commit apart,scripts/-only)--minimal-dir/--config-dir. Found during a documentation QA sweep; related epic gominimal/inbox#271.