Background
CodeQL surfaces ~10 "Importing value of mutable attribute" alerts across codex_runner.py, mcp.py, mcp_server.py, poller.py, review_config.py, and scm/github.py. Each does:
from bubo.paths import ROOT, CONFIG, RENDERED_PROMPTS
Because bubo.paths exposes module-level constants that ARE mutated at runtime (cli._retarget_paths rewrites paths.ROOT/paths.DB/… when bubo init --root X runs; the test suite monkeypatches the same), a by-value import means those modules hold a stale snapshot and won't observe a retarget.
Why this isn't urgent
- Pre-existing. Identical on
main before the Bubo rename (just llm_reviewer.paths); the rename only changed the module name, so the alerts re-surfaced on the diff.
- No live bug today. The modules that actually run under a custom
--root (e.g. db.init_db) already access paths.DB at call-time, which is why the --root flow and the test fixtures pass. The flagged value-imports are in code paths that aren't exercised with a retargeted root in the same process.
Proposed fix
Convert the value-imports to module-attribute access repo-wide:
from bubo import paths
...
paths.ROOT, paths.CONFIG, paths.RENDERED_PROMPTS
This makes _retarget_paths correct-by-construction everywhere and clears the CodeQL class. Mechanical but touches ~7 files and their usages — better as its own PR than riding the rename.
Also noted (not fixing)
CodeQL flags a poller ↔ github cyclic import. It's intentional and already mitigated: github.main() does a deferred from bubo.poller import main inside the function (to let one host run both bubo-poller and bubo-gh-poller). Leaving as-is.
cc @mountainowl
Background
CodeQL surfaces ~10 "Importing value of mutable attribute" alerts across
codex_runner.py,mcp.py,mcp_server.py,poller.py,review_config.py, andscm/github.py. Each does:Because
bubo.pathsexposes module-level constants that ARE mutated at runtime (cli._retarget_pathsrewritespaths.ROOT/paths.DB/… whenbubo init --root Xruns; the test suite monkeypatches the same), a by-value import means those modules hold a stale snapshot and won't observe a retarget.Why this isn't urgent
mainbefore the Bubo rename (justllm_reviewer.paths); the rename only changed the module name, so the alerts re-surfaced on the diff.--root(e.g.db.init_db) already accesspaths.DBat call-time, which is why the--rootflow and the test fixtures pass. The flagged value-imports are in code paths that aren't exercised with a retargeted root in the same process.Proposed fix
Convert the value-imports to module-attribute access repo-wide:
This makes
_retarget_pathscorrect-by-construction everywhere and clears the CodeQL class. Mechanical but touches ~7 files and their usages — better as its own PR than riding the rename.Also noted (not fixing)
CodeQL flags a
poller ↔ githubcyclic import. It's intentional and already mitigated:github.main()does a deferredfrom bubo.poller import maininside the function (to let one host run bothbubo-pollerandbubo-gh-poller). Leaving as-is.cc @mountainowl