elsa-core/specs/010-workflow-json-hardening/tasks.md
Sipke Schoorstra c2fb027c41
Refactor: Overhauls workflow JSON type serialization (#7549)
* Avoid null endpoint DTO metadata in tests

* Enforce console logs hub read permission

* Remove unused console logs hub import

* Support mapped endpoint metadata in auth tests

* Reduce console log capture throughput impact

* Address Copilot console logs review

* Refactor task scheduling to support tenant-level background work and enhance logging functionality.

* Introduce ConsoleStreamHook for stdout/stderr tee and enhance logging validation. Adjust test cases and startup warnings for distributed lock provider usage.

* Refactor console logging pipeline with capture optimization and new ConsoleLogsHost; update tests accordingly.

* Add Ansi SGR parser for console logs and associated unit tests

* Remove ANSI color renderings and parsers; integrate ConsoleLogScopeAccessor for improved logging context with workflow instance ID support.

* Address console logs code quality feedback

* Address PR review feedback

* Preserve console logs extension points

* Stabilize console logs host lifecycle

* Address final automated review comments

* Tighten console log capture shutdown

* Address console log review feedback

* Address follow-up review feedback

* Cover final review feedback

* Avoid recursive console provider initialization

* Guard console host lease shutdown

* Preserve console log scope and provider lifetime

* Correlate console log scope fallback

* Tighten console scope correlation

* Expose host services during provider construction

* Redact ANSI-normalized console lines

* Remove `ConsoleCaptureTee` and related services and tests

* Use pipeline contributors for console log context

* Update CShells package versions to 0.0.24-preview.132

* Filter live console logs by workflow instance

* Enhance console logging with activity execution metadata and extend test coverage.

* Address console logs stream consumption comment

* Add diagnostics OpenTelemetry backend

* Introduce dedicated workflow JSON type registry and hardening

This change addresses GitHub issue #7541 by establishing a separate type registry (`IWorkflowJsonTypeRegistry`) for workflow JSON serialization. This decouples workflow type resolution from expression type aliases, enforcing a strict trust boundary.

Key aspects:
- New workflow JSON emits preferred aliases for registered types.
- Existing persisted workflows can be loaded via registered legacy names.
- Unknown, abstract, interface, open generic, or inappropriate collection types are rejected during deserialization, enhancing security.
- Public APIs (e.g., incident strategies) now expose consistent workflow JSON type identifiers.

This ensures secure, predictable, and backward-compatible handling of types within workflow definitions and payloads.

* Remove unused project references and streamline console log endpoint

* Move serialization type aliases to Elsa.Common

* Update serialization integration fixtures for aliases

* Stabilize missing rate limiter policy test
2026-05-31 11:09:39 +02:00

8 KiB

Tasks: Workflow JSON Type Hardening

Input: Design documents from /specs/010-workflow-json-hardening/ Prerequisites: plan.md, spec.md, research.md, data-model.md, contracts/

Tests: Required by the feature specification for compatibility, rejection behavior, incident strategies, runtime payloads, JSON islands, and custom workflow types.

Phase 1: Setup (Shared Infrastructure)

Purpose: Confirm the clean worktree and documentation context.

  • T001 Verify the dedicated worktree status in /Users/sipke/Projects/Elsa/elsa-core-7541
  • T002 Update Spec Kit agent context in /Users/sipke/Projects/Elsa/elsa-core-7541/AGENTS.md

Phase 2: Foundational (Blocking Prerequisites)

Purpose: Add the dedicated workflow JSON trust boundary before changing user-facing behavior.

  • T003 Add serialization type registry contracts in src/modules/Elsa.Common/Serialization/ISerializationTypeRegistry.cs
  • T004 Add serialization type options in src/modules/Elsa.Common/Serialization/SerializationTypeOptions.cs
  • T005 Add serialization type registry implementation in src/modules/Elsa.Common/Serialization/SerializationTypeRegistry.cs
  • T006 Add workflow JSON registration extensions in src/modules/Elsa.Common/Extensions/SerializationTypeOptionsExtensions.cs
  • T007 Update workflow JSON resolver to use the dedicated registry in src/modules/Elsa.Common/Serialization/SerializationTypeResolver.cs
  • T008 Update workflow type converters to use the dedicated registry in src/modules/Elsa.Workflows.Core/Serialization/Converters/TypeJsonConverter.cs, src/modules/Elsa.Workflows.Core/Serialization/Converters/PolymorphicObjectConverter.cs, src/modules/Elsa.Workflows.Core/Serialization/Converters/PolymorphicObjectConverterFactory.cs, and src/modules/Elsa.Workflows.Core/Serialization/Converters/PolymorphicDictionaryConverter.cs

Checkpoint: Workflow JSON converters no longer depend on ExpressionOptions.


Phase 3: User Story 1 - Load Existing Workflows Safely (Priority: P1) MVP

Goal: Existing registered CLR type names remain readable while unsafe names fail.

Independent Test: Deserialize legacy workflow JSON/type payloads with registered names and verify unsafe identifiers are rejected.

Tests for User Story 1

  • T009 [US1] Update resolver tests for dedicated registry compatibility in test/unit/Elsa.Workflows.Core.UnitTests/Serialization/Converters/SerializationTypeResolverTests.cs
  • T010 [US1] Add regression coverage for expression-only aliases not being accepted by workflow JSON in test/unit/Elsa.Workflows.Core.UnitTests/Serialization/Converters/SerializationTypeResolverTests.cs

Implementation for User Story 1

  • T011 [US1] Register core workflow JSON aliases and legacy names in src/modules/Elsa.Workflows.Core/Features/WorkflowsFeature.cs and src/modules/Elsa.Workflows.Core/ShellFeatures/WorkflowsFeature.cs
  • T012 [US1] Update workflow serializers and hashing to consume ISerializationTypeRegistry in src/modules/Elsa.Workflows.Core/Serialization/Serializers/JsonWorkflowStateSerializer.cs, src/modules/Elsa.Workflows.Core/Serialization/Serializers/SafeSerializer.cs, src/modules/Elsa.Workflows.Core/Serialization/Serializers/BookmarkPayloadSerializer.cs, and src/modules/Elsa.Workflows.Core/Services/Hasher.cs

Checkpoint: User Story 1 can be validated independently.


Phase 4: User Story 2 - Use Consistent Type Identifiers in APIs (Priority: P2)

Goal: Incident strategy descriptors emit the same workflow type identifiers that workflow JSON accepts.

Independent Test: Descriptor output for incident strategies returns aliases and supported legacy identifiers remain readable.

Tests for User Story 2

  • T013 [US2] Add incident strategy descriptor regression tests in test/unit/Elsa.Workflows.Api.UnitTests/Endpoints/IncidentStrategies/ListTests.cs

Implementation for User Story 2

  • T014 [US2] Register incident strategy aliases and legacy names in src/modules/Elsa.Workflows.Core/Features/WorkflowsFeature.cs and src/modules/Elsa.Workflows.Core/ShellFeatures/WorkflowsFeature.cs
  • T015 [US2] Emit workflow JSON aliases from incident strategy descriptors in src/modules/Elsa.Workflows.Api/Endpoints/IncidentStrategies/List/Endpoint.cs
  • T016 [US2] Update client model documentation for identifier semantics in src/clients/Elsa.Api.Client/Resources/IncidentStrategies/Models/IncidentStrategyDescriptor.cs

Checkpoint: User Story 2 can be validated independently.


Phase 5: User Story 3 - Register Workflow-Serializable Types Explicitly (Priority: P3)

Goal: Modules and host applications register workflow JSON types without using expression options.

Independent Test: Runtime and extension payloads resolve from workflow JSON registrations while expression-only aliases do not.

Tests for User Story 3

  • T017 [US3] Update runtime feature tests for workflow JSON registrations in test/unit/Elsa.Workflows.Runtime.UnitTests/Features/WorkflowRuntimeFeatureTests.cs
  • T018 [US3] Update runtime trigger comparer tests for the dedicated registry in test/unit/Elsa.Workflows.Runtime.UnitTests/Comparers/WorkflowTriggerEqualityComparerTests.cs

Implementation for User Story 3

  • T019 [US3] Move runtime workflow payload registration to workflow JSON options in src/modules/Elsa.Workflows.Runtime/WorkflowRuntimeTypeAliasRegistrar.cs, src/modules/Elsa.Workflows.Runtime/Features/WorkflowRuntimeFeature.cs, and src/modules/Elsa.Workflows.Runtime/ShellFeatures/WorkflowRuntimeFeature.cs
  • T020 [US3] Move module payload registrations to workflow JSON options in src/modules/Elsa.Http/Features/HttpFeature.cs, src/modules/Elsa.Http/ShellFeatures/HttpFeature.cs, src/modules/Elsa.Scheduling/Features/SchedulingFeature.cs, src/modules/Elsa.Resilience/Features/ResilienceFeature.cs, src/modules/Elsa.Resilience/ShellFeatures/ResilienceFeature.cs, src/modules/Elsa.Alterations/Features/AlterationsFeature.cs, src/modules/Elsa.Persistence.EFCore/Modules/Management/WorkflowDefinitionPersistenceFeature.cs, and src/modules/Elsa.Workflows.Management/Features/WorkflowManagementFeature.cs
  • T021 [US3] Update runtime trigger comparison to use ISerializationTypeRegistry in src/modules/Elsa.Workflows.Runtime/Comparers/WorkflowTriggerEqualityComparer.cs and src/modules/Elsa.Workflows.Runtime/Services/TriggerIndexer.cs

Checkpoint: User Story 3 can be validated independently.


Phase 6: Polish & Cross-Cutting Concerns

Purpose: Documentation and validation.

  • T022 Add workflow JSON hardening documentation in doc/wiki/workflow-core.md
  • T023 Run targeted workflow core unit tests with dotnet test test/unit/Elsa.Workflows.Core.UnitTests/Elsa.Workflows.Core.UnitTests.csproj --filter SerializationTypeResolverTests
  • T024 Run targeted workflow runtime unit tests with dotnet test test/unit/Elsa.Workflows.Runtime.UnitTests/Elsa.Workflows.Runtime.UnitTests.csproj --filter WorkflowRuntimeFeatureTests
  • T025 Review changed files and ensure .specify/feature.json and Spec Kit artifacts are correct

Dependencies & Execution Order

  • Setup: T001-T002 first.
  • Foundational: T003-T008 block all user stories.
  • US1: T009-T012 produces the MVP compatibility slice.
  • US2: T013-T016 depends on the registry from Foundational and may run after US1.
  • US3: T017-T021 depends on the registry from Foundational and may run after US1.
  • Polish: T022-T025 after implementation.

Parallel Opportunities

  • Test updates in T009, T013, T017, and T018 can be developed in parallel after T003-T008.
  • Module registration moves in T020 can be parallelized by module after the extension API exists.
  • Documentation T022 can run after the contract behavior is finalized.

Implementation Strategy

  1. Establish the dedicated registry and switch converters.
  2. Preserve legacy compatibility for existing workflow JSON.
  3. Align incident strategy API descriptors with the registry.
  4. Move runtime/module payload registrations off expression options.
  5. Validate with targeted tests and documentation.