Audit follow-ups and release 1.3.0#7
Conversation
…er the gate - test_cold_run_installs_from_requirements_lock compared the requirements.lock path as a raw string; bash writes '/' joins while pathlib renders '\' on Windows. Extract the -r argument from the pip log and compare as Path. - New tests/test_skill_update.py: update/backup/rollback/auto-update paths (skill_update.py 42% -> 96%). - Cover the multi-intent merge branch in detect_intent and the vec_cache / vec_meta / orphan-pruning family in storage/repo.py (70% -> 92%) using plain stand-in tables so the optional sqlite-vec extension is not required. - CBX_NO_SKILL_AUTO_UPDATE=1 guard in _try_auto_update_skills + conftest: the suite (and any CLI run inside the checkout) used to rewrite the committed .skill_version stamps whenever installed package metadata was stale. Total coverage 78.13% -> 80.64%; the 80% gate passes again. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…gate - scripts/sync_skill_copies.py: src/codebase_index/skill_template/ is the canonical source; the script regenerates the committed installed copies (.claude/.codex/.opencode), the plugin skill (skills/), the shared installer files (skill/), the .skill_version stamps, the plugin.json version and the requirements.lock release tag. --check reports drift and exits 1 for CI. Comparison normalizes CRLF/LF so core.autocrlf worktrees don't false-positive. - CI lint job gains a 'Skill copies in sync' step. - pyproject.toml switches to hatch dynamic versioning: the version now lives only in src/codebase_index/__init__.py; test_plugin_manifest.py reads it from there. - .gitattributes: cbx is a POSIX script without an extension, so *.sh never matched it and Windows checkouts got a CRLF shebang. Pin it to eol=lf. - CONTRIBUTING.md documents the bump-and-sync flow. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ruff check tests was failing on F401 before unrelated changes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…le_id) - resolve_edges did one indexed lookup per symbol edge and up to ~20 full-table LIKE scans per import edge. Now: one GROUP BY for globally unique symbol names, one pass over file paths expanded into an in-memory '/'-aligned suffix map (case-folded like SQLite LIKE), one executemany. Identical resolutions on this repo's index (digest-checked), 7-28x faster at 248 files; the gap grows with file count since LIKE scans disappear. - edges(file_id) was unindexed: replace_edges deletes per file on every incremental update and files deletions cascade into edges - both were full scans (EXPLAIN-verified before/after). - _embed_chunks wrote vector blobs row by row; now a single batched upsert_chunk_vector_blobs (executemany). - recompute_degrees was checked and left alone: its correlated subqueries already use idx_edges_src/idx_edges_dst. - New graph tests pin the resolution semantics: ambiguous symbol names stay unresolved, ambiguous import suffixes need a longer path, import matching stays ASCII case-insensitive. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- New src/codebase_index/service.py owns what the two surfaces duplicated: cache/db path formula (was hand-built in 5+ places), db+config resolution, the explain query rewrite, vector-aware search sessions, and the stats payload. - MCP search_code/explain_code now resolve the embedding backend like the CLI does (warnings to stderr - stdout carries JSON-RPC). Before, hybrid search over MCP silently ran without the vector channel even with embeddings on. - MCP index_stats now reports the per-language graph tier (full/partial) the skill keys on - it was CLI-only. - MCP db resolution unified with the CLI: config loads from CBX_ROOT/cwd; CBX_DB_PATH overrides only the index location (it used to also hijack the config root). stats/watch now honor CBX_DB_PATH like the search family. - cli.py module docstring no longer claims commands are M0 stubs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…auses - _parse_all: the silent fallback from ProcessPool to sequential parsing now prints a stderr warning - a degraded build was indistinguishable from a normal one. - skill auto-update (cli callback + auto_update_if_needed): failures are still swallowed so they never break the user's real command, but they now report to stderr with the exception and a recovery hint. - embedded_chunk_ids / prune_orphan_vectors: except Exception narrowed to sqlite3.OperationalError - the only expected case is vec tables not created yet; real errors propagate instead of silently disabling the vector channel. - Deliberately left alone: _package_version 'unknown' fallbacks, walker/ freshness OSError skips (files vanishing mid-walk), _open_in_browser's platform fallback chain - all are legitimate fallbacks, not hidden failures. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…aims The layout section contained two concatenated trees from different eras (one claimed graph/ was a stub and listed incremental.py / summarize.py that never shipped). Replace with one tree matching the actual source, including service.py and the generated skill-copy note; describe the real incremental mechanism (fingerprints + freshness.py) and the schema version guard instead of nonexistent migrations. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Version bump in src/codebase_index/__init__.py (single source; hatch dynamic versioning propagates to package metadata). - scripts/sync_skill_copies.py stamped plugin.json, requirements.lock (v1.3.0 tarball), and the committed .skill_version copies. - CHANGELOG: 1.3.0 section consolidating this cycle (embedding cache, batched graph build, shared CLI/MCP service layer, skill-copy sync tooling, coverage signals, pagination, error visibility, test-suite hermeticity). - README + docs: install tags moved to @v1.3.0, Project Status rewritten, stale current-release references updated. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4446a498cd
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| for rel, want in expected_files(repo, version).items(): | ||
| path = repo / rel | ||
| if not path.exists(): | ||
| problems.append(f"{rel.as_posix()}: missing") | ||
| elif _norm(path.read_bytes()) != _norm(want): | ||
| problems.append(f"{rel.as_posix()}: differs from skill_template") |
There was a problem hiding this comment.
Detect stale files in synced skill copies
When a file is deleted or renamed under src/codebase_index/skill_template, this check only iterates the files that still exist in the template, so stale files left in .claude/, .codex/, .opencode/, skills/, or the shared installer copy are neither removed by sync nor reported by the new CI --check. That lets obsolete skill scripts/docs remain committed even though the sync tool reports the copies are in sync.
Useful? React with 👍 / 👎.
Both failures predate this branch (CI on main has been red since Jun 5): - test_missing_python_reports_clearly subtracted python's directories from PATH, but on CI runners the system python3 lives in /usr/bin next to mkdir, so bootstrap.sh found it and attempted a real install. PATH now contains only thin wrappers exec'ing the needed coreutils by absolute path. - The golden fixture's 'git commit' silently failed on Windows runners (no git identity, auto-detection fails there), leaving head_commit null. Commit with an explicit -c user.name/user.email and assert it succeeds. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Summary
Eight commits closing all six findings of the 2026-06-09 audit, plus the 1.3.0 release prep:
CBX_NO_SKILL_AUTO_UPDATE=1), coverage 78% → 81% (gate passes again).scripts/sync_skill_copies.py: every committed skill copy and version stamp is generated fromsrc/codebase_index/skill_template/; CI fails on drift. Hatch dynamic versioning makessrc/codebase_index/__init__.pythe single version source.edges(file_id)index, batched vector writes.index_statsreports the graph tier.excepttosqlite3.OperationalError.@v1.3.0.Test plan
python scripts/sync_skill_copies.py --checkcleanresolve_edgesproduce byte-identical resolutions (digest-checked)After merge: tag
v1.3.0on main → release workflow builds, smoke-tests, and publishes the GitHub release.🤖 Generated with Claude Code