Repository navigation
[Bug]: required Python Tests gate is red on main after #6703 added a 146th top-level module #6728
Description
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
f9bdae67596c185cebc81dc555dd6a3e0242e9c5 (current main)
Host or runtime surface
Not host-specific
LoopX area
Build, packaging, installer, or CI
Problem
The required Python Tests pytest job is deterministically red on current main, so merge-gate cannot pass for any PR without a maintainer bypass.
tests/architecture/test_top_level_module_budget.py pins 145 top-level modules under loopx/. PR #6703 (fix(lark): wake existing reply workers when durable work arrives, merged 2026-10-17T03:39:35Z as dc3feb5ce) added loopx/chat_turn_release.py; that module has exactly one importer, loopx/chat_runtime.py. The PR did not move another module below a package root and did not record a design decision for a new top-level module, so the count is now 146 against the 145 pin.
This is not the older #5685 measurement (150 vs 147, a different set of chat_* modules that is no longer reproducible). It is a new overflow introduced by #6703. #5685's last comment says that if the count rises again on main, the PR that pushed it over is the place to fix it; #6703 is merged, so this issue tracks that follow-up.
Who is harmed and how much. Every PR whose Python Tests run inherits this failure (docs- and presentation-only PRs that skip the Python Tests workflow are unaffected). The full suite is collected into six pytest shards in .github/workflows/python-tests.yml; one failing test fails its shard, the shard job fails pytest, and merge-gate stays red. At the time of writing there are 30 open PRs, and each new push or rebase gets the same unrelated red check. Contributors must diff failure sets against a clean baseline to prove their change is not the cause, and maintainers can no longer tell an inherited failure from a real regression in a PR. The gate's stated purpose — making top-level growth visible instead of silently inherited — is itself defeated while the test is red on main.
Minimal reproduction
From a clean checkout of f9bdae67596c185cebc81dc555dd6a3e0242e9c5:
git rev-parse HEAD
# f9bdae67596c185cebc81dc555dd6a3e0242e9c5
git ls-tree --name-only HEAD loopx/ | grep -E '^loopx/[^/]+\.py$' | wc -l
# 146
python -m pytest -q tests/architecture/test_top_level_module_budget.pyObserved:
1 failed, 5 passed
E AssertionError: loopx/ grew from 145 to 146 top-level modules; the RFC only
allows a move into a subpackage, and new top-level modules need a recorded
design decision first.
E assert not ['workflow_skill_install.py']
The printed offender is the lexical diagnostic artifact documented in #5685; the real delta is loopx/chat_turn_release.py:
git ls-tree --name-only fdf03ec6112aedf497b7ab1d6e5bc4db19c2ae5f loopx/ | grep -E '^loopx/[^/]+\.py$' | wc -l # 145 (parent)
git ls-tree --name-only dc3feb5ce85a0b4bd8879b8b7be465bbd6cdf5b6 loopx/ | grep -E '^loopx/[^/]+\.py$' | wc -l # 146
git log --diff-filter=A --format='%h %s' -1 f9bdae675 -- loopx/chat_turn_release.py
# dc3feb5ce fix(lark): wake existing delivery workers on durable workExpected behavior
tests/architecture/test_top_level_module_budget.py passes on main, so pytest/merge-gate can report the PR's own failures only, and the top-level count stays at the pinned budget.
Actual behavior
The pinned budget test fails on unmodified main, so every PR's required pytest shard fails with a change-unrelated error.
PR #6703's own pytest job was cancelled before completion (gh pr checks 6703 shows pytest COMPLETED CANCELLED), so the new module never ran the gate before merge.
Sanitized diagnostics
$ python -m pytest -q tests/architecture/test_top_level_module_budget.py
FAILED tests/architecture/test_top_level_module_budget.py::test_top_level_module_count_stays_at_the_pinned_budget
1 failed, 5 passed in 1.63s
The failure is deterministic and independent of the host (only loopx/*.py names and the JSON pin are read).
Additional context
The module is a 30-line private helper (TurnReleaseWakeup) whose only importer is loopx/chat_runtime.py (from .chat_turn_release import TurnReleaseWakeup), and it has no other code, test, example or doc reference. The narrow fix is to move the helper below a package root, which lowers the count back to the pin without changing runtime behavior; no compatibility shim is needed because the module was introduced in #6703 and has no external callers. The repair PR places it in the existing loopx/capabilities/native_chat/ package that chat_runtime.py already imports for its native-chat companions. Inlining it into loopx/chat_runtime.py is not available: that module is already one line under its reviewed 2210-line ceiling in loopx/canary/module_metric_baseline.json, and the maintainability ratchet rejects the growth.
Related: #5685 (earlier overflow of the same gate, no longer reproducible), #6703 (introduced this one), #5191 (added the gate), docs/architecture/rfcs/monorepo-distribution-split-v0.md M0/Section 9.
Activity
coordination: agent-w3n8 backfill issue loopx-project#6728 and PR loo…
fix(architecture): move the turn-release wakeup under native_chat