SafeChat Slack Bot

AGENTS.md

Guidance for AI coding agents working on this repository. Human contributors should read CONTRIBUTING.md and README.md first — this file is the condensed, machine-facing version.

Project overview

SafeChat Slack Bot is a Slack bot (Slack Bolt, Socket Mode) that detects PII — Brazilian CPF, email addresses and Brazilian phone numbers — in channel messages and replies in-thread asking the author not to share sensitive data. Python 3.11, Poetry, Docker-first, i18n via gettext.

Repo layout

src/bot.py                              entrypoint: builds AsyncApp, starts AsyncSocketModeHandler
src/listeners/register.py               registers every listener
src/listeners/messages/regex_message.py new messages matching the compiled pattern
src/listeners/messages/message_changed.py  edited messages (subtype message_changed)
src/rules/constants.py                  the regex patterns
src/rules/pattern.py                    Pattern singleton: compiles the rules, find_all(text) -> int
src/config/settings.py                  settings.conf + ENV via ConfigParser
src/config/language.py                  gettext wrapper: language.translate(msgid)
src/locales/{en,pt_BR}/LC_MESSAGES/base.po  translations
tests/                                  mirrors src/

Setup

Prerequisites: Python 3.11, Docker + Docker Compose, gettext (provides msgfmt), Poetry.

Both targets create .env from env.template if absent and compile the .mo files. .env and *.mo are gitignored and must stay that way — never commit either.

Commands

Task Docker (canonical) Local
install make docker/install make local/install
tests make docker/test make local/tests
lint make docker/lint make local/lint
lint + autofix make docker/lint/fix make local/lint/fix
run make docker/run make local/run
compile translations make generate-mo-files make generate-mo-files

CI (.github/workflows/pull_request.yml) runs make docker/installmake docker/lintmake docker/test. See the Makefile for every target.

Code style

Ruff, configured in pyproject.toml: line-length = 120, target-version = py311, 4-space indent, double quotes. Lint rules: E, F, W (pycodestyle/pyflakes), I (isort), N (pep8-naming), S (flake8-bandit). Run make local/lint/fix before committing.

Project ethos from CONTRIBUTING.md: be pythonic, DRY, KISS.

Testing

pytest with testpaths = ["tests"] and pythonpath = ["src"].

Adding a detection rule

  1. Add the regex to src/rules/constants.py.
  2. Append it to self.rules in Pattern.__init__ (src/rules/pattern.py).
  3. Add positive and negative cases to tests/rules/test_pattern.py.

Watch for over-matching: the rules are joined with | into one pattern, and the current CPF regex matches any run of 11 digits — a phone number counts as a CPF. Assert exact find_all counts.

Internationalization

User-facing strings must go through language.translate("..."). Add the msgid to both src/locales/en/LC_MESSAGES/base.po and src/locales/pt_BR/LC_MESSAGES/base.po, then run make generate-mo-files. Adding a new locale also requires a msgfmt line in the Dockerfile.

Commits and pull requests

Releases

The tag and the GitHub Release are created automatically by .github/workflows/release.yml when a version without a tag lands on main. CONTRIBUTING.md has the full process.

Security

This bot handles credentials and PII by definition. Treat these as hard rules: