feat(temporal): resolve activity/workflow dispatch names from env-var-with-default vars#79
Merged
Merged
Conversation
…ault vars
When a workflow names its activity/child-workflow through a local variable
read from an env var with a literal fallback, resolve the dispatch to that
literal default instead of leaving it unresolved:
actName := cmp.Or(os.Getenv("CHARGE_ACTIVITY"), "ChargeCard")
workflow.ExecuteActivity(ctx, actName, id) // -> activity "ChargeCard"
name := os.Getenv("K"); if name == "" { name = "ChargeCard" }
The parser does a narrow, intra-procedural lookup anchored on a literal
os.Getenv / os.LookupEnv read (so the value is provably env-sourced, not a
general data-flow guess) and tags the stub edge temporal_name_origin=
env_default. The resolver then lands the edge at the speculative tier
(OriginSpeculative, confidence 0.4, MetaSpeculative=true) rather than
ast_resolved — the runtime env override may name a different handler than
the literal default, so the edge is present but hidden from default queries.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This was referenced Jun 12, 2026
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.
Summary
Resolve a Temporal activity / workflow dispatch name when it comes from a local variable read from an env var with a literal default, instead of leaving the call unresolved — landing the resolved edge at the speculative tier since the runtime env value may differ from the default.
This is one half of a split from #75 (the other half — Go-side query/signal/update handler edges — is in a separate PR so each can be reviewed independently).
Changes
ExecuteActivity/ExecuteLocalActivity/ExecuteChildWorkflowname argument is a bare identifier assigned, in the enclosing function, from an env-var-with-literal-default, resolve the dispatch to that literal default:os.Getenv/os.LookupEnvread (so the value is provably env-sourced — this is not general constant propagation), and only considers assignments lexically before the call. Anything else is left unresolved, no guessing.temporal_name_origin=env_default; the resolver then lands it at the speculative tier (OriginSpeculative, confidence0.4,MetaSpeculative=true) rather thanast_resolved. The edge is present but hidden from default queries, reusing the existing speculative-edge convention (OriginSpeculative/MetaSpeculative, cf.speculative_dispatch.go).Testing
go test -race ./...) for the touched packages (internal/parser/languages,internal/resolver,internal/indexer). The only failures in my environment are the pre-existinginternal/indexerwatcher tests failing withinotify ... too many open files(a local WSL fd-limit issue, unrelated — no watcher files touched).go_temporal_test.go:cmp.Orandif x==""shapes + negative cases for a plain non-env variable and an env read with no literal default), resolver-level (temporal_calls_test.go: speculative-tier resolution + unresolved-stays-placeholder), and end-to-end (temporal_e2e_test.go).Checklist
OriginSpeculative/MetaSpeculativetier and confidence-label machinery)Meta["methods"]for interfaces (if applicable) — n/aEdgeMemberOfedges to their containing type (if applicable) — n/aNotes for reviewers
This is the more opinionated of the two split PRs: it adds a narrow intra-procedural data-flow shortcut, which is a small departure from the otherwise AST-local detector. It's deliberately bounded (literal
os.Getenv/os.LookupEnvanchor, literal default only, lexically-before-the-call) and emitted at the speculative/hidden tier precisely so it can't silently distort the high-confidence graph. Happy to gate it behind a flag or narrow it further if you'd prefer.