Синтезируем контекст из полей самой 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>
3.4 KiB
3.4 KiB
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проходит