Support legacy fields
diff --git a/mapper/mapper.go b/mapper/mapper.go
index 0377c88..424896e 100644
--- a/mapper/mapper.go
+++ b/mapper/mapper.go
@@ -178,17 +178,36 @@
 			replacement = token.Wrap
 		}
 
-		// Apply foundry and layer overrides
-		if opts.Direction { // true means AtoB
-			applyFoundryAndLayerOverrides(pattern, opts.FoundryA, opts.LayerA)
-			applyFoundryAndLayerOverrides(replacement, opts.FoundryB, opts.LayerB)
-		} else {
-			applyFoundryAndLayerOverrides(pattern, opts.FoundryB, opts.LayerB)
-			applyFoundryAndLayerOverrides(replacement, opts.FoundryA, opts.LayerA)
+		// Create deep copies of pattern and replacement to avoid modifying the original parsed rules
+		patternBytes, err := parser.SerializeToJSON(pattern)
+		if err != nil {
+			return nil, fmt.Errorf("failed to serialize pattern for copying: %w", err)
+		}
+		patternCopy, err := parser.ParseJSON(patternBytes)
+		if err != nil {
+			return nil, fmt.Errorf("failed to parse pattern copy: %w", err)
 		}
 
-		// Create matcher and apply replacement
-		m, err := matcher.NewMatcher(ast.Pattern{Root: pattern}, ast.Replacement{Root: replacement})
+		replacementBytes, err := parser.SerializeToJSON(replacement)
+		if err != nil {
+			return nil, fmt.Errorf("failed to serialize replacement for copying: %w", err)
+		}
+		replacementCopy, err := parser.ParseJSON(replacementBytes)
+		if err != nil {
+			return nil, fmt.Errorf("failed to parse replacement copy: %w", err)
+		}
+
+		// Apply foundry and layer overrides to the copies
+		if opts.Direction { // true means AtoB
+			applyFoundryAndLayerOverrides(patternCopy, opts.FoundryA, opts.LayerA)
+			applyFoundryAndLayerOverrides(replacementCopy, opts.FoundryB, opts.LayerB)
+		} else {
+			applyFoundryAndLayerOverrides(patternCopy, opts.FoundryB, opts.LayerB)
+			applyFoundryAndLayerOverrides(replacementCopy, opts.FoundryA, opts.LayerA)
+		}
+
+		// Create matcher and apply replacement using the copies
+		m, err := matcher.NewMatcher(ast.Pattern{Root: patternCopy}, ast.Replacement{Root: replacementCopy})
 		if err != nil {
 			return nil, fmt.Errorf("failed to create matcher: %w", err)
 		}
@@ -293,8 +312,38 @@
 
 	// Restore rewrites if they existed
 	if oldRewrites != nil {
-		if resultMap, ok := resultData.(map[string]any); ok {
-			resultMap["rewrites"] = oldRewrites
+		// Process old rewrites through AST to ensure backward compatibility
+		if rewritesList, ok := oldRewrites.([]any); ok {
+			processedRewrites := make([]any, len(rewritesList))
+			for i, rewriteData := range rewritesList {
+				// Marshal and unmarshal each rewrite to apply backward compatibility
+				rewriteBytes, err := json.Marshal(rewriteData)
+				if err != nil {
+					return nil, fmt.Errorf("failed to marshal old rewrite %d: %w", i, err)
+				}
+				var rewrite ast.Rewrite
+				if err := json.Unmarshal(rewriteBytes, &rewrite); err != nil {
+					return nil, fmt.Errorf("failed to unmarshal old rewrite %d: %w", i, err)
+				}
+				// Marshal back to get the transformed version
+				transformedBytes, err := json.Marshal(&rewrite)
+				if err != nil {
+					return nil, fmt.Errorf("failed to marshal transformed rewrite %d: %w", i, err)
+				}
+				var transformedRewrite any
+				if err := json.Unmarshal(transformedBytes, &transformedRewrite); err != nil {
+					return nil, fmt.Errorf("failed to unmarshal transformed rewrite %d: %w", i, err)
+				}
+				processedRewrites[i] = transformedRewrite
+			}
+			if resultMap, ok := resultData.(map[string]any); ok {
+				resultMap["rewrites"] = processedRewrites
+			}
+		} else {
+			// If it's not a list, restore as-is
+			if resultMap, ok := resultData.(map[string]any); ok {
+				resultMap["rewrites"] = oldRewrites
+			}
 		}
 	}