Skip to content

fix(global-discover): bucket codex sessions by originator - #1488

Open
0xDevNinja wants to merge 1 commit into
garrytan:mainfrom
0xDevNinja:fix/1315-codex-originator-and-cc-truncation
Open

fix(global-discover): bucket codex sessions by originator#1488
0xDevNinja wants to merge 1 commit into
garrytan:mainfrom
0xDevNinja:fix/1315-codex-originator-and-cc-truncation

Conversation

@0xDevNinja

@0xDevNinja 0xDevNinja commented May 14, 2026

Copy link
Copy Markdown
Contributor

Summary

Buckets codex sessions by payload.originator. scanCodex normalizes it into { desktop, exec, claude_code, other } and surfaces the breakdown at tools.codex.originators (global) and codex_originators (per-repo), plus the summary view. Existing codex totals are untouched — the change is purely additive, so no consumer breaks.

Unknown, missing, null, and non-string originators land in other rather than being dropped, so the buckets always sum to the codex total. Whitespace is trimmed before matching.

Refs #1315 — this covers Problem 1 only. See scope note below.

Why

/retro global narrated "codex was the primary execution tool, 414 sessions across 7 repos" when codex actually drove dev for one repo's middle phase. The other ~309 codex_exec entries were CC firing codex as a cross-model review subagent. A single bucket can't tell those apart.

Scope

Originally this PR carried two patches from #1315. It has since been rebased onto current main and narrowed to Problem 1:

  • Problem 1 (here): originator bucketing. Still missing on main — rg "originator" returns nothing in bin/gstack-global-discover.ts.
  • Problem 2 (dropped): the extractCwdFromJsonl cwd-truncation fix landed independently via v1.41.1.0 fix wave: 7 HIGH bugs from external audit + regression tests (PR #1169 follow-up) #1592 / v1.41.1.0 (64KB / 30-line / drop-partial). Main's trade-offs there are deliberate and have regression tests; no reason to re-litigate them from this branch. The CLAUDE_PROJECTS_DIR test knob went with it.
  • Problem 3 (not addressed): the /retro global "sessions = file count, not interactive dev" annotation. Belongs in the retro skill template, and probably deserves its own issue.

Because Problems 2 and 3 aren't both resolved here, this uses Refs rather than Fixes so merging doesn't auto-close #1315.

Tests

test/global-discover.test.ts — 35 pass, 0 fail. Covers each bucket, the whitespace-trim case, missing / null / non-string originator → other, and a per-repo sum invariant (desktop + exec + claude_code + other == sessions.codex).

Thanks

@Akagilnc for the review that caught the staleness, and for the .trim() and null-originator suggestions — both are in.

@Akagilnc

Copy link
Copy Markdown

Heads-up that this PR is now stale against main. The Problem 2 fix landed independently via #1592 / v1.41.1.0 on 2026-05-20: main's extractCwdFromJsonl uses a 64KB cap, scans up to 30 lines, and drops the trailing partial segment before parsing. The current PR is marked CONFLICTING / DIRTY.

The two implementations make different trade-offs rather than one being a strict superset:

  • This PR's 128KB read covers a hypothetical >64KB first-line case that main's 64KB read doesn't.
  • Main's 30-line scan handles cases where cwd lands past line 15 (which this PR caps at).
  • Main's trailing-partial-drop is cleaner at the buffer boundary, but drops a file whose final line has no trailing newline — a corner this PR's implementation does happen to handle.

That said, main is the one that's merged, has regression tests, and chose the 64KB / 30-line / drop-partial mix deliberately. Keeping this PR's Problem 2 patch would mean re-arguing those defaults from scratch.

The unique remaining value here is Problem 1 — bucketing Codex sessions by payload.originator. That part is genuinely missing on main (rg "originator" returns nothing in current bin/gstack-global-discover.ts) and the design looks good: case-insensitive normalization, unknown values land in other rather than being dropped, additive (existing totals unchanged), 7 new tests with sum invariants.

Suggestion: rebase onto main, drop the extractCwdFromJsonl / CLAUDE_PROJECTS_DIR / CC-bigline-test changes, keep only the originator bucketing. Two small additions worth picking up while rebasing:

  • normalizeCodexOriginator should .trim() before lowercasing — currently "Codex Desktop " (with a stray space) lands in other.
  • Add explicit tests for missing / null / non-string originator values mapping to other.

Happy to open a follow-up PR with just the originator half if that helps — no rush from my side, just flagging since the PR has been quiet for ~16 days.

Codex rollouts carry a free-form payload.originator string but global
discovery collapsed every codex session into one number, so /retro
global could not tell real interactive dev (Codex Desktop) from
subagent / scripted runs (codex_exec) or CC-driven calls (Claude Code).

Add a four-bucket classifier (desktop / exec / claude_code / other).
Unknown, missing, null, and non-string originators land in other rather
than being dropped, so the per-bucket counts always sum to the codex
total. Whitespace is trimmed before matching. Buckets surface in both
the JSON output (tools.codex.originators + per-repo codex_originators)
and the summary view.

Refs garrytan#1315.
@0xDevNinja
0xDevNinja force-pushed the fix/1315-codex-originator-and-cc-truncation branch from 69a2b46 to b729817 Compare June 16, 2026 06:35
@0xDevNinja 0xDevNinja changed the title fix(global-discover): bucket codex by originator + read 128KB for CC cwd fix(global-discover): bucket codex sessions by originator Jun 16, 2026
@0xDevNinja

Copy link
Copy Markdown
Contributor Author

Rebased onto current main and narrowed the scope to just the codex-originator bucketing, per @Akagilnc's review.

Dropped (now redundant): the extractCwdFromJsonl 8KB→128KB change and the CLAUDE_PROJECTS_DIR test knob. That cwd-truncation fix landed independently via #1592 / v1.41.1.0 (64KB / 30-line / drop-partial), and main's deliberate trade-offs there are the ones with regression tests. No reason to re-argue them from this branch.

Kept (unique, missing on main — rg "originator" returns nothing): the four-bucket classifier so /retro global can separate real interactive dev (Codex Desktop) from subagent / scripted runs (codex_exec) and CC-driven calls (Claude Code).

Picked up both follow-ups you flagged:

  • normalizeCodexOriginator now .trim()s before lowercasing, so "Codex Desktop " maps to desktop instead of other.
  • Added explicit tests for missing / null / non-string originatorother, plus a whitespace-trim test.

Buckets are additive (existing totals unchanged) and always sum to the codex total. 35 tests pass.

@Akagilnc

Copy link
Copy Markdown

Thanks for the rebase and for picking up both follow-ups — the .trim() and the missing/null/non-string tests are exactly what I had in mind, and narrowing to the originator bucketing makes this much easier to reason about.

Three small housekeeping suggestions, all non-blocking and entirely up to you and the maintainers:

  1. The PR description is still the pre-rebase version. It describes both patches (including the extractCwdFromJsonl 8KB→128KB change and the CLAUDE_PROJECTS_DIR knob) and reports 26 pass, 0 fail, whereas the rebased branch drops patch 2 and you mention 35 passing. Might be worth refreshing so reviewers reading the description see the current scope.

  2. Fixes #1315 in the description vs Refs #1315 in the commit. The commit message has it right — Fixes is a closing keyword, so merging as-is would auto-close gstack-global-discover: session counts conflate originator types and undercount CC by ~5x #1315. Since this PR now only covers Problem 1, that would close the issue with Problem 3 (the /retro global "sessions = tool invocations" annotation, which you flagged as out of scope) still unaddressed. Changing the description to Refs #1315 would keep the two in sync.

  3. Problem 2's fix never got linked back to the issue. It landed in v1.41.1.0 fix wave: 7 HIGH bugs from external audit + regression tests (PR #1169 follow-up) #1592 / v1.41.1.0 on 2026-05-20, but that PR doesn't reference gstack-global-discover: session counts conflate originator types and undercount CC by ~5x #1315, so the issue currently has no record that half of it is already resolved. Worth a note on gstack-global-discover: session counts conflate originator types and undercount CC by ~5x #1315 at some point, and Problem 3 probably deserves its own issue.

Either way, the bucketing work here looks good to me. Thanks for sticking with it.

@0xDevNinja

Copy link
Copy Markdown
Contributor Author

good catches, both real. updated the description: scope is originator-only now, 35 tests, and swapped Fixes -> Refs so merging doesn't close #1315 with problem 3 still open. the commit already said Refs, i just forgot the body when i rebased.

agreed on the third one too. i'll drop a note on #1315 pointing at #1592 for problem 2 and open a separate issue for the /retro global annotation, that's a retro-template change and doesn't belong here.

Akagilnc commented Jul 15, 2026

Copy link
Copy Markdown

Thanks for following through on this. Really appreciate the cleanup and for linking everything back together — much easier to follow now.

@time-attack

Copy link
Copy Markdown
Contributor

@16francej Merge this version because it correctly buckets Codex sessions by originator and passed the Mac checks.

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.

gstack-global-discover: session counts conflate originator types and undercount CC by ~5x

3 participants