Release v0.0.60
Overviewβ
This release lands two long-tracked capabilities and hardens the transition pipeline. Sandboxed, component-referenced custom C# script helpers let consuming teams ship their own helper classes as .csx components and reference them from a mapping's scripts.helpers, compiled and run under a two-layer sandbox (#710). State aliases expose role-scoped, multi-language state labels without touching the internal state identity (#648). The transition pipeline gains configurable async execution modes β continuation enqueueing, transition atomicity, chain-ownership gating, and a chain reaper for stuck instances (#725). FunctionScope is now enforced consistently on every function-invocation entry point (#709). A correctness fix removes EF compiled queries (broken under PGBouncer + multi-schema) and makes the duplicate-key check deterministic (#715), and an operations hardening pass disables production Swagger and promotes function/mapping failures to Error-level logging (#724). This bump also advances the component schema to 0.0.46.
Featuresβ
Sandboxed, component-referenced custom C# script helpers (#710)β
Consuming developers can now ship their own C# helper classes as components β uploaded as .csx, just like flows, tasks, and views β reference them from a transition mapping, and have the runtime build the helper classes first, then compile and run the mapping against them. Helpers are sandboxed and cached by content hash.
- Delivery: a helper is a component (
.csx), source-compiled at runtime (not a precompiled DLL) β the only delivery the runtime can sandbox, since it owns the Roslyn compile. - Wiring: referenced from the mapping's
scriptsblock viascripts.helpers[]. Explicit, per-flow, no global state.ScriptBasestays runtime-owned. - Sandbox grants:
scripts.allowedAssemblies[]makes the reference allow-list dynamic per-mapping β merged on top of the global baseline (Scripting:Sandbox:AllowedAssemblies), so a flow grants only the assemblies its helpers need without widening the baseline for everyone. - Trust: restricted/sandboxed (best-effort) via a two-layer compile-time gate β reference allow-list plus a banned-API analyzer β compiled into a shared collectible
AssemblyLoadContext.
// transition mapping β scripts block
"scripts": {
"helpers": [ // helper component references
{ "key": "rsa-crypto", "version": "1.0.0", "domain": "core", "flow": "sys-mappings" }
],
"allowedAssemblies": [ "System.Security.Cryptography" ] // per-mapping sandbox grant
}
Migration guide: for a detailed Turkish walkthrough of every v0.0.60 feature and its migration steps, see vNext v0.0.60 Migration Rehberi.
Reference: issue #710 β see also Mappings and the Mapping component.
State aliases with role-based visibility (#648)β
The same internal state can now be presented differently depending on the user's role, while the underlying workflow logic continues to use the real state identity. An applicant's case may internally sit in one of several detailed evaluation states, while the customer sees a single simplified alias such as "Application Under Review".
A state may declare an optional alias[] array, where each stateAlias carries:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Alias name. |
roles | roleGrant[] | yes | Roles for which this alias applies. DENY overrides ALLOW. |
labels | languageLabel[] | yes | Multi-language labels shown to matching users. |
Multiple internal states can map to the same external alias, and alias resolution is layered on top of the existing role model (so DENY grants still win). Internal workflow logic, transitions, and persistence are unaffected β aliases only shape the presentation layer of query/response rendering.
Reference: issue #648 β see also Workflow component and Authorization.
Configurable async transition execution modes (#725)β
The transition pipeline gains configurable async execution, controlled by four runtime flags:
- Continuation enqueueing β continuations can be enqueued (optionally via the outbox) for improved durability instead of running inline.
- Transition atomicity β controls whether a transition and its continuation commit as one unit.
- Chain ownership gating β a chain ownership token system provides fine-grained control over access to instances in the Busy state, preventing concurrent chains from stepping on each other.
- Stuck-instance recovery β a new chain reaper service automatically resolves instances whose heartbeats have gone stale, releasing ownership so they can resume.
The change ships with EF Core migrations for the durability refactor schema changes, plus architecture documentation covering the execution modes and operational guidance.
Reference: PR #725 β see also Sync vs Async execution.
Consistent FunctionScope enforcement on invocation (#709)β
FunctionScope is now enforced uniformly across both function-invocation entry points (GetFunctionByKeyAsync and GetFunctionByInstanceAsync), which both funnel through ExecuteFunctionAsync:
| Scope | Rule |
|---|---|
| Domain | Always runs β exempt from every scope restriction. |
| Instance | Only runs when an instance exists. |
Flow (TaskScope.Flow, "F") | Requires an instance and the function to be declared in that instance's flow (workflow.Functions). |
Previously the guard only checked Flow membership, and only when an instance was present β so Instance/Flow-scoped functions could be invoked through the domain-level endpoint with no restriction, and scope failures leaked out as incidental 404s. Scope violations now return a deliberate 403 Forbidden (FunctionScopeNotSatisfied, Function:800002).
Fixesβ
Remove EF compiled queries + deterministic duplicate-key check (#715)β
Two related defects in the EF instance repository layer:
- EF compiled queries break under PGBouncer + multi-schema.
EF.CompileAsyncQuerycaches the query plan β including the resolved schema β on astatic readonlydelegate shared across all requests. With per-request schema resolution (ICurrentSchema) and PGBouncer transaction pooling, the cached delegate could bind to the wrong schema / stale connection state. EF Core already caches non-compiled query plans transparently, so the compiled queries provided no benefit while causing correctness bugs β they are now removed. - Non-deterministic duplicate-key check.
CheckExistingInstanceAsynclooked up an existing instance with no status filter and no ordering, so when multiple rows shared a key (terminal history plus a live one) Postgres could return an arbitrary row β occasionally allowing a second active instance with the same key. The check is now deterministic: a key is considered "in use" only by non-terminal (Active/Busy) instances, guaranteeing at most one live instance per key.
Reference: issue #715
Operations & Observabilityβ
Disable production Swagger + harden function/mapping logging (#724)β
- Swagger off in production.
UseAetherApiVersioningnow passesuseSwagger/useSwaggerUias!IsProduction()across the four pipelines (Orchestration,Execution,InboxWorker,OutboxWorker), so the public production surface no longer exposes the API explorer. The administrativePublishAsyncendpoint is hidden from the API Explorer via[ApiExplorerSettings(IgnoreApi = true)]. - Failures are visible.
FunctionAppService.ExecuteFunctionAsyncnow catches task-coordinator exceptions and logs execution and output/script-mapping failures atErrorlevel (returning a clear failureResultwhen mapping throws). Task business-failure logs inTaskExecutionEnginewere promoted fromDebugtoError. - No more NREs in executor logs. Direct
context.ScriptContext.Instance.Idusage was replaced withInstance?.Id ?? Guid.Emptyacross the script / Dapr / HTTP / trigger executors, so custom functions running without an instance context no longer throwNullReferenceExceptionwhile logging.
Reference: PR #724
Configuration Updatesβ
Configuration for v0.0.60:
{
"runtimeVersion": "0.0.60",
"schemaVersion": "0.0.46"
}
Note: Schema version advances to 0.0.46 (from
0.0.43). The bump addsscripts.helpers[]/scripts.allowedAssemblies[]on transition mappings (#710) and thealias[]/stateAliasdefinition on states (#648). Update@burgan-tech/vnext-schemain your domain project before validating against this runtime.
Container images: published at tag 0.0.60 under ghcr.io/burgan-tech/vnext/* (execution, orchestrator, init, inbox, outbox, db-migrator), Cosign-signed (keyless OIDC) with SBOM + provenance. Immutable digests are listed in the GitHub release.
Issues Referencedβ
- vnext #710 β Sandboxed, component-referenced custom C# script helpers.
- vnext #648 β State alias support with role-based visibility.
- vnext #725 β Configurable async transition execution modes (continuation, atomicity, chain ownership, chain reaper).
- vnext #709 β Enforce
FunctionScopeon function invocation (closes #637). - vnext #715 β Remove EF compiled queries; deterministic instance-key check.
- vnext #724 β Disable production Swagger; harden function/mapping error logging.
Summaryβ
- Custom C# helpers ship as
.csxcomponents, referenced viascripts.helpers[]and sandboxed per-mapping withscripts.allowedAssemblies[]. - State aliases expose role-scoped, multi-language state labels (DENY overrides ALLOW) without changing internal state identity.
- Async transition modes add continuation enqueueing (outbox-capable), transition atomicity, chain-ownership tokens, and a chain reaper for stuck instances.
FunctionScopeis enforced on every invocation path; violations now return 403 instead of incidental 404s.- Fix: EF compiled queries removed (PGBouncer + multi-schema safe); duplicate-key check is deterministic (one live instance per key).
- Ops: production Swagger disabled; function/mapping failures logged at
Error; executor-log NREs eliminated. - Schema advances to 0.0.46.
vNext Runtime Platform Team
Released June 13, 2026
