Files
jellybit/openspec/changes/archive/2026-07-07-magnet-context-extraction/tasks.md
T
avandClaude Opus 4.8 e9ec26d09a Ingest: контекст распознавания из полей magnet-ссылки
Синтезируем контекст из полей самой magnet-ссылки (dn, xl, tr/xs, kt) без
сети и дополняем им текст от транспорта: пользовательский текст первым, при
пустом — синтез единственный. Обогащённый контекст идёт только в
download.Context (его читают recognition и веб-UI); вход namer и отображаемое
имя не меняются — строки-факты (Размер:/Трекер:) в display_name не текут.

- magnet.Info: поля ExactLength/Sources/Keywords + Info.Context() (синтез,
  отсев dn-заглушек *-topic-<id>, домен трекера, человекочитаемый размер)
- Parse устойчив к ссылке в процент-кодировке (разовый QueryUnescape)
- ingest: mergeContext → download.Context, namer на сыром req.Context
- Влита дельта capability ingest в openspec/specs, change заархивирован

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-07 20:38:01 +03:00

3.4 KiB
Raw Blame History

1. Парсинг полей magnet

  • 1.1 Расширить magnet.Info полями ExactLength int64 (из xl), Sources []string (из xs), Keywords []string (из kt)
  • 1.2 В Parse заполнить новые поля из vals; xl парсить строго как десятичное целое (байты), при ошибке — оставлять 0 (best-effort)
  • 1.3 Тесты парсинга: magnet с xl/xs/kt, гибридный, невалидный xl, отсутствие полей
  • 1.4 Устойчивость Parse к ссылке, скопированной целиком в процент-кодировке (magnet%3A%3F…): разовый QueryUnescape на фолбек-пути + тест; тест на реальной рутрекер-ссылке (dn с кириллицей → Context)

2. Синтез контекста из полей

  • 2.1 Реализовать func (Info) Context() string (или SynthContext) в пакете magnet: строки-факты через \n — название (dn, если не заглушка), Размер: из xl (человекочитаемо), Трекер:/происхождение из домена tr/xs, Ключевые слова: из kt
  • 2.2 Детектор заглушки dn вида *-topic-<id> (не включать как название)
  • 2.3 Helper нормализации домена трекера/источника из URL (tr/xs)
  • 2.4 Тесты синтеза: содержательный dn; dn-заглушка rutracker-topic-*; только размер; только домен; все поля вместе; пустой Info → пустая строка; проверить отсутствие сетевых вызовов (чистая функция)

3. Слияние в ingest

  • 3.1 В Ingest собрать enrichedContext = join(nonEmpty(req.Context, info.Context())) — пользовательский текст первым, синтез следом
  • 3.2 Класть enrichedContext только в download.Context (вместо сырого req.Context); вызов namer.DeriveName(ctx, req.Context, info.DisplayName) оставить как есть — namer синтез НЕ получает
  • 3.3 Тесты ingest: magnet-only (пустой req.Context) → download.Context синтезирован; непустой текст + поля → оба присутствуют, текст первым; пустой текст и бедный magnet → пустой контекст, приём проходит
  • 3.4 Регресс-тест: голый rutracker-magnet (dn=rutracker-topic-<id>, только tr, без текста) → download.display_name НЕ равен Трекер: … (именование не деградирует), а download.Context содержит домен трекера

4. Транспорты и проверка

  • 4.1 Убедиться, что приём голого magnet (пустой контекст) штатно проходит в httpapi и tgbot (при необходимости — тест на пустой context)
  • 4.2 task test и task lint зелёные
  • 4.3 openspec validate magnet-context-extraction --strict проходит