snapshot of https://github.com/zulip/zulip.git @ 48c69911c7dd4e03b20552eb3bd77ad8151c1357 (2026-09-15)
Some checks failed
Code scanning / CodeQL (push) Failing after 15s
Zulip production suite / Ubuntu 22.04 production build (push) Failing after 26s
Zulip production suite / Debian 12 production install with custom db name and user (push) Has been skipped
Zulip production suite / Ubuntu 22.04 production install and PostgreSQL upgrade with pgroonga (push) Has been skipped
Zulip production suite / Ubuntu 24.04 production install (push) Has been skipped
Zulip production suite / Ubuntu 26.04 production install (push) Has been skipped
Zulip production suite / Debian 13 production install (push) Has been skipped
Zulip production suite / 7.0 Version Upgrade (push) Has been skipped
Zulip production suite / 8.0 Version Upgrade (push) Has been skipped
Zulip production suite / 6.0 Version Upgrade (push) Has been skipped
Zulip production suite / 10.0 Version Upgrade (push) Has been skipped
Zulip production suite / 9.0 Version Upgrade (push) Has been skipped
Zulip production suite / 12.0 Version Upgrade (push) Has been skipped
Zulip production suite / 11.0 Version Upgrade (push) Has been skipped
GitHub Actions Security Analysis with zizmor / zizmor (push) Failing after 3s
Zulip CI / Debian 12 (Python 3.11, backend + documentation) (push) Failing after 26s
Zulip CI / Ubuntu 22.04 (Python 3.10, backend + frontend) (push) Failing after 3s
Zulip CI / Ubuntu 24.04 (Python 3.12, backend) (push) Failing after 25s
Zulip CI / Ubuntu 26.04 (Python 3.14, backend) (push) Failing after 25s
Zulip CI / Debian 13 (Python 3.13, backend) (push) Failing after 28s
Zulip production suite / Required jobs (push) Has been cancelled
Zulip CI / Required jobs (push) Has been cancelled
API Documentation Update Check / check-feature-level-updated (push) Has been cancelled
API Documentation Update Check / notify-if-api-docs-changed (push) Has been cancelled
Some checks failed
Code scanning / CodeQL (push) Failing after 15s
Zulip production suite / Ubuntu 22.04 production build (push) Failing after 26s
Zulip production suite / Debian 12 production install with custom db name and user (push) Has been skipped
Zulip production suite / Ubuntu 22.04 production install and PostgreSQL upgrade with pgroonga (push) Has been skipped
Zulip production suite / Ubuntu 24.04 production install (push) Has been skipped
Zulip production suite / Ubuntu 26.04 production install (push) Has been skipped
Zulip production suite / Debian 13 production install (push) Has been skipped
Zulip production suite / 7.0 Version Upgrade (push) Has been skipped
Zulip production suite / 8.0 Version Upgrade (push) Has been skipped
Zulip production suite / 6.0 Version Upgrade (push) Has been skipped
Zulip production suite / 10.0 Version Upgrade (push) Has been skipped
Zulip production suite / 9.0 Version Upgrade (push) Has been skipped
Zulip production suite / 12.0 Version Upgrade (push) Has been skipped
Zulip production suite / 11.0 Version Upgrade (push) Has been skipped
GitHub Actions Security Analysis with zizmor / zizmor (push) Failing after 3s
Zulip CI / Debian 12 (Python 3.11, backend + documentation) (push) Failing after 26s
Zulip CI / Ubuntu 22.04 (Python 3.10, backend + frontend) (push) Failing after 3s
Zulip CI / Ubuntu 24.04 (Python 3.12, backend) (push) Failing after 25s
Zulip CI / Ubuntu 26.04 (Python 3.14, backend) (push) Failing after 25s
Zulip CI / Debian 13 (Python 3.13, backend) (push) Failing after 28s
Zulip production suite / Required jobs (push) Has been cancelled
Zulip CI / Required jobs (push) Has been cancelled
API Documentation Update Check / check-feature-level-updated (push) Has been cancelled
API Documentation Update Check / notify-if-api-docs-changed (push) Has been cancelled
This commit is contained in:
383
AGENTS.md
Normal file
383
AGENTS.md
Normal file
@@ -0,0 +1,383 @@
|
||||
# AGENTS.md - Guidelines for AI Contributions to Zulip
|
||||
|
||||
This file provides guidance to AI coding agents for contributing to
|
||||
the Zulip codebase. These guidelines are designed to produce
|
||||
contributions that meet the same high standards we expect from human
|
||||
contributors.
|
||||
|
||||
When doing any work with AI assistants, it is crucial to follow our
|
||||
AI use policy and guidelines (the "AI use policy and guidelines"
|
||||
section in `CONTRIBUTING.md`). In particular:
|
||||
|
||||
> **Do not submit an AI-generated PR you haven't personally
|
||||
> understood and tested**, as this wastes maintainers' time. PRs that
|
||||
> appear to violate this guideline will be closed without review.
|
||||
|
||||
> **Do not post AI-generated messages** in the [Zulip development
|
||||
> community](https://zulip.com/development-community/) -- we want to
|
||||
> read your own genuine expression of your thoughts.
|
||||
|
||||
Claude Code automatically uses `.claude/rules/` and `.claude/skills/`.
|
||||
If you are a different agent, read the files in these folders to see
|
||||
the rest of the agent instructions and when they're relevant. Rules
|
||||
are relevant for files listed in `paths:` at the top of the rule
|
||||
file. Skills explain when they're relevant in their `description`.
|
||||
|
||||
## Philosophy
|
||||
|
||||
Zulip is a team chat application used by thousands of organizations,
|
||||
built to last for many years. It is developed by a vibrant open-source
|
||||
community, with maintainers who have consistently emphasized **high
|
||||
standards for codebase readability, code review, commit discipline,
|
||||
debuggability, automated testing, tooling, documentation, and all the
|
||||
other subtle details that together determine whether software is easy
|
||||
to understand, operate, and modify**.
|
||||
|
||||
Zulip's engineering strategy is to **"move quickly without breaking
|
||||
things"**. This is possible because the project has invested years in
|
||||
testing, tooling, code structure, documentation, and development
|
||||
practices that catch bugs systematically rather than relying on
|
||||
individual vigilance. Maintainers spend most of their review time on
|
||||
product decisions and code structure/readability, not on chasing
|
||||
correctness issues — because the process is designed to prevent them.
|
||||
|
||||
This means Zulip's coding philosophy is to **focus relentlessly on
|
||||
making the codebase easy to understand and difficult to make dangerous
|
||||
mistakes**. This applies equally to AI-generated contributions. Every
|
||||
change should make the codebase more maintainable and easier to read.
|
||||
|
||||
### No detail is too small
|
||||
|
||||
There is no category of "minor issue" that is acceptable to ship —
|
||||
if something is broken in any state, size, theme, or language where
|
||||
a user would encounter it, it must be fixed before merging. If a fix
|
||||
would require a design decision, raise it as a question rather than
|
||||
shipping the broken state. See `.claude/rules/ui-testing.md` for
|
||||
what to test for UI changes (the file loads automatically when you
|
||||
work on frontend files).
|
||||
|
||||
The right attitude is: "What could go wrong, and how do I verify that
|
||||
it doesn't?" not "It looks fine to me." **What isn't tested probably
|
||||
doesn't work** — this applies to visual changes just as much as to
|
||||
backend logic.
|
||||
|
||||
### Understand before coding
|
||||
|
||||
Before writing any code, you must understand:
|
||||
|
||||
1. What the existing code does and why, including the relevant help center or
|
||||
developer-facing documentation.
|
||||
2. What problem you're solving, in its full scope.
|
||||
3. Why your approach is the right solution, and available alternatives.
|
||||
4. How you will verify that your work is correct, and avoid regressions
|
||||
that are plausible for the type of work you're doing.
|
||||
|
||||
The answer to "Why is X an improvement?" should never be "I'm not sure."
|
||||
|
||||
## Workflow
|
||||
|
||||
Follow this workflow for every task: **understand → propose → implement → verify**.
|
||||
|
||||
### 1. Understand Before Coding
|
||||
|
||||
Before making any changes:
|
||||
|
||||
```bash
|
||||
# Read relevant documentation
|
||||
cat docs/*/<relevant-area>.md
|
||||
cat starlight_help/src/content/docs/<topic>.md
|
||||
cat api_docs/<topic>.md and read the relevant part of zerver/openapi/zulip.yaml
|
||||
|
||||
# Look at existing code patterns
|
||||
git grep "similar_function_name"
|
||||
git log --oneline -20 -- path/to/file.py
|
||||
|
||||
# Check for related issues on GitHub
|
||||
```
|
||||
|
||||
### 2. Propose an Approach
|
||||
|
||||
Before writing code, explain the plan:
|
||||
|
||||
- Explain your understanding of the problem and all relevant design decisions
|
||||
- What changes are needed and why
|
||||
- How the changes fit with existing patterns
|
||||
- What could break and how to prevent regressions
|
||||
|
||||
### 3. Implement in Minimal, Coherent Commits
|
||||
|
||||
Structure changes as clean commits:
|
||||
|
||||
- Backend and API changes, with tests and API doc changes documented
|
||||
fully using our double-entry changelog system. Instructions for
|
||||
documentation can be found in `.claude/rules/api-changelog.md`
|
||||
(loaded automatically when you edit `zerver/openapi/zulip.yaml`).
|
||||
- Frontend UI changes (with tests and user-facing documentation
|
||||
updates). Remember to plan to use your visual test skill
|
||||
(`.claude/skills/visual-test/SKILL.md`) to check your work whenever
|
||||
you change web app code (HTML, CSS, JS).
|
||||
|
||||
Each commit should be self-contained, highly readable and reviewable
|
||||
using `git show --color-moved`, and pass lint/tests independently. If
|
||||
extracting new files or moving code, always do that in a separate
|
||||
commit from other changes.
|
||||
|
||||
### 4. Verify Before Finalizing
|
||||
|
||||
Run the linter and the relevant tests before making each commit; see
|
||||
"Testing Requirements" below for instructions.
|
||||
|
||||
Run through the `/self-review` skill's checklist before suggesting opening
|
||||
a PR (`.claude/skills/self-review/SKILL.md`).
|
||||
|
||||
## Before You Start
|
||||
|
||||
### Read the Relevant Documentation
|
||||
|
||||
Zulip has over 185,000 words of developer documentation. Before working on any area:
|
||||
|
||||
- Read documentation from docs/, starlight_help/src/content/docs/, and api_docs/.
|
||||
`docs/subsystems/directory-structure.md` explains where code lives.
|
||||
- Read existing code in the area you're modifying.
|
||||
- Use `git grep` to find similar patterns in the codebase and read those.
|
||||
|
||||
### Understand the Code Style
|
||||
|
||||
- **Be consistent with existing code.** Look at surrounding code and follow
|
||||
the same patterns, as this is a thoughtfully crafted codebase.
|
||||
- **Use clear, greppable names** for functions, arguments, variables, and
|
||||
tests. Future developers will `git grep` for relevant terms when
|
||||
researching a problem, so names should communicate purpose clearly.
|
||||
- Keep everything well factored for maintainability. Avoid duplicating
|
||||
code, especially where access control or subtle correctness is involved.
|
||||
- Run `./tools/lint` to catch style issues before committing, including mypy issues.
|
||||
- Prefer writing code that is readable without explanation over heavily
|
||||
commented code using clever tricks.
|
||||
- Don't reference line numbers (e.g., `filter.ts:493`) in comments, commit
|
||||
messages, or PR descriptions; they get stale when files are edited.
|
||||
Reference symbol names instead.
|
||||
|
||||
**Comments**
|
||||
|
||||
- Comments should explain "why" when the reason isn't obvious, not
|
||||
narrate "what" the code does.
|
||||
- Comments should have a line to themself except for CSS px math.
|
||||
- Comments should never describe the change being made or a bug
|
||||
being fixed. They should read as if they were there all along.
|
||||
Descriptions of the diff belong in the commit message instead.
|
||||
- Match comment density of nearby code and similar functions.
|
||||
If similar code doesn't comment on something, don't comment
|
||||
on it in new code.
|
||||
- Avoid metaphors in favor of clear descriptive language. Match
|
||||
existing idioms verbatim for comments describing specific
|
||||
situations (e.g., `/* Override bootstrap defaults */`) rather
|
||||
than writing a new or longer explanation.
|
||||
|
||||
**Further rules**
|
||||
|
||||
Frontend rules can be found in `.claude/rules/frontend.md` (loaded
|
||||
automatically when you work on frontend JS/TS and template files).
|
||||
|
||||
CSS rules can be found in `.claude/rules/css.md` (loaded
|
||||
automatically when you work on CSS files).
|
||||
|
||||
Python rules can be found in `.claude/rules/python.md` (loaded
|
||||
automatically when you work on .py files).
|
||||
|
||||
See: `docs/contributing/code-style.md`
|
||||
|
||||
## Commit Discipline
|
||||
|
||||
Zulip follows the Git project's practice of **"Each commit is a minimal
|
||||
coherent idea."** This is non-negotiable.
|
||||
|
||||
### Each Commit Must:
|
||||
|
||||
1. **Be coherent**: Implement one logical change completely and atomically.
|
||||
2. **Pass tests**: Include test updates in the same commit as code changes.
|
||||
3. **Not make Zulip worse**: Work is ordered so no commit has regressions.
|
||||
4. **Be safe to deploy individually**: Or explain in detail why not.
|
||||
5. **Be minimal** and **reviewable**: Don't combine moving code with changing
|
||||
it in the same commit; make liberal use of small prep commits for
|
||||
no-op refactoring that are easy to verify.
|
||||
|
||||
### Never:
|
||||
|
||||
- Mix multiple separable changes in a single commit.
|
||||
- Create a commit that "fixes" a mistake from an earlier commit in the same PR;
|
||||
always edit Git to fix the original commit.
|
||||
- Add content in one commit only to remove or move it in the next;
|
||||
plan upfront what belongs where and do it right the first time.
|
||||
- Include debugging code, commented-out code, or temporary TODOs.
|
||||
- Leave commits that break if a later commit in the PR is dropped.
|
||||
When a commit is flagged as potentially droppable, verify all
|
||||
earlier commits work correctly without it.
|
||||
|
||||
### Open Independently Useful Fixes as Separate PRs
|
||||
|
||||
If, while building a feature, you find and fix a pre-existing bug or
|
||||
make a refactor that would be worth merging even if the feature never
|
||||
lands, split this into its own PR. A small isolated PR gets more
|
||||
scrutiny than the same change as part of a large PR. Prep commits
|
||||
that mainly make sense in the context of the feature PR should stay
|
||||
in the feature's PR.
|
||||
|
||||
### Commit Message Format
|
||||
|
||||
Use the `/commit-message` skill whenever you write or reword a
|
||||
commit message (`.claude/skills/commit-message/SKILL.md`).
|
||||
|
||||
## Testing Requirements
|
||||
|
||||
Zulip server takes pride in its ~98% test coverage. All server changes
|
||||
must include nice tests that follow our testing philosophy.
|
||||
|
||||
When writing tests, follow our testing philosophy in
|
||||
`.claude/rules/testing.md` (loaded automatically when you work on
|
||||
test files).
|
||||
|
||||
Manage your time by running specific backend test collections, not
|
||||
the entire suite; the node suite is fast enough to run in full.
|
||||
|
||||
```bash
|
||||
# Includes mypy and typescript checkers
|
||||
./tools/lint path/to/changed/files.py
|
||||
./tools/test-backend zerver.tests.test_relevant_module
|
||||
./tools/test-js-with-node
|
||||
```
|
||||
|
||||
### Manual Testing for UI Changes
|
||||
|
||||
If a PR makes frontend changes, manually verify the affected UI
|
||||
using the checklist in `.claude/rules/ui-testing.md` (loaded
|
||||
automatically when you work on frontend files).
|
||||
|
||||
## What Not To Do
|
||||
|
||||
- Always check if you're working on top of the latest upstream/main, and
|
||||
fetch + rebase when starting a project so you're not using a stale branch.
|
||||
If you're continuing a project, start by rebasing, resolving merge
|
||||
conflicts carefully.
|
||||
- Don't make design or UX decisions silently. When a technical
|
||||
constraint forces a tradeoff, present the constraint and options
|
||||
to the user rather than picking one. Never remove features, hide
|
||||
UI elements, or change interaction patterns without asking.
|
||||
- Don't submit code you haven't tested
|
||||
- Don't skip becoming familiar with the code you're modifying
|
||||
- Don't make claims about code behavior without verification, and
|
||||
cite your sources.
|
||||
- Don't generate PR descriptions that just describe what files changed
|
||||
- Always do a pre-mortem: Think about how to avoid a bug recurring,
|
||||
how it might break something that already works, or imagine under
|
||||
what circumstances your changes might need to be reverted.
|
||||
|
||||
## Pull Request Guidelines
|
||||
|
||||
When opening a pull request, prefix the PR title with `[ai]` (e.g.,
|
||||
`[ai] compose: Fix cursor position after emoji insertion.`). Use
|
||||
`upstream/main` as the base branch. Use the `/pr-description` skill
|
||||
to write the PR description
|
||||
(`.claude/skills/pr-description/SKILL.md`).
|
||||
|
||||
## When to Pause and Discuss
|
||||
|
||||
Recommend pausing for discussion when:
|
||||
|
||||
- The approach involves security-sensitive code
|
||||
- Database migrations are needed (See `docs/subsystems/schema-migrations.md`).
|
||||
- The change alters behavior in several subsystems at once (renames
|
||||
and type annotation changes that touch many files do not count)
|
||||
- Performance implications are unclear
|
||||
- The feature design isn't fully specified
|
||||
- The API or data model design isn't fully specified
|
||||
- An API change may not be compatible (See `docs/processes/api-design.md`).
|
||||
- Existing tests are failing for unclear reasons
|
||||
|
||||
## Task-Specific Approaches
|
||||
|
||||
### For Bug Fixes
|
||||
|
||||
1. Look at the relevant code and brainstorm theories for
|
||||
how the bug might be possible
|
||||
2. Provide a clear explanation for the bug, and ideally
|
||||
provide steps for reproducing the bug on `main` in the
|
||||
dev environment. Verify the cause of the bug before
|
||||
suggesting a fix, unless a bug is very difficult to verify,
|
||||
in which case say so and explain a hypothesis instead.
|
||||
3. Analyze and propose a fix with a clear explanation
|
||||
4. Write tests that would have caught this bug if possible
|
||||
5. Audit for whether the bug may exist elsewhere or might be
|
||||
re-introduced and propose appropriate changes to address if so.
|
||||
|
||||
### For New Features
|
||||
|
||||
1. Read the relevant documentation in docs/
|
||||
2. Show similar existing features in the codebase
|
||||
3. Propose an implementation approach before coding
|
||||
4. Implement, following "Commit Discipline" above
|
||||
|
||||
### For Refactoring
|
||||
|
||||
1. Show the current implementation
|
||||
2. Explain what makes it problematic
|
||||
3. Propose the refactoring approach
|
||||
4. Implement in commits that each leave the codebase working
|
||||
5. No behavior changes unless explicitly discussed
|
||||
6. Verify completeness: use `git grep` to find all occurrences and
|
||||
confirm nothing was missed
|
||||
|
||||
## Key Documentation Links
|
||||
|
||||
- Contributing guide: `docs/contributing/contributing.md`
|
||||
- Code style: `docs/contributing/code-style.md`
|
||||
- Commit discipline: `docs/contributing/commit-discipline.md`
|
||||
- Testing overview: `docs/testing/testing.md`
|
||||
- Backend tests: `docs/testing/testing-with-django.md`
|
||||
- Code review: `docs/contributing/code-reviewing.md`
|
||||
- mypy guide: `docs/testing/mypy.md`
|
||||
|
||||
## Help Center Documentation
|
||||
|
||||
When making any user-facing change, **read
|
||||
`docs/documentation/helpcenter.md`** in full and review the relevant
|
||||
help center articles under `starlight_help/src/content/docs/` for any
|
||||
updates that should be made. The writing guide there is the source
|
||||
of truth for help center conventions, components, and structure.
|
||||
|
||||
## Zulip Chat Links
|
||||
|
||||
When you encounter a Zulip narrow URL (e.g., from `chat.zulip.org` in a
|
||||
GitHub issue, PR, or user message), use the `/fetch-zulip-messages`
|
||||
skill (`.claude/skills/fetch-zulip-messages/SKILL.md`) to read the
|
||||
conversation. Do not use `WebFetch` — it cannot access Zulip message
|
||||
content.
|
||||
|
||||
## Common Commands
|
||||
|
||||
```bash
|
||||
./tools/provision # Set up development environment
|
||||
./tools/run-dev # Start development server
|
||||
./tools/lint # Run all linters
|
||||
./tools/test-backend # Run Python tests
|
||||
./tools/test-js-with-node # Run JavaScript tests
|
||||
./tools/run-mypy # Run type checker
|
||||
git grep "pattern" # Search codebase (use extensively!)
|
||||
```
|
||||
|
||||
Most of these commands take minutes, so run them in the background.
|
||||
|
||||
If a tool complains that provision is outdated, run `./tools/provision`
|
||||
to fix it. Do not use `--skip-provision-check` to work around the
|
||||
error; the check exists because tests and linters depend on provisioned
|
||||
dependencies being current.
|
||||
|
||||
If the development environment runs in a container (Vagrant/Docker),
|
||||
run `./tools/` commands inside it. Files and new screenshots will be
|
||||
accessible on both sides.
|
||||
|
||||
```bash
|
||||
vagrant ssh -c 'cd ~/zulip && ./tools/lint path/to/changed/files.py'
|
||||
```
|
||||
|
||||
If `vagrant ssh` fails with a Docker daemon error, Docker Desktop isn't
|
||||
running; ask the user to start it.
|
||||
Reference in New Issue
Block a user