Skip to content

Releases

Versioning

The Payroll Engine uses Semantic Versioning. v1.0.0 is the first stable public release. Incompatible changes to the REST API, database schema, or JSON exchange are called out as breaking changes in the release notes and normally ship in a new major version. Minor and patch releases aim to stay backward compatible—always read the notes for your upgrade.

During the earlier 0.y.z development series, breaking changes could occur in any release (SemVer initial-development semantics for major version zero). That phase is complete.


Release Artifacts

A release contains the following artifacts:

Docker Images (GitHub Container Registry)

  • ghcr.io/payroll-engine/payrollengine.backend — Backend API server
  • ghcr.io/payroll-engine/payrollengine.payrollconsole — Payroll Console
  • ghcr.io/payroll-engine/payrollengine.webapp — Web Application
  • ghcr.io/payroll-engine/payrollengine.mcp.server — MCP Server

See the Container Setup page for installation instructions.

Release Assets (download from Assets section below)

  • REST API swagger.json
  • Scripting developer reference
  • Service developer reference
➡️ Continue to GitHub Releases

v1.0.0 - Apr 2026

First stable release. Highlights:

  • Wage type cachesWageTypeCycleCache and WageTypeConsolidatedCycleCache reduce database round-trips during payrun scripts when wage types are tagged via the corresponding payroll cluster sets
  • PasswordAvailable — user API and client models indicate whether a password is set without exposing the hash
  • Exchange import — payrun jobs that end with intentional Abort/Cancel are treated as an expected test outcome during import, not a hard failure

Backend

Database update required — run the Update-Model scripts (SQL Server and MySQL) from schema 0.9.7 → 1.0.0 before starting the backend. Nine legacy Payroll ClusterSet* columns are replaced by a single ClusterSet JSON column; existing rows are migrated in the scripts. The persistence layer enforces minimum schema version 1.0.0.

Breaking changes

  • Database schema 1.0.0 — cluster-set columns consolidated (see above)
  • Exchange JSON — former top-level clusterSet* properties on Payroll move under clusterSet (PayrollClusterSets); migrate existing import/export files

Libraries

  • Client.CoreIPayroll / Payroll use a single ClusterSet property; PasswordAvailable on IUser / User; exchange import honors intentional abort status where applicable

See the full changelog in RELEASE_NOTES.md on the main repo.


v0.10.0-beta.4 - Apr 2026

Highlights

  • Payrun Job Import — new POST /payruns/jobs/import endpoint for archive restore, tenant migration, and staging seeding; transactional, duplicate-safe, with full reference validation
  • Tenant Isolation — server-wide TenantIsolationLevel policy with TenantIsolationFilter; RegulationShare.IsolationLevel for per-share access control; cross-tenant consolidation report scripting via ExecuteConsolidatedQuery
  • MCP Libraries — new Mcp.Core (infrastructure: isolation model, permission system, ToolBase) and Mcp.Tools (27 read-only tools) as standalone NuGet packages
  • OData Extensionsany() lambda operator and in operator for JSON collection column filtering; SQL Server and MySQL backend-aware
  • Install Regulation Package — new InstallRegulationPackage console command installs regulation NuGet packages directly into a PE backend tenant

Backend

Database Update required — run ModelUpdate.sql (SQL Server, schema 0.9.6 → 0.9.7) or apply the equivalent changes manually (MySQL) before starting the backend.

New Features

  • New endpoint POST /api/tenants/{tenantId}/payruns/jobs/import — imports PayrunJobSet[] (payrun job + result sets) from an archive or external system
  • Phase 1a: resolves all references (Payrun, Division, User, Employee) by stable business-key names; returns 422 on failure
  • Phase 1b: duplicate check by payrun job name; returns 409 on conflict
  • Phase 2: transactional insert with full rollback on failure
  • PayrollResult denormalized name fields: PayrollName, PayrunName, PayrunJobName, EmployeeIdentifier, DivisionName
  • TenantIsolationLevel server-wide policy — TenantIsolationFilter on every request: None (transparent), Consolidation (report scripts only), Read (GET + ReadSemantic POST cross-tenant), Write (full cross-tenant). See Security
  • RegulationShare.IsolationLevelConsolidation (cross-tenant result access for report scripts, regulation not added as payroll layer) or Write (full payroll layer, default)
  • Report.ReportIsolation — per-report access control aligned with TenantIsolationLevel
  • OData any() lambda operator — filters on JSON collection columns using correlated EXISTS sub-queries
  • OData in operator — value-set filter mapped to SQL WHERE col IN (...)
  • MySQL: IDbContext.BuildCollectionFromRaw abstracts OPENJSON / JSON_TABLE difference

Breaking Change

  • Payrun.RetroTimeType (enum) replaced by Payrun.RetroBackCycles (int): -1 = unlimited (default), 0 = current cycle only, n = n previous cycles; DB migration required (Update-Model.sql)

MCP Server

  • Division isolation: list_employees pushes division filter to the backend — eliminates client-side post-filtering

Libraries

  • Mcp.Core (new) — Core infrastructure for Payroll Engine MCP servers: isolation model, role-based permission system, ToolBase with typed service factories and isolation-aware query helpers, ToolRegistrar for startup-time tool filtering
  • Mcp.Tools (new) — 27 read-only MCP tools across HR, Payroll, Report and System roles built on Mcp.Core
  • CoreRetroTimeType enum removed breaking change
  • Client.Scripting — WageType and Collector temporal selectors (.PrevPeriod, .NextPeriod, .Cycle, .PrevCycle, .NextCycle, .RetroSum); new Calculation action group with 15 standard payroll calculation actions (AnnualProjection, CycleToPeriod, PeriodToCycle, CappedContribution, InsuranceWage, D2Delta and more); period-offset consolidation actions GetConsolidatedWageTypeValue and GetConsolidatedCollectorValue

Console

  • New InstallRegulationPackage command — installs a regulation NuGet package (.nupkg) into a PE backend tenant; supports local paths, wildcards, and HTTP(S) URLs; features version check, dependency check, dry-run mode
  • New PayrunEmployeePreviewTest command — tests payrun job preview results without persistence
  • HttpGet: optional second parameter writes response body to a file
  • HttpPost / HttpPut: Content-Type set to application/json (was text/plain → HTTP 415)
  • URL placeholder resolution: {tenant:X}, {user:X}, {division:X}, {employee:X}, {regulation:X}, {payroll:X}, {payrun:X}, {payrunJob:X} resolved to numeric IDs at runtime

Tests

  • New PayrunJobImport.Test — full export → delete → import → verify cycle for POST /payruns/jobs/import

v0.10.0-beta.3 - Mar 2026

Highlights

  • MCP Server — new PayrollEngine.McpServer repo: 29 read-only tools across 4 roles (System, HR, Regulation, Payroll) via stdio transport; compatible with Claude Desktop, GitHub Copilot, and other MCP clients
  • Backend DiagnosticsGET /api/admin/information exposes assembly, API, auth, database (incl. edition), and runtime configuration
  • MySQL Support — new Persistence.MySql provider (preview) alongside existing SQL Server
  • Report IsolationReportIsolation scoping across domain, API, and client models
  • Report Schema Builder — new ReportBuild console command generates or updates .frx skeleton documents; IDocumentService.GenerateAsync in Document library
  • Load Test Markdown ReportPayrunLoadTest now produces a Markdown report with full infrastructure section (CPU model, RAM, database edition, backend diagnostics)
  • Test Phase SeparationPayrunTestRunner import and test phases are now independent

Backend

New Features

  • GET /api/admin/information — new endpoint returning backend diagnostics: assembly version/build date, API version/name, authentication mode (with OAuth authority/audience), database type/catalog/version/edition, and runtime configuration (MaxParallelEmployees, timeouts, ScriptSafetyAnalysis, audit trail, CORS, rate limiting)
  • MySQL 8.4 LTS support via new Persistence.MySql provider (preview) — activate with PayrollServerConfiguration__DbProvider=MySql
  • IDbContext extended with GetDatabaseInformationAsync() returning DatabaseInformation including edition
  • ReportIsolation — new domain model and audit trail: report execution scoped to None, Global, Company, Division, or Employee

Breaking Change

  • MaxParallelEmployees default changed from sequential (off) to auto (ProcessorCount) — use off or -1 to restore sequential behavior

Bug Fixes

  • Fixed concurrent assembly load collision in AssemblyCache — proper lock to prevent race conditions during parallel payrun execution
  • Fixed CaseValueRepositoryBase.GetPeriodCaseValuesAsync period filter: < corrected to <= for Start boundary

MCP Server (new, preview)

  • AI agent interface for payroll data queries — read-only by design, no mutation operations
  • stdio transport via Model Context Protocol; compatible with Claude Desktop, GitHub Copilot, Cursor, and other MCP clients
  • 28 tools in 4 roles: System (tenant/user), HR (employee, case values, audit trail), Regulation (wage types, lookups), Payroll (payrun jobs and results)
  • Employee context enrichment injected into all employee-scoped results; list_payroll_result_values fully denormalized
  • get_case_time_values: Historical, Current, and Forecast temporal perspectives
  • Role-based permissions (McpRole / McpPermission) and isolation levels (MultiTenant, Tenant, Division, Employee) configurable via appsettings.json or environment variables
  • Docker image available; claude_desktop_config.json example included

Console

  • New ReportBuild command — executes a report and generates or updates the schema document (.frx skeleton) for template design
  • PayrunLoadTest Markdown report: ms/Employee and Employees/h columns in Test Summary; CPU model (Windows Registry), RAM available (GlobalMemoryStatusEx), and database edition in Test Infrastructure section
  • Fixed report template encoding: ASCII → UTF-8 for FRX, XSL and XSD streams

Web App

  • Fixed report template encoding: ASCII → UTF-8 for XSL, XSD and FRX streams
  • Fixed payrun job workflow: Draft panel displayed correctly after job start and on page reload

Libraries

  • CoreIDocumentService with GenerateAsync, MergeAsync and ExcelMergeAsync; Apply property on Query, ApplyOperation on QuerySpecification; new ReportIsolation enum
  • Client.CoreAdminService / IAdminService with GetBackendInformationAsync(); BackendInformation model hierarchy incl. Edition; IAttributeService added to IDivisionService, ITaskService, IRegulationService, IReportService; ReportIsolation on IReport/Report
  • DocumentIDocumentService.GenerateAsync: generates .frx skeleton from DataSet or rebuilds Dictionary section of existing template in CI mode
  • Client.TestPayrunTestRunner refactored into separate ImportAsync / TestAsync phases
  • Client.Scripting — fixed CasePayrollValue.FindMatchingPeriodValue: left-contains-right branch for retro payruns (Period open-ended vs. CalendarPeriod trimmed end)
  • Client.ServicesWeekPayrollCycle: migrated from removed IPayrollCalendar to CultureInfo/Calendar

Tests

  • ConsolidatedEdge.Test (new)NoRetro flag isolation in GetConsolidatedWageTypeResults: NoRetro=false returns the retro-corrected prior value; NoRetro=true returns the original main-run value
  • PayrunTag.Test (new)GetWageTypeResults tag-filter isolation: Alpha-tagged retro sub-run result queryable by tag; non-existent tag returns zero
  • MultiDivision.Test (new) — division-scoped case value isolation (valueScope: Division): same employee across two divisions, each payroll resolves its own salary independently

Examples

  • TemporalPayroll (new) — demonstrates the two independent time axes of case value resolution: periodStart (valueDate) and evaluationDate; 7 payrun jobs cover a 2×2 retro matrix and 3 forecast scenarios
  • ReportPayrollCumulativeJournal: fixed monthly result columns typed as decimal

v0.10.0-beta.1 - Mar 2026

Highlights

  • Payrun Job Preview — synchronous single-employee calculation without persisting results
  • Async Payrun Job Queue — background processing with bounded channel and webhook notification
  • Parallel Employee Processing — configurable parallelism with thread-safe state isolation
  • Persist Parallelism — configurable concurrent DB writes (MaxParallelPersist), load-tested default of 2 delivers 30% throughput gain
  • Bulk Employee Creation — high-throughput import via SqlBulkCopy
  • Excel Regulation Import — full regulation import from Excel workbooks
  • Load Testing Framework — generate, setup, execute, and benchmark payrun performance
  • CI/CD Release Pipeline — single-click wave-based release with version guard and dry-run
  • Docker & GitHub Packages — automated container builds and NuGet publishing
  • Authentication & Security — configurable auth modes, CORS, rate limiting, script safety analysis

CI/CD & Infrastructure

  • New orchestrated release pipeline with wave-based build ordering and single-click release via GitHub Actions
  • Version guard prevents accidental overwrites of existing releases, packages, and tags
  • Directory.Build.props auto-updated, committed, and tagged by the workflow
  • Dry-run mode for pipeline testing without side effects
  • GitHub Packages as primary NuGet source for all PayrollEngine.* packages
  • New nuget.config with package source mapping (PayrollEngine.* → GitHub Packages, * → NuGet.org)
  • Dedicated sync workflow for selective NuGet.org publishing
  • Automated Linux container builds for Backend, PayrollConsole, and WebApp published to ghcr.io/payroll-engine/*
  • swagger.json auto-generated from Backend via Swashbuckle CLI and attached to releases
  • New ci.yml workflow for build and test on pull requests and pushes to main
  • Updated exchange schema (PayrollEngine.Exchange.schema.json)

Backend

New Features

  • Payrun job preview endpoint (POST .../payruns/jobs/preview)
  • Synchronous single-employee payrun calculation without persisting results
  • Returns PayrollResultSet with wage type, collector, and payrun results
  • Supports any RetroPayMode; returns HTTP 422 if retro is triggered
  • Asynchronous payrun job processing with background queue
  • PayrunJobQueue with bounded channel for backpressure (capacity: 100)
  • PayrunJobWorkerService as BackgroundService for job dequeuing and processing
  • Job pre-created and persisted before enqueue, returns HTTP 202 with location header
  • Webhook notification on job completion or abort
  • Configurable parallel employee processing (MaxParallelEmployees)
  • Values: 0/off (sequential, default), half, max, -1 (automatic), 1N (explicit)
  • Per-employee PayrunEmployeeScope for mutable state isolation
  • Thread-safe progress reporting with batched DB persistence (every 10 employees)
  • Configurable persist parallelism (MaxParallelPersist, default: 2)
  • Controls concurrent DB writes per payrun job (SemaphoreSlim count)
  • Load-tested: 2 is the optimal value; 4+ shows no measurable gain
  • Failed persists retried up to 3× with backoff; no data loss possible
  • Employee processing timing logs (LogEmployeeTiming)
  • Bulk employee creation endpoint (POST .../employees/bulk) using SqlBulkCopy
  • Retro payrun period limit (MaxRetroPayrunPeriods, default: 0/unlimited)
  • CORS configuration (Cors) with AllowedOrigins, AllowedMethods, AllowedHeaders, AllowCredentials, PreflightMaxAgeSeconds
  • Rate limiting (RateLimiting) with global policy and dedicated payrun job start policy
  • Configurable authentication (Authentication) with modes: None, ApiKey, OAuth
  • OAuth with Authority, Audience, RequireHttpsMetadata, ClientSecret
  • Startup validation for OAuth authority and audience
  • Explicit Swagger toggle (EnableSwagger, default: false)
  • Per-category audit trail configuration (AuditTrail) replacing single AuditTrailDisabled bool
  • Script safety analysis (ScriptSafetyAnalysis, default: false) for banned API usage detection
  • Configurable database collation check (DbCollation, default: SQL_Latin1_General_CP1_CS_AS)
  • New PayrollServerConfiguration for centralized server settings
  • ConsolidatedPayrunResultQuery for consolidated payrun result queries
  • Updated database scripts for schema version 0.9.6

Breaking Change

  • Refactored PayrunJobInvocation from id-based to name/identifier-based references
  • Removed PayrunId and UserId properties from API and domain models
  • PayrunName and UserIdentifier are now the required fields

Bug Fixes

  • Fixed inverted slot filter logic in GetCaseValuesAsync
  • Fixed NullReferenceException in timeless case value path
  • Fixed sort lookup values by RangeValue in BuildRangeBrackets
  • Fixed calculator cache key to include culture
  • Fixed deterministic culture fallback in CalculateEmployeeAsync to en-US
  • Fixed CodeFactory.CodeFiles race condition with ConcurrentDictionary
  • Fixed thread-safe timer initialization in AssemblyCache
  • Fixed sync-over-async bridge in scripting layer
  • Added production UseExceptionHandler middleware for structured JSON error responses

Console

  • New PayrunEmployeePreviewTest command for testing payrun job preview results
  • New PayrollMerge command — merges multiple payroll files (JSON or YAML) into a single file
  • New load test commands: LoadTestGenerate, LoadTestSetup, LoadTestSetupCases, PayrunLoadTest
  • New .pecmd file type registration scripts included in the release package
  • Register-PecmdExtension.ps1 — Windows (user-level, no admin required)
  • register-pecmd.sh — Linux (MIME + desktop integration) and macOS (shell wrapper)
  • Fixed case relation validate script publisher comparing build expression instead of validate expression
  • Fixed collector custom result culture validation

Web App

  • Fixed SSL certificate validation bypass with config-controlled AllowInsecureSsl setting
  • Fixed HttpClient singleton disposal in BackendServiceBase
  • Fixed NullReferenceException in SetupUserTasks
  • Fixed TaskService injection in UserSession from [Inject] attribute to constructor injection
  • Enabled UseHsts in production pipeline

Libraries

  • Client Services — fixed inverted condition in ReportParameterParser, fixed GetContinuePeriods loop termination, fixed WeekPayrollCycle.GetPayrollPeriod week offset
  • Client Test — new PayrunEmployeePreviewTestRunner, fixed null reference and collector custom result issues
  • Client Scripting — fixed JsonElement null handling, deep copy in CaseValue, Date.Tomorrow/Yesterday as computed properties, off-by-one fixes, updated IPayrunRuntime; added RetroSum wage type accessor (^$WageType.RetroSum) and GetRetroWageTypeValueSum(number/name) scripting API
  • Client Core — new NamespaceUpdateTool, AddCasesBulkAsync, async payrun job support, fixed inverted validation and duplicate detection, HttpClient ownership pattern
  • Core — new PayrunPreviewRetroException, replaced SHA1 with SHA256, regex timeout for ReDoS prevention, stream and DataTable fixes

v0.9.0-beta17 - Feb 18, 2026

  • Backend
  • Added OAuth support, configurable in appsettings.json.
  • Assembly cache: added tenant isolation

  • Console

  • All import, export, and test commands now support for YAML.
  • New command PayrollConvert.
    • Converts payroll files between JSON and YAML.
    • Support for file masks and recursive conversions.
  • Wiki: updated examples to YAML.

  • Client Services

  • New YamlReader and YamlWriter to read and write YAML files.
  • Support for JSON schema embedding in YAML files.

v0.9.0-beta16 - Feb 11, 2026

  • Lookup Range Brackets
  • New objects lookup range result containing a list of lookup range brackets.
  • Each bracket is defined by a numeric range from RangeStart to RangeEnd including the lookup key and value.
  • The RangeValue field in each bracket contains the distributed value for progressive lookups, as well as the amount used from the matching bracket.
  • For an example check the Lookup test.

  • Scripting API

  • Payroll function: added acces to the lookup range bracktes.
  • Payroll function: added access the threshold lookup bracket using a range value.
  • Payroll function: added access to progressive lookup bracktes using a range value.

  • Backend

  • Payroll controller: new endpoint to get the payroll lookup ranges.
  • Action parser: alternative text added for the logical operators && (AND) and operator || (OR).
  • Regulation audit trail Breaking Change
    • The regulation audit trail is now disabled by default.
    • Enable the audit trail configuration in appsettings.json:
    • Script: enable or disbable auditing of scripts.
    • Lookup: enable or disbable auditing of lookups and lookup values.
    • Input: enable or disbable auditing of cases, case fields and case relations.
    • Payrun: enable or disbable auditing of collectors and wage types.
    • Report: enable or disbable auditing of reports, report templates and report parameters.

v0.9.0-beta15 - Feb 5, 2026

  • No-Code Actions
  • Actions Min, Max, Range, Contains: support for time range.
  • New action Within: test if a value is within a range.
  • New action GetTimeSpan: duration between two dates.
  • New action YearDiff: calculate years between two dates.
  • New action Age: calculate age.
  • New actions SameYear, SameMonth, SameDay: test for equal dates.
  • Action value: added timespan/year/month/day properties.
  • Action value: added methods to add and subtract year/month/day/timespan.

  • Scripting API

  • Payroll function: added properties year/month/day for cycle/period start and end date.

  • Backend

  • Improved bulk data import performance for lookups.

  • Web App

  • Regulation page action grid: use italic font style for comments.

v0.9.0-beta14 - Jan 14, 2026

  • New feature Async payrun job processing Payroll-Engine/PayrollEngine.Backend#6
    • Implement asynchronous payrun job processing using Channel and BackgroundService.
    • Return HTTP 202 Accepted immediately with Location header for status polling.
    • Prevent HTTP 524 timeout errors when processing large payrolls (500+ employees).
    • Backend Breaking Changes:
    • POST /api/tenants/{id}/payruns/jobs now returns HTTP 202 Accepted instead of HTTP 201 Created.
    • Response includes Location header for status polling.
    • Clients must poll status endpoint to determine job completion.
  • Test library: added support for async payrun jobs.
  • Web App payrun jobs page: added support for async payrun jobs.

See Release Archive for earlier releases.