* 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
4 KiB
Implementation Plan: Workflow JSON Type Hardening
Branch: codex/7541-workflow-json-hardening | Date: 2026-05-29 | Spec: spec.md
Input: Feature specification from /specs/010-workflow-json-hardening/spec.md
Note: This template is filled in by the /speckit-plan command. See .specify/templates/plan-template.md for the execution workflow.
Summary
Reintroduce workflow JSON hardening through a workflow-specific type registry and resolver. Existing registered legacy CLR names remain readable, new workflow JSON emits aliases when available, and public descriptor APIs use the same identifier contract they accept.
Technical Context
Language/Version: C# latest with nullable reference types, multi-targeting through existing project settings
Primary Dependencies: System.Text.Json, Elsa feature/module infrastructure, existing expression registry for expression-only behavior
Storage: Existing workflow JSON payloads only; no schema changes
Testing: Targeted dotnet test for workflow core/runtime/api test projects
Target Platform: Elsa server/library consumers on supported .NET target frameworks
Project Type: Modular .NET library and API modules
Performance Goals: Type lookup remains dictionary-based and does not add reflection scans to normal serialization
Constraints: No arbitrary CLR type loading; compatibility only for explicitly registered workflow JSON legacy names
Scale/Scope: Workflow definitions, workflow state, trigger/bookmark payloads, incident strategy descriptor contract, and module/extension registrations
Constitution Check
GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.
PASS. The change stays inside existing workflow modules, adds one explicit extensibility point for serialization trust, preserves public compatibility, and includes focused tests. No new persistence provider or unrelated module is introduced.
Project Structure
Documentation (this feature)
specs/[###-feature]/
├── plan.md # This file (/speckit-plan command output)
├── research.md # Phase 0 output (/speckit-plan command)
├── data-model.md # Phase 1 output (/speckit-plan command)
├── quickstart.md # Phase 1 output (/speckit-plan command)
├── contracts/ # Phase 1 output (/speckit-plan command)
└── tasks.md # Phase 2 output (/speckit-tasks command - NOT created by /speckit-plan)
Source Code (repository root)
src/modules/Elsa.Workflows.Core/
├── Contracts/
├── Extensions/
├── Options/
├── Serialization/
└── Features/
src/modules/Elsa.Workflows.Runtime/
├── Features/
├── ShellFeatures/
└── Services/
src/modules/Elsa.Workflows.Api/
└── Endpoints/IncidentStrategies/
test/unit/Elsa.Workflows.Core.UnitTests/
test/unit/Elsa.Workflows.Runtime.UnitTests/
test/integration/Elsa.Workflows.IntegrationTests/
Structure Decision: Extend the existing workflow core serialization surface and update runtime/API registrations in place. Tests stay in the nearest existing workflow test projects.
Complexity Tracking
Fill ONLY if Constitution Check has violations that must be justified
| Violation | Why Needed | Simpler Alternative Rejected Because |
|---|---|---|
| [e.g., 4th project] | [current need] | [why 3 projects insufficient] |
| [e.g., Repository pattern] | [specific problem] | [why direct DB access insufficient] |