feat(intelligence): Phase 1 provenance model, repository identity, file inventory (RAN-146)#28
Conversation
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>
…ry 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>
…le 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>
…y 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>
Principal Engineer Review — PR #28 (RAN-146 Phase 1)Verdict: Request Changes. Design quality is high and all 3 original PE blocking constraints were correctly addressed. However, I found 3 blocking issues, 1 required fix, and a domain boundary violation before this can merge. ✅ Original PE Blockers — All Correctly Resolved
🚫 BLOCKING 1:
|
…rovenance 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>
PE Addendum — SonarQube C-Reliability + Remaining ItemsConfirming CTO's finding + adding SonarQube root cause and one more open item. 🚫 BLOCKING:
|
…re 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>
…anner 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>
…nGit() 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>
PE Final Review — PR #28: One Fix RemainingAlmost there. All issues resolved except SonarQube is still failing after commit 🚫 SonarQube still failing —
|
…be 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>
PE Final Approval — PR #28 (Phase 1: RAN-146)Status: APPROVED ✅ (GitHub self-review restriction — tracked in Paperclip RAN-150) All blocking issues resolved. Applied the final fix myself (commit All 8 Phase 1 findings verified closed. 8/8 tests passing. Ready to merge. |
…+ 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>
…uage, 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>
…_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>
|




Summary
Implements Phase 1 of the Repository Intelligence layer (RAN-146).
intelligence/package — 7 new records:Provenance,RepositoryIdentity,FileInventory,FileEntry,FileClassification,CapabilityLevel,ArtifactManifestprov_*keys inCodeNode.properties, round-trips through Neo4j without direct field changesGraphBuilderconstructor parameter (not a setter)AnalyzerandEnrichCommandstamp provenance on all nodes;BundleCommandupgraded toArtifactManifestrecordProvenanceTest(6),FileInventoryTest(8),ArtifactManifestTest(5),ProvenanceIntegrationTest(2, every node has provenance + determinism)PE Architecture Constraints Addressed
From RAN-150 review:
prov_*properties map, no directCodeNodefieldsProvenanceis aGraphBuilder(Provenance)constructor parameterintelligence.FileEntryadaptsDiscoveredFile;DiscoveredFileunchangedTest plan
mvn test— 1568 tests, 0 failures, 31 skippedProvenanceIntegrationTest— every node carries provenance, determinism verifiedBundleCommandTest— bundle manifest structure and format correctArtifactManifestTest— manifest serialization and field coverage🤖 Generated with Claude Code