Strategy Reference¶
Every XRDConversionConfig rule picks one of these built-in strategies. Each is designed with bidirectional semantics — hub→spoke and spoke→hub — and the engine determines losslessness for each direction independently. Any direction the engine can't prove round-trips exactly requires acknowledgeLossy: true on the rule, or the whole config is rejected.
The default posture is fail-closed: any hub or spoke field left unclaimed by a rule, and not structurally identical on both sides, is a validation error — never a silent drop. See XRDConversionConfig for the full rule-authoring model.
All strategies at a glance¶
| Strategy | What it does | Typically lossless? |
|---|---|---|
fieldRename |
Renames a field, preserving its value and shape exactly. | Always |
scalarToObject |
Hub scalar ⇄ spoke object wrapping it under a key. | Usually |
objectToScalar |
Hub object ⇄ spoke scalar extracted from a key. | Usually |
singletonArrayToObject |
Hub single-element array ⇄ spoke object. | Conditional |
objectToSingletonArray |
Hub object ⇄ spoke single-element array. | Conditional |
fieldsToMap |
Several hub sibling fields ⇄ one spoke map. | Conditional |
mapToFields |
Hub map ⇄ several spoke sibling fields. | Conditional |
toAnnotation |
Stashes a hub field's value into a spoke annotation. | Conditional (restoreOnReverse) |
toLabel |
Stashes a hub field's value into a spoke label. | Conditional (restoreOnReverse) |
fromAnnotation |
Restores a spoke field from a hub annotation (inverse of toAnnotation). |
Conditional (stashOnReverse) |
fromLabel |
Restores a spoke field from a hub label (inverse of toLabel). |
Conditional (stashOnReverse) |
enumRemap |
Bidirectionally maps a scalar field's enumerated values. | Conditional |
defaultValue |
Injects a default for a field that only exists on one side. | One direction always lossy |
constant |
Forces a field to a fixed value on the side it exists on. | One direction always lossy |
delete |
Intentionally drops a field that exists on only one side. | Always requires acknowledgement |
jsonPatch |
Escape hatch: raw RFC 6902 JSON Patch per direction. | Lossy unless losslessOverride |
forEach |
Applies a nested rule list to each element of an array. | Depends on nested rules |
typeCoerce |
Converts a scalar's JSON type (string/int/number/bool). | Conditional (onFractionalInteger; integers beyond 2⁵³) |
scalarToFields |
Decomposes one scalar into several fields via regex + template. | Lossy unless losslessOverride |
fieldsToScalar |
Joins several fields into one scalar via template + regex. | Lossy unless losslessOverride |
arrayToMapByKey |
Array of objects ⇄ map keyed by one of their fields. | Array→map yes, map→array no |
mapToArrayByKey |
Map ⇄ array of objects keyed by one of their fields. | Map→array no, array→map yes |
numericScale |
Rescales a numeric field by a fixed factor. | Conditional (integer side) |
listJoin |
Array of scalars ⇄ delimited string. | Always |
listSplit |
Delimited string ⇄ array of scalars. | Always |
quantity |
Kubernetes Quantity string ⇄ integer millivalue. | Integer→canonical string is lossy; string→milli is exact at milli resolution |
duration |
Go duration string ⇄ integer seconds. | Integer→canonical string is lossy; sub-second strings error |
mapKeyRename |
Rename known keys in a free-form map; other keys pass through. | Always (injective renames) |
cel |
Arbitrary CEL expressions over declared paths. | Always lossy (requires acknowledgeLossy; no losslessOverride) |
Reading the examples¶
Every strategy page follows the same shape:
- What it does and when to use it.
- Lossy/lossless semantics, called out explicitly per direction.
- An XRD schema snippet showing the field on the hub version and the corresponding field on a spoke version.
- The
XRDConversionConfigrule that maps between them. - Example objects at both versions, so you can see the exact before/after shape.
All examples are self-contained and runnable through convctl test — see Getting Started and the CLI Reference. For complete configs combining several strategies against a whole schema, see Examples; for a single fixture exercising every strategy in this reference at once — with a rule-by-rule index of where each one lives — see Kitchen sink.