Skip to content

[group] Intra-repo service communication tracking#625

Closed
ivkond wants to merge 3 commits into
abhigyanpatwari:mainfrom
ivkond:feat/intra-repo-service-tracking-v2
Closed

[group] Intra-repo service communication tracking#625
ivkond wants to merge 3 commits into
abhigyanpatwari:mainfrom
ivkond:feat/intra-repo-service-tracking-v2

Conversation

@ivkond

@ivkond ivkond commented Apr 1, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a group system for repository analysis with intra-repo service communication tracking for microservice monorepos. This is the foundation for cross-repo impact analysis (follow-up PR).

What changed:

  • Group infrastructure: types, config parser, contract registry, exact matching engine
  • Service boundary detection for monorepos (package.json, go.mod, Dockerfile, pom.xml, Cargo.toml markers)
  • HTTP route extractor (Spring, Express, Laravel, FastAPI + fetch/axios consumers)
  • gRPC extractor (proto parsing + Go/Java/Python/TS server/client detection)
  • Topic extractor (Kafka, RabbitMQ, NATS producers/consumers across 4 languages)
  • Intra-repo matching between services within the same monorepo
  • CLI commands: group create/add/remove/list/sync/contracts/query/status
  • MCP tools: group_list, group_sync, group_contracts, group_query, group_status
  • Documentation for new CLI commands and MCP tools in both READMEs

Why:
The GitNexus author requested intra-repo service tracking as a prerequisite for cross-repo analysis (#606). Proving that microservice monorepos index well is the foundation — once intra-repo works, the same extractors feed directly into the virtual graph for multi-repo support.

Backward compatibility & roadmap

Groups are fully opt-ingitnexus analyze continues to work exactly as before. For small/medium monorepos (2-20 services), a single analyze on the whole repo already captures everything in one graph, and impact/query tools see inter-service relationships through existing CALLS/IMPORTS edges.

Groups become valuable for:

  • Large monorepos (20+ services) where per-service indexing is faster and less noisy
  • Multi-repo setups where services live in separate git repositories

The gRPC, Kafka/RabbitMQ/NATS, and HTTP extractors currently run only inside group sync. A natural next step is integrating them into the standard analyze pipeline so that inter-service communication edges (gRPC calls, topic pub/sub) are captured automatically for all repos — no group setup required. This would make service communication tracking zero-config for monorepos of any size, while groups remain available for cross-repo and advanced use cases.

How to verify:

cd gitnexus
npx tsc --noEmit                    # typecheck
npm run test:unit                   # 2658 unit tests
npm run test:integration            # 1973 integration tests
# Monorepo fixture test:
npx vitest run test/integration/group/monorepo-sync.test.ts

Risk / rollback:

  • All new code is in src/core/group/ — isolated from existing functionality
  • No existing APIs changed; service field is optional and backward-compatible
  • gitnexus analyze behavior is completely unchanged
  • Rollback: revert the PR (no migrations, no schema changes)

Not in this PR (follow-up):

Test plan

  • 15 unit tests — ServiceBoundaryDetector
  • 16 unit tests — matching (incl. 4 intra-repo cases)
  • 13 unit tests — GrpcExtractor
  • 19 unit tests — TopicExtractor
  • 14 unit tests — GroupService
  • 9 unit tests — sync pipeline + stableRepoPoolId
  • Config parser, storage, types, HTTP extractor tests
  • 3 integration tests — monorepo sync (fixture with auth/orders/gateway)
  • Full regression: all existing tests pass

🤖 Generated with Claude Code

@vercel

vercel Bot commented Apr 1, 2026

Copy link
Copy Markdown

@ivkond is attempting to deploy a commit to the NexusCore Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions

github-actions Bot commented Apr 1, 2026

Copy link
Copy Markdown
Contributor

CI Report

All checks passed

Pipeline Status

Stage Status Details
✅ Typecheck success tsc --noEmit
✅ Tests success unit tests, 3 platforms
✅ E2E success gitnexus-web changes only

Test Results

Tests Passed Failed Skipped Duration
4999 4953 0 46 187s

✅ All 4953 tests passed

46 test(s) skipped — expand for details
  • buildTypeEnv > known limitations (documented skip tests) > Ruby block parameter: users.each { |user| } — closure param inference, different feature
  • Swift constructor-inferred type resolution > detects User and Repo classes, both with save methods
  • Swift constructor-inferred type resolution > resolves user.save() to Models/User.swift via constructor-inferred type
  • Swift constructor-inferred type resolution > resolves repo.save() to Models/Repo.swift via constructor-inferred type
  • Swift constructor-inferred type resolution > emits exactly 2 save() CALLS edges (one per receiver type)
  • Swift self resolution > detects User and Repo classes, each with a save function
  • Swift self resolution > resolves self.save() inside User.process to User.save, not Repo.save
  • Swift parent resolution > detects BaseModel and User classes plus Serializable protocol
  • Swift parent resolution > emits EXTENDS edge: User → BaseModel
  • Swift parent resolution > emits IMPLEMENTS edge: User → Serializable (protocol conformance)
  • Swift cross-file User.init() inference > resolves user.save() via User.init(name:) inference
  • Swift cross-file User.init() inference > resolves user.greet() via User.init(name:) inference
  • Swift return type inference > detects User class and getUser function
  • Swift return type inference > detects save function on User (Swift class methods are Function nodes)
  • Swift return type inference > resolves user.save() to User#save via return type of getUser() -> User
  • Swift return-type inference via function return type > resolves user.save() to User#save via return type of getUser()
  • Swift return-type inference via function return type > user.save() does NOT resolve to Repo#save
  • Swift return-type inference via function return type > resolves repo.save() to Repo#save via return type of getRepo()
  • Swift implicit imports (cross-file visibility) > detects UserService class in Models.swift
  • Swift implicit imports (cross-file visibility) > resolves UserService() constructor call across files (no explicit import)
  • Swift implicit imports (cross-file visibility) > resolves service.fetchUser() member call across files
  • Swift implicit imports (cross-file visibility) > creates IMPORTS edges between files in the same module
  • Swift extension deduplication > detects Product class
  • Swift extension deduplication > resolves Product() constructor despite extension creating duplicate class node
  • Swift extension deduplication > resolves product.save() to Product.swift (primary definition)
  • Swift constructor call fallback (no new keyword) > resolves OCRService() as constructor call across files
  • Swift constructor call fallback (no new keyword) > resolves ocr.recognize() member call via constructor-inferred type
  • Swift export visibility (internal vs private) > resolves PublicService() constructor across files
  • Swift export visibility (internal vs private) > resolves internalHelper() across files (internal = module-scoped)
  • Swift if let / guard let binding resolution > detects User and Repo classes
  • Swift if let / guard let binding resolution > resolves user.save() inside if-let to User#save
  • Swift if let / guard let binding resolution > resolves repo.save() inside guard-let to Repo#save
  • Swift if let / guard let binding resolution > user.save() in if-let does NOT resolve to Repo#save
  • Swift await / try expression unwrapping > resolves user.save() via await fetchUser() return type
  • Swift await / try expression unwrapping > resolves repo.save() via try parseRepo() return type
  • Swift await / try expression unwrapping > detects fetchUser and parseRepo as functions
  • Swift for-in loop element type inference > detects User and Repo classes
  • Swift for-in loop element type inference > creates implicit import edges between files
  • Swift field-type resolution > detects classes and their properties
  • Swift field-type resolution > emits HAS_PROPERTY edges from class to field
  • Swift field-type resolution > resolves field-chain call user.address.save() → Address#save
  • Swift field-type resolution > emits ACCESSES edges for field reads in chains
  • Swift field-type resolution > populates field metadata (visibility, declaredType) on Property nodes
  • Swift call-result binding > resolves call-result-bound method call user.save() → User#save
  • Swift call-result binding > getUser() is present as a defined function
  • Swift call-result binding > emits processUser -> getUser CALLS edge for let-assigned free function call

Code Coverage

Tests

Metric Coverage Covered Base Delta Status
Statements 70.87% 13917/19637 70.85% 📈 +0.0 🟢 ██████████████░░░░░░
Branches 60.07% 9048/15062 60.09% 📉 -0.0 🔴 ████████████░░░░░░░░
Functions 75.1% 1258/1675 75.59% 📉 -0.5 🔴 ███████████████░░░░░
Lines 73.03% 12667/17344 73.06% 📉 -0.0 🔴 ██████████████░░░░░░

📋 View full run · Generated by CI

@ivkond ivkond changed the title feat(group): intra-repo service communication tracking [group] Intra-repo service communication tracking Apr 1, 2026
ivkond and others added 3 commits April 2, 2026 00:39
Core foundation for repository group analysis:
- Type system: ContractType, ExtractedContract, StoredContract, CrossLink
  with optional `service` field for intra-repo matching
- Config parser for group.yaml (repos, detection flags, matching thresholds)
- Contract registry storage with atomic writes
- Exact matching engine with per-type normalization (HTTP, gRPC, topic)
  and intra-repo support (different services within same repo can match)
- Extract LadybugDB pool-adapter from MCP backend for reuse by sync pipeline
- Git staleness checker for group status reporting

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Service communication detection for microservice monorepos:

- ServiceBoundaryDetector: auto-detects service boundaries via markers
  (package.json, go.mod, Dockerfile, pom.xml, Cargo.toml, build.gradle,
  pyproject.toml, etc.)
- HttpRouteExtractor: graph-assisted (Strategy A) with source-scan
  fallback (Strategy B) for Spring, Express, Laravel, FastAPI providers
  and fetch/axios consumers
- GrpcExtractor: parses .proto files, detects Go/Java/Python/TS gRPC
  servers (RegisterXxxServer, @GrpcService, add_XxxServicer_to_server,
  @GrpcMethod) and clients (NewXxxClient, newBlockingStub, XxxStub)
- TopicExtractor: Kafka (@KafkaListener, producer.send), RabbitMQ
  (@RabbitListener, channel.publish/consume), NATS (nc.Subscribe/Publish)
  across Java, Node, Go, and Python

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Wire extractors into the sync pipeline with service boundary detection.
GroupService provides high-level API for all group operations.

- Sync pipeline: orchestrates extraction (HTTP, gRPC, topics) with
  service boundary assignment and exact matching
- GroupService: groupList, groupSync, groupContracts, groupQuery,
  groupStatus (groupImpact deferred to cross-repo follow-up PR)
- CLI: group create/add/remove/list/sync/contracts/query/status
- MCP tools: group_list, group_sync, group_contracts, group_query,
  group_status
- Monorepo fixture: 3 services (auth/orders/gateway) connected via
  gRPC + Kafka + HTTP — all intra-repo cross-links discovered
- Documentation: CLI commands and MCP tools added to both READMEs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@ivkond ivkond force-pushed the feat/intra-repo-service-tracking-v2 branch from 4358269 to 4fed097 Compare April 1, 2026 21:41
@ivkond ivkond closed this Apr 1, 2026
@ivkond ivkond deleted the feat/intra-repo-service-tracking-v2 branch April 1, 2026 21:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant