hecks

Identity is a value concept and relationships state their cardinality

Status: Accepted — implementation in progress.

Context

ADR 0025 made two simplifications that do not read like the domain language we want Bluebooks to preserve. It made identified_by point at a field, even when the domain already has a named value concept for that identity, and it removed has_many, has_one, and belongs_to because their old implementations were only aliases for a scalar reference.

The first simplification hides an SME concept at the declaration site. The second removes useful domain vocabulary because one implementation of that vocabulary was dishonest. In particular, the former has_many did not hold a collection at all.

Decision

This ADR supersedes the Identity and References sections of ADR 0025. Its other decisions remain in force.

Identity has three live declaration forms:

identified_by AccountNumber, as: :number

identified_by do
  attribute :scheme, PaymentScheme
  attribute :end_to_end_id, EndToEndIdentifier
end

identified_by :branch_code, :box_number

Relationships are structural aggregate/entity state with literal cardinality:

Relationship declarations do not create inverses, do not imply aggregate lifecycle, and do not decide whether a command inserts or updates. A command’s receiver is routing information, while cross-aggregate facts in command input are identity values rather than retained relationships.

Compatibility and sequencing

The language adds and proves the new forms before removing the old live form. The self-hosted language, examples, and fixtures are migrated through one resolved exemplar per section. Only after the live inventory is clean does the language lifecycle mark one-symbol identity retired and make it shadow-only.

Historical relationship words remain readable with their historical scalar shape under the era/shadow grammar. A current has_many always means a real list; language/era version distinguishes those semantics.

The executable sequence, focused verification gates, and corpus migration are specified in docs/value-object-identity-and-relationships-plan.md.

Consequences