mirror of
https://github.com/rennf93/roboco.git
synced 2026-08-03 07:23:24 +02:00
[F005,F006] grok auth: directory mount + atomic-write fallback
F005: the single-file bind mount of auth.json pinned the inode, so the orchestrator's atomic refresh (tmp+rename within ~/.grok) never reached a running grok container — a long-lived container hung at the login prompt when the original ~6h token expired. Mount the host ~/.grok DIRECTORY (ro) at /home/agent/.grok-auth-ro; the entrypoint symlinks ~/.grok/auth.json at that RO mount so grok + the --check backstop read the live credential (the directory mount sees the host-side rename) while grok's writable state (config.toml, sessions/) stays in the image's ~/.grok. F006: a rotated refresh_token is single-use — xAI invalidates the old one the instant it issues the new one. If the atomic write failed after the rotation, the file kept the now-dead old refresh_token and the credential was permanently lost on the next refresh. _atomic_write now falls back to a direct write when tmp+replace fails, so the rotated token always lands on disk (losing the write is catastrophic; losing atomicity is not). TDD: RED tests watched fail, then GREEN. ruff+mypy clean; 32 grok tests green, no regressions.
This commit is contained in:
@@ -27,12 +27,22 @@ if ! ( cd /app && python -m roboco.agent_sdk.prompt_guard "${ROBOCO_INITIAL_PROM
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Auth fail-fast guard. The SuperGrok token (~/.grok/auth.json, mounted read-only)
|
||||
# has a ~6h TTL; on an expired/missing token headless grok does NOT refresh — it
|
||||
# hangs forever at an interactive "Waiting for authorization..." prompt, which
|
||||
# reads as a silent zombie container. The orchestrator refreshes the host token
|
||||
# on a loop; this is the in-container backstop: exit 78 (EX_CONFIG) immediately
|
||||
# so _handle_stopped_container surfaces it, instead of hanging for hours.
|
||||
# Auth fail-fast guard. The SuperGrok token (~/.grok/auth.json) has a ~6h TTL;
|
||||
# on an expired/missing token headless grok does NOT refresh — it hangs forever
|
||||
# at an interactive "Waiting for authorization..." prompt, which reads as a
|
||||
# silent zombie container. The orchestrator refreshes the host token on a loop;
|
||||
# this is the in-container backstop: exit 78 (EX_CONFIG) immediately so
|
||||
# _handle_stopped_container surfaces it, instead of hanging for hours.
|
||||
#
|
||||
# F005: the orchestrator mounts the host ~/.grok DIRECTORY read-only at
|
||||
# /home/agent/.grok-auth-ro (a single-file bind mount pins the inode, so the
|
||||
# atomic auth.json refresh never reached a running container). Symlink
|
||||
# ~/.grok/auth.json at that RO mount so grok + the --check backstop read the
|
||||
# LIVE credential (the directory mount sees the host-side rename), while grok's
|
||||
# own writable state (config.toml, sessions/) still lands in the image's
|
||||
# ~/.grok. `rm -f` first in case the image baked a stub auth.json.
|
||||
rm -f /home/agent/.grok/auth.json
|
||||
ln -s /home/agent/.grok-auth-ro/auth.json /home/agent/.grok/auth.json
|
||||
if ! ( cd /app && python -m roboco.llm.providers.grok_auth --check ); then
|
||||
echo "[grok] auth token missing or expired — refusing to run (would hang at" \
|
||||
"the login prompt). Refresh ~/.grok/auth.json (orchestrator auto-refresh or" \
|
||||
|
||||
Reference in New Issue
Block a user