fix(PS-140): scope the cross-package gate's skip to the ROOT so a rename can fail it - #369
Open
ywatanabe1989 wants to merge 1 commit into
Open
fix(PS-140): scope the cross-package gate's skip to the ROOT so a rename can fail it#369ywatanabe1989 wants to merge 1 commit into
ywatanabe1989 wants to merge 1 commit into
Conversation
…ame can fail it
The gate could not fail. Its helper caught ModuleNotFoundError from the FULL
dotted path and skipped on it, but a renamed or moved submodule raises exactly
that exception -- so the one failure the gate exists to catch was swallowed and
the run reported green. The file's own docstring promised the opposite
("Renames or moves ... surface as a hard failure here"), and the two cases it
undertook to distinguish were indistinguishable to it.
An absent peer and a rename inside an installed peer raise the same exception
type. They are separable by SCOPE, not by type: skip when the ROOT distribution
is not installed, hard-import the FULL path. Dropping the skip altogether would
be the opposite pole of the same bug -- a lean install where a peer is
legitimately absent (optional extra, marker-gated dep) would fail, giving a gate
that cannot PASS in place of one that cannot FAIL.
Both control arms, one run, bogus entry "scitex_io._this_module_does_not_exist"
injected into each helper:
old helper -> SKIPPED "not importable in this environment
(auto-gen snapshot drift / optional peer absent)"
new helper -> FAILED ModuleNotFoundError: No module named
'scitex_io._this_module_does_not_exist'
Removing the bogus entry returns the gate to green.
The umbrella needs one further absence recognised, and it does not widen the
hole: `scitex.<x>` forwards to a separate `scitex_<x>` distribution, so
`import scitex.io` fails naming `scitex_io` while the root `scitex` is present.
That is skipped only when the missing name is a DIFFERENT top-level
distribution with no importable spec -- a missing submodule of an installed
distribution never matches, which is what keeps a rename loud.
Two consequences of the gate coming alive:
- 31 declared entries were stale snapshot rows, pruned. None appears anywhere
in src/: `src/scitex/` has no `bridge`, `_dev/` holds only `__init__.py`, and
`gen` is a module (gen.py) so `scitex.gen._x` can never be a submodule.
- 4 entries are a real, live defect and are recorded as strict xfails rather
than skipped away: src/scitex imports scitex_dev.{docs,search,skills,types}
from cli/docs.py, cli/skills.py, cli/mcp.py, _mcp/__init__.py and
_mcp/_umbrella_tools.py, and the pinned scitex-dev==0.28.0 ships none of them
-- `git ls-tree v0.28.0 src/scitex_dev/` lists `_docs` and `_skills` only.
This is not a local version skew. `_show_list` in cli/docs.py imports
unguarded, so it raises at runtime. Where the symbols moved is not
unambiguous (scitex_dev._docs exports none of get_docs/build_docs/
search_docs), so the import sites are left to a separate change rather than
guessed at; strict=True means the gate fails the day they are fixed until the
record is deleted.
Readings on tests/integration/test_cross_package_imports.py:
before 110 passed, 84 skipped
after 110 passed, 49 skipped, 4 xfailed
Same 110 passing. The 35 skips that disappeared were the gate's blind spot.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The defect: a gate that cannot fail
tests/integration/test_cross_package_imports.pypromised, in its own docstring:It did the opposite. Its helper caught
ModuleNotFoundErrorraised by importingthe full dotted path and skipped on it:
A renamed or moved submodule —
scitex_io._load_cache→scitex_io._loading._load_cache, the incident this file was written for —raises exactly that exception. So the one failure the gate exists to catch was
swallowed and the run reported green. An absent peer and a rename inside an
installed peer raise the same exception type, and the old code could not tell
them apart, so it treated every rename as an absence.
The fix: skip on the ROOT, hard-import the FULL path
The two cases are separable by scope, not by exception type:
extra, marker-gated dependency, lean install). Skip.
Fail. That is the gate.
Simply dropping the skip would be the opposite pole of the same bug: a lean
install where a peer is legitimately absent would fail — a gate that cannot
PASS in place of one that cannot FAIL.
The umbrella needs one further absence recognised, and it does not widen the
hole:
scitex.<x>forwards to a separatescitex_<x>distribution, soimport scitex.iofails namingscitex_iowhile the rootscitexis present.That is skipped only when the missing name is a different top-level
distribution with no importable spec at all. A missing submodule of an
installed distribution never matches it, which is what keeps a rename loud.
Proof the gate is alive — both control arms, one run
A bogus entry
"scitex_io._this_module_does_not_exist"was injected into theold helper and the new one and both were run together:
Old code: SKIPPED (green). New code: FAILED. The control files were then
deleted and the gate re-run:
Baseline on the same tree before the change:
110 passed, 84 skipped. Same 110passing — the 35 skips that disappeared were the gate's blind spot.
Two consequences of the gate coming alive
31 stale snapshot rows, pruned. None appears anywhere in
src/:src/scitex/has nobridge,_dev/holds only__init__.py, andgenis amodule (
gen.py) soscitex.gen._xcan never be a submodule. They were rowsthat could only ever skip. (For scale: the SSoT collector
_collect_cross_package_importsfinds 18 cross-package imports in thecurrent source against 194 declared — the umbrella's snapshot has never been
regenerated, because PS-140 exempts the umbrella and so nothing ever complained.)
4 entries are a real, live defect — recorded as strict xfails, not skipped
away.
src/sciteximportsscitex_dev.{docs,search,skills,types}fromcli/docs.py,cli/skills.py,cli/mcp.py,_mcp/__init__.pyand_mcp/_umbrella_tools.py, and the pinnedscitex-dev==0.28.0ships none ofthem:
So this is not a local version skew — it is broken against the version this
package pins.
_show_listincli/docs.pyimports unguarded, so it raises atruntime. Where the symbols moved to is not unambiguous —
scitex_dev._docsexports none of
get_docs/build_docs/search_docs— so the import sitesare left to a separate change rather than guessed at.
strict=Truemeans thisgate fails the day they are corrected, until the record is deleted; it cannot
rot into a permanent exemption.
This is the defect class PS-140 was written for, and it was invisible for as
long as the gate could not fail.
Audit note
scitex-dev ecosystem audit-project scitexreports no PS-140 both beforeand after this change:
check_ps140_integration_gatereturns early on_is_umbrella(repo), so the umbrella's gate is never checked by the rule. Thedefect was real regardless, which is why it is fixed here. No PS-224 finding is
reported for this repo either.