jackin'
Developer ReferenceBehavioral Specs

Auth Source-Folder Sync - Behavioral Spec

Behavioral invariant contract for alternate agent credential/config folders. This spec records the goal and evidence for sync_source_dir so future runtime, console, or documentation changes preserve the intended behavior.

Goal

Operators can keep multiple host logins for the same agent and select which login a workspace or role should use. In sync mode, sync_source_dir is the agent credential/config directory itself, not a replacement home directory. jackin' must prepare the container by reading the same files and credential backends that the agent uses on the host for that selected profile.

The feature is successful when a workspace configured with an alternate source folder launches the selected agent already authenticated as the alternate account, while the default host CLI can still use the default account outside jackin'.

Scope requirements

Source-folder sync is a scoped account-selection mechanism, not a global account switch. The same host machine may have several project workspaces, and each workspace must be able to point an agent at a different host profile. For example, workspace A can sync Codex from one CODEX_HOME, while workspace B syncs Codex from another CODEX_HOME; launching one workspace must not rewrite, clear, or depend on the other workspace's source folder.

The same rule applies inside one workspace at the role layer. A workspace role override can choose a different source folder for an agent than the workspace default. That lets one workspace run role A with one cloud account and role B with another cloud account for the same agent, while agents without a role override continue inheriting the workspace or global source folder.

Evidence

The failing run showed the console saved an alternate Claude Code source folder, but runtime setup reported no forwarded Claude credentials. Claude Code then opened first-run onboarding and theme selection inside the container. That proves the console persistence path worked, while launch-time auth preparation interpreted the selected folder incorrectly.

Local host verification established that the default behavior is agent-specific:

AgentHost profile selectorAccount verification commandSelected source folder for jackin'
Claude CodeCLAUDE_CONFIG_DIR=/path/to/claude-profileclaude auth status or an authenticated launch/path/to/claude-profile
CodexCODEX_HOME=/path/to/codex-profile/status inside Codex/path/to/codex-profile
AmpXDG_DATA_HOME=/path/to/xdg-data-rootamp --no-color usage/path/to/xdg-data-root/amp

Claude Code on macOS stores the OAuth secret in the system Keychain, while .claude.json carries account/config metadata. The Keychain service name is per config dir: the default ~/.claude uses the bare Claude Code-credentials item, and every other CLAUDE_CONFIG_DIR uses Claude Code-credentials-<suffix>, where <suffix> is the first eight hex chars of the SHA-256 of the absolute config dir path (verified live: ~/.claude-work…-3342f2c7). An alternate Claude CLAUDE_CONFIG_DIR therefore selects both the profile metadata and the credential from that folder's own Keychain entry.

Credential extraction for an explicit source folder must read only that folder: its .credentials.json file (Linux / explicit export) or its per-config-dir Keychain entry (macOS). It must never fall back to the default ~/.claude credentials or the default Claude Code-credentials Keychain item — doing so leaks the operator's default account (e.g. a personal Max login) into a capsule explicitly pointed at an Enterprise source folder. When the selected folder yields no readable credentials, preparation leaves the capsule unauthenticated and logs the miss rather than substituting the default account.

Amp does not use AMP_DATA_HOME for main account credentials. The current CLI derives its data store from XDG_DATA_HOME and writes the API key to $XDG_DATA_HOME/amp/secrets.json; ~/.config/amp/settings.json remains preferences-only.

Invariants

INVDescriptionVerify by
INV-1sync_source_dir is a direct agent credential/config directory, not a home directory that gets agent defaults appended under itUnit tests for Codex, Amp, Kimi, OpenCode, and Grok copy credentials directly from source_dir/<credential-file> or the selected Kimi directory
INV-2Claude Code source-folder sync copies .claude.json from the selected CLAUDE_CONFIG_DIRA regression test prepares Claude state from a source folder containing .claude.json and confirms the role-state account file contains that metadata
INV-3Claude Code credential extraction for an explicit source folder reads only that folder (its .credentials.json, else its per-config-dir macOS Keychain entry) and never falls back to the default host credentialsA regression test prepares Claude state from a source folder with no credentials while default host credentials exist, and confirms the role-state credentials.json is not the default account (HostMissing, not Synced)
INV-4Amp source-folder sync reads secrets.json from the selected Amp data directoryA regression test calls Amp source-folder provisioning with source_dir/secrets.json and confirms the role-state secret is mounted
INV-5Runtime launch mounts prepared auth state only when preparation produced or preserved a credential handoff fileLaunch mount tests assert Claude, Codex, and Amp include auth mounts under synced states and omit them under ignored/missing states
INV-6Source-folder resolution preserves the three-layer account-selection scope: workspace-role override, then workspace, then globalResolver tests prove role overrides win over workspace/global, and launch-boundary tests prove the same resolver shape is used per agent and per role before RoleState::prepare
INV-7The Source Folder picker validates a candidate folder against the selected agent's credential structure and rejects a wrong folder inline instead of saving itvalidate_sync_source_dir unit tests cover every sync agent (valid, empty, and wrong-folder cases); the picker commit handler surfaces the rejection reason and keeps the picker open

Source-folder shapes

AgentDefault sourceExplicit source-folder meaning
Claude CodeHost ~/.claude plus macOS Keychain or ~/.claude/.credentials.jsonThe CLAUDE_CONFIG_DIR directory containing .claude.json; credential comes from that folder's .credentials.json or its per-config-dir Keychain entry, with no fallback to the default account
Codex~/.codex/auth.jsonThe CODEX_HOME directory containing auth.json
Amp~/.local/share/amp/secrets.jsonThe Amp data directory containing secrets.json, usually $XDG_DATA_HOME/amp
Kimi~/.kimi-codeThe .kimi-code directory itself
OpenCode~/.local/share/opencode/auth.jsonThe OpenCode data directory containing auth.json
Grok~/.grok/auth.jsonThe Grok directory containing auth.json

Host alias examples

Use separate host aliases only for local verification and account setup; jackin' itself should not create or mutate these host aliases.

alias claude-alt='CLAUDE_CONFIG_DIR="$HOME/.claude-alt" claude'
alias codex-alt='CODEX_HOME="$HOME/.codex-alt" codex'
alias amp-alt='XDG_DATA_HOME="$HOME/.local/share/amp-alt-xdg" XDG_CONFIG_HOME="$HOME/.config/amp-alt-xdg" XDG_CACHE_HOME="$HOME/.cache/amp-alt-xdg" amp'

After logging in through those aliases, configure jackin' source folders as:

Claude Code: ~/.claude-alt
Codex:       ~/.codex-alt
Amp:         ~/.local/share/amp-alt-xdg/amp

Smoke criteria

  1. Verify the default host CLI still reports the default account.
  2. Verify the alternate alias reports the alternate account.
  3. In jackin console, configure the workspace or role Auth tab to sync mode and set Source folder to the alternate folder. Selecting a folder that lacks the agent's credential structure (e.g. the Amp data root instead of its amp/ subfolder) is rejected in the picker with a structure error and is not saved.
  4. Launch the agent from that workspace or role.
  5. Inside the container, run the agent's account/status command or equivalent and confirm it reports the alternate account without triggering first-run login/onboarding.

For Claude Code, the strongest failure signal is first-run onboarding after runtime setup prints that no credentials were forwarded. For Codex, /status must show the alternate account. For Amp, amp --no-color usage must show the alternate account after the selected data directory has been copied into the container.

Non-goals

jackin' must not silently write host aliases, rotate host logins, or mutate host-side agent config while launching a workspace. Operators may create alternate host profiles themselves, and jackin' only reads from the selected source folder or default credential backend during launch preparation.

On this page