В какой-то момент я понял, что живу в режиме вечного поиска. Договор аренды — где-то в почте, чеки на технику — в телеге, настройки ноутбука — в заметках, список задач — в пяти разных приложениях, а важные решения — в голове. Я попробовал собрать это как проект: git, структура папок, метаданные, шифрование, хуки, генерация коротких сводок и нормальные бэкапы. Рассказываю, как я это сделал, где облажался и какие куски кода реально помогают поддерживать порядок.
Почему git вообще подходит для личного архива, а не только для кода
Я раньше думал, что git для жизни звучит как мем. Но потом словил штуку, знакомую любому айтишнику: контекст теряется быстрее, чем кажется. Ты переезжаешь, меняешь телефон, ставишь новую систему, подписываешь новый контракт, и внезапно оказывается, что половина важных деталей лежит в разных местах, да ещё и без версий.
Git хорош не потому что модно, а потому что даёт три конкретные вещи:
История. Не просто финальная версия файла, а цепочка изменений. Ты обновил резюме, добавил новый проект, потом удалил, потом снова вернул. Ты поменял провайдера, тарифы, условия. Ты ведёшь лог своих домашних сетевых настроек, и наконец-то понимаешь, когда и почему оно сломалось.
Дифы. Когда ты обновил список доступов или настройки, сразу видно, что изменилось. И это не магия, это просто удобный взгляд на изменения.
Репликация. Репозиторий можно клонировать, зеркалировать, хранить на разных носителях, проверять целостность, автоматизировать бэкапы. В отличие от условных заметок в приложении, где ты зависишь от сервиса и его экспорта.
И тут вопрос к тебе. У тебя есть хотя бы один файл, который ты точно не хочешь потерять, но не уверен, где он лежит? У меня таких было десятки. Я устал.

Структура репозитория: как не утонуть в папках и перфекционизме
Главная ловушка личного архива в том, что хочется сделать идеально. Красивые схемы, таксономия, стандарты, всё по феншую. Я так и сделал. И, конечно, забросил через неделю.
Потом я сделал две вещи, которые реально спасли проект.
Первая вещь — это папка inbox. Всё новое падает туда вообще без разборки. Получил документ, файл, чек, письмо, экспорт — просто закинул. Разбор потом. Это снимает порог входа.
Вторая вещь — это простое ядро данных. Мне оказалось достаточно трёх слоёв:
Сырьё как есть. Оригинальные файлы, выгрузки, pdf, сканы, всё, что пришло.
Извлечённые факты. Небольшие yaml-карточки, где есть дата, тип, стороны, суммы, срок, ссылки на исходники.
Короткие сводки. Один файл, который я могу открыть на телефоне и быстро понять состояние дел.
Вот как у меня выглядит структура, без претензий на универсальность.
00_inbox
временная свалка, но контролируемая;10_profile
базовая инфа, контакты, важные логины и доступы не храню тут, про это ниже;20_timeline
помесячные записи, что произошло и что изменилось;30_documents
договоры, аренда, страховки, учеба, визы, что угодно;40_finance
бюджеты, подписки, платежи, возвраты, чеки;50_projects
личные проекты, учебные штуки, портфолио, резюме;60_configs
настройки устройств, сети, dotfiles, заметки по железу;90_exports
выгрузки сервисов, чтобы не зависеть от того, что завтра они закроются.
Пример карточки документа, которую реально удобно обновлять.
type: contract
date_signed: 2025-09-01
title: apartment_rent
party_a: me
party_b: landlord
valid_until: 2026-08-31
amount:
value: 25000
currency: TRY
attachments:
- ../30_documents/2025-09-01_rent_contract.pdf
notes:
- deposit equals one month
- utilities excludedТакие yaml-файлы потом можно индексировать, проверять и собирать в сводки.
Приватность и безопасность: личный архив без паранойи не работает
Как только ты начинаешь складывать личные документы в одно место, оно становится супервкусной целью. Тут не надо быть безопасником, чтобы понять, что потери будут неприятные.
Я для себя разложил угрозы максимально просто:
Потеря устройства. Ноут украли, телефон утопил, диск умер.
Случайная утечка. Не тот файл отправил, не ту папку синхронизировал, не туда запушил.
Компрометация облака. Условно, хакнули сервис, утекли токены, или просто кто-то получил доступ к аккаунту.
Что я сделал в итоге.
Репозиторий лежит в зашифрованном контейнере, чтобы физический доступ к диску не решал ничего. Дальше я шифрую критичные файлы перед тем, как отправлять в удалённое хранилище. Не потому что я не доверяю диску, а потому что бэкап вне дома должен быть таким, чтобы его не было страшно потерять.
Пример скрипта на bash, который шифрует выбранные папки с помощью age и кладёт результат в отдельную директорию, чтобы не смешивать с рабочими файлами.
#!/usr/bin/env bash
set -euo pipefail
repo_dir="$(cd "$(dirname "$0")/.." && pwd)"
out_dir="$repo_dir/.encrypted"
recipients_file="$repo_dir/keys/recipients.txt"
mkdir -p "$out_dir"
include_dirs=(
"10_profile"
"20_timeline"
"30_documents"
"40_finance"
)
recipient_args=()
while IFS= read -r r; do
[ -n "$r" ] && recipient_args+=(-r "$r")
done < "$recipients_file"
for d in "${include_dirs[@]}"; do
find "$repo_dir/$d" -type f ! -name "*.age" -print0 | while IFS= read -r -d '' f; do
rel="${f#$repo_dir/}"
out="$out_dir/$rel.age"
mkdir -p "$(dirname "$out")"
age "${recipient_args[@]}" -o "$out" "$f"
done
done
echo "encrypted written to $out_dir"И да, ключи нельзя хранить рядом. Я держу приватный ключ отдельно, плюс резерв на втором носителе. Не суперудобно, зато потом спишь спокойнее.
Автоматизация, чтобы архив не превратился в кладбище файлов
Самое обидное — когда ты красиво начал, а потом перестал поддерживать. Я видел это у себя пару раз. Поэтому я добавил минимум автоматики, который не бесит, но держит дисциплину:
Первое правило: inbox нельзя коммитить. Иначе ты просто легализуешь свалку.
Второе правило: у важных файлов должны быть даты и понятные имена. Без этого поиск превращается в археологию.
Третье правило: метаданные должны проходить проверку. Иначе yaml карточки быстро деградируют.
Вот мой pre-commit hook, который ловит самые тупые ошибки.
#!/usr/bin/env bash
set -euo pipefail
fail() { echo "hook failed: $1" >&2; exit 1; }
staged="$(git diff --cached --name-only)"
echo "$staged" | grep -q '^00_inbox/' && fail "move files out of 00_inbox before commit"
# проверяем, что yaml-карточки документов содержат ключевые поля
changed_yaml="$(echo "$staged" | grep -E '^(30_documents|40_finance)/.*\.yaml$' || true)"
for f in $changed_yaml; do
python3 scripts/validate_cards.py "$f"
done
# запрещаем огромные бинарники в обычном git
changed_bin="$(echo "$staged" | grep -E '\.(pdf|zip|png|jpg)$' || true)"
for f in $changed_bin; do
size="$(wc -c < "$f")"
if [ "$size" -gt 25000000 ]; then
fail "file too big for normal git: $f"
fi
done
echo "ok"А вот валидатор карточек на Python. Очень простой, но уже ловил мне косяки.
#!/usr/bin/env python3
import sys
import yaml
REQUIRED = ["type", "title"]
def die(msg: str) -> None:
print(msg, file=sys.stderr)
sys.exit(1)
path = sys.argv[1]
with open(path, "r", encoding="utf-8") as f:
doc = yaml.safe_load(f)
if not isinstance(doc, dict):
die(f"{path}: root must be a mapping")
for k in REQUIRED:
if k not in doc or doc[k] in (None, ""):
die(f"{path}: missing {k}")
# опциональная проверка даты, если она есть
for date_key in ("date_signed", "date", "paid_at"):
if date_key in doc and isinstance(doc[date_key], str):
if len(doc[date_key]) < 10:
die(f"{path}: suspicious date in {date_key}")
print(f"{path}: ok")Честно, эти две штуки сделали больше, чем любые красивые идеи. Потому что поддержка — это рутина, а рутина любит простые барьеры.
Тяжёлые файлы и целостность: LFS, манифесты и почему хэши спасают нервы
В какой-то момент в архиве появляются сканы, фото, большие pdf, экспорты, иногда даже видео. Если это всё бездумно коммитить, репозиторий начнёт пухнуть и умирать. Я пошёл по гибридной схеме:
Текст, yaml, небольшие документы живут в обычном git.
Крупные бинарники отправляю в git lfs, чтобы клон не превращался в скачивание всего мира.
Самые тяжёлые штуки, типа сырых экспортов и архивов, держу во внешнем vault, а в репо храню индекс и контро��ьные суммы.
Контрольные суммы вообще underrated вещь. Когда ты переносишь архивы между дисками, ты не хочешь гадать, битый файл или нет. Ты хочешь проверить и забыть.
Скрипт на bash, который делает sha256 манифест для папки.
#!/usr/bin/env bash
set -euo pipefail
dir="${1:-90_exports}"
out="${2:-90_exports_manifest.sha256}"
find "$dir" -type f -print0 | sort -z | xargs -0 sha256sum > "$out"
echo "written $out"А индекс файла я веду так.
type: export
date: 2026-01-10
source: bank_app
scope: transactions_2025
archive:
path: /vault/personal/exports/2026-01-10_bank_2025.csv.zst
sha256: 9b1c0f3d...cafe1234
notes:
- contains categories and merchant names
- imported into local ledgerВыглядит занудно, но это ровно та занудность, которая потом экономит часы. Особенно когда прошло полгода и ты вообще не помнишь, что где лежит.
Сводки и поисковый кайф: один файл, который заменяет миллион вкладок
Самая приятная часть личного архива — это когда ты перестаёшь искать. Не в смысле, что всё идеально, а в смысле, что у тебя появляется понятная точка входа.
Я сделал себе генератор сводки. Он берёт profile, последние изменения из timeline, список активных подписок, ближайшие даты продлений, и делает один markdown-файл. Его можно открыть на телефоне, перед поездкой, перед переездом, перед любым мутным событием, когда надо быстро вспомнить контекст.
Вот пример генератора на Python. Он специально без наворотов, чтобы работал везде.
#!/usr/bin/env python3
import os
import glob
import yaml
from datetime import datetime
REPO = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
def load_yaml(path: str):
with open(path, "r", encoding="utf-8") as f:
return yaml.safe_load(f)
def newest_files(pattern: str, limit: int = 5):
files = glob.glob(os.path.join(REPO, pattern))
files.sort(reverse=True)
return files[:limit]
profile = load_yaml(os.path.join(REPO, "10_profile", "profile.yaml"))
lines = []
lines.append("# Личный дайджест\n")
lines.append(f"Обновлено: {datetime.now().strftime('%Y-%m-%d')}\n\n")
lines.append("## Контакты и базовое\n")
for k in ("name", "city", "email"):
if k in profile:
lines.append(f"- {k}: {profile[k]}\n")
lines.append("\n## Последние события\n")
for p in newest_files("20_timeline/*.md", 3):
base = os.path.basename(p)
lines.append(f"\n### {base}\n")
with open(p, "r", encoding="utf-8") as f:
chunk = f.read().strip().splitlines()[:20]
lines.extend([x + "\n" for x in chunk])
lines.append("\n## Подписки и платежи\n")
subs_path = os.path.join(REPO, "40_finance", "subscriptions.yaml")
if os.path.exists(subs_path):
subs = load_yaml(subs_path).get("active", [])
for s in subs:
lines.append(f"- {s.get('name','unknown')} next {s.get('next_charge','?')} {s.get('amount','')}\n")
out = os.path.join(REPO, "10_profile", "digest.md")
with open(out, "w", encoding="utf-8") as f:
f.write("".join(lines))
print("written:", out)И вот тут у меня в конце дайджеста появляется маленький ритуал, который неожиданно оказался важнее всех скриптов. Я записываю коротко и суть.
Что сейчас самое слабое место? Где я точно забуду или затяну, если не ткнуть себя носом? Какие две вещи надо сделать на этой неделе, чтобы потом не разгребать месяц? Что я откладываю уже третий раз подряд? И есть ли что-то, что пора выкинуть из архива, потому что оно только захламляет и создаёт ложное ощущение контроля?
Прикол в том, что когда это пишешь рядом с фактами, оно перестаёт быть абстрактным. Не просто «надо бы заняться документами», а конкретно «обновить контакты», «продлить подписку», «закинуть экспорт», «проверить, что бэкап вообще открывается, а не лежит для галочки». Иногда я там же оставляю себе одну тупую, но полезную заметку: где я последний раз сломал систему. Например, когда кинул что-то в inbox и забыл разобрать, или когда сохранил файл как final_final2.pdf и сам же потом матерился.
И это, честно, очень разгружает голову. Потому что раньше всё это было в фоне: я помню, что где-то что-то важно, но не помню, что именно, и оно зудит. А тут ты открываешь один файл, видишь картину, понимаешь, что у тебя под контролем, а что нет, и закрываешь без ощущения вечного незавершённого квеста.
Если захочешь попробовать, не начинай с криптографии и хуков. Начни с простого: сделай репо, папку inbox, один профильный файл и один таймлайн за месяц. Поймай удовольствие от того, что ты что-то нашёл за 10 секунд, а не за 10 минут. А потом уже докрутишь шифрование, проверки и генераторы. Эта штука реально растёт постепенно, и в этом её кайф: ты просто перестаёшь терять важное.
