The project backup archive placed the workspace at the archive root (./samagent, ./whmcs-claude-agent, ./.git, …) while the sanitized home config sat under a labeled home-claude/ folder. On extraction the workspace files scattered loose into the extraction directory and only home-claude/ appeared as a distinct folder — so the backup read as "config only, workspace missing." Some archive viewers also didn't surface the root-level entries at all, reinforcing the impression.
Fix
Add --transform='flags=r;s,^\./,workspace/,' to the tar command so the workspace nests under workspace/, parallel to home-claude/. flags=r scopes the rename to member names only, leaving symlink targets (relative and absolute) intact. Excludes still match the pre-transform names, so node_modules/target are still dropped.
Verification
cargo check passes.
Ran the exact production tar script against a live container: extraction now yields two clearly-labeled folders workspace/ + home-claude/; workspace .git history preserved; node_modules/target excluded (0 leaked); symlink targets unchanged.
No restore command exists in the codebase (backup is a download-only artifact), so the internal layout change breaks nothing.
## Problem
The project backup archive placed the workspace at the **archive root** (`./samagent`, `./whmcs-claude-agent`, `./.git`, …) while the sanitized home config sat under a labeled `home-claude/` folder. On extraction the workspace files scattered loose into the extraction directory and only `home-claude/` appeared as a distinct folder — so the backup read as "config only, workspace missing." Some archive viewers also didn't surface the root-level entries at all, reinforcing the impression.
## Fix
Add `--transform='flags=r;s,^\./,workspace/,'` to the tar command so the workspace nests under `workspace/`, parallel to `home-claude/`. `flags=r` scopes the rename to member **names only**, leaving symlink targets (relative and absolute) intact. Excludes still match the pre-transform names, so `node_modules`/`target` are still dropped.
## Verification
- `cargo check` passes.
- Ran the exact production tar script against a live container: extraction now yields two clearly-labeled folders `workspace/` + `home-claude/`; workspace `.git` history preserved; `node_modules`/`target` excluded (0 leaked); symlink targets unchanged.
- No restore command exists in the codebase (backup is a download-only artifact), so the internal layout change breaks nothing.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
The backup archive placed the workspace at the archive root (`./...`)
while the sanitized home config sat under `home-claude/`. On extraction
the workspace files scattered loose into the extraction directory and
only `home-claude/` showed up as a distinct folder, so the backup read
as "config only, workspace missing" — and some archive viewers didn't
surface the root-level entries at all.
Add `--transform='flags=r;s,^\./,workspace/,'` so the workspace nests
under `workspace/`, parallel to `home-claude/`. `flags=r` scopes the
rewrite to member names only, leaving symlink targets (relative and
absolute) intact. Excludes still match the pre-transform names.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Review caught that `flags=r` disables rewriting of both symlink AND
hardlink target names. Leaving symlink targets alone is intended, but a
hardlink's stored target is an archive-internal reference to another
member's name — when member names become `workspace/...` but the
hardlink target stays `./hard_link`, extraction fails hard:
tar: workspace/file.txt: Cannot hard link to './hard_link':
No such file or directory
`flags=rh` rewrites regular member names and hardlink target names
together (keeping the pair consistent) while still leaving symlink
targets untouched. Verified in-container: extract exit 0, symlink target
preserved, hardlink pair shares one inode, nesting under workspace/ intact.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
jknapp
merged commit 876ba8a8fc into main2026-07-01 13:23:08 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Problem
The project backup archive placed the workspace at the archive root (
./samagent,./whmcs-claude-agent,./.git, …) while the sanitized home config sat under a labeledhome-claude/folder. On extraction the workspace files scattered loose into the extraction directory and onlyhome-claude/appeared as a distinct folder — so the backup read as "config only, workspace missing." Some archive viewers also didn't surface the root-level entries at all, reinforcing the impression.Fix
Add
--transform='flags=r;s,^\./,workspace/,'to the tar command so the workspace nests underworkspace/, parallel tohome-claude/.flags=rscopes the rename to member names only, leaving symlink targets (relative and absolute) intact. Excludes still match the pre-transform names, sonode_modules/targetare still dropped.Verification
cargo checkpasses.workspace/+home-claude/; workspace.githistory preserved;node_modules/targetexcluded (0 leaked); symlink targets unchanged.🤖 Generated with Claude Code
workspace/in project backupReview caught that `flags=r` disables rewriting of both symlink AND hardlink target names. Leaving symlink targets alone is intended, but a hardlink's stored target is an archive-internal reference to another member's name — when member names become `workspace/...` but the hardlink target stays `./hard_link`, extraction fails hard: tar: workspace/file.txt: Cannot hard link to './hard_link': No such file or directory `flags=rh` rewrites regular member names and hardlink target names together (keeping the pair consistent) while still leaving symlink targets untouched. Verified in-container: extract exit 0, symlink target preserved, hardlink pair shares one inode, nesting under workspace/ intact. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>