Conversation
This was referenced Apr 8, 2026
c01eb26 to
94b0702
Compare
ff079ef to
35c9400
Compare
This was referenced Apr 20, 2026
6d66905 to
6f6d9a6
Compare
c103b93 to
da2363e
Compare
c2fa71a to
2dcdd29
Compare
a8a52ed to
090907d
Compare
05ee118 to
559e5b8
Compare
175603e to
63d64d5
Compare
ab9f9ea to
7b7ac90
Compare
rhan-oai
added a commit
that referenced
this pull request
Apr 29, 2026
## Why Codex analytics needs a typed seam for app-server-originated request/response traffic so future tool-approval analytics can consume those facts without adding bespoke callsite tracking each time. Server responses arrive as JSON-RPC `id + result` payloads, so analytics has to reconstruct the matching typed response from the original typed request while that request context still exists in app-server. This also puts analytics on the app-server outbound path, which needs to avoid keeping the runtime alive during shutdown. The final ownership fix keeps the normal strong auth-manager retention in analytics and makes the external-auth refresh bridge hold a weak back-reference to `OutgoingMessageSender`, breaking the runtime cycle at the bridge boundary instead of exposing retention policy through the analytics client API. ## What changed - Adds typed `ServerRequest` and `ServerResponse` analytics facts, plus `AnalyticsEventsClient::track_server_request` and `track_server_response`. - Renames the existing client-side facts to `ClientRequest` and `ClientResponse` so reducers can distinguish client-to-server traffic from server-to-client traffic. - Adds `ServerRequest::response_from_result`, allowing a stored typed request to decode the matching typed server response from a raw JSON-RPC result payload. - Threads `AnalyticsEventsClient` through `OutgoingMessageSender` and records targeted server requests, replayed targeted requests, and matching targeted responses with the responding connection id needed for correlation. - Intentionally leaves broadcast server requests/responses out of analytics for now because the current model is per connection, while broadcasts fan one logical request out across multiple connections. - Breaks the app-server shutdown cycle by storing `Weak<OutgoingMessageSender>` in `ExternalAuthRefreshBridge` and upgrading it only when an external-auth refresh is actually requested. - Keeps reducer ingestion of the new server-side facts as no-ops for now; this PR is plumbing for later tool-approval analytics work. ## Verification - `cargo test -p codex-analytics` - `cargo test -p codex-app-server outgoing_message::tests::` - Covers typed-response reconstruction plus the targeted, replayed, broadcast-exclusion, and response-attribution analytics paths. ## Follow-up This PR intentionally stops at ingestion plumbing, so `ServerRequest` and `ServerResponse` facts are still reducer no-ops. Once a follow-up PR adds real downstream analytics output for those facts: - replace the temporary pre-reducer observation seam with reducer tests for the emitted event shape; - add end-to-end coverage in `app-server/tests/suite/v2/analytics.rs` for the real app-server workflow and captured analytics payload; - remove the temporary sender-level observer tests added here in favor of the real-output coverage above. --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/17088). * #18748 * #18747 * #17090 * #17089 * #20241 * #20239 * __->__ #17088
2351355 to
7b7ac90
Compare
This was referenced Apr 30, 2026
This was referenced Apr 30, 2026
owenlin0
approved these changes
May 6, 2026
Collaborator
Author
|
/merge |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
After the tool-item schemas are in place, analytics needs to emit them from the app-server item lifecycle rather than requiring bespoke tracking at each callsite. The reducer should also reuse the shared thread analytics context introduced below it in the stack so later event families do not repeat the same reducer joins or missing-state ladder.
What changed
Duration semantics
duration_msis computed from the app-server item lifecycle timestamps:completed_at_ms - started_at_ms. That makes it the duration of the lifecycle Codex observed locally, not necessarily the upstream provider's full execution time.response.output_item.addedbeforeresponse.output_item.done; in that casestarted_at_mscomes from the added event andcompleted_at_mscomes from the done event.response.output_item.done; when there is no earlier added event, Codex synthesizes the started item immediately before completion, soduration_mscan be0even though upstream image generation took longer.execution_duration_msis populated only where the completed item already carries a native execution duration; otherwise it remainsnullwhileduration_msstill reflects the local lifecycle interval.Currently placeholder / partial fields
Some fields are included in the schema for the intended steady-state contract, but this PR does not yet populate them from real approval/review state:
review_count,guardian_review_count, anduser_review_countcurrently default to0.final_approval_outcomecurrently defaults tounknown.requested_additional_permissionsandrequested_network_accesscurrently default tofalse.Verification
cargo test -p codex-analyticsStack created with Sapling. Best reviewed with ReviewStack.