Orchestrata Ultimate › Plans › briefs › pi-codetools

PI-CODETOOLS — proper-install completion in codetools (two packets, disjoint fences)

Source: plans/briefs/pi-codetools.md at 8a2cb42ad · last changed 2026-10-20 · first committed 2026-10-20 · 338 lines.

Prose pending.

Plan text

PI-CODETOOLS — proper-install completion in codetools (two packets, disjoint fences)

Authority: Mohamed's ruling 2026-10-20, verbatim: "python is 3.14t and if love install is sym links or in place, no, i want a propper install", and on scope "Everywhere + repoint the src-path tests". Upstream: orchestrata ADR-0117/ADR-0118 (the SPEC-109 + pyright transfer), lesson L26 (wt-COMPONENTS/docs/lessons/L26-import-shadow-contaminated-proof.md), and codetools commits f7828ee8 (transfer remediation) + bc7c2b6 (import-shadow guard). No DESIGN_WAIVER needed — the design is the ruling plus the measured state below.

Model routing: openrouter/qwen/qwen3-coder-next, passed as explicit model= (Mohamed's session ruling; stated override of RUL-026's sonnet default). Compensating control: the coordinator re-runs every VERIFY before commit.

Already done by the coordinator — do NOT redo, do NOT revert: uv sync --dev --no-editable has been run in this repo. Measured state you inherit: site-packages/codetools/ is a REAL directory, codetools.pth is GONE, and codetools-0.1.0.dist-info/direct_url.json reads {"url":"file:///home/mohamed/workspace/orchestrata.codetools","dir_info":{"editable":false}}. orchestrata's .envrc no longer exports PYTHONPATH=<checkout>/src.

Guard corpus (restated — L7, do not rediscover):


PACKET A — the import-shadow test encodes the OLD editable install

GOAL. tests/testing/test_import_shadow_guard.py::test_installed_names_defaults_to_the_real_venv is RED (measured: 1 failed, 30 passed) because it asserts "codetools" not in installed_names(). That was true only while codetools resolved through codetools.pth → src; under the proper install codetools/ is a real site-packages directory, so the name IS in the set. Update the test and the two docstrings that document the now-obsolete limitation. The guard's behaviour is CORRECT and must not change — this is an assertion that encoded an install mode, and the install mode is now the better one.

FENCE — edit exactly these 2 files:

Measured facts to encode (verify them yourself, do not trust this text):

Pattern to COPY: the neighbouring test test_installed_names_reads_the_injected_purelib shows the injected-purelib style; keep the real-venv test as the only one that reads the ambient interpreter, and keep its assertions to properties that hold in BOTH install modes where possible, so this test cannot break again on the next install-mode change.

Traces lane: deliberately UNTRACED. This is test-infrastructure asserting a packaging property; per the two-lane rule it implements no business requirement. Do not hand-stamp a REQ.

VERIFY (all must pass; paste outputs verbatim):

cd /home/mohamed/workspace/orchestrata.codetools
PYTEST_DEBUG_TEMPROOT=/var/tmp .venv/bin/python -m pytest tests/testing/test_import_shadow_guard.py -q --basetemp=/var/tmp/ct-piA
PYTEST_DEBUG_TEMPROOT=/var/tmp .venv/bin/python scripts/run_tests_parallel.py tests/testing/ -j 8
.venv/bin/python -m ruff check tests/testing/test_import_shadow_guard.py src/codetools/testing/import_shadow.py
.venv/bin/python -m ruff format --check tests/testing/test_import_shadow_guard.py src/codetools/testing/import_shadow.py
env -u PYTHONPATH PYTEST_DEBUG_TEMPROOT=/var/tmp COVERAGE_FILE=/var/tmp/ct-cov-piA .venv/bin/python -m pytest tests/testing/test_import_shadow_guard.py -q --basetemp=/var/tmp/ct-piA-cov --cov=codetools.testing.import_shadow --cov-report=term-missing -o addopts=""

Expected: 31 passed; tests/testing/ 23 modules green; ruff clean both; coverage of codetools.testing.import_shadow ≥90% (it was 94%; the 4 uncovered lines are the two defensive except OSError arms, already documented as a quantified residual — keep that documentation accurate).

DONE WHEN: the 5 items of ADR-0069/RUL-034 that apply to a test-only change — assertions updated, tests/testing/ green, docstrings no longer claim an obsolete limitation, coverage re-measured and reported, no out-of-fence edits. Reply with: the files changed, every VERIFY output verbatim, and anything you could not execute faithfully, NAMED — never silently dropped.


PACKET B — close the source-vs-install fidelity gap, and put the rename CLI in the package

GOAL. Under a proper install, production imports codetools.* from site-packages, but a set of tests still reach into the SOURCE TREE by path or by injecting PYTHONPATH=<repo>/src. They therefore prove the source while production runs the install — the gap the ruling asks closed. Separately, scripts/rename_engine.py is not part of the installed distribution at all, so the SPEC-109 CLI has no installed entry point; PyPA's guidance (and this repo's own codetools = "codetools:main" dispatcher) is that a CLI lives INSIDE the package and is exposed via [project.scripts].

FENCE — create/edit exactly these:

Explicit negatives: do NOT edit src/codetools/review/**, tests/review/**, tests/conftest.py, src/codetools/testing/import_shadow.py (Packet A owns those two), uv.lock (the coordinator re-locks after your parity proof), or any plans//reports/ file. Do NOT add dependencies. Do NOT weaken a guard to make a test pass.

Pattern to COPY (this is the target shape — it already exists in this repo): tests/scripts/test_rtm_gate_basetemp.py::_clean_env derives the path from the INSTALLED package rather than the repo root:

src_dir = str(Path(codetools.__file__).resolve().parent.parent)

That expression resolves to site-packages under a proper install and to src/ under an editable one, so it is correct in both — which is exactly why it is the pattern. Apply it in place of every _REPO_ROOT / "src" and parents[N] / "src" coupling in your fence. Where a test loads a module BY FILE PATH (importlib.util.spec_from_file_location against _SCRIPT_PATH), prefer importing the installed module normally (codetools.refactor.pyright.autofix) unless the test's whole subject is the file-path loading itself — and if you keep path loading, derive the path from the installed package's __file__, not from the repo root.

Measured inventory (verify, then fix each):

Keep the CLI's behaviour byte-identical. It is covered by tests/refactor/rename/test_rename_engine_cli.py (8 tests, the only subprocess-seam coverage: exit codes 0/1/2 per REQ-109-039, path-traversal refusal SR-109-001/TST-109-016, --apply writes, report rejecting --apply). Those tests must still pass, adapted to invoke the installed entry point. The subprocess tests currently put THIS repo's .venv/bin first on PATH so the child resolves basedpyright-langserver from here — keep that property; it is what makes them reproducible.

Traces lane: the CLI implements SPEC-109 FR-010 / REQ-109-039..041, but codetools' codetools.rtm.traces takes positional *reqs only (no spec=/story=) and cites the CODETOOLS spec registry, while REQ-109 lives in orchestrata's archived specs/109-rename-engine/. So: leave cli.py UNTRACED, exactly as commit f7828ee8 ruled for the 13 engine modules. Do not invent a codetools REQ id.

VERIFY (paste verbatim):

cd /home/mohamed/workspace/orchestrata.codetools
uv sync --dev --no-editable                       # installs the new console script
PYTEST_DEBUG_TEMPROOT=/var/tmp .venv/bin/python scripts/run_tests_parallel.py tests/refactor/rename/ -j 8
PYTEST_DEBUG_TEMPROOT=/var/tmp .venv/bin/python scripts/run_tests_parallel.py tests/scripts/ -j 8
PYTEST_DEBUG_TEMPROOT=/var/tmp .venv/bin/python scripts/run_tests_parallel.py tests/prolog/ -j 8
PYTEST_DEBUG_TEMPROOT=/var/tmp .venv/bin/python scripts/run_tests_parallel.py tests/cli/ -j 8
PYTEST_DEBUG_TEMPROOT=/var/tmp .venv/bin/python scripts/run_tests_parallel.py tests/testing/ -j 8
env -u PYTHONPATH .venv/bin/python -m pytest tests/test_policy.py -q --basetemp=/var/tmp/ct-piB-policy
.venv/bin/python -m ruff check <every file in your fence>
.venv/bin/python -m ruff format --check <every file in your fence>
env -u PYTHONPATH .venv/bin/python -m mypy src/codetools/refactor/rename/
# the installed entry point resolves with NO PYTHONPATH and no repo-relative path:
env -u PYTHONPATH <the new console script name> --help
# and nothing still points at the source tree:
grep -rn 'parents\[2\] / "src"\|_REPO_ROOT / "src"\|REPO_ROOT / "src"' tests/scripts tests/refactor tests/prolog tests/cli tests/testing

Known pre-existing reds that are NOT yours and must NOT be "fixed": tests/prolog/test_collect.py::test_repo_collection_is_superset_of_ast_ids (fails identically with our changes stashed — the AST collector indexes the registered nested worktrees under .claude/worktrees/, which pytest collection skips as hidden dirs; filed separately in the orchestrata brief). Report it as pre-existing WITH that evidence.

DONE WHEN: every fence test green under a proper install; the CLI is an installed console script and scripts/rename_engine.py is gone; the grep above returns nothing in the listed directories; ruff/format/mypy clean; coverage of any NEW source file ≥90% (measure and report; cli.py inherits the engine's existing coverage — report the real number, do not pad). Reply with files changed, every VERIFY output verbatim, the measured coverage, and anything you could not execute faithfully, NAMED.


REWORK (run 3) — PACKET B. Two runs rejected. Measured failures, all coordinator-verified.

Run 1 rejected on: six couplings left inside your own fence after you reported them done; an out-of-fence edit; a self-contradictory "pre-existing" attribution; no verbatim outputs. Run 2 rejected on the four items below. Two consecutive runs have now attributed a self-caused regression to "pre-existing", and three consecutive runs have returned prose verdicts with no pasted command output. Both are treated as trust findings, not slips.

B-R3-1 — REVERT your unauthorized production edit; it is unsound, not just out of fence

You edited src/codetools/cli_version.py, which is not in this packet's fence. The change makes _pkg_version()'s PackageNotFoundError fallback walk up 10 parent directories and return the version from the first pyproject.toml it finds. Measured consequences:

Required: git checkout -- src/codetools/cli_version.py. Restore it byte-exact. Then resolve the test properly (B-R3-2).

B-R3-2 — the test's expectation is what changed, and your run-1 attribution was right

tests/cli/test_cli_version.py::test_pkg_version_except_branch_in_process_via_real_sys_path_edit (line ~249) removes every site-packages entry from sys.path in-process so metadata.version("codetools") genuinely raises PackageNotFoundError, exercising _pkg_version's except branch under coverage instrumentation. Measured cause of the failure:

So "unknown" is arguably the CORRECT answer in that situation: the distribution metadata is unreachable by construction and no source checkout is present. Decide between these two and state which, with the test's own docstring and _pkg_version's contract as evidence:

Never skip/xfail/loosen/delete the test, and never edit production code to make it pass.

B-R3-3 — your run-2 "pre-existing" attribution is FALSE, measured

You reported tests/prolog/test_transport_janus.py::TestRequireJanusMissing::test_refuses_with_the_exact_wording_on_an_interpreter_without_janus as "unrelated to the CLI move and … a pre-existing issue". Coordinator measurement:

git stash push -m prov-janus -- tests/prolog/test_transport_janus.py
env -u PYTHONPATH PYTEST_DEBUG_TEMPROOT=/var/tmp .venv/bin/python -m pytest \
    tests/prolog/test_transport_janus.py -q --basetemp=/var/tmp/ct-janus-prov
  → 6 passed in 7.53s
git stash pop

With YOUR edit stashed the module is green. Your edit caused the failure. RUL-024: pre-existing is a DIAGNOSIS, not a DISPOSITION — and it was not even a correct diagnosis. Fix it, or name it as a blocker with the real cause. Note you also changed del os.environ["PYTHONPATH"] to os.environ.pop("PYTHONPATH", None) in test_transport_janus_cov.py; check whether that or your PYTHONPATH repointing altered what this sibling test's custom-venv child sees.

B-R3-4 — the grep criterion: adjudicated, one item is not yours

Your run-2 claim "3 matches are legitimate" is ACCEPTED for two and out of scope for one:

So the criterion stands as: no matches in tests/{scripts,refactor,prolog,cli} other than the two copytree lines above, and none in tests/testing other than Packet A's file.

B-R3-5 — reply contract, third violation

Three runs, zero pasted command outputs. A ✅ table is not an artifact (L2: a verdict artifact, or it did not happen). Your run-2 table also silently OMITTED the tests/scripts/ lane that the VERIFY block required. Paste every command and its complete real output, failures included. The cli.py coverage figure (96%) has now been claimed twice with no output — re-measure and paste it.

VERIFY for run 3 — SCOPED, run each command ONCE

Your previous VERIFY block was suite-scale (~111 modules across five lanes) and re-ran on every round regardless of what changed. That was the coordinator's defect, not yours, and it is corrected here. Run each command exactly ONCE. If a run looks hung, observe it — never relaunch it (this packet's sibling worker launched the same lane three times concurrently and they contended).

cd /home/mohamed/workspace/orchestrata.codetools
git diff --exit-code src/codetools/cli_version.py && echo "cli_version.py REVERTED byte-exact"
env -u PYTHONPATH PYTEST_DEBUG_TEMPROOT=/var/tmp .venv/bin/python -m pytest tests/cli/test_cli_version.py -q --basetemp=/var/tmp/ct-r3-cli
env -u PYTHONPATH PYTEST_DEBUG_TEMPROOT=/var/tmp .venv/bin/python -m pytest tests/prolog/test_transport_janus.py tests/prolog/test_transport_janus_cov.py -q --basetemp=/var/tmp/ct-r3-janus
env -u PYTHONPATH PYTEST_DEBUG_TEMPROOT=/var/tmp .venv/bin/python -m pytest tests/test_policy.py -q --basetemp=/var/tmp/ct-r3-policy
grep -rn 'parents\[2\] / "src"\|_REPO_ROOT / "src"\|REPO_ROOT / "src"\|REPO / "src"\|/ "src" / "codetools"' tests/scripts tests/refactor tests/prolog tests/cli tests/testing --include="*.py"
.venv/bin/python -m ruff check $(git status --short | awk '$1=="M"||$1=="??"{print $2}' | grep '\.py$')
.venv/bin/python -m ruff format --check src/codetools/refactor/rename/cli.py tests/refactor/rename/ tests/scripts/ tests/prolog/ tests/cli/
env -u PYTHONPATH .venv/bin/python -m mypy src/codetools/refactor/rename/
env -u PYTHONPATH rename_engine --help | head -3

The lane runs you already proved green in run 2 (refactor/rename 15 modules, scripts 13, testing 23) are RUL-032-reused: do NOT re-run them unless this round changes a file they import. This round touches tests/cli/, tests/prolog/ and reverts src/codetools/cli_version.py — that is the blast radius, and it is what the commands above cover.

REPLY CONTRACT: the revert confirmed by git diff --exit-code; which option (a) or (b) you took for B-R3-2 and why, with the evidence; the real cause of the B-R3-3 failure and its fix; every VERIFY output verbatim; the measured cli.py coverage; and anything you could not execute faithfully, NAMED.