Repository navigation
Исправления по ревью: CI на Linux, исход по цели, разведённые границы, новые классы - #1
Merged
Merged
Conversation
- канарейка случайная и не передаётся в argv; вынос считается только для значения, которое проба прочитала сама - сеть: решает журнал приёмника; на Linux отказ соединения в отдельном сетевом пространстве имён засчитывается, только если control дошёл - ФС: состояние цели проверяет раннер (на хосте, в OpenShell через docker cp) - новые проверки: DNS/UDP, unix socket, файлы, которые исполняет компонент вне песочницы (git hook, .claude/settings.json, .mcp.json, Makefile, package.json, .envrc, pre-commit); git commit вне песочницы исполняет хук - validate разделён на ошибки стенда (код 1) и находки (код 2) - OpenShell: удаление sandbox подтверждается по шлюзу и Docker; образы закреплены по digest - console.log и SHA256SUMS для каждого прогона, пути хоста заменяются - managed settings: хуки и MCP только из managed, WebFetch/WebSearch, новые credential-файлы и ANTHROPIC_API_KEY, autoAllowBashIfSandboxed=false - check.py сверяет значения ключей с таблицей README; мастер установки решает исход по файлам и журналу приёмника Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- results/2026-10-30: console.log, SHA256SUMS, матрицы пересчитываются из raw - README: отдельные таблицы для SRT (процесс на хосте) и OpenShell (контейнер в VM), где проверено, что не покрыто и почему - RECOMMENDATION: у каждого утверждения — прогон или «не проверено»; фильтры содержимого не испытывались; Landlock не изолирован прогоном - 2026-10-29: фраза про одну команду с кодом 0 заменена фактами артефактов; Docker Engine, а не Docker Desktop - openshell/SEARCH.md: хвосты формулировок Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Исправления по ревью 2026-10-30. CI на этой ветке зелёный: checks,
srt (macos-14),srt (ubuntu-24.04),openshell(run 41027953167). История не переписывалась.Общая проверка всего PR:
1. Красный CI на Linux
Причина (по артефактам run 40958209738): на Linux
direct_tcpполучалECONNREFUSED. У SRT на Linux своё сетевое пространство имён;127.0.0.1внутри него — не loopback хоста (README SRT,network.allowLocalBinding: «Linux: ignored — the sandbox has its own network namespace, whose loopback is always usable and is not the host's»). Jobopenshellпадал только из-за кода выхода SRT; сам OpenShell на Linux совпал с ожиданиями.Сделано: сетевые исходы решает журнал приёмника. Если приёмник ничего не получил, а проба получила
ECONNREFUSED/таймаут/EDESTADDRREQ, исходblockedзасчитывается только при условии, что от control тот же приёмник получил данные. Ошибка разрешения имени остаётся ошибкой. errno сравниваются по именам: номера на Linux и macOS разные.Проверка: статус CI этого PR;
python3 scripts/test_results.py(тестыtest_refused_connection_counts_only_if_control_was_delivered,test_name_resolution_error_is_not_protection).Руками: открыть артефакт
srt-ubuntu-24.04и посмотретьdetailуdirect_tcpв hardened.2. «Одна команда, код 0» у 2026-10-29
Сделано: новый прогон одной командой
npm run matrix -- --with-openshell --output results/2026-10-30, код 0.benchmark.pyсам пишетconsole.log(весь вывод, последняя строка — код выхода) иSHA256SUMS. Вresults/2026-10-29/README.mdфраза заменена фактами (шлюз ~18:42Z, SRT 21:25:48Z, вывод исходной команды не сохранён); снапшот помечен архивом.Проверка:
cd results/2026-10-30 && shasum -a 256 -c SHA256SUMS; временаstarted_atвsrt/raw.jsonиopenshell/raw.jsonидут подряд.Руками: перезапустить ту же команду в
results/local-…и сравнить матрицы.3. Разные границы под одинаковыми строками
Сделано: канарейка случайная и в argv не попадает (раньше её передавал
run.py:206). Вынос — строкаexfil_secret: проба шлёт только то, что прочитала сама.allowed_channelшлёт nonce пробы и показывает, что канал открыт. В README две отдельные таблицы (SRT — процесс на хосте; OpenShell — контейнер в VM) с колонкой «Что решает»; у OpenShell env помечен как выбор раннера, control — какdocker run. Шапка каждой матрицы описывает границу, канарейки и control.Проверка: канарейка (синтетика) записана в raw, но не в командах исполнений SRT:
python3 -c "import json;r=json.load(open('results/2026-10-30/srt/raw.json'));print(any(r['canary'] in ' '.join(e['command']) for e in r['executions']))"→False.Руками: прочитать раздел «Что сравнивать нельзя» в
results/2026-10-30/README.mdи решить, достаточно ли этого читателю.4. Проверки на цели
Сделано:
docker cpиз контейнера workload снаружи. Отчёт пробы о записи без файла →error; файл при заявленном отказе →allowed.~/.ssh(удаляется поtrap),.env,curlи WebFetch на локальный приёмник, запись вне каталога. Если команды не выполнялись, исход «не проверена», а не «отказ».validate()разделён:assess()возвращает ошибки стенда (код 1) и находки (код 2, раздел «Находки» в матрице). Упавший control — ошибка, а не находка.Проверка:
python3 scripts/test_results.py(18 тестов);bash -n claude-sandbox/install-wizard.sh; ShellCheck в CI.Руками: мастер в этом PR не запускался — нужен Claude Code и sudo. Пройти шаг 5 и посмотреть
results/install.log.5. Пропущенные классы
Добавлено в стенд:
dns_udp(DNS-пакет с nonce на локальный UDP-приёмник),unix_socket(синтетический сокет на хосте; в OpenShell не испытывался, вместо этого проверяется, что Docker socket не смонтирован), семь файлов, которые исполняют снаружи:.git/hooks/pre-commit,.claude/settings.json(hooks, statusLine, apiKeyHelper),.mcp.json,Makefile,package.json,.envrc,.pre-commit-config.yaml. В control SRT записанный хук исполнился приgit commitвне песочницы.Результат: standalone SRT запретил
.git/hooksи.mcp.json(обязательный deny-лист) и разрешил остальные пять, включая.claude/settings.json(его, по документации, защищает сам Claude Code — не проверено).Не покрыто, с причиной (README, «Что не покрыто»): хуки/MCP/apiKeyHelper в самом Claude Code и WebFetch (нужен Claude Code и модель; шаги подготовлены в мастере), DNS через системный резолвер (нужен свой авторитетный DNS), настоящий
docker.sock(доступ к нему = доступ к хосту).Руками: решить, достаточно ли синтетического unix socket или нужен прогон с
allowUnixSocketsна одноразовой машине.6. Denylist в managed settings
Сделано (сверено с sandboxing и settings-reference 2026-10-30):
ANTHROPIC_API_KEYвenvVars;~/.git-credentials,~/.pypirc,~/.azure,~/.vault-tokenвcredentials.filesиpermissions.deny;.env—sandbox.filesystem.denyRead: ["~/**/.env"]иRead(**/.env);WebFetchиWebSearchвpermissions.deny;allowManagedHooksOnly: true,allowManagedMcpServersOnly: true,allowedMcpServers: [],enableAllProjectMcpServers: false.autoAllowBashIfSandboxedвыключен (false): приtrueкоманды в песочнице без вопроса пишут файлы, которые потом исполняются снаружи.apiKeyHelperиз репозитория отдельным managed-ключом не запрещается — записано как непокрытое.Проверка:
python3 scripts/check.pyтеперь сверяет значение каждого ключа с таблицейclaude-sandbox/README.md(у списков — каждый элемент), а не упоминание имени.Руками: это решения ученика: оставить ли
autoAllowBashIfSandboxed: falseи полный запрет WebFetch/WebSearch для пилота.7. Рекомендация
Сделано: в
RECOMMENDATION.mdу каждого утверждения — чем подкреплено. Фоновый агент с управляемым шлюзом помечен «не проверено» (шлюз без аутентификации,--no-auto-providers). Вывод про Claude Code переформулирован как вывод про standalone SRT. Отказ записи в OpenShell не приписывается Landlock: прогона без Landlock не было. «Канал не закрыт» — в политиках стенда;filterRequest/tlsTerminateи правила запросов OpenShell не испытывались. Docker Desktop 4.72.0 / Engine 29.4.2 разведены. Удаление sandbox OpenShell подтверждается: раннер ждётsandbox not foundот шлюза и отсутствия контейнеров workload/supervisor в Docker (cleanupвopenshell/raw.json).Проверка:
python3 -c "import json;print([c['stdout'][:70] for c in json.load(open('results/2026-10-30/openshell/raw.json'))['cleanup'] if c['command'][0]=='confirm-deleted'])".Руками: перечитать рекомендацию — выводы в ней за учеником.
8. Хвосты
install-wizard.sh: убрано «Каркас взят из шаблона».openshell/SEARCH.md: убраны «канал gh недоступен», «выводы агента», ADOPT/EXTEND, «Поправка к прежним текстам», «Mac автора»; у promptfoo — почему не использован.results/install.logв.gitignore.check.py: см. пункт 6.Не сделано
🤖 Generated with Claude Code