Problem
The current implementation of TaskProjection.Apply (and similar projection/copy methods) assigns the Metadata dictionary of AgentTask by reference, rather than cloning it. This means that mutating Metadata in a copied/returned AgentTask will also mutate the original instance. This violates the intended isolation and snapshot semantics documented in the code and PRs, and could potentially cause subtle concurrency or correctness bugs.
Context
- See discussion in PR #381
- The PR improves immutability for Artifacts and History, but not the
Metadata property at the AgentTask level
- The contract and comments promise that the returned
AgentTask is isolated and safe for concurrent readers, which is not currently true for Metadata
Mitigation
- Currently,
Metadata is not actively mutated in projection logic, so this is not a critical bug, but represents a gap between intended design and implementation
Suggested fix
- Change TaskProjection and any similar places to clone the
Metadata dictionary for new AgentTask instances (e.g., Metadata = current.Metadata is not null ? new Dictionary<string, JsonElement>(current.Metadata) : null)
- Audit other copy/project/With* implementations for the same shallow-copy issue
Impact
- Resolves the gap between doc'd isolation and actual behavior
- Avoids potential future correctness or concurrency bugs
/cc @darrelmiller (tracking so we can safely merge PR #381)
Problem
The current implementation of
TaskProjection.Apply(and similar projection/copy methods) assigns theMetadatadictionary ofAgentTaskby reference, rather than cloning it. This means that mutatingMetadatain a copied/returnedAgentTaskwill also mutate the original instance. This violates the intended isolation and snapshot semantics documented in the code and PRs, and could potentially cause subtle concurrency or correctness bugs.Context
Metadataproperty at the AgentTask levelAgentTaskis isolated and safe for concurrent readers, which is not currently true forMetadataMitigation
Metadatais not actively mutated in projection logic, so this is not a critical bug, but represents a gap between intended design and implementationSuggested fix
Metadatadictionary for new AgentTask instances (e.g.,Metadata = current.Metadata is not null ? new Dictionary<string, JsonElement>(current.Metadata) : null)Impact
/cc @darrelmiller (tracking so we can safely merge PR #381)