Common patterns (or anti-) for Data vs Contracts?

I think it would not qualify as an example. I can say that based on Split: [ContractId Iou]. The existence of that seems to imply that Iou is being used purely as an almost prototypical data container. Moreover, it explicitly enables various workflows where the Pool does not have signatures to create the Ious, as those signatures can be gathered later, and need only be present when Splitting.

I go over a similar example here, where it is clear that it would be wrong for the contract to exist, even though all its data is present and packed into a payload. The presence of Pool in PoolInvite is very much like this.

I think this is why we don’t have the antipatterns page anymore. To be sure, there are right ways and wrong ways to do things in Daml, but when too much domain-specific judgement is required, documenting a bright-line rule can be…an antipattern.

As such, the rule here is really “use contracts for contracts, and use data for data”. For what it’s worth, the previously linked post has several examples where using an associated record type from a template is the right choice, and using a contract ID would be wrong. But I determined these examples based on how they were being used.