feat: add ContextKey[T], flow.Logger and log interceptors#78
Merged
Conversation
Introduce a tiny, type-safe convention for flowing cross-cutting values (logger, identity, k8s client, ...) through context.Context across go-workflow and any user / contrib code that participates in a Workflow: - ContextKey[T] generic helper with With / From / FromOr methods. Each value type declares one canonical package-level ContextKey[T] var; uniqueness is by T so two such vars of the same T deliberately share the same key. - flow.Logger: canonical ContextKey[*slog.Logger] published by the main package so contrib code does not have to invent its own key for the conventional "the logger lives in ctx" pattern. - flow.LogStepFields(extra...) StepInterceptor: derives the ctx logger with step=<flow.String(step)> plus any caller-supplied extras, then re-injects so Steper.Do reads the enriched logger via flow.Logger.FromOr. - flow.LogAttemptField() AttemptInterceptor: same pattern, binds attempt=N inside the retry loop. Also adds the corresponding openspec capability (context-values) and a runnable example file (example/14_context_values_test.go) demonstrating the three usages. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Trim 14_context_values_test.go down to the two minimal scenarios that actually motivate the API: a string-typed UserKey to demonstrate the ContextKey[T] pattern itself, and a single Logger example wiring both LogStepFields and LogAttemptField. Drops the JSON-capture helper, the contrived Identity struct, and the third Example that overlapped with the second one — the point of these examples is "passing values through ctx is the everyday pattern in go-workflow", not Azure / k8s specifics. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…nciple Passing values through ctx is one of the most common things users do in go-workflow — almost every step in a real workflow reaches for a logger, a request ID or a client out of the ctx, often before it ever cares about retries or sub-workflows. The example file therefore belongs near the front of the learning path, paired with 03_data_flow as the two ways data enters a Step.Do (typed point-to-point Input vs. graph-wide ctx). - Move 14_context_values_test.go to 04, shifting the previous 04..13 down to 05..14 (callbacks, conditions, branching, retry, sub-workflow, options, observability, debugging, testing, mutators). - Update every "see NN_xxx" cross-reference inside example files and the one reference in the main README.md. - Reorganize example/README.md to reflect the new numbering, group 04_context_values under "Move data into a Step" alongside 03_data_flow, and add a new "How this path is ordered" section that documents the rule explicitly: examples are sorted by frequency-of-use to build the user's mental model in the right order, and the file numbers are ordering hints — not stable identifiers — so future additions should be placed where they fit, even if it pushes later files down by one. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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
Introduces a tiny, type-safe convention for flowing cross-cutting values (logger, identity, k8s client, ...) through `context.Context` across go-workflow and any user / contrib code that participates in a Workflow.
Motivation: `contrib/azure`-style packages should not each invent their own context key for logger / identity / etc.; this gives the whole ecosystem one shared, type-safe convention with zero boilerplate per value type.
What's in the diff
Test plan
Out of scope
The other 9 capability specs in `openspec/specs/` fail `--strict` validation (missing `## Purpose` and/or `SHALL`/`MUST` keywords), but those are pre-existing issues unrelated to this change and should be addressed in a separate PR.
🤖 Generated with Claude Code