feat: dynamic git memory system#16
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4394cf6ac0
ℹ️ 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".
| # Read chunks for target file from DB | ||
| cursor = self.backend.conn.cursor() | ||
| cursor.execute( | ||
| "SELECT content FROM chunks WHERE file_path = ? LIMIT 5", |
There was a problem hiding this comment.
Read the existing chunk code column
The indexed chunks table stores source text in the code column, not content (the same schema is used by both storage backends), so this query raises an OperationalError and the broad except below turns every lookup into []. In any healthy indexed repo, related_files() and semantic_blast_radius() therefore never return semantic relations.
Useful? React with 👍 / 👎.
| from .memory.intent_classifier import IntentClassifier | ||
| from .memory.recency import RecencyConfig | ||
|
|
||
| config = Config.load(workspace_root / ".sia-code" / "config.json") |
There was a problem hiding this comment.
Reuse the resolved MCP configuration
For MCP calls that resolved a non-default index_dir or a shared linked-worktree index, the active config is under context.index_dir, not necessarily workspace_root/.sia-code. Reloading this hard-coded path silently falls back to defaults when it is absent, so settings such as git_dynamic.enabled = false, custom base_branch, thresholds, or narrative_model are ignored during git-context auto-enrichment.
Useful? React with 👍 / 👎.
| reverted_hash = m.group(1) | ||
| return RevertPair( | ||
| reverted_hash=reverted_hash, |
There was a problem hiding this comment.
Normalize abbreviated reverted hashes
The hash-reference regex accepts abbreviated hashes, but this stores the raw prefix as reverted_hash; later filter_reverted() and GitDynamicMemory.file_history() compare those values to full commit hashes exactly. When a revert body uses a short hash like This reverts commit abc1234, the detector reports a pair but the original commit is not filtered from effective history.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 238d7d6305
ℹ️ 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".
| commit_infos = [ | ||
| CommitInfo(hash=c.hash, message=c.message) for c in all_commits | ||
| ] |
There was a problem hiding this comment.
Load commit bodies for hash-based revert filtering
Because the git log parser only captures the subject and this constructs CommitInfo without a body, the detector never sees the standard This reverts commit ... line from normal git-revert bodies. When a recent revert targets an older commit outside the limited file history, or when the revert subject was edited, the reverting commit stays in effective_commits and pollutes owners/narratives instead of being excluded.
Useful? React with 👍 / 👎.
| for r in repo_results: | ||
| if hasattr(r, "chunk") and hasattr(r.chunk, "file_path"): | ||
| r.chunk.file_path = f"{repo_name}/{r.chunk.file_path}" |
There was a problem hiding this comment.
Relativize multi-repo paths before prefixing
In multi-repo searches the subrepos are indexed from resolved absolute paths, so returned chunks already have paths like /workspace/api/src/app.py; prefixing the repo name here produces non-existent paths such as api//workspace/api/src/app.py. This breaks any workflow that copies, opens, or feeds the reported path back into another command; the path should be made relative to the subrepo root before adding the disambiguating repo prefix.
Useful? React with 👍 / 👎.
| project_dir = Path.cwd() | ||
| config = Config.load(project_dir / ".sia-code" / "config.json") |
There was a problem hiding this comment.
Resolve the active index dir for git-context
This command hard-codes Path.cwd()/.sia-code, unlike the rest of the CLI which resolves SIA_CODE_INDEX_DIR and shared linked-worktree indexes. In those setups Config.load silently falls back to defaults when this file is absent, so custom git_dynamic settings such as disabled enrichment, thresholds, or narrative model are ignored for sia-code memory git-context.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: dc89df384c
ℹ️ 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".
| # Prefix file paths with repo name for disambiguation | ||
| for r in repo_results: | ||
| if hasattr(r, "chunk") and hasattr(r.chunk, "file_path"): | ||
| r.chunk.file_path = f"{repo_name}/{r.chunk.file_path}" |
There was a problem hiding this comment.
Avoid mutating frozen chunks in multi-repo search
In a multi-repo workspace, any backend that returns a SearchResult hits this assignment, but SearchResult.chunk is a frozen Chunk dataclass, so setting file_path raises FrozenInstanceError. Because the surrounding try catches all exceptions and passes, every repo with matches contributes no results and multi-repo search can report No results found even when matches exist.
Useful? React with 👍 / 👎.
| console.print( | ||
| f"[dim]Multi-repo: searching across {len(multi_backends)} repos[/dim]" | ||
| ) |
There was a problem hiding this comment.
Preserve structured output in multi-repo mode
When sia-code search --format json or --format csv runs in a registered multi-repo workspace, this diagnostic is printed to stdout before the structured payload. That makes the output invalid JSON/CSV for scripts even though the rest of the command suppresses progress messages for structured formats.
Useful? React with 👍 / 👎.
| hit_files = list({m["file_path"] for m in search_hits["matches"] if "file_path" in m})[:3] | ||
| if hit_files: | ||
| git_context_payload = _compute_git_context( | ||
| context.workspace_root, hit_files, limit=3 | ||
| ) |
There was a problem hiding this comment.
Read file paths from serialized chunks
search_hits["matches"] is produced by _serialize_result, which stores the path under match["chunk"]["file_path"], not at the top level. This condition therefore never collects any hit_files, so engineering_bootstrap always returns an empty git_context despite having search hits to enrich.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 76b1b61802
ℹ️ 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".
| max_files_per_commit: int = 20 # squash dilution guard | ||
| working_window_days: int = 14 | ||
| recency_halflife_days: float = 30.0 | ||
| base_branch: str = "main" |
There was a problem hiding this comment.
Wire base_branch into BranchResolver
This adds git_dynamic.base_branch, but none of the new GitDynamicMemory(...) call sites pass it into BranchResolverConfig, so the resolver still uses its built-in main/master/develop defaults. In repos whose comparison branch is configured to something else (for example release), memory git-context and MCP git context compute merge-base and cross-branch history against the wrong branch despite the setting being present.
Useful? React with 👍 / 👎.
| if f == file_path: | ||
| continue |
There was a problem hiding this comment.
Normalize target paths before co-change filtering
When callers pass an absolute path, which is the form emitted by indexed chunks and accepted by git log, diff-tree --name-only still returns repo-relative file names. This equality then fails to skip the target file, so the file can be counted as its own co-change and appear in its own blast radius with high coupling; normalize file_path to the repo-relative path before comparing against files.
Useful? React with 👍 / 👎.
| # After successful load, prevent future network calls | ||
| # Model is now cached locally — no need to hit HF Hub again | ||
| import os | ||
| os.environ["HF_HUB_OFFLINE"] = "1" |
There was a problem hiding this comment.
Do not force the daemon offline after one model
This sets HF_HUB_OFFLINE process-wide after the first model load. If the same long-lived daemon later receives a request for a different embedding.model that is not already cached, SentenceTransformer cannot download it and embedding requests fail, even though the daemon explicitly supports multiple models via self.models.
Useful? React with 👍 / 👎.
| dynamic_git = _compute_git_context( | ||
| context.workspace_root, result.related_files[:3], | ||
| limit=3, include_blast_radius=False, | ||
| ) |
There was a problem hiding this comment.
Pass git-context paths that Git can match
result.related_files comes from CausalTracer._normalize_path, which strips the leading slash from absolute chunk paths (for example /workspace/repo/src/app.py becomes workspace/repo/src/app.py). Passing those strings to _compute_git_context from workspace_root makes the underlying git log -- <path> match no tracked file in normally indexed repos, so dynamic_git is empty even when memory_trace found related files.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1f6a139075
ℹ️ 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".
| if not repo_config_path.exists(): | ||
| config.save(repo_config_path) |
There was a problem hiding this comment.
Refresh sub-repo config before rebuilding
In a multi-repo workspace that has already been indexed, this guard prevents copying changed workspace config into .sia-code/repos/<repo>/config.json; the subprocess later loads that stale file, so even sia-code index --clean . continues using old exclude patterns, embedding model/dimensions, and other settings for existing subrepos. That can produce indexes inconsistent with the active config after any config change.
Useful? React with 👍 / 👎.
| " except Exception:\n" | ||
| " backend.create_index()\n" | ||
| "coord = IndexingCoordinator(config, backend)\n" | ||
| "stats = coord.index_directory(repo_dir)\n" |
There was a problem hiding this comment.
Use incremental indexing for multi-repo updates
When sia-code index --update . runs in a multi-repo workspace, the child process opens the existing repo index and then calls the full index_directory path instead of the incremental path with the hash cache/chunk index. Full indexing only upserts chunks it sees and does not remove chunks for deleted files or old chunk boundaries, so update mode leaves stale chunks searchable in each subrepo.
Useful? React with 👍 / 👎.
39d2ec8 to
e8b6886
Compare
On Python 3.13 with macOS ARM64 (Apple Silicon), importing usearch's native extension before calling SentenceTransformer.encode() causes a segmentation fault (signal 11). This is a shared-library symbol conflict between usearch's C++ bindings and the tokenizers/torch native extensions. Root cause: usearch.index was imported at module level in usearch_backend.py, which meant it was always loaded before the embedding model. When store_chunks_batch() later called encode(), the process crashed with SIGSEGV. Fix: - Move usearch import from module-level to a lazy helper (_lazy_usearch) - In create_index() and open_index(), pre-initialize the embedding model BEFORE importing usearch, ensuring torch/tokenizers native libs load first - Use TYPE_CHECKING guard for type annotations Tested: sia-code index --clean on a test project and ~/.dotfiles now successfully indexes files (previously produced 0 chunks with exit 0).
…t radius, and revert detection - New modules: recency.py, git_dynamic.py, blast_radius.py, revert_detector.py, intent_classifier.py, diff_analyzer.py, semantic_grouper.py - Consolidated CLI: 'memory git-context' command combining all git context features - Consolidated MCP: 'git_context' tool + auto-enrichment in research/bootstrap/trace - Auto-escalating flan-t5 model (large on 16GB+, base otherwise) as fact-rewriter - Exponential recency decay with configurable halflife (30d default) - Branch/worktree awareness with cross-branch search and relevance scoring - Squash-merge dilution guard for co-change coupling - Revert detection via message patterns + fuzzy Jaccard matching - Zero new dependencies (uses existing GitPython + sentence-transformers) - 23 tests passing (8 unit + 15 integration)
- Auto-detect multi-repo workspace (folders with git sub-directories) - Fan-out indexing: each repo indexed independently with own .sia-code/ - Multi-repo registry (.sia-code/multi-repo.json) for aggregated search - Aggregated search: queries all registered sub-repo indexes, merges results - Embed daemon auto-start: _try_auto_start_daemon() in _get_embedder() Uses subprocess.Popen (not in-process fork which causes sys.exit) - MPS device detection in both daemon and fallback embedder - HF_HUB_OFFLINE=1 set after first model load (prevents network calls) - Model stays warm via daemon (1h idle timeout)
- Fix ValueError: shapes (768,) and (1,768) not aligned in _vector_search by flattening query vector with .flatten() - Pre-warm embed daemon before multi-repo fan-out loop - Add per-repo timing to multi-repo indexing output
…h isolation - Indexes stored at .sia-code/repos/<name>/ instead of <repo>/.sia-code/ No pollution of sub-repo directories - Each repo indexed in isolated subprocess (5 min timeout per repo) One repo crashing doesn't kill the entire fan-out - sqlite-vec warning fires once per session (class-level dedup) - Subprocess env sets HF_HUB_OFFLINE=1 to prevent network calls
- Scale per-repo timeout from estimated file count (5m..30m) - Save multi-repo registry before and during fan-out so partial runs are visible - Aggregate Error: Sia Code not initialized. Run 'sia-code init' first. across workspace .sia-code/repos even if run was interrupted - Increase embedding batch size on higher-memory machines (96/128) - Fallback multi-repo status when registry missing but repos dir exists
- add repo-specific multi-repo override config schema - add built-in ai-toolkit indexing policy (core first-party focus) - estimate chunks for heavy repos and size timeout from chunk count - persist per-repo status, estimated chunks, and last error in registry - improve multi-repo status output with inferred indexed state for legacy runs
- run light repos concurrently using multi_repo.fanout_concurrency (default 2) - keep heavy repos serialized based on chunk threshold - preserve subprocess crash isolation and per-repo registry updates - default multi-repo concurrency to 2 for faster workspace indexing
e8b6886 to
7fc74a9
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7fc74a9fbc
ℹ️ 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".
| "backend = create_backend(sia_dir, config, suppress_stdout_notices=True)\n" | ||
| "if do_clean:\n" | ||
| " idx = sia_dir / 'index.db'\n" | ||
| " if idx.exists(): idx.unlink()\n" |
There was a problem hiding this comment.
Clean stale repo artifacts before backend detection
When sia-code index --clean . is run after a sub-repo index was created with a different storage backend, this constructs the backend before removing the old index artifacts. create_backend() checks the existing index.db/vectors.usearch and can exit on a backend mismatch before the clean branch runs, so multi-repo clean cannot migrate or rebuild those subrepos; delete the stale artifacts before backend creation, as the single-repo clean path does.
Useful? React with 👍 / 👎.
| recommend_repo_timeout_seconds, | ||
| ) | ||
|
|
||
| if is_multi_repo_workspace(directory): |
There was a problem hiding this comment.
Honor the multi-repo opt-out flag
When a workspace has multiple child git repos and the user sets multi_repo.enabled = false, this unconditional check still takes the fan-out path and returns before the normal single-repo indexing flow. That makes the new opt-out config ineffective and prevents users from indexing the workspace as one project in exactly the scenario the flag is meant to control.
Useful? React with 👍 / 👎.
| if not hist.effective_commits: | ||
| console.print(f"[yellow]No history found for {fp}[/yellow]") | ||
| continue |
There was a problem hiding this comment.
Keep git-context JSON output parseable
When sia-code memory git-context --format json is called with any requested file that has no history, this warning is emitted to stdout before the JSON payload; if all files miss, the later no-results branch emits only rich text. In both cases scripts expecting JSON get invalid output, so diagnostics should be suppressed for JSON or represented inside the JSON result.
Useful? React with 👍 / 👎.
- add lightweight repo profile awareness (general/data_science/annotation_platform) - add built-in CVAT indexing override for annotation-platform repos - prioritize cvat apps/core/ui/sdk first-party source - defer serverless/utils/cvat-cli and lazy-index tests/docs/helm/ai-models - exclude nested test trees with **/tests/** in CVAT first pass - surface repo profile in multi-repo status output
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5c52813d4d
ℹ️ 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".
| # Check configured base first | ||
| candidates = [self.config.base_branch] + self.config.base_branch_fallbacks | ||
| for branch in candidates: | ||
| check = self._git("rev-parse", "--verify", f"refs/heads/{branch}", check=False) |
There was a problem hiding this comment.
In CI or feature-branch checkouts where the configured base exists only as origin/main and no local refs/heads/main has been created, this check misses the base branch and falls back to the current/another local branch. In that scenario get_branch_context() uses the wrong base (often the current branch), so cross-branch history is skipped even with cross_branch_enabled; check remote refs such as refs/remotes/*/{branch} before falling back.
Useful? React with 👍 / 👎.
| if self.embedding_enabled: | ||
| self._get_embedder() |
There was a problem hiding this comment.
Defer embedder loading on read-only usearch opens
For legacy/usearch indexes with embeddings enabled, every read-only open now loads or auto-starts the embedding model before SQLite is usable. Lexical-only flows such as sia-code search --regex, status/health checks, or scripts on a host without the model cached can now fail or block on model download even though they only need the existing FTS database; keep the embedder lazy until semantic search or indexing actually calls _embed().
Useful? React with 👍 / 👎.
- use larger chunks for data_science repos - use even larger chunks for annotation_platform repos - reduce first-pass chunk volume for ai-toolkit and CVAT - keep repo-specific path policies while lowering embedding/storage cost
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0658c36205
ℹ️ 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".
| config.indexing.include_patterns = override.index_first | ||
|
|
||
| merged_excludes = list(config.indexing.exclude_patterns) | ||
| for group in (override.dependency_tier, override.lazy_index, override.skip): |
There was a problem hiding this comment.
Honor dependency-tier indexing flag
When a multi-repo workspace sets multi_repo.heavy_repo_run_dependency_tier = true or adds dependency_tier patterns expecting those secondary files to remain searchable, this loop still treats dependency_tier exactly like lazy_index and skip by appending it to exclude_patterns. As a result, the dependency-tier files for the built-in heavy repo profiles are never indexed and the new config flag has no effect.
Useful? React with 👍 / 👎.
- add embedding granularity/budget config fields - use smaller bge-small model for heavy repo profiles when cached - add persistent content-addressed embedding cache across runs - embed only selected chunks per file for heavy profiles - pass batch size through daemon protocol/client/server - add safer daemon retry fallback in embedding path - keep vector writes stable by deduping selected chunk ids - add local heavy-repo benchmark script
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bc00706659
ℹ️ 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".
| import transformers # noqa: F401 | ||
|
|
||
| self._can_model = True |
There was a problem hiding this comment.
Check cache before enabling narrative models
In environments where transformers is installed but the selected google/flan-t5-* weights are not already cached, this enables the model path and memory git-context/MCP git-context calls (which include narratives by default) will try to load or download a large model before falling back to the heuristic. That can hang or fail local/offline workflows that should still be instant with the heuristic narrative; gate this on the model being locally available or an explicit config opt-in rather than just the import.
Useful? React with 👍 / 👎.
- data_science repos: 24 vectors/file - annotation_platform repos: 16 vectors/file - improves research recall while keeping timeout at 300s floor for current heavy profiles
- fix multi-repo search dropping all results due to immutable chunk mutation - make CLI research multi-repo aware by aggregating repo-local research results - use hybrid seeding for budgeted indexes in MultiHopSearchStrategy - normalize displayed paths to repo-relative multi-repo paths
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
- rank budgeted semantic vectors by chunk type and role hints per file - prefer class/method/function/definition chunks over low-value comments/blocks - add query variant expansion for research seeding - synthesize code-like identifiers (CamelCase/snake_case/API forms) - aggregate 2-3 rewritten seed queries in MultiHopSearchStrategy - use hybrid seeding for budgeted indexes
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
- baseline fast policy for any repo: larger chunks, higher merge threshold, budgeted semantic indexing - default general repos to 32 vectors/file under budget mode - keep stronger profile-specific tuning for data_science and annotation_platform repos
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
- make FLAN query rewrite opt-in via config and cached-only - cache FLAN rewrite summarizer in-process when enabled - keep heuristic+BGE-assisted rewrite as default path - gate multi-repo fan-out on multi_repo.enabled - honor heavy_repo_run_dependency_tier in repo config - use incremental indexing for multi-repo update subprocesses - clean stale backend artifacts before multi-repo clean rebuilds - keep git-context JSON output parseable with structured warnings - resolve remote base branches like origin/main - gate FLAN narrative use on local model cache
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ecef62f691
ℹ️ 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".
| return | ||
|
|
||
| # Table format | ||
| for fp, entry in all_results.items(): |
There was a problem hiding this comment.
When sia-code memory git-context finds history in the default table format, this loop is still indented as part of the preceding if not all_results: suite (after a return). For non-empty results that whole suite is skipped, so the command silently exits without printing any git context; for empty results it returns before reaching the loop. Dedenting this block restores the advertised default output path.
Useful? React with 👍 / 👎.
- Add RepoRankingContext and build_ranking_context helper - Score repos by: cwd boost + query name match + profile hint match - Skip zero-relevance repos in research when positive-score repos exist - Apply path bonus for first-party code, penalty for tests/docs/vendor - Set flan_query_rewrite=True by default (cached-only remains) - Improves multi-repo workspace research precision dramatically
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 45737dd726
ℹ️ 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".
| self._first_party_re = _re.compile(_FIRST_PARTY_PATTERNS[0], _re.IGNORECASE) | ||
| self._low_value_re = _re.compile(_LOW_VALUE_PATTERNS[0], _re.IGNORECASE) |
There was a problem hiding this comment.
Compile the full ranking regexes
In any registered multi-repo workspace, sia-code search and research call build_ranking_context(), which constructs this class; because _FIRST_PARTY_PATTERNS and _LOW_VALUE_PATTERNS are plain strings, indexing them with [0] passes only '(' to re.compile, raising a regex parse error before reranking can happen. This makes multi-repo search/research fail as soon as they reach repo-aware ranking; compile the full string instead of its first character.
Useful? React with 👍 / 👎.
| if vectors is not None: | ||
| for j, chunk_id in enumerate(chunk_ids): | ||
| self._vector_insert(int(chunk_id), vectors[j]) | ||
| selected_indices = self._select_semantic_embedding_indices(chunks) |
There was a problem hiding this comment.
Remove vectors for chunks dropped by the budget
When a file is reindexed in budget mode and a previously embedded chunk falls outside selected_indices (for example after switching an existing index from chunk mode to budget mode, or after the file grows and the top-N selection changes), this only upserts vectors for the newly selected chunks and leaves any existing vector rows for the omitted chunk IDs behind. Semantic/hybrid search will still scan those vectors, so max_vectors_per_file/semantic_chunk_types are not actually enforced and stale embeddings can be returned for chunks that were deliberately excluded.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e016bcd292
ℹ️ 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".
| total_files = sum(s.get("indexed_files", 0) for s in all_stats) | ||
| total_chunks = sum(s.get("total_chunks", 0) for s in all_stats) | ||
| console.print(f" Total: {total_files} files, {total_chunks} chunks across {len(all_stats)} repos") | ||
| return |
There was a problem hiding this comment.
Keep --watch active for multi-repo indexing
When sia-code index --watch . is run at a registered multi-repo workspace, execution takes this multi-repo branch and returns immediately after the one-shot fan-out index, so the watch-mode block later in this command is never reached. In that context file changes are not monitored even though the CLI accepted --watch; the multi-repo path needs to enter an equivalent watcher or defer this return when watch is set.
Useful? React with 👍 / 👎.
| embedding_granularity=config.embedding.granularity, | ||
| max_vectors_per_file=config.embedding.max_vectors_per_file, | ||
| semantic_chunk_types=config.embedding.semantic_chunk_types, |
There was a problem hiding this comment.
Honor budgeted embeddings for usearch indexes
When the effective backend is usearch (explicitly configured or auto-detected from a legacy index), these budget controls are forwarded but UsearchSqliteBackend never consumes them; its store_chunks_batch() still embeds every chunk. In multi-repo/heavy-repo indexing, build_repo_config() relies on embedding.granularity='budget' and max_vectors_per_file to cap semantic work, so usearch users silently bypass the cap and can hit the same full-repo embedding cost/timeouts the new policy is meant to avoid.
Useful? React with 👍 / 👎.
Summary
Introduces an on-demand git-memory system that computes file history, blast radius, revert-awareness, and semantic meaning dynamically (instead of static batch).
New Features
Core Modules (
sia_code/memory/)recency.py— Exponential decay with configurable halflife (30d default) + 14-day working windowgit_dynamic.py— GitDynamicMemory orchestrator + BranchResolver (cross-branch search, worktree awareness, merge_base detection)blast_radius.py— Co-change coupling analysis with squash-merge dilution guardrevert_detector.py— Message regex + fuzzy Jaccard matching for revert detectionintent_classifier.py— Heuristic commit classification from conventional commit prefixesdiff_analyzer.py— Auto-escalating flan-t5 fact-rewriter (large on 16GB+, base otherwise)semantic_grouper.py— Reuses existing index embeddings for semantic file relationsConsolidated Interface
git_contexttool + auto-enrichment inresearch,engineering_bootstrap,memory_tracesia-code memory git-context <files...>with--no-blast-radius,--no-narrative,--format jsonKey Design Decisions
Tests
Usage