Repository navigation
fix(reports): await the late usage report in session-start pull - #1323
Conversation
The session-start pull runs in the detached hook-dispatch --bg-only pass. pull() stops waiting for its usage report after 5 s, and the dispatcher's process.exit(0) then cut the push: the commit stayed in the local reports checkout and .reports-lock kept a dead PID. pull() now keeps the late report together with the release of its sync locks and exports settleLateUsageReport(); the pull handler awaits it before returning. The host does not wait for the detached pass, so the session is not delayed. Fixes Tencent#1322
|
No findings in the specified PR diff. The PR description documents sufficient testing: a post-build real-CLI session-start run verifies the slow report push completes, usage data is consumed, and Reviewed only the diff; did not run, build, or install PR code. |
SaulMoro
left a comment
There was a problem hiding this comment.
This was generated by AI during triage.
@scpia Thanks, approving. This fixes #1322.
We built this head and its base 2401d047 and ran the issue's repro with the real CLI: a 7 s reports update hook, then hook-dispatch session-start --tool claude --bg-only.
- base: the pass exits after 5.3 s,
stats/alice.yamlnever reaches the remote, and usage is not truncated. - this PR: the pass waits about 8 s, the stats reach the remote (
review.count: 1), usage is truncated, and no commit stays unpushed. Both locks are released.
report-timeout.test.ts passes 20/20 here, and the new case fails on base with fatal: invalid object name 'teamai-reports'. tsc, build and lint pass. The foreground path is unchanged, since the pull handler is background: true.
Suggestions:
[P2 non-blocking]The failure half of #1322 ("fails with a logged reason and a released lock") has no test here. #1324'skeeps a rejected session-start report retryable and releases its lockspasses on this head. Pulling it in would cover it.[P3 nit]settleLateUsageReport()runs only ifpull()resolves. Ifpull()throws after the late report starts, the pass can exit with the push in flight. We found no trigger. Afinallywould cover it:
- await pull({ silent: true });
+ try {
+ await pull({ silent: true });
+ } finally {
+ await settleLateUsageReport();
+ }Not run: the full unit and e2e suites, Windows.
Fixes #1322.
What changes
The session-start
pullhandler runs in the detachedhook-dispatch --bg-onlypass.pull()waits at most 5 s for its usage report and then returns while the report is still pushing; the dispatcher'sprocess.exit(0)then cut that push. The commit stayed in the local reports checkout,.reports-lockkept a dead PID, and the next session start ran into the same race.pull.tskeeps the late report together with the release of its sync locks (the chain it already built) and exportssettleLateUsageReport(), which resolves once both are done.pullhandler awaits it before it returns. Background handlers only run in the detached pass, which the host does not wait for, so the session is not delayed. The handler stays bounded byPULL_TIMEOUT_MS, and a stalled reports git is still killed by the block timeout from fix(reports): kill stalled side-branch git with createGitWithBlockTimeout #1268.The foreground hook path,
teamai pullfrom the CLI and the detached pull of the git hooks are unchanged; the last two already exit only when the event loop is empty.Testing
After
npm run build:src/__tests__/e2e/report-timeout.test.ts:hook-dispatch session-start --tool claude --bg-onlyagainst a remote whose update hook sleeps 7 s. Without the fix it fails withfatal: invalid object name 'teamai-reports'(the push never reached the remote); with it the stats land, the usage file is consumed and.sync-lockis gone.npx vitest run --config vitest.e2e.config.ts src/__tests__/e2e/report-timeout.test.ts: 20 passed.hook-handlers.test.ts: thepullhandler returns only aftersettleLateUsageReport()resolves. The four other suites that mock../pull.jsnow mock the new export too, so their pull handler no longer throws at its end. The seven suites that mockpull.jsor exercise hook dispatch: 432 passed.npx tsc --noEmitandnpm run lintare clean.npx vitest runon WSL2 (Ubuntu, Node 22.23): 12021 passed, 12 failed. Eleven fail the same way onmain2401d04 in this environment (cursor-bubble-range,cursor-user-images,init-hang-regression,self-mode-agents,submodule-checkout, andgit-kind-reports"a stalled origin").workflow-reconciliationfailed under the full run's load and passes when run alone.Only Claude and the
gitprovider were run; the change does not depend on the agent or the provider, the rest is left to CI.