Files
soothe2-re/AGENTS.md
T

9.3 KiB
Raw Blame History

AGENTS.md — runbook for AI agents working in this repo

Статус → README.md:13 (единственный источник TOTAL). Этот файл — только runbook: сборка, метрика, env-флаги, tooling hazard. Полный журнал — handoff/NOTES_LEVEL_INDEX.mdhandoff/NOTES_LEVEL.md (живая голова) + handoff/archive/. Карта метода — handoff/BLOCKMAP_529fe0.md. ЭТОТ ФАЙЛ ЧИТАЙ ПЕРВЫМ.

Золотое правило (обязательно)

  1. Цель — bit-exact реверс кода, НЕ эмпирическая подгонка кривых. Каждый параметр должен иметь источник (decomp адрес / live-таблица), а не быть подогнанным числом. Если берёшь эмпирику — явно пометь и занеси в «осталось».
  2. Источник истины — декомпиляция (decomp_funs.txt, decomp_funs2.txt, handoff/nls_dasm/*.dis) и live-снимки (/tmp/snap_rt.bin). Обновлять заметки при любом новом декоде.
  3. Команды через rtk (токен-фильтр), включая цепочки &&.

Сборка и тесты (канон)

# собрать библиотеку + framed_test (bridge, 44.1k) + render48k (структурная цепь, 48k/4096)
cmake -S dsp -B dsp/build
cmake --build dsp/build --target framed_test render48k

# bridge-рендер (N=2048, hop=512, SR 44100, sqrt-Hann OLA)
# формат полосы: fc,q,sens,level_scale  (одна полоса в comma-форме)
./dsp/build/framed_test /home/m/soothe-bt/tone1kq.wav /tmp/o.wav 678.7611083984375,0.99999785,12,600
# многополосный: через отдельные аргументы fc q sens scale  (см. framed_test.cpp)

# структурный рендер (внутренняя сетка 48000/4096: resample -> FUN_180529fe0 chain -> resample)
./dsp/build/render48k /home/m/soothe-bt/tone1kq.wav /tmp/o48.wav 1000,0.99999785,12

# корпусные прогонки (62 случая, честная 24-bit метрика)
python3 scripts/corpus.py                                            # bridge + guard --compare
python3 scripts/corpus_structural.py                                 # структурная цепь
python3 scripts/corpus_structural.py --vs-bridge scripts/baseline_bridge.json

# отдельные модули (bit-exact черные проверки)
cmake --build dsp/build --target twin_check tables_check fftconv_check vlog_check leveltrack_check levelpath_check fn529fe0_check exp2_check
./dsp/build/twin_check        # float-parity twin-резонатора

TOOLING HAZARD: cmake пропускает пересборку при изменении исходника в ту же секунду — параметрические свипы молча гоняют STALE бинарь. Протокол: touch исходника перед сборкой + проверять свежесть mtime бинаря (пример: /tmp/sweep_fresh.py паттерн в NOTES_LEVEL:21a).

Метрика (tone-cmp, Goertzel stead-state)

Сравнивать тримкнутый выход (длина = длина входа) с референсом *_ref.wav / t1kq_b1f_*:

# ref: t1kq_b1f_678.7611083984375.wav (или t1kq_b1f_1000.wav и т.д. по fc полосы)
# вход: tone1kq.wav (тон 1000 Гц)
import wave, numpy as np
def load(p):
    w=wave.open(p,'rb'); n=w.getnframes(); d=w.readframes(n)
    return np.frombuffer(d,dtype=np.int16).astype(np.float64).reshape(-1,w.getnchannels()).mean(1)/32768
def ta(x,f,sr=44100):
    x=x[-int(0.75*sr):]; t=np.arange(len(x))/sr; w=2*np.pi*f
    return np.hypot(2*np.sum(x*np.cos(w*t))/len(x), 2*np.sum(x*np.sin(w*t))/len(x))
def db(a): return 20*np.log10(max(a,1e-9))
inp=load('/home/m/soothe-bt/tone1kq.wav')
out=load('/tmp/o.wav')
ref=load('/home/m/soothe-bt/t1kq_b1f_678.7611083984375.wav')   # fc полосы = 678.76
err = db(ta(out,1000)/ta(ref,1000))     # err в dB, цель <0.1

Тестовый корпус (/home/m/soothe-bt/, вне git): tone1kq.wav(вход), t1kq_b1f_<fc>.wav (рефы), comb.wav/comb_ref.wav (мультиполосный).

Структура ключевых файлов

  • dsp/framed_model.{cpp,hpp} — C++ порт mask-apply цепи (ГЛАВНЫЙ файл).
  • dsp/render48k.cpp — пайплайн 48000/4096 (resample → chain → resample).
  • dsp/twin.{cpp,hpp} — twin FUN_180535880 (float-parity).
  • scripts/corpus.py / corpus_structural.py — харнессы + guard --compare.
  • handoff/NOTES_LEVEL.md — живой журнал (голова 24mm5+, хвост → archive/).
  • handoff/NOTES_LEVEL_INDEX.md — оглавление журнала.
  • handoff/BLOCKMAP_529fe0.md — блок-карта FUN_180529fe0.
  • handoff/nls_dasm/ — 134 дизассембла.

Env-флаги экспериментов (актуальные)

флаг действие
RT_VLAW=1 закон применённой стадии: mask=10^((α·ln1p(lvl/β)+c)/20)
RT_SYN=1 STFT БЕЗ синтез-окна (найденный слой плагина)
RT_WIN=0/1/2 окно анализа: sym-hann / periodic / rect
RT_NOWARP=1 отключить warp-модуляцию маски
RT_NOIIR3=1 отключить IIR3 ×2
RT_IIR12=0 отключить частотные IIR1/2 (КРИТИЧНО с RT_VLAW — иначе размывают дипы)
RT_DUMP_BIN=<f> (+RT_DUMP_FRAME=N) дамп тракта бина N: am/res/lvl_raw/band_level/prewarp/w
RT_VDBG=1 stderr-печать vlaw-вычислений
RT_FAITHFUL=1 faithful-цепь dsp/fnfaith.cpp (детекторный каскад)
RT_FIRCONV=1/3 FIR-применение (1=complex-mul, 3=1.019·mask^1.8345)

Полный набор dual-решения: RT_VLAW=1 RT_SYN=1 RT_NOWARP=1 RT_NOIIR3=1 RT_IIR12=0.

Инструменты

скрипт назначение
scripts/rendersnap2.py <rpp> [cap] [outdir] мягкий STOP-снаппер (RENDER_FILE из rpp!)
scripts/campaign.py <base> <fc> <q> <sens> <in> <drives> <out> ячейка параметризации (~8 мин)
scripts/disasm_func.py <VA> [len] capstone-дизасм с RIP-константами
scripts/iat_name.py рантайм-резолв импортов (SIGSTOP!)
scripts/probe_states.py / probe_mem.py / dump_dispatch.py live state/память/таблицы
scripts/hunt2.py перебор ctx-инстансов
scripts/scan_pairs.py, scan_lutsub.py диагностика памяти

Датасеты: /tmp/opencode/sc_{q,sens,qmap,k,f,d}* + tract_* + *.pkl/.npz (см. NOTES_LEVEL_INDEX.md). Открытые пробелы → BITEXACT_PLAN.md.

Архитектурная проблема chain_9_19 (КРИТИЧЕСКОЕ)

chain_9_19 из dsp/fn52fe0.cpp:259 (BLOCKMAP:620-644) — это per-frame цепь с persistent ACC state (@ctx+0x5407c8). Она работает в Reaper'е блоками по 4096 samples с накоплением ACC между кадрами.

Попытки интеграции (c23646d revert + 12 итераций):

  • ACC steady-state iteration 10-100x: не сходится, потому что chain требует block-based feedback (выход frame N → вход frame N+1), а не одноразовой итерации.
  • Frame-based вызов с casc_curve (cascade output ~0.0004): chain output = 0 (неправильный масштаб input).
  • Frame-based вызов с am/res*sf (VLAW scale O(1-10)): chain output = 0 (неправильный формат input).
  • f6f8_ (IIR1 out buffer) не был инициализирован → segfault.

Критический пробел: НЕИЗВЕСТЕН формат I/O chain_9_19:

  1. Какой масштаб input? (casc_curve ~0.0004 vs VLAW scale O(1-10) vs что-то другое)
  2. Что представляет output? (mask? level curve? log-domain vs linear?)
  3. Как ACC (track) взаимодействует с chain в рамках одного кадра?

Правильный путь:

  1. Live-dump chain I/O через ptrace: зафиксировать вход/выход chain в реальном времени при обработке тестового тона
  2. Или: детальный анализ decompilation 52a580-52b3cd для понимания data flow

Статус: chain отключен, используется VLAW path (RT_VLAW=1). Target 0.314→<0.05 требует live-dump chain I/O или полной транскрипции data flow из decompilation.


Чистая работа

  • Не коммитить: *.bin, *.wav/rpp, *.log, dsp/build/, ghidra-proj/, dl/lib/bin/include/, regions*/. См. .gitignore.
  • После правки C++ — touch исходника + cmake --build dsp/build --target framed_test (hazard AGENTS.md:66) + python3 scripts/corpus.py --compare scripts/baseline_bridge.json --tol 0.25.