Skip to content

Commit 439b35f

Browse files
committed
docs: add AGENTS.md for AI coding agent guidance
Add a root AGENTS.md following the agents.md convention, covering project overview, repo layout, setup, commands, code style, testing conventions, how to add a detection rule, i18n, commit/PR format and the security rules that apply to a bot handling Slack tokens and PII. Add a thin CLAUDE.md pointing at it so there is a single source of truth, and cross-link it from README.md, README.PTBR.md and CONTRIBUTING.md.
1 parent ff274da commit 439b35f

6 files changed

Lines changed: 133 additions & 1 deletion

File tree

.gitignore

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,4 +156,10 @@ poetry.lock
156156

157157
# Secrets and credentials
158158
*.pem
159-
*.credentials
159+
*.credentials
160+
161+
# Claude Code
162+
.claude/logs/
163+
.claude/plans/
164+
.claude/memory/
165+
.claude/settings.local.json

AGENTS.md

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# AGENTS.md
2+
3+
Guidance for AI coding agents working on this repository. Human contributors should read
4+
[CONTRIBUTING.md](CONTRIBUTING.md) and [README.md](README.md) first — this file is the condensed,
5+
machine-facing version.
6+
7+
## Project overview
8+
9+
SafeChat Slack Bot is a Slack bot (Slack Bolt, Socket Mode) that detects PII — Brazilian CPF, email
10+
addresses and Brazilian phone numbers — in channel messages and replies in-thread asking the author
11+
not to share sensitive data. Python 3.11, Poetry, Docker-first, i18n via gettext.
12+
13+
## Repo layout
14+
15+
```
16+
src/bot.py entrypoint: builds AsyncApp, starts AsyncSocketModeHandler
17+
src/listeners/register.py registers every listener
18+
src/listeners/messages/regex_message.py new messages matching the compiled pattern
19+
src/listeners/messages/message_changed.py edited messages (subtype message_changed)
20+
src/rules/constants.py the regex patterns
21+
src/rules/pattern.py Pattern singleton: compiles the rules, find_all(text) -> int
22+
src/config/settings.py settings.conf + ENV via ConfigParser
23+
src/config/language.py gettext wrapper: language.translate(msgid)
24+
src/locales/{en,pt_BR}/LC_MESSAGES/base.po translations
25+
tests/ mirrors src/
26+
```
27+
28+
## Setup
29+
30+
Prerequisites: Python 3.11, Docker + Docker Compose, `gettext` (provides `msgfmt`), Poetry.
31+
32+
- `make docker/install` — recommended, and what CI runs.
33+
- `make local/install` — local Poetry install.
34+
35+
Both targets create `.env` from [env.template](env.template) if absent and compile the `.mo` files.
36+
`.env` and `*.mo` are gitignored and must stay that way — never commit either.
37+
38+
## Commands
39+
40+
| Task | Docker (canonical) | Local |
41+
| --- | --- | --- |
42+
| install | `make docker/install` | `make local/install` |
43+
| tests | `make docker/test` | `make local/tests` |
44+
| lint | `make docker/lint` | `make local/lint` |
45+
| lint + autofix | `make docker/lint/fix` | `make local/lint/fix` |
46+
| run | `make docker/run` | `make local/run` |
47+
| compile translations | `make generate-mo-files` | `make generate-mo-files` |
48+
49+
CI ([`.github/workflows/pull_request.yml`](.github/workflows/pull_request.yml)) runs
50+
`make docker/install``make docker/lint``make docker/test`. See the [Makefile](Makefile) for
51+
every target.
52+
53+
## Code style
54+
55+
Ruff, configured in [pyproject.toml](pyproject.toml): `line-length = 120`, `target-version = py311`,
56+
4-space indent, double quotes. Lint rules: `E`, `F`, `W` (pycodestyle/pyflakes), `I` (isort),
57+
`N` (pep8-naming), `S` (flake8-bandit). Run `make local/lint/fix` before committing.
58+
59+
Project ethos from [CONTRIBUTING.md](CONTRIBUTING.md): be pythonic, DRY, KISS.
60+
61+
## Testing
62+
63+
`pytest` with `testpaths = ["tests"]` and `pythonpath = ["src"]`.
64+
65+
- Tests in this repo are `unittest.TestCase` / `IsolatedAsyncioTestCase` classes with
66+
`unittest.mock` (`AsyncMock`, `MagicMock`, `patch`) — **not** bare pytest functions. Follow the
67+
existing style.
68+
- Name tests for the behaviour they assert, e.g. `test_if_text_can_be_a_cpf_with_success`.
69+
- Coverage runs in branch mode with **`fail_under = 100`** (`src/bot.py` omitted). New code without
70+
tests breaks the build.
71+
- `pytest-asyncio` is installed but no `asyncio_mode` is configured — write async tests with
72+
`IsolatedAsyncioTestCase`.
73+
74+
## Adding a detection rule
75+
76+
1. Add the regex to `src/rules/constants.py`.
77+
2. Append it to `self.rules` in `Pattern.__init__` (`src/rules/pattern.py`).
78+
3. Add positive **and** negative cases to `tests/rules/test_pattern.py`.
79+
80+
Watch for over-matching: the rules are joined with `|` into one pattern, and the current CPF regex
81+
matches any run of 11 digits — a phone number counts as a CPF. Assert exact `find_all` counts.
82+
83+
## Internationalization
84+
85+
User-facing strings must go through `language.translate("...")`. Add the msgid to **both**
86+
`src/locales/en/LC_MESSAGES/base.po` and `src/locales/pt_BR/LC_MESSAGES/base.po`, then run
87+
`make generate-mo-files`. Adding a new locale also requires a `msgfmt` line in the
88+
[Dockerfile](Dockerfile).
89+
90+
## Commits and pull requests
91+
92+
- Use [Conventional Commits](https://www.conventionalcommits.org/): `feat:`, `fix:`, `docs:`,
93+
`chore:`, `refactor:`, `test:`. (History predates this convention and is inconsistent — follow the
94+
convention going forward.)
95+
- **Never add `Co-Authored-By` lines or any AI / "Generated with" attribution** to commits or PR
96+
bodies.
97+
- Never commit directly to `main` — always work on a branch.
98+
- An issue must exist before a PR (see the [pull request template](.github/PULL_REQUEST_TEMPLATE)).
99+
Reference it with `closes #NN`.
100+
- Make sure lint and tests pass locally before opening the PR.
101+
102+
## Security
103+
104+
This bot handles credentials and PII by definition. Treat these as hard rules:
105+
106+
- `SLACK_BOT_TOKEN` and `SLACK_APP_TOKEN` come from environment variables only. Never hardcode a
107+
token, never log one, and never paste a real value into docs, tests or fixtures — reference
108+
[env.template](env.template) and the variable names instead.
109+
- **Never log raw message text or matched PII.** Listeners log exceptions only; keep it that way.
110+
- Do not suppress Ruff `S` (bandit) findings with `# noqa` without a written justification.
111+
- Changes to scopes in [manifest.json](manifest.json) are security-relevant — call them out
112+
explicitly in the pull request.
113+
- Report vulnerabilities through [SECURITY.md](SECURITY.md), not a public issue.

CLAUDE.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# CLAUDE.md
2+
3+
See @AGENTS.md for project setup, commands, style, testing and security guidance.

CONTRIBUTING.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,9 @@ F | [pyflakes](https://pypi.org/project/pyflakes/)
4444
I | [isort](https://pypi.org/project/isort/)
4545
N | [pep8-naming](https://pypi.org/project/pep8-naming/)
4646
S | [flake8-bandit](https://pypi.org/project/flake8-bandit/)
47+
48+
# AI Coding Agents
49+
50+
If you use an AI coding agent (Claude Code, Cursor, Copilot, Codex and friends) to contribute, point it at [AGENTS.md](AGENTS.md). It follows the [agents.md](https://agents.md/) convention and covers setup, commands, code style, testing conventions, commit format and the security rules that apply to this bot — it handles Slack tokens and PII, so those rules are not optional.
51+
52+
You are still responsible for everything you submit: read the diff, run `make local/lint` and `make local/tests`, and make sure the pull request describes the change in your own words.

README.PTBR.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ run | `make docker/run` | `make local/run` | Para rodar a aplicação
7272

7373
*Confira todos os comandos disponíveis no arquivo [Makefile](Makefile)*.
7474

75+
*Agentes de IA: veja [AGENTS.md](AGENTS.md) para orientações específicas.*
76+
7577
## Múltiplos Idioma
7678

7779
O Bot consegue interagir com outros idiomas além do Português utilizando o padrão [i18n](https://docs.python.org/3/library/i18n.html).

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ push image | `make docker/image/push` | - | to push the docker image
7878

7979
*Please, check all available commands in the [Makefile](Makefile) for more information*.
8080

81+
*AI coding agents: see [AGENTS.md](AGENTS.md) for agent-specific guidance.*
82+
8183
## Multi Language
8284

8385
The Bot supports multiple languages using [i18n](https://docs.python.org/3/library/i18n.html) pattern.

0 commit comments

Comments
 (0)