> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getnao.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Contributor Guide

> How anyone on your team can add or fix context in your organization's nao context repository

This guide is for people who use the nao agent every day and want to make it smarter: analytics engineers, analysts, data leads, and the business users who know what a metric really means.

<Note>
  This is about **your organization's context repository** - the repo holding `nao_config.yaml`, `RULES.md`, and your synced schemas. It is not about contributing to the [nao open-source project](https://github.com/getnao/nao) itself.
</Note>

You do not need to be a nao admin, and you do not need to understand how nao is deployed. If you can write Markdown and open a pull request, you can improve the agent.

## How nao works

The agent knows nothing about your business on its own. Everything it understands - what a customer is, which table holds revenue, why last July looks strange - comes from your **context**: a set of Markdown and YAML files describing your data and your rules.

When someone asks a question, the agent goes through roughly the same motions an analyst would:

<Steps>
  <Step title="It reads the context">
    It looks for the files that describe the concepts in the question - definitions, table documentation, business rules.
  </Step>

  <Step title="It writes SQL">
    Based on what it found, not on guesses about your schema.
  </Step>

  <Step title="It runs the query and answers">
    Then it explains the result, showing the SQL it used.
  </Step>
</Steps>

That first step is where your contribution lands. **The quality of the answers is the quality of the context** - a wrong answer is almost always a missing or ambiguous file, not a broken model.

The important part for you: the context is a plain file system. Nothing is hidden in a database or in a black box, which is exactly what makes it contributable by the people who know the business.

## How a nao context is structured

```text theme={null}
your-context/
├── nao_config.yaml
├── RULES.md
├── semantics/
├── docs/
├── databases/
├── repos/
├── agent/
└── tests/
```

| Path              | Type                          | What it holds                                                                                                            |
| ----------------- | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `nao_config.yaml` | Manual                        | Database connections, LLM models, and sync settings. Usually maintained by an admin.                                     |
| `RULES.md`        | Manual                        | The agent's core instructions, plus its map of where everything else lives. Read on every message.                       |
| `semantics/`      | Manual                        | Domain knowledge: metric definitions, funnel stages, business terminology.                                               |
| `docs/`           | Manual, except `docs/notion/` | Free-form documentation. Pages synced from Notion land in `docs/notion/`.                                                |
| `databases/`      | Auto, except `annotations.md` | One folder per table with its schema, sample rows, and statistics. Your own notes on a table go in its `annotations.md`. |
| `repos/`          | Auto                          | Copies of your dbt, BI, or ETL repositories, refreshed from the source repo.                                             |
| `agent/`          | Manual                        | Skills, system prompt overrides, MCP servers, and custom tools.                                                          |
| `tests/`          | Manual                        | Question and expected-SQL pairs used by `nao test`.                                                                      |

**Manual** files are written by you and your teammates. **Auto** files are produced by `nao sync`, which pulls them from your warehouse and your repositories - and rewrites them on every run. More on what that means for your edits [below](#generated-vs-manual-files).

<Tip>
  The structure is not fixed. It is your file system - you can add folders and organize by team, domain, or project. See [Custom Context](/nao-agent/context-builder/custom-context).
</Tip>

## How the agent finds context

Writing a good file is only half the job. If the agent never opens it, it may as well not exist.

### What the agent always sees

On every single message, before it does anything:

* **The system prompt** - nao's built-in prompt, plus any override in `agent/prompts/`, plus the [SQL dialect rules](/nao-agent/context-builder/system-prompts#warehouse-dialect-rules) for your warehouses, injected automatically.
* **`RULES.md`** - in full, every time.

That is it. Everything else in the repository is invisible until the agent decides to go looking.

### What the agent has to go find

To reach anything else, the agent uses its file tools:

| Tool     | What it does                      | What makes your file findable                                             |
| -------- | --------------------------------- | ------------------------------------------------------------------------- |
| `list`   | Lists files and directories       | A predictable path and an obvious folder                                  |
| `search` | Finds files by glob pattern       | A descriptive **file name** (`marketing_attribution.md`, not `notes2.md`) |
| `grep`   | Regex search across file contents | The **words your users actually type** appearing in the text              |
| `read`   | Reads one file                    | A pointer telling it this file is worth opening                           |

So a contribution is discoverable when at least one of these is true:

1. **`RULES.md` points at it.** This is the reliable one. The `## Context map` section exists to route the agent: "CRM funnel statuses -> `docs/crm.md`, read before any sales question."
2. **Its name says what it holds.** `semantics/finance.md` gets found by a glob search for a finance question. `misc.md` does not.
3. **It contains the vocabulary of the question.** If your team says "churn" but your file only ever says "attrition", `grep` will miss it. Write both.
4. **It sits where the agent is already looking.** A note filed next to `table=orders/` gets read when the agent inspects that table, with no pointer needed.

<Warning>
  A perfect file in `docs/`, referenced by nothing and named nothing memorable, is dead weight: it costs review time and gets read only by accident. **Adding a new file usually means also adding one line to `RULES.md`.**
</Warning>

## Generated vs manual files

Some of your context is written by hand. The rest is produced by `nao sync`, which connects to your warehouse and your repositories and regenerates files from them.

This is the single most common way a contribution gets lost: an edit to a generated file disappears on the next sync.

You never have to guess which is which. Every file written by `nao sync` carries a frontmatter header declaring who owns it.

**Generated** - overwritten on the next sync. Your edit will disappear.

```yaml theme={null}
---
type: generated
comment: This file is managed and generated by the agent, do not modify it!
---
```

**Manual** - written once, never touched again. Safe to edit.

```yaml theme={null}
---
type: manual
comment: These are manual notes you want the agent to keep in mind, safe to edit.
---
```

If the thing you want to fix lives in a generated file, fix it **upstream** instead:

| You want to change            | Don't edit                | Do this instead                                                                |
| ----------------------------- | ------------------------- | ------------------------------------------------------------------------------ |
| A column description          | `databases/**/columns.md` | Fix the description in the warehouse or in your dbt `schema.yml`, then re-sync |
| A caveat about one table      | `databases/**/columns.md` | Write it in that table's `annotations.md`                                      |
| Anything in a synced dbt repo | `repos/dbt/...`           | Open a PR on the dbt repo itself; nao pulls it on the next sync                |
| A Notion page                 | `docs/notion/...`         | Edit the page in Notion                                                        |
| Which tables are in scope     | `databases/`              | Change `include` / `exclude` in `nao_config.yaml` (ask an admin)               |

<Tip>
  `annotations.md` exists in every table folder for exactly this reason. It is created empty and never overwritten, so it is the right home for "this table double-counts refunds, join to `fct_refunds` to net them out".
</Tip>

## Where does my contribution belong?

| What you want to add                                                              | Where it goes                                                                                        |
| --------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
| A rule that applies to *every* answer (tone, SQL style, row limits, PII handling) | `RULES.md`, broad rules section                                                                      |
| A pointer to where some context lives                                             | `RULES.md`, `## Context map`                                                                         |
| The canonical definition of a metric                                              | Your semantic layer if you have one, otherwise `semantics/<domain>.md` - **once, in one place only** |
| Domain knowledge (funnel stages, lifecycle definitions, campaign types)           | `semantics/<domain>.md`                                                                              |
| A quirk, trap, or caveat about one specific table                                 | that table's `annotations.md`                                                                        |
| A column description                                                              | Upstream: the warehouse or dbt `schema.yml`                                                          |
| A repeatable multi-step analysis the agent should always run the same way         | A [skill](/nao-agent/context-engineering/skills) in `agent/skills/`                                  |
| A one-off explanation of a data incident ("July numbers are low, tracking broke") | `docs/`, dated, with a pointer from `RULES.md`                                                       |
| A question the agent must get right forever                                       | A test in `tests/`                                                                                   |

<Tip>
  When in doubt between `RULES.md` and a sub-file: `RULES.md` costs tokens on every message ever sent. A sub-file costs tokens only when it is read. Put it in a sub-file and point to it.
</Tip>

## Rules for writing context

### Size

| Rule                                                     | Why                                                                                                   |
| -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
| **Hard limit: keep every file under 32,000 characters**  | That is the `read` tool's cap. Past it, the tail of your file is silently never seen.                 |
| **Practical target: one screen to a few pages per file** | Cheap to read, easy to review, easy for the agent to keep straight.                                   |
| **Split by domain, not by size**                         | `semantics/marketing.md` + `semantics/finance.md` beats one `semantics.md` cut in half.               |
| **Keep `RULES.md` lean**                                 | It is billed on every message. It should be an index and a set of broad rules, never an encyclopedia. |

The File Explorer shows an estimated token count per file, and [Recommendations](/nao-agent/context-engineering/recommendations) flags files that are `truncated_on_read`, `frequent_and_expensive`, or `rare_but_outlier`. If your file is flagged, split it.

### Content

* **Open with a scope line.** One sentence saying what the file covers and when to read it, in the words a user would use. It is what tells the agent whether this is the file it needs.
* **One canonical definition per concept.** Two definitions of "active customer" in two files is worse than none - the agent will pick one at random and be inconsistent. If it is already defined somewhere, link to it instead of restating it.
* **Never duplicate what `nao sync` generates.** Column lists and row counts are already in `databases/`. Restating them means they go stale the day the schema changes.
* **Be explicit, not elegant.** Name the exact table, the exact column, the exact filter. `WHERE status = 'won'` beats "filter on won opportunities".
* **Show the SQL.** A formula the agent can copy is worth three paragraphs describing it.
* **Write the failure modes.** "Do not use `raw_orders`, it includes test orders; use `fct_orders`" prevents a whole class of wrong answers.
* **Use your users' words.** Include synonyms and internal jargon so `grep` finds the file.
* **Date and timezone conventions matter.** Week start, fiscal calendar, timezone of `created_at`. These cause silent, plausible-looking errors.
* **No secrets, no PII, no credentials.** Context files are read by the agent and visible to reviewers.

## When to contribute

Contribute whenever you catch the agent being wrong, vague, or slow in a way you know how to fix:

| What you noticed                                                          | What that usually means                                                    |
| ------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| The agent used the wrong table for a metric you own                       | No canonical definition, or two conflicting ones                           |
| It gave a number that "looks right but isn't"                             | A join, filter, or deduplication caveat isn't written down anywhere        |
| It asked a clarifying question everybody on your team knows the answer to | A convention (fiscal year, week start, default currency) is missing        |
| It answered inconsistently to the same question asked twice               | The same concept is defined in two places                                  |
| It took several exploratory queries to get there                          | The agent had to discover by querying what your context could have told it |

<Tip>
  Before you write anything, check **Settings -> Recommendations**. nao audits its own production usage and may already have found and drafted the exact fix you were about to write. See [Recommendations](/nao-agent/context-engineering/recommendations).
</Tip>

## How to contribute

|              | From the browser                                  | From your machine                                              |
| ------------ | ------------------------------------------------- | -------------------------------------------------------------- |
| **Who**      | Admins and Context Admins                         | Anyone with access to the context repo                         |
| **Where**    | **Settings -> File Explorer** in nao              | Your own editor, on a git clone                                |
| **Good for** | A quick wording fix, adding a rule, an annotation | Larger edits, running `nao sync` or `nao test`, editing config |
| **Output**   | A commit on a branch, then a pull request         | A commit on a branch, then a pull request                      |

Both paths end the same way: a pull request that someone reviews. Context is a shared source of truth, so it goes through review like code.

### From the browser

Open **Settings -> File Explorer**. Search covers file contents as well as names, so you can find the file by the term the agent got wrong.

<Steps>
  <Step title="Find the file">
    Markdown opens as a rendered page. Click **Source** to edit with a live preview. Each file shows an estimated token count, so you can see what it costs the agent before you make it longer.
  </Step>

  <Step title="Edit and save">
    `Cmd+S` saves to **your own private copy** of the repository. Neither the live agent nor your teammates see the change yet.
  </Step>

  <Step title="Commit">
    Saved edits collect in the **Git** panel under the file tree. Pick what to commit. Commits are authored as you, with nao as co-author. Committing from the main branch creates a branch automatically.
  </Step>

  <Step title="Open the pull request">
    The first push on a branch opens a pull request. Later pushes update that same one.
  </Step>
</Steps>

Editing requires a [connected context repository](/nao-agent/chat/admin/git). Without one, every file is read-only. If a specific file refuses to be edited, nao tells you why - see [Why a file is read-only](/nao-agent/chat/admin/file-explorer#why-a-file-is-read-only).

### From your machine

Clone the context repo, edit, and open a PR as you would for any other repository.

```bash theme={null}
git clone https://github.com/your-org/your-nao-context.git
cd your-nao-context
git checkout -b add-marketing-semantics
```

You do not need database credentials to edit Markdown. You only need them if you want to run `nao sync` (to regenerate schema files) or `nao test` (to check your change against the test suite).

<Warning>
  Never commit credentials. Secrets belong in environment variables referenced from `nao_config.yaml`, never in a context file. See [Git Repository Setup](/nao-agent/context-builder/git-repository).
</Warning>

### What reviewers look for

If you review context pull requests, check these:

* Does this contradict a definition that already exists elsewhere?
* Is it in the right file, or was `RULES.md` used as a dumping ground?
* Will it survive the next `nao sync`?
* Is it findable - named well, pointed to, using the vocabulary of real questions?
* Is it explicit enough that two different people would read it the same way?
* Does it carry a test?

## Next steps

<CardGroup cols={2}>
  <Card title="Principles" icon="lightbulb" href="/nao-agent/context-engineering/principles">
    The MECE and token-cost rules behind these guidelines
  </Card>

  <Card title="Rules" icon="list-check" href="/nao-agent/context-builder/rules-context">
    The full reference for RULES.md and sub-rules files
  </Card>

  <Card title="Evaluation" icon="flask" href="/nao-agent/context-engineering/evaluation">
    Write tests that protect your contribution
  </Card>

  <Card title="Recommendations" icon="wand-magic-sparkles" href="/nao-agent/context-engineering/recommendations">
    Let nao tell you what to contribute next
  </Card>
</CardGroup>
