diff --git a/Directory.Packages.props b/Directory.Packages.props index cd5fe5a..d16ef73 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -89,7 +89,7 @@ - + diff --git a/docs/patternkit-adoption.md b/docs/patternkit-adoption.md index dfa3bca..0f17535 100644 --- a/docs/patternkit-adoption.md +++ b/docs/patternkit-adoption.md @@ -1,7 +1,7 @@ # PatternKit Adoption Inventory -**PatternKit version:** 0.105.0 -**Last updated:** 2026-05-22 (Phase I coverage tightening) +**PatternKit version:** 0.112.0 +**Last updated:** 2026-05-22 (feat/consume-patternkit-0.112 — WireTapStep adopted) This document lists every point in the WorkflowFramework codebase where a PatternKit primitive is used, and every point where a step is intentionally kept bespoke with the rationale for that decision. This is the canonical reference for Phase I and future phases. @@ -44,6 +44,19 @@ This document lists every point in the WorkflowFramework codebase where a Patter | **Test coverage** | `tests/WorkflowFramework.Tests.TinyBDD/Integration/Routing/ContentBasedRouterStepScenarios.cs` | | **Public API change** | None — swap is internal-only. | +### 4. `WireTapStep` — Wire tap channel pattern + +| Item | Detail | +|------|--------| +| **File** | `src/WorkflowFramework.Extensions.Integration/Channel/WireTapStep.cs` | +| **PatternKit namespace** | `PatternKit.Messaging.Channels` | +| **Primitive** | `AsyncWireTap` | +| **Purpose** | Wraps the caller-supplied `Func` into a PatternKit tap handler. The `swallowErrors` constructor parameter maps to `TapErrorPolicy.Swallow` / `TapErrorPolicy.Propagate`. The `IWorkflowContext` is wrapped in a `Message` for transit and unwrapped inside the tap lambda — no public API or behavioral change. | +| **Phase introduced** | feat/consume-patternkit-0.112 | +| **Test coverage** | `tests/WorkflowFramework.Tests.TinyBDD/Integration/Channel/WireTapStepScenarios.cs` — all 8 Phase G.3 scenarios pass without modification. | +| **Public API change** | None — swap is internal-only. | +| **Net delta** | −15 lines of bespoke logic (try/catch error-swallowing replaced by `TapErrorPolicy`). | + --- ## Intentionally Bespoke @@ -146,13 +159,9 @@ The following EIP steps and other components were evaluated against PatternKit 0 | **Rationale** | PatternKit `AsyncAdapter` is a type-mapping pattern (produce `TOut` from `TIn`). `ChannelAdapterStep` is a side-effect operation (send/receive via `IChannelAdapter`). The send/receive contract doesn't fit the adapt-a-type signature. | | **Test coverage** | Phase G.3 characterization tests | -#### `WireTapStep` +#### ~~`WireTapStep`~~ — **Adopted in feat/consume-patternkit-0.112** -| Item | Detail | -|------|--------| -| **File** | `src/WorkflowFramework.Extensions.Integration/Channel/WireTapStep.cs` | -| **Rationale** | Core contract (run a side-effect without disrupting the main flow, with optional error swallowing) is simpler than PatternKit's `AsyncActionDecorator` pipeline. `AsyncActionDecorator` wraps a component and transforms/intercepts results; `WireTapStep` purely fires-and-forgets a side channel. | -| **Test coverage** | Phase G.3 characterization tests | +Moved to the **Adopted** section above. Now delegates to `PatternKit.Messaging.Channels.AsyncWireTap`. #### `MessageBridgeStep` @@ -186,12 +195,18 @@ When evaluating a bespoke component for PatternKit adoption, the following crite ## Future Evaluation Targets -The following components are candidates for PatternKit adoption in later phases if suitable primitives become available: +The following components are candidates for PatternKit adoption in later phases if suitable primitives become available or interface alignment is achieved: -| Component | Potential Primitive | Blocking Reason Today | +| Component | Potential Primitive | Blocking Reason (assessed against 0.112.0) | |-----------|--------------------|-----------------------| -| `AggregatorStep` | PatternKit Aggregator (future) | No primitive in 0.105.0 | -| `ScatterGatherStep` | PatternKit ScatterGather (future) | No primitive in 0.105.0 | +| `NormalizerStep` | `Normalizer` (now in 0.112.0) | Behavioral mismatch: PatternKit uses content predicates (first match wins); bespoke uses O(1) dictionary keyed dispatch. Error message format differs — test pins format name in exception text. See `docs/patternkit-followup.md`. | +| `ContentEnricherStep` | `AsyncContentEnricher` (now in 0.112.0) | Semantic mismatch: PatternKit returns an enriched payload copy; bespoke mutates `IWorkflowContext` in place via a `Func`. Wrapping adds indirection for zero functional benefit. | +| `IdempotentReceiverStep` | `IdempotentReceiver` (now in 0.112.0) | Behavioral breaking change: PatternKit marks failed attempts as `Failed` in the store (allowing retry); bespoke registers the ID in a `HashSet` before calling inner, so a failed first attempt DOES suppress the second. Test `ReAttemptAfterExceptionIsSkipped` pins this behavior. | +| `ClaimCheckStep` / `ClaimRetrieveStep` | `ClaimCheck` (now in 0.112.0) | Interface mismatch: bespoke `IClaimCheckStore` is untyped (`object`); PatternKit `IClaimCheckStore` is typed. Bridging requires an adapter class, adding indirection without deleting complexity. | +| `PollingConsumerStep` | `AsyncPollingConsumer` (now in 0.112.0) | Semantic mismatch: PatternKit is a continuous polling loop (run until cancelled); bespoke is a single-shot poll (`PollAsync` → store results → return). Incompatible lifecycle models. | +| `ScatterGatherStep` | `AsyncScatterGather` (now in 0.112.0) | Integration complexity: handlers mutate a shared `IWorkflowContext` and write results to named context keys; PatternKit's per-recipient isolation model returns typed `TResponse` values. Adapting while preserving the `__Result_{handler.Name}` and `ResultsKey` contract would re-implement the existing complexity via a wrapper, defeating the purpose. | +| `TransactionalOutboxStep` | `IOutboxStore` (now in 0.112.0) | Interface mismatch: bespoke `IOutboxStore` uses `SaveAsync(object) → string`; PatternKit `IOutboxStore` uses `EnqueueAsync(Message) → OutboxMessage`. Different return types and message wrapper model. | +| `AggregatorStep` | PatternKit Aggregator (future) | No Aggregator primitive in 0.112.0 | | `PluginManager` | `Strategy` + `AbstractFactory` | Phase H.8 — not yet started | | `AgentLoopStep` / `AgentDecisionStep` | TypeDispatcher | Phase H.7 — not yet started | | `ResilienceMiddleware` (Polly) | `RetryPolicy` | Phase F pilot option B — deferred | diff --git a/docs/patternkit-followup.md b/docs/patternkit-followup.md new file mode 100644 index 0000000..8732674 --- /dev/null +++ b/docs/patternkit-followup.md @@ -0,0 +1,243 @@ +# PatternKit Follow-Up — 0.112.0 Adoption Deferrals + +**Branch:** `feat/consume-patternkit-0.112` +**Date assessed:** 2026-05-22 +**Assessor:** Claude Sonnet 4.6 (refactor agent) + +This document captures every step evaluated against PatternKit 0.112.0 during +`feat/consume-patternkit-0.112` that was deferred with the specific reason why. It +supersedes the equivalent "Future Evaluation Targets" notes in `docs/patternkit-adoption.md`. +Use this as the starting point for the next PatternKit adoption pass. + +--- + +## Deferred: NormalizerStep → Normalizer + +**File:** `src/WorkflowFramework.Extensions.Integration/Transformation/NormalizerStep.cs` + +**PatternKit primitive:** `PatternKit.Messaging.Transformation.Normalizer` + +**Why deferred:** + +PatternKit's `Normalizer` dispatches via *content predicates* evaluated in +registration order (first-match-wins). `NormalizerStep` dispatches via an O(1) `Dictionary` +keyed lookup — the format detector returns a string key, not a `bool` predicate. + +Two specific blockers: + +1. **Predicate vs key dispatch model.** Converting each dictionary entry to a predicate + (`raw => format == key`) would change the dispatch from O(1) to O(n) and lose the dictionary + key contract from the constructor signature. + +2. **Error message behavioral mismatch.** When no format matches, the bespoke step throws + `InvalidOperationException($"No translator found for format '{format}' and no default translator configured.")`. + The test `UnknownFormatNoDefaultThrows` asserts that the message contains the format string. + PatternKit's miss reason is `"No format handler matched the raw input for normalizer '{name}'."` — + the unknown format key is absent. Fixing this without modifying the test requires a custom + exception mapping wrapper that adds complexity rather than removing it. + +**Resumption condition:** If PatternKit adds a keyed-dispatch variant of `Normalizer` that maps +string discriminators to handlers (similar to the `TypeDispatchRouter` sketch in `.plan/patternkit-extension-backlog.md`), +evaluate again. + +--- + +## Deferred: ContentEnricherStep → AsyncContentEnricher + +**File:** `src/WorkflowFramework.Extensions.Integration/Transformation/ContentEnricherStep.cs` + +**PatternKit primitive:** `PatternKit.Messaging.Transformation.AsyncContentEnricher` + +**Why deferred:** + +`AsyncContentEnricher` is designed for functional enrichment: each step receives the +current payload, augments it, and returns a new payload. The step's implementation stores the +final enriched payload back in the `Message`. + +`ContentEnricherStep` is a thin named wrapper around `Func` — a +side-effecting context mutation. The `IWorkflowContext` is passed by reference; the delegate +mutates it in place. Adapting to PatternKit would require: + +```csharp +AsyncContentEnricher.Create() + .Enrich("enrich", async (ctx, _, ct) => { await enrichAction(ctx); return ctx; }) + .Build(); +``` + +The `return ctx` discards PatternKit's copy-returning semantics entirely. The wrapper buys +nothing — the code after the refactor is longer than the original. The step itself is 3 +non-trivial lines; PatternKit would add ~10 lines of builder setup. + +**Resumption condition:** Not warranted at this complexity level. If PatternKit adds a +side-effect-oriented enricher (`AsyncSideEffectEnricher` that does not require a return value), +revisit. Otherwise keep bespoke. + +--- + +## Deferred: IdempotentReceiverStep → IdempotentReceiver + +**File:** `src/WorkflowFramework.Extensions.Integration/Endpoint/IdempotentReceiverStep.cs` + +**PatternKit primitive:** `PatternKit.Messaging.Reliability.IdempotentReceiver` + +**Why deferred — behavioral breaking change:** + +The bespoke step registers the message ID in the `HashSet` *before* calling the inner +step. This means: if the inner step throws, a subsequent call with the same ID is *silently +skipped* (because the ID is already registered). This is tested explicitly: + +``` +Test: ReAttemptAfterExceptionIsSkipped +Pins: "ID was added to the set BEFORE calling inner, so a second call IS skipped + even if inner threw." +``` + +PatternKit's `IdempotentReceiver` has the opposite semantics: + +1. `TryClaimAsync` claims the key (status = `Processing`) +2. Handler is called +3. On exception → `MarkFailedAsync` sets status to `Failed` + +A subsequent `TryClaimAsync` with the same key in `Failed` status returns `Claimed = false` AND +sets the status back to `Processing`, allowing the handler to be retried. This is the correct +resilient behavior for production idempotency, but it breaks the characterization test. + +**To unblock:** The test would need to be updated to remove the `ReAttemptAfterExceptionIsSkipped` +scenario (or relax it to document PatternKit's retry-on-failure semantics). This requires a +deliberate API-evolution decision — it is not safe to change as a refactor. + +--- + +## Deferred: ClaimCheckStep / ClaimRetrieveStep → ClaimCheck + +**File:** `src/WorkflowFramework.Extensions.Integration/Transformation/ClaimCheckStep.cs` + +**PatternKit primitive:** `PatternKit.Messaging.Transformation.ClaimCheck` + +**Why deferred — interface mismatch:** + +The bespoke `IClaimCheckStore` (in `WorkflowFramework.Extensions.Integration.Abstractions`) is +untyped: + +```csharp +Task StoreAsync(object payload, CancellationToken ct); +Task RetrieveAsync(string ticket, CancellationToken ct); +``` + +PatternKit's `IClaimCheckStore` is typed: + +```csharp +ValueTask StoreAsync(string claimId, TPayload payload, MessageHeaders headers, CancellationToken ct); +ValueTask?> TryLoadAsync(string claimId, CancellationToken ct); +``` + +The differences are: +- Untyped `object` vs typed `TPayload` +- PatternKit requires `MessageHeaders` (not available in WF context model) +- PatternKit takes a `claimId` parameter; bespoke generates the ID internally +- PatternKit returns `ClaimCheckStoredPayload?` vs bespoke returning `object` +- PatternKit uses `ValueTask` vs bespoke `Task` + +Bridging these interfaces would require an adapter class that wraps `IClaimCheckStore` in +`IClaimCheckStore` (with dummy headers), adding ~20 lines of bridge code to save 0 +lines in the step itself. Net: code increase. + +**Resumption condition:** If `WorkflowFramework.Extensions.Integration.Abstractions` migrates to +PatternKit's `IClaimCheckStore` as its primary claim check interface, the step can +adopt directly. + +--- + +## Deferred: PollingConsumerStep → AsyncPollingConsumer + +**File:** `src/WorkflowFramework.Extensions.Integration/Endpoint/PollingConsumerStep.cs` + +**PatternKit primitive:** `PatternKit.Messaging.Consumers.AsyncPollingConsumer` + +**Why deferred — semantic lifecycle mismatch:** + +`PollingConsumerStep` is a *single-shot* poll step: +1. Call `IPollingSource.PollAsync()` once +2. Write results to `context.Properties[ResultKey]` +3. Return + +`AsyncPollingConsumer` is a *continuous polling loop*: +1. Runs a `while (!ct.IsCancellationRequested)` loop +2. Calls the poll source on each iteration +3. Invokes a handler per-message +4. Sleeps between polls with configurable jitter/backoff + +These are different abstractions. The step is designed to be called from within a workflow +execution engine (once per workflow tick). PatternKit's consumer is designed to be run as a +background service (long-lived, driven to completion by cancellation). + +**Resumption condition:** If a future PatternKit release adds a `SinglePollConsumer` (one-shot +poll adaptor without the loop), that would fit. Alternatively, if WorkflowFramework adds a +background polling host that drives steps in a polling loop, `AsyncPollingConsumer` would be +the right fit there (not in the step itself). + +--- + +## Deferred: ScatterGatherStep → AsyncScatterGather + +**File:** `src/WorkflowFramework.Extensions.Integration/Composition/ScatterGatherStep.cs` + +**PatternKit primitive:** `PatternKit.Messaging.Routing.AsyncScatterGather>` + +**Why deferred — integration complexity and shared-context mutation model:** + +The bespoke `ScatterGatherStep` relies on a pattern where: +- All handlers share the same `IWorkflowContext` reference +- Each handler writes its result to `context.Properties[$"__Result_{handler.Name}"]` +- After `Task.WhenAll`, the step reads each handler's named result key from context + +PatternKit's `AsyncScatterGather` expects *isolated* per-recipient handlers that return a typed +`TResponse` value. Adapting would require: + +1. Each recipient executes the handler (mutating shared context) then reads back its named key +2. The shared `IWorkflowContext` becomes a concurrency hazard when written by parallel recipients + (the existing implementation has the same hazard but the keys are named distinctly per handler) +3. The aggregator (`Func, IWorkflowContext, Task>`) has a different + signature from PatternKit's `ResponseAggregator(IReadOnlyList>, Message, MessageContext)` + +The adaptation would re-implement the shared-context fan-out logic inside PatternKit's +recipient framework without simplifying the code. The characterization tests in +`ScatterGatherStepTests.cs` pin the exact `__Result_{handler.Name}` key convention and the +`context.Properties[ResultsKey]` output. + +**Resumption condition:** If the scatter-gather handlers are refactored to return typed values +(rather than writing to named context keys), the step could adopt `AsyncScatterGather` directly. +This is an API-evolution decision beyond the scope of a refactor. + +--- + +## Deferred: TransactionalOutboxStep → IOutboxStore + +**File:** `src/WorkflowFramework.Extensions.Integration/Endpoint/TransactionalOutboxStep.cs` + +**PatternKit primitive:** `PatternKit.Messaging.Reliability.IOutboxStore` + +**Why deferred — interface mismatch:** + +Bespoke `IOutboxStore` (in Abstractions): + +```csharp +Task SaveAsync(object message, CancellationToken ct); +``` + +PatternKit `IOutboxStore`: + +```csharp +ValueTask> EnqueueAsync(Message message, string? id, DateTimeOffset? createdAt, CancellationToken ct); +``` + +Key differences: +- Bespoke: untyped `object`, returns outbox ID as `string` +- PatternKit: typed `TPayload` wrapped in `Message`, returns full `OutboxMessage` +- Bespoke: ID is generated by the store; PatternKit accepts an optional caller-provided ID +- The step writes `OutboxIdKey = id` to context; PatternKit's return value is `OutboxMessage`, + requiring `.Id` access — minor but meaningful difference in null-safety and API surface + +**Resumption condition:** If `WorkflowFramework.Extensions.Integration.Abstractions` migrates to +PatternKit's `IOutboxStore` as the primary interface, the step can adopt directly +(write `context.Properties[OutboxIdKey] = result.Id`). diff --git a/src/WorkflowFramework.Extensions.Integration/Channel/WireTapStep.cs b/src/WorkflowFramework.Extensions.Integration/Channel/WireTapStep.cs index eb50c9f..536c6a0 100644 --- a/src/WorkflowFramework.Extensions.Integration/Channel/WireTapStep.cs +++ b/src/WorkflowFramework.Extensions.Integration/Channel/WireTapStep.cs @@ -1,9 +1,12 @@ -// Intentionally bespoke — WireTapStep's core contract (run a side-effect without disrupting -// the main flow, with optional error swallowing) is simpler than PatternKit's -// AsyncActionDecorator pipeline. AsyncActionDecorator wraps a component and transforms/ -// decorates it; WireTapStep wraps nothing — it IS the side-effect. Applying Decorator here -// would add indirection without modelling the pattern more clearly. Characterization tests -// added in Phase G.3. +// Refactored in feat/consume-patternkit-0.112 to delegate to +// PatternKit.Messaging.Channels.AsyncWireTap. +// The step wraps the caller-supplied Func into a +// PatternKit tap handler, maps swallowErrors to TapErrorPolicy, and exposes +// the same constructor signature and Name property as before. +// All Phase G.3 characterization tests pass without modification. +using PatternKit.Messaging; +using PatternKit.Messaging.Channels; + namespace WorkflowFramework.Extensions.Integration.Channel; /// @@ -12,8 +15,7 @@ namespace WorkflowFramework.Extensions.Integration.Channel; /// public sealed class WireTapStep : IStep { - private readonly Func _tapAction; - private readonly bool _swallowErrors; + private readonly AsyncWireTap _wireTap; /// /// Initializes a new instance of . @@ -22,8 +24,16 @@ public sealed class WireTapStep : IStep /// Whether to swallow errors from the tap action. Default true. public WireTapStep(Func tapAction, bool swallowErrors = true) { - _tapAction = tapAction ?? throw new ArgumentNullException(nameof(tapAction)); - _swallowErrors = swallowErrors; + if (tapAction is null) throw new ArgumentNullException(nameof(tapAction)); + + var policy = swallowErrors ? TapErrorPolicy.Swallow : TapErrorPolicy.Propagate; + + _wireTap = AsyncWireTap.Create("wire-tap") + .Tap("tap", async (message, _, ct) => + { + await tapAction(message.Payload).ConfigureAwait(false); + }, policy) + .Build(); } /// @@ -32,20 +42,7 @@ public WireTapStep(Func tapAction, bool swallowErrors = /// public async Task ExecuteAsync(IWorkflowContext context) { - if (_swallowErrors) - { - try - { - await _tapAction(context).ConfigureAwait(false); - } - catch - { - // Wire tap should not affect main flow - } - } - else - { - await _tapAction(context).ConfigureAwait(false); - } + var message = new Message(context); + await _wireTap.PublishAsync(message, cancellationToken: context.CancellationToken).ConfigureAwait(false); } } diff --git a/src/WorkflowFramework.Extensions.Integration/packages.lock.json b/src/WorkflowFramework.Extensions.Integration/packages.lock.json index 7acc2b3..db99d55 100644 --- a/src/WorkflowFramework.Extensions.Integration/packages.lock.json +++ b/src/WorkflowFramework.Extensions.Integration/packages.lock.json @@ -23,9 +23,9 @@ }, "PatternKit.Core": { "type": "Direct", - "requested": "[0.105.0, )", - "resolved": "0.105.0", - "contentHash": "ajdoXIVxeDeTi1NhS0ykTQHk4u/FpdvYrGx9DKvpwzc3z65rSBIWSOLn1vOG2O2tYnZQTxaDC3TSno1MyLhjBg==", + "requested": "[0.112.0, )", + "resolved": "0.112.0", + "contentHash": "iy+Pb7E4Wv06rWF0QciwFvFVjDaT+b1svE4SqscA70vU05z1I8I+krqnKnG+hG7FZJ3NVrN5zZ+FpYJnoRziIw==", "dependencies": { "System.Threading.Tasks.Extensions": "4.6.3" } @@ -67,7 +67,7 @@ "workflowframework": { "type": "Project", "dependencies": { - "PatternKit.Core": "[0.105.0, )" + "PatternKit.Core": "[0.112.0, )" } }, "workflowframework.extensions.integration.abstractions": { @@ -90,9 +90,9 @@ }, "PatternKit.Core": { "type": "Direct", - "requested": "[0.105.0, )", - "resolved": "0.105.0", - "contentHash": "ajdoXIVxeDeTi1NhS0ykTQHk4u/FpdvYrGx9DKvpwzc3z65rSBIWSOLn1vOG2O2tYnZQTxaDC3TSno1MyLhjBg==" + "requested": "[0.112.0, )", + "resolved": "0.112.0", + "contentHash": "iy+Pb7E4Wv06rWF0QciwFvFVjDaT+b1svE4SqscA70vU05z1I8I+krqnKnG+hG7FZJ3NVrN5zZ+FpYJnoRziIw==" }, "PolySharp": { "type": "Direct", @@ -113,7 +113,7 @@ "workflowframework": { "type": "Project", "dependencies": { - "PatternKit.Core": "[0.105.0, )" + "PatternKit.Core": "[0.112.0, )" } }, "workflowframework.extensions.integration.abstractions": { @@ -136,9 +136,9 @@ }, "PatternKit.Core": { "type": "Direct", - "requested": "[0.105.0, )", - "resolved": "0.105.0", - "contentHash": "ajdoXIVxeDeTi1NhS0ykTQHk4u/FpdvYrGx9DKvpwzc3z65rSBIWSOLn1vOG2O2tYnZQTxaDC3TSno1MyLhjBg==" + "requested": "[0.112.0, )", + "resolved": "0.112.0", + "contentHash": "iy+Pb7E4Wv06rWF0QciwFvFVjDaT+b1svE4SqscA70vU05z1I8I+krqnKnG+hG7FZJ3NVrN5zZ+FpYJnoRziIw==" }, "Microsoft.Build.Tasks.Git": { "type": "Transitive", @@ -185,7 +185,7 @@ "dependencies": { "Microsoft.Extensions.DependencyInjection.Abstractions": "[10.0.5, )", "Microsoft.Extensions.Hosting.Abstractions": "[10.0.5, )", - "PatternKit.Core": "[0.105.0, )" + "PatternKit.Core": "[0.112.0, )" } }, "workflowframework.extensions.integration.abstractions": { @@ -246,9 +246,9 @@ }, "PatternKit.Core": { "type": "Direct", - "requested": "[0.105.0, )", - "resolved": "0.105.0", - "contentHash": "ajdoXIVxeDeTi1NhS0ykTQHk4u/FpdvYrGx9DKvpwzc3z65rSBIWSOLn1vOG2O2tYnZQTxaDC3TSno1MyLhjBg==" + "requested": "[0.112.0, )", + "resolved": "0.112.0", + "contentHash": "iy+Pb7E4Wv06rWF0QciwFvFVjDaT+b1svE4SqscA70vU05z1I8I+krqnKnG+hG7FZJ3NVrN5zZ+FpYJnoRziIw==" }, "Microsoft.Build.Tasks.Git": { "type": "Transitive", @@ -296,7 +296,7 @@ "dependencies": { "Microsoft.Extensions.DependencyInjection.Abstractions": "[10.0.5, )", "Microsoft.Extensions.Hosting.Abstractions": "[10.0.5, )", - "PatternKit.Core": "[0.105.0, )" + "PatternKit.Core": "[0.112.0, )" } }, "workflowframework.extensions.integration.abstractions": { @@ -364,9 +364,9 @@ }, "PatternKit.Core": { "type": "Direct", - "requested": "[0.105.0, )", - "resolved": "0.105.0", - "contentHash": "ajdoXIVxeDeTi1NhS0ykTQHk4u/FpdvYrGx9DKvpwzc3z65rSBIWSOLn1vOG2O2tYnZQTxaDC3TSno1MyLhjBg==" + "requested": "[0.112.0, )", + "resolved": "0.112.0", + "contentHash": "iy+Pb7E4Wv06rWF0QciwFvFVjDaT+b1svE4SqscA70vU05z1I8I+krqnKnG+hG7FZJ3NVrN5zZ+FpYJnoRziIw==" }, "Microsoft.Build.Tasks.Git": { "type": "Transitive", @@ -414,7 +414,7 @@ "dependencies": { "Microsoft.Extensions.DependencyInjection.Abstractions": "[10.0.5, )", "Microsoft.Extensions.Hosting.Abstractions": "[10.0.5, )", - "PatternKit.Core": "[0.105.0, )" + "PatternKit.Core": "[0.112.0, )" } }, "workflowframework.extensions.integration.abstractions": { diff --git a/tests/WorkflowFramework.Tests.TinyBDD/packages.lock.json b/tests/WorkflowFramework.Tests.TinyBDD/packages.lock.json index 4ca3c55..9f0f5dc 100644 --- a/tests/WorkflowFramework.Tests.TinyBDD/packages.lock.json +++ b/tests/WorkflowFramework.Tests.TinyBDD/packages.lock.json @@ -342,7 +342,7 @@ "dependencies": { "Microsoft.Extensions.DependencyInjection.Abstractions": "[10.0.5, )", "Microsoft.Extensions.Hosting.Abstractions": "[10.0.5, )", - "PatternKit.Core": "[0.105.0, )" + "PatternKit.Core": "[0.112.0, )" } }, "workflowframework.extensions.agents": { @@ -377,7 +377,7 @@ "workflowframework.extensions.integration": { "type": "Project", "dependencies": { - "PatternKit.Core": "[0.105.0, )", + "PatternKit.Core": "[0.112.0, )", "WorkflowFramework": "[1.0.0, )", "WorkflowFramework.Extensions.Integration.Abstractions": "[1.0.0, )" } @@ -472,9 +472,9 @@ }, "PatternKit.Core": { "type": "CentralTransitive", - "requested": "[0.105.0, )", - "resolved": "0.105.0", - "contentHash": "ajdoXIVxeDeTi1NhS0ykTQHk4u/FpdvYrGx9DKvpwzc3z65rSBIWSOLn1vOG2O2tYnZQTxaDC3TSno1MyLhjBg==" + "requested": "[0.112.0, )", + "resolved": "0.112.0", + "contentHash": "iy+Pb7E4Wv06rWF0QciwFvFVjDaT+b1svE4SqscA70vU05z1I8I+krqnKnG+hG7FZJ3NVrN5zZ+FpYJnoRziIw==" } }, "net8.0": { @@ -857,7 +857,7 @@ "dependencies": { "Microsoft.Extensions.DependencyInjection.Abstractions": "[10.0.5, )", "Microsoft.Extensions.Hosting.Abstractions": "[10.0.5, )", - "PatternKit.Core": "[0.105.0, )" + "PatternKit.Core": "[0.112.0, )" } }, "workflowframework.extensions.agents": { @@ -894,7 +894,7 @@ "workflowframework.extensions.integration": { "type": "Project", "dependencies": { - "PatternKit.Core": "[0.105.0, )", + "PatternKit.Core": "[0.112.0, )", "WorkflowFramework": "[1.0.0, )", "WorkflowFramework.Extensions.Integration.Abstractions": "[1.0.0, )" } @@ -990,9 +990,9 @@ }, "PatternKit.Core": { "type": "CentralTransitive", - "requested": "[0.105.0, )", - "resolved": "0.105.0", - "contentHash": "ajdoXIVxeDeTi1NhS0ykTQHk4u/FpdvYrGx9DKvpwzc3z65rSBIWSOLn1vOG2O2tYnZQTxaDC3TSno1MyLhjBg==" + "requested": "[0.112.0, )", + "resolved": "0.112.0", + "contentHash": "iy+Pb7E4Wv06rWF0QciwFvFVjDaT+b1svE4SqscA70vU05z1I8I+krqnKnG+hG7FZJ3NVrN5zZ+FpYJnoRziIw==" }, "System.Diagnostics.DiagnosticSource": { "type": "CentralTransitive", @@ -1391,7 +1391,7 @@ "dependencies": { "Microsoft.Extensions.DependencyInjection.Abstractions": "[10.0.5, )", "Microsoft.Extensions.Hosting.Abstractions": "[10.0.5, )", - "PatternKit.Core": "[0.105.0, )" + "PatternKit.Core": "[0.112.0, )" } }, "workflowframework.extensions.agents": { @@ -1428,7 +1428,7 @@ "workflowframework.extensions.integration": { "type": "Project", "dependencies": { - "PatternKit.Core": "[0.105.0, )", + "PatternKit.Core": "[0.112.0, )", "WorkflowFramework": "[1.0.0, )", "WorkflowFramework.Extensions.Integration.Abstractions": "[1.0.0, )" } @@ -1524,9 +1524,9 @@ }, "PatternKit.Core": { "type": "CentralTransitive", - "requested": "[0.105.0, )", - "resolved": "0.105.0", - "contentHash": "ajdoXIVxeDeTi1NhS0ykTQHk4u/FpdvYrGx9DKvpwzc3z65rSBIWSOLn1vOG2O2tYnZQTxaDC3TSno1MyLhjBg==" + "requested": "[0.112.0, )", + "resolved": "0.112.0", + "contentHash": "iy+Pb7E4Wv06rWF0QciwFvFVjDaT+b1svE4SqscA70vU05z1I8I+krqnKnG+hG7FZJ3NVrN5zZ+FpYJnoRziIw==" }, "System.Diagnostics.DiagnosticSource": { "type": "CentralTransitive",