This is an automated email from the ASF dual-hosted git repository.

chaokunyang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fory-site.git

commit 751c40a47d6a47eced47b3c0b8c7dab10e7a9dad
Author: chaokunyang <[email protected]>
AuthorDate: Fri Jun 5 06:01:28 2026 +0000

    πŸ”„ synced local 'docs/guide/' with remote 'docs/guide/'
---
 docs/guide/cpp/schema-evolution.md        | 12 +++++++++++-
 docs/guide/csharp/schema-evolution.md     |  9 +++++++++
 docs/guide/dart/schema-evolution.md       | 16 +++++++++++++++-
 docs/guide/go/schema-evolution.md         | 31 +++++++++++++++++++++++++++++--
 docs/guide/java/schema-evolution.md       |  9 +++++++++
 docs/guide/javascript/schema-evolution.md |  9 +++++++++
 docs/guide/kotlin/type-serialization.md   |  9 +++++++++
 docs/guide/python/schema-evolution.md     | 15 +++++++++++++++
 docs/guide/rust/schema-evolution.md       | 13 ++++++++++++-
 docs/guide/scala/type-serialization.md    |  9 +++++++++
 docs/guide/swift/schema-evolution.md      | 17 ++++++++++++++++-
 docs/guide/xlang/field-nullability.md     |  6 ++++--
 12 files changed, 147 insertions(+), 8 deletions(-)

diff --git a/docs/guide/cpp/schema-evolution.md 
b/docs/guide/cpp/schema-evolution.md
index 9844a26dec..f266a0a250 100644
--- a/docs/guide/cpp/schema-evolution.md
+++ b/docs/guide/cpp/schema-evolution.md
@@ -98,9 +98,19 @@ Compatible mode supports the following schema changes:
 | Remove fields      | Supported     | Extra fields are skipped                
|
 | Reorder fields     | Supported     | Fields matched by name, not position    
|
 | Change nullability | Supported     | `T` ↔ `std::optional<T>`                
|
-| Change field types | Not supported | Types must be compatible                
|
+| Change field types | Selected      | Scalar changes must be lossless         
|
 | Rename fields      | Not supported | Field names must match (case-sensitive) 
|
 
+Compatible readers can handle selected scalar field type changes when the 
value is lossless. A
+matched field can read between `bool`, `std::string`, numeric scalars, and 
decimal fields when the
+converted value has the same logical value. Boolean strings must be exactly 
`"0"`, `"1"`, `"true"`,
+or `"false"`. Numeric strings must use finite ASCII decimal notation without 
whitespace, a leading
+`+`, Unicode digits, separators, or non-finite values such as `NaN` and 
`Infinity`. Numbers and
+decimals can be read as canonical strings, and numeric widening or narrowing 
succeeds only when no
+precision or range is lost. Nullable and optional field wrappers still compose 
with these conversions,
+but reference-tracked scalar type changes are incompatible. Invalid strings 
and lossy conversions fail
+during deserialization.
+
 ## Adding Fields (Backward Compatibility)
 
 When deserializing old data with a new schema that has additional fields:
diff --git a/docs/guide/csharp/schema-evolution.md 
b/docs/guide/csharp/schema-evolution.md
index 108634b773..c0a6566531 100644
--- a/docs/guide/csharp/schema-evolution.md
+++ b/docs/guide/csharp/schema-evolution.md
@@ -31,6 +31,15 @@ Fory fory = Fory.Builder()
 
 Compatible mode writes type metadata that allows readers and writers with 
different struct definitions to interoperate.
 
+Compatible readers also tolerate selected scalar field type changes when the 
value is lossless. A
+matched field can read between `bool`, `string`, numeric scalars, and 
`decimal` when the converted
+value has the same logical value. Boolean strings must be exactly `"0"`, 
`"1"`, `"true"`, or
+`"false"`. Numeric strings use finite ASCII decimal syntax without whitespace, 
a leading plus sign,
+Unicode digits, underscores, hexadecimal notation, `NaN`, or infinities. 
Numbers and decimals read as
+strings use canonical plain decimal text. Nullable fields still compose with 
these conversions, but
+reference-tracked scalar type changes are incompatible. Invalid strings, 
out-of-range values, and lossy
+numeric conversions fail during deserialization.
+
 ## Example: Add a Field
 
 ```csharp
diff --git a/docs/guide/dart/schema-evolution.md 
b/docs/guide/dart/schema-evolution.md
index 51777b8372..2e8fe46556 100644
--- a/docs/guide/dart/schema-evolution.md
+++ b/docs/guide/dart/schema-evolution.md
@@ -34,6 +34,17 @@ final fory = Fory();
 
 In compatible mode, Fory includes enough field metadata in each message so 
that the reader can skip unknown fields and use defaults for missing ones. Use 
stable field IDs (see below) to anchor the schema across changes.
 
+Compatible readers also tolerate selected scalar field type changes when the 
value is lossless. A
+matched field can read between `bool`, `String`, numeric scalars, and 
`Decimal` when the converted
+value has the same logical value. For example, `"true"` and `"false"` can be 
read as booleans,
+`"123"` can be read as a numeric field that can hold `123`, numbers and 
decimals can be read as
+canonical strings, and numeric widening or narrowing succeeds only when no 
precision or range is
+lost. Scalar conversion applies only to matched compatible fields, not root 
values or collection
+elements. String-to-number conversion accepts finite ASCII decimal literals 
without whitespace, a
+leading `+`, Unicode digits, underscores, `NaN`, or `Infinity`. Nullable 
fields still compose with
+these conversions, but reference-tracked scalar type changes are incompatible. 
Invalid strings,
+out-of-range values, and lossy conversions fail with `InvalidDataException` 
during deserialization.
+
 ### Schema-Consistent Mode
 
 Both sides must have the same model. Fory validates that the schemas match and 
will reject messages from a different schema version. Use this when all 
services are always updated together and you want schema mismatches to be 
caught as fast errors.
@@ -68,11 +79,14 @@ If you add field IDs after payloads are already in 
production, existing stored m
 - Add a new optional field with a new, unused field ID.
 - Rename a field β€” as long as the `@ForyField(id: ...)` stays the same.
 - Remove a field β€” the peer will just ignore the missing value and use the 
Dart default.
+- Change selected scalar field types when all deployed values convert without 
precision or range
+  loss.
 
 **Unsafe changes** (may break existing messages):
 
 - Reuse an existing field ID for a different field.
-- Change a field's type to an incompatible type (e.g., `@ForyField(type: 
Int32Type()) int` β†’ `String`).
+- Change a field's type to an incompatible type or to a scalar type that 
cannot represent the peer
+  values exactly.
 - Change the registration identity (`id` or `name`) of a type after messages 
are in production.
 - Change a field's logical meaning without changing its ID.
 
diff --git a/docs/guide/go/schema-evolution.md 
b/docs/guide/go/schema-evolution.md
index 2c5e04d2f0..509fd7c042 100644
--- a/docs/guide/go/schema-evolution.md
+++ b/docs/guide/go/schema-evolution.md
@@ -159,6 +159,33 @@ type PersonV2 struct {
 
 Compatible mode handles this automatically by matching fields by name.
 
+### Compatible Scalar Field Changes
+
+Compatible mode can also read selected scalar type changes for matched 
top-level
+struct fields when the serialized value converts without changing its logical
+value:
+
+- `bool` fields can be read from strings that are exactly `"0"`, `"1"`,
+  `"true"`, or `"false"`. Bool values read as strings become `"true"` or
+  `"false"`, and numeric `0` and `1` can be read as bools.
+- Integer, unsigned integer, floating point, and decimal fields can be read
+  across numeric scalar types only when the value is represented exactly by the
+  target field type.
+- Numeric fields can be read from strings only when the string is a finite 
ASCII
+  decimal literal with no whitespace, leading `+`, Unicode digits, separators,
+  radix prefixes, or special values such as `NaN` and `Infinity`.
+- Numeric fields read as strings use canonical output: integers have normal
+  decimal text, floating point values use exact plain decimal text with a
+  decimal point, and decimals omit insignificant trailing fractional zeros.
+
+Scalar conversion composes with pointer and `optional.Optional[T]` fields when
+the matched top-level scalar field is not reference-tracked. If a remote
+nullable or optional field is absent, the local field follows the normal
+missing/null compatible-mode behavior. Reference-tracked scalar type changes 
are
+incompatible. If a present value cannot be converted losslessly,
+deserialization fails with a data error instead of treating the field as
+missing.
+
 ## Incompatible Changes
 
 Some changes are NOT supported, even in compatible mode:
@@ -168,11 +195,11 @@ Some changes are NOT supported, even in compatible mode:
 ```go
 // NOT SUPPORTED
 type V1 struct {
-    Value int32  // int32
+    Value []int32  // list of int32
 }
 
 type V2 struct {
-    Value string  // Changed to string - INCOMPATIBLE
+    Value []string  // Element type changed - INCOMPATIBLE
 }
 ```
 
diff --git a/docs/guide/java/schema-evolution.md 
b/docs/guide/java/schema-evolution.md
index 21270cc1a3..5666e2f4a1 100644
--- a/docs/guide/java/schema-evolution.md
+++ b/docs/guide/java/schema-evolution.md
@@ -40,6 +40,15 @@ option unless they previously overrode the schema mode.
 
 In this compatible mode, deserialization can handle schema changes such as 
missing or extra fields, allowing it to succeed even when the serialization and 
deserialization processes have different class schemas.
 
+Compatible readers also tolerate selected scalar field type changes when the 
value is lossless. A
+matched field can read between `boolean`, `String`, numeric scalars, and 
`BigDecimal` when the value
+has the same logical value after conversion. For example, `"true"` and 
`"false"` can be read as
+booleans, `"123"` can be read as a numeric field that can hold `123`, numbers 
and decimals can be
+read as canonical strings, and numeric widening or narrowing succeeds only 
when no precision or range
+is lost. Numeric strings use finite ASCII decimal syntax. Nullable and boxed 
fields still compose with
+these conversions, but reference-tracked scalar type changes are incompatible. 
Invalid strings and
+lossy conversions fail during deserialization.
+
 ```java
 Fory fory = Fory.builder().withXlang(false)
   .withCompatible(true)
diff --git a/docs/guide/javascript/schema-evolution.md 
b/docs/guide/javascript/schema-evolution.md
index 4f9e0eac6a..95d39f32cd 100644
--- a/docs/guide/javascript/schema-evolution.md
+++ b/docs/guide/javascript/schema-evolution.md
@@ -26,6 +26,15 @@ Schema evolution lets different versions of your service 
exchange messages safel
 - **Compatible mode** (default): writes extra field metadata so readers can 
skip unknown fields and tolerate missing ones. Good for independent 
deployments, rolling upgrades, and xlang services.
 - **Schema-consistent mode**: more compact, but both sides must have exactly 
the same schema. Use it only when schemas do not change, or when all services 
update together.
 
+Compatible readers also tolerate selected scalar field type changes when the 
conversion is lossless.
+A matched field can read between `boolean`, `string`, numeric scalars, and 
`Decimal` when the
+converted value has the same logical value. For example, `"true"`, `"false"`, 
`"1"`, and `"0"` can
+be read as booleans, exact finite ASCII numeric strings can be read as numeric 
fields that can hold
+them, numbers and decimals can be read as canonical strings, and numeric 
widening or narrowing
+succeeds only when no precision or range is lost. Invalid strings and lossy 
conversions fail during
+deserialization. Nullable fields still compose with these conversions, but 
reference-tracked scalar
+type changes are incompatible.
+
 ## Default Compatible Mode
 
 ```ts
diff --git a/docs/guide/kotlin/type-serialization.md 
b/docs/guide/kotlin/type-serialization.md
index 1acb10db94..6bc3bbcb23 100644
--- a/docs/guide/kotlin/type-serialization.md
+++ b/docs/guide/kotlin/type-serialization.md
@@ -23,6 +23,15 @@ This page covers serialization of Kotlin-specific JVM types 
in native mode. For
 cross-language Kotlin models, use the xlang path described in
 [Static Generated Serializers](static-generated-serializers.md).
 
+When compatible mode is enabled, Kotlin readers use the JVM compatible-read 
rules for selected
+scalar field type changes. A matched field can read between `Boolean`, 
`String`, numeric scalars,
+and `java.math.BigDecimal` when the converted value has the same logical 
value. For example,
+`"true"` and `"false"` can be read as booleans, `"123"` can be read as a 
numeric field that can hold
+`123`, numbers and decimals can be read as canonical strings, and numeric 
widening or narrowing
+succeeds only when no precision or range is lost. Numeric strings use finite 
ASCII decimal syntax.
+Invalid strings and lossy conversions fail during deserialization. Nullable 
and boxed fields still
+compose with these conversions, but reference-tracked scalar type changes are 
incompatible.
+
 ## Setup
 
 All examples assume the following setup:
diff --git a/docs/guide/python/schema-evolution.md 
b/docs/guide/python/schema-evolution.md
index 182d54c90f..402978bb7e 100644
--- a/docs/guide/python/schema-evolution.md
+++ b/docs/guide/python/schema-evolution.md
@@ -23,6 +23,21 @@ Apache Foryβ„’ supports schema evolution in compatible mode, 
allowing fields to
 while maintaining compatibility. Xlang mode enables compatible mode by 
default. In native mode,
 set `compatible=True` explicitly when Python-only payloads need schema 
evolution.
 
+Compatible readers also tolerate selected scalar field type changes when the 
value is lossless. A
+matched field can read between `bool`, `str`, numeric scalars, and `Decimal` 
when the converted value
+has the same logical value. For example, `"true"`, `"false"`, `"0"`, and `"1"` 
can be read as
+booleans; `"123"` can be read as a numeric field that can hold `123`; numbers 
and decimals can be
+read as canonical strings; and numeric widening or narrowing succeeds only 
when no precision or range
+is lost.
+
+Scalar conversion is only applied to matched compatible fields, not to root 
values or collection
+elements. String-to-number conversion accepts finite ASCII decimal literals 
without whitespace, a
+leading `+`, Unicode digits, underscores, or special values such as `NaN` and 
`Infinity`. Invalid
+strings, out-of-range values, and lossy conversions fail with 
`pyfory.error.ForyInvalidDataError`
+during deserialization.
+Optional and nullable fields still compose with these conversions, but 
reference-tracked scalar type
+changes are incompatible.
+
 ## Xlang Default
 
 ```python
diff --git a/docs/guide/rust/schema-evolution.md 
b/docs/guide/rust/schema-evolution.md
index 14c536afc4..f3e3bb3d7c 100644
--- a/docs/guide/rust/schema-evolution.md
+++ b/docs/guide/rust/schema-evolution.md
@@ -89,12 +89,23 @@ struct StableMessage {
 - Remove obsolete fields (skipped during deserialization)
 - Change field nullability (`T` ↔ `Option<T>`)
 - Reorder fields (matched by name, not position)
+- Change selected scalar field types when the value converts without precision 
or range loss
 - Type-safe fallback to default values for missing fields
 
+Compatible readers can handle selected scalar field type changes when the 
value is lossless. A
+matched field can read between `bool`, `String`, numeric scalars, and decimal 
fields when the
+converted value has the same logical value. For example, `"true"` and 
`"false"` can be read as
+booleans, `"123"` can be read as a numeric field that can hold `123`, numbers 
and decimals can be
+read as canonical strings, and numeric widening or narrowing succeeds only 
when no precision or range
+is lost. Numeric strings use finite ASCII decimal syntax. Optional fields 
still compose with these
+conversions, but reference-tracked scalar type changes are incompatible. 
Invalid strings and lossy
+conversions fail during deserialization.
+
 ## Compatibility Rules
 
 - Field names must match (case-sensitive)
-- Type changes are not supported (except nullable/non-nullable)
+- Type changes are supported only for nullable/non-nullable changes and 
selected lossless scalar
+  conversions
 - Nested struct types must be registered on both sides
 
 ## Enum Support
diff --git a/docs/guide/scala/type-serialization.md 
b/docs/guide/scala/type-serialization.md
index 00a8574a84..44856c584a 100644
--- a/docs/guide/scala/type-serialization.md
+++ b/docs/guide/scala/type-serialization.md
@@ -23,6 +23,15 @@ This page covers serialization of Scala-specific JVM types 
in native mode. For
 cross-language Scala models, use the xlang path described in
 [Schema IDL And Xlang](schema-idl.md).
 
+When compatible mode is enabled, Scala readers use the JVM compatible-read 
rules for selected
+scalar field type changes. A matched field can read between `Boolean`, 
`String`, numeric scalars,
+and `java.math.BigDecimal` when the converted value has the same logical 
value. For example,
+`"true"` and `"false"` can be read as booleans, `"123"` can be read as a 
numeric field that can hold
+`123`, numbers and decimals can be read as canonical strings, and numeric 
widening or narrowing
+succeeds only when no precision or range is lost. Numeric strings use finite 
ASCII decimal syntax.
+Invalid strings and lossy conversions fail during deserialization. Optional 
and boxed fields still
+compose with these conversions, but reference-tracked scalar type changes are 
incompatible.
+
 ## Setup
 
 All examples assume the following setup:
diff --git a/docs/guide/swift/schema-evolution.md 
b/docs/guide/swift/schema-evolution.md
index f7fe019136..a585076674 100644
--- a/docs/guide/swift/schema-evolution.md
+++ b/docs/guide/swift/schema-evolution.md
@@ -21,6 +21,18 @@ license: |
 
 Fory supports schema evolution through compatible mode, which is enabled by 
default in Swift.
 
+Compatible readers also tolerate selected scalar field type changes when the 
value is lossless. A
+matched field can read between `Bool`, `String`, numeric scalars, and 
`Decimal` when the converted
+value has the same logical value. For example, `"true"` and `"false"` can be 
read as booleans,
+`"123"` can be read as a numeric field that can hold `123`, numbers and 
decimals can be read as
+canonical strings, and numeric widening or narrowing succeeds only when no 
precision or range is
+lost. Numeric strings use finite ASCII decimal syntax. Invalid strings and 
lossy conversions fail
+during deserialization.
+
+Scalar conversion also composes with optional fields. A present optional value 
is converted by the
+same rules, while a missing optional value keeps Swift's normal 
compatible-mode default for the
+local field. Reference-tracked scalar type changes are incompatible.
+
 ## Default Compatible Mode
 
 ```swift
@@ -66,10 +78,13 @@ assert(v2.phone == nil)
 - Add new fields
 - Remove old fields
 - Reorder fields
+- Change a matched scalar field between `Bool`, `String`, numeric scalars, or 
`Decimal` when every
+  value you write is lossless for the reader
 
 ## What Is Not Safe
 
-- Arbitrary type changes for an existing field (for example `Int32` to 
`String`)
+- Arbitrary type changes for an existing field, including scalar values that 
are out of range,
+  rounded, non-finite, or not accepted by the compatible numeric string grammar
 - Inconsistent registration mapping across peers
 
 ## Schema-consistent Mode Behavior
diff --git a/docs/guide/xlang/field-nullability.md 
b/docs/guide/xlang/field-nullability.md
index b10c06dc3e..7113c629a3 100644
--- a/docs/guide/xlang/field-nullability.md
+++ b/docs/guide/xlang/field-nullability.md
@@ -242,14 +242,16 @@ When a non-nullable field receives a null value:
 
 ## Schema Compatibility
 
-The nullable flag is part of the struct schema fingerprint. Changing a field's 
nullability is a **breaking change** that will cause schema version mismatch 
errors.
+The nullable flag is part of the struct schema fingerprint. In 
schema-consistent reads, changing a field's nullability is a **breaking 
change** that will cause schema version mismatch errors.
 
 ```
 Schema A: { name: String (non-nullable) }
 Schema B: { name: String (nullable) }
-// These have different fingerprints and are incompatible
+// These have different fingerprints for schema-consistent reads
 ```
 
+In compatible mode, top-level scalar fields can still be matched when their 
scalar type is otherwise compatible and the nullability or optional wrapper 
differs. Present values are read through compatible scalar conversion and must 
satisfy the normal lossless conversion checks. Remote null values follow the 
compatible-read null/default behavior for the local field.
+
 ## Best Practices
 
 1. **Use non-nullable by default**: Only make fields nullable when null is a 
valid semantic value


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to