This is definitely a bug because according to documentation,
When you add a component in markup, you can initialize public property
values in the component based on property values of the owner
component. The data binding for property values is one-way. If the
property value changes in the owner component, the updated value
propagates to the child component.
The child component must treat property values passed from the owner
component as read-only. If the child component tries to change a value
passed from an owner component, you see an error in the browser
To trigger a mutation for the property value provided by the owner
component, the child component can send an event to the parent. If the
parent owns the data, the parent can change the property value, which
propagates down to the child component via the one-way data binding.
Also in the same documentation, you will find example of
todoapp and child comp
todoitem, in which its clearly written that
Nothing happens in the UI! You see an error in the browser console
saying that you can’t change the value of itemName. You can’t change
itemName in c-todoitem because you can only set the value of a public
property (@api) at component construction time.
So, whether the properties are complex or primitive data-types, @api public properties in child should not be allowed to be modified after the construction time when they are passed from parent component.