Skip to content

fix(ingest): keep the model Codex reports, and stop calling it OpenAI - #390

Merged
blitzcrieg1 merged 1 commit into
masterfrom
fix/codex-model-ingest
Nov 7, 2026
Merged

blitzcrieg1 merged 1 commit into
masterfrom
fix/codex-model-ingest

Conversation

@blitzcrieg1

Copy link
Copy Markdown
Owner

Fixes #389.

What was wrong

The Codex hook reads the reported model and sends it as a nested model object. ExternalIngestBody did not declare model, so it was dropped over HTTP and the event recorded codex as both model and provider. The spool replay skips that route, so the same call could record different values depending on whether the receiver was up.

The hook also hardcoded provider: "openai". Codex can use any endpoint, so fixing the drop alone would have labelled a GLM model as OpenAI.

What changed

Codex reports glm-5.3 Before After
Over HTTP {"id": "codex", "provider": "codex"} {"id": "glm-5.3", "provider": "codex"}
From the spool {"id": "glm-5.3", "provider": "openai"} {"id": "glm-5.3", "provider": "codex"}
  • ExternalIngestBody declares model. A wrong-shaped value is ignored rather than refused, because the field was ignored while undeclared.
  • map_codex_hook states no provider, and model.provider falls back to the source app as it does for other agents.
  • Model values are capped at 256 characters in external.py, so the cap covers both paths.
  • The schema doc now says what these fields mean: codex there means "not reported", and neither field shows what actually served the request.

Consumers

AiSOC's template reads model.id and model.provider. They are not renamed or moved, but the values change for Codex events, so the schema doc's promise means announcing this in the AiSOC discussion before it ships. That has not been posted. Tenzir's listed fields do not include them.

Not in this PR

  • Inferred approval events (codex_inferred) are generated without a model and still say codex.
  • Older records are not rewritten.
  • Claude Code, Cursor and Antigravity still capture no model.
  • The source-app fallback is unchanged, so model.id can still hold an agent's name.

Checks

Run locally on this branch, before a final edit to one code comment. After that edit, the two changed test files and ruff were rerun.

  • Full suite: 2118 passed, 6 skipped, 3 failed. The failures are the ones CLAUDE.md lists for the dogfood machine: test_arguments_sent_as_a_json_string_are_enriched, test_the_cli_rotates_lists_and_verifies and the README count (2125 expected, 2127 collected locally). Their messages match, but they were not re-run with .env moved aside, so CI is the check on those.
  • Benchmark: 0 missed, 0 false positives.
  • Ruff: clean.
  • Fingerprint: 15846a0915769d4a, unchanged. No frozen file is touched.
  • Tests that exercise the bug failed before the fix, including one through the real route and one through drain_spool.
  • Not run: a real Codex session against a live recorder.

🤖 Generated with Claude Code

The Codex hook sent the model as a nested `model` object that
ExternalIngestBody did not declare, so pydantic dropped it over HTTP and the
event recorded `codex` as both model and provider. On the dogfood machine
that was 4,175 Codex events against 130 with a real name. The spool replay
skips that route, so the same call could record different values depending on
whether the receiver was up. The roundtrip guard missed it because it only ran
the Claude mapper, which sends no model. This is the fourth field lost this way.

The hook also hardcoded provider "openai", which fixing the drop alone would
have spread: Codex can use any endpoint, so a GLM model would have been labelled
OpenAI. It now states no provider, and model.provider falls back to the source
app as it does for other agents.

A `model` of the wrong shape is ignored rather than refused, because the field
was ignored while undeclared and declaring it must not start losing events. The
length bound sits in external.py, which both paths reach.

Fixes #389. model.id and model.provider are read by AiSOC's template. They are
not renamed or moved, but Codex values change, so announce this there before
release. Inferred approval events still carry no model, and older records are
not rewritten. Fingerprint unchanged at 15846a0915769d4a.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@blitzcrieg1
blitzcrieg1 merged commit 4a7a4e1 into master Nov 7, 2026
11 checks passed
@github-actions github-actions Bot locked and limited conversation to collaborators Nov 7, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Codex's reported model is dropped on HTTP ingest, so model.id records codex

1 participant