Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .githooks/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Git hooks (versioned)

Хуки в `.git/hooks/` не версіонуються, тому спільні лежать тут.
Увімкнути для свого клону (один раз):

```bash
git config core.hooksPath .githooks
```

| Хук | Що робить |
|---|---|
| `prepare-commit-msg` | Якщо коміт робиться з сесії Claude Code (змінна `CLAUDECODE`), додає в кінець повідомлення `Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>`. Ідемпотентно; merge/squash не чіпає. Співавтора можна перевизначити: `git config claude.coauthor "Name <email>"`. |

Вимкнути назад: `git config --unset core.hooksPath`.
31 changes: 31 additions & 0 deletions .githooks/prepare-commit-msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/bin/sh
# prepare-commit-msg — додає трейлер співавторства до коміту, коли коміт
# робиться з сесії Claude Code (у її оточенні є змінна CLAUDECODE).
#
# Активація (один раз на клон):
# git config core.hooksPath .githooks
#
# Ідемпотентно: якщо трейлер уже є (наприклад, переданий через
# `git commit --trailer ...` або в тексті -m), другий не додається.
# Для merge/squash-комітів і rebase нічого не робить.
#
# Перевизначити співавтора: git config claude.coauthor "Name <email>"

MSG_FILE="$1"
SOURCE="$2"

# Лише для звичайних комітів (не merge, не squash, не amend через rebase)
case "$SOURCE" in
merge|squash) exit 0 ;;
esac

# Лише з-під Claude Code
[ -n "$CLAUDECODE" ] || exit 0

COAUTHOR="$(git config --get claude.coauthor 2>/dev/null)"
[ -n "$COAUTHOR" ] || COAUTHOR="Claude Fable 5.1 <noreply@anthropic.com>"

git interpret-trailers --in-place \
--if-exists doNothing \
--trailer "Co-Authored-By: $COAUTHOR" \
"$MSG_FILE"
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,19 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

## [3.0.9] - 2026-09

### Added — tooling
- Versioned git hooks in `.githooks/` (enable with
`git config core.hooksPath .githooks`): `prepare-commit-msg` appends the
`Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>` trailer to
commits made from a Claude Code session (`CLAUDECODE` env), idempotently;
merge/squash commits untouched; co-author overridable via
`git config claude.coauthor`. Documented in INSTALL.md.
- `CLAUDE.md`: per-repository instructions for Claude Code sessions (enable
the hooks on a fresh clone, commit/version rules, workflow, invariants
the tests protect, release procedure).

## [3.0.8] - 2026-09

### Added — surname prefix and faker locale (requirements)
Expand Down
78 changes: 78 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# CLAUDE.md — інструкції для сесій Claude Code у цьому репозиторії

## Перше, що зробити в новому клоні

```bash
git config core.hooksPath .githooks # хук додає Co-Authored-By до комітів із Claude Code
pip install -e '.[full]' && pip install -r requirements-dev.txt
```

У хмарному контейнері системний `cryptography` буває зламаний (`_cffi_backend`
відсутній) — тоді: `pip install --force-reinstall --ignore-installed cryptography cffi`.

## Мова спілкування

Відповідати користувачу **українською**. Код, коміти, CHANGELOG — англійською
(коментарі в коді можуть бути українською, як у наявному коді).

## Правила комітів

- **Кожен коміт бампає patch-версію** у двох місцях: `datamasking/_version.py`
та літерал `__version__` у `data_masking.py` (CI звіряє їх). Плюс запис у
`CHANGELOG.md` під новим `## [X.Y.Z]`.
- Трейлери в кінці повідомлення (хук додає `Co-Authored-By`, якщо
`core.hooksPath` увімкнено; інакше — вручну):
```
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: <URL сесії>
```
- Ніяких ідентифікаторів моделі в коді, коментарях чи PR-описах — лише в трейлері.

## Робочий процес

1. Гілка розробки: `claude/refactor-data-masking-lIcWN` (скидається на
`origin/main` перед новою задачею: `git reset --hard origin/main`).
2. Перед комітом: `python -m pytest tests/ -q -p no:cacheprovider`,
`python -m mypy datamasking/ --config-file mypy.ini` (має бути 0 помилок —
джоба blocking), `flake8 . --select=E9,F63,F7,F82`.
3. Push → PR у `main` → дочекатись **зеленого CI на всій матриці**
(Linux 3.9/3.11/3.13, Windows 3.12, core-only, package, mypy) → squash-merge.
Після мержу гілку синхронізувати з `main`.
4. Стежити за CI через GitHub API за **повним SHA** (`?head_sha=<40 hex>`);
скорочений SHA API ігнорує.
5. **Теги через проксі не пушаться** — релізи створює користувач вручну
(тег `vX.Y.Z` запускає `release.yml`, який збирає й публікує все сам). Текст
реліз-нотесу — англійською, після завершення пайплайна (він перезаписує опис).

## Архітектура (коротко)

- Пакет `datamasking/`: `masking/` (рушій, `surname.py` — синтетичні прізвища з
префіксом оригіналу), `unmasking/`, `extras/` (config, security, selective,
re_mask, tools, logger, password_generator), `rank_data.py`, `diagnose.py`.
- Кореневі `masking/`, `unmasking/`, `modules/`, `rank_data.py` — **shim-и**
зворотної сумісності (DeprecationWarning), у wheel не потрапляють.
- `datamasking/__init__.py` навмисно легкий (без faker) — `diagnose` має
лишатись stdlib-only.
- Mapping-файли: unmask залежить лише від mapping, не від алгоритму маскування,
тому зміни масок не ламають розмаскування старих файлів
(`tests/fixtures/legacy_mappings/` — реальні файли v2.3.0/v2.5.1/v2.6.5).

## Інваріанти, які перевіряють тести — не ламати

- Маска прізвища: перші N символів оригіналу (N = `SURNAME_PREFIX_LENGTH`,
не більше половини слова, хоча б один символ основи змінюється) + синтетична
основа + закінчення; **ніколи** не містить оригінал, його основу чи слово
документа; детермінована від seed(оригінал).
- Імена/по батькові ніколи не мапляться самі на себе.
- `--encrypt` пише лише `.enc` (plaintext mapping не створюється), mapping —
атомарно з правами 0600.
- Коди виходу: 0 успіх, 1 помилка, 2 неправильне використання; жодних
traceback-ів на очікуваних помилках.
- Тести, що потребують cryptography/pyyaml, мають `skipif` (є CI-джоба
core-only без них).

## Файли, яких не має бути в репо

`config.yaml` у корені, `output_*`, `masking_map_*`, `masking_report_*`,
`input_recovery_*`, `input.txt` (усе в `.gitignore`; фікстури тестів названі
інакше — `source.txt`). `conftest.py` падає, якщо тест лишає `config.yaml`.
2 changes: 1 addition & 1 deletion data_masking.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
# Re-exports from masking package for backward compatibility
# ============================================================================

__version__ = "3.0.8"
__version__ = "3.0.9"

from datamasking.masking.constants import (
__version__, __author__, __contact__, __phone__, __license__, __year__,
Expand Down
2 changes: 1 addition & 1 deletion datamasking/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@
(і не тягнучи faker під час збірки).
"""

__version__ = "3.0.8"
__version__ = "3.0.9"
16 changes: 16 additions & 0 deletions docs/INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,22 @@ startup. The `build/` directory contains the analysis results

---

## Contributing: git hooks

Shared hooks live in `.githooks/` (the `.git/hooks/` directory is not versioned).
Enable them once per clone:

```bash
git config core.hooksPath .githooks
```

`prepare-commit-msg` appends `Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>`
to commits made from a Claude Code session (detected via the `CLAUDECODE`
environment variable); it is idempotent and leaves merge/squash commits alone.
Override the co-author with `git config claude.coauthor "Name <email>"`.

---

## Dependencies

| Package | Version | Purpose |
Expand Down
Loading