9.8 KiB
AGENTS.md — runbook for AI agents working in this repo
Статус →
README.md:13(единственный источник TOTAL). Этот файл — только runbook: сборка, метрика, env-флаги, tooling hazard. Полный журнал —handoff/NOTES_LEVEL_INDEX.md→handoff/NOTES_LEVEL.md(живая голова) +handoff/archive/. Карта метода —handoff/BLOCKMAP_529fe0.md. ЭТОТ ФАЙЛ ЧИТАЙ ПЕРВЫМ.
Золотое правило (обязательно)
- Цель — bit-exact реверс кода, НЕ эмпирическая подгонка кривых. Каждый параметр должен иметь источник (decomp адрес / live-таблица), а не быть подогнанным числом. Если берёшь эмпирику — явно пометь и занеси в «осталось».
- Источник истины — декомпиляция (
decomp_funs.txt,decomp_funs2.txt,handoff/nls_dasm/*.dis) и live-снимки (/tmp/snap_rt.bin). Обновлять заметки при любом новом декоде. - Команды через
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 vlaw_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:
- Какой масштаб input? (casc_curve ~0.0004 vs VLAW scale O(1-10) vs что-то другое)
- Что представляет output? (mask? level curve? log-domain vs linear?)
- Как ACC (track) взаимодействует с chain в рамках одного кадра?
Правильный путь:
- Live-dump chain I/O через ptrace: зафиксировать вход/выход chain в реальном времени при обработке тестового тона
- Или: детальный анализ decompilation
52a580-52b3cdдля понимания data flow
Статус: chain отключен, используется VLAW path (RT_VLAW=1). Target 0.314→<0.05 требует live-dump chain I/O или полной транскрипции data flow из decompilation.
Live-dump chain (ptrace): chain вызывается в рантайме (DIV#0-7 на 0x1803a06a0):
- Input:
a= bands_curve (VLAW output, min=0, max=17.6, mean=0.048) b= tmp6f8 (step 9b accumulation, min=0, max=0.8, mean=0.8)- 8 DIV hits на одном кадре (dual-band: 2 bands × 4 iterations?)
Для полного live-dump нужно: breakpoints на всех шагах 9-19 (LOG#1, DIVIDE, dc40, FMA, EXP#1, array-mul, kWarp, LOG#2, IIR4×2, EXP#2).
Чистая работа
- Не коммитить:
*.bin,*.wav/rpp,*.log,dsp/build/,ghidra-proj/,dl/lib/bin/include/,regions*/. См..gitignore. - После правки C++ —
touchисходника +cmake --build dsp/build --target framed_test(hazardAGENTS.md:66) +python3 scripts/corpus.py --compare scripts/baseline_bridge.json --tol 0.25.