From 583023a10d3c546ff068fba8c70e449d1ba2bb43 Mon Sep 17 00:00:00 2001 From: Jeremy Andrews Date: Fri, 14 Aug 2026 21:23:24 +0200 Subject: [PATCH 1/2] Add MAINTAINING.md, this package's own maintenance facts What lives only here: the single version source, the CI job list, the manual PyPI upload, the vendored Snowball stemmers, and the asset copy that nothing checks. The facts true of more than one Scolta repo stay in scolta-core's shared MAINTAINING.md, RELEASING.md, REGRESSION.md and ASSETS.md; this file links there rather than repeating them. --- MAINTAINING.md | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 MAINTAINING.md diff --git a/MAINTAINING.md b/MAINTAINING.md new file mode 100644 index 0000000..ac5f048 --- /dev/null +++ b/MAINTAINING.md @@ -0,0 +1,43 @@ +# MAINTAINING — scolta-python + +The Python binding: a Pagefind index builder plus an AI proxy. Published on PyPI as `scolta`. + +Everything true of more than one Scolta repo lives in +[scolta-core/MAINTAINING.md](https://github.com/tag1consulting/scolta-core/blob/main/MAINTAINING.md): +the version rules, the release order, the fleet checks, the rules every repo shares. How the browser +bundle is copied and checked is in +[scolta-core/ASSETS.md](https://github.com/tag1consulting/scolta-core/blob/main/ASSETS.md). + +**What it is.** The Python binding, a faithful port of `scolta-php`. It depends on `scolta-core` (the +vendored WASM). `scolta-django` depends on this. + +**Where the version lives.** `src/scolta/__init__.py` `__version__`, and only there. `pyproject.toml` +declares `dynamic = ["version"]` and reads it through `[tool.hatch.version]`, so the package metadata and +`scolta.__version__` cannot drift apart. Set one place, not two. + +**Where it publishes.** PyPI, as `scolta` (a flat namespace: ownership is shown by the PyPI org, not a +name prefix). To confirm: `pip install scolta` in a clean venv resolves the new version. + +**CI checks.** `test` (ruff lint, `ruff format --check`, and pytest across Python 3.10 to 3.13, with +Chromium installed so the browser E2E runs rather than skipping), `Build & validate dist artifacts` +(`uv build`, `uvx twine check dist/*`, then `scripts/validate-dist.py` for content and size), and +`JS tests (Jest)` for the shared JS suite under `tests/js`. The `test` job also checks out scolta-core so +the prompt-text identity gate runs against the real `src/prompts.rs` instead of skipping. + +**On release day.** Release this before scolta-django. **There is no release workflow**, so a tag +publishes nothing: rehearse on TestPyPI (`uv build` → `uvx twine check dist/*` → upload → install in a +clean venv), then upload for real with `twine upload dist/*` by hand. CI's `dist` job is the only gate in +front of that upload, and it runs on every pull request. + +**Watch out for.** + +- This package carries the browser bundle at `src/scolta/assets/` and re-vendors it with + `python scripts/vendor_assets.py` from a sibling `../scolta-php` checkout. The copy is fail-closed by + extension allowlist, so a `.sha256`, `.d.ts` or `.map` can never ship. Never hand-edit an asset here. +- Nothing checks that copy against scolta-php. Unlike scolta-drupal and scolta-wp there is no + `assets-in-sync` job, so a stale bundle goes unnoticed until someone looks. +- The Snowball stemmers under `src/scolta/index/snowball/` are **vendored, not a dependency**, because + no published `snowballstemmer` release reproduces Pagefind's `pagefind_stem` byte for byte. Regenerate + them with `scripts/generate-stemmers.sh` against the pinned crate; the stemmer parity tests guard it. +- `PyICU` is an optional `[icu]` extra, mirroring `ext-intl` being a Composer "suggest" in scolta-php. + Without it the tokenizer falls back to a mapping, exactly as PHP does. From 6c134c3dfd45ea6b4ef8997f639ded3098e844c4 Mon Sep 17 00:00:00 2001 From: Jeremy Andrews Date: Sat, 15 Aug 2026 16:03:22 +0200 Subject: [PATCH 2/2] Drop the dash punctuation and the heavy emphasis --- MAINTAINING.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MAINTAINING.md b/MAINTAINING.md index ac5f048..d7594ac 100644 --- a/MAINTAINING.md +++ b/MAINTAINING.md @@ -1,4 +1,4 @@ -# MAINTAINING — scolta-python +# Maintaining scolta-python The Python binding: a Pagefind index builder plus an AI proxy. Published on PyPI as `scolta`. @@ -24,7 +24,7 @@ Chromium installed so the browser E2E runs rather than skipping), `Build & valid `JS tests (Jest)` for the shared JS suite under `tests/js`. The `test` job also checks out scolta-core so the prompt-text identity gate runs against the real `src/prompts.rs` instead of skipping. -**On release day.** Release this before scolta-django. **There is no release workflow**, so a tag +**On release day.** Release this before scolta-django. There is no release workflow, so a tag publishes nothing: rehearse on TestPyPI (`uv build` → `uvx twine check dist/*` → upload → install in a clean venv), then upload for real with `twine upload dist/*` by hand. CI's `dist` job is the only gate in front of that upload, and it runs on every pull request. @@ -36,7 +36,7 @@ front of that upload, and it runs on every pull request. extension allowlist, so a `.sha256`, `.d.ts` or `.map` can never ship. Never hand-edit an asset here. - Nothing checks that copy against scolta-php. Unlike scolta-drupal and scolta-wp there is no `assets-in-sync` job, so a stale bundle goes unnoticed until someone looks. -- The Snowball stemmers under `src/scolta/index/snowball/` are **vendored, not a dependency**, because +- The Snowball stemmers under `src/scolta/index/snowball/` are vendored, not a dependency, because no published `snowballstemmer` release reproduces Pagefind's `pagefind_stem` byte for byte. Regenerate them with `scripts/generate-stemmers.sh` against the pinned crate; the stemmer parity tests guard it. - `PyICU` is an optional `[icu]` extra, mirroring `ext-intl` being a Composer "suggest" in scolta-php.