From a071497302d8dfd4d2f6b3aef73da860797a4ec9 Mon Sep 17 00:00:00 2001 From: scitex-agent-container Date: Mon, 31 Aug 2026 15:15:38 +0000 Subject: [PATCH 1/5] chore(deps): scitex-clew becomes a floor (>=0.20.0), not an exact pin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All three occurrences in pyproject.toml — the core dependency (L82), the `clew` extra (L796) and the `dev` extra (L951) — read `scitex-clew==0.17.0`, a build tagged 2026-07-06. That exact pin is why a completed migration never arrived. clew moved its four stores off the retired embedded file engine onto the per-host PostgreSQL and released it as 0.20.0; the `==` meant this package kept resolving the July build regardless. The symptom is observable in this repo: running the suite re-creates `.scitex/clew/runtime/clew.db`, whose first sixteen bytes are `SQLite format 3`. A floor also fixes the general failure the pin caused, not just this instance of it — subsequent clew fixes now reach consumers without a manual bump here. The version chosen is the first clew release that carries the migration. Also corrects the `clew` extra's comment: since 0.20.0 clew resolves its stores through `scitex_dev.store.host_store()`, so it is no longer a standard-library-only extra. --- CHANGELOG.md | 10 ++++++++++ pyproject.toml | 17 ++++++++++++----- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a3df26065..048c14b9a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed +- **`scitex-clew` is a FLOOR (`>=0.20.0`), not an exact pin.** All three + occurrences in `pyproject.toml` (core dependency, the `clew` extra, the + `dev` extra) read `scitex-clew==0.17.0` — a July 6 build. clew moved its + four stores off the retired embedded file engine onto the per-host + PostgreSQL, and because of the `==` that never reached this package: + running this suite still re-created a `.scitex/clew/runtime/clew.db` + database file. `>=0.20.0` sets the floor at the first clew release that + carries the migration and lets subsequent fixes through. + ## [2.30.5] - 2026-06-30 ### Changed diff --git a/pyproject.toml b/pyproject.toml index 265512614..cfbe3b9e5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -78,8 +78,13 @@ dependencies = [ "beautifulsoup4>=4.12.0", # HTML parsing - used by web/cli modules # Config + env loading (scitex.helpers.load_scitex_env delegates here) "scitex-config==0.3.6", - # Reproducibility Verification - "scitex-clew==0.17.0", + # Reproducibility Verification. + # A FLOOR, not a pin: an exact `==` froze this at 0.17.0 (2026-07-06) for + # two months, so the storage-backend migration shipped in clew 0.20.0 never + # reached anyone here and the retired embedded file engine kept being used. + # 0.20.0 is the first release where clew's stores resolve through + # scitex_dev.store.host_store() instead of a database file. + "scitex-clew>=0.20.0", # App SDK — unified file storage for local + cloud "scitex-app==0.2.11", # Delegated core modules (thin re-exports) @@ -792,8 +797,10 @@ web = [ # Clew Module - Hash-based verification for reproducible science (Ariadne's thread) # Use: pip install scitex[clew] -# Note: No extra dependencies - uses only the standard library -clew = ["scitex-clew==0.17.0"] +# Note: clew's own dependencies come with it. Since 0.20.0 its stores resolve +# through scitex_dev.store.host_store() (the per-host PostgreSQL), not a +# database file, so this is no longer a standard-library-only extra. +clew = ["scitex-clew>=0.20.0"] # Writer Module - Academic paper writing # Use: pip install scitex[writer] @@ -948,7 +955,7 @@ dev = [ "scitex-audio==0.3.0", "scitex-audit==0.2.0", "scitex-browser==0.1.15", - "scitex-clew==0.17.0", + "scitex-clew>=0.20.0", # NOTE: scitex-hub (optional peer powering cloud/module/project; formerly # scitex-cloud) is intentionally NOT in [dev] — it is unreleased, so listing # it here would break CI's `.[all,dev]` resolve. Install explicitly via From f55252b835a17fb891763b0f304d97b0b2a52ffe Mon Sep 17 00:00:00 2001 From: scitex-agent-container Date: Mon, 31 Aug 2026 16:06:17 +0000 Subject: [PATCH 2/5] =?UTF-8?q?chore(deps):=20bump=20scitex-dev=20to=200.5?= =?UTF-8?q?7.0=20=E2=80=94=20the=20clew=20floor=20is=20unusable=20without?= =?UTF-8?q?=20it?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The first commit moved scitex-clew to a floor. CI then showed the floor alone is not enough: clew's stores resolve through `scitex_dev.store.host_store()`, and the pinned `scitex-dev==0.28.0` has no `scitex_dev.store` at all. The failure mode is the same silent one the clew pin caused. The resolve SUCCEEDED; the break landed at import: [scitex-dev linter] WARNING: failed to load plugin 'clew': ModuleNotFoundError: No module named 'scitex_dev.store' with TestClewIntegration::test_status, ::test_hash_file and TestCrossModuleWorkflow::test_io_save_then_clew_hash failing on py3.11, 3.12 and 3.13. clew 0.20.1 (scitex-ai/scitex-clew#158) declares `scitex-dev>=0.49.2`, so the bad combination is refused at resolve time from now on. That floor is measured by a real write-then-read, not by importing: 0.43.1 is the first release carrying `scitex_dev.store` and `host_store`, imports every symbol clew imports, and still raises `TypeError: tuple indices must be integers or slices, not str` inside `Store.rows()`. 0.28.0 FAIL, 0.43.1 FAIL, 0.46.0 FAIL, 0.48.0 FAIL, 0.49.0 FAIL, 0.49.2 OK, 0.49.3 OK, 0.50.0 OK, 0.57.0 OK. 0.57.0 is PyPI's newest, matching this file's established practice of pinning the umbrella at latest. The clew floor moves to >=0.20.1 in all three places for the same reason. --- CHANGELOG.md | 14 ++++++++++++-- pyproject.toml | 27 ++++++++++++++++++++------- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 048c14b9a..7113ad6f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,8 +14,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 four stores off the retired embedded file engine onto the per-host PostgreSQL, and because of the `==` that never reached this package: running this suite still re-created a `.scitex/clew/runtime/clew.db` - database file. `>=0.20.0` sets the floor at the first clew release that - carries the migration and lets subsequent fixes through. + database file. `>=0.20.1` sets the floor at the first clew release that + carries the migration with honest metadata, and lets subsequent fixes + through. +- **`scitex-dev` 0.28.0 → 0.57.0, required by the clew floor above.** clew's + stores resolve through `scitex_dev.store.host_store()`, and 0.28.0 has no + `scitex_dev.store` at all. Left at 0.28.0 the resolve still SUCCEEDS and + the failure lands at import instead: `failed to load plugin 'clew': + ModuleNotFoundError: No module named 'scitex_dev.store'`, with three clew + integration tests failing on all three Python legs. clew 0.20.1 declares + `scitex-dev>=0.49.2` — a floor measured by a real write-then-read, since + 0.43.1 imports every symbol clew uses and still raises `TypeError: tuple + indices must be integers or slices, not str` inside `Store.rows()`. ## [2.30.5] - 2026-06-30 diff --git a/pyproject.toml b/pyproject.toml index cfbe3b9e5..bc3917cd8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -83,12 +83,25 @@ dependencies = [ # two months, so the storage-backend migration shipped in clew 0.20.0 never # reached anyone here and the retired embedded file engine kept being used. # 0.20.0 is the first release where clew's stores resolve through - # scitex_dev.store.host_store() instead of a database file. - "scitex-clew>=0.20.0", + # scitex_dev.store.host_store() instead of a database file; 0.20.1 is the + # first that declares an honest scitex-dev floor for it. + "scitex-clew>=0.20.1", # App SDK — unified file storage for local + cloud "scitex-app==0.2.11", # Delegated core modules (thin re-exports) - "scitex-dev==0.28.0", + # + # scitex-dev 0.28.0 -> 0.57.0 is REQUIRED BY the clew floor above, not an + # optional freshness bump: clew's stores resolve through + # `scitex_dev.store.host_store()`, and 0.28.0 has no `scitex_dev.store` at + # all. Left at 0.28.0 the resolve still SUCCEEDS and the failure lands at + # import instead — measured here as "failed to load plugin 'clew': + # ModuleNotFoundError: No module named 'scitex_dev.store'" plus three + # failing clew integration tests on all three Python legs. + # The floor clew declares is 0.49.2, measured by a real write-then-read + # (0.43.1 imports every symbol and still TypeErrors inside `Store.rows()`); + # 0.57.0 is PyPI's newest, matching this file's established practice of + # pinning the umbrella at latest. + "scitex-dev==0.57.0", "scitex-io==0.3.3", "scitex-stats==0.2.24", "scitex-audio==0.3.0", @@ -800,7 +813,7 @@ web = [ # Note: clew's own dependencies come with it. Since 0.20.0 its stores resolve # through scitex_dev.store.host_store() (the per-host PostgreSQL), not a # database file, so this is no longer a standard-library-only extra. -clew = ["scitex-clew>=0.20.0"] +clew = ["scitex-clew>=0.20.1"] # Writer Module - Academic paper writing # Use: pip install scitex[writer] @@ -955,14 +968,14 @@ dev = [ "scitex-audio==0.3.0", "scitex-audit==0.2.0", "scitex-browser==0.1.15", - "scitex-clew>=0.20.0", + "scitex-clew>=0.20.1", # NOTE: scitex-hub (optional peer powering cloud/module/project; formerly # scitex-cloud) is intentionally NOT in [dev] — it is unreleased, so listing # it here would break CI's `.[all,dev]` resolve. Install explicitly via # `pip install scitex[cloud]` when scitex-hub is available. "scitex-container==0.2.1", "scitex-dataset==0.5.0", - "scitex-dev==0.28.0", + "scitex-dev==0.57.0", "scitex-etc==0.2.1", "scitex-genai==0.1.1", "scitex-io==0.3.3", @@ -1098,7 +1111,7 @@ all = [ # ============================================ # Tool Configurations # ============================================ -linter = ["scitex-dev==0.28.0"] +linter = ["scitex-dev==0.57.0"] orochi = ["scitex-orochi==0.17.0"] agent-container = ["scitex-agent-container==0.21.11"] From 06bd0dc3a15ef48f9a914ac661049016fe1c9f4e Mon Sep 17 00:00:00 2001 From: scitex-agent-container Date: Mon, 31 Aug 2026 16:51:47 +0000 Subject: [PATCH 3/5] chore(deps): scitex-dev also becomes a floor (>=0.57.0), not ==0.57.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous local commit fixed the resolve-vs-import gap (clew needs scitex_dev.store.host_store(), scitex-dev==0.28.0 has none) by bumping scitex-dev to 0.57.0 — but kept it as an exact `==` pin in all three places (core dependency, `dev` extra, `linter` extra). That repeats the exact bug this PR exists to fix for clew: an exact `==` silently freezes a dependency and blocks every subsequent fix from reaching this package without a manual PR, which is what let scitex-clew==0.17.0 sit for two months while clew migrated off the retired storage engine. scitex-dev>=0.57.0 in all three occurrences. Verified against PyPI (JSON API + simple index) immediately before this commit: 0.57.0 is still the newest scitex-dev release, and it satisfies clew 0.20.1's declared `scitex-dev>=0.49.2` floor. --- CHANGELOG.md | 23 +++++++++++++---------- pyproject.toml | 22 +++++++++++----------- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7113ad6f3..1daf01469 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Changed -- **`scitex-clew` is a FLOOR (`>=0.20.0`), not an exact pin.** All three +- **`scitex-clew` is a FLOOR (`>=0.20.1`), not an exact pin.** All three occurrences in `pyproject.toml` (core dependency, the `clew` extra, the `dev` extra) read `scitex-clew==0.17.0` — a July 6 build. clew moved its four stores off the retired embedded file engine onto the per-host @@ -17,15 +17,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 database file. `>=0.20.1` sets the floor at the first clew release that carries the migration with honest metadata, and lets subsequent fixes through. -- **`scitex-dev` 0.28.0 → 0.57.0, required by the clew floor above.** clew's - stores resolve through `scitex_dev.store.host_store()`, and 0.28.0 has no - `scitex_dev.store` at all. Left at 0.28.0 the resolve still SUCCEEDS and - the failure lands at import instead: `failed to load plugin 'clew': - ModuleNotFoundError: No module named 'scitex_dev.store'`, with three clew - integration tests failing on all three Python legs. clew 0.20.1 declares - `scitex-dev>=0.49.2` — a floor measured by a real write-then-read, since - 0.43.1 imports every symbol clew uses and still raises `TypeError: tuple - indices must be integers or slices, not str` inside `Store.rows()`. +- **`scitex-dev` also becomes a FLOOR (`>=0.57.0`), not an exact pin — + required by the clew floor above.** clew's stores resolve through + `scitex_dev.store.host_store()`, and the previous exact `scitex-dev==0.28.0` + pin has no `scitex_dev.store` at all. Left at 0.28.0 the resolve still + SUCCEEDS and the failure lands at import instead: `failed to load plugin + 'clew': ModuleNotFoundError: No module named 'scitex_dev.store'`, with + three clew integration tests failing on all three Python legs. clew 0.20.1 + declares `scitex-dev>=0.49.2` — a floor measured by a real write-then-read, + since 0.43.1 imports every symbol clew uses and still raises `TypeError: + tuple indices must be integers or slices, not str` inside `Store.rows()`. + 0.57.0 is PyPI's newest at time of writing; using `>=` rather than `==` + here avoids repeating the exact freeze bug this PR fixes for clew. ## [2.30.5] - 2026-06-30 diff --git a/pyproject.toml b/pyproject.toml index bc3917cd8..75bc4f742 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -90,18 +90,18 @@ dependencies = [ "scitex-app==0.2.11", # Delegated core modules (thin re-exports) # - # scitex-dev 0.28.0 -> 0.57.0 is REQUIRED BY the clew floor above, not an - # optional freshness bump: clew's stores resolve through + # scitex-dev 0.28.0 -> a FLOOR at 0.57.0, not a pin — same reasoning as the + # clew floor above, and REQUIRED BY it: clew's stores resolve through # `scitex_dev.store.host_store()`, and 0.28.0 has no `scitex_dev.store` at - # all. Left at 0.28.0 the resolve still SUCCEEDS and the failure lands at - # import instead — measured here as "failed to load plugin 'clew': - # ModuleNotFoundError: No module named 'scitex_dev.store'" plus three - # failing clew integration tests on all three Python legs. + # all. Left at an exact 0.28.0 pin the resolve still SUCCEEDS and the + # failure lands at import instead — measured here as "failed to load + # plugin 'clew': ModuleNotFoundError: No module named 'scitex_dev.store'" + # plus three failing clew integration tests on all three Python legs. # The floor clew declares is 0.49.2, measured by a real write-then-read # (0.43.1 imports every symbol and still TypeErrors inside `Store.rows()`); - # 0.57.0 is PyPI's newest, matching this file's established practice of - # pinning the umbrella at latest. - "scitex-dev==0.57.0", + # 0.57.0 is PyPI's newest at time of writing. An exact `==` here would + # repeat the exact bug this PR fixes for clew, so this is `>=`, not `==`. + "scitex-dev>=0.57.0", "scitex-io==0.3.3", "scitex-stats==0.2.24", "scitex-audio==0.3.0", @@ -975,7 +975,7 @@ dev = [ # `pip install scitex[cloud]` when scitex-hub is available. "scitex-container==0.2.1", "scitex-dataset==0.5.0", - "scitex-dev==0.57.0", + "scitex-dev>=0.57.0", "scitex-etc==0.2.1", "scitex-genai==0.1.1", "scitex-io==0.3.3", @@ -1111,7 +1111,7 @@ all = [ # ============================================ # Tool Configurations # ============================================ -linter = ["scitex-dev==0.57.0"] +linter = ["scitex-dev>=0.57.0"] orochi = ["scitex-orochi==0.17.0"] agent-container = ["scitex-agent-container==0.21.11"] From b4cdbb5c088583369876fd6ea902c42fa0dde27b Mon Sep 17 00:00:00 2001 From: scitex-agent-container Date: Mon, 31 Aug 2026 16:56:21 +0000 Subject: [PATCH 4/5] fix(deps): scitex-scholar, scitex-ssh conflicted with the scitex-dev floor Pushing the scitex-dev>=0.57.0 floor and re-running CI (run 33416452001 et al., all on py3.11/3.12/3.13) surfaced two more unresolvable transitive conflicts, not visible until the resolver actually ran: Because scitex-dev>=0.57.0 depends on scitex-scholar>=1.4.3 and scitex==2.30.8 depends on scitex-dev>=0.57.0, we can conclude that scitex==2.30.8 depends on scitex-scholar>=1.4.3. And because scitex==2.30.8 depends on scitex-scholar==1.4.2, ... unsatisfiable. Because scitex-dev>=0.57.0 depends on scitex-ssh>=1.1.0 and scitex depends on scitex-dev>=0.57.0, ... scitex depends on scitex-ssh==1.0.1, ... unsatisfiable. Both are minimal bumps to the first release that satisfies scitex-dev's own declared floor: scitex-scholar==1.4.2 -> ==1.4.3, scitex-ssh==1.0.1 -> ==1.1.0. Checked each new version's own requires_dist on PyPI before bumping - neither pulls in anything that conflicts with the rest of this file's pins. Verified locally with uv pip compile --extra all --extra dev pyproject.toml: resolves cleanly now, locking scitex-clew==0.20.1, scitex-dev==0.57.0, scitex-scholar==1.4.3, scitex-ssh==1.1.0. --- CHANGELOG.md | 8 ++++++++ pyproject.toml | 10 +++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1daf01469..ba664996f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 tuple indices must be integers or slices, not str` inside `Store.rows()`. 0.57.0 is PyPI's newest at time of writing; using `>=` rather than `==` here avoids repeating the exact freeze bug this PR fixes for clew. +- **`scitex-scholar` 1.4.2 → 1.4.3 and `scitex-ssh` 1.0.1 → 1.1.0, required + by the scitex-dev floor above.** scitex-dev 0.57.0 itself declares + `scitex-scholar>=1.4.3` and `scitex-ssh>=1.1.0`; the previous exact pins + here (`==1.4.2`, `==1.0.1`) were below both floors and made the whole + dependency set unresolvable (`uv`: "your requirements are unsatisfiable"), + measured directly from a failed CI run on this branch before this commit. + Both stay exact pins (unlike clew/scitex-dev above) — this is a transitive + unblock, not the freeze-prone coupling this PR targets. ## [2.30.5] - 2026-06-30 diff --git a/pyproject.toml b/pyproject.toml index 75bc4f742..52892f0e2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -109,7 +109,7 @@ dependencies = [ "scitex-notebook==0.1.2", # Delegated modules from #51 standalonization "scitex-db==0.1.12", - "scitex-scholar==1.4.2", + "scitex-scholar==1.4.3", "scitex-parallel==0.1.8", "scitex-types==0.1.6", "scitex-path==0.1.7", @@ -676,7 +676,7 @@ scholar = [ "connectedpapers-py", # # Heavy dependencies handled by _AVAILABLE flags # "torch", - "scitex-scholar==1.4.2" + "scitex-scholar==1.4.3" ] # Schema Module - Data schema validation @@ -748,7 +748,7 @@ tex = [ # Tunnel Module - SSH reverse tunnel for NAT traversal # Use: pip install scitex[tunnel] tunnel = [ - "scitex-ssh==1.0.1", + "scitex-ssh==1.1.0", ] # Torch Module - PyTorch support @@ -980,8 +980,8 @@ dev = [ "scitex-genai==0.1.1", "scitex-io==0.3.3", "scitex-notification==0.2.9", - "scitex-scholar==1.4.2", - "scitex-ssh==1.0.1", + "scitex-scholar==1.4.3", + "scitex-ssh==1.1.0", "scitex-stats==0.2.24", "scitex-ui==0.6.0", "scitex-writer==2.24.1", From d200aefd1a91fb17e813362975acc824348b7c6e Mon Sep 17 00:00:00 2001 From: scitex-agent-container Date: Mon, 31 Aug 2026 17:08:58 +0000 Subject: [PATCH 5/5] test(clew): fix stale hash-length assertion, wire an ephemeral store for CI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Re-running the pytest matrix with the clew/scitex-dev floors resolving surfaced two more failures in exactly the three named tests, neither a pin problem: 1. test_hash_file / test_io_save_then_clew_hash asserted `len(h) == 32`. clew's hash_file() (see scitex-clew's clew-fix-truncated-hash-comparison) intentionally stopped truncating its SHA-256 digest to 32 hex chars — that truncation silently broke every external hash comparison. The full 64-char digest is the corrected, intended behaviour; the assertion here was written against the old truncated output and is now updated to match. 2. test_status hit `scitex_dev.store._errors.StoreTargetError: Cannot connect to Postgres store 'runs' at postgres[host=/home/runner/.scitex/pg/run ...]`. clew>=0.20.1's four stores resolve through scitex_dev.store.host_store(), which by default targets the fleet's central Postgres — unreachable (and not something a test should touch) from this off-fleet GitHub Actions runner. scitex-scholar, scitex-writer and scitex-dev's own CI hit the identical wall on 2026-08-29; scitex-dev shipped scitex_dev.store.testing.ephemeral_cluster_dsn() as the shared fix. Added a module-scoped `_clew_store_dsn` fixture that starts a throwaway local cluster via that helper and a `_clew_store` fixture that points SCITEX_STORE_DSN at it for the duration of one test; wired into all three of TestClewIntegration::test_status, TestClewIntegration::test_hash_file and TestCrossModuleWorkflow::test_io_save_then_clew_hash. Skips (not fails) if the runner has no initdb/pg_ctl — verified locally that path raises cleanly; GitHub's ubuntu-latest image ships PostgreSQL 16 server binaries under /usr/lib/postgresql/16/bin, which ephemeral_cluster_dsn() already knows to look for. --- tests/integration/test_integration.py | 45 ++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/tests/integration/test_integration.py b/tests/integration/test_integration.py index 29ae13d21..491849efb 100755 --- a/tests/integration/test_integration.py +++ b/tests/integration/test_integration.py @@ -30,6 +30,37 @@ def tmp_dir(): shutil.rmtree(d, ignore_errors=True) +@pytest.fixture(scope="module") +def _clew_store_dsn(): + """A throwaway local PostgreSQL cluster for clew's store-backed tests. + + As of scitex-clew>=0.20.1, clew's four stores resolve through + `scitex_dev.store.host_store()`, which defaults to the fleet's central + Postgres (unreachable from this off-fleet CI runner, and not something a + test must ever write to regardless). Point `SCITEX_STORE_DSN` at a + private, throwaway cluster instead, using the exact affordance + scitex-dev shipped for this: scitex-scholar, scitex-writer and + scitex-dev's own CI independently hit the same "off-fleet CI cannot + exercise a store-backed path" wall on 2026-08-29, and + `scitex_dev.store.testing.ephemeral_cluster_dsn()` is the shared fix. + + Module-scoped: one throwaway cluster serves every clew test in this + file rather than paying `initdb`+`pg_ctl start` per test. + """ + testing = pytest.importorskip("scitex_dev.store.testing") + try: + with testing.ephemeral_cluster_dsn() as dsn: + yield dsn + except RuntimeError as exc: + pytest.skip(f"no throwaway PostgreSQL available for clew's store: {exc}") + + +@pytest.fixture +def _clew_store(_clew_store_dsn, monkeypatch): + """Point SCITEX_STORE_DSN at the throwaway cluster for one test.""" + monkeypatch.setenv("SCITEX_STORE_DSN", _clew_store_dsn) + + # --------------------------------------------------------------------------- # 1. Lazy loading and namespace # --------------------------------------------------------------------------- @@ -208,17 +239,21 @@ def test_ecosystem_registry(self): class TestClewIntegration: """Verify stx.clew is accessible through unified namespace.""" - def test_status(self): + def test_status(self, _clew_store): result = stx.clew.status() assert isinstance(result, dict) - def test_hash_file(self, tmp_dir): + def test_hash_file(self, tmp_dir, _clew_store): path = os.path.join(tmp_dir, "test.txt") with open(path, "w") as f: f.write("hello") h = stx.clew.hash_file(path) assert isinstance(h, str) - assert len(h) == 32 # SHA-256 prefix + # Full SHA-256 hex digest (64 chars). Prior to scitex-clew's + # clew-fix-truncated-hash-comparison fix, hash_file() returned the + # first 32 hex chars only, which silently broke external hash + # comparisons; clew now returns the full digest. + assert len(h) == 64 # --------------------------------------------------------------------------- @@ -229,13 +264,13 @@ def test_hash_file(self, tmp_dir): class TestCrossModuleWorkflow: """Verify modules work together in realistic workflows.""" - def test_io_save_then_clew_hash(self, tmp_dir): + def test_io_save_then_clew_hash(self, tmp_dir, _clew_store): """Save a file via stx.io, verify clew can hash it.""" path = os.path.join(tmp_dir, "data.csv") df = pd.DataFrame({"a": [1, 2, 3]}) stx.io.save(df, path) h = stx.clew.hash_file(path) - assert len(h) == 32 + assert len(h) == 64 # full SHA-256 hex digest, see test_hash_file def test_stats_then_io_save(self, tmp_dir): """Run a stat test, save results via stx.io."""