Skip to content

fix(cli): resolve paths from THIS install, not from $HOME#8

Open
damonleelcx wants to merge 2 commits into
develop-v1.0.4from
fix/cli-follows-its-own-install
Open

fix(cli): resolve paths from THIS install, not from $HOME#8
damonleelcx wants to merge 2 commits into
develop-v1.0.4from
fix/cli-follows-its-own-install

Conversation

@damonleelcx

Copy link
Copy Markdown

What

The installer has supported --install-dir / --sandbox for a long time, but the CLI had no notion of it: ~24 sites derived their paths from the user's home via dirs::home_dir().join(".aikey"). A relocated install's aikey therefore operated on the default install's vault, config, run state and logs — two installs, one data plane, and no error message anywhere.

resolve_aikey_dir() becomes the single resolver:

  1. AIKEY_HOME, absolute only. A relative value is ignored rather than honoured — these paths are written into config and handed to services, where a value that depends on the current working directory is a latent bug (same class as the CWD-relative .aikey/... collapse that bit aikey-local-server under systemd). Falling back to the historical default is the safer failure.
  2. Derived from the binary's own location (<root>/bin/aikey<root>). This is what makes relocation work with nothing exported: AIKEY_HOME covers the installer's own sub-invocations, but a user typing aikey months later has no such variable — and the binary they ran already knows which install it belongs to.
  3. $HOME/.aikey — unchanged for every ordinary install.

Two guards on the exe-derivation: the parent directory must be named bin (so a dev build under target/debug falls through), and the candidate root must carry an install marker (so a shim in /usr/local/bin doesn't make us treat /usr/local as an install and start writing a vault there). current_exe() resolves symlinks, so a link in ~/bin still points home.

Verification

Live, with the same $HOME for both binaries:

binary vault it targets
relocated (<root>/bin/aikey) <root>/data/vault.db
installed (~/.aikey/bin/aikey) ~/.aikey/data/vault.db ✓ found
dev build (target/release/aikey) ~/.aikey/data/vault.db — unaffected

Before this change all three pointed at the last row.

1138 unit tests pass, including four new ones covering override, verbatim use, relative-ignored, and empty-value fallback.

Notes for review

  • Branched off develop-v1.0.4 rather than the feature/model-mapping-egress-v1.0.4 branch this work was written on, so open PR feat(cli): P1e credential re-grain + aikey use two-axis summary + provider(s) mislabel fix #6 stays scoped to its own feature. Re-verified on this base.
  • Paired with the installer-side work in aikeylabs/workflow#16, which exports AIKEY_HOME and relocates the rendered config. Neither depends on the other to be correct, but they are the same defect family.

🤖 Generated with Claude Code

Damon and others added 2 commits July 22, 2026 08:05
The installer has supported --install-dir / --sandbox for a long time, but the
CLI had no notion of it: ~24 sites derived their paths from the user's home via
dirs::home_dir().join(".aikey"). A relocated install's `aikey` therefore operated
on the DEFAULT install's vault, config, run state and logs — two installs, one
data plane, no error message anywhere.

resolve_aikey_dir() becomes the single resolver, in this order:

  1. AIKEY_HOME, absolute only. A relative value is ignored rather than honoured:
     these paths are written into config and handed to services, where a value
     that depends on the current working directory is a latent bug (the same
     class as the CWD-relative `.aikey/...` collapse that bit aikey-local-server
     under systemd). Falling back to the historical default is the safer failure.

  2. Derived from the binary's own location: <root>/bin/aikey → <root>. This is
     what makes relocation work with nothing exported. AIKEY_HOME covers the
     installer's own sub-invocations, but a user typing `aikey` months later has
     no such variable — and the binary they just ran already knows which install
     it belongs to. Two guards: the parent directory must be named `bin`, so a
     dev build under target/debug falls through; and the candidate root must
     carry an install marker, so a shim dropped in /usr/local/bin does not make
     us treat /usr/local as an install and start writing a vault there.
     current_exe() resolves symlinks, so a link in ~/bin still points home.

  3. $HOME/.aikey — unchanged for every ordinary install.

All production callers route through it; no module rebuilds the path by hand.

Verified live with the same $HOME for both binaries: the relocated one targets
its own vault (<root>/data/vault.db) while the real install's binary still
targets ~/.aikey/data/vault.db, and a dev build is unaffected. 1138 unit tests
pass, including four new ones covering override, verbatim use, relative-ignored
and empty-value fallback.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant