Agent Diagnostic
Investigated by running the reproduction steps manually using openshell sandbox upload against a minimal git repository containing a symlink. Confirmed the symlink is absent in the sandbox and replaced by a regular directory. Tested on v0.0.36 and v0.0.42 — both exhibit the same behavior. Could not resolve — this requires a fix in the upload tar-building logic.
Description
openshell sandbox upload resolves symlinks in the source tree when building the tar archive. Symlinks arrive in the sandbox as regular directories (their targets, expanded inline). Git tracks them as symlink blobs, so git status in the sandbox immediately reports every symlink path as deleted:.
What should happen: Symlinks should be preserved as symlinks in the sandbox, matching the source tree exactly.
Reproduction Steps — v0.0.36
# 1. Download openshell v0.0.36 (Linux x86_64)
curl -L https://github.com/NVIDIA/OpenShell/releases/download/v0.0.36/openshell-x86_64-unknown-linux-musl.tar.gz \
| tar -xz -C /tmp/openshell-036 --one-top-level
chmod +x /tmp/openshell-036/openshell
# 2. Create a minimal git repo with a symlink
mkdir /tmp/symlink-repro && cd /tmp/symlink-repro
git init -q
mkdir real-dir && echo "hello" > real-dir/file.txt
ln -s real-dir link-dir
git add . && git commit -qm "init"
# 3. Create a sandbox (requires a running gateway)
/tmp/openshell-036/openshell sandbox create --name symlink-test --keep --no-tty -- true
# 4. Upload the repo
/tmp/openshell-036/openshell sandbox upload symlink-test /tmp/symlink-repro /sandbox/repo
# 5. Check for symlinks — expect one, get none
/tmp/openshell-036/openshell sandbox exec --name symlink-test --no-tty -- /usr/bin/find /sandbox/repo -type l
# (no output)
# 6. Confirm link-dir is a real directory instead of a symlink
/tmp/openshell-036/openshell sandbox exec --name symlink-test --no-tty -- /usr/bin/ls -la /sandbox/repo/symlink-repro/
# 7. Clean up
/tmp/openshell-036/openshell sandbox delete symlink-test
Reproduction Steps — v0.0.42 (standalone gateway)
# 1. Download openshell v0.0.42 binaries (Linux x86_64)
mkdir /tmp/openshell-042
curl -L https://github.com/NVIDIA/OpenShell/releases/download/v0.0.42/openshell-x86_64-unknown-linux-musl.tar.gz \
| tar -xz -C /tmp/openshell-042
curl -L https://github.com/NVIDIA/OpenShell/releases/download/v0.0.42/openshell-gateway-x86_64-unknown-linux-gnu.tar.gz \
| tar -xz -C /tmp/openshell-042
curl -L https://github.com/NVIDIA/OpenShell/releases/download/v0.0.42/openshell-sandbox-x86_64-unknown-linux-gnu.tar.gz \
| tar -xz -C /tmp/openshell-042
chmod +x /tmp/openshell-042/openshell /tmp/openshell-042/openshell-gateway /tmp/openshell-042/openshell-sandbox
# 2. Start the standalone gateway (Podman driver, no TLS for local testing)
OPENSHELL_SSH_HANDSHAKE_SECRET=test-secret \
/tmp/openshell-042/openshell-gateway \
--disable-tls \
--disable-gateway-auth \
--drivers podman \
--db-url sqlite:///tmp/openshell-042-test.db \
--port 8081 \
--bind-address 0.0.0.0 \
--docker-supervisor-bin /tmp/openshell-042/openshell-sandbox \
&
# 3. Register and select the gateway
/tmp/openshell-042/openshell gateway add http://127.0.0.1:8081 --name gw-042
/tmp/openshell-042/openshell gateway select gw-042
# 4. Create the same minimal git repo (skip if already done above)
mkdir -p /tmp/symlink-repro && cd /tmp/symlink-repro
git init -q
mkdir -p real-dir && echo "hello" > real-dir/file.txt
ln -sf real-dir link-dir
git add . && git commit -qm "init" 2>/dev/null || true
# 5. Create a sandbox
/tmp/openshell-042/openshell sandbox create --name symlink-test --keep --no-tty -- true
# 6. Upload the repo
/tmp/openshell-042/openshell sandbox upload symlink-test /tmp/symlink-repro /sandbox/repo
# 7. Check for symlinks — expect one, get none
/tmp/openshell-042/openshell sandbox exec --name symlink-test --no-tty -- /usr/bin/find /sandbox/repo -type l
# (no output)
# 8. Confirm link-dir is a real directory
/tmp/openshell-042/openshell sandbox exec --name symlink-test --no-tty -- /usr/bin/ls -la /sandbox/repo/symlink-repro/
# 9. Clean up
/tmp/openshell-042/openshell sandbox delete symlink-test
kill %1
Expected output (step 5 / step 7)
/sandbox/repo/symlink-repro/link-dir
Actual output (step 5 / step 7)
ls -la shows link-dir as a regular directory in both versions:
drwxr-xr-x. 1 sandbox sandbox 16 ... link-dir
drwxr-xr-x. 1 sandbox sandbox 16 ... real-dir
Environment
- openshell:
0.0.36 and 0.0.42 (both affected)
- OS: Linux x86_64
- Driver: Podman (rootless)
Impact
Any workflow uploading a git repo with symlinks will see those paths reported as deleted: by git status inside the sandbox, even though the working tree is otherwise intact. This causes spurious git noise and can lead agents to attempt restoring files that were never deleted.
Agent-First Checklist
Agent Diagnostic
Investigated by running the reproduction steps manually using
openshell sandbox uploadagainst a minimal git repository containing a symlink. Confirmed the symlink is absent in the sandbox and replaced by a regular directory. Tested on v0.0.36 and v0.0.42 — both exhibit the same behavior. Could not resolve — this requires a fix in the upload tar-building logic.Description
openshell sandbox uploadresolves symlinks in the source tree when building the tar archive. Symlinks arrive in the sandbox as regular directories (their targets, expanded inline). Git tracks them as symlink blobs, sogit statusin the sandbox immediately reports every symlink path asdeleted:.What should happen: Symlinks should be preserved as symlinks in the sandbox, matching the source tree exactly.
Reproduction Steps — v0.0.36
Reproduction Steps — v0.0.42 (standalone gateway)
Expected output (step 5 / step 7)
Actual output (step 5 / step 7)
ls -lashowslink-diras a regular directory in both versions:Environment
0.0.36and0.0.42(both affected)Impact
Any workflow uploading a git repo with symlinks will see those paths reported as
deleted:bygit statusinside the sandbox, even though the working tree is otherwise intact. This causes spurious git noise and can lead agents to attempt restoring files that were never deleted.Agent-First Checklist
debug-openshell-cluster,debug-inference,openshell-cli)