Skip to content

[AIGTWY-4881] Add CUJ 6 repeated-config E2E journey - #987

Merged
david-siqi-liu merged 1 commit into
mainfrom
david/integ-test-cuj-6
Oct 7, 2026
Merged

david-siqi-liu merged 1 commit into
mainfrom
david/integ-test-cuj-6

Conversation

@david-siqi-liu

@david-siqi-liu david-siqi-liu commented Oct 5, 2026 •

Copy link
Copy Markdown
Collaborator

CUJ 6 (AIGTWY-4881, epic AIGTWY-4875) checks that a developer who receives successive admin configs ends up with exactly the latest one: no stale ug-managed values, and their own settings untouched. It runs live on main's dedicated-workspace CUJ framework (#1000) with the TUI request recorder (#994), against the CUJ 6 plan in the UG Configure E2E doc.

Workspace configs are read only, because parallel CI jobs share them. Each phase is the single published config of its own pre-provisioned workspace, and one shared home moves through them:

  • A: dbc-8c38ce9b-634b, CUJ 1's config plus the named MCP ug_e2e.tools.fixture_reader
  • B: dbc-175bc4a3-a511, Claude on the Bedrock MPS ug_e2e.providers.bedrock, Codex on UC discovery ug_e2e.models, Codex as the default agent
  • C: dbc-998133ab-de86, Codex only, on the static list system.ai.gpt-5-6-luna

All three share one metastore, the ug_e2e fixtures, and one trace table. The test never writes workspace config; it checks each published config against the plan at the start and asserts it is unchanged at teardown. A to B to C also exercises ug's cross-workspace switch.

Builds on #1010 (merged), and on #1004 (merged), whose workspace_origin keeps the TUI request recorder's http://127.0.0.1:<port> origin for the workspace API calls CUJ 6 routes through it.

Changes:

  • tests/e2e_cuj/test_cuj_repeated_config.py: one class, phases as ordered class-scoped fixtures (phase_a -> phase_b -> phase_c) returning frozen evidence, 28 small tests on top.
    • Setup: seeds user-owned Claude and Codex prefs, a user stdio MCP, and a hand-written skill, with no ug state.
    • Readback: each phase workspace publishes exactly the plan's config (agents, model sources, defaults, headers, tracing, MCP selector).
    • Phase A: configures twice; identical settings and registrations, no duplicates; both agents complete a task with their phase headers and default models at gateway ingress (recorder) and in the native turn.
    • Phase B: Claude carries databricks-model-provider-service and no Phase A headers; Codex carries databricks-model-service-parent-schema and only the Phase B header; request and turn models match the sources. Bare ug in a real terminal launches Codex and completes a task on ug_e2e.models.codex_primary, and writes the Phase B header into /etc/codex/managed_config.toml. Static picker, family defaults, tracing keys, static Codex catalog, and the managed MCP are gone and stay gone after launches. Codex emits a span; Claude emits none.
    • Phase C: configures in a terminal (Phase B's terminal launch made ug own the machine-wide files) and clears Phase B's headers from /etc. Codex requests carry no Phase B headers, the picker is exactly Luna, Codex and bare ug both run Luna, ug claude is rejected with no inference request, and no Codex span is emitted while the Phase B span proves the trace query works.
    • Every phase: user prefs, MCP registrations, and skill files are unchanged, and each agent's registered user MCP still starts and lists its tool.
  • tests/e2e_cuj/helpers/constants.py: the CUJ 6 metastore fixtures. The Claude tracing keys come from ucode.agents.claude.CLAUDE_OTEL_TRACE_ENV_KEYS.
  • tests/e2e_cuj/helpers/tui_request_recorder.py: retarget_session is public so a terminal configure can be retargeted to the recorder.

Known gaps (tracked in AIGTWY-4972):

  • Managed skills are not covered: UC skill bundles can't be uploaded on these workspaces' Default Storage catalog (Files API HTTP 501).

Validation: ruff check and format pass; related unit tests pass. Live: E2E CUJs on this head passed 48 tests (CUJ 6's 28, plus CUJ 1, 2, 4, and 5) in 11m36s: https://github.com/databricks/unity-gateway/actions/runs/37567899055/job/112619786676

This pull request and its description were written by Isaac.

@david-siqi-liu david-siqi-liu added the quicktree-assisted PR created with quicktree-assisted workflow label Oct 5, 2026
@david-siqi-liu
david-siqi-liu force-pushed the david/integ-test-cuj-6 branch 8 times, most recently from 277e8ee to ab9b2a1 Compare October 6, 2026 01:36
@david-siqi-liu
david-siqi-liu marked this pull request as ready for review October 6, 2026 01:39
@david-siqi-liu david-siqi-liu added the ug-review Run the automated UG review label Oct 6, 2026
@github-actions

github-actions Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

UG review

The visible patch adds a cross-workspace, shared-home E2E journey and exposes recorder retargeting, with no production changes shown. The new test file is truncated, so its later phase fixtures and assertions could not be reviewed.

No actionable findings.

Some patches were unavailable or truncated to fit the review context. Treat this as a partial review.

Automated advisory review of 2911d8ca82cc using Lilly's UG review rubric. It does not approve or block this PR.

@david-siqi-liu
david-siqi-liu force-pushed the david/integ-test-cuj-6 branch from ab9b2a1 to dd1693e Compare October 6, 2026 01:44
@david-siqi-liu

Copy link
Copy Markdown
Collaborator Author

Re the UG review finding on .github/workflows/e2e-cuj.yml:7:

  • Added tests/integration/utils/** to the trigger in dd1693e. CUJ 6 imports its harness, terminal, evidence, and SQL helpers from there, so changes to them now run the journey.
  • Not adding src/ucode/** yet. The journey takes about 7 minutes against one dedicated workspace and runs serialized across PRs, so every product PR would queue behind it. Until [AIGTWY-4901] Only remove a Codex model ug wrote #921 lands it would also fail on Phase B for every product PR. This is worth revisiting once CUJ runs get per-run workspace allocation.

@david-siqi-liu
david-siqi-liu force-pushed the david/integ-test-cuj-6 branch from dd1693e to 0f80c82 Compare October 6, 2026 02:09
@david-siqi-liu

Copy link
Copy Markdown
Collaborator Author

Follow-up: #998 landed a shared dedicated-cuj job in integration.yml that runs all of tests/e2e_cuj, so 0f80c82 drops this PR's .github/workflows/e2e-cuj.yml entirely. The trigger-path question no longer applies to this PR.

Comment thread tests/e2e_cuj/test_cuj_repeated_config.py Outdated
Comment thread tests/e2e_cuj/test_cuj_repeated_config.py Outdated
@david-siqi-liu
david-siqi-liu force-pushed the david/integ-test-cuj-6 branch 3 times, most recently from 0dde064 to 542df38 Compare October 6, 2026 18:21
@david-siqi-liu
david-siqi-liu force-pushed the david/integ-test-cuj-6 branch from 542df38 to 547d1a1 Compare October 6, 2026 22:47
sunishsheth2009 pushed a commit to sunishsheth2009/ucode that referenced this pull request Oct 6, 2026
…atabricks#1010)

Standalone extract of the `default_model` part of databricks#921, so CUJ 6 (databricks#987)
isn't blocked on the provenance stack.

`codex.default_model()` called `clear_model_preferences` when there was
no managed default in the state it was given. `ug configure` writes
Codex's managed `model`, then `save_state` -> `hydrate_state` (without
the managed overlay) -> `default_model_for_tool` ->
`codex.default_model()` deleted it again. Codex then started on whatever
model the gateway listed first instead of the admin's default. The live
CUJ 6 run reproduced this: with a UC-location config, Codex served
`codex_extra` instead of the managed default `codex_primary`.

Changes:
- `src/ucode/agents/codex.py`: `default_model()` no longer calls
`clear_model_preferences`, so looking up the default never rewrites
config. The launch path still calls it, so a stale model ug pinned is
still retired at launch.
- `tests/test_agent_codex.py`: the test that asserted the lookup cleared
`model` and `model_reasoning_effort` now asserts it leaves the config
byte-for-byte unchanged (the same flip databricks#921 makes).

databricks#921 still carries the broader provenance-based fix. When it lands, it
supersedes this line with no conflict in intent.

Validation: `ruff check` and `ruff format --check` pass. Full `pytest`:
3201 passed; the only 2 failures are `test_e2e_user_agent`, which needs
a live gateway and also fails locally on main. The updated test fails
without the fix.

This pull request and its description were written by Isaac.

Co-authored-by: Isaac <no-reply@databricks.com>
@david-siqi-liu
david-siqi-liu force-pushed the david/integ-test-cuj-6 branch from 547d1a1 to 0a7edee Compare October 6, 2026 23:13
Comment thread src/ucode/databricks.py
Comment thread tests/e2e_cuj/helpers/constants.py Outdated
One shared home moves through three read-only workspaces (A, B, C), each with
exactly one published CodingAgentConfig, on main's dedicated-workspace CUJ
framework. Gateway requests are asserted through the TUI request recorder.

Co-authored-by: Isaac <no-reply@databricks.com>
@david-siqi-liu
david-siqi-liu force-pushed the david/integ-test-cuj-6 branch from 52a78cb to 2911d8c Compare October 7, 2026 03:41
@david-siqi-liu
david-siqi-liu added this pull request to the merge queue Oct 7, 2026
Merged via the queue into main with commit b3a42ae Oct 7, 2026
27 checks passed
@david-siqi-liu
david-siqi-liu deleted the david/integ-test-cuj-6 branch October 7, 2026 14:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

quicktree-assisted PR created with quicktree-assisted workflow ug-review Run the automated UG review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants