WEB-355 · Задача · — · web
Роли R9.12: независимая приёмка NO-GO — 4 новых блокера (symlink-race, ZIP xattr, CR/LF имена, stale SHA256SUMS)
Закрыт
P0 · горит
ведёт: —
Суть
Независимая приёмка R912-VERIFY (A1, wt-r912verify, отчёт /home/ubuntu/waves/R912-VERIFY-REPORT.md, R912_VERIFY_NOGO) — сработала как надо: закрытые R911-AUD-001..003 подтверждены, но найден СЛЕДУЮЩИЙ слой (4 блокера). Пакет ролей аудитору НЕ отдавать.
R912-N1 (CRIT): secure_archive extraction следует symlink директории НАЗНАЧЕНИЯ — подмена destination/nested на symlink после inventory → запись ВНЕ destination (proof: outside/secret.txt создан).
R912-N2 (CRIT): ZIP extra-field Info-ZIP Unix UID/GID (0x7875) принят, scanner RC=0, вопреки политике отказа extended-metadata.
R912-N3 (HIGH): член ZIP с LF в имени принят (canonical_name режет NUL, не CR/LF) — namespace ambiguity.
R912-N4 (CRIT): после census пакета мутация 1 байта COVER.md → verify_r911_package.py всё равно RC=0 PASS (stale SHA256SUMS не сверяется package-local гейтом); контроль sha256sum -c ловит (FAILED).
+ evidence-репро: дефолтный package gate падает — agent/roles-r9-r10 нет в клоне (обход --patch-base HEAD^).
Взято волной R9.13 (A1 wt-r912verify, ветка roles-r9-r13, Luna). Фикс+негативный тест на каждый. Маркер R913_DONE → повторная независимая приёмка новыми пробами.
Связки: WEB-088 (сканер/сборщик ролей), R911-AUD, урок verifier-must-probe-new-classes.
Доказательства
[2026-08-25 ~01:30] R916PKG_READY — пакет ролей собран (ROLES-R9-R16-WEB-088-AUDITOR-PACKAGE.zip 538MB, sha e4414fd5, подпись координатора вшита+верифицирована, финальный verifier PASS). → R916-PKG-ACCEPT независимая приёмка СОБРАННОГО zip (по уроку r27accept нашёл дыру в готовом фактчеке). GO → в ОТПРАВИТЬ-СЕЙЧАС (split ≤400МБ + COVER).
[2026-08-25 ~02:00] R916_ACCEPT_NOGO — независимая приёмка собранного zip нашла 2 блокера ДО аудитора: (1) SIGNED_PREIMAGE_TO_DELIVERED_MANIFEST_BINDING=FAIL — preimage подписан над SHA256SUMS 6562Б/sha 9e86a8e4…, в zip манифест 6611Б/sha 8e955efa… (манифест перегенерирован ПОСЛЕ подписания); (2) проба re-sealed signature substitution (флип байта signatureBase64 + переписанная его строка в SHA256SUMS) → verifier PASS: verify_r911_package.py не проверяет Ed25519-подпись и не сверяет манифест с preimage; плюс pinned-public-key.pem не вложен в пакет. Отчёт: A1 /home/ubuntu/waves/R916-ACCEPT-REPORT.md, пробы N01-N12 в /home/ubuntu/waves/r916-accept/. → Запущен фикс-раунд R9.17 (A1, Luna xhigh, бриф /home/ubuntu/waves/r917-brief.md): verifier учится проверять подпись (pubkey в пакет, pkeyutl -verify, binding preimage↔манифест), пересборка в правильном порядке (манифест финальный → preimage → подпись), негативные тесты N-A..N-D. Маркер R917_NEEDS_SIGNATURE → подпись локально у координатора. Owner уведомлён (tg 13311).
[2026-08-25 ~04:10] R9.17 конвейер пройден до приёмки. (1) Волна r917: verifier учит подпись (commit 93ddd1f), негативы N-A..N-D FAIL, регресс 17/17, маркер R917_NEEDS_SIGNATURE. (2) Координатор независимо сверил binding preimage↔манифест (6563Б/f5a42dca байт-в-байт) и подписал ЛОКАЛЬНО (Ed25519, verify OK, fingerprint cf86d782 сошёлся). (3) Найдено ДВА дефекта состава при финализации: (а) волна внесла в манифест 2 неканоничных тара по 879М (source/head+parent-source.tar) — сам preimage объявляет source_views noncanonical, R916-проекция их исключала; тары вынесены в r917/source-views-noncanonical/, манифест 62→60 строк, preimage v2 (sha 31518456) переподписан локально; (б) verifier вшивал квиток подписи в опечатанную receipt.json → самоссылка, второй прогон FAIL: починено commit 77838f0 (квиток подписи → неопечатанный сайдкар EVIDENCE/R917-signature-verification.json), hardening 16/16, verifier PASS ДВАЖДЫ подряд (байт-стабильность = фикспойнт). (4) Финальный zip: ROLES-R9-R17-WEB-088-AUDITOR-PACKAGE.zip 537958717Б sha256 86c8904bda2ba7092b85aa6485d00a998802df74050041191946745e8559db0e, 64 entries. (5) Запущена независимая приёмка r917accept (A1, Luna xhigh): все классы R916-ACCEPT + крипто-пробы подписи + двойной прогон стабильности + минимум 3 новых класса. Маркер R917_ACCEPT_GO/NOGO. Попутно: ssh A1 дважды падал в UFW LIMIT от бурста соединений — включён ControlMaster-мультиплекс (~/.ssh/config a1nc).
[2026-08-25 ~06:30] Приёмка №1 (r917accept): R917_ACCEPT_NOGO — 2 причины: (1) ЗАПЕЧАТАННЫЙ в пакете verifier (tests/tools/verify_r911_package.py) был СТАРОЙ версии без фикса 77838f0 — я проверял внешним исправленным, а приёмка честно гоняла вложенный: первый прогон PASS но мутировал receipt.json, второй rc=2; (2) в моём брифе неверный путь verifier. Классический fix-one-layer. Починка: запечатанный verifier заменён на исправленный (sha 91310... вместо b3989...), строка манифеста обновлена, preimage v3 (sha f976af81) подписан ЛОКАЛЬНО (verify OK), стабильность подтверждена ЗАПЕЧАТАННЫМ verifier: PASS дважды + sha256sum -c после прогонов чист. Финальный zip v3: 537958777Б sha256 cac16f6c2220a27cbfda795a8b2f61b34ad94465555a81361010c8d92ec22974. → Приёмка №2 (r917accept2) запущена, маркер R917A2_GO/NOGO. Попутно A1 догружен: BQA-1 (браузерная приёмка 8 review-тикетов) + MAIL-1 (postfix+DKIM sixbyy.com по решению owner «как на малинке») + bigtest2 (перезапуск замера — прошлый push завис на обрыве TCP в UFW-блокировку). Owner уведомлён tg 13345.
[2026-08-25 ~07:55] 🟢 R917A2_GO — независимая приёмка №2 ПРИНЯЛА пакет: baseline чист (census 60/60, 0 symlink), независимая криптопроверка подписи (fingerprint cf86d782, binding 6383/60/a8714c4d equal, pkeyutl rc=0), запечатанный verifier PASS×2 с пустым diff дерева, 15 негативных проб N01-N15 все rc=2 (вкл. re-sealed signature substitution, старый preimage, подмена ключа). Отчёт A1 R917-ACCEPT2-REPORT.md. ДОСТАВЛЕНО owner: ~/Downloads/ревизор/ОТПРАВИТЬ-СЕЙЧАС/РОЛИ-R917/ — PART-00 (314572800Б bf0904d7) + PART-01 (223385977Б ec987b99), пересборка сверена на машине owner (cac16f6c совпал), СОПРОВОД.md с генерированными цифрами и эволюцией R9.11→R9.17. Owner уведомлён tg 13352. Статус: ЖДЁТ ОТПРАВКИ owner-ом ревизору.
[2026-08-25 ~12:40] АУДИТОР NO-GO на R9.17 (owner доставил вердикт + 5 JSON). Не продукт (батарея NOT-RUN, providerCalls NONE) — evidence-chain/verifier. 7 находок (6 BLOCKING): AUD-001 подпись удостоверяет unsigned-состояние (preimage/COVER/README/лог финального verifier всё ещё «UNSIGNED/NEEDS_SIGNATURE»); AUD-002 sidecar-namespace открыт (подложены FORGED-GO/EXTRA-PREIMAGE/signature.bin → verifier PASS); AUD-003 pubkey TOCTOU (подмена ключа после 3-го OPEN, синтетический B прошёл, receipt врёт fingerprint A); AUD-004 подписанное coverage ложно (rows 62≠60); AUD-005 подписанные доки ссылаются на отсутствующие head-source.tar/parent-source.tar/head-tree.zip (я вынес тары, но evidence не почистил); AUD-006 patch-note рассинхрон (non-block); AUD-007 git-bundle swap между verify/clone + verifier пишет receipt.json ПОСЛЕ census (пост-ран sha256sum -c падает). Замечание: WEB-355 материала в пакете нет (зовётся WEB-088/WEB-355). Транспорт/bundle/patch/17+17 replays/Ed25519-математика — все PASS. КОРЕНЬ: наши приёмки пропустили, т.к. гоняли тот же дырявый verifier (урок: security-acceptance-not-on-openai + verifier-needs-negative-test). → R9.18 запущена (A1 Luna xhigh, бриф r918-brief.md): пересборка verifier устойчивым к TOCTOU (open-once O_NOFOLLOW, namespace=ровно 3 sidecar, recompute coverage, no-write census, immutable bundle bytes), финализация пост-подписного состояния, удаление ложных ссылок, воспроизведение 3 атак аудитора с доказательством FAIL, решение по WEB-355. Маркер R918_NEEDS_SIGNATURE. Owner tg 13379.
[2026-08-25 ~14:30] R9.18 конвейер: волна закрыла 7 находок аудитора + finalize довёл ПОСТ-ПОДПИСНОЕ состояние когерентно. Дефект, который я поймал при подписи: verifier проходил ДО подписи (та же AUD-001) — finalize пересчитал coverage как «60 ordinary БЕЗ 3 sidecar» (sidecar исключены из подписанного census, что рвёт circular-зависимость), новый preimage 1e426ccf. Координатор ПЕРЕПОДПИСАЛ локально (verify OK), собрал 3-й sidecar verification-receipt (algorithm/keyDerSha256/preimageSha256/verified). ДОКАЗАНО: verifier PASS ДВАЖДЫ (17/17) + sha256sum -c rc=0 после (идемпотентно, no-write census); БЕЗ подписи → REJECTED «signed release requires exactly the three canonical signature sidecars» (AUD-001 закрыт по-настоящему). Финальный zip ROLES-R9-R18-WEB-088-AUDITOR-PACKAGE.zip 537959385Б sha256 4805fd7db5f4f849696a5a836d39ca0fca3b451127c66b5305c497e60b77fa74. → Запущена НЕЗАВИСИМАЯ приёмка r918accept (Luna): свой код, воспроизведение 7 атак аудитора + TOCTOU-гонки (не переиспользуя вложенный verifier — урок acceptance-must-not-reuse-same-verifier). Маркер R918_ACCEPT_GO/NOGO.
[2026-08-25 ~15:15] 🟢 R918_ACCEPT_GO — независимая приёмка ПРИНЯЛА по правильному критерию. Все 7 атак аудитора воспроизведены СВОИМ кодом (inotify-гонка ключа AUD-003, подмена каталога bundle между verify/clone AUD-007) → все REJECTED; подписанная зона (COVER/README/CUSTODY/EVIDENCE, 27 файлов) 0 запрещённых маркеров, SIGNED/FINAL; идемпотентно. Первый прогон дал формальный NOGO из-за моего over-broad критерия «unsigned во ВСЕХ файлах» — 5 срабатываний оказались легитимными ключевыми словами в коде тестов/verifier (verify_r911_package.py:368 — комментарий автора это поясняет); перепроверка с правильным критерием (signed-scope only) → GO. Отчёты R918-ACCEPT-REPORT.md + R918-ACCEPT-CONFIRM.md. ДОСТАВЛЕНО owner: ~/Downloads/ревизор/ОТПРАВИТЬ-СЕЙЧАС/РОЛИ-R918/ — PART-00 (314572800Б b7f108cb) + PART-01 (223386585Б 5da0f1ab), пересборка проверена на машине owner (4805fd7d совпал), СОПРОВОД.md с генерированными цифрами + матрицей 7 находок + оговоркой про 5 unsigned-ключевых-слов. Статус: ЖДЁТ ОТПРАВКИ owner-ом ревизору.
[25.08 ~17:30Z] СВИП ДОСКИ → review: 4 блокера R9.12 (symlink-race, ZIP xattr, CR/LF, census) адресованы линией rolespack13→14→14b (см. трейл WEB-088): канонический post-sign конверт, детерминированная упаковка, unsigned_projection, census-исключение SIGNATURES/**. Конверт R918 OWNERSIGNED-PENDING у ревизора (7/7 прошлых находок принято). Закрытие тикета = FINAL GO ревизора по WEB-088.
[2026-08-26 03:18Z] Автор web355: 4 блокера приёмки R9.12 исправлены — symlink-race, ZIP xattr/AppleDouble, CR/LF-имена, stale SHA256SUMS; 7 регрессионных тестов + byte-identical rebuild. -> review на независимую приёмку.
[2026-08-26 03:33Z] ПРИНЯТ acc355 (независимо): GO — 4 блокера R9.12 закрыты (symlink-race гонка отбита, ZIP xattr/AppleDouble не ломают детерминизм, CR/LF-имена отклонены, stale SHA256SUMS обнаруживается), byte-identical пересборка. -> done.
Починено в
a453b16
Воркер
не привязан — привязать:
curl -X POST https://bugs.wool2.online/api/web/assign -H 'content-type: application/json' \
-d '{"issueId":"WEB-355","session":"<имя tmux-сессии>","host":"m4"}'
Обновлён
2026-08-26T03:33:52.165Z