# Schema v4

Generate flat YAML only. `schema_version: 4`, `brain.name`, and each `note_types.<name>.directory` are required.

- `note_types` may add `description`, `role`, `optional_fields`, `required_fields`, `typeclasses`, `identity_fields`, and `grounding_rules`. A grounding rule uses `evidence`; use `declaration` for a note that never auto-stales. Do not emit retired `grounding`.
- `edge_types` may constrain `source_types` and `target_types` to declared note types, with `cardinality` (`one-to-one`, `one-to-many`, `many-to-one`, or `many-to-many`), `acyclic`, `excludes`, `lifecycle`, and `identity_policy`.
- An extension has `type`, `values` for enums, and `applies_to` declared note types. Add it only when the field is useful.
- A query has exactly one body: `steps`, `let` plus `in`, or `native`. `text_search` needs exactly one of `query_arg` and `query`; `select` needs a declared `type`.

### Representative YAML

```yaml
schema_version: 4
brain:
  name: example-project
  description: Repository knowledge
note_types:
  module:
    directory: modules
    description: Source components
    grounding_rules:
      - evidence: source-hash
  gap:
    directory: gaps
    description: Work to resolve
    grounding_rules:
      - evidence: declaration
edge_types:
  contains:
    description: Module owns a gap
    source_types: [module]
    target_types: [gap]
    cardinality: one-to-many
    acyclic: true
extensions:
  status:
    type: enum
    values: [open, done]
    applies_to: [gap]
query_paths:
  search:
    description: Full-text search over notes
    args:
      - name: q
        type: string
    steps:
      - text_search:
          query_arg: q
          limit: 30
  open-gaps:
    description: Work that remains
    args: []
    steps:
      - select:
          type: gap
          where:
            status:
              ne: done
```
