contractId vs key use cases / patterns for establishing parent-child relationships

I am comparing patterns of passing/using contractId vs contract Keys when creating associations between contracts. Example

a contract representing an “organization”: the org can create a “department”: the department uses a key or a contract ID of the org? (or there could be a party per org).

Is there some “real-world” recommendations on when to use one style vs another?

Considerations i have seen:

  1. Using the contractId means replacing the parent contract means the sub-contracts are invalid
  2. Using Party for each org means ever increasing number of Parties as a “role” style use of party.
  3. You could maybe get around arching the parent contract if you follow a strict separation of Data contracts vs “action”/role/code contracts as explained in: Role Pattern usage based on examples: User Template with choices vs choices on the sub-templates? - #2 by drsk
  4. It feels like any long term contract (such as contracts representing an “organization”) would be better suited using Keys to mitigate the potential of accidental archive of the contract
  5. ContractId feels better suited for transactional short term actions that are dependent on a specific state of the parent: such as a group invites a new member to the group, the Group may only want to honour the invites for the current state of the group: if the group contract changes then new invites would need to be established.

Thanks

Off the top of my head, using the org and department example, seems like best method is to use keys.

For example, you create an org contract with the name “BadlySpelledOrgName”, then a department contract.

If the department contract references the “BadlySpelledOrgName” via contract ID, and the org updates the name, or any field, a new contarct ID is generated (since we are essentially archiving this org contract, and creating a new org contract with the updated fields) and now, this department contract is referencing a non existent contract ID.

As long as there is some relationship between two contracts, I’d suggest to never use Contract ID as a reference key.

What about using the contract itself as a reference key? Like this:

template A
  with
    p : Party
  where
    signatory p
    nonconsuming choice CreateB : ContractId B
      controller p
      do 
        create B with
           a = this
        
template B
  with
    a : A
  where
    signatory (signatory a)

Or would it be better to modify A to have a key and then B would reference A’s key?

What does that look like when it gets serialized?