feat(temporal): orphan/integrity detection + analyze temporal_orphans tool - #88
Merged
Merged
Conversation
… MCP tool Closes the loop with integrity analysis (no dedicated ContractTemporal — temporal lives as EdgeCalls+via-meta and blast-radius already traverses it generically). - resolver.DetectTemporalOrphans walks the resolved graph for four gaps: broken_dispatch (a temporal.stub still pointing at a placeholder — a workflow dispatches a non-existent activity/child-workflow), signal_no_handler / query_no_handler (a signal sent / query called with a name no workflow handles), and orphan_activity / orphan_workflow (registered but never dispatched/started — dead code). - MCP: analyze kind=temporal_orphans surfaces it (handleAnalyzeTemporalOrphans). Unit test (resolver) + handler test (mcp). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A dispatch whose call site is a test file (*_test.go, *Test.java, files under tests/, ...) is almost always a fixture or mock; counting it as a broken_dispatch is the dominant false positive. DetectTemporalOrphans now skips such dispatches, keyed on the stub edge's own FilePath via a new isTestFilePath predicate (port of indexer.IsTestFile; the resolver cannot import indexer). Only unresolved dispatches are affected; resolved test->activity edges keep their consumed bookkeeping. Robust under incremental reindex (pure function of the path, no Meta dependency). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
zzet
reviewed
Jun 15, 2026
| func (s *Server) handleAnalyze(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { | ||
| kind, err := req.RequireString("kind") | ||
| if err != nil { | ||
| return mcp.NewToolResultError("kind is required (one of: dead_code, hotspots, cycles, would_create_cycle, todos, blame, coverage, stale_code, ownership, coverage_gaps, stale_flags, releases, cgo_users, wasm_users, orphan_tables, unreferenced_tables, coverage_summary, channel_ops, def_use, goroutine_spawns, field_writers, race_writes, unclosed_channels, unsafe_patterns, health_score, annotation_users, config_readers, event_emitters, pubsub, string_emitters, error_surface, log_events, sql_rebuild, external_calls, synthesizers, resolution_outcomes, retrieval_log, routes, models, components, k8s_resources, images, kustomize, cross_repo, impact, named, tests_as_edges, connectivity_health, pagerank, louvain, wcc, scc, kcore)"), nil |
Owner
There was a problem hiding this comment.
@avfirsov the 1-line fix needed for the PR (add temporal_orphans to the analyze usage string)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds Temporal integrity / orphan detection plus an
analyze kind=temporal_orphansMCP tool, and excludes test-file dispatchers from thebroken_dispatchcount.Two commits:
broken_dispatch,signal_no_handler,query_no_handler,orphan_activity,orphan_workflow. Exposed viaanalyze kind=temporal_orphans(MCP + CLI). Newinternal/resolver/temporal_orphans.go.*_testfiles were inflatingbroken_dispatchas false positives; a smalltestpathhelper filters them out.Why
Gives a single, graph-grounded answer to "what Temporal wiring is broken?" — unresolved activity/workflow dispatches, signals/queries with no handler, and registered-but-never-dispatched handlers — without manual grepping. The test-file filter keeps the headline number trustworthy.
Tests
New unit + table tests:
temporal_orphans_test.go,temporal_orphans_testfilter_test.go,tools_analyze_temporal_test.go.go build ./...clean;internal/resolverandinternal/mcpsuites pass.Notes
Self-contained — only new files plus a tool registration; no changes to existing resolution behavior beyond the test-file exclusion.