Nuspec Reference
The virtufin* extension elements in the worker nupkg's .nuspec are read by Virtufin.Worker.DevKit (the VirtufinWorkerNuspec class) and by the WM's WorkerNupkgLoader. They tell the WM which file in the nupkg is the worker (DLL or .so), what C-ABI function names to resolve, and what ABI version the worker targets.
The fields
| Field | Type | Purpose |
|---|---|---|
<id> |
string | The NuGet package id (e.g. Virtufin.Worker.WebSocketManagerController). The build script reads this from the csproj's <PackageId>. |
<version> |
string | The content-addressed version (<LIBRARY_VERSION>-sha.<8hex>). The build script writes this — the csproj emits a placeholder. |
<authors> |
string | "Virtufin". |
<description> |
string | "WebSocketManagerController worker for the WorkManager" (managed) or "...(NativeAOT)" (AOT). |
<virtufinAbiVersion> |
int | The native worker ABI version. Default 1. The WM's NativeDllEngine rejects a nupkg whose value isn't in VirtufinWorkerNuspec.SupportedAbiVersions. |
<virtufinEntryPoint> |
string | The C-ABI function name for the dispatch entry point. Default "Process". The WM calls NativeLibrary.GetExport(handle, "Process") to resolve it. |
<virtufinFreeResult> |
string | The C-ABI function name for the result-free callback. Default "FreeResult". The WM calls NativeLibrary.GetExport(handle, "FreeResult") after each Process call. |
<virtufinLibrary> |
string | The basename of the worker file (no extension). For a managed nupkg, this is the worker DLL's basename (e.g. WebSocketManagerController). For an AOT nupkg, this is the basename of the .so (e.g. WebSocketManagerController — the AOT build renames WebSocketManagerController.so to libWebSocketManagerController.so at build time). |
The contract
The nupkg must have exactly one virtufinLibrary value. The PackageWorker and PackageWorkerNative MSBuild targets both emit the same virtufinLibrary value, so a --format both nupkg has a single virtufinLibrary that resolves to either the managed DLL or the AOT .so depending on which engine loads the nupkg.
The other virtufin* fields are advisory for the AOT path only (the managed engine doesn't read them — it uses reflection on IWorker to discover the worker class). For a managed-only nupkg, the virtufinEntryPoint / virtufinFreeResult / virtufinLibrary fields are still required by the schema but are not read at load time.
Defaults
The build scripts default the virtufin* fields to:
- virtufinAbiVersion = 1
- virtufinEntryPoint = Process
- virtufinFreeResult = FreeResult
- virtufinLibrary = <AssemblyName> (the csproj's assembly basename)
These match the VirtufinWorkerNuspec.Default* constants. Override them in the csproj's <NuspecProperties> if your worker exports different names (e.g. you have multiple C-ABI entry points and want to mark a custom one).
The full nuspec shape (managed)
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
<metadata>
<id>Virtufin.Worker.WebSocketManagerController</id>
<version>0.0.8-sha.bbaf1313</version>
<authors>Virtufin</authors>
<description>WebSocketManagerController worker for the WorkManager.</description>
<virtufinAbiVersion>1</virtufinAbiVersion>
<virtufinEntryPoint>Process</virtufinEntryPoint>
<virtufinFreeResult>FreeResult</virtufinFreeResult>
<virtufinLibrary>WebSocketManagerController</virtufinLibrary>
</metadata>
</package>
The full nuspec shape (AOT, combined-managed-and-AOT nupkg)
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
<metadata>
<id>Virtufin.Worker.WebSocketManagerController</id>
<version>0.0.8-sha.<8hex></version>
<authors>Virtufin</authors>
<description>Virtufin worker nupkg (managed + NativeAOT).</description>
<virtufinAbiVersion>1</virtufinAbiVersion>
<virtufinEntryPoint>Process</virtufinEntryPoint>
<virtufinFreeResult>FreeResult</virtufinFreeResult>
<virtufinLibrary>WebSocketManagerController</virtufinLibrary>
</metadata>
</package>
The <description> text varies by mode; the rest is identical.
The wire contract summary
| Surface | Owner | Where it lives |
|---|---|---|
<PackageId> (NuGet id) |
wire | config.json script_url_template + config/last_published.version |
<version> |
wire | build_version.txt (build script writes it) |
<virtufinLibrary> |
wire | csproj <AssemblyName> (managed and AOT must agree) |
<virtufinAbiVersion> |
engine | csproj <NuspecProperties> (build script default 1) |
<virtufinEntryPoint> |
engine | csproj <NuspecProperties> (build script default Process) |
<virtufinFreeResult> |
engine | csproj <NuspecProperties> (build script default FreeResult) |
The wire rows are the contract between worker author and consumer (the script that downloads + uses the nupkg). The engine rows are the contract between worker author and the WM's NativeDllEngine.
See also
- Worker Author Guide — how the AOT shim is structured to match the nuspec
- Build Script — how the build script writes the nuspec
- Packaging Modes — the nupkg structure the nuspec is part of