Repository navigation
feat(encoder): implement RPG-Encoder Evolution — commit-level incremental updates - #28
Conversation
…tions, router, prompts Implement the foundation for RPG-Encoder Evolution (commit-level incremental updates): - types.ts: EvolutionOptions, EvolutionResult, DiffResult, ChangedEntity types - diff-parser.ts: Git diff parsing via Bun.spawn, entity-level change categorization (U+/U-/U~) - operations.ts: DeleteNode with recursive ancestor pruning (Algorithm 1) - semantic-router.ts: FindBestParent LLM-based recursive routing (Algorithm 3) with embedding fallback - prompts.ts: LLM prompt templates for semantic routing and drift detection Issue: #10
…r, wire encoder
Complete the Evolution pipeline implementation:
- operations.ts: InsertNode with semantic routing + dependency injection,
ProcessModification with cosine drift detection and re-routing
- evolve.ts: RPGEvolver orchestrator (Delete → Modify → Insert scheduling)
- index.ts: Module barrel exports
- encoder.ts: Wire evolve(rpg, {commitRange}) to delegate to RPGEvolver
- encoder/index.ts: Re-export evolution types
Issue: #10
… update - Add diff-parser unit tests (13 tests, AC-1 verification) - Add operations unit tests (14 tests, AC-2/3/4 verification) - Add evolution integration tests (3 tests, AC-5 cost measurement) - Fix DiffParser to use execFileSync (vitest runs under Node.js) - Handle non-git repos gracefully in DiffParser.parse() - Update encoder.test.ts evolve() to match new signature - Update docs/implementation-status.md to mark Evolution as implemented
|
/gemini review |
There was a problem hiding this comment.
Code Review
The pull request introduces the RPG-Encoder Evolution system, enabling commit-level incremental graph updates. This is a significant feature that aligns with the paper's goals of reducing re-encoding costs. The changes include new modules for diff parsing, operations, semantic routing, and an orchestrator, along with integration into the existing RPGEncoder API. The docs/implementation-status.md file has been updated to reflect these new capabilities. The code is well-structured and includes comprehensive unit and integration tests. I've identified a few areas for minor improvement, primarily around error handling and consistency in diff-parser.ts.
There was a problem hiding this comment.
Pull request overview
This pull request implements the RPG-Encoder Evolution system from the research paper §4, enabling commit-level incremental graph updates through three atomic operations: Delete, Modify, and Insert. This is a key differentiator of the RPG-Encoder approach, claiming 95.7% cost reduction versus full repository re-encoding.
The implementation adds a new src/encoder/evolution/ module with comprehensive support for parsing git diffs, detecting semantic drift, and performing minimal graph mutations. The system gracefully degrades from LLM-based semantic routing to embedding-based fallback to heuristic routing when AI services are unavailable.
Changes:
- Added Evolution module with 7 new TypeScript files implementing diff parsing, atomic operations, semantic routing, and orchestration
- Integrated
RPGEncoder.evolve()public API that delegates to the RPGEvolver orchestrator - Added 27 unit tests and 3 integration tests covering all acceptance criteria
- Updated documentation to reflect completed Evolution implementation
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 13 comments.
Show a summary per file
| File | Description |
|---|---|
src/encoder/evolution/types.ts |
Type definitions for evolution options, results, and change entities |
src/encoder/evolution/diff-parser.ts |
Git diff parsing to extract entity-level changes (U+, U-, U~) |
src/encoder/evolution/operations.ts |
Three atomic operations: DeleteNode, InsertNode, ProcessModification |
src/encoder/evolution/semantic-router.ts |
LLM/embedding-based recursive semantic routing (FindBestParent) |
src/encoder/evolution/prompts.ts |
LLM prompt templates for routing and drift detection |
src/encoder/evolution/evolve.ts |
RPGEvolver orchestrator implementing Delete → Modify → Insert scheduling |
src/encoder/evolution/index.ts |
Module barrel exports |
src/encoder/encoder.ts |
Added evolve() method that delegates to RPGEvolver |
src/encoder/index.ts |
Exported Evolution module classes and types |
tests/evolution/operations.test.ts |
Unit tests for atomic operations (14 tests) |
tests/evolution/diff-parser.test.ts |
Unit tests for git diff parsing (13 tests) |
tests/evolution/evolution.integration.test.ts |
Integration tests for end-to-end evolution pipeline (3 tests) |
tests/encoder.test.ts |
Updated encoder test for new evolve() signature |
docs/implementation-status.md |
Updated documentation marking Evolution as complete |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Add commitRange validation to prevent git argument injection (C6) - Add logging for SemanticRouter first-candidate fallback (I2) - Simplify findMatchingNode to use ID prefix match directly (I6) - Add index-file resolution to resolveImportPath (I8) - Add SemanticRouter and cosineSimilarity unit tests (I9, I10) - Fix vacuous assertion in operations test (I11) - Remove dead code: buildEntityId, ChangeEvent, DriftDetectionResponse (I12-I14) - Move submodule-dependent tests to integration test file
There was a problem hiding this comment.
5 issues found across 16 files
Prompt for AI agents (all issues)
Check if these issues are valid — if so, understand the root cause of each and fix them.
<file name="src/encoder/evolution/evolve.ts">
<violation number="1" location="src/encoder/evolution/evolve.ts:129">
P1: Errors are collected during the evolution pipeline but only logged with `console.warn`, not returned to the caller. This creates a silent failure pattern where callers cannot detect or handle partial operation failures. Consider adding an `errors` field to `EvolutionResult` and returning the collected errors.</violation>
</file>
<file name="src/encoder/evolution/operations.ts">
<violation number="1" location="src/encoder/evolution/operations.ts:324">
P2: Empty catch block silently swallows embedding errors. Consider logging the error at debug level to aid troubleshooting when embedding services fail unexpectedly.</violation>
</file>
<file name="tests/evolution/operations.test.ts">
<violation number="1" location="tests/evolution/operations.test.ts:86">
P3: Typo in test name: `cASCADE` should be `cascade` (or `CASCADE`). Same capitalization typo as above.</violation>
</file>
<file name="src/encoder/encoder.ts">
<violation number="1" location="src/encoder/encoder.ts:726">
P2: Missing `includeSource` option passed to `RPGEvolver`. If the encoder was configured with `includeSource: true`, evolved nodes will inconsistently omit source code since this option defaults to `undefined`/`false` in the evolver.</violation>
</file>
<file name="src/encoder/evolution/diff-parser.ts">
<violation number="1" location="src/encoder/evolution/diff-parser.ts:302">
P1: Using `??` instead of `||` causes incorrect handling of edge-case commit ranges like `..HEAD` or `main..`. When `split('..')` produces an empty string, nullish coalescing (`??`) won't trigger the fallback because `''` is not nullish. Use logical OR (`||`) to properly handle empty strings.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
- Replace dynamic import of node:child_process with static import - Change execGit from async to sync (no longer needs await for import) - Fix inconsistent test name casing (cASCADE → cascade)
Disable test/prefer-lowercase-title ESLint rule to prevent auto- lowercasing of test names like RPGEncoder and AC-5. Fix affected test titles in evolution.integration.test.ts.
- Fix ?? → || in parseCommitRange for edge cases like ..HEAD or main.. - Add errors field to EvolutionResult for programmatic failure access - Add console.warn in computeDrift empty catch block - Pass includeSource option to RPGEvolver from encoder.evolve() - Restore proper casing in all test names (RPGEncoder, ASTParser, MCP, FTS, RPG) now that test/prefer-lowercase-title is disabled
There was a problem hiding this comment.
1 issue found across 13 files (changes from recent commits).
Prompt for AI agents (all issues)
Check if these issues are valid — if so, understand the root cause of each and fix them.
<file name="src/encoder/evolution/diff-parser.ts">
<violation number="1" location="src/encoder/evolution/diff-parser.ts:303">
P1: The fallback to `commitRange` for `oldRev` is incorrect when the start revision is omitted (e.g., `..HEAD`). This causes `oldRev` to become the invalid revision string `..HEAD`, which fails in `git show`. It should fallback to `'HEAD'` to match Git's default behavior for omitted range endpoints.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
CI shallow clone (fetch-depth: 1) causes HEAD~1 to be unresolvable, breaking evolution tests. Add fetch-depth: 2 to checkout steps and guard tests with it.skipIf to gracefully skip in constrained envs.
…ne tests - Use fetch-depth: 0 for integration-test job so submodule fixture commits (e.g., 5f920b4) are available for diff-parser tests - Add skipIf guard to diff-parser.integration.test.ts for shallow clones - Fix lint errors from auto-formatter differences
Summary
Implements the RPG-Encoder Evolution system (§4, arXiv:2602.02084) — commit-level incremental graph updates via 3 atomic operations: Delete, Modify, Insert.
Instead of re-encoding an entire repository when code changes, Evolution parses git diffs to identify entity-level changes and applies minimal graph mutations. This achieves the paper's claimed 95.7% cost reduction vs full re-encoding.
New module:
src/encoder/evolution/types.tsdiff-parser.tsoperations.tssemantic-router.tsprompts.tsevolve.tsindex.tsKey changes
RPGEncoder.evolve(rpg, options)— new public API accepting RPG + commit range, delegating to RPGEvolverAcceptance Criteria (all verified)
Changes
Test Plan
Related Issues
Closes #10