Skip to content

[codex] Fix Codex provider default and app-status busy turns - #589

Merged
100yenadmin merged 6 commits into
mainfrom
codex/worldos-codex-provider-model-default
Jun 2, 2026
Merged

[codex] Fix Codex provider default and app-status busy turns#589
100yenadmin merged 6 commits into
mainfrom
codex/worldos-codex-provider-model-default

Conversation

@100yenadmin

@100yenadmin 100yenadmin commented Jun 2, 2026

Copy link
Copy Markdown
Member

Summary

  • Default the Codex provider scripts to the current model unless explicitly set to auto/CLI default.
  • Keep /openworlds/ deep links attached to live campaigns when the route uses either catalog id shape.
  • Make /app-status reflect a pending player move as busy instead of reporting the app as playable while the DM turn is still resolving.
  • Keep the handoff driver polling through transient /app-status timeouts so slow provider turns are classified as narration progress/failure rather than immediate provider failure.

Product Impact

  • Browser-first app iteration gets a more honest live-read model: agents can tell the difference between an actionable table and a table waiting on DM narration.
  • Fresh-player table sessions keep private art, visible narration, enabled actions, and /move evidence connected on the same build.
  • The GUI remains a reader plus /move intent submitter; no engine campaign-state write authority moves into the viewer.

Validation

  • python3 -m pytest viewer/tests/test_openworlds_static.py -q
  • python3 -m pytest qa/test_app_handoff_gate.py qa/test_macos_app_static.py -q
  • uv run --directory servers/engine --group dev pytest tests/test_codex_provider_wrapper.py -q -p no:xdist
  • bash -n scripts/play_codex_dm.sh scripts/play_codex_actor.sh
  • Local browser-scripted smoke on this branch: web gate passed with private art present, two moves resolved, zero evidence gaps, and intentionally skipped native gates. This is not a release verdict.

Notes

  • Evidence artifacts and private screenshots are retained outside the public repository.
  • Full built-app handoff and five-persona RRI remain required before release consideration.

Summary by CodeRabbit

  • New Features

    • App status now reports pending player turns and shows effective action availability.
  • Improvements

    • More resilient status polling that records transient probe errors without aborting.
    • Better campaign matching so active/requested campaigns are tracked reliably.
    • Codex model selection defaults pinned to a supported model (gpt-5.5) and help text clarified.
  • Bug Fixes

    • Handoff gates now surface evidence-manifest blockers and update evidence-gap reporting.
  • Tests

    • Expanded tests for timeout handling, handoff evidence, and model-selection behavior.

@coderabbitai

coderabbitai Bot commented Jun 2, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@100yenadmin, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 9 minutes and 18 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 2bfcf963-f7fc-47cc-9c7a-49cff004210a

📥 Commits

Reviewing files that changed from the base of the PR and between 47d932a and 08c3ad5.

📒 Files selected for processing (6)
  • qa/app_handoff_gate.py
  • qa/app_smoke_scripted.py
  • qa/test_app_handoff_gate.py
  • qa/test_macos_app_static.py
  • scripts/play_codex_dm.sh
  • servers/engine/tests/test_codex_provider_wrapper.py
📝 Walkthrough

Walkthrough

This PR pins Codex defaults to gpt-5.5 and updates tests; broadens campaign matching to id or campaign_id; derives pending-player-turn from chat logs to gate /app-status actions; and makes QA handoff gating resilient to transient /app-status errors while adding evidence-manifest blocker handling.

Changes

Codex Model Default Pinning

Layer / File(s) Summary
Help text and documentation
scripts/play_codex_actor.sh, scripts/play_codex_dm.sh
Updated --help output documents WORLDOS_CODEX_MODEL default gpt-5.5 and retains CLAWDND_CODEX_MODEL as legacy fallback.
Model selection and argument construction
scripts/play_codex_actor.sh, scripts/play_codex_dm.sh
Both scripts compute CODEX_MODEL from WORLDOS_CODEX_MODELCLAWDND_CODEX_MODELgpt-5.5 and add --model unless the value is auto, default, or cli-default (case-insensitive).
Contract tests for model pinning and delegation
qa/test_macos_app_static.py, servers/engine/tests/test_codex_provider_wrapper.py
Tests updated: fake Codex must receive --model gpt-5.5 in the pinning test; new test validates delegation to CLI-default when WORLDOS_CODEX_MODEL="auto".

Campaign Matching Enhancement

Layer / File(s) Summary
Campaign matcher helper and live-session integration
viewer/openworlds/app.jsx
New openWorldsCampaignMatches(c, campaignRef) matches when c.id === campaignRef or c.campaign_id === campaignRef; useLiveSession activeCampaign selection uses the matcher.
Campaign catalog loading with matcher
viewer/openworlds/app.jsx
loadCampaignCatalog uses matcher to compute requestedEntry/requestedStillExists and requestedActiveId, and prefers requestedActiveId when assigning activeCampaign.
Rendered current campaign selection
viewer/openworlds/app.jsx
TitleBar current campaign selection uses openWorldsCampaignMatches instead of id-only equality.
Test assertions for campaign matching
viewer/tests/test_openworlds_static.py
Static-route tests updated to require openWorldsCampaignMatches usage and verify requestedActiveId/requestedStillExists logic and broadened campaign reference comparison.

App Status Pending Player Turn Detection

Layer / File(s) Summary
Chat file summary and readiness logic
viewer/server.py
Added _chat_file_summary() to parse chat JSONL and extract last_chat_role and pending_player_turn; _app_status_readiness extended to accept pending_player_turn and compute surface_can_act.
Effective action gating and payload shape
viewer/server.py
When pending_player_turn is true, effective can_act is cleared and enabled actions become empty; /app-status now includes viewer.last_chat_role, live.surface_can_act, and live.pending_player_turn.
Tests and environment setup for pending-turn detection
viewer/tests/test_openworlds_static.py
Test setup preserves/restores WORLDOS_PROVIDER and CLAWDND_PROVIDER; new test validates /app-status reports busy readiness and pending_player_turn when last chat row is player-authored.

App Status Error Resilience & QA Handoff Gate

Layer / File(s) Summary
Evidence manifest blockers and gate failures
qa/app_handoff_gate.py
Added evidence_manifest_blockers(payload) and use it in run_web_scripted() and run_native_provider_gate() to fail passing gates when the manifest reports handoff blockers; gate.evidence_gaps updated from manifest when present.
Error capture and logging in drive_moves
qa/app_handoff_gate.py
drive_moves now captures last_status_error from smoke.wait_for_status exceptions, appends a failed GET /app-status entry (with the error string) to network.ndjson, and continues polling; no_narration failure detail includes the last status error when available.
Unit tests for manifest blockers and transient timeouts
qa/test_app_handoff_gate.py
Added tests asserting evidence_manifest_blockers includes handoff_gate.blocking_reasons; run_web_scripted fails on smoke evidence gaps with propagated evidence_gaps; drive_moves tolerates a transient TimeoutError("busy status probe") and logs it.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 Hop and hum, the gates align,
Codex picks its fav'rite line.
Campaigns match by id or name,
App-status learns the player's claim.
Tests hop through timeouts — all is fine.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.41% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the two main changes: Codex provider default model handling and app-status busy turn reporting for pending player moves.
Description check ✅ Passed The PR description includes a clear summary of changes, product impact, comprehensive validation steps, and licensing/CLA acknowledgment as required by the template.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@100yenadmin
100yenadmin marked this pull request as ready for review June 2, 2026 21:28
@100yenadmin

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 2, 2026

Copy link
Copy Markdown
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
scripts/play_codex_actor.sh (1)

200-210: ⚡ Quick win

gpt-5.5 pin matches Codex’s supported ChatGPT-auth model (repo tests expect --model gpt-5.5)

The main risk flagged (that codex exec --model gpt-5.5 would reject the slug) doesn’t apply: OpenAI’s Codex model list includes gpt-5.5, and servers/engine/tests/test_codex_provider_wrapper.py::test_codex_dm_wrapper_run_pins_supported_default_model_with_fake_codex asserts the wrapper invokes Codex with --model gpt-5.5 when using the default/auto path. The duplication across scripts/play_codex_actor.sh and scripts/play_codex_dm.sh (both defaulting to ...:-gpt-5.5) is also intentional and covered by static QA assertions.

Optional: if older Codex CLI versions ever fail to recognize gpt-5.5, consider falling back to auto/default/cli-default (or emitting a clearer error) instead of hard-failing all MODE=run runs.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/play_codex_actor.sh` around lines 200 - 210, The default model
selection currently pins CODEX_MODEL to "gpt-5.5" and sets MODEL_ARGS
accordingly; keep that pin (matching tests expecting --model gpt-5.5) and
explicitly document it in the header comment, and optionally add a silent
fallback path that translates unsupported CLI-model errors into using the
empty/auto/default branch (e.g., detect unrecognized model and unset CODEX_MODEL
so MODEL_ARGS stays empty) to avoid hard-failing MODE=run; update
scripts/play_codex_actor.sh (and mirror in scripts/play_codex_dm.sh) to
implement the fallback and add a short comment referencing CODEX_MODEL and
MODEL_ARGS so the behavior is clear to readers and test authors.
qa/test_app_handoff_gate.py (1)

246-318: ⚡ Quick win

Consider explicitly asserting detail is empty.

The review context states the test "asserts ok/bucket/detail output," but currently only ok and bucket are explicitly verified. While the assertTrue(ok, detail) pattern is good for debugging (it shows detail if the assertion fails), it doesn't verify detail's value when ok is True.

✨ Suggested addition
 self.assertTrue(ok, detail)
 self.assertEqual(bucket, "")
+self.assertEqual(detail, "")
 self.assertIn("busy status probe", network)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@qa/test_app_handoff_gate.py` around lines 246 - 318, Add an explicit
assertion that the returned detail is empty in
test_drive_moves_tolerates_transient_app_status_timeout: after the existing
assertions on ok and bucket, assert that detail == "" (or use an appropriate
empty-check) so the test verifies the detail value rather than only using it as
the assertTrue message; reference the local variables detail and ok in the test
to locate where to insert this assertion.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@viewer/server.py`:
- Around line 5425-5433: The loop that reads lines from
Path(path).read_text(...) counts lines before parsing and treats
json.JSONDecodeError as a malformed record; move the JSON parsing ahead of
incrementing summary["line_count"] so you only increment when json.loads(line)
succeeds, and on JSONDecodeError treat the line as an incomplete trailing row
(skip without incrementing or marking narration/chat present). Update the block
that sets payload and summary["line_count"] (referencing variables payload and
summary["line_count"]) so counting happens after isinstance(payload, dict) /
successful parse.

---

Nitpick comments:
In `@qa/test_app_handoff_gate.py`:
- Around line 246-318: Add an explicit assertion that the returned detail is
empty in test_drive_moves_tolerates_transient_app_status_timeout: after the
existing assertions on ok and bucket, assert that detail == "" (or use an
appropriate empty-check) so the test verifies the detail value rather than only
using it as the assertTrue message; reference the local variables detail and ok
in the test to locate where to insert this assertion.

In `@scripts/play_codex_actor.sh`:
- Around line 200-210: The default model selection currently pins CODEX_MODEL to
"gpt-5.5" and sets MODEL_ARGS accordingly; keep that pin (matching tests
expecting --model gpt-5.5) and explicitly document it in the header comment, and
optionally add a silent fallback path that translates unsupported CLI-model
errors into using the empty/auto/default branch (e.g., detect unrecognized model
and unset CODEX_MODEL so MODEL_ARGS stays empty) to avoid hard-failing MODE=run;
update scripts/play_codex_actor.sh (and mirror in scripts/play_codex_dm.sh) to
implement the fallback and add a short comment referencing CODEX_MODEL and
MODEL_ARGS so the behavior is clear to readers and test authors.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: bb1f6eae-dc84-452d-9d95-258ec9834007

📥 Commits

Reviewing files that changed from the base of the PR and between 3031c19 and 59d2ca5.

📒 Files selected for processing (9)
  • qa/app_handoff_gate.py
  • qa/test_app_handoff_gate.py
  • qa/test_macos_app_static.py
  • scripts/play_codex_actor.sh
  • scripts/play_codex_dm.sh
  • servers/engine/tests/test_codex_provider_wrapper.py
  • viewer/openworlds/app.jsx
  • viewer/server.py
  • viewer/tests/test_openworlds_static.py

Comment thread viewer/server.py
@100yenadmin
100yenadmin merged commit 1441484 into main Jun 2, 2026
15 checks passed
@100yenadmin
100yenadmin deleted the codex/worldos-codex-provider-model-default branch June 2, 2026 22:15
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.

1 participant