# AI Policy

Source: https://docs.gryt.chat/docs/about/ai

How AI is and isn't used in Gryt's development

## The short version

Gryt is built by one person, so some AI assistance is the difference between shipping and not shipping. It also means there's nobody else to catch my mistakes, so the rule has to be about what gets reviewed rather than about what gets typed.

The rule:

- **AI may be used anywhere in Gryt**, including the code that matters most.
- **Code that can affect your security never merges without me reading it line by line.** Those areas can't be committed directly — they go through a pull request, and I review the whole diff before it lands.
- **Everything else** — docs, the site, interface code, tooling — is reviewed like any normal change.

Nothing security-relevant reaches you unread. That's the actual promise.

## Review-required areas

Changes here always go through a pull request, and I read every line before merging. No direct pushes, no exceptions for small changes.

| Area | Path | Why |
|------|------|-----|
| SFU / media plane | `packages/sfu` | WebRTC, RTP forwarding, ICE, SVC layer selection. Everything else depends on it. |
| Server auth & crypto | `packages/server/src/auth`, `src/middleware` | Challenge-response authentication, JWT validation, token handling. |
| Identity service | `packages/auth` | The certificate authority that ties public keys to Gryt identities. |
| Message encryption | `packages/crypto` | The code that seals a direct message, and decides whether somebody’s key is the one you saw before. Both apps run this one, and it’s published to npm. |
| Client identity & keys | `packages/client/src/packages/common/src/auth/` | Where your keypair is generated and stored on your device. |
| Image processing | `packages/image-worker` | Decodes untrusted uploads. Image parsing has a long history of memory-safety bugs. |
| Bug reports and feedback | `packages/reports` | The service the in-app report forms post to. Anyone on the internet can POST to it, and it stores what they send. |
| Server data layer | `packages/server/src/db`, `src/storage` | Persistence and object storage. |

The image worker probably looks out of place. It compresses avatars and generates thumbnails, which isn't high-stakes work. But it takes a file someone else uploaded and hands it to a decoder, so it handles untrusted input and I treat it like the rest. The report service is on the list for the same reason. It's the one endpoint in Gryt that anyone can post to without joining a server first, so what it accepts and what it keeps get read line by line.

`packages/crypto` is the newest of these and the only one published as a package. The desktop app and the phone run the same code rather than two versions of it, which is deliberate — two implementations of one envelope means two clients that send each other messages nobody can read, and the sender sees the words they typed either way. It also means a mistake there is a mistake in both at once, and a published version can't be taken back the way a commit can.

## Normal review

- **Documentation** — including this page
- **The marketing site and blog** — `packages/site`
- **Interface and presentation code** — components, styling, layout in `packages/client`
- **Dev tooling and ops scripts** — `ops/`, build scripts, CI configuration
- **Tests, type definitions, and refactors that don't change behaviour**

The difference is how much damage a mistake does. A wrong paragraph in the docs means someone gets confused and opens an issue. A wrong certificate check means someone gets impersonated. Both get reviewed; only one gets read line by line with that in mind.

## Why this changed

This policy originally said the review-required areas were hand-written only, with no AI involvement at all. That rule was too blunt, and it broke in a way that made the problem obvious: adding a CI workflow file to the SFU repository was forbidden, because the rule covered the whole repository rather than the code that actually matters. A YAML file that pings a task tracker isn't a threat to anyone's security.

The thing worth promising was never "no model touched this." It's "nobody ships security-relevant code to you without a human reading it first." That's what this version says, and it's a rule I can actually hold to.

<Callout type="warn">
Be clear about what this is worth: I am the only maintainer. Those repositories require an approving review before merge, but I am also the administrator and can override that. So this isn't an independent gate — it's my own review discipline, made visible. Judge it on the public record below, not on my say-so.
</Callout>

## What this policy isn't about

Gryt ships **RNNoise**, a neural network that removes background noise from your microphone. It runs locally on your device and never sends audio anywhere.

This policy is about who writes and reviews Gryt's code, not about which algorithms the code uses. RNNoise is a feature, and the code around it's reviewed like the rest of the client.

## How to verify this

Every commit that had AI assistance carries a `Co-Authored-By` trailer naming the model, so you can see exactly where AI was involved:

```bash
git log --format='%H %s%n%(trailers:key=Co-Authored-By)'
```

For the review-required areas there's a second trail: every change arrives as a pull request, so you can read the diff, the review and the discussion on GitHub. If you find a direct commit to one of those paths that never went through a PR, that's me breaking my own rule. Open an issue.

## For contributors

The same rules apply, with one addition: say so.

**You must:**

- Tick the AI-assisted box in the pull request template if any part of your patch was AI-generated or AI-assisted
- Expect a slower, closer review if your patch touches a review-required area

**What happens then:**

- Normal-tier contributions get reviewed normally
- Review-required contributions get read line by line, and I'll ask questions or rewrite parts before merging
- Undisclosed AI-generated code in a review-required area is grounds for closing the PR

This isn't meant to make contributing feel adversarial. Disclosure just tells me how closely to read.

## Tooling in the repo

Two files exist for AI tools rather than for people:

- **`.claude/CLAUDE.md`** — the working rules for the repository. Branch naming, which paths are review-required, how the submodules and releases fit together. It's also a reasonable summary if you're new here and not using a model at all.
- **`.claude/launch.json`** — how to start the client, the marketing site and the docs locally, so a tool can run the project without guessing at commands or ports.

Neither of them grants anything. The review rules above are held up by me reading pull requests, so a tool that ignores both files gets exactly the same review as one that follows them. They're there to stop an agent inventing its own way to run the project, which is usually where the odd behaviour starts.

If you use different tooling, `ops/start_dev.sh` starts everything the same way, and `.claude/CLAUDE.md` is worth reading either way.

## This policy can change

It already has once. Gryt is in early development and my thinking will keep shifting as the tooling does. The principle underneath won't: the parts of Gryt that can hurt you if they're wrong get read by a human who understands them, before they ship.

When the policy changes, it changes here, in a commit you can read.

Questions or concerns — [sivert@gryt.chat](mailto:sivert@gryt.chat) or [Discord](https://gryt.chat/discord).
