Skip to content

sync: label the agent's Claude runs autofork, so the 5-hour limit meters them like interactive Claude Code - #18

Merged
AVGVSTVS96 merged 2 commits into
mainfrom
entrypoint
Nov 3, 2026
Merged

AVGVSTVS96 merged 2 commits into
mainfrom
entrypoint

Conversation

@AVGVSTVS96

@AVGVSTVS96 AVGVSTVS96 commented Nov 3, 2026 •

Copy link
Copy Markdown
Owner

Claude Code labels claude -p requests sdk-cli, and Claude's 5-hour limit drains faster for that label than for interactive Claude Code: about 1.6x to 1.7x in Theo's A/B on one Max account (pingdotgg/t3code#24649), 1.8x to 2.9x in anthropics/claude-code#97074. The weekly limit isn't affected. T3 Code fixed it for its own sessions in pingdotgg/t3code#28410 by setting CLAUDE_CODE_ENTRYPOINT=t3-code; a check after that merge on a Pro plan found a session labeled t3-code, started with claude -p, drained at the interactive rate (0.92x to 0.96x, ±20% from the whole-percent meter).

Change

  • agent() starts the agent with CLAUDE_CODE_ENTRYPOINT=autofork. That's the one place the engine starts Claude: patch rebuilds, verify fixes and workflow updates all go through it, and action.sh only runs the engine.
  • A CLAUDE_CODE_ENTRYPOINT the user set wins. One inherited from a Claude Code session autofork runs inside (CLAUDECODE is set there, with that session's own label, like sdk-cli) is replaced, as T3 Code does with an inherited host value.
  • It's set for a custom agent command too, so a custom command that runs Claude gets the same label.

Unlike T3 Code, this doesn't read the label from Claude's settings.json env: Claude Code 2.1.316 ignores it there, and forks run in Actions with no settings file.

Verification

The billed-run test checks that the stub claude sees CLAUDE_CODE_ENTRYPOINT=autofork, and mine when the user set mine outside a Claude Code session. bun run check passes.

Note

Label the agent's Claude runs autofork so the 5-hour limit meters them at the interactive rate

  • src/autofork.ts: agent() now starts the agent with CLAUDE_CODE_ENTRYPOINT=autofork. Claude's 5-hour limit drains faster for runs labeled sdk-cli (the label claude -p gets). This applies to custom agent commands too.
  • If the user set their own CLAUDE_CODE_ENTRYPOINT, it's kept. The exception is when CLAUDECODE is set: then the value came from the surrounding Claude Code session and gets replaced.
  • dist/autofork.js: the built bundle, rebuilt with the same change.
  • test/autofork.test.ts: the billed-run test now checks that an inherited sdk-cli becomes autofork, and that mine is kept when it's set outside a Claude Code session.
  • Risk: Low. Only one env var changes, and env ?? process.env gives the same environment as before when no env is passed. The label is read once, when the module loads.
🔬 microscope summarized 0bc9ba4. 0 files reviewed, 0 issues evaluated, 0 filtered, 0 comments posted

Note

Set CLAUDE_CODE_ENTRYPOINT to autofork for agent-spawned Claude runs

Labels the agent's Claude runs as autofork so the 5-hour limit meters them like interactive Claude Code. A new selector in autofork.ts picks the label: it uses CLAUDE_CODE_ENTRYPOINT when CLAUDECODE is unset or empty, otherwise it defaults to autofork. The agent process launcher then sets CLAUDE_CODE_ENTRYPOINT on the spawned environment, overriding any inherited value.

Tests in autofork.test.ts cover both paths: an inherited sdk-cli label inside a Claude Code session becomes autofork, and an inherited mine label is kept when CLAUDECODE is empty. autofork.js is the regenerated bundle.

Behavioral Change: the spawned agent's CLAUDE_CODE_ENTRYPOINT value is now always overwritten with the selected label.

Macroscope summarized 0bc9ba4.

Comment thread test/autofork.test.ts Resolved
Comment thread src/autofork.ts Resolved
@AVGVSTVS96

AVGVSTVS96 commented Nov 3, 2026 •

Copy link
Copy Markdown
Owner Author

microscope reviewed 0bc9ba4

Check Result
Correctness No issues new, 1 open, 0 code objects reviewed
Architecture, Standards, and Engineering Philosophy No violations: the entrypoint label is added in one place with no new dependencies
Approvability Needs human approval

Approvability: The code change is small and works. If env is undefined, {...(env ?? process.env)} gives the same result as before. Tests cover both the inherited-label case and the case where the user sets their own label. Two things still need a person. First, the PR exists to change how Anthropic's 5-hour usage limit counts autofork's Claude runs. It sets CLAUDE_CODE_ENTRYPOINT=autofork on purpose so claude -p runs are counted at the interactive rate instead of the sdk-cli rate. Whether it's acceptable to relabel requests to get more usage under the limit is a policy and terms-of-service call that a human should make. Second, there's an unresolved review finding: when autofork runs inside a Claude Code session (CLAUDECODE set), a label the user deliberately set is silently replaced with autofork, and neither the code comment nor the README says so. The label also goes to custom agent commands, which changes what every user-supplied agent sees in its environment.

Resolved since the last review:

  • test/autofork.test.ts:2349
Architecture, Standards, and Engineering Philosophy

I checked the diff against each standard and found nothing to flag.

  • Service boundaries and dependency direction: The diff adds no imports and doesn't reach into any other module. All of it is inside src/autofork.ts.
  • Public API: No exported types or request/response shapes change. The only signature involved, agent(), stays the same. When no env is passed, env ?? process.env keeps the old behavior of using the current environment. The callers that pass BOT (lines 818 and 1151) still get exactly that environment, now with one extra variable.
  • Simplicity: It's a one-line module-level constant plus a one-line spread at the only place the engine starts Claude, with no extra layers of indirection. A comment explains why an inherited CLAUDE_CODE_ENTRYPOINT is replaced when CLAUDECODE is set, and two tests cover the override cases.
  • Tech stack: No new packages.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant