# Спецификация: чистый помощник форматирования рублёвых сумм `formatRub`

## Цель

Дать единый чистый помощник для отображения денежных сумм в интерфейсе: на вход —
целое число копеек, на выход — человекочитаемая строка вида `1 234,56 ₽`. Помощник
не обращается к БД, не читает локаль из окружения, не имеет побочных эффектов —
только детерминированное преобразование числа в строку.

## Контракт функции {#D1}

`formatRub(kopecks)` принимает **целое** число копеек (integer, может быть
отрицательным) и возвращает строку. Тысячи рублёвой части разделяются узким
неразрывным пробелом, копейки отделяются запятой и всегда показываются двумя
цифрами, в конце — неразрывный пробел и символ `₽`. Функция чистая: один и тот же
вход всегда даёт один и тот же выход, внешнее состояние не читается и не меняется.

## Краевые случаи {#D2}

- `0` → `0,00 ₽` (ноль показывается явно, не пустой строкой).
- Отрицательная сумма → знак минус перед числом: `-500` копеек → `-5,00 ₽`.
- Не целое (`12.5`) или не число (`NaN`, `null`, строка) → выбрасывается `TypeError`
  с понятным сообщением; молчаливое округление запрещено (потеря копеек недопустима).
- Крупная сумма (`123456789` копеек) → `1 234 567,89 ₽`: разделитель тысяч ставится
  в каждой группе из трёх цифр рублёвой части.

## Конвенция представления {#D3}

Рублёвая и копеечная части получаются делением на 100 без потери точности через
работу с целыми (рубли = `Math.trunc`, копейки = остаток по модулю 100), а не через
плавающую арифметику над результатом деления. Разделитель тысяч — символ U+202F
(narrow no-break space), десятичный разделитель — запятая (российская конвенция),
суффикс валюты — U+00A0 + `₽`.

## Критерий приёмки {#D4}

Набор примеров вход→выход проходит как тесты: `0 → "0,00 ₽"`, `-500 → "-5,00 ₽"`,
`123456789 → "1 234 567,89 ₽"`, `99 → "0,99 ₽"`, `100 → "1,00 ₽"`. Передача `12.5`
и `"abc"` приводит к `TypeError`. Функция не делает ни одного обращения к внешним
ресурсам (проверяется отсутствием импортов кроме чистых утилит).

```verified-context-json
[
  {
    "id": "ctx-pricing-freeze",
    "kind": "EXTRACTED",
    "ref": "tools/cost-pricing.mjs",
    "anchor": "export const PRICING = Object.freeze("
  }
]
```
