I'll try to answer to my best.
As for the immutable part, I'd say you're right but when I do some changes, they are inplace.
1/ con.insert(yourtable, {"col1": ['value1'], "col2": ['value2']})
| See https://ibis-project.org/backends/duckdb#ibis.backends.duckdb.Backend.insert
2/ con.raw_sql("DELETE FROM mytable WHERE col == 'value'")
| See : https://ibis-project.org/how-to/extending/sql#backend.raw_sql
3/ I'd go for mutate
| See : https://ibis-project.org/reference/expression-tables.html#ibis.expr.types.relations.Table.mutate