Repository navigation
bug: openshell sandbox upload <local-dir> <remote-dir> flattens contents instead of creating named subdirectory #885
Description
Activity
This issue appears to have been opened without an agent investigation.
OpenShell is an agent-first project - please point your coding agent at the repo and have it diagnose this before we triage. Your agent can load skills like
debug-openshell-cluster,debug-inference,openshell-cli, andgenerate-sandbox-policy.See CONTRIBUTING.md for the full workflow.
- addedstate:triage-neededOpened without agent diagnostics and needs triageOpened without agent diagnostics and needs triage
on Apr 19, 2026 - added 2 commits that reference this issue
on Apr 19, 2026 Both proposed-direction variants are pushed to the fork as reference branches, ready to convert to PRs once a maintainer signals direction. Each compiles clean and includes unit tests for the directory-prefix logic.
Variant A — match
scp -rsemantics by default (breaking)
Branch:fix/sandbox-upload-preserve-dir-default
Diff: main...mjamiv:OpenShell:fix/sandbox-upload-preserve-dir-defaultSingle-file change to
crates/openshell-cli/src/ssh.rs. Always wraps a directory's contents under the source basename. Paths without a meaningful basename (.,/) preserve the legacy flat extraction. Tests cover both branches.Variant B — opt-in
--preserve-dirflag (non-breaking)
Branch:feat/sandbox-upload-preserve-dir-flag
Diff: main...mjamiv:OpenShell:feat/sandbox-upload-preserve-dir-flagAdds
preserve_dir_name: boolparameter tosandbox_sync_up(withfalsefor backward compat at non-CLI call sites), wires--preserve-dirinto theUploadcommand, and updates the command help to call out the default-flatten behavior so operators discover the flag without a production incident first.Variant A is what I'd reach for personally — the breaking change is small (one release-note line) and the current behavior is a quiet footgun. Variant B is the safer option if backward compatibility weighs heavier. Happy to open whichever you prefer as a PR; reply with the variant name and I'll mark it ready for review.
Heads-up for triage: the body has been edited from H2 (
##) to H3 (###) headers so the agent diagnostic section now matches the regex at.github/workflows/issue-triage.yml:26. The bot's only complaint was header level — the diagnostic content was substantive on first filing. Safe to drop thestate:triage-neededlabel on review.Thanks @mjamiv - I agree on variant A. Happy to reivew a PR.
- added a commit that references this issue
on Apr 24, 2026 - added a commit that references this issue
on Apr 24, 2026 - added a commit that references this issue
on May 14, 2026 - removedstate:triage-neededOpened without agent diagnostics and needs triageOpened without agent diagnostics and needs triage
on Oct 1, 2026
Agent Diagnostic
openshell-cliskill and walked thesandbox uploadcommand path incrates/openshell-cli/.<local>is a directory, the CLI walks the directory and uploads each entry into<remote>directly. The local directory's name is dropped from the destination path.scp -randcp -rsemantics operators expect from any *nix-style file-transfer tool.tar -czf foo.tgz -C parent foo && openshell sandbox upload <name> foo.tgz /tmp/ && ssh ... 'tar -xzf /tmp/foo.tgz -C <remote>/'. The tarball preserves the source-directory prefix deterministically.Description
openshell sandbox upload <local-dir> <remote-dir>flattens the local directory's contents into the remote destination instead of creating a subdirectory named after the local directory.In our case this caused a real near-miss: a directory of content was uploaded into a sibling location alongside existing files at the destination. No data was lost (all uploaded files were new and didn't collide), but the recovery path required a full diff against backups to confirm. A future variant of the same operation could silently shadow files at the destination with no warning.
Reproduction Steps
openshell sandbox upload <name> /tmp/upload-test /sandbox/dest/ssh <sandbox> 'ls /sandbox/dest/'a.txt sub/— theupload-test/prefix is gone; contents are flat in/sandbox/dest/.upload-test/containinga.txtandsub/b.txt, mirroringscp -r ./upload-test <remote>:/sandbox/dest/.Environment
ghcr.io/nvidia/openshell/cluster:0.0.16Proposed direction
Two options:
scp -r/cp -rsemantics — preserve the source directory's basename as a subdirectory of the destination. Principle-of-least-surprise fix; aligns with every comparable file-transfer tool.--preserve-dirflag for the standard semantics, plus a CLI help update calling out the divergence loudly.I prefer (1). The current behavior is a quiet footgun for any operator with prior file-transfer experience. Cost is one breaking-change note in the release. Happy to convert this to a PR if a maintainer signals direction.
Agent-First Checklist
openshell-cli)