Support arbitrary koral nodes in AST
diff --git a/pkg/parser/parser_test.go b/pkg/parser/parser_test.go
index 464c497..d2964ce 100644
--- a/pkg/parser/parser_test.go
+++ b/pkg/parser/parser_test.go
@@ -183,12 +183,16 @@
 			wantErr: true,
 		},
 		{
-			name: "Invalid node type",
+			name: "Unknown node type",
 			input: `{
 				"@type": "koral:unknown",
 				"key": "value"
 			}`,
-			wantErr: true,
+			expected: &ast.CatchallNode{
+				NodeType:   "koral:unknown",
+				RawContent: json.RawMessage(`{"@type":"koral:unknown","key":"value"}`),
+			},
+			wantErr: false,
 		},
 	}
 
@@ -273,6 +277,21 @@
 }`,
 			wantErr: false,
 		},
+		{
+			name: "Serialize unknown node type",
+			input: &ast.CatchallNode{
+				NodeType: "koral:unknown",
+				RawContent: json.RawMessage(`{
+  "@type": "koral:unknown",
+  "key": "value"
+}`),
+			},
+			expected: `{
+  "@type": "koral:unknown",
+  "key": "value"
+}`,
+			wantErr: false,
+		},
 	}
 
 	for _, tt := range tests {
@@ -338,3 +357,53 @@
 	require.NoError(t, err)
 	assert.Equal(t, expected, actual)
 }
+
+func TestRoundTripUnknownType(t *testing.T) {
+	// Test that parsing and then serializing an unknown node type preserves the structure
+	input := `{
+		"@type": "koral:unknown",
+		"key": "value",
+		"wrap": {
+			"@type": "koral:term",
+			"foundry": "opennlp",
+			"key": "DET",
+			"layer": "p",
+			"match": "match:eq"
+		},
+		"operands": [
+			{
+				"@type": "koral:term",
+				"foundry": "opennlp",
+				"key": "AdjType",
+				"layer": "m",
+				"match": "match:eq",
+				"value": "Pdt"
+			}
+		]
+	}`
+
+	// Parse JSON to AST
+	node, err := ParseJSON([]byte(input))
+	require.NoError(t, err)
+
+	// Check that it's a CatchallNode
+	catchall, ok := node.(*ast.CatchallNode)
+	require.True(t, ok)
+	assert.Equal(t, "koral:unknown", catchall.NodeType)
+
+	// Check that wrap and operands were parsed
+	require.NotNil(t, catchall.Wrap)
+	require.Len(t, catchall.Operands, 1)
+
+	// Serialize AST back to JSON
+	output, err := SerializeToJSON(node)
+	require.NoError(t, err)
+
+	// Compare JSON objects
+	var expected, actual interface{}
+	err = json.Unmarshal([]byte(input), &expected)
+	require.NoError(t, err)
+	err = json.Unmarshal(output, &actual)
+	require.NoError(t, err)
+	assert.Equal(t, expected, actual)
+}