Conventions
Every project has rules about where things go and what things are called. Conventions are those rules written down once, in a file cix reads, so your assistant follows them instead of inferring them from whichever three files it happened to open.
Why a file, rather than a reminder
An assistant picks up house style from context. That works while the context is representative and fails quietly when it isn't — the component lands in src/ui because the last file it read lived there, the helper is called format_date in a camelCase codebase, and both are now real files with real imports.
A new file is the first place style goes wrong and the cheapest place to fix it. Moving a file that doesn't exist yet costs nothing. Moving one a week later costs every import pointing at it.
The document
conventions.json, in your repository root, committed to git. cix init writes a first version from your detected stack; the rest is yours to edit. It declares two kinds of rule:
| Rule | Says | Example |
|---|---|---|
| Folders | Where each kind of file belongs | components live in src/components |
| Naming | What each kind of file is called | components are PascalCase |
A "kind" is your word, not cix's — components, composables, models, utils, tests, whatever your project actually distinguishes. Rules apply per kind, so a project can be strict about components and silent about scripts.
See The conventions file for every key and how to write one by hand.
Three moments it shows up
| When | What happens | Where |
|---|---|---|
| Before a file is created | Your assistant checks a proposed path against the rules for that kind, and gets a corrected path back when the answer is no | Any client, on demand |
| At the moment of writing | A new file whose name breaks a naming rule is refused before it lands | Claude Code |
| Across the whole repository | An audit reports misplaced files, naming violations, and orphan symbols (Max) | Any client, on demand |
The three answer the same question at different costs: free advice, a gate, and a measure of how much drift already accumulated. Conventions in use covers each in detail.
Uncertainty never refuses
cix distinguishes five states, and only one of them can produce a refusal.
| State | Means | Effect |
|---|---|---|
| Rules available | The document is present and declares at least one rule | Can produce a verdict, including a refusal |
| No rules declared | The document exists and declares nothing | Never refuses — an empty rulebook, not a missing one |
| Not synchronized | No stored copy for this repository and branch | Never refuses |
| Invalid | A stored document that couldn't be interpreted | Never refuses, and never treated as empty |
| Unknown | Storage or identity couldn't be determined | Never refuses |
This is the difference between a check you leave on and one you disable after the third false accusation. A rule cix could not read is not evidence that your file is wrong, so it doesn't get to block your file. The four non-refusing states aren't silent either — where one is worth acting on, it's reported alongside the write that was allowed.
The empty case is worth naming on its own. {"folders": {}, "naming": {}} means this project declares no rules, and cix says exactly that instead of implying the file is missing. An empty document is also not a recorded decision to opt out — opting out is a separate setting.
Rules cix can't evaluate
Naming rules are evaluated for PascalCase, camelCase, and snake_case. Any other value you declare — a regex, a prefix scheme, a house convention with no standard name — is reported as not assessed rather than passed.
A rule that quietly returns "valid" because nothing evaluated it is worse than no rule at all, because you would stop watching that kind of file.
Heads — conventions catch the misplaced new file and the misnamed new file. They are not a policy engine and they do not review your architecture.
Next: The conventions file.