Skip to content

fix(cli install): pass missing verbose arg and use background-neutral styles#294

Closed
HumanBean17 wants to merge 12 commits into
masterfrom
fix/installer-ci-and-colors
Closed

fix(cli install): pass missing verbose arg and use background-neutral styles#294
HumanBean17 wants to merge 12 commits into
masterfrom
fix/installer-ci-and-colors

Conversation

@HumanBean17

Copy link
Copy Markdown
Owner

Summary

Fixes two regressions from #292:

  • CI failure: run_build_ast_graph() now requires a verbose keyword argument, but installer.py:run_init_if_needed() wasn't passing it — verbose=not quiet added.
  • Color scheme on dark terminals: The blue/cyan foreground colors added for light-background visibility look terrible on dark terminals. Replaced with bold + underline (no hardcoded fg), which is readable on both light and dark backgrounds.

Test plan

  • tests/test_installer.py — all 66 tests pass
  • tests/test_installer_integration.py — both previously-failing integration tests pass
  • ruff check — clean
  • CI green on this branch

🤖 Generated with Claude Code

@HumanBean17 HumanBean17 force-pushed the fix/installer-ci-and-colors branch 4 times, most recently from b4e0e6c to a93cfff Compare June 8, 2026 08:20
HumanBean17 and others added 12 commits June 8, 2026 16:01
Explicitly release Kuzu native objects (Connection, Database, QueryResult)
before Python's shutdown GC reclaims them in unpredictable order. The
use-after-free manifests as a segfault in an asyncio background thread
after test_kuzu_queries.py completes.

- Add KuzuGraph.close() to release _conn and _db
- Add yield-based teardown to all kuzu_graph fixtures in conftest.py
- Release kuzu objects in kuzu_db_path fixture after assertions
- Release kuzu objects in _open_stale_ontology_graph helper

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The previous fix only set references to None without calling the native
close() methods on kuzu.Connection and kuzu.Database. This led to
use-after-free segfaults when Python's GC reclaimed the objects in
unpredictable order, especially in asyncio background threads.

Changes:
- KuzuGraph.close(): Call _conn.close() and _db.close() explicitly
- conftest kuzu_db_path fixture: Call conn.close() and db.close()
- test_kuzu_queries helper: Call conn.close() and db.close()

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…flicts

The segfault was caused by pytest-asyncio's background event loop thread
conflicting with Kuzu's internal threading. Setting num_threads=1 on
Connection initialization avoids this conflict.

Changes:
- KuzuGraph.__init__: Set num_threads=1 on Connection
- conftest kuzu_db_path fixture: Set num_threads=1
- test_kuzu_queries helper: Set num_threads=1

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The segfault was caused by pytest-asyncio creating background event loops
for all tests when asyncio_mode=auto. Kuzu's C++ library conflicts with
these background threads, causing segfaults during test execution.

Solution:
- Switch asyncio_mode from auto to strict in both pytest.ini files
- Explicitly mark async test files with pytest.mark.asyncio:
  - tests/test_mcp_v2.py
  - tests/test_mcp_tools.py
  - tests/test_lancedb_e2e.py

This prevents pytest-asyncio from creating event loops for kuzu tests
while keeping asyncio working for tests that explicitly opt in.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
pytest-asyncio leaves event loops running after async tests complete,
causing background threads that conflict with Kuzu's C++ library during
subsequent kuzu tests.

Added pytest_runtest_teardown hook to explicitly close lingering event
loops after each test, ensuring no background asyncio threads exist when
kuzu queries execute.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Root cause: importing server.py triggered lancedb module load, which
spawns a LanceDBBackgroundEventLoop daemon thread. This background
thread conflicts with Kuzu's C++ internals during query execution,
causing a segfault in later tests.

- Lazy-import search_lancedb in server.py and mcp_v2.py (only needed
  when search/tables tools are actually called)
- Remove ineffective pytest_runtest_teardown hook that closed main-
  thread event loops but never touched the LanceDB background thread
- Revert asyncio_mode back to auto (strict was part of the failed
  fix chain)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Module-level run_search=None and TABLES=None with _init_search() let
tests monkeypatch mcp_v2.run_search while still deferring the real
search_lancedb import until first use.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ests

The LanceDB background event-loop thread was still being created during
test collection via two paths:
- search_lancedb.py imported lancedb at module level (line 14)
- test_brownfield_overrides.py tests imported java_index_flow_lancedb
  which imports cocoindex.connectors.lancedb

Changes:
- search_lancedb.py: replace `import lancedb` with lazy _connect_lancedb()
  helper that imports on first use
- test_brownfield_overrides.py: gate the 3 tests that trigger
  cocoindex/lancedb imports behind JAVA_CODEBASE_RAG_RUN_HEAVY

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
These tests call run_search() which triggers _connect_lancedb() ->
import lancedb -> LanceDBBackgroundEventLoop daemon thread. On CI
(Ubuntu) the thread race-conditions with Kuzu C++ queries causing a
segfault. On macOS the race didn't manifest due to timing differences.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…led fix chain

The 5 prior fix attempts introduced num_threads=1 and explicit close/GC
in conftest fixtures. These changes ALTERED Kuzu's C++ threading behavior
and likely converted a latent race condition into a reliable segfault on
CI. The original code (default num_threads, no explicit close) ran fine
alongside the LanceDB background thread for months.

The real fix is preventing the LanceDB thread from being created (done
in prior commits). Reverting these workarounds restores the stable state.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…gfault

test_increment_updates_lance_after_touch_java_file imports lancedb
which spawns a LanceDBBackgroundEventLoop daemon thread. This thread
conflicts with Kuzu C++ queries in subsequent tests, causing segfaults.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…Kuzu segfault

index_dir_has_existing_artifacts imported lancedb to check for existing
Lance tables, spawning a LanceDBBackgroundEventLoop daemon thread. This
thread causes Kuzu C++ segfaults in subsequent tests (kuzu is archived
with known thread-safety bugs).

Replace the lancedb import with a filesystem heuristic that checks for
data.lance files inside subdirectories. Same detection capability, zero
thread creation.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@HumanBean17 HumanBean17 force-pushed the fix/installer-ci-and-colors branch from 4cbf7eb to 4641682 Compare June 8, 2026 13:01
@HumanBean17 HumanBean17 closed this Jun 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant