Mount and unmount

Mount a workspace at a local path and clean up cleanly.

mkdir -p /mnt/work
artifacts mount cases /mnt/work
Mounting /mnt/work ...
$

The prompt comes back within ~1 second. The actual FUSE-serving process detaches into the background; your shell, container entrypoint, or agent runtime can keep going.

Daemon vs foreground

Daemon is the default. Pass --foreground (-f) to keep FUSE attached to your terminal. That's useful for ops/debug when you want to see live JuiceFS logs, but not what you want in production.

artifacts mount cases /mnt/work --foreground

Verify the mount

mount | grep /mnt/work
# JuiceFS:tzu-cases-... on /mnt/work type fuse.juicefs (rw,...)

ls /mnt/work
# .accesslog .config .stats .trash    plus your data

.stats is the same Prometheus-format metrics file you'd find in any JuiceFS mount; useful for ad-hoc poking at request counts and cache hit rates.

Unmount

artifacts unmount /mnt/work

All three paths trigger the same graceful unmount: the supervisor propagates the signal to the FUSE-serving child, juicefs finishes in-flight ops, the kernel mount goes away within ~0.5 seconds.

Don't kill -9 (SIGKILL) the mount. SIGKILL bypasses the unmount handler and leaves a stale FUSE mount. The mountpoint becomes unresponsive (ls /mnt/work hangs) until cleared with sudo umount -f /mnt/work (or umount -l lazy fallback).

Mount on a path that's already mounted

artifacts mount cases /mnt/work
# (succeeds, mount is up)

artifacts mount cases /mnt/work
# Error: path /mnt/work is already a mount point;
#        run `artifacts unmount /mnt/work` first

The CLI does a pre-flight check against /proc/self/mountinfo so the collision shows up as a clear error instead of an obscure EBUSY deep in juicefs's mount loop.

Read-only mode

artifacts mount cases /mnt/work --read-only

v0 enforces --read-only client-side only. The Redis ACL still permits writes; a determined caller could bypass the flag. A true server-enforced read-only mode is a v1 task that requires JuiceFS patches to suppress write-on-read paths (atime, lease bookkeeping). Use this flag for accident-prevention, not as a security boundary.

Cache profiles

Mount cache lives under ~/.cache/artifacts/mount-<hash>/. The hash is per-workspace + mountpoint, so re-mounting the same workspace re-uses the warm cache.

artifacts mount cases /mnt/work --cache-profile benchmark

interactive (default), benchmark, and custom are the supported profiles. benchmark allocates more buffer + prefetch, which suits the find-and-read workload an agent typically does. custom honours per-mount overrides via additional flags (see artifacts mount --help).

Mount session lifetime

Each artifacts mount call mints a fresh per-mount Redis ACL with a unique token. The token's TTL defaults to 5 years (effectively no expiry). The cleanup paths are explicit artifacts unmount, workspace delete, or operator-driven revocation. v0 never "expires" your mount mid-flight.

If a customer wants a short-lived session for some reason (CI smoke test that mounts, runs, unmounts):

# JSON API directly:
curl -X POST -H "Authorization: Bearer $JWT" -H 'Content-Type: application/json' \
    https://artifacts.tonbo.dev/workspaces/<handle>/<name>/mount-sessions \
    -d '{"mode":"rw","ttl_seconds":300}'   # 5 minutes

(The CLI doesn't expose --ttl-seconds today; if you need it, ask.)