From 2ae72b60e9f5885970fea8a39265b2906d5297cb Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 8 Sep 2026 08:57:18 +0000 Subject: [PATCH] =?UTF-8?q?chore:=20versioned=20git=20hooks=20=E2=80=94=20?= =?UTF-8?q?auto=20Co-Authored-By=20trailer=20for=20Claude=20Code=20commits?= =?UTF-8?q?=20(v3.0.9)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Claude-Session: https://claude.ai/code/session_01XT6iUWaQgahXDB9TWX9Bq7 Co-Authored-By: Claude Fable 5.1 --- .githooks/README.md | 14 +++++++ .githooks/prepare-commit-msg | 31 ++++++++++++++ CHANGELOG.md | 13 ++++++ CLAUDE.md | 78 ++++++++++++++++++++++++++++++++++++ data_masking.py | 2 +- datamasking/_version.py | 2 +- docs/INSTALL.md | 16 ++++++++ 7 files changed, 154 insertions(+), 2 deletions(-) create mode 100644 .githooks/README.md create mode 100755 .githooks/prepare-commit-msg create mode 100644 CLAUDE.md diff --git a/.githooks/README.md b/.githooks/README.md new file mode 100644 index 0000000..e875091 --- /dev/null +++ b/.githooks/README.md @@ -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 `. Ідемпотентно; merge/squash не чіпає. Співавтора можна перевизначити: `git config claude.coauthor "Name "`. | + +Вимкнути назад: `git config --unset core.hooksPath`. diff --git a/.githooks/prepare-commit-msg b/.githooks/prepare-commit-msg new file mode 100755 index 0000000..6702317 --- /dev/null +++ b/.githooks/prepare-commit-msg @@ -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 " + +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 " + +git interpret-trailers --in-place \ + --if-exists doNothing \ + --trailer "Co-Authored-By: $COAUTHOR" \ + "$MSG_FILE" diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c68009..883fcf5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 ` 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) diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..89d798a --- /dev/null +++ b/CLAUDE.md @@ -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 + Claude-Session: + ``` +- Ніяких ідентифікаторів моделі в коді, коментарях чи 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`. diff --git a/data_masking.py b/data_masking.py index 7b85381..775135a 100644 --- a/data_masking.py +++ b/data_masking.py @@ -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__, diff --git a/datamasking/_version.py b/datamasking/_version.py index 9cbad54..1e84f9c 100644 --- a/datamasking/_version.py +++ b/datamasking/_version.py @@ -9,4 +9,4 @@ (і не тягнучи faker під час збірки). """ -__version__ = "3.0.8" +__version__ = "3.0.9" diff --git a/docs/INSTALL.md b/docs/INSTALL.md index 262bd84..4abe0a0 100644 --- a/docs/INSTALL.md +++ b/docs/INSTALL.md @@ -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 ` +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 "`. + +--- + ## Dependencies | Package | Version | Purpose |