|
1 | 1 | # Analyzer Specification |
2 | 2 |
|
3 | 3 | > Generated by openlore v1.0.0 on 2026-04-05 10:50 |
4 | | -> Source files: src/core/analyzer/repository-mapper.ts, src/api/types.ts, src/core/analyzer/embedding-service.ts, src/core/analyzer/subgraph-extractor.ts, src/core/analyzer/architecture-writer.ts, src/core/analyzer/dependency-graph.ts, src/core/analyzer/spec-vector-index.ts, src/core/analyzer/file-walker.ts, src/core/analyzer/import-resolver-bridge.ts, src/core/analyzer/refactor-analyzer.ts, src/core/analyzer/vector-index.ts, src/core/analyzer/import-parser.ts, src/core/analyzer/signature-extractor.ts, src/core/analyzer/artifact-generator.ts, src/core/analyzer/cpp-header-resolver.ts, src/core/analyzer/call-graph.ts, src/core/analyzer/duplicate-detector.ts, src/core/analyzer/type-inference-engine.ts, src/core/analyzer/significance-scorer.ts, src/core/analyzer/http-route-parser.ts, src/core/analyzer/ast-chunker.ts, src/core/analyzer/codebase-digest.ts, src/utils/progress.ts, src/utils/prompts.ts, src/utils/logger.ts, src/utils/shutdown.ts, src/core/analyzer/iac/project.ts, src/core/services/edge-store.ts, src/core/services/mcp-handlers/analysis.ts, openspec/specs/analyzer/spec.md, src/core/analyzer/landmark-signals.ts, src/core/services/mcp-handlers/landmarks.ts, src/core/services/mcp-handlers/reachability.ts, src/core/services/mcp-handlers/tool-contract.ts, src/cli/commands/mcp.ts, src/core/services/tool-dispatch.ts, src/core/analyzer/cfg.ts, src/core/services/mcp-watcher.ts, src/core/services/mcp-handlers/graph.ts, src/core/analyzer/cfg.test.ts, src/core/services/mcp-handlers/graph.test.ts, src/core/decisions/anchor.ts, src/core/decisions/anchor-adapter.ts, src/core/services/mcp-handlers/memory.ts, src/types/index.ts, src/constants.ts, openspec/changes/add-content-addressed-stable-symbol-ids/specs/analyzer/spec.md, src/core/scip/stable-id.test.ts, src/core/analyzer/personalized-pagerank.ts, src/core/services/mcp-handlers/orient.ts |
| 4 | +> Source files: src/core/analyzer/repository-mapper.ts, src/api/types.ts, src/core/analyzer/embedding-service.ts, src/core/analyzer/subgraph-extractor.ts, src/core/analyzer/architecture-writer.ts, src/core/analyzer/dependency-graph.ts, src/core/analyzer/spec-vector-index.ts, src/core/analyzer/file-walker.ts, src/core/analyzer/import-resolver-bridge.ts, src/core/analyzer/refactor-analyzer.ts, src/core/analyzer/vector-index.ts, src/core/analyzer/import-parser.ts, src/core/analyzer/signature-extractor.ts, src/core/analyzer/artifact-generator.ts, src/core/analyzer/cpp-header-resolver.ts, src/core/analyzer/call-graph.ts, src/core/analyzer/duplicate-detector.ts, src/core/analyzer/type-inference-engine.ts, src/core/analyzer/significance-scorer.ts, src/core/analyzer/http-route-parser.ts, src/core/analyzer/ast-chunker.ts, src/core/analyzer/codebase-digest.ts, src/utils/progress.ts, src/utils/prompts.ts, src/utils/logger.ts, src/utils/shutdown.ts, src/core/analyzer/iac/project.ts, src/core/services/edge-store.ts, src/core/services/mcp-handlers/analysis.ts, openspec/specs/analyzer/spec.md, src/core/analyzer/landmark-signals.ts, src/core/services/mcp-handlers/landmarks.ts, src/core/services/mcp-handlers/reachability.ts, src/core/services/mcp-handlers/tool-contract.ts, src/cli/commands/mcp.ts, src/core/services/tool-dispatch.ts, src/core/analyzer/cfg.ts, src/core/services/mcp-watcher.ts, src/core/services/mcp-handlers/graph.ts, src/core/analyzer/cfg.test.ts, src/core/services/mcp-handlers/graph.test.ts, src/core/decisions/anchor.ts, src/core/decisions/anchor-adapter.ts, src/core/services/mcp-handlers/memory.ts, src/types/index.ts, src/constants.ts, openspec/changes/add-content-addressed-stable-symbol-ids/specs/analyzer/spec.md, src/core/scip/stable-id.test.ts, src/core/analyzer/personalized-pagerank.ts, src/core/services/mcp-handlers/orient.ts, src/core/analyzer/domain-naming.ts, src/core/analyzer/schema-extractor.ts |
5 | 5 |
|
6 | 6 | ## Purpose |
7 | 7 |
|
@@ -5061,6 +5061,36 @@ The system SHALL surface epistemic-lease freshness as neutral factual signals (e |
5061 | 5061 |
|
5062 | 5062 | > Decision recorded: 8e95746d |
5063 | 5063 | > Date: 2026-06-16 |
| 5064 | +### Requirement: UnifyDomainnameDerivationBehindASingleLeaffirstHelper |
| 5065 | + |
| 5066 | +The system SHALL derive domain names using a leaf-first path walk with shared noise-directory filtering, ensuring consistent domain naming across dependency-graph clustering and repository mapping. |
| 5067 | + |
| 5068 | +> Decision recorded: 201ace19 |
| 5069 | +> Date: 2026-06-16 |
| 5070 | +### Requirement: AddJpahibernateEntityParserToSchemaExtractor |
| 5071 | + |
| 5072 | +The system SHALL extract schema models from Java files annotated with JPA @Entity or @MappedSuperclass, parsing table names, field names, types, and nullable status. |
| 5073 | + |
| 5074 | +> Decision recorded: 6af4d045 |
| 5075 | +> Date: 2026-06-16 |
| 5076 | +### Requirement: GeneralizeFileextensionStrippingAndJavaMethodSignatureExtractionForMultilanguageSupport |
| 5077 | + |
| 5078 | +The system SHALL extract Java method signatures including modifiers, generic type parameters, and throws clauses, while rejecting block-comment contents and body-level statements as false positives. |
| 5079 | + |
| 5080 | +> Decision recorded: 8f94535c |
| 5081 | +> Date: 2026-06-16 |
| 5082 | +### Requirement: InjectCallgraphEdgesIntoTheDependencyGraphForJvmLanguages |
| 5083 | + |
| 5084 | +The system SHALL inject call-graph edges into the file-level dependency graph for JVM languages whose same-package references produce no import statements. |
| 5085 | + |
| 5086 | +> Decision recorded: 67580817 |
| 5087 | +> Date: 2026-06-17 |
| 5088 | +### Requirement: JaxrsRouteDetectionRequiresJavaxjakartawsrsImportToAvoidFalsePositivesFromHttpClientLibraries |
| 5089 | + |
| 5090 | +The system SHALL only classify a Java/Kotlin file as a JAX-RS server endpoint when it imports from the javax.ws.rs or jakarta.ws.rs package, to prevent false positives from HTTP client annotation libraries. |
| 5091 | + |
| 5092 | +> Decision recorded: f9de2e30 |
| 5093 | +> Date: 2026-06-17 |
5064 | 5094 |
|
5065 | 5095 | ## Technical Notes |
5066 | 5096 |
|
@@ -5438,3 +5468,73 @@ Shortest-path distance ranks a candidate by its single cheapest path to the task |
5438 | 5468 | The epistemic-lease feature injected escalating imperative language into every MCP tool response (STOP, "Repository model: EXPIRED", "do NOT…"). This is structurally a prompt-injection pattern — it trains agents to obey authoritative imperatives in tool output, the exact behavior agents must resist — and contradicts the north-star decision (c6d1ad07: deterministic structural facts, not guessing) and the landmark-salience principle (hand the agent facts, let it rank). Wall-clock age alone escalated to CRITICAL (false positive), and the agent's own commits flipped the lease to stale via git-hash divergence even though committing is the most-informed action in a session. Fix: emit a single neutral, factual freshness note (minutes since orient, cognitive load since orient, whether the analysis index is behind HEAD) phrased as information the agent can act on, not a command. Drive severity from accumulated cognitive load, not wall clock. |
5439 | 5469 |
|
5440 | 5470 | **Consequences:** staleBlock/degradedSignal reworded to neutral facts (no STOP/EXPIRED/do-NOT, no system-banner box art); git-hash divergence no longer forces stale — it sets a factual index-behind-HEAD flag and at most contributes to degraded; computeStaleDepth driven by cognitive load, not wall-clock age; decay tracking, cross-module density/oscillation model, and telemetry retained; epistemic-lease gains a spec requirement (mcp-handlers) and ADR where it previously had neither. |
| 5471 | + |
| 5472 | +### Unify domain-name derivation behind a single leaf-first helper |
| 5473 | + |
| 5474 | +**Status:** Approved |
| 5475 | +**Date:** 2026-06-16 |
| 5476 | +**ID:** 201ace19 |
| 5477 | + |
| 5478 | +Domain naming was split across two diverging functions: `suggestDomainName` (dependency-graph clusters) correctly walks the path leaf-first and skips build-layout/reverse-DNS noise, but `inferDomains` (repository-mapper, which drives SUMMARY's 'Detected Domains' and the generated OpenSpec spec files) walked root-first and picked the first non-skip segment. On Java/Kotlin projects this grabbed the reverse-DNS org root (e.g. `org/springframework/...`) so every business file collapsed into one nonsense `springframework` domain — the exact bug reported in #138 and still present after #139, which only fixed the cluster path. Extracting one shared `deriveDomainFromPath` helper (leaf-first walk + shared DOMAIN_NOISE_DIRS + canonical pattern map) makes both code paths agree and prevents future drift. |
| 5479 | + |
| 5480 | +**Consequences:** New module src/core/analyzer/domain-naming.ts owns DOMAIN_NOISE_DIRS, the canonical domain pattern map, and deriveDomainFromPath. dependency-graph.ts and repository-mapper.ts both consume it. inferDomains now yields leaf-package business domains (vet/owner/system) instead of the org root; SUMMARY and generated specs change accordingly for Java/Kotlin/Go projects. |
| 5481 | + |
| 5482 | +### Add JPA/Hibernate entity parser to schema extractor |
| 5483 | + |
| 5484 | +**Status:** Approved |
| 5485 | +**Date:** 2026-06-16 |
| 5486 | +**ID:** 6af4d045 |
| 5487 | + |
| 5488 | +Java codebases using JPA/Hibernate annotations (@Entity, @MappedSuperclass) had no schema extraction support, leaving persistent models invisible to the schema inventory. The parser reads raw Java source (not skeletonized) because the TS/Py skeletonizer would mangle annotations and field declarations. |
| 5489 | + |
| 5490 | +**Consequences:** OrmType union gains 'jpa' variant; Java files with @Entity/@MappedSuperclass are parsed from raw source while all other languages continue through the skeletonizer. Future ORM dialects for Java (e.g. Micronaut Data, jOOQ codegen) would need separate parsers. |
| 5491 | + |
| 5492 | +### Generalize file-extension stripping and Java method signature extraction for multi-language support |
| 5493 | + |
| 5494 | +**Status:** Approved |
| 5495 | +**Date:** 2026-06-16 |
| 5496 | +**ID:** 8f94535c |
| 5497 | + |
| 5498 | +The analyzer hardcoded JS/TS/Python extensions in several places, causing Java/Kotlin files to leak extensions into entity names (e.g. VetControllerJava), miss handler methods with inline annotations (@ResponseBody), mis-parse license-header block comments as declarations, and drop methods with complex generic type parameters. Fixes generalize extension stripping, add block-comment tracking, widen the method regex for annotations in return-type position, and reject body-statement false positives. |
| 5499 | + |
| 5500 | +**Consequences:** Extension stripping is now generic (any single dot-extension), which is broader but could theoretically strip meaningful suffixes from unconventional filenames. Java signature extraction is richer (modifiers, type params, throws clauses preserved) but the regex is more complex to maintain. |
| 5501 | + |
| 5502 | +### Inject call-graph edges into the dependency graph for JVM languages |
| 5503 | + |
| 5504 | +**Status:** Approved |
| 5505 | +**Date:** 2026-06-17 |
| 5506 | +**ID:** 67580817 |
| 5507 | + |
| 5508 | +Java/Kotlin require imports only for cross-package references; same-package classes are used with no import. The dependency graph was built purely from import edges, so a Java project's file-level graph was nearly empty (spring-petclinic: 10 edges) while its call graph held 1261 — same-package relationships were invisible, hurting structural comprehension and leaving cluster views empty. Fix: (1) run injection for Java/Kotlin regardless of import-edge count, (2) seed the dedup set with existing edges so injected call edges never duplicate an import edge, (3) resolve call-graph file paths to absolute so the two id spaces align. |
| 5509 | + |
| 5510 | +**Consequences:** New exported SAME_PACKAGE_IMPLICIT_LANGS set (Java, Kotlin). injectCallGraphEdges now dedupes against pre-existing edges, making it safe to run alongside import edges. The absolute-path resolution also repairs the previously-silent no-op injection for Swift/C/C++. Java/Kotlin dependency graphs are now populated (petclinic 10→70 edges, gson 318→1517) with structural clusters; injected edges carry isCallEdge:true. |
| 5511 | + |
| 5512 | +### Require a ws.rs import for JAX-RS route detection |
| 5513 | + |
| 5514 | +**Status:** Approved |
| 5515 | +**Date:** 2026-06-17 |
| 5516 | +**ID:** 954eac79 |
| 5517 | + |
| 5518 | +JAX-RS route detection fired on any Java file containing both @Path and an HTTP-method annotation (@GET/@POST/...). Retrofit — an HTTP CLIENT library — uses identically-named @GET/@POST/@Path from retrofit2.http on interface methods (client request templates), so OpenLore hallucinated 28 phantom server routes for it (adversarial-audit finding). The defining signal for a real JAX-RS server resource is the javax.ws.rs / jakarta.ws.rs import, which Retrofit never has and Spring does not need. Gating JAX-RS detection on that import removes the false positives without affecting Spring (separate detection path) or genuine JAX-RS resources (which always import ws.rs). |
| 5519 | + |
| 5520 | +**Consequences:** extractJavaRouteDefinitions now requires an `import javax|jakarta.ws.rs` before classifying a file as JAX-RS. Retrofit/OkHttp client interfaces yield 0 routes; petclinic Spring routes (17) and JAX-RS resources (which import ws.rs) are unaffected. |
| 5521 | + |
| 5522 | +### JPA field parser handles inline annotations on the same line as the field declaration |
| 5523 | + |
| 5524 | +**Status:** Approved |
| 5525 | +**Date:** 2026-06-17 |
| 5526 | +**ID:** 8605684f |
| 5527 | + |
| 5528 | +Common JPA patterns place annotations inline with the field (e.g. `@Id private Long id;`). The previous parser only recognized annotations on their own line, causing inline-annotated fields — including primary keys — to be silently dropped from schema extraction. |
| 5529 | + |
| 5530 | +**Consequences:** The parser now iteratively strips leading annotations before testing for a field match, correctly capturing inline-annotated fields. Pure-annotation lines still accumulate in pendingAnn for multi-line annotation stacks. |
| 5531 | + |
| 5532 | +### JAX-RS route detection requires javax/jakarta.ws.rs import to avoid false positives from HTTP client libraries |
| 5533 | + |
| 5534 | +**Status:** Approved |
| 5535 | +**Date:** 2026-06-17 |
| 5536 | +**ID:** f9de2e30 |
| 5537 | + |
| 5538 | +Retrofit interfaces use identically-named @GET/@POST/@Path annotations from retrofit2.http, which are client request templates, not server endpoints. Without checking the import package, the parser would emit phantom server routes for HTTP client definitions. |
| 5539 | + |
| 5540 | +**Consequences:** JAX-RS routes are only detected when the file imports from javax.ws.rs or jakarta.ws.rs; projects using non-standard JAX-RS re-exports would not be recognized. Retrofit and similar HTTP client interfaces are correctly excluded. |
0 commit comments