fix(skills): исправлена настройка песочницы Codex через AppArmor
- Зачем: - Профили на пути установки Codex ломались после переустановки, а прежние проверки могли давать ложный успех. - Что: - Штатный профиль системного bwrap выбран основным способом настройки; исторические обходы ограничены подтверждёнными случаями. - Уточнены диагностика, переход со старых профилей и проверки режимов и границ записи. - Обновлены связанные инструкции и записан результат применения на Ubuntu 24.04.4 с Codex 0.154.0. - Проверка: - Пройдены quick_validate, проверка ссылок, синтаксиса Bash и git diff --check. - Штатный профиль применён; старые профили выгружены. Оба режима и запреты записи проверены из процесса unconfined; подтверждены метки AppArmor у bwrap и дочерней команды.
This commit is contained in:
1 parent
67aa5e67d5
commit
26fdb7584c
3 files changed
+162
-127
No files matched your search
@@ -15,10 +15,10 @@ WSL2 Ubuntu: exec/resume/`-o`/фоновый Bash — весь конвейер)
|
|||||||
|
|
||||||
## Сквозные правила (любая ветка)
|
## Сквозные правила (любая ветка)
|
||||||
|
|
||||||
- **Предполёт — один раз на новой машине или в новом харнессе.** Две
|
- **Предполёт — на новой машине, в новом харнессе и после обновления или
|
||||||
проверки. Песочница: диагностика из
|
переустановки Codex.** Две проверки. На Linux/WSL песочница: оба режима
|
||||||
[codex-sandbox-apparmor.md](codex-sandbox-apparmor.md) (сигнатура поломки
|
и границы записи по [codex-sandbox-apparmor.md](codex-sandbox-apparmor.md).
|
||||||
и лечение — там же). Вывод доходит до файла: `codex --version > f;
|
Вывод доходит до файла: `codex --version > f;
|
||||||
wc -c f` — непусто значит, что рецепты ниже работают как написаны. Пусто:
|
wc -c f` — непусто значит, что рецепты ниже работают как написаны. Пусто:
|
||||||
среда теряет унаследованный файловый дескриптор, и на входе, и на выходе
|
среда теряет унаследованный файловый дескриптор, и на входе, и на выходе
|
||||||
(известный случай — T3 Code, [lessons.md](lessons.md) 2026-08-06); тогда
|
(известный случай — T3 Code, [lessons.md](lessons.md) 2026-08-06); тогда
|
||||||
@@ -118,14 +118,12 @@ WSL2 Ubuntu: exec/resume/`-o`/фоновый Bash — весь конвейер)
|
|||||||
`jq`, редиректы под Windows работают). `$SCRATCH` задавай
|
`jq`, редиректы под Windows работают). `$SCRATCH` задавай
|
||||||
forward-slash-путём (`/c/Users/...`), не `C:\...`; пути в аргументах
|
forward-slash-путём (`/c/Users/...`), не `C:\...`; пути в аргументах
|
||||||
кавычь; в выводах под Windows возможны `\r`.
|
кавычь; в выводах под Windows возможны `\r`.
|
||||||
- **Linux: sandbox может молча сломаться обновлением Codex.** Сигнатура:
|
- **Linux: shell-команды падают до запуска, хотя web_search работает.**
|
||||||
web_search работает, а `pwd` внутри песочницы — нет
|
При ошибке bwrap, в том числе `Failed RTM_NEWADDR`, сначала установи
|
||||||
(`bwrap: loopback: Failed RTM_NEWADDR`). Обход без sudo
|
причину и фактический способ запуска по
|
||||||
`use_legacy_landlock=true` чинит только read-only, write-режим с ним
|
[codex-sandbox-apparmor.md](codex-sandbox-apparmor.md). Там же — штатная
|
||||||
паникует; полный фикс — AppArmor-профиль, и он под sudo: сам не применяй,
|
настройка, переход со старого обхода и критерий готовности. При провале
|
||||||
дай пользователю готовые команды из
|
предполёта сначала восстанови среду, затем запускай рабочие задачи.
|
||||||
[codex-sandbox-apparmor.md](codex-sandbox-apparmor.md) (`!`-префикс в чат),
|
|
||||||
после применения профиля напомни убрать `use_legacy_landlock`.
|
|
||||||
- **Блок классификатора — сначала сузь песочницу, потом зови пользователя.**
|
- **Блок классификатора — сначала сузь песочницу, потом зови пользователя.**
|
||||||
Первая проверка: нет ли в команде `-s danger-full-access` — классификатор
|
Первая проверка: нет ли в команде `-s danger-full-access` — классификатор
|
||||||
его блокирует, и он не нужен (почему — в ветке исполнителя). Если блок не
|
его блокирует, и он не нужен (почему — в ветке исполнителя). Если блок не
|
||||||
|
|||||||
+149
-112
@@ -1,120 +1,157 @@
|
|||||||
# Sandbox Codex на Linux: диагностика и починка (bwrap/AppArmor)
|
# Песочница Codex на Linux: проверка и настройка AppArmor
|
||||||
|
|
||||||
Справочник: симптомы, корень и рецепты фикса поломки песочницы Codex CLI
|
Читай при первом запуске на Linux/WSL, после смены версии или установки
|
||||||
на Linux с AppArmor (эмпирика Ubuntu 24.04, 2026-07-10). Самодостаточен.
|
Codex и при отказе команд внутри песочницы. Основной путь — системный
|
||||||
|
`bwrap` со штатным профилем AppArmor. Способ запуска проверяй по фактам:
|
||||||
|
номер версии сам по себе не доказывает выбор встроенного или системного bwrap.
|
||||||
|
|
||||||
## Симптом
|
## 1. Проверь запуск в нужной среде
|
||||||
|
|
||||||
Любая команда внутри sandbox Codex падает **до запуска процесса**, даже `pwd`:
|
Из рабочего каталога проекта выполни оба вызова тем же способом, которым
|
||||||
|
будет запущен исполнитель или ревьюер:
|
||||||
```
|
|
||||||
bwrap: loopback: Failed RTM_NEWADDR: Operation not permitted
|
|
||||||
```
|
|
||||||
|
|
||||||
Проявляется и в read-only, и в workspace-write. Codex не может ни читать файлы через shell, ни выполнять команды — задачи либо виснут, либо честно завершаются отказом.
|
|
||||||
|
|
||||||
## Корневая причина (подтверждена kernel audit log)
|
|
||||||
|
|
||||||
**Codex CLI 0.144.1 (npm) сменил Linux-sandbox backend**: раньше был Landlock/seccomp без user namespaces, теперь — vendored bubblewrap (`…/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/codex-resources/bwrap`), который создаёт unprivileged user namespace + network namespace.
|
|
||||||
|
|
||||||
Ubuntu 24.04 с `kernel.apparmor_restrict_unprivileged_userns = 1` загоняет такой userns в запретительный AppArmor-профиль `unprivileged_userns`, который блокирует два шага, нужных bwrap: запись `/proc/PID/uid_map` и `RTM_NEWADDR` (поднятие loopback). Доказательство из audit log:
|
|
||||||
|
|
||||||
```
|
|
||||||
apparmor="AUDIT" operation="userns_create" comm="bwrap" profile="unconfined" target="unprivileged_userns"
|
|
||||||
apparmor="DENIED" operation="open" name="proc/…/uid_map" profile="unprivileged_userns" denied_mask="wr"
|
|
||||||
```
|
|
||||||
|
|
||||||
Важные отрицательные результаты (экономят время диагностики):
|
|
||||||
|
|
||||||
- **Плагин openai-codex (1.0.5 → 1.0.6) ни при чём** — он лишь передаёт режимы sandbox бинарю codex; даунгрейд плагина не помогает.
|
|
||||||
- Системный `/usr/bin/bwrap` падает так же — это не баг vendored-сборки.
|
|
||||||
- Система не менялась (машина без ребута 14 недель, политика AppArmor старая) — это дрейф самого Codex CLI, прилетевший с обновлением npm-пакета.
|
|
||||||
|
|
||||||
## Применённый фикс без sudo (обратимый)
|
|
||||||
|
|
||||||
В `~/.codex/config.toml` добавлено:
|
|
||||||
|
|
||||||
```toml
|
|
||||||
[features]
|
|
||||||
use_legacy_landlock = true
|
|
||||||
```
|
|
||||||
|
|
||||||
Backup рядом: `~/.codex/config.toml.bak-20260710`. Откат — восстановить backup или удалить две строки.
|
|
||||||
|
|
||||||
## Проверка (сквозная, через codex-companion)
|
|
||||||
|
|
||||||
- Read-only задача `task --wait --fresh` («pwd + первая строка /etc/os-release») — команды выполняются, вернула корректные значения.
|
|
||||||
- **web_search работает**: задача сходила на github.com/openai/codex/releases. Нюанс: сетевой доступ из *shell-команд внутри sandbox* по-прежнему закрыт (`npm view` виснет) — это корректный read-only режим; инструмент web_search исполняется вне sandbox и не страдает.
|
|
||||||
- Изоляция сохранена: запись вне workspace запрещена.
|
|
||||||
|
|
||||||
## Известное ограничение фикса
|
|
||||||
|
|
||||||
`use_legacy_landlock` чинит **только read-only**. Режим `--write`/workspace-write с этим флагом **паникует**:
|
|
||||||
|
|
||||||
```
|
|
||||||
permission profiles requiring direct runtime enforcement are incompatible with --use-legacy-landlock
|
|
||||||
```
|
|
||||||
|
|
||||||
— workspace-write требует именно bwrap-backend. Полный фикс — ниже, нужен sudo.
|
|
||||||
|
|
||||||
## Полный фикс (sudo; применён и проверен 2026-07-10)
|
|
||||||
|
|
||||||
**Ловушка, съевшая первую попытку**: профиль на путь vendored bwrap
|
|
||||||
(`**/codex-resources/bwrap`) НЕ работает — Codex ≥0.144 исполняет
|
|
||||||
**встроенный** bwrap из memfd (`linux-sandbox/src/bundled_bwrap.rs`,
|
|
||||||
`memfd_create` в бинаре), и путевой attachment не цепляется никогда: в audit
|
|
||||||
виден `profile="unconfined" comm="bwrap"` → transition в
|
|
||||||
`unprivileged_userns`. Прямой запуск vendored bwrap с диска при этом
|
|
||||||
проходит — ложное подтверждение, не верь ему.
|
|
||||||
|
|
||||||
**Рабочий вариант**: вешать профиль на **сам бинарь codex** (родителя) —
|
|
||||||
memfd-exec'нутый ребёнок наследует метку через exec, и правило `userns,`
|
|
||||||
разрешает namespace. Стандартный приём Ubuntu для браузеров/Electron.
|
|
||||||
`/etc/apparmor.d/codex-bwrap`:
|
|
||||||
|
|
||||||
```
|
|
||||||
abi <abi/4.0>,
|
|
||||||
include <tunables/global>
|
|
||||||
|
|
||||||
profile codex-cli /home/dmitry/.npm-global/lib/node_modules/@openai/codex/**/bin/codex flags=(unconfined) {
|
|
||||||
userns,
|
|
||||||
include if exists <local/codex-cli>
|
|
||||||
}
|
|
||||||
|
|
||||||
profile codex-bwrap /home/dmitry/.npm-global/lib/node_modules/@openai/codex/**/codex-resources/bwrap flags=(unconfined) {
|
|
||||||
userns,
|
|
||||||
include if exists <local/codex-bwrap>
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Загрузить: `sudo apparmor_parser -r /etc/apparmor.d/codex-bwrap`. После этого **убрать** `use_legacy_landlock` из config.toml и проверить оба режима:
|
|
||||||
|
|
||||||
```
|
|
||||||
codex sandbox -c 'sandbox_mode="workspace-write"' -- sh -c 'touch ./__p && rm ./__p && echo OK'
|
|
||||||
codex sandbox -- sh -c 'touch ./__p 2>/dev/null && echo BROKEN || echo RO_OK'
|
|
||||||
```
|
|
||||||
|
|
||||||
Проверено 2026-07-10: WRITE_OK, read-only блокирует запись, workspace-write
|
|
||||||
не пускает в `/etc` — изоляция сохранена.
|
|
||||||
|
|
||||||
Переносимость: путь в профиле — под конкретную машину (`~/.npm-global/...`); glob `**` переживает обновления версий Codex, но если npm-global живёт в другом месте — путь поправить. Перезагружать профиль нужно только при смене самого расположения.
|
|
||||||
|
|
||||||
**Вариант B — грубый, не рекомендуется**: `sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0` (+ файл в `/etc/sysctl.d/`). Ослабляет защиту всей машины.
|
|
||||||
|
|
||||||
## Диагностические команды для другой машины
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
codex --version # 0.144.1+ → bwrap-backend
|
codex sandbox -c 'sandbox_mode="read-only"' -- sh -c 'pwd && echo READ_OK'
|
||||||
sysctl kernel.apparmor_restrict_unprivileged_userns # 1 → будет блокировка
|
codex sandbox -c 'sandbox_mode="workspace-write"' -- sh -c \
|
||||||
bwrap --ro-bind / / --unshare-net --dev /dev --proc /proc true && echo BWRAP_OK
|
'set -eu; probe=$(mktemp ./.codex-sandbox-check.XXXXXX); rm -- "$probe"; echo WRITE_OK'
|
||||||
sudo dmesg | grep -iE 'apparmor.*(userns|bwrap)' | tail # AUDIT/DENIED — подтверждение
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Связанные записи
|
Успех — нулевой код выхода и соответствующий маркер от каждой команды.
|
||||||
|
Это проверка запуска; проверка запретов записи — в разделе 4.
|
||||||
|
Работающий `web_search` ничего не говорит о выполнении shell-команд.
|
||||||
|
|
||||||
Принесено 2026-07-10 из ветки `codex-sandbox-fix-20260710` (исходная машина —
|
Если в конфигурации остался `use_legacy_landlock=true`, для проверочных
|
||||||
Ubuntu 24.04; там сжатая версия жила в codex-companion.md, который в основной
|
вызовов добавь `-c 'features.use_legacy_landlock=false'`: проверяем штатную
|
||||||
линии уже поглощён codex-exec.md). Сжатая версия урока здесь — в
|
песочницу, а не старый обход.
|
||||||
[codex-exec.md](codex-exec.md), сквозное правило «Linux: sandbox может молча
|
|
||||||
сломаться обновлением Codex»; датированная запись — в
|
## 2. Установи причину отказа
|
||||||
[lessons-archive.md](lessons-archive.md).
|
|
||||||
|
`bwrap: loopback: Failed RTM_NEWADDR: Operation not permitted` — повод
|
||||||
|
проверить AppArmor, но не достаточный диагноз. Собери:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
codex --version
|
||||||
|
cat /etc/os-release
|
||||||
|
type -a codex bwrap
|
||||||
|
sysctl kernel.apparmor_restrict_unprivileged_userns
|
||||||
|
cat /proc/self/attr/current
|
||||||
|
```
|
||||||
|
|
||||||
|
Проверь журнал ядра за время неудачного вызова: записи `apparmor="DENIED"`
|
||||||
|
для `userns_create`, `uid_map` или настройки сети подтверждают ограничение
|
||||||
|
AppArmor. Отсутствие доступа к журналу — пробел в диагностике, а не
|
||||||
|
доказательство причины. При отказе доступа к
|
||||||
|
`codex-bwrap-synthetic-mount-targets` сравни минимальный вызов из среды
|
||||||
|
агента и из обычного терминала хоста. Если на хосте он работает, исследуй
|
||||||
|
ограничения внешней песочницы и способ запуска агента; профиль AppArmor
|
||||||
|
пока не считай причиной. Если вызов падает и на хосте, а причина по
|
||||||
|
доступным данным не установлена, сохрани точную ошибку и результаты обоих
|
||||||
|
запусков; запроси недостающие записи журнала за это время. До подтверждения
|
||||||
|
причины рецепт AppArmor не применяй.
|
||||||
|
|
||||||
|
По [документации OpenAI](https://learn.chatgpt.com/docs/sandboxing#prerequisites)
|
||||||
|
Codex выбирает первый `bwrap` из `PATH`, а при его отсутствии использует
|
||||||
|
встроенный. Проверяй `PATH` именно запускающего процесса: оболочка,
|
||||||
|
редактор и агент могут видеть разные установки. При расхождении с этим
|
||||||
|
поведением установи фактический исполняемый файл дочернего bwrap через
|
||||||
|
`/proc/<pid>/exe` или трассировку `execve`/`execveat`; одного `command -v`
|
||||||
|
для этого недостаточно.
|
||||||
|
|
||||||
|
## 3. Настрой системный bwrap
|
||||||
|
|
||||||
|
Если подтверждена блокировка AppArmor, используй пакет `bubblewrap` и
|
||||||
|
профиль `bwrap-userns-restrict` из дистрибутива. Путь в профиле должен
|
||||||
|
соответствовать фактически запускаемому bwrap. При другой копии в `PATH`
|
||||||
|
сначала приведи запуск к системной установке.
|
||||||
|
|
||||||
|
Для Ubuntu 24.04 официальный рецепт использует пакеты:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install bubblewrap apparmor-profiles apparmor-utils
|
||||||
|
```
|
||||||
|
|
||||||
|
Если `/etc/apparmor.d/bwrap-userns-restrict` уже существует, изучи его;
|
||||||
|
локальные изменения сохрани. Если файла нет, проверь наличие штатного
|
||||||
|
образца и установи его:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
test -f /usr/share/apparmor/extra-profiles/bwrap-userns-restrict && \
|
||||||
|
sudo install -m 0644 /usr/share/apparmor/extra-profiles/bwrap-userns-restrict \
|
||||||
|
/etc/apparmor.d/bwrap-userns-restrict
|
||||||
|
```
|
||||||
|
|
||||||
|
Загрузи профиль без перезагрузки машины:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apparmor_parser -r /etc/apparmor.d/bwrap-userns-restrict
|
||||||
|
```
|
||||||
|
|
||||||
|
В Ubuntu 25.04 профиль поставляется пакетом `apparmor`; на других выпусках
|
||||||
|
проверь состав пакетов. Если образца нет или загрузка не удалась, останови
|
||||||
|
этот рецепт и выясни совместимость пакетов и AppArmor по документации
|
||||||
|
дистрибутива. Отсутствующий профиль не заменяй расширением разрешений всей
|
||||||
|
машины или отключением песочницы.
|
||||||
|
|
||||||
|
Установка пакетов и изменение профилей — настройка машины. Выполняй её в
|
||||||
|
пределах уже разрешённой задачи; если настройка среды не разрешена, сначала
|
||||||
|
подготовь конкретные команды по результатам диагностики и запроси согласие.
|
||||||
|
|
||||||
|
## 4. Проверь результат и убери старый обход
|
||||||
|
|
||||||
|
Повтори оба вызова из раздела 1. Затем проверь границы записи, явно задавая
|
||||||
|
режим каждому вызову:
|
||||||
|
|
||||||
|
- `read-only`: чтение работает, создание временного файла внутри проекта
|
||||||
|
запрещено.
|
||||||
|
- `workspace-write`: создание и удаление временного файла внутри проекта
|
||||||
|
работает; запись за пределами разрешённых каталогов запрещена.
|
||||||
|
|
||||||
|
Для проверки запрета используй отдельный временный каталог, в который тот
|
||||||
|
же пользователь может записать вне проверяемой песочницы. Отказ засчитывай
|
||||||
|
только после успешного запуска команды и как запрет доступа, а не любую
|
||||||
|
ошибку. `/etc` не подходит: запись туда обычно запрещена уже правами Unix;
|
||||||
|
`/tmp` не подходит для проверки внешнего запрета, если разрешён политикой.
|
||||||
|
Удали только созданные проверкой файлы и каталоги.
|
||||||
|
|
||||||
|
Если раньше был установлен профиль на бинарь Codex (например,
|
||||||
|
`codex-bwrap` с секциями `codex-cli*`), одного успешного прогона недостаточно:
|
||||||
|
дочерние процессы могут наследовать его разрешения. При переходе сохрани
|
||||||
|
старый профиль для отката, выведи его из автозагрузки и выгрузи его секции
|
||||||
|
из ядра. Запусти проверку из новой оболочки, не унаследовавшей старую метку
|
||||||
|
AppArmor, и новым процессом Codex. Продолжение прежней сессии не доказывает
|
||||||
|
независимость от обхода. При неудаче восстанови старую настройку и сохрани
|
||||||
|
диагноз; переход не завершён.
|
||||||
|
|
||||||
|
Готово, когда оба режима и запреты записи проверены, а при переходе со
|
||||||
|
старого профиля — ещё и подтверждена независимость от него. После этого
|
||||||
|
убери оставшийся `use_legacy_landlock` из конфигурации. Если системная
|
||||||
|
настройка не выполнялась, различай «инструкция подготовлена» и
|
||||||
|
«песочница на этой машине исправлена».
|
||||||
|
|
||||||
|
## Исторические обходы и границы применимости
|
||||||
|
|
||||||
|
- **2026-07-10, Codex 0.144.1, Ubuntu 24.04.** Наблюдался запуск встроенного
|
||||||
|
bwrap через `memfd`: профиль на дисковый файл bwrap не применялся.
|
||||||
|
Профиль на сам бинарь Codex с разрешением `userns` помог. Это запасной
|
||||||
|
вариант для подтверждённого встроенного запуска, если перейти на
|
||||||
|
поддерживаемый системный bwrap нельзя; путь определяют на конкретной
|
||||||
|
машине, ограничивая его текущей установкой.
|
||||||
|
- **Тогда же:** `use_legacy_landlock=true` помогал read-only, но
|
||||||
|
workspace-write завершался ошибкой несовместимости. Для конвейера,
|
||||||
|
которому нужна запись, это не решение.
|
||||||
|
- **2026-09-10, Codex 0.154.0.** Смена npm-установки на standalone вывела
|
||||||
|
бинарь из-под старого профиля; добавление второго пути устранило симптом.
|
||||||
|
Затем этот рецепт применён на Ubuntu 24.04.4: штатный профиль из
|
||||||
|
`apparmor-profiles` 4.0.1really4.0.1-0ubuntu0.24.04.7 установлен без
|
||||||
|
изменений, старые профили Codex выгружены и убраны из автозагрузки.
|
||||||
|
Из процесса `unconfined` проверены чтение, запрет записи в read-only,
|
||||||
|
запись внутри workspace-write и запрет снаружи; перед проверкой обычная
|
||||||
|
пользовательская запись в оба временных каталога проходила.
|
||||||
|
Через `/proc` подтверждены `/usr/bin/bwrap` с меткой `bwrap (enforce)`
|
||||||
|
и дочерняя команда с `bwrap//&unpriv_bwrap (enforce)`.
|
||||||
|
`apparmor_restrict_unprivileged_userns=1` сохранён, legacy-обход отсутствует.
|
||||||
|
|
||||||
|
Наблюдения относятся к указанным установкам, а не ко всем версиям Codex.
|
||||||
|
Штатный рецепт и состав пакетов сверены с документацией OpenAI 2026-09-10.
|
||||||
|
Связанная запись: [lessons-archive.md](lessons-archive.md).
|
||||||
@@ -55,9 +55,9 @@
|
|||||||
|
|
||||||
- Ревьюер Codex без read-only: мандат промптом надёжен, песочница не режется.
|
- Ревьюер Codex без read-only: мандат промптом надёжен, песочница не режется.
|
||||||
Поглощено: codex-exec (ветка ревьюера).
|
Поглощено: codex-exec (ветка ревьюера).
|
||||||
- Sandbox-инцидент CLI 0.144.1 (bwrap+userns vs AppArmor) и ловушка memfd
|
- Sandbox-инцидент CLI 0.144.1 (bwrap+userns vs AppArmor): при наблюдавшемся
|
||||||
(профиль на путь bwrap не цепляется — вешать на бинарь codex). Поглощено:
|
запуске через memfd помог профиль на бинарь Codex. Актуальная настройка
|
||||||
codex-exec + codex-sandbox-apparmor.md.
|
и границы этого обхода — в [codex-sandbox-apparmor.md](codex-sandbox-apparmor.md).
|
||||||
- Постановка через `/to-tickets` ложится в конвейер без трения; двойное
|
- Постановка через `/to-tickets` ложится в конвейер без трения; двойное
|
||||||
слепое ревью постановки окупилось (Клод — механика кода, Codex — уровень
|
слепое ревью постановки окупилось (Клод — механика кода, Codex — уровень
|
||||||
требований; пересечение 2 из ~15). Поглощено: SKILL.md этапы 1–2.
|
требований; пересечение 2 из ~15). Поглощено: SKILL.md этапы 1–2.
|
||||||
|
|||||||
Reference in new issue
Block a user