Skip to content

Latest commit

 

History

History
40 lines (31 loc) · 3.77 KB

File metadata and controls

40 lines (31 loc) · 3.77 KB

Cross-repo API contracts

Gortex detects API contracts across repos and matches providers to consumers:

# After indexing, contracts are auto-detected
gortex track .

# Via MCP tools
contracts                        # list all detected contracts (default action)
contracts {action: "check"}      # find mismatches and orphans
Contract type Detection Provider Consumer
HTTP routes Framework annotations (gin, Express, FastAPI, Spring, etc.) Route handler HTTP client calls (fetch, http.Get)
gRPC Proto service definitions Service RPC Client stub calls
GraphQL Schema type/field definitions Schema Query/mutation strings
Message topics Pub/sub patterns across Kafka, RabbitMQ, NATS, and Redis (KindTopic nodes, produces_topic / consumes_topic edges); dynamic topic names suppressed Publish calls Subscribe calls
WebSocket Event emit/listen patterns emit() on()
Env vars os.Getenv, process.env, .env files Setenv / .env Getenv / process.env
OpenAPI Swagger/OpenAPI spec files Spec paths (linked to HTTP routes)
Temporal workflows Go SDK worker.RegisterActivity(WithOptions) / RegisterActivities / Java @ActivityInterface / @WorkflowInterface annotations Activity / workflow function (carries temporal_role Meta) workflow.ExecuteActivity / ExecuteChildWorkflow / client.ExecuteWorkflow / handler & signal/query calls

Contracts are normalized to canonical IDs (e.g., http::GET::/api/users/{id}) and matched across repos to detect orphan providers/consumers and mismatches.

Temporal edge taxonomy

The Go and Java extractors tag Temporal call sites with a via Meta value on the EdgeCalls edge (plus temporal_kind and temporal_name); ResolveTemporalCalls rewrites the resolvable ones (temporal.stub / temporal.start) to the registered handler / workflow node. Because they are ordinary EdgeCalls, find_usages / get_callers / explain_change_impact traverse them with no temporal-specific code.

via Direction Emitted from temporal_kind Resolved?
temporal.register provider tag worker.RegisterActivity(WithOptions) / RegisterWorkflow(WithOptions) / RegisterActivities activity / workflow indexed, not rewritten
temporal.stub workflow → activity / child-workflow workflow.ExecuteActivity / ExecuteLocalActivity / ExecuteChildWorkflow activity / workflow yes → registered handler
temporal.start service → workflow client.ExecuteWorkflow / SignalWithStartWorkflow workflow yes → registered workflow
temporal.handler workflow exposes workflow.SetQueryHandler / GetSignalChannel / SetUpdateHandler (+WithOptions) query / signal / update provider edge
temporal.signal-send sender → running workflow workflow.SignalExternalWorkflow / client.SignalWorkflow signal consumer edge
temporal.query-call caller → running workflow client.QueryWorkflow query consumer edge

Extra Meta on these edges: temporal_registered_name (the RegisterOptions{Name} override that is the actual dispatch key), temporal_register_plural (a RegisterActivities(&Struct{}) registration whose exported methods are each promoted), and temporal_name_origin=env_default (a dispatch name resolved from an env-var-with-literal-default, landed at the speculative tier). Node roles are stamped as temporal_role (activity / workflow / activity_interface / workflow_interface / signal / query / update). Aliased import wf "go.temporal.io/sdk/workflow" receivers are canonicalised before detection.