22. Data and backup

[!ref] Full details in the User Manual, "Upgrade, backup and sync".

22.1 Backup contents

Item Description
Workspaces Names, paths, archived state
Session history All messages, including tool calls, plans, todos, approvals
Personas Built-in + custom
Skills Global + workspace + plugin-provided
Tool policy Three-state + allow list
External services Credentials encrypted
Channel bindings Peer ↔ workspace
Settings General + per-workspace

22.2 Backup and restore

Operation Steps
Backup Close app → Settings → About → Data directory → tar the whole directory
Restore Close app → replace the data directory → launch
Cross-device migration Restore the backup to the same-named directory on the new device
Sync (experimental) Settings → About → Sync once enabled

22.3 Full wipe

Close app → uninstall → delete the data directory

The data directory contains sign-in credentials, session history and external-service credentials; deletion is irreversible.

22.4 SSH remote workspace protocol

Field Type Default Description
Protocol enum zworkspace zworkspace / ssh
Host string user@host[:port]
Auth enum password password / private_key / private_key_with_passphrase
Private key path string File picker; resolved locally
Remote root string ~ ~ auto-expands to remote home. / is rejected; both .. escapes and ~/.. (including ~//../) single-level traversal are blocked; after expansion and real-path resolution the same checks are applied a second time
Credential encryption SM4-GCM GM at-rest + bound to machine; a random salt on every save
Credential retention bool Remember The "Remember password / passphrase" checkbox. Unchecked ⇒ ephemeral credential: kept for the lifetime of the connection (so reconnects work), cleared on app start and on exit. Per-workspace, persisted as the remember flag in ssh_secrets.yaml; legacy entries without the field count as remembered
Host fingerprint Confirm on first connect The first connection shows the SHA256 fingerprint and only pins it to known_hosts after you verify and confirm; no password is sent before confirmation. A key change on a known host is rejected outright (possible man-in-the-middle)

Differences between SSH workspaces and local:

Capability Local SSH
fs.* file ops Local SFTP / remote shell
fs.grep Go RE2 Remote system grep (faster)
fs.exec sync Local Remote shell
fs.exec.start background Allowed (sessions end with the Interpreter's lifecycle) Allowed (session state kept on the remote under <root>/.avlcode/sessions/, surviving reconnects and app restarts; setsid puts each in its own process group so a kill takes the whole descendant tree; logs are complete files — none of the local 256 MiB ring-buffer tail loss; no venv detection)
File-change panel git Local git Remote git (hidden if no remote git)
Skills / Plugins / Hooks Local .avlcode/ Remote .avlcode/
File threat scan Local bytes SFTP bytes → scan
sys.info identity Local True remote identity
"Close and clear data" menu Shown Hidden + backend-rejected (avoid deleting remote files)
"Remove workspace" Drops local records + credentials Drops local records + credentials only (no remote-file deletion)
Cross-OS client Remote commands don't inject local env; remote paths in POSIX form (Windows ↔ Linux fully ironed out)

22.5 Session-level path attachments

Field Type Default Description
Entry "+" menu: Attach directory (read-only) / Attach directory (read-write)
Permission enum ro (read / list / search) / rw (additionally allow write / delete / create)
Scope Session Only this session; others unaffected
Persistence In session Persists with the session; auto-reapplies after restart
Display "Attached paths" strip above input Removable at any time
Path labelling Absolute paths Search / list results show absolute paths
Session identity injection System injects _session_id into the call chain AI cannot forge identity to misuse other sessions' attachments

22.6 Project instructions (AGENTS.md)

Putting AGENT.md / AGENTS.md / CLAUDE.md at the workspace root injects a # Project Instructions block automatically.

Field Behaviour
Filename priority AGENT.md > AGENTS.md > CLAUDE.md
Injection point Standalone block at the head of the system prompt
Re-read Every turn; edits take effect immediately
Subdir injection When the AI touches a file under a subdir, all AGENT.mds on the path are also injected (deduped per session per subdir)
Truncation UTF-8 character-boundary-safe + truncation marker
Symlink guard EvalSymlinks real-path check; rejects if outside workspace
Built-in editor Session / workspace menu "Edit AGENTS.md"; Cmd/Ctrl+S save, Tab / Shift+Tab indent, unsaved-changes protection, empty-state template
Category Detection Click behaviour
Workspace-internal file paths With known extension (e.g. src/main.go / README.md) Reveal in system file manager
External links http(s) URLs Default browser
Paths in inline-code backticks With extension Same detection as plain links
file:line in tool results / answers path:line(:col)? Workspace file with a line → "View" opens a source preview scrolled to that line
Lone .md / .mdx path in a code block File exists (async-checked, then upgraded to clickable) Opens the Markdown preview drawer
Plain inline code Not detected as a link
Dangerous protocols Non-http(s) Blocked
Plain directories / no-extension fragments e.g. a/b, /etc/hosts Not clickable

Click pops a non-modal floating toolbar (primary "View / Open" + "Copy"); rendered with Popover API at top layer; not obscured inside dialogs. For a source file with a line number, "View" calls PreviewSourceFile(target, line) and positions a code view on that line, making the file:line evidence from code.search / code.ask verifiable.