Files
shater/SPECS
omar a57717dabb
release / aarch64_cortex-a53 (push) Successful in 3m43s
release / x86_64 (push) Successful in 3m30s
release / apk aarch64_cortex-a53 (push) Successful in 5m11s
release / apk x86_64 (push) Failing after 5m8s
release / release apk (push) Has been skipped
release / release (push) Successful in 12s
health plan S7: docs, contract comments, SPEC 019 update
- lx-changelog: health board + observatory + global probe + sub cache entry
- DECISIONS.md: D18 board vs delete-and-overlay, D19 observatory vs sweep, D20 global probe settings
- contract comments: urltest.go CheckOutbounds (fast circuit) + observatory.go loop (background circuit + freshness gate) document the two-circuit split
- SPEC 019: dial-error section updated - slots still not moved, but board verdict demotes dead slot on next pick + retry (§5.B); sticky/replace-in-slot/never-shrink invariants preserved
2026-07-24 18:30:48 +03:00
..

SPECS — sing-box-lx (Spec Kit)

Все задачи — папки NNN-NAME. Внутри: SPEC.md → PLAN.md → TASKS.md → IMPLEMENTATION_REPORT.md.

Имя папки: NNN-NAME

Часть Значение Расшифровка
NNN 001, 002, … Сквозной номер — стабильный якорь, не меняется никогда
NAME UPPER_SNAKE Название

Имя папки не несёт тип/статус: они меняются по ходу задачи, а имя должно оставаться стабильным (на него ссылаются из кода, доков и сабмодуля). Ссылки давай короткой формой SPECS/NNN-NAME — она переживёт смену статуса.

Тип и статус — в шапке SPEC.md + Roadmap

Источник правды по типу/статусу — таблица-шапка в начале SPEC.md каждой задачи; Roadmap ниже её агрегирует.

| Поле | Значение |
|------|----------|
| Тип | F (feature) \| B (bug) \| Q (question/исследование) |
| Статус | N (new) \| O (open) \| W (wait) \| C (complete) |

Файлы внутри папки

Файл Назначение
SPEC.md Что и зачем — проблема, требования, критерии приёмки
PLAN.md Как строить — архитектура, изменяемые файлы, зона касания upstream
TASKS.md Чеклист по этапам
IMPLEMENTATION_REPORT.md Отчёт после реализации
HISTORY.md Хронология: как делали раньше, почему переделали. Только при смене архитектуры фичи (см. правило структуры ниже)

Структура SPEC.md — актуальное состояние сверху, НЕ хронология

Правило: SPEC.md описывает ТЕКУЩУЮ (актуальную) архитектуру фичи в первую очередь. Порядок разделов — от актуального состояния к деталям, НЕ по хронологии разработки.

  • Верх SPEC.md = как фича устроена СЕЙЧАС (актуальная архитектура), затем детали/контракт/критерии.
  • НЕ вести SPEC.md как дневник («сначала сделали так, потом в rc.9 исправили…»). Пометки вида «ИСПРАВЛЕНО в rc.N», «прежнее утверждение неверно», отвергнутые подходы — НЕ в SPEC.md.
  • Когда архитектура фичи МЕНЯЕТСЯ (переделали механизм): SPEC.md переписывается под новое состояние, а старое состояние + обоснование смены (как делали, почему это оказалось неверно, почему выбрали новое) выносятся в HISTORY.md этой же папки.
  • Читатель SPEC.md должен понять, как всё работает СЕЙЧАС, не продираясь через историю решений. История — по запросу, в HISTORY.md.

Конфигурация фич

Пользовательский конфиг XHTTP и AmneziaWG 2.0 (поля + примеры) — ../docs-lx/lx-config.md.

Корень SPECS

Файл Назначение
CONSTITUTION.md Неизменяемые принципы, приоритеты, запреты
IMPLEMENTATION_PROMPT.md DoD, git/ребейз-ритуал, контракт выхода

Workflow

  1. Папка SPECS/NNN-NAME/ (следующий номер). В шапке SPEC.md — Тип + Статус: N.
  2. SPEC.md → PLAN.md → TASKS.md.
  3. Реализация по TASKS с учётом IMPLEMENTATION_PROMPT и CONSTITUTION.
  4. IMPLEMENTATION_REPORT.md, DoD-чеклист, статус в шапке SPEC.md и Roadmap → C.

Roadmap (план задач)

# Задача Статус Суть
001 FORK_BOOTSTRAP C Remotes, ветка lx, Makefile.lx, версия -lx (ldflags), CI-скелет, lx-test/config — ✅ собрано/проверено
002 XHTTP_CLIENT_TRANSPORT C ✅ live-validated против Xray (3x-ui): packet-up/auto работают (handshake+DNS+HTTPS+download); stream-one — был баг, исправлен в 011
003 AWG2_CLIENT_ENDPOINT C ✅ Функционален, проверен живым AWG2-сервером (handshake+keepalive+трафик). merged-форк Leadaxe/wireguard-go (sagernet+обфускация) через submodule; S1–S4/H1–H4/I1–I5
004 BUILD_CI_RELEASE C ✅ Makefile.lx/libbox-теги, дешёвый CI (lint+build-check на push; cross×6+AAR на dispatch), lx-release.yml (релиз v1.13.13-lx.3 опубликован — 6 desktop + 2 AAR), lx-rebase.yml (авто-ребейз → PR/issue, демо зелёное)
005 AWG2_RANGED_MAGIC_HEADERS C ✅ Проверено живым awg2-сервером с ranged-конфигом (handshake+трафик). Диапазонные H1–H4 ("N-M") из awg2-экспортов: option.MagicHeader (number|string) → spec-строка в IpcSet; vendored wireguard-go уже умел
006 LINUX_MUSL_STATIC_ROUTER_BUILDS C ✅ CI-приёмка 4/4 арки статикой (amd64/arm64/armv7/mipsle-softfloat, statically linked, libdl=0, naive сохранён). musl-сборки под роутеры по подобию upstream build.yml (cronet-go + Chromium musl-toolchain, with_musl). Чинит #1 (libdl.so.2 на AsusWRT + armv7). CI-only, без Go-кода
007 AWG_OVER_WIREGUARD_DETOUR_GUARD C ✅ Код+тесты+DoD, Start-guard field-verified (Android lx.9). Bug в 003: AWG-нода с detour на WireGuard-туннель (плоский WG или AWG) вешает ядро на Android (AWG внутри WG). Два дополняющих guard'а: Start-guard (Endpoint.Start, статическая транзитивная detour-цепь — device не поднимается) + selector-guard (SelectOutbound — при переключении селектора на WG гасит AWG-потребителей до переключения, через ConsumersOf). Оба — вариант B (ядро живёт, узел не встаёт, ошибка в лог). Ленивый dialer-guard (lx.8) откачен. detour на VLESS и WG→AWG — разрешены. Чинит #2
008 AWG_JUNK_PARAM_VALIDATION C ✅ Код+тесты+DoD. Bug в 003 (найден при 007): jmin > jmax паникует rand.Int в amneziawg-go (краш в timer-горутине). validateJunk в awgIpcLines отвергает на уровне конфига (check/старт), без паники. Узко — только краш-кейс; jc-несогласованность осознанно не трогаем (минимальный дифф, совместимость). Чинит #3
009 WIRESOCK_MASQUERADE_PROFILES C ✅ Код+тесты+DoD; механизм проверен вживую (туннель + трафик на 009), релиз v1.13.13-lx.11. WireSock-стиль id/ip/ib (домен/протокол/браузер) — декларативный сахар над I1 CPS. Профили quic (1-RTT short header) / dns (EDNS OPT response) / stun (Binding Success Response) / sip (200 OK response), структуры портированы из open-source WireSock amneziawg-proxy/src/transform.rs (MIT). Механизм — I1 only (S1–S4 невозможен против WARP, сабмодуль не трогаем). id обязателен только для dns/sip (там идёт на провод), для quic/stun опционален. Строгая LDH-валидация домена (security-граница: инъекция в SIP/DNS). ib — без JA3-fingerprint (честно задокументировано). Все профили приняты реальным newObfChain; sing-box check зелёный; адверсариальный ревью (6 агентов) — 0 находок
010 WG_ENDPOINT_GRO_SPLIT_BRAIN C ✅ Корень подтверждён на железе, фикс верифицирован (download 0.44→20.7 Mbps), вмержен в lx (lx.14). Bug: WG-endpoint без detour на Android режет download (GRO split-brain — UDP_GRO включён, а receive-путь linux-only). Фикс — гейт UDP_GRO за !android в сабмодуле wireguard-go (conn/). UDP/WG-only
011 XHTTP_STREAM_ONE_DOWNLINK C ⚠️ Принято на синтетике; лайв НЕ прогонялся (нет reality+xhttp ноды). Bug в 002 (жалоба): vless+reality+xhttp+mode:auto не работал. Корень (сверено с Xray + issue #5635 + hiddify): stream-one слал <path>/<sessionId>, а Xray-сервер роутит stream-one только при пустом sessionId → downlink не-VLESS → unknown version. Фикс: голый путь без sessionId; mode:auto+reality → stream-one (детект reality по имени типа, без with_utls-зависимости). Юнит-тесты (URL-layout + reality-детект), check, сборки зелёные. Ветка lx-xhttp-streamone, в lx не влито; лайв — открытый TODO в REPORT
012 TCP_DOWNLINK_STALL_ZOMBIE_CONNS C ⚠️ НЕ воспроизводится на lx.14 (статус закрытия — «not reproducible»). Симптом (↑517 ↓0, WhatsApp/Telegram «висят») наблюдался на РАЗНЫХ нодах, включая WG → зонтик над «↓0»-сталлом, не один баг. WG-долю закрыл 010 (UDP/WG-only). Для не-WG (VLESS/reality) отдельного код-фикса нет — симптом сейчас не воспроизводится без подтверждённого объяснения. Артефакты: зонд LX_CONN_TRACE (не прогнан в бою), PROBE.md
013 PACKAGE_NAME_REGEX_RULE_ITEM C ✅ Код+тесты, сборки/vet/gofmt зелёные. Бэкпорт апстрим-фичи 1.14 (941ce58b) на базу 1.13.13 без полной миграции: rule-item package_name_regex (regex-матчинг Android-пакета) для route/DNS/headless. Новый route/rule/rule_item_package_name_regex.go + поля/регистрация/cond в 6 файлах роутинга. Хунк RuleSetVersion5 из коммита НЕ переносился (это rule-set v5, не фича). Полная миграция на 1.14 отложена до v1.14.0 stable (feasibility: ~1,5–2 дня, риск — ребейз AWG-подмодуля; lx-rebase.yml сам исключает alpha)
014–021 (см. шапки в SPECS/NNN-*/SPEC.md) C Command-протокол RPC (014/015), connections-мьютекс (016), Connection.Detour (017), DNS-query-стрим (018), URLTest пул/sticky (019), multi-WG idle-suspend (020), MASQUE CONNECT-IP outbound (021). Источник статуса — шапка каждого SPEC.md
023 MUSL_TOOLCHAIN_MIRROR C 🛠 Durable-зеркало Chromium musl-тулчейна. snapshot.debian.org периодически 503-ит и блокирует релиз (v1.14.0-lx.2-rc.1 падал дважды на нём; actions/cache промахивается из-за ref-scoping тегов). Producer-workflow (lx-musl-toolchain-mirror.yml) заливает собранный тулчейн 4 арок в release-ассет musl-toolchain-cache; lx-release.yml восстанавливает его на cache-miss ДО фолбэка на snapshot. Источники: actions/cache → lx-mirror → snapshot. Обе workflow lx-owned, upstream-дифф нулевой. Зеркало заполнено, restore проверен
022 LX_DEEP_AUDIT C 🔍 Аудит-исследование + ремедиация. Многоагентный аудит всей LX-дельты по 10 осям + адверсариальная верификация каждой находки. 32→27 подтверждено (0 critical, 1 high, 1 medium, 6 low, 19 nit), 5 опровергнуто. Исправлено 24/27 (ветка lx-spec022-audit-fixes): P0 #1 masque h2 CONNECT висел навечно (ctx игнорировался); P1 #2 idle-suspend воскрешал guard-suspended AWG (hang ядра Android); + все P2/P3. Осознанно пропущены #12/#17/#18 (санкционированные компромиссы / ребейз-цена). Реестр + ремедиация в SPEC.md
024 RUNTIME_LOOP_GUARD DEFERRED 🔁 Guard от runtime-колец в detour/selector. Статическое кольцо ядро отклоняет на старте (circular outbound dependency); собранное в рантайме через SelectOutbound — нет защиты → fatal stack overflow, падение процесса. Проработана событийная модель E1–E5 + topologyMu-линеаризация гонки; адверсарская проверка (7 агентов): deadlock/false-positives HOLDS, но TOCTOU BREAKS — даже полный ядерный guard негерметичен без покрытия endpoint-mgr/Remove/history-side-channels и без устранения pointer↔tag расхождения после рантайм-Create. Решение (2026-07-06): защита на уровне UI (LxBox), ядро не трогаем. Design record: SPEC.md

Вне этого репозитория: потребление ядра лаунчером (singbox-launcher) — парсинг type=xhttp в реальный XHTTP-транспорт (сейчас 023 маппит его в httpupgrade), AWG-поля в визарде, замена bin/sing-box. Это отдельные задачи в репозитории лаунчера.