Skip to content

Commit 11fbdc6

Browse files
authored
Merge pull request #1865 from entireio/fix/codex-tailer-emitted-race
fix(codex): close tailer emitted-flag race causing token scale flap
2 parents b0fd1e7 + 40c09d8 commit 11fbdc6

1 file changed

Lines changed: 13 additions & 4 deletions

File tree

cmd/entire/cli/agent/codex/review_tokens.go

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,10 @@ const (
3535
// token_count.total_token_usage is a running SESSION total (not per-turn
3636
// scale like turn.completed usage), so each emission is an absolute count —
3737
// matching consumers' overwrite-not-sum semantics. Duplicate totals are
38-
// suppressed so we only emit on real movement. emitted is set after the
39-
// first successful send; the parser uses it to suppress its per-turn-scale
40-
// stdout emissions so a single source stays authoritative.
38+
// suppressed so we only emit on real movement. emitted is set immediately
39+
// before each send (never after — see drain) so it is observable no later
40+
// than the Tokens event itself; the parser uses it to suppress its
41+
// per-turn-scale stdout emissions so a single source stays authoritative.
4142
//
4243
// Returns when stop is closed (the stdout stream ended) — after one final
4344
// catch-up drain of the file, so the last token_count codex wrote is not
@@ -126,11 +127,19 @@ func (t *rolloutTail) drain() error {
126127
continue
127128
}
128129
t.lastIn, t.lastOut = in, outTok
130+
// Set emitted BEFORE the send: the parser suppresses its
131+
// per-turn-scale turn.completed Tokens once the tailer has
132+
// emitted, so the flag must be observable no later than the
133+
// Tokens event itself. Storing after the send leaves a window
134+
// where a consumer sees the tailer's Tokens while emitted is
135+
// still false, letting a concurrent turn.completed leak a
136+
// per-turn value and flap the counter between scales.
137+
//
129138
// Unconditional send is safe: the parser waits for the
130139
// tailer before closing the channel, and the run contract
131140
// guarantees the consumer drains until close.
132-
t.out <- reviewtypes.Tokens{In: in, Out: outTok}
133141
t.emitted.Store(true)
142+
t.out <- reviewtypes.Tokens{In: in, Out: outTok}
134143
}
135144
}
136145
if readErr != nil {

0 commit comments

Comments
 (0)