# Правила ведения каталога

Эти правила действуют для всего репозитория. Перед изменением метаданных сверяйся
со схемами в `schema`. Не добавляй поля, которых нет в схеме.

## Структура

- Все категории и программы находятся внутри корневой папки `catalog`.
  `catalog/index.md` описывает корневую категорию.
- `catalog/files.yaml` содержит размеры и SHA-256 всех файлов программ. Он
  создаётся командой `pnpm fill-metadata` и вручную не редактируется.
- Каждая категория и каждая программа внутри `catalog` находятся в собственной
  папке и содержат ровно один файл `index.md`.
- Вложенность категорий не ограничена. Дочерние категории и программы
  определяются по файловой структуре и не перечисляются в индексе категории.
- Имя папки — стабильный идентификатор. Используй строчные латинские буквы,
  цифры, дефис и подчёркивание.
- В папке программы все загружаемые файлы находятся в `files`, а скриншоты — в
  `img`.
- Не создавай отдельные файлы или папки метаданных для версий. Все версии
  описываются в `versions` YAML Front Matter единственного `index.md` программы.
- Папки без `index.md`, например `schema`, `files` и `img`, не являются
  категориями.

## Формат index.md

Каждый `index.md` состоит из YAML Front Matter между строками `---` и
обязательного Markdown-тела. Front Matter содержит только метаданные, а тело —
описание категории или программы. Поле `description` в Front Matter не
используй.

## YAML категории

Используй следующие поля Front Matter и сохраняй их порядок:

```md
---
format: 1
type: category
name: Русское название категории
order: -10
---

Описание категории на русском языке.
```

`order` — необязательное целое число для сортировки соседних категорий. Меньшее
значение выводится раньше, отсутствие поля равнозначно `order: 0`. При равных
значениях категории сортируются по названию. Располагай `order` после `name`.

## YAML программы

Поля программы располагай в следующем порядке:

1. `format: 1` — обязательное поле.
2. `type: program` — обязательное поле.
3. `name` — обязательное официальное название программы.
4. `order` — необязательное целое число для сортировки соседних программ.
5. `summary` — обязательное короткое описание программы на русском языке.
6. `targets` — необязательный непустой массив целевых платформ.
7. `homepage` — необязательный URL домашней страницы.
8. `source` — необязательный URL исходного кода.
9. `forum` — необязательный URL темы программы на форуме.
10. `author` — необязательное имя автора или название организации-разработчика.
11. `screenshots` — обязательный массив путей; используй `[]`, если изображений
   нет.
12. `versions` — обязательный непустой массив версий.
13. `additional_files` — необязательный массив файлов, не привязанных к версии.

`order` работает так же, как у категорий: меньшее значение выводится раньше,
отсутствие поля равнозначно `order: 0`. При равных значениях программы
сортируются по названию. Располагай `order` после `name`.

После закрывающей строки `---` размести обязательное подробное описание
программы на русском языке в обычном Markdown. Не добавляй в тело заголовок с
названием программы: `name` уже содержит название, а генератор сам создаёт
заголовок страницы.

Новые версии добавляй в начало `versions`, от новых к старым. Каждая версия
имеет такой вид:

```yaml
- version: "1.2.0"
  status: current
  released: "2007-08-14"
  files:
      - path: files/program-1.2.0.zip
        description: Назначение файла на русском языке
        platform: win32
```

Поля версии располагай в порядке `version`, `status`, `released`, `description`,
`files`. Обязательны только `version` и непустой массив `files`. Необязательный
`status` принимает `current` для актуальной версии и `archived` для устаревшей,
сохранённой ради архива. Если статусы используются у программы, указывай их у
всех её версий. Поле `released` добавляй только при наличии достоверной даты.
Не переноси changelog в `description` версии и не добавляй это поле для полноты.
Оно допустимо только в особом случае, когда нужно зафиксировать существенное
ограничение, которое нельзя выразить номером версии или описанием конкретного
файла.

Необязательное поле файла `platform` принимает одно из значений: `win32`,
`win64`, `dos`, `java` или `j2me`. Для Windows разрядность входит в название
платформы; отдельное поле `architecture` не используется.

Поля файла располагай в порядке `path`, `description`, `platform`. Размеры и
SHA-256 не добавляй в индекс программы: они хранятся только в автоматически
создаваемом `catalog/files.yaml`.

`description` файла добавляй только для существенной информации: отличия от
других вариантов, особого назначения или дополнительных материалов в архиве.
Не повторяй в нём название программы, номер версии, имя файла или тип
«программа», «дистрибутив», «исполняемый файл».

### Короткое описание

`summary` выводится рядом с названием программы в списке категории. Напиши
естественное краткое описание, по которому понятно, что это за программа, для
чего она нужна и с какими телефонами или форматами работает. Опирайся на полное
описание и технический смысл программы, а не на единый шаблон. Не используй
оценочные усилители вроде «комплексная», «универсальная», «мощная» или
«полноценная». Храни `summary` во Front Matter и не вычисляй его автоматически
из первого абзаца Markdown-тела.

### Целевые платформы

`targets` описывает платформы телефонов и программные среды, с которыми работает
программа. Допустимые значения: `higold`, `egold`, `sgold`, `odm`, `brew`.

Не выводи платформу только из номера серии телефона. Если совместимость
достоверно не установлена, не добавляй `targets`. Всегда перечисляй платформы
явно; общего значения для всех платформ нет. У общей программы, не связанной с
платформами Siemens, например редактора аудио или конвертера файлов, `targets`
не указывай: такая программа выводится в корневой категории. Это относится и к
конвертерам форматов конкретных моделей, если они работают только с локальными
файлами и не взаимодействуют с телефоном.

J2ME не является значением `targets`. Мидлеты размещай в корневой категории
`catalog/j2me` без `targets`; у их файлов используй `platform: j2me`.

Файлы, которые подходят ко всем версиям или существуют отдельно от релиза,
помещай в `additional_files`, а не внутрь случайной версии:

```yaml
additional_files:
  - path: files/manual.pdf
    description: Руководство пользователя
```

## Текст и достоверность

- Названия категорий, описания программ, версий и файлов пиши на русском языке.
  Официальные названия продуктов и технологий не переводи.
- Если доступно авторское описание, сохраняй его лексику, тон, порядок мыслей и
  характерные формулировки. Не переписывай текст в нейтральном справочном стиле
  и не заменяй авторские термины своими. Исправляй только оформление Markdown,
  явные опечатки и очевидные грамматические ошибки.
- Сохраняй полноту исходного описания. Не сокращай перечень возможностей до
  общего пересказа и не удаляй значимые технические подробности.
- Не используй нейросетевой слоп: пустые вводные фразы, канцелярит, тавтологии,
  эвфемизмы и пересказ очевидного из названия. Пиши коротко и прямо, используй
  принятые технические термины. Например, пиши «кряк», а не «средство запуска
  без аппаратного ключа», и «эмулятор для Siemens Mobility Toolkit», а не
  «пакет, воспроизводящий программное окружение телефона».
- Основное описание находится в Markdown-теле `index.md`; пиши его как обычный
  Markdown без YAML-отступов и литеральных блоков. Поля `description` версий и
  файлов остаются обычными строками YAML. Не вставляй HTML-разметку.
- Каждый пункт Markdown-списка начинай с заглавной буквы.
- Не выдумывай даты, ссылки, возможности или платформы. Неизвестное
  необязательное поле лучше не добавлять.
- Сначала пытайся определить версию по странице, имени файла, README и
  метаданным бинарника. Если номер версии нигде не указан и достоверно получить
  его невозможно, используй каталоговое значение `version: "1.0"`. Не выводи
  номер версии из даты сборки.
- Если источник содержит только текущую версию, добавляй только её. Не ищи
  более ранние архивы в Wayback Machine без отдельного указания пользователя.

## Пути и файлы

- Все пути относительны папке программы и используют `/`.
- Путь загружаемого файла начинается с `files/`; путь скриншота — с `img/`.
- Абсолютные пути, `..` и обратная косая черта запрещены.
- Каждый путь из YAML должен указывать на существующий файл.
- Один файл нельзя одновременно указывать в `versions` и `additional_files`.
- Дистрибутивы и отдельные исполняемые файлы храни в ZIP, совместимом со
  встроенным распаковщиком Windows XP: методы Store или Deflate, без шифрования
  и Zip64. Не добавляй RAR, 7z и незапакованные EXE.
- RAR, 7z, ZIP, отдельные EXE и распакованные дистрибутивы перепаковывай только командой
  `pnpm repack-archive <путь>`. Она создаёт рядом проверенный ZIP и сохраняет
  имена, содержимое и время изменения файлов. По умолчанию исходник остаётся;
  `--replace` используй только когда его нужно удалить после успешной проверки.
  Для другого пути назначения используй `--output <путь>`. Папку-источник
  скрипт упаковывает целиком; `--replace` для папок запрещён.
- Временные файлы задачи сохраняй в `/tmp/codex/<task_name>`. Для перепаковки
  передавай этот каталог через `--temp-dir <путь>`.
- После перепаковки замени путь в `index.md` и выполни
  `pnpm fill-metadata`, чтобы обновить `catalog/files.yaml`.
- Архивы должны проходить через Git LFS согласно `.gitattributes`. Остальные
  файлы хранятся в обычном Git.

## Стиль YAML

- Кодировка — UTF-8, окончания строк — LF, отступ — два пробела, табуляция
  запрещена.
- Максимальная длина строки во Front Matter — 140 символов. Короткое строковое
  значение, включая `summary`, не переноси, если оно помещается в этот лимит.
- Версии и даты всегда заключай в двойные кавычки.
- Дата имеет формат `YYYY-MM-DD`.
- Не используй YAML-теги, anchors, aliases и merge keys.
- Не допускай неизвестных полей и дубликатов в массивах.

## Проверка

Перед завершением изменения:

1. Проверь YAML Front Matter всех затронутых `index.md` безопасным YAML-парсером
   и убедись, что Markdown-тело не пустое.
2. Проверь их по `schema/index.schema.json` валидатором JSON Schema Draft 2020-12,
   если он доступен.
3. Выполни `pnpm fill-metadata`, затем `pnpm fill-metadata:check`. Команда
   пересобирает `catalog/files.yaml` для всего каталога.
4. Для каждого нового архива выполни `git check-attr filter -- <путь>` и
   убедись, что значение равно `lfs`.
5. Выполни `git diff --check`.
