# Exposed Surface Nothing is exposed by accident. ## Opt-In Rules - A model only becomes queryable once it opts in via `toolConfig()` and `allowRead()`. - Relations are only available when you configure them explicitly, and only with a description: ```php ->relations([ 'author' => 'The author who wrote the article.', ]) ``` A relation method existing on the model is not enough by itself. It has to be listed here to be exposed at all. There is no way to add a relation without a description either. The description is the text the AI is shown for that relation in `with` and `withAggregate`, so an undescribed relation is simply invisible rather than present but unexplained. ## Columns The current runtime column set comes from the model schema snapshot, not from the field-description map alone. - database columns are discovered from the table at runtime - `visible` and `hidden` decide which columns stay exposed - casts refine the detected data types - enum columns contribute known enum values for validation hints Field descriptions still matter, but today they are descriptive metadata, not the hard allowlist. ## Relation Rules - Nested eager-loading paths are derived from the frozen configs of related models. - Nested relation paths are limited by `relationPathMaxDepth`. - Root model scopes are always applied to the main query. - Related model scopes are applied when a configured relation is eager-loaded. - Direct relation aggregates also respect the related model's configured scopes. - Relation aggregates are supported for direct configured relations only. - Dotted relation-path columns are supported only for relation kinds that can be translated into auto-derived join paths. ## Supported Query Shape Today - `explain` - `expressions` - `select` - `distinct` - `where` - `groupBy` - `orderBy` - `limit` - `offset` - `with` - `withAggregate`