Files
arca/PLAN.md
Kyle Isom e44dd382dd M6: shell completions with dynamic alias lookup
Add ValidArgsFunction to mount and unmount commands that reads config
aliases for tab completion. Install zsh, bash, and fish completion
scripts via flake postInstall. Update PLAN.md with post-1.0 roadmap.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 08:35:19 -07:00

155 lines
3.7 KiB
Markdown

# arca — Post-1.0 Plan
## Current State (v1.0.0)
Released. FIDO2/passphrase/keyfile/TPM2 unlock with method sequencing,
idempotent mount/unmount, config aliases, init command, status command,
NixOS LD_LIBRARY_PATH workaround for cryptsetup token plugins, unit
tests, nix flake packaging.
---
## v1.1: Shell completions and verbose mode
### M6: Shell completions
Cobra generates completion scripts. Wire them up so alias names
complete in the shell.
#### Files changed
- `cmd/root.go`
- `flake.nix`
#### Work
1. Cobra provides `completion` subcommand by default (`arca completion
zsh`, `arca completion bash`, etc.). Verify it works.
2. Add a custom `ValidArgsFunction` to `mountCmd` and `unmountCmd`
that reads the config and returns alias names + device paths from
`arca status`. This gives dynamic completion for:
```
arca mount <TAB> -> backup media /dev/sda1
arca unmount <TAB> -> backup media
```
3. In `flake.nix`, install the zsh completion file to
`$out/share/zsh/site-functions/_arca` so NixOS picks it up
automatically.
### M7: Verbose mode
Add `-v` / `--verbose` flag to aid debugging (e.g., the FIDO2 plugin
discovery issue we hit during development).
#### Files changed
- `cmd/root.go`
- `internal/cryptsetup/cryptsetup.go`
- `internal/unlock/unlock.go`
- `internal/udisks/client.go`
#### Work
1. Add a `--verbose` / `-v` persistent flag on the root command. Store
in a package-level `Verbose bool`.
2. In `cryptsetup.Open`: print the full command being executed
(including `LD_LIBRARY_PATH` and privilege wrapper).
3. In `findTokenPluginDir`: print which directory was found (or that
none was found).
4. In `unlock.Unlock`: print which method is being attempted before
each try.
5. In `udisks.NewClient`: print the D-Bus connection status.
Use `fmt.Fprintf(os.Stderr, "arca: ...")` for verbose output — no
logging framework needed.
---
## v1.2: Config management and cleanup
### M8: `arca add <device>`
Add a single device to an existing config without regenerating
everything.
#### Files changed
- `cmd/add.go` (new)
- `internal/config/config.go`
#### Work
1. New subcommand: `arca add /dev/sda1` or `arca add --uuid <uuid>`.
2. Resolve the device via udisks2 to get UUID.
3. Generate a UUID-prefix alias (same as `init`).
4. Prompt for alias name (default: UUID prefix), methods (default:
passphrase), and optional mountpoint.
5. Append to existing config. If the UUID is already configured, print
the existing alias and exit.
6. Add `config.Save(*Config)` to write the config file (currently
only `init` writes, with inline marshaling).
### M9: `init --merge`
Merge newly discovered devices into an existing config without
overwriting existing entries.
#### Files changed
- `cmd/init.go`
- `internal/config/config.go`
#### Work
1. Add `--merge` flag to `init`. When set, load existing config
first.
2. For each discovered device, skip if its UUID already exists in
config (regardless of alias name).
3. Add new devices with UUID-prefix aliases.
4. Write the merged config.
This replaces the current `--force` behavior for the common case of
"I plugged in a new drive."
### M10: Mount cleanup
Privileged unmount leaves empty directories under `/mnt/`.
#### Files changed
- `internal/cryptsetup/cryptsetup.go`
- `cmd/unmount.go`
#### Work
1. After `Unmount`, attempt `rmdir` on the mount point. Only remove
if empty (not `rm -rf`).
2. Use privileged `rmdir` since the directory was created with
privilege.
---
## Non-goals
- `--dry-run` flag
- `--json` output for `status`
- udev auto-mount on plug
- Keyfile creation/management
- Multiple config files or config includes
- Systemd mount unit integration