Skip to content

Commit f06ff60

Browse files
feat(intelligence): Phase 4 evidence packs + runtime API (RAN-161) (#30)
* checkpoint: pre-yolo 20260403-163239 * fix(security): add npm override for lodash >= 4.17.24 to fix HIGH CVEs Adds lodash >= 4.17.24 override in package.json to resolve two CVEs (HIGH code injection via _.template, MODERATE prototype pollution via _.unset/_.omit) in transitive dependencies swagger-ui-react and @antv/g6. All lodash instances now resolve to 4.18.1. npm audit reports 0 vulnerabilities. Co-Authored-By: Paperclip <noreply@paperclip.ing> * feat(intelligence): implement capability matrix and deterministic query planner (RAN-148) Adds Phase 3 of the Repository Intelligence system: - CapabilityMatrix: static per-language × per-dimension capability registry (EXACT/PARTIAL/LEXICAL_ONLY/UNSUPPORTED) for Java, TypeScript, JavaScript, Python, Go, C#, Rust, and lexical-only languages. - QueryPlanner (@service): deterministic routing to GRAPH_FIRST, MERGED, LEXICAL_FIRST, or DEGRADED paths based solely on QueryType + language + capability level. No LLM, no probabilistic logic. - QueryType enum: FIND_SYMBOL, FIND_REFERENCES, FIND_CALLERS, FIND_DEPENDENCIES, SEARCH_TEXT, FIND_CONFIG. - CapabilityDimension enum: 9 analysis dimensions. - QueryPlan record: carries route, capability snapshot, and optional degradation note. - GET /api/capabilities endpoint (optional ?language= filter). - get_capabilities MCP tool (32nd tool). - 40 unit + determinism tests (20 CapabilityMatrixTest, 20 QueryPlannerTest). Co-Authored-By: Paperclip <noreply@paperclip.ing> * feat(intelligence): Phase 1 provenance model, repository identity, file inventory (RAN-146) Implements the foundational contracts for the Repository Intelligence layer: - intelligence/ package: Provenance, RepositoryIdentity, FileInventory, FileEntry, FileClassification, CapabilityLevel, ArtifactManifest records - Provenance stored via prov_* keys in CodeNode.properties (round-trips through Neo4j) - RepositoryIdentity resolves git URL, commit SHA, branch from git CLI at analysis time - FileInventory builds a deterministic sorted list of all discovered files with classification heuristics (source/config/doc/test/generated) - GraphBuilder now accepts Provenance as constructor parameter (not a mutable setter) - Analyzer and EnrichCommand stamp provenance on all nodes during pipeline - BundleCommand upgraded to use ArtifactManifest record (repo identity, inventory summary) - Tests: ProvenanceTest (6), FileInventoryTest (8), ArtifactManifestTest (5), ProvenanceIntegrationTest (2) — all nodes carry provenance + determinism verified Addresses PE architecture review blocking constraints from RAN-150: - BLOCKING 1: Provenance uses properties map (prov_* prefix), not direct CodeNode fields - BLOCKING 2: Provenance is a GraphBuilder constructor parameter, not a setter - BLOCKING 3: FileEntry added to intelligence/ without modifying DiscoveredFile Co-Authored-By: Paperclip <noreply@paperclip.ing> * fix(intelligence): address PE architecture review — RepositoryIdentity constructor + AnalysisCache hash reuse - GraphBuilder now accepts RepositoryIdentity + extractorVersion as constructor params; Provenance is derived internally (never constructed externally by callers) - Analyzer and EnrichCommand updated to pass RepositoryIdentity directly to GraphBuilder - AnalysisCache.getHashForPath() added for reverse path→hash lookup - buildFileInventory() now populates FileEntry.contentHash from cache (no file re-reads) Addresses BLOCKING 2 and BLOCKING 3 from PE review on RAN-150. Co-Authored-By: Paperclip <noreply@paperclip.ing> * fix(intelligence): address CTO review — TreeMap determinism + Neo4j provenance round-trip (RAN-146) - FileInventory.countsByClassification() now uses TreeMap for deterministic key ordering (fixes non-deterministic HashMap iteration in manifest by_classification field) - Provenance.fromProperties() handles String schema version from Neo4j round-trip (bulkSave stores Integer props as String via .toString(); parseInt handles both types) - Add ProvenanceNeo4jRoundTripTest: two mock-based tests verifying prov_* -> prop_prov_* -> prov_* round-trip including schemaVersion Integer/String coercion and null fields Co-Authored-By: Paperclip <noreply@paperclip.ing> * fix(intelligence): fix HashMap determinism in FileInventory + gitignore entries (RAN-154) - countsByLanguage(): use TreeMap::new for deterministic alphabetical key ordering - toSummary() byLang: add thenComparing secondary sort to break ties alphabetically - toSummary() byCls: use LinkedHashMap::new to preserve TreeMap insertion order - .gitignore: add playwright-report/ and test-results/ frontend build artifacts Co-Authored-By: Paperclip <noreply@paperclip.ing> * fix(intelligence): address PE review — cpp capability table + QueryPlanner profile guard (RAN-155) - Add CPP_CAPS table (distinct from C# — no ORM, lexical-only auth) - Add explicit case "cpp","c++" to CapabilityMatrix.tableFor() - Add "cpp" to asSerializableMap() hardcoded language list - Remove incorrect CSHARP_CAPS fallback for cpp in ANTLR_LANGUAGES branch - Add @Profile("serving") to QueryPlanner so it is not instantiated during indexing CLI runs Co-Authored-By: Paperclip <noreply@paperclip.ing> * fix(intelligence): fix Process resource leak in RepositoryIdentity.runGit() Process does not implement AutoCloseable in Java 25, so try-with-resources is not applicable. Use try-finally with proc.destroy() to ensure OS process handles are always released, resolving SonarQube C-Reliability finding. Closes RAN-156 Co-Authored-By: Paperclip <noreply@paperclip.ing> * fix(intelligence): close InputStream explicitly in runGit() — SonarQube S2095 Wrap proc.getInputStream() in try-with-resources so the InputStream is closed after readAllBytes(). proc.destroy() in the finally block remains to terminate the child process; the InputStream close ensures the file descriptor is released immediately rather than waiting on GC. Co-Authored-By: Paperclip <noreply@paperclip.ing> * feat(intelligence): Phase 2 lexical intelligence — doc comment index + snippet store (RAN-147) New package: intelligence/lexical - CodeSnippet: bounded source snippet record (path, line range, language, provenance) - LexicalResult: query result record (node, score, matchedField, snippet, provenance) - DocCommentExtractor: extracts Javadoc/JSDoc, Go/Rust line comments, Python docstrings - SnippetStore: extracts bounded code snippets (max 50 lines) from source files - LexicalEnricher: populates lex_comment and lex_config_keys properties before Neo4j load - LexicalQueryService: findByIdentifier, findByDocComment, findByConfigKey (serving profile) Infrastructure changes: - GraphStore: add searchLexical() + lexical_index (standard analyzer on prop_lex_* fields) - EnrichCommand: inject LexicalEnricher, add enrichment step before Neo4j bulk load - lexical_index created in both GraphStore.bulkSave() and EnrichCommand Tests: 24 new tests across DocCommentExtractor, SnippetStore, LexicalEnricher All 1591 tests passing. Co-Authored-By: Paperclip <noreply@paperclip.ing> * test(intelligence): Phase 1-3 test execution — edge cases, cross-language, RepositoryIdentity (RAN-159) - RepositoryIdentityTest (8 tests): non-git dir graceful null, commit SHA on git repo, detached HEAD branch normalised to null, record equality/null safety - ProvenanceEdgeCasesTest (6 tests): empty dir, single-file, unsupported-language-only, mixed-language (Java/TS/Python/Go), no-git-history null provenance fields, mixed-language determinism - LexicalCrossLanguageTest (11 tests): TypeScript/JavaScript block comments, Python triple-quoted docstrings (single-line and multiline), Go line comments, cross-language determinism, DocCommentExtractor direct calls All 1616 tests pass (0 failures, 0 errors, 31 skipped). Co-Authored-By: Paperclip <noreply@paperclip.ing> * fix(intelligence): explicit UTF-8 in RepositoryIdentity.runGit() — DM_DEFAULT_ENCODING (RAN-160) Replace new String(is.readAllBytes()) with new String(is.readAllBytes(), StandardCharsets.UTF_8) to eliminate SpotBugs HIGH DM_DEFAULT_ENCODING finding on RepositoryIdentity.java:44. This was the sole blocker gating all Phase 1-3 PRs from merge. Co-Authored-By: Paperclip <noreply@paperclip.ing> * feat(intelligence): Phase 4 evidence packs + runtime API — RAN-161 - EvidencePack record + EvidencePackRequest + EvidencePackAssembler (@service) - ArtifactMetadata record with SHA-256 integrity hash computation - IntelligenceController: GET /api/intelligence/{evidence,manifest,capabilities} - McpTools: get_evidence_pack + get_artifact_metadata @mcptool methods - CodeIqConfig: maxSnippetLines property (default 50, configurable) - Tests: EvidencePackAssemblerTest, IntelligenceControllerTest, McpToolsEvidenceTest (16 tests) - Fix existing McpToolsTest + TopologyEndpointTest for updated constructor Co-Authored-By: Paperclip <noreply@paperclip.ing> * fix(intelligence): Phase 4 critical bugs — C++ dead code, fetchReferences graph traversal, ArtifactMetadata @bean (RAN-171) - CapabilityMatrix: add missing `case "cpp", "c++"` so C++ queries return CPP_CAPS instead of silently falling through to CSHARP_CAPS - EvidencePackAssembler: replace doc-comment text search in fetchReferences() with CALLS/DEPENDS_ON graph edge traversal via GraphStore - CodeIqConfig: add @bean @Profile("serving") provider for ArtifactMetadata so /manifest endpoint and get_artifact_metadata MCP tool are no longer permanently null - EvidencePackAssemblerTest: pass GraphStore mock to updated constructor Co-Authored-By: Paperclip <noreply@paperclip.ing> * fix(intelligence): add cpp to CapabilityMatrix.asSerializableMap() (RAN-172) CPP_CAPS was fully defined and tableFor("cpp") routed correctly, but asSerializableMap() omitted "cpp" from the language array, silently dropping C++ capabilities from the /manifest endpoint and get_artifact_metadata MCP tool response. Co-Authored-By: Paperclip <noreply@paperclip.ing> --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
1 parent 1ad6f3c commit f06ff60

117 files changed

Lines changed: 5133 additions & 3204 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ src/main/frontend/node_modules/
4343
src/main/frontend/node/
4444
src/main/frontend/dist/
4545
src/main/frontend/tsconfig.tsbuildinfo
46+
playwright-report/
47+
test-results/
4648
# Generated explorer CSS (rebuild via: cd src/main/frontend && npm run build:explorer-css)
4749
src/main/resources/static/css/explorer.css
4850

src/main/frontend/package-lock.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/main/frontend/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@
3333
"tailwindcss-animate": "^1.0.7"
3434
},
3535
"overrides": {
36-
"dompurify": "^3.3.3"
36+
"dompurify": "^3.3.3",
37+
"lodash": ">=4.17.24"
3738
},
3839
"devDependencies": {
3940
"@axe-core/playwright": "^4.10.1",
70.6 KB
Loading
Binary file not shown.

0 commit comments

Comments
 (0)