Workable.Sdk
1.1.82326.1
dotnet add package Workable.Sdk --version 1.1.82326.1
NuGet\Install-Package Workable.Sdk -Version 1.1.82326.1
<PackageReference Include="Workable.Sdk" Version="1.1.82326.1" />
<PackageVersion Include="Workable.Sdk" Version="1.1.82326.1" />
<PackageReference Include="Workable.Sdk" />
paket add Workable.Sdk --version 1.1.82326.1
#r "nuget: Workable.Sdk, 1.1.82326.1"
#:package Workable.Sdk@1.1.82326.1
#addin nuget:?package=Workable.Sdk&version=1.1.82326.1
#tool nuget:?package=Workable.Sdk&version=1.1.82326.1
Workable
Workable is a .NET work orchestration library for applications that need more than "run this in the background." It turns background jobs, operational tasks, recurring work, and user-triggered actions into first-class work the host can queue, observe, control, and configure.
Most applications eventually grow work that does not fit cleanly inside the request, controller action, message handler, or command that started it. Sending email, refreshing caches, synchronizing data, running maintenance tasks, retrying transient failures, and coordinating long-running operations all need identity, state, cancellation, status, events, and a way to be found later. Workable gives that work a consistent runtime model instead of leaving each feature to invent its own.
Workable is useful when you want feature code to define work near the feature that needs it, while the host application keeps control of execution. Feature assemblies can declare their own work with Workable.Sdk. Libraries that need to use a hosted system can depend on Workable.Abstractions and accept IWorkSystem from the host. The host application owns the actual Workable systems, decides which work belongs in each system, and controls how workers start, retry, recur, respect concurrency, and stay available for inspection.
That split lets teams add work near the feature that needs it without forcing every feature library to know how the application hosts work. At runtime, the host gets a consistent surface for queueing work, awaiting completion, pausing, canceling, reconfiguring workers, and subscribing to work events.
Workable also gives applications a path to expose the same authored work through more than one channel. Direct .NET callers, HTTP endpoints, MCP clients, and realtime SignalR clients can all work against the same catalog while preserving request context, structured outcomes, worker history, and invocation rules.
Why Use Workable?
- Define work once and invoke it through .NET, HTTP, or MCP when those channels are enabled.
- Register workflow definitions that coordinate existing work through dispatch, typed fan-out, parallel branches, and join steps inside the host runtime.
- Keep feature libraries independent from the host runtime while still letting them contribute work.
- Queue fire-and-forget work without losing the ability to query, observe, cancel, pause, retry, or purge it.
- Give operators a real admin surface for work: live system and worker visibility, executable definitions, diagnostics, and control actions instead of one-off job screens and custom tooling.
- Attach runtime behavior such as recurrence, transient retry, failed-worker handling, idempotency, concurrency, durability, retention, logging, profiling, initialization, invocation policy, and start policy.
- Persist short-lived iteration logs and profiles so developers and agents can inspect the work they just ran and answer questions such as how many SQL commands or HTTP requests it executed.
- Use structured inputs, outputs, messages, worker snapshots, event payloads, and status summaries instead of ad hoc task tracking.
- Preserve who or what started work through request context and origin metadata for HTTP, MCP, SignalR, and direct .NET calls.
Packages
Core Packages
Workable.Sdk: contracts and registration helpers for assemblies that author work.Workable.Abstractions: contracts for libraries that consume an already-hosted work system.Workable: in-process host and runtime for Workable systems.
Optional Packages
Workable.SqlServer: SQL Server persistence integration for durable queueing and completion, durable workflows, persistence-backed idempotency and concurrency, and expiring execution diagnostics.Workable.AspNetCore: ASP.NET Core request-context and authorization integration for custom endpoints and hosts.Workable.Entra: Workable actor and authorization-claim integration for ASP.NET Core hosts that already authenticate Microsoft Entra identities.Workable.Views: shared component-view contracts and projections used by HTTP and SignalR adapters; most applications receive it transitively throughWorkable.HttpApiorWorkable.SignalRinstead of referencing it directly.Workable.HttpApi: standard HTTP endpoints for queueing, querying, and controlling workers and workflow runs.Workable.Mcp: MCP server adapter for authored work, worker and workflow queries, and worker and workflow actions.Workable.SignalR: realtime worker collections, worker and workflow events, worker details, and component-view updates for ASP.NET Core clients.
Apps And Tools
apps/samples/Workable.SampleHost: runnable ASP.NET Core sample app with HTTP API, MCP, SignalR, fake-auth profiles, and SQL Server LocalDB durability scenarios.apps/tools/Workable.PerformanceHarness: opt-in scenario runner and BenchmarkDotNet harness for runtime, query, view, realtime, and SQL durability performance work.apps/tools/Workable.SqlServer.Cli: SQL Server schema generation and deployment CLI for Workable persistence.apps/web/workable-admin-ui: Next.js admin UI for inspecting and operating Workable systems through the HTTP API and SignalR realtime updates.
Documentation
Start with the docs landing page: Workable Docs.
Recommended entry points:
- Getting Started if you are evaluating or integrating Workable.
- Registration if you are authoring work in feature assemblies.
- Workflows if you want to author multi-step orchestrations from existing work definitions.
- Implementation if you want to implement work classes and understand what executor code can do at runtime.
- Queueing if you already have work definitions and want to invoke them.
- Configuration if you are tuning start behavior, retry, recurrence, failed-worker handling, concurrency, durability, logging, retention, or invocation rules.
- Persistent Execution Diagnostics if a developer or agent needs expiring iteration logs, profiles, or SQL/HTTP operation counts from recently executed work.
- HTTP API, MCP, and Realtime if you are exposing Workable over transports.
- Microsoft Entra Authentication if the host already authenticates Entra identities and Workable should interpret their actor and group claims without taking ownership of JWT configuration.
- Abstractions Surface if you are consuming a hosted system from another library.
- Workable SQL Server Integration if you need durable queueing, durable workflows, persistence-backed coordination, or execution-diagnostics storage.
- Sample Host if you want a runnable reference app.
- Admin UI if you want the browser-based operator surface.
- Performance Harness if you are measuring runtime or adapter performance.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.0)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Workable.Sdk:
| Package | Downloads |
|---|---|
|
Workable.Abstractions
Consume a hosted Workable system from libraries that need to queue, query, observe, or control work without hosting the runtime. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.1.82326.1 | 66 | 8/24/2026 |
| 1.1.81126.1 | 239 | 8/11/2026 |
| 1.1.80926.1 | 172 | 8/9/2026 |
| 1.1.80726.1 | 179 | 8/8/2026 |
| 1.1.80526.1 | 206 | 8/5/2026 |
| 1.1.71926.1 | 233 | 7/21/2026 |
| 1.1.70926.1 | 240 | 7/10/2026 |
| 1.1.70626.2 | 288 | 7/6/2026 |
| 1.1.70626.1 | 205 | 7/6/2026 |
| 1.1.63026.1 | 219 | 6/30/2026 |
| 1.1.61226.1 | 259 | 6/12/2026 |
| 1.1.159.1 | 285 | 6/8/2026 |
| 1.1.158.1 | 219 | 6/7/2026 |
| 1.1.157 | 219 | 6/7/2026 |
| 1.1.153.1 | 230 | 6/2/2026 |
| 1.1.146.1 | 420 | 5/26/2026 |
| 1.1.142.3 | 253 | 5/23/2026 |
| 1.1.0 | 246 | 5/22/2026 |
| 1.1.0-preview | 194 | 5/21/2026 |
| 1.0.0 | 226 | 5/21/2026 |
# 1.1.082326.1
Date: 2026-08-23
These notes describe only the user-visible and public API differences from `1.1.081126.1`. Intermediate implementation details are omitted.
## Breaking Changes
- `Workable.Entra` no longer registers or configures JWT bearer authentication. Hosts now own authentication handlers, tenant, issuer, audience, signature and lifetime validation, inbound-claim mapping, JWT events, policies, challenges, and middleware ordering. Workable only selects and interprets a host-authenticated identity.
- `WorkableEntraAuthorizationOptions` removed `TenantId`, `Audience`, `AdditionalAudiences`, `AuthorityHost`, `Authority`, `AllowSignalRAccessTokensFromQueryString`, `SignalRAccessTokenQueryStringName`, and `SignalRAccessTokenQueryStringPaths`. Related authority and SignalR constants were removed from `WorkableEntraAuthorizationDefaults`; legacy configuration keys with those names are ignored.
- `Workable.Entra` no longer references `Microsoft.AspNetCore.Authentication.JwtBearer`. Applications relying on that transitive dependency must reference and configure their chosen authentication package directly.
- `MapWorkableApi(...)`, `MapWorkableMcp(...)`, and `MapWorkableSignalR(...)` now apply the host's `DefaultPolicy` unless a named policy or `useHostFallbackPolicy: true` is selected. Hosts that intentionally rely only on `FallbackPolicy` must opt into that behavior. Existing binaries and method-group bindings to the former signatures must be rebuilt or updated.
- The public `WorkableRealtimeHub` constructor now requires `IWorkableSignalRPayloadSerializer`. Direct constructors must supply that dependency.
- `IWorkActorFactory`, `IWorkRequestContextFactory`, `IHttpContextWorkCommandDispatcher`, and `IHttpContextWorkflowCommandDispatcher` are request-scoped. Singleton consumers must resolve them from an active request or explicit service scope.
- `Workable.SignalR` no longer modifies the host's shared JSON protocol options. Workable retains its string-enum wire format through package-local serialization. The default serializer supports only an effective `WorkableRealtimeHub` protocol list containing `json`; hosts selecting another protocol must replace `IWorkableSignalRPayloadSerializer`.
- In explicit transport-scheme mode, `WorkableAspNetCoreAuthentication.IsAuthenticated(...)` reports only an already-selected Workable principal. Custom low-level endpoints must first call `EnsureAuthenticatedAsync(...)` or `GetAuthenticatedPrincipalAsync(...)`.
- `IWorkExecutionDiagnosticsRepository.UpsertCaptureRule(...)` now atomically replaces the active system-wide or same-definition rule. Custom repositories must implement the same-scope replacement contract.
- `IWorkAuthorizationBuilder` adds explicit Discover helpers. Custom implementations must implement the expanded interface.
- Workflow Queue, Start, Pause, and Cancel grants are now enforced individually at runtime instead of treating coarse Operate metadata as authority for every workflow action.
- Removed the realtime debug HTTP routes under `/debug/realtime` and their public snapshot DTOs. Subscription bookkeeping is now internal to the SignalR runtime.
- Inaccessible named systems now use the same not-found behavior as unknown systems across HTTP, SignalR, and MCP. Clients must handle the corresponding `404`, hub not-found error, or empty MCP tool list.
- Whitespace-only named Workable systems are rejected during registration because blank transport selectors identify the default system.
- The admin UI now requires an independent `sessionSecret` for Basic authentication. The Basic password is no longer accepted as a session-signing fallback.
## Authorization and Host Authentication
- Added `AllowDiscoverToGroups(...)` and `AllowDiscoverToKnownAuthenticatedUsers()` with the redacted `IWorkSystemSession.Discovery` catalog. Discover exposes definition descriptors and schemas without retained work data; Read and Operate imply Discover.
- Added `AllowReadToKnownAuthenticatedUsers()` for known authenticated actors that should read definitions and retained work without receiving queue, worker-action, or reconfiguration permission.
- Added discovery/read/operate properties and counts to `WorkDefinitionAuthorization` and `WorkSystemAccessSummary` without changing existing positional record construction or deconstruction shapes.
- Added a no-configuration `AddWorkableEntraAuthorization()` overload for hosts that want Workable to interpret their existing authenticated principal as Entra.
- Added `IWorkClaimsIdentitySelector`, ordered `IWorkActorClaimsMapper`, ordered `IWorkAuthorizationGroupClaimMapper`, and Entra `IdentityPredicate` extension points. Actor identity, authentication state, and groups are derived from one host-selected authenticated identity.
- Entra integration configuration now owns only `AuthenticationScheme`, `MapScopesToWorkableGroups`, `MapAppRolesToWorkableGroups`, and `MapGroupsToWorkableGroups`. `AuthenticationScheme` selects an existing host scheme; leaving it unset preserves the host-produced principal. Malformed explicit values fail configuration.
- Workable captures one identity, actor projection, and claims-derived group set per HTTP or MCP operation and per SignalR connection. Deferred work reuses that snapshot without retaining request-scoped services.
- Explicit transport authentication remains private to Workable request state and does not replace `HttpContext.User`. HTTP and MCP challenges are delegated to the host-selected challenge handler.
- Operate-only callers receive control outcomes without retained worker, definition, workflow-run, output, or exception details. Discovery, direct reads, notifications, completion handles, and workflow child projections apply the same definition and diagnostics boundaries.
- Named systems remain concealed until the caller has system access. HTTP host discovery also redacts complete catalog totals from callers without full discovery permission.
## SignalR
- Capability discovery is now mapping-driven. One mapped hub path can be advertised while aliases use `advertise: false`; registration without a mapped hub no longer advertises an unusable route.
- Added host-owned default, named, and fallback authorization-policy selection without registering policies or choosing authentication schemes.
- Added optional `UseWorkableSignalRAccessTokens()` middleware. It promotes one syntactically valid query token only for a mapped Workable hub after routing and before host authentication.
- Added host-replaceable payload serialization that preserves host JSON naming, encoding, and converter choices without changing global SignalR options.
- Added eager validation for Workable-owned timing, capacity, batch-size, overflow, event-filter, and protocol settings when a hub is mapped.
- Added independent per-connection and host-wide admission bounds for named-view, raw-event, and worker-overview subscriptions. Invalid, authorization-disjoint, and unproducible subscriptions are rejected before retaining capacity.
- Added configurable raw-event filter count and value-length limits. Blank restrictions, incomplete key filters, undefined key kinds, contradictory view scopes, and duplicate component ids are rejected rather than broadened or retained.
- Authentication and claims authorization are frozen when the connection is established, and the connection closes at the host-issued authentication ticket's `ExpiresUtc`.
- Realtime groups are isolated by system, authorization, criteria, and actor. Subscription replacement and disconnect cleanup preserve the active subscription state.
- SignalR and other HTTP-derived Workable provenance retain only path base and path, excluding query strings that may contain credentials or caller-controlled secrets.
## Admin UI Security
- Built-in Basic authentication is disabled by default and must be enabled explicitly. Malformed enablement fails configuration.
- Added process-local failed-attempt protection shared by form login and direct Basic authorization, with source-and-account, account-wide, and process-wide buckets. Multi-process deployments should continue to rate-limit Basic login at the edge.
- Session-signing secrets are required independently from authentication credentials and must contain at least 32 UTF-8 bytes. Sessions are bound to the active Basic credentials or Entra tenant/client configuration, re-evaluate Entra email policy on every request, and enforce an absolute lifetime in addition to sliding renewal.
- Entra OAuth state is authenticated, production OAuth and session cookies use browser-enforced `__Host-` semantics, and duplicate cookies are rejected. Logout uses bounded signed tombstones shared through browser state, remains effective across delayed or concurrent authentication responses, and does not require a server-side session store or shorten sessions created after logout.
- Entra metadata, signing-key, and token backchannels enforce HTTPS authority-origin binding, refused redirects, request deadlines, cancellation, one-MiB response limits, and bounded coalescing caches. Signing-key rotation uses one coalesced, retry-throttled refresh while retaining the last valid cached key set through transient refresh failures.
- Delegated Entra tokens are encrypted and bound to the immutable signed-in identity, admin session, tenant/client, and target API configuration. Refresh coordination and immutable browser snapshots support concurrent requests and multiple admin UI processes.
- Production Entra target APIs must use HTTPS. Explicit malformed target bindings and malformed security settings fail closed.
- Server-only JSON configuration now validates security-sensitive container, string, list, and boolean types at runtime. Syntactically valid but wrong-typed values fail closed instead of being coerced or reaching authentication code.
- The admin proxy refuses redirects, bounds request bodies, streams responses with cancellation and backpressure, releases discarded upstream bodies, supports `DELETE`, and returns valid rotated authentication state even when the hosted API request fails.
- Production-facing configuration failures return generic client responses while retaining exact diagnostics server-side.
## Profiling and Execution Diagnostics
- Added system-wide temporary full-profile capture rules and per-worker `ProfilingCaptureMode` reconfiguration. Exact-worker full capture requires diagnostics access and authoritative worker-reconfiguration permission.
- Added worker-overview profiling state and `CanToggleFullProfileCapture` advisory authorization for permission-aware clients.
- Added `IWorkWorkerReconfigurationAuthorizationSource`, `IWorkOperationAccessSource`, and `WorkOperationAccessSummary` so custom systems and views can report exact caller-scoped controls without replacing authoritative checks.
- Added `IWorkSystemSession.ReconfigureDefinition(...)` as the caller-scoped definition-reconfiguration operation, including Operate-without-Read support.
- Persistent diagnostics now keeps one active rule per system-wide or definition scope in memory and SQL Server. Saving the same scope replaces the previous rule under concurrency.
- Capture controls moved from the admin overview to the system catalog, definition detail, and worker detail. The UI supports creating, updating, and disabling capture at the relevant scope, with refreshed state and auto-dismissing success feedback.
- Actor-only and combined actor/definition profile rules remain available through HTTP, but the admin UI does not create them because it cannot validate host-owned stable actor identifiers.
## Validation, Limits, and Data Boundaries
- Undefined worker and workflow actions return an invalid result or HTTP `400` instead of falling back to another action. Queue and reconfiguration payloads reject undefined enum values.
- Component views accept at most 32 non-empty, case-insensitively unique component ids.
- Workflow child samples are limited to `0` through `25`. Workflow run and child pages have bounded skip, take, retained-child, receipt, and authoritative-read work.
- Workflow operator views, shared events, and completion messages expose child data only when the caller can read the child definition. Child-controlled messages, exception text, and diagnostic metadata are replaced with stable workflow-owned results across that boundary.
- Change streams, iteration completions, bulk worker actions, queue outcomes, system-stop results, MCP discovery, and transport errors preserve the same caller Read, diagnostics, and existence-hiding boundaries as direct operations.
- Host-provider and custom-converter failures return stable transport errors instead of raw exception details. Workable-owned validation errors remain actionable.
- Execution-diagnostics queries validate result counts at the core boundary before invoking built-in or custom repositories.
- HTTP host discovery distinguishes the unnamed default system from legal named systems such as `<default>`.
- Admin login return paths reject browser-normalized cross-origin forms, and inaccessible named systems have the same externally visible result as unknown systems.
## Performance
- Authorization access summaries now count work and workflow access in single passes, match authorization groups without LINQ/delegate allocations, and cache system-wide Read and Operate decisions within each evaluator.
- SQL Server durable claims and final cleanup now preserve a consistent queue-before-entry lock order, including claim-result materialization, so those operations can proceed concurrently without a lock-order deadlock.
- Focused benchmarks against `1.1.081126.1` measured `DescribeAccess` 36–37% faster with 60–66% less allocation at 8 and 64 definitions. SignalR throughput remained within run-to-run variance across the tested connection and subscription workloads.
## Documentation and Testing
- Reworked the Entra guide around host-owned authentication, existing schemes, identity classification, claim mapping, audience ownership, multi-tenant actor ids, group overage, and deployment checks.
- Updated HTTP, MCP, SignalR, ASP.NET Core, authorization, profiling, execution-diagnostics, project-structure, getting-started, sample-host, admin UI, workflow, and queueing documentation for the final release behavior.
- Removed documentation for the deleted realtime debug routes.
- Added broad .NET, SQL Server, MCP, SignalR, HTTP, workflow, authorization, and admin UI regression coverage for the new public behavior and security boundaries.
- Added first-class .NET and SQL Server extension coverage collection and expanded persistence, profiling, registration, validation, and failure-path tests to bring both the core non-UI surface and `Workable.SqlServer` above 95% branch coverage independently.
- Added the admin UI `test:coverage` command with inline TypeScript/TSX source maps so changed production branches can be mapped to the native Node coverage report.