Managed gh lookup deadline

Historical design: retires this PATH shim in favor of explicit project GitHub routing. The bounded lookup and secret-free failure guarantees remain, but real gh now owns its option grammar; the source fixture below is not installed by production materialization.

Source boundary

caco-daemon::agent::spawn::install_gh_shim generates the managed agent gh shim. It selects the next executable on PATH, supplies the configured project repository when absent, and resolves the invocation's effective host before selecting a configured account. It does not change the node-global active account. This change applies to that generated shim, not arbitrary project overrides, gh-multiplex, or the separate synthetic shell-function fallback in caco-config.

Aurora's installed shim was independently matched byte-for-byte to the original source literal, SHA-256 effed1e6bcb57232d1a2baca3660b0c9486a05672ef114064b749c41fa6980f5. The retained offline gh pr list --help attempts waited in local gh auth token lookup while top-level --version returned immediately. That identifies the blocking layer, not a keyring implementation cause or the exact phase of an earlier PR publication. No real credential lookup is used by the regression suite.

Contract

Top-level help/version retains its existing pass-through behavior. Unambiguous two/three-argument help forms for the built-in pr, issue, repo, run, workflow and release groups also reach the real CLI without credential lookup. The shim does not search for help anywhere in argv: a --title --help value, a word after --, and --help=false do not change account routing. Arguments are forwarded unchanged.

Local account lookup has a five-second default deadline through the already-declared coreutils timeout, with a one-second hard-stop grace. CACO_GH_TOKEN_LOOKUP_TIMEOUT_SECS permits an integer from 1 through 60; invalid values fail before lookup. Missing timeout tooling fails explicitly rather than reverting to an unbounded helper. Failed, timed-out, empty or whitespace-bearing lookup output never starts the requested command and never falls back to another account. The wrapper reports only a fixed failure description and numeric helper-wrapper status; raw lookup stderr and credential bytes are not emitted. Status 124 is the timeout utility's deadline status; 137 can reflect hard termination and is not independently claimed as proof of a particular signal cause. Successful lookup pins the exact account for the target host, while supplied credentials for that host's gh token family and an existing GH_REPO remain unchanged. The requested command's own exit status remains authoritative.

Effective-host routing

Project provisioning supplies GH_HOST from the configured identity/remote unless explicitly overridden. The shim supports the built-in api, pr, issue, repo, run, workflow, release, and read-only auth token/status groups. API/auth --hostname HOST and --hostname=HOST override GH_HOST; repository commands respect -R, --repo, host-qualified repository arguments/URLs, GH_REPO, and unambiguous current remotes where applicable. An unqualified repository uses GH_HOST or gh's github.com default, not the configured account's hostname alone. Literal option values are consumed without interpreting their contents as routing flags, and -- ends option parsing without hiding a positional repository URL. Original-CI reads support run view --attempt/-a as an unsigned value, --job/-j as a literal value, and --log-failed as a boolean; run list -a remains the boolean --all. API --allow-escape-sequences is supported as a boolean, without broadening unknown-option admission or host/account guards. Unknown options/extensions, absolute API URLs, conflicting routes, ambiguous remote hosts, and interactive repository creation/cloning without an explicit repository fail before lookup. Managed auth login/logout/switch and other auth mutations are refused rather than changing node-global account state. Repository template creation and auth status without an explicit hostname are unsupported because they can introduce additional host targets.

CACO_GH_AUTH_HOSTNAME and CACO_GH_AUTH_USER bind the project's selected account. Other target hosts require a unique exact account in CACO_GH_AUTH_ROUTES, a non-secret, deterministic host=user comma-separated projection of configured identities. Different hosts may have different usernames; duplicate identical routes coalesce, while distinct accounts on the same alternate host remain ambiguous. Missing or ambiguous accounts refuse without consulting gh's active account or borrowing the project host's credential. GH_TOKEN then GITHUB_TOKEN take precedence for github.com and *.ghe.com; GH_ENTERPRISE_TOKEN then GITHUB_ENTERPRISE_TOKEN take precedence for other hosts. An explicit token override does not require a configured account route, but unsupported host semantics and auth mutations remain refused. Lookup exports only the target host family's token variable, and the bounded named-account fallback is bound to that same resolved host/user pair. No global auth switch/login state is read or changed.

Evidence and deployment

scripts/tests/managed-gh-lookup-test.py executes the exact generated script literal against fake local helpers. It covers offline help, literal help data, account/host/repo/argument preservation, supplied credentials, normal command failure, cooperative and unresponsive helper deadlines, failed/empty/whitespace results, invalid deadlines, and missing timeout tooling. It also covers explicit hostname forms, distinct usernames across hosts, host-qualified repositories/URLs, local remote discovery, missing/ambiguous accounts, both credential families, routing-like literal values, unsupported routes, and refusal of global auth mutations. Synthetic credential canaries must not appear in output, and failure fixtures prove the requested command was never reached. The suite is part of the credential-free source guard lane; existing Rust tests still exercise shim installation and account/hostname provisioning.

Source publication is not installed-wrapper or live-auth acceptance. Existing managed shims change only through their normal owner-controlled materialization lifecycle after the containing source is deployed. Do not hand-edit an installed shim, copy credentials, switch accounts, or replay a publication with uncertain prior acceptance as a way to test this change.