# Ownership and calls replace modules

A domain owns everything in it, and it is the boundary of what other code
can see. Declarations are private to their domain unless they are marked
`public`.

## What can be public

Entity identities, types, failures, events, queries, libraries and actions
can be public. So can a fixture, which is still callable only from tests,
fixtures and seeds: another domain's tests call a public fixture through
its domain, as `planning.alice_with_todos()`
([Shared test data: fixtures](shared-test-data-fixtures.md)).

`public` on anything else (a function, a route group, a schedule, a
subscriber, a test or a seed) is `visibility.public_not_allowed`.

`public` on a declaration nothing outside its domain uses is
`visibility.public_unused`. A use counts if it comes from another domain's
code or tests, from a root `tests/` scenario, or from the signature of a
public declaration one of those uses. The domain's own tests don't count.

**Everything reachable from a public declaration is public.** A type in a
public action's, query's, library's or event's signature, and a failure it
can raise, must itself be public or shared. This is checked on every
compile. An internal failure is mapped or handled before it leaves the
domain. A package's public surface follows the same rule
([What is public](the-package-format.md#what-is-public)).

## Changing another domain's data

A public action is a domain's way for others to change its data. Checkout
in `ordering` can call `inventory.reserve_stock(...)`, and both changes
commit or roll back together, in one database transaction. Another domain
never touches the entities directly. If a domain ever moves to a database
of its own, the compiler refuses the shared transaction rather than lose
the all-or-nothing guarantee.

Events are for reactions that don't need to be all-or-nothing, such as
sending a confirmation email. They run after the commit, so a failed email
never rolls back an order.

## Calls name their owner

The part before the dot names the owner of what you call:
`temporal.in_zone(x)`, `rounding.half_even(x)`, `Todo.get(id)`,
`inventory.reserve_stock(...)`. Your own domain's actions and queries are
called by name alone: `complete_todo(todo_id)`. An own-domain action or
query called as `planning.snooze_todo()` from inside `planning` is
`semantic.own_domain_qualification`.

Searching for `inventory.` finds the calls into that domain. It doesn't
find generated entity operations such as `Order.get`, which are named by
their entity.

A call names one owner. A library is called by its own name, never through
its domain, so `pantry.sacks.grams_in(1)` or `pantry.nonexistent.thing(x)`
is `semantic.unknown_callee`. Only a connection's operations take three
names ([Calling](calling.md)). A call that reaches nothing
is always reported, never left to fail when it runs.

There are no `module` headers. Each file names where its names come from
on `use` lines: see [Imports](imports.md).
