Once a Companion Specification is released, there are rules what is allowed, and what is not allowed to create a new version with extended functionality as described in section 3. The next sections provide recommendations how to add functionality to a new version of the same namespace, and section 11.3 finally gives recommendations on how to create a new namespace for a breaking change.
InstanceDeclarations can be added optionally on each place without the need to create subtypes. This does not only include InstanceDeclaration on an TypeDefinition directly, but also on an InstanceDeclaration of the TypeDefinition (without the need to change the type of the owning InstanceDeclaration). If InstanceDeclarations need to be added mandatory, either a subtype needs to be created with the mandatory InstanceDeclaration, or the InstanceDeclaration is only added optional and a new Conformance Unit requires the InstanceDeclaration to be present.
If not only a single InstanceDeclaration, but a grouped set that belongs together, should be added to potentially several TypeDefinitions, an Interface or AddIn should be defined first and used in all places (see OPC 10000-3).
As stated in 3.2.4 this is not allowed for Enumeration DataType. Ideally, an approach as described in 7.12 had been used allowing the extension. If not, the only option is to deprecate the old Enumeration (and all its usage in Variables, Method Signatures, Structured DataTypes etc.) and define a new Enumeration (or preferable an extensible approach). This is very cumbersome, specifically if the DataType has been used directly or indirectly in various places.
It is not allowed to add new fields to a Structured DataType. However, a subtype can be created having additional fields. It depends on the usage of the DataType, whether the subtype can be used. If it is used in another structured DataType not stating, that subtypes are allowed, this does not work (see 7.9). For Variables, it can be specified if subtypes of the DataType are allowed. If not, this can also not be used. For Method arguments, the meta data may define whether subtypes are allowed, but the Method cannot be changed requiring the subtype. Therefore, in those cases ideally the structure would already have an integrated extension mechanism (see 7.9).
If this is not the case, a new subtype needs to be created and all its usages replaces, which might be very cumbersome, specifically if the DataType has been used directly or indirectly in various places.
For OptionSets based on numeric DataTypes it is not allowed to add new Bits (see 3.2.7). Therefore, either a new DataType is created having the old and new bits (with all the implications), or a new DataType is created just having the additional bits and the usage of that new OptionSet is added, wherever the old one is used.
For OptionSets based on the OptionSet DataType, it is also not allowed to add new Bits (see 3.2.8). However, subtypes can be created supporting additional Bits, as long as the overall length is not changed. As alternative, the same approach as for numeric OptionSets apply.
When the old model has some base functionality missing or mandatory functionality wrongly defined, it might be required to deprecated some old TypeDefinition and define new once instead. Although this could be considered as a breaking change (see 11.3), it may also be solved in the existing Namespace by deprecating the old TypeDefinitions and define new ones. If one TypeDefinition is replaced with exactly one new one, it is recommended to use the same name with a version number (e.g. 2) at the end. This approach requires, that also all usages of the old TypeDefinition are replaced with the new one, which in turn might require new versions of other TypeDefinitions as well.
In case it is required or desirable to create a new version independent of the old model of a Companion Specification, for example because something fundamental was done wrong or with bad modelling practices that is hindering the application of the specification, a new NamespaceUri has to be used. In this case, it is recommended to use the old NamespaceUri and extend it with “V<VersionNumber>/”, like “V2/” for version 2. It should only contain the major version number, as only major version number changes should indicate a breaking change. In case a new Namespace is created, also new ConformanceUnits and Profiles have to be created, as the old ones reference to the old Namespace.