Skip to content

refactor(turn): bind the advisory primary through the shared decision owner - #4450

Merged
huangruiteng merged 1 commit into
mainfrom
codex/turn-command-owner-extraction-20260915
Sep 15, 2026
Merged

huangruiteng merged 1 commit into
mainfrom
codex/turn-command-owner-extraction-20260915

Conversation

@huangruiteng

Copy link
Copy Markdown
Collaborator

Problem

main is red on full-public-smokes:

AssertionError: turn.py has 1123 lines, above budget 1114; extract a cohesive command owner before adding more code

The managed Turn host-selection wiring took loopx/cli_commands/turn.py from 1094 to 1123 lines against a frozen baseline of 1114, and the ratchet smoke (examples/cli-command-module-size-ownership-command-modularization-smoke.py) correctly rejects that.

While finding a cohesive extraction, the underlying duplication was the right thing to fix: turn.py reimplemented the controller advisory-primary rebinding inline, and loopx/cli_commands/turn_decision.py::apply_controller_advisory_primary already owns that exact rule for managed-step. Its own docstring states the intent:

run-once and managed-step must agree on what "the current governing decision" means: read the same live status, apply the same controller advisory primary, and sign the same loopx_turn_envelope_v0. Duplicating that chain would let the two drift, so both owners build through this module.

The two copies had to stay step-identical by inspection: resolve the advisory primary, re-resolve the decision with it requested, fail closed when it is no longer eligible, record selected_by, and keep the advisory portfolio on the decision.

Change

turn.py calls the shared owner instead of repeating the rule:

decision = apply_controller_advisory_primary(build_turn_decision)

No behavior change. turn.py is back to 1111 lines, under its 1114 baseline, and the fail-closed rule now has exactly one home so the two Turn subcommands cannot drift.

Evidence

  • python examples/cli-command-module-size-ownership-command-modularization-smoke.py → ok (this is the red check).
  • pytest tests/test_loopx_turn_driver.py tests/test_loopx_turn_managed_step.py tests/test_turn_default_host_binding.py -q → 109 passed. This includes test_turn_cli_binds_advisory_primary_without_hiding_portfolio, which drives the CLI end-to-end and asserts both selected_by == "turn_controller_advisory_primary" and that the advisory portfolio stays on the envelope — i.e. the behavior this refactor moves.
  • pytest tests/test_loopx_turn_driver.py -k advisory_primary -q → 1 passed.
  • ruff check loopx/cli_commands/turn.py → clean.
  • loopx canary premerge --from-git-diff → merge_gate_passed: true, self_merge_allowed: true; 4 catalog canaries including the maintainability ratchet and CLI output-budget smokes passed.

Boundary

loopx/cli_commands/turn.py only, +5/-17. No new module, no new surface, no budget number was raised or lowered.

… owner

`run-once` duplicated the controller advisory-primary rebinding that
`turn_decision.apply_controller_advisory_primary` already owns for
`managed-step`. The two copies had to stay step-identical by inspection:
resolve the advisory primary, re-resolve the decision with it requested, fail
closed when it is no longer eligible, record selected_by, and keep the
advisory portfolio on the decision.

Call the shared owner instead. Behavior is unchanged; the fail-closed rule now
has one home, so the two Turn subcommands cannot drift.

This also brings loopx/cli_commands/turn.py back under its frozen size
baseline: the managed host-selection wiring took it to 1123 lines against a
budget of 1114, which left full-public-smokes red on main.

Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
@huangruiteng
huangruiteng merged commit a0b5bcb into main Sep 15, 2026
20 checks passed
@huangruiteng
huangruiteng deleted the codex/turn-command-owner-extraction-20260915 branch September 15, 2026 11:58

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Approval conclusion (author-owned PR; GitHub blocks formal self-approval).

Exact head reviewed: a1213edce

Verdict: APPROVE. One file, +5/-17, no user-visible surface, no new module, no behavior change.

What I verified

  • The red check is real and reproduced: python examples/cli-command-module-size-ownership-command-modularization-smoke.py fails on latest main with turn.py has 1123 lines, above budget 1114. The regression is mine — 3f916ff38 (#4443) took turn.py from 1094 to 1123 against a frozen baseline of 1114 that was already in place at 3f916ff38^.
  • The extraction is not invented for the gate. turn_decision.apply_controller_advisory_primary already owns this exact rule and turn.py reimplemented it inline, step for step: resolve the advisory primary, re-resolve with it requested, fail closed when it is no longer eligible, set selected_by, keep the advisory portfolio. turn_decision.py's own docstring says both Turn subcommands must build through it so they cannot drift. This is duplicate knowledge being collapsed, which is the refactor the size gate is asking for.
  • Call counts are unchanged: both the removed inline version and the shared function call the builder once, and a second time only when an advisory primary was returned.
  • Behavior is pinned by an existing end-to-end test, not by inspection: tests/test_loopx_turn_driver.py::test_turn_cli_binds_advisory_primary_without_hiding_portfolio drives the CLI and asserts both selected_by == "turn_controller_advisory_primary" and that the advisory portfolio survives onto the envelope. It passes.
  • pytest tests/test_loopx_turn_driver.py tests/test_loopx_turn_managed_step.py tests/test_turn_default_host_binding.py -q → 109 passed.
  • ruff check loopx/cli_commands/turn.py → clean. py_compile → clean.
  • The ratchet smoke is green at the new head (1111 ≤ 1114).
  • loopx canary premerge --from-git-diff → merge_gate_passed: true, self_merge_allowed: true; 4 catalog canaries passed including the maintainability ratchet and CLI output-budget smokes.
  • docs/reference/protocols/turn-envelope-v0.md documents selected_by=turn_controller_advisory_primary; that value is unchanged.

Boundary: loopx/cli_commands/turn.py only. No budget number was raised or lowered, so the ratchet keeps its existing meaning. No frontend, Lark, or CLI entry point changes, so there is no user-visible surface to read back.

Residual risk: none identified for this diff. full-public-smokes shard 0 on main has two further, unrelated failures that pre-date this branch — cli-help-manpage-smoke (unclassified: ['goal-actions']) and canary-promotion-readiness-smoke (nested install-local-smoke.py exits 1 in CI, while it passes locally on a clean latest-main worktree). Neither is touched here and neither is caused by this change.

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