Status: Design Discussion, Unresolved. The conclusion leans towards "do not implement multi-account parallel execution (proven unfeasible); same-account multi-worker parallel execution is technically possible but has limited value and low priority." Scope: Only concerns
agy(Antigravity CLI). Parallel execution forclaude/codexis a separate topic. Relevant code:lib/commands/antigravity.sh,lib/targets/antigravity.sh,docs/dogfood-agy-headless.md,HANDOFF.md(OPEN —clikae auto/ dropped-parallel-task relay).
1. Problem Restatement
Issue #25 asks: Can clikae support parallel execution of multiple agy workers to fan-out large parallelizable tasks (e.g. translating a dictionary, batch summarization) to speed up execution, while preserving clikae's core value of "burning across tanks without affecting the main budget"?
There are actually two distinct propositions here that must be separated, otherwise we risk mixing up a dead end with a viable path:
- Proposition A: Multi-account parallel execution — Running multiple agy workers simultaneously, each logged into a different Google account, burning their respective subscription pools. This is intuitively the most attractive option (throughput ×N, quota ×N).
- Proposition B: Same-account multi-worker execution — Running multiple agy workers simultaneously, all sharing the same account, isolating their states (sessions, working directories, logs) via
$HOME, but burning the same subscription pool.
The core conclusion of this note: A is technically impossible on agy (proven unfeasible by testing, do not pursue); B is technically possible but since quota is shared, the benefit of "parallelism" is heavily compromised, making it a low-priority edge case.
2. Why "Multi-Account Parallelism" (Prop A) is Impossible — Technical Root Cause
This is not a guess; it's a conclusion based on local testing and code analysis (see agy-gemini-shared-quota memory, lib/commands/antigravity.sh comments, and lib/targets/antigravity.sh header).
2.1 The root cause in one sentence: agy's authentication is machine-wide global, not bound to $HOME
clikae's standard model for switching accounts is "point each shell to a per-profile config dir" (CLIKAE_CONFIG_DIR, CODEX_HOME, etc.). This requires that the CLI's identity can be redirected by an environment variable or flag. agy does not conform to this:
- The agy state directory does follow
$HOME(os.UserHomeDir→~/.gemini), so overriding$HOMEisolates sessions, logs, and work states. - However, agy's authentication (Google OAuth) is stored in a single machine-wide macOS Keychain item (service
gemini, accountantigravity), not in~/.gemini. No environment variable (likeANTIGRAVITY_EXECUTABLE_DATA_DIR,GEMINI_HOME) or flag can redirect this login.
Proven conclusion (must be documented, as we once mistakenly thought it could run in parallel but had to retract): "Overriding
$HOMEonly moves 'state', not 'auth'; auth is globally single and only recognizes the last logged-in account." So even if you open three shells with different$HOMEpaths, all three agy processes will read the same Keychain login = the same account.
2.2 How clikae currently handles "multi-account" — Global exclusive switching, not parallel execution
The multi-account mode in lib/commands/antigravity.sh (opt-in, taking over ~/.gemini) works around this limitation by using a global, one-at-a-time approach:
- Switching a tank = pointing the
~/.geminisymlink to that tank's slot directory, and copying that tank's token from clikae's Keychain namespace back to the canonical Keychain item (_agy_kc_stash/_agy_kc_restore, Keychain-to-Keychain, token never hits disk). - Because there is only one canonical Keychain item, this switch is GLOBAL: only one agy tank is active at any time, across all terminal windows. The code even contains a
_agy_assert_not_runningguard: it refuses to switch the symlink if agy is currently running, to avoid corrupting the active session.
In other words, clikae's official account switching is inherently machine-wide exclusive. This is the opposite of "multi-account parallelism": parallelism requires multiple active canonical logins, but agy only gives you one slot.
2.3 Conclusion: Prop A is a dead end
- Opening multiple agy processes with different
$HOMEpaths → all use the same account (globally single auth). - Using different accounts → requires rewriting that single Keychain login in turns → inherently sequential, not parallel.
- Therefore, multi-account parallelism for agy is impossible under its current design. Do not pursue this; we can only wait for Google to officially support per-profile auth.
Comparison:
claudeandcodexcan run in parallel across multiple accounts (each shell has its ownCLIKAE_CONFIG_DIRorCODEX_HOME; the "burn-all-tanks" mode inHANDOFF.mdis true parallel execution for claude and codex). agy is the only engine blocked by this limitation.
3. "Same-Account Multi-Worker" (Prop B) Feasibility Analysis
Since multi-account parallelism is out, the only parallelism left is B: the same account, multiple workers, isolating state with $HOME, sharing the same quota.
3.1 Technical Feasibility — possible, but requires bypassing clikae's existing guards
- State isolation is fine:
$HOMEoverride gives each worker its own~/.gemini(sessions, work directories, and logs are isolated). One worker going off-track or hang-killing doesn't affect the others. Technically sound. - Shared login is fine but fragile: Multiple workers read the same canonical Keychain login. Reading the token is parallelizable (read-only), so in theory, N agy instances can run concurrently using the same account.
- ⚠️ Bypassing the global model: clikae's multi-account mode treats
~/.geminias a single symlink and_agy_assert_not_runningexplicitly refuses to touch the symlink when agy is running. To implement B, we must not use the existing symlink-swap mechanism, and instead create a separate path where we launch agy directly usingHOME=...without touching the~/.geminisymlink. This means B and the existing multi-account mode are two entirely separate paths and cannot be mixed. - Authentication prerequisite: The account used by the workers must be the one currently in the canonical Keychain item (the last logged-in one). You cannot use two different accounts simultaneously in B. So the prerequisite for B is "switch to the desired tank first using clikae, verify the login, and then fan-out N same-account workers."
3.2 Consequences of Shared Quota — The fatal drawback of B
The N workers in B burn the same subscription pool. Consequently:
- No quota multiplier. The advantage of multi-account parallelism (multiplying quota by N) does not exist in B. You are just burning the same pool of fuel faster.
- Faster rate limiting. The dry rate of agy requests is already very fast (dry-run tests show 23–25k tokens per request). Running N workers in parallel means the pool is drained at N× speed, hitting
RESOURCE_EXHAUSTED (429) Individual quota reachedmuch sooner (the dry signal for agy is found in~/.gemini/antigravity-cli/cli.logas an E-level line). - Quota is bound to the account, not the process. So parallel execution doesn't give you more total capacity, it just hits the wall faster, with the added complexity of coordinating multiple workers hitting limits at the same time.
In short: B trades "wall-clock throughput" for "earlier rate limiting + coordination complexity", without gaining any additional quota.
3.3 Does B have any value?
Yes, but very narrow, and mostly replaceable by simpler solutions:
- The only real benefit is wall-clock reduction: If the task is naturally partitionable (N independent pieces) and the quota pool is large enough to not dry out, N parallel workers are indeed faster than sequential execution. The agy spawning 5 subagents in parallel for translation in
docs/dogfood-agy-headless.mdfits this shape—but note that this was internal subagent spawning within agy, and clikae didn't need to manage separate$HOMEpaths. - Counterexamples (where B's value is negated):
- Small tasks → Sequential is fast enough; not worth the overhead of fan-out.
- Large tasks that dry out the account → Parallel execution just hits the limit faster, leaving you to coordinate a "half-finished, dried-out task" (like the mid-run dry task in the HANDOFF dogfood).
- Offloading main thread budget → This is achieved by sequential offloading (already proven in dogfood), no parallelism required.
4. Recommendations
4.1 Multi-Account Parallelism (Prop A): Do not implement. Mark as known unfeasible.
- Explicitly document in agy docs (
docs/) and issue #25: agy cannot do multi-account parallel execution due to the technical root cause: "auth is globally single-account and does not follow$HOME". This prevents future agents or humans from trying to reinvent this dead end. - Mark the agy row in
clikae tanks/ board as non-parallel / global-single (which also resolves the mismatch betweenenv agyandtankslist noted in HANDOFF § "Grunt-dispatch friction").
4.2 Same-Account Multi-Worker (Prop B): Do not implement by default; consider only under strict conditions, low priority.
Do not recommend implementing this now. Reasons: narrow value (only saves wall-clock), no quota multiplier, requires bypassing the symlink model, and adds complex rate-limit coordination—poor ROI.
If implemented in the future, satisfy all prerequisites first:
- A frequently occurring real-world task shape that is large, partitionable, and has enough quota pool. Otherwise, it is over-engineering.
- The task must be idempotent + verified by artifact (so a dropped piece can be safely re-fired, as concluded in HANDOFF).
- Implement agy dry detection (parsing 429 lines in
cli.log) to halt all workers when the account hits a rate limit, preventing useless retries (note: agy-pexits with 0 and empty output on limit, so exit code cannot be trusted). - Design it as completely independent of the existing multi-account symlink model to avoid polluting the
_agy_*global switching logic.
4.3 Higher-Priority Alternatives (better ROI than B)
- In-process subagents for agy: For parallel translations/batches, let the single agy agent spawn subagents internally (dogfood proved 5-way parallelism works), so clikae doesn't need to manage
$HOME. Spend effort on writing clean headless recipes (non-exploratory, tight boundaries, long timeout) instead of multi-worker orchestration. - Cross-engine parallelism: To get true fan-out + quota multipliers, distribute parallel chunks across multiple claude/codex tanks (which support true multi-account parallelism). agy can act as a single sequential worker in that pool (matching the global-single role it played in the HANDOFF run).
5. If B is to be implemented — Future Reference Sketch
Provided for future reference; do not implement now.
5.1 Shape
Add an independent subcommand (do not bundle with cmd_antigravity's symlink flow), e.g. clikae agy --fan-out N -- <task-template>, or delegate to the burn/pool layer.
# Conceptual sketch (non-executable): N workers on the same account, separate $HOME, sharing quota.
# Prerequisite: User has already switched the canonical login to the target account via `clikae agy <tank>`.
_agy_fanout() {
local n="$1"; shift # number of workers
local task_dir="$1"; shift # directory for in/out artifacts (use /tmp to avoid iCloud sync lag)
# ⚠️ Do not touch the ~/.gemini symlink or call _agy_kc_stash/_agy_kc_restore.
# Each worker gets a temporary HOME to isolate state; auth reads the global canonical Keychain.
for i in $(seq 1 "$n"); do
local whome; whome="$(mktemp -d)"
# Setup authentication for the worker:
# macOS: Auth is in the global Keychain (machine-wide), worker reads it natively -> no copy needed.
# Linux: Auth is in ~/.gemini file -> copy the active ~/.gemini to $whome/.gemini.
(
HOME="$whome" \
agy -i "$(render_task "$i")" \
--dangerously-skip-permissions --add-dir "$task_dir" \
--print-timeout 900s \
> "$task_dir/worker-$i.out" 2>&1 &
)
done
wait
# Post-run: verify artifact for each worker; if missing, inspect its out log / global cli.log for 429.
# On rate limit (exit 0 but empty output / RESOURCE_EXHAUSTED in log) -> mark the pool dry, report failed chunks to orchestrator.
}
5.2 Critical Implementation Details
- macOS vs Linux Auth Behavior: macOS auth is in the global Keychain, shared natively across N workers; Linux auth is in the
~/.geminifile, requiring each$HOMEworker to copy the active auth file first (sharing it read-only—never log in concurrently from workers to avoid race conditions). - Avoid reusing
_agy_assert_not_runningguard: The guard is "refuse to touch symlink if agy is running." Since B does not touch the symlink, it doesn't conflict—but it means B cannot run concurrently with a normal interactive agy session (as they would conflict on the canonical login's session state). Document this constraint: the account is exclusively locked for fan-out. - Dry Detection:
tail -Fthecli.logof each worker (located under each worker's$HOME) because agy redirects its log per run. - Artifact-first: Workers must write to files rather than stdout (dogfood lesson: large stdout under agy
-pcan hang). Use/tmpto avoid iCloud sync latency. - Constraint exploration + long timeout: Prompt must use tight boundaries ("do not explore git, just translate") otherwise agy's agentic behavior will run off-topic and hit
--print-timeout.
6. Summary
agy multi-account parallelism = dead end (global single auth), do not pursue. agy same-account multi-worker = technically possible but trades earlier rate limiting and coordination complexity for wall-clock gains, without adding total quota; do not implement by default. For parallel execution, use agy's internal subagents, or distribute tasks across multi-account claude/codex tanks.