# Database Schema Core Constraints

This file contains semantic rules that complement two machine contracts:

- `schema.json` defines valid schema-instance structure.
- `registry.schema.json` defines the project registry structure.

When a machine contract and this file differ, the machine contract controls structural validity. Report validation failures; do not silently repair user input.

## Fidelity has highest priority

Preserve every user-declared name, type, default, required flag, readonly flag, enum value, index, structure, label, and description. Do not normalize, translate, rename, add, remove, or "improve" these values without an explicit request.

When a declaration has a precision, timezone, index, naming, portability, or driver risk:

1. state the risk and available alternatives outside the artifact;
2. keep the requested representation unchanged;
3. continue the requested task unless the user must make an irreversible decision.

A warning never authorizes a scope change or an edit to generated artifacts.

## Location and registry

- The consuming project owns `docs/schemas/SCHEMA-REGISTRY.json`; use it as the first lookup for canonical schema locations.
- Without a record or an explicit shared location, use `docs/schemas/<table_name>.jsonc` and create or update the project registry.
- A current explicit user choice or an existing registry record may select shared storage. Do not infer that a schema should be shared.
- Keep a project registry entry even when the canonical document is external.
- If a registered file is missing, report the broken path and preserve the record. Do not create a hidden replacement.

Schema instances are JSONC and may use comments. Their `$schema` path must resolve to the distributed `schema.json`. Import paths are relative and must follow the machine contract.

## Contract semantics

- `required: true` means required and non-null.
- `required: false` means nullable. Generated strong types must represent null explicitly.
- A type is either a standard type string or a non-empty explicit mapping object. Never merge the two forms for one field.
- Explicit language or database mappings are authoritative for that target.
- `table_name` is the complete physical or logical name. A dot is part of the name, not a namespace separator. Quote the entire identifier when native SQL would otherwise interpret the dot, but do not rename it.

Read [type-mapping.md](type-mapping.md) only when mapping types, nullability, precision, dates, enums, or driver-specific values. Read [indexes-and-risks.md](indexes-and-risks.md) only for index work. Read [multi-source-layout.md](multi-source-layout.md) only for registry version 2, shared storage, or multiple systems.

## Bidirectional synchronization

- Code to schema: changes to persistent fields, names, constraints, defaults, readonly behavior, enums, indexes, or mappings must be reflected in the canonical schema.
- Schema to code: changes to those schema declarations must be reflected in all affected migrations, models, DTOs, entities, and persistence validation.
- Review: report mismatches and their impact. Do not choose a resolution that changes user intent without authorization.

Generated code must retain provenance near the contract:

```text
// @schema-ref: <schema_path>#<table>@<field>
```

Use the target language's comment syntax. Keep the actual project-relative source path.
