Package EigenRegex for import (closes #13) - #14
Conversation
The engine shipped as a flat five-file `load_file` library, so its private helpers (`_peek`, `pos`, `n`, `branches`, …) lived in the global namespace and silently clobbered any consumer using the same names — exactly what eigen-sheet hit wiring regex-powered find & replace (#36): two `_peek` definitions, last one wins, `len: null has no length` far from the cause. Fold the split into a single importable root `regex.eigs` + `eigs.json` (name `regex`), matching the package-template contract (one root leaf, top-level non-underscore bindings become `regex.*`, `_`-names stay private). `import regex` now namespaces the whole engine, so the caller-globals collision class (#5) and the `_peek` clash (#13) are structurally gone rather than mitigated by `local`. - Public surface: `re_compile`/`re_match`/`re_search`/`re_find_all`/ `re_replace` (spans) + `compat_match`/`compat_find`/`compat_replace` (builtin-shaped, folded in from the compat shim — namespaced, so no builtin shadowing across the import boundary). - Internal entry points privatised to `_rx_parse`/`_rx_compile_ast`/ `_rx_vm_run`; all helpers already `_`-prefixed. - Tests converted from `load_file` to `import regex` (S1–S8, smoke, bench). S9 flipped from the load_file scope suite to an import-isolation guard (adds a `_peek` collision the old model couldn't survive). New `tests/test_pkg_smoke.sh` stages the package into `eigs_modules/regex/` and imports it the way `--pkg add` would, asserting public surface + internal privacy. - Docs (README/CLAUDE.md) updated to the import model; `EIGS_REF` drift fixed (v0.26.0 → the actual v0.30.0 pin). - GAPS.md: logged a builtin `regex_match` non-participating-group shape change (v0.30.0 `["b"]` → v0.32.0 `["b", null, "b"]`) surfaced by the S8 differential — will bite an EIGS_REF bump. 359 checks + package smoke, green against the CI-pinned v0.30.0. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Closing as already-landed, not as rejected — and the reason is a mistake on my side worth recording. During the ecosystem-wide v0.30.0 → v0.32.0 pin sweep, this repo's working tree was checked out on So the packaging work IS on main (41cc66e) and is green — This PR must not be merged now. Its branch predates the pin bump, so the only remaining delta against main is Fix applied going forward: sweep loops now branch from a fetched |
Closes #13.
Problem
EigenRegex was a flat five-file
load_filelibrary: its private helpers (_peek,pos,n,branches, …) lived in the global namespace and silently clobbered any consumer using the same names — exactly what eigen-sheet hit wiring regex find & replace (#36): two_peekdefinitions, last-one-wins,len: null has no lengthsurfacing far from the cause.Fix
Fold the split into a single importable root
regex.eigs+eigs.json(nameregex), matching the package-template contract (one root leaf; top-level non-underscore bindings becomeregex.*;_-names stay private).import regexnow namespaces the whole engine, so the caller-globals collision class (#5) and the_peekclash (#13) are structurally gone rather than mitigated bylocal.re_compile/re_match/re_search/re_find_all/re_replace(positional spans) +compat_match/compat_find/compat_replace(builtin-shaped, folded in from the compat shim — namespaced, so no builtin shadowing across the import boundary)._rx_parse/_rx_compile_ast/_rx_vm_run; all other helpers were already_-prefixed.load_file→import regex(S1–S8, smoke, bench). S9 flipped from the load_file scope suite to an import-isolation guard (now also survives a consumer_peekcollision the old model couldn't). Newtests/test_pkg_smoke.shstages the package intoeigs_modules/regex/and imports it the way--pkg addwould, asserting public surface + internal privacy.EIGS_REFdrift (CLAUDE.md said v0.26.0; actual pin is v0.30.0).Verification
359 checks + package smoke, all greenagainst the CI-pinned v0.30.0 (built from the tag).--lint regex.eigs: no issues.Side finding (logged in GAPS.md, not fixed here)
Running the S8 differential against a v0.32.0 runtime surfaced a builtin
regex_matchshape change: non-participating capture groups went from truncated (regex_match of ["b","(a)|(b)"]→["b"]on v0.30.0) to null-filled (["b", null, "b"]on v0.32.0). Not an EigenRegex bug, but it will break the S8 differential on anEIGS_REFbump and is a breaking builtin-shape change worth an upstream decision.🤖 Generated with Claude Code