Skip to content

codex: desktop OTEL tracing on Windows - #1188

Merged
andy-xu-db merged 1 commit into
mainfrom
andy-xu-db/stack/andy/codex-desktop-tracing-windows
Oct 21, 2026
Merged

andy-xu-db merged 1 commit into
mainfrom
andy-xu-db/stack/andy/codex-desktop-tracing-windows

Conversation

@andy-xu-db

@andy-xu-db andy-xu-db commented Oct 19, 2026 •

Copy link
Copy Markdown
Collaborator

Follows #1187 (macOS, merged); this PR's diff is the Windows change only.

What

Extends the Codex desktop OTEL login service from the previous PR in this stack to Windows: a per-user logon task com.databricks.ug-codex-otel that needs no admin rights. It runs the venv's pythonw.exe -m ucode.cli otel-proxy, so no console window appears.

Notes

  • Task Scheduler keeps its own copy of the task, so ug keeps the XML it registered in ~/.ucode to track ownership and the port. The file is UTF-16, the encoding schtasks reads, so write_text_file gains an encoding argument.
  • Like macOS, Windows returns early from the shared functions, so the Linux and macOS code is untouched; the Linux unit is still byte-identical to main.
  • A changed definition runs /End before /Create /F, which would otherwise leave the old proxy running. IgnoreNew keeps /Run from starting a second proxy next to a running one.

Validation

  • A component test simulates schtasks and checks the task XML, the UTF-16 file, an unchanged launch, a workspace change, and removal. It passes in the Windows unit-test CI job.
  • just lint passes; tests/test_agent_codex.py passes. The 7 full-suite failures (test_agents_init update prompts, test_e2e_user_agent) fail the same way on main.
  • End to end on a GitHub windows-latest runner, with ug installed by uv tool install, the real Databricks CLI, and Codex's real codex app-server, against a local fake workspace:
    • ug configure writes the exporter and registers the task; the proxy listens within ~2s under windowless pythonw.exe.
    • App-server sessions export OTLP traces with the Databricks token, before and after a simulated logout/login (/End + /Run).
    • Disabling tracing removes the exporter and the task.
  • A standard (non-admin) user registered the task as their own At logon time / Interactive only task, and removal worked.

Limits

  • Marked shortcut: in code: a crashed proxy waits for the next logon or ug codex launch, and the task doesn't get the shell's DATABRICKS_* overrides.
  • The non-admin run couldn't start the task because that test user had no desktop session; a real user configuring from their own session wasn't tested.
  • Not run with a real workspace, a real reboot, or the Codex desktop app itself (only its app server).

This pull request and its description were written by Isaac.

@andy-xu-db
andy-xu-db force-pushed the andy-xu-db/stack/andy/codex-desktop-tracing-macos branch from d3d26e0 to f01858e Compare October 19, 2026 20:35
@andy-xu-db
andy-xu-db force-pushed the andy-xu-db/stack/andy/codex-desktop-tracing-windows branch from 6748798 to 8c0af20 Compare October 19, 2026 20:35
@andy-xu-db
andy-xu-db changed the base branch from andy-xu-db/stack/andy/codex-desktop-tracing-macos to main October 19, 2026 20:35
@andy-xu-db
andy-xu-db marked this pull request as ready for review October 19, 2026 20:53
@andy-xu-db
andy-xu-db requested a review from masonc08 October 19, 2026 21:14
@andy-xu-db
andy-xu-db force-pushed the andy-xu-db/stack/andy/codex-desktop-tracing-windows branch from 062d447 to 575bd49 Compare October 19, 2026 22:35
Comment thread src/ucode/agents/codex.py
Comment thread src/ucode/agents/codex.py
Comment thread src/ucode/agents/codex.py
zhulinchng pushed a commit to zhulinchng/ucode that referenced this pull request Oct 21, 2026
## 🥞 Stacked PR
Use this
[link](https://github.com/databricks/unity-gateway/pull/1187/files) to
review incremental changes.
-
[**stack/andy/codex-desktop-tracing-macos**](databricks#1187)
[[Files
changed](https://github.com/databricks/unity-gateway/pull/1187/files)] ←
_this PR_
-
[stack/andy/codex-desktop-tracing-windows](databricks#1188)
[[Files
changed](https://github.com/databricks/unity-gateway/pull/1188/files/1ef8a4ca357206e5d133f591107a48460c9de89f..575bd49dcd472f5705f795765bfcf7d21a7b88a6)]

---------
## What

databricks#1112 runs ug's OTEL proxy as a login service so Codex desktop traces
get a fresh Databricks token, but only on Linux. This adds the same
service on macOS: the LaunchAgent `com.databricks.ug-codex-otel` in
`~/Library/LaunchAgents`, loaded with `launchctl bootstrap gui/<uid>`.
`KeepAlive` restarts it after a failure.

The proxy, fixed port, `~/.codex/config.toml` exporter, warn-only setup,
and removal on disable or `ug revert` are unchanged. Linux code is
untouched: macOS returns early from the shared functions, and the Linux
unit and `systemctl` calls are byte-identical to main. Windows follows
in the next PR of this stack.

## Notes

- An unchanged launch leaves a loaded agent alone; a changed plist is
reloaded with `bootout` + `bootstrap`.
- The only code shared with the systemd path is `_otel_service_env()`,
the variables the service inherits, so the unit and the plist can't
drift apart.

## Validation

- A component test simulates `launchctl` and checks the plist, an
unchanged launch, a workspace change, and removal.
- A script generates the Linux unit and the `systemctl` call sequence
from this branch and from main: they're identical.
- `just lint` passes; `tests/test_agent_codex.py` passes. The 7
full-suite failures (`test_agents_init` update prompts,
`test_e2e_user_agent`) fail the same way on main.
- End to end on a GitHub `macos-latest` runner, with ug installed by `uv
tool install`, the real Databricks CLI, and Codex's real `codex
app-server`, against a local fake workspace:
  - `ug configure` writes the exporter and starts the LaunchAgent.
- App-server sessions export OTLP traces through it to
`/ai-gateway/otel/v1/traces` with the Databricks token, before and after
a simulated logout/login (`bootout` + `bootstrap`).
- `KeepAlive` restarts a killed proxy, and disabling tracing removes the
exporter and the agent.

This pull request and its description were written by Isaac.

## E2E Test:
<img width="1366" height="779" alt="Screenshot 2026-10-19 at 4 33 27 PM"
src="https://github.com/user-attachments/assets/61c82543-174c-497e-a956-970032144e44"
/>

Co-authored-by: Isaac <no-reply@databricks.com>
@github-actions

Copy link
Copy Markdown

Polly AI Review

Blocking issues

  • Cross-workspace trace leakage — src/ucode/agents/codex.py:717. Can we roll back the saved XML when /Create fails? Otherwise a later /Query succeeds against the old task, and /Run sends workspace B’s desktop traces to workspace A.

    The XML is updated before task registration succeeds. If registration fails while the previous task remains registered, subsequent runs consider B’s definition unchanged and never retry registration. The existing exporter still targets the same port.

    Extend tests/test_agent_codex.py::TestCodexManagedConfig::test_desktop_tracing_scheduled_task_lifecycle: fail /Create during an A→B change, retry, and assert B’s task is registered before /Run.

Security vulnerabilities

The blocker above can expose traces to the previously configured workspace. No additional security vulnerabilities were identified.

Non-blocking notes

None.

Approach

The per-platform service definitions fit the existing lifecycle. Preserve retryability by rolling back the saved definition after registration failure. _run_systemctl could also delegate to _run_service_command instead of duplicating its subprocess/error wrapper.

Summary

Diff size (computed): 6 files; +296 / -30 lines (326 changed text lines); 0 binary files.

Category Files Added Deleted Share of changed text lines
Tests and test support 2 130 2 40.5%
Documentation 2 12 7 5.8%
Dependencies and lockfiles 0 0 0 0.0%
Implementation / other 2 154 21 53.7%

Shares use additions + deletions, including generated text and lockfiles. Binary files have no line count. Tests include fixtures/helpers under test paths and colocated test/spec files; categories are path-based, not coverage measurements.

Changes

The diff enables persistent Codex desktop tracing through a macOS LaunchAgent and a Windows per-user scheduled task. Shared changes provide service environment construction, definition/port parsing, and UTF-16 file writing. Documentation describes the platform-specific setup and diagnostics.

The size is proportional to that outcome. Consolidating the duplicate subprocess wrappers is a concrete, small reduction; the platform-specific definitions otherwise serve distinct requirements.

Tests

Test-by-test assessment
Test / case Behavior protected Layer Needed? Action / rationale
tests/test_agent_codex.py::TestCodexManagedConfig::test_desktop_tracing_launch_agent_lifecycle Plist contents and environment, stable port, unchanged launch, workspace replacement, and disable cleanup Component with simulated launchctl keep Provides distinct coverage of the LaunchAgent lifecycle and plist port parsing.
tests/test_agent_codex.py::TestCodexManagedConfig::test_desktop_tracing_scheduled_task_lifecycle UTF-16 task XML, command arguments and user, unchanged launch, replacement ordering, and removal Component with simulated schtasks keep Protects Windows-specific serialization and lifecycle behavior. Failed replacement followed by retry is not covered.
tests/README.md — Codex desktop OTEL coverage paragraph Documents simulated service coverage and native login/reboot limitations Documentation keep Accurately distinguishes component assertions from native platform validation; introduces no executable cases.

Both added test methods are accounted for; no existing test cases were modified or removed.

Existing tests/test_agent_codex.py::TestCodexManagedConfig::test_desktop_tracing_lifecycle covers shared warning behavior, preservation of another exporter, and revert. Existing CLI/proxy tests cover workspace-specific proxy configuration and fixed-port behavior. These do not protect against a failed scheduled-task replacement being treated as successfully applied.

Component testing is the appropriate layer for the replacement/retry regression. Native validation uniquely establishes actual Task Scheduler registration, interactive logon, and windowless behavior. The PR describes platform exercises but leaves real non-admin desktop-session and reboot behavior unverified.

Tests were not executed during this review. Findings are based on the frozen diff and trusted-checkout context.

Scope

No unrelated changes were found. The macOS changes included in the full stacked diff, Windows task support, shared helpers, tests, and documentation all support persistent Codex desktop tracing. No unresolved scope questions were identified.


Automated review by Polly · workflow run

Extend the Codex desktop OTEL login service to Windows as a per-user
logon task com.databricks.ug-codex-otel (no admin), running the venv's
pythonw.exe -m ucode.cli otel-proxy so no console window appears.
Task Scheduler keeps its own copy, so ug keeps the XML it registered
in ~/.ucode (UTF-16, the encoding schtasks reads) to track ownership
and the port. A changed definition ends the running task before
/Create /F; IgnoreNew keeps /Run from starting a second proxy.

Co-authored-by: Isaac <no-reply@databricks.com>
@andy-xu-db
andy-xu-db force-pushed the andy-xu-db/stack/andy/codex-desktop-tracing-windows branch from 575bd49 to d345b38 Compare October 21, 2026 16:12
@andy-xu-db

Copy link
Copy Markdown
Collaborator Author

/merge

@andy-xu-db
andy-xu-db added this pull request to the merge queue Oct 21, 2026
Merged via the queue into main with commit 4da19ea Oct 21, 2026
105 of 108 checks passed
@andy-xu-db
andy-xu-db deleted the andy-xu-db/stack/andy/codex-desktop-tracing-windows branch October 21, 2026 17:49
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.

2 participants