_resolve_test_rel: absolute-py regex mis-matches the / in tests/test_ #1

Closed
opened 2026-07-25 08:12:39 +00:00 by marfrit · 0 comments
Owner

Analysis

_resolve_test_rel() in bullpen-grinder has a regex ordering bug that makes it impossible to use tests/test_<name>.py as a SPEC path without triggering the wrong match.

The bug

The regex chain (line 497-519 of bullpen-grinder on boltzmann at /usr/local/bin/bullpen-grinder):

m = (re.search(r"/[\w./-]+\.(?:test|spec)\.(?:js|ts)\b", body or "")
     or re.search(r"/[\w./-]+_test\.(?:js|ts|go|py)\b", body or "")
     or re.search(r"/[\w./-]+\.py\b", body or "")   # ← THIS ONE
     or re.search(r"tests/[\w./-]+\.py", body or "")
     ...

When the body contains tests/test_namespace_query.py, the absolute regex r"/[\w./-]+\.py\b" matches the / between tests/ and test_. It returns /test_namespace_query.py instead of the correct tests/test_namespace_query.py.

The absolute regex fires at /test_ because [\w./-]+ greedily consumes test_namespace_query and .py\b matches the suffix.

Impact

/test_namespace_query.py is an absolute path but wrong — it's not the real location. The coordinator then either:

  • Passes it to _remote_grind where os.path.join(work, "/abs/path") discards the worktree (related bug)
  • Or _repo_test_files can't find a bare /test_*.py at the repo root

No SPEC path with a tests/ prefix can resolve correctly through the regex chain.

Workaround

Two formats that work:

  1. Bare filename: test_namespace_query.py alone in the body — falls through to named-file resolution
  2. Full absolute path: SPEC: /tmp/bullpen-build/.../tests/test_namespace_query.py\nREPO: /tmp/bullpen-build/.../ — matches the absolute regex correctly (but hits the os.path.join bug)

Room reference

Observed on hertz (room) + noether (bullpen-grinder --serve py):

  • Message 1610: INVALID TICKET ❌ — /test_namespace_query.py does not exist in /tmp/...
  • Message 1613: same error repeated
  • Message 1616: same error repeated

Every dispatch using SPEC: tests/test_namespace_query.py repo=... format produced /test_namespace_query.py.

Hosts

Host Role
hertz Room + lmcp tools (room_say, room_read)
noether bullpen-grinder --serve py coordinator — where _resolve_test_rel runs
boltzmann Grind host — the code lives in /usr/local/bin/bullpen-grinder

Suggested fix

The absolute regex should be guarded to only match at a word/whitespace boundary before the leading /, or moved below the tests/ relative regex in the chain. E.g.:

m = (re.search(r"(?:^|\s)(/[\w./-]+\.(?:test|spec)\.(?:js|ts))\b", body or "")
     ...
## Analysis `_resolve_test_rel()` in `bullpen-grinder` has a regex ordering bug that makes it impossible to use `tests/test_<name>.py` as a SPEC path without triggering the wrong match. ### The bug The regex chain (line 497-519 of bullpen-grinder on boltzmann at `/usr/local/bin/bullpen-grinder`): ```python m = (re.search(r"/[\w./-]+\.(?:test|spec)\.(?:js|ts)\b", body or "") or re.search(r"/[\w./-]+_test\.(?:js|ts|go|py)\b", body or "") or re.search(r"/[\w./-]+\.py\b", body or "") # ← THIS ONE or re.search(r"tests/[\w./-]+\.py", body or "") ... ``` When the body contains `tests/test_namespace_query.py`, the **absolute** regex `r"/[\w./-]+\.py\b"` matches the `/` between `tests/` and `test_`. It returns `/test_namespace_query.py` instead of the correct `tests/test_namespace_query.py`. The absolute regex fires at `/test_` because `[\w./-]+` greedily consumes `test_namespace_query` and `.py\b` matches the suffix. ### Impact `/test_namespace_query.py` is an absolute path but wrong — it's not the real location. The coordinator then either: - Passes it to `_remote_grind` where `os.path.join(work, "/abs/path")` discards the worktree (related bug) - Or `_repo_test_files` can't find a bare `/test_*.py` at the repo root **No SPEC path with a `tests/` prefix can resolve correctly through the regex chain.** ### Workaround Two formats that work: 1. **Bare filename**: `test_namespace_query.py` alone in the body — falls through to named-file resolution 2. **Full absolute path**: `SPEC: /tmp/bullpen-build/.../tests/test_namespace_query.py\nREPO: /tmp/bullpen-build/.../` — matches the absolute regex correctly (but hits the os.path.join bug) ### Room reference Observed on hertz (room) + noether (bullpen-grinder --serve py): - Message 1610: `INVALID TICKET ❌ — /test_namespace_query.py does not exist in /tmp/...` - Message 1613: same error repeated - Message 1616: same error repeated Every dispatch using `SPEC: tests/test_namespace_query.py repo=...` format produced `/test_namespace_query.py`. ### Hosts | Host | Role | |---|---| | **hertz** | Room + lmcp tools (room_say, room_read) | | **noether** | bullpen-grinder `--serve py` coordinator — where `_resolve_test_rel` runs | | **boltzmann** | Grind host — the code lives in `/usr/local/bin/bullpen-grinder` | ### Suggested fix The absolute regex should be guarded to only match at a word/whitespace boundary before the leading `/`, or moved below the `tests/` relative regex in the chain. E.g.: ```python m = (re.search(r"(?:^|\s)(/[\w./-]+\.(?:test|spec)\.(?:js|ts))\b", body or "") ... ```
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: marfrit/bullpen#1