Skip to main content
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.
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 itself.
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:
1

It reads the context

It looks for the files that describe the concepts in the question - definitions, table documentation, business rules.
2

It writes SQL

Based on what it found, not on guesses about your schema.
3

It runs the query and answers

Then it explains the result, showing the SQL it used.
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

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.
The structure is not fixed. It is your file system - you can add folders and organize by team, domain, or project. See Custom Context.

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 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: 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.
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.

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.
Manual - written once, never touched again. Safe to edit.
If the thing you want to fix lives in a generated file, fix it upstream instead:
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”.

Where does my contribution belong?

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.

Rules for writing context

Size

The File Explorer shows an estimated token count per file, and 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:
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.

How to contribute

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.
1

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.
2

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.
3

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.
4

Open the pull request

The first push on a branch opens a pull request. Later pushes update that same one.
Editing requires a connected context repository. 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.

From your machine

Clone the context repo, edit, and open a PR as you would for any other repository.
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).
Never commit credentials. Secrets belong in environment variables referenced from nao_config.yaml, never in a context file. See Git Repository Setup.

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

Principles

The MECE and token-cost rules behind these guidelines

Rules

The full reference for RULES.md and sub-rules files

Evaluation

Write tests that protect your contribution

Recommendations

Let nao tell you what to contribute next