Skip to content

[Bug]: native Windows Codex App settlement plans emit a POSIX-only Turn reference #7808

Open

Description

@JasonBuildAI

Preflight

  • I searched existing issues and discussions for this behavior.
  • This report is not an unpatched security vulnerability.
  • The report and attachments contain no credentials or private/internal material.

Issue origin

Observed or reproduced in a real environment.

LoopX version or commit

70f643153ea773b7bc1ef71bdb06095b0744bd6d (current upstream main).

Host or runtime surface

Codex App on native Windows with PowerShell 7 or Windows PowerShell 5.1.

LoopX area

Control plane (goals, todos, quota, scheduler, registry, runtime).

Problem

Impact: Native Windows Codex App admission without an explicit Turn returns a machine-readable settlement plan whose validation, writeback, spend, and terminal-closeout commands bind --turn-instance-id "${LOOPX_TURN:?}". PowerShell does not implement POSIX ${name:?} expansion, so it passes an empty argument even when $LOOPX_TURN is set; the CLI rejects that command with QUOTA_VALIDATION_FAILED. The returned closeout/recovery recipe therefore cannot settle the same Windows host that produced it without manual command rewriting.

This affects the documented no-Turn Codex App path (quota should-run --codex-app) and every generated settlement step from that plan. It is generated deterministically on each affected request, not an intermittent shell error. The native Windows path is a supported product surface and has a required windows-powershell CI lane. This is the same host-runnable-command contract repaired for onboarding and heartbeat bootstrap in #7158 / #7160: loopx/project_prompt.py already renders the heartbeat Turn argument as $LOOPX_TURN on native Windows, but the settlement-plan owner was not included.

Minimal reproduction

On native Windows at 70f643153, the pure plan builder emits the broken reference:

uv run --extra test python -c "from loopx.control_plane.quota.effect_program import build_codex_app_settlement_plan as b; p=b(goal_id='goal', agent_id='agent', todo_id='todo', scoped_cli_args='', lifecycle_actor_args=''); print(p.as_dict()['identity']['turn_instance_id']); print(next(s['command_template'] for s in p.as_dict()['ordered_steps'] if s.get('command_template') and 'spend-slot' in s['command_template']))"

It prints ${LOOPX_TURN:?} as the identity and inside the quota spend-slot command. The shell behavior is independently reproducible:

$LOOPX_TURN = 'turn-repro-1'
python -c "import sys; print(sys.argv[1:])" "${LOOPX_TURN:?}"

Observed: ['']. Expected: $LOOPX_TURN is forwarded as turn-repro-1.

Feeding the emptied Turn through the real quota spend-slot command returns rc 1:

error_code: QUOTA_VALIDATION_FAILED
reason: turn_instance_id must be 1-128 public-safe letters, numbers, or ._:-
state: blocked_validation

Expected behavior

A settlement plan produced on native Windows should emit PowerShell-runnable commands, using $LOOPX_TURN (and an explicit missing-value guard if required), while POSIX hosts retain the existing "${LOOPX_TURN:?}" output byte-for-byte. The returned validation/writeback/spend/closeout commands should forward the concrete Turn selected by the host rather than an empty value.

Actual behavior

The plan identity and generated commands keep the POSIX-only reference on native Windows. PowerShell treats it as an unknown variable reference and forwards an empty Turn, so the first settlement command that validates the identity fails and the remaining writeback/spend/closeout steps cannot run.

Additional context

Activity

  1. added
    bugSomething isn't working
    triageNeeds maintainer triage or routing.
    on Nov 1, 2026
  2. added a commit that references this issue on Nov 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingtriageNeeds maintainer triage or routing.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions