cron-child-oauth-audit
Skill2 starsChanged 25 days agoMITView on GitHub
Diagnose a cron or daemon-spawned "claude --print" child that fails silently because it launched without an auth token, when a scheduled task's critic or subprocess returns ERROR or GATE_DOWN with duration_api_ms 0 on every firing.
In this repository57 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- llms.txtllms.txt
- advisorSkill
- agent-dispatchSkill
- arenaSkill
- audit-pypi-model-packageSkill
- branching-workflowSkill
- code-reviewSkill
- criticSkill
- daily-forestSkill
- deep-researchSkill
- diagnose-cron-timeoutSkill
- dreamingSkill
- eod-summarySkill
- filingSkill
- forest-synthesisSkill
- goalsSkill
- graph-hygieneSkill
- ideaSkill
- inline-tagsSkill
- intel-analyzerSkill
- longformSkill
- loop-experimentSkill
- loop-librarySkill
- meta-memory-reviewSkill
- office-hoursSkill
- open-loopsSkill
- plan-ceo-reviewSkill
- plan-design-reviewSkill
- prdSkill
- progressive-disclosureSkill
- reality-feedback-createSkill
- reality-review-weeklySkill
- recallSkill
- reconcile-extractionSkill
- redactSkill
- repo-auditSkill
- research-digestSkill
- review-gateSkill
- run-long-job-detachedSkill
- saveSkill
- scopeSkill
- self-auditSkill
- shadow-test-local-classifierSkill
- signal-scorerSkill
- skill-auditSkill
- skill-chainingSkill
- spawn-agent-in-tenantSkill
- spawn-tenantSkill
- split-log-rows-by-session-kindSkill
- subagent-delegationSkill
- telegram-dump-routerSkill
- telegram-reply-toolSkill
- verify-stackSkill
- wave-planSkill
- weekly-retroSkill
The file
Files
Cron-child OAuth audit: a silently tokenless spawned Claude child
When to run this
A scheduled or daemon-spawned claude --print (or -p) subprocess fails the same way on every firing, with no reason string in logs/errors.jsonl, and the failure looks like: rc != 0, duration_api_ms: 0, num_turns: 1, stop_reason: "stop_sequence". Auth fails before any real API call registers. In a long-running stack this shape tends to recur once per spawn site (the critic hook, the scheduler's own child launcher, a cron wrapper), so treat a new occurrence as this bug class first, before inventing a new theory.
Procedure
- Find the spawn site. Grep the daemon or scheduler code for the failing schedule's dispatch path (usually
subprocess.runorPopencallingclaude --printorclaude -p). Check whetherenv=is passed explicitly. - Check the parent's own environment. With no
env=, the child inherits the PARENT process's environment, not a login shell's. For a long-running daemon, check directly (/proc/<daemon_pid>/environ) whetherCLAUDE_CODE_OAUTH_TOKENis present. It usually is not: the setup-token file is loaded by interactive shells and by launchers that source it on purpose, not by every process a daemon forks. - Confirm the failure signature before touching anything. Pull a handful of the failing events' raw log lines. The tokenless shape is
duration_api_ms: 0withnum_turns: 1(fails before the first API call, not after running out of turns). A different shape (realduration_api_msabove 0, then a failure) is a different bug; do not apply this fix blind. - Apply the fix with the shared helper, not a per-file copy. In Python:
from lib_claude_child_env import child_env, then passenv=child_env()to the subprocess call (scripts/lib/lib_claude_child_env.py). In shell launchers, sourcescripts/lib/lib_claude_setup_auth.shbefore callingclaude. Both load the long-lived setup token into a COPY of the environment and fail open (if the token is missing, the child still launches on whatever credentials exist). If the child could re-trigger the same critic or hook (recursion risk), also set the disable-guard env var the child's entry point already honors. One-time setup of the token:scripts/session/install_setup_auth.sh. - Make future failures loud. Add a failure branch that logs the real
rcand stderr (or the parsed error) on a non-zero exit, instead of returning a genericERRORorOPERATOR_REVIEWverdict with no reason. A logged reason turns a multi-day silent run into a same-day root cause. - Validate before calling it done.
py_compilethe changed file. Simulate both paths if you can (a good token gives a real API call; a forced bad token hits the new named failure branch with a captured reason). Restart whatever process holds the old module in memory: daemons cache imports, so editing the file alone does not apply the fix. - Confirm live, not just in theory. Watch the next 1 or 2 real firings of the affected schedules for a clean verdict (PASS, WARN or SHIP, not ERROR). Also check sibling schedules that share the same dispatch function: this bug class is usually function-wide, so a real fix shows up as a flip across every caller, not only the schedule that was noticed first. Cite the level from
knowledge/evidence-ladder.md(the live firing is L5).
Why a setup token and not copied credentials
A copied interactive credentials file refreshes on its own schedule. Several same-account processes refreshing independently invalidate each other, which shows up as random 401s and repeated re-login prompts. A claude setup-token credential has no refresh cycle, so there is nothing to race. Details in the header of scripts/lib/lib_claude_setup_auth.sh.
Caveat
This is specifically the tokenless-child signature. Do not reach for this fix on a generically failing cron without first confirming the step 3 signature. A different bug wearing the same "verdict: ERROR" costume would get the wrong fix and stay hidden.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

