ревью: цикл задачи проверяет механику, метки сняты
Состав прогона постоянный: гейт, спеки, код, триаж; приёмник тем идёт, когда у проекта есть свои темы. Метка, разметка и проход review-scope упразднены, review-levels.md удалён, ось «метка» снята из axes.md. Ступень 4 ушла из цикла: review-proof упразднён через день после заведения, review-architecture переехал в code-deep-review вслед за adversary и ops. Темы security, operations и architecture закрывает review-code сверкой с записанными инвариантами, потолком 1 находка. Умолчание разметки действий перевёрнуто на инлайн; развилка осталась за необратимым, изменением дельта-спек и нарушенным инвариантом. Задачи из урожая заводятся по слову человека, а не шагом сценария. Чекпоинт назван единственным местом, где решается форма решения. Потеряны ось времени в цикле и суждение о форме после кода — обе потери названы в «Честном пределе» строкой границ покрытия. Журнал — тема 77.
This commit is contained in:
@@ -11,13 +11,12 @@
|
||||
пересказывается.
|
||||
|
||||
**OpenSpec — жёсткая предпосылка именно этого сценария** (SKILL.md,
|
||||
«Предпосылки»): на нём стоят шаги 2, 4 и 7 и проход `review-specs`.
|
||||
«Предпосылки»): на нём стоят шаги 2, 4 и 6 и проход `review-specs`.
|
||||
|
||||
Тонкая обёртка над каноническими скиллами `opsx:propose` / `opsx:apply` /
|
||||
`opsx:archive` — их шаги не переизобретаются, а **зовёт их агент**, не ты
|
||||
(SKILL.md, «Кто пишет: письмо уходит агентам»). Ревью — скилл
|
||||
`av-dev:code-review`; он же держит правило выбора метки, а называет её агент
|
||||
`review-scope` — один раз на задачу, **после того как код написан**.
|
||||
`av-dev:code-review`; состав его прогона постоянный, выбирать и размечать нечего.
|
||||
|
||||
## Ход работы
|
||||
|
||||
@@ -28,17 +27,15 @@ flowchart TD
|
||||
s2["2. opsx:propose — change, дельта-спеки,<br/>tasks.md — агентом"]
|
||||
s3(["3. ЧЕКПОИНТ: объяснение<br/>в чём проблема, как решаем,<br/>чем рискуем"])
|
||||
s4["4. opsx:apply — код, гейт,<br/>поведенческая верификация — агентом"]
|
||||
s5["5. разметка — review-scope по диффу:<br/>размер, сложность, метка, план тем"]
|
||||
s6["6. ревью кода по метке<br/>+ отработка замечаний агентом"]
|
||||
s7["7. opsx:archive + синк документации —<br/>одним агентом"]
|
||||
s8["8. коммит работы — av-dev-git:commit"]
|
||||
s9["9. закрыть задачу — av-dev:task-track,<br/>вторым коммитом учёта"]
|
||||
s5["5. ревью кода — постоянный состав<br/>+ отработка замечаний агентом"]
|
||||
s6["6. opsx:archive + синк документации —<br/>одним агентом"]
|
||||
s7["7. коммит работы — av-dev-git:commit"]
|
||||
s8["8. закрыть задачу — av-dev:task-track,<br/>вторым коммитом учёта"]
|
||||
|
||||
in --> s1
|
||||
s1 --> s2 --> s3 --> s4 --> s5 --> s6 --> s7 --> s8 --> s9
|
||||
s5 -.->|"план задачи: темы и глубины"| s6
|
||||
s1 --> s2 --> s3 --> s4 --> s5 --> s6 --> s7 --> s8
|
||||
s3 -.->|"скорректировать:<br/>правка спек и дизайна"| s3
|
||||
s6 -.->|"находка отменяет дизайн:<br/>меняются дельта-спеки"| s3
|
||||
s5 -.->|"находка отменяет дизайн:<br/>меняются дельта-спеки"| s3
|
||||
```
|
||||
|
||||
Схема — **сводка**: содержание каждого шага в его разделе ниже, и при
|
||||
@@ -63,8 +60,8 @@ flowchart TD
|
||||
Задача сделана, когда верно всё:
|
||||
|
||||
1. гейт проекта зелёный;
|
||||
2. ревью проведено, **план прогона сверен с исходом по каждой теме**, темы без
|
||||
отчёта и без дома названы в границах покрытия;
|
||||
2. ревью проведено, **перечень тем сверен с исходом по каждой**, темы без отчёта
|
||||
и без дома названы в границах покрытия;
|
||||
3. решение прошло чекпоинт и не разошлось с одобренным — либо разошлось, и
|
||||
чекпоинт был пройден заново;
|
||||
4. change заархивирован, дельты влиты в актуальные спеки;
|
||||
@@ -141,6 +138,13 @@ flowchart TD
|
||||
нечем: человек читает предложение как оно есть. Взамен стоп пришёл **раньше** —
|
||||
коррекция здесь стоит правки спеки, а не переписывания готового кода.
|
||||
|
||||
**Это единственное место процесса, где решается форма решения, и решает её
|
||||
человек.** Ревью после кода судит корректность и механику против записанного
|
||||
критерия; «то ли это решение» там не спрашивает ни один проход, а глубокое ревью
|
||||
области придёт позже и не всегда. Значит, чекпоинт — не формальность и не
|
||||
доклад о ходе работ: одобренное здесь уезжает в код без второго суждения о
|
||||
замысле.
|
||||
|
||||
**Объяснение не сочиняется заново — оно собирается из артефактов**, `proposal.md`
|
||||
и `design.md`. Третий пересказ был бы третьим домом одного и того же и разошёлся
|
||||
бы с обоими. Что показываешь:
|
||||
@@ -180,8 +184,7 @@ flowchart TD
|
||||
(SKILL.md, «Кто пишет»): сказанное человеком уходит ему дословно, вместе с
|
||||
идентификатором change и требованием перепрогнать
|
||||
`openspec validate --strict <id>`. Затем чекпоинт **заново** — правленое
|
||||
объяснение читает тот же человек. Разметки на этот момент ещё нет, и повторять
|
||||
здесь нечего: она идёт после кода;
|
||||
объяснение читает тот же человек;
|
||||
- **не одобрено** — исход «не доведена» с причиной. Change остаётся
|
||||
незаархивированным, задача не закрывается, ничего не коммитится наполовину.
|
||||
|
||||
@@ -192,7 +195,7 @@ flowchart TD
|
||||
поведенческая верификация. Возврат — адреса тронутого, исход гейта и строка
|
||||
верификации; диффа в нём нет. **Исход гейта возвращается сводкой, путём к логам
|
||||
шагов и отпечатком дерева** (SKILL.md, «Возврат — не длиннее экрана»): его
|
||||
передача на шаг 6 избавляет ревью от второго прогона того же гейта.
|
||||
передача на шаг 5 избавляет ревью от второго прогона того же гейта.
|
||||
|
||||
Код — по конвенциям проекта
|
||||
(каталог `docs/conventions/`). Меняешь схему — обнови её описание в документации
|
||||
@@ -208,87 +211,47 @@ flowchart TD
|
||||
**Сервис не оставляем лежать.** Если запуск упал — агент чинит или откатывает до
|
||||
конца шага; возврат с лежащим сервисом — незакрытый шаг, а не исход.
|
||||
|
||||
### 5. Разметка задачи — агент `review-scope`
|
||||
### 5. Ревью кода — состав постоянный
|
||||
|
||||
**Один запуск на всю задачу, и он идёт после кода.** Запусти агента
|
||||
`review-scope`, дав ему корень проекта, идентификатор change, базу диффа и запись
|
||||
задачи. Код уже написан, и **дифф — его источник размера**: он видит, сколько
|
||||
мест тронуто на самом деле, а не сколько обещала постановка.
|
||||
Вызови Skill **`av-dev:code-review`**, дав ссылку на change `<id>`, базу диффа,
|
||||
режим запуска и **исход гейта с шага 4** — сводку, путь к логам шагов и отпечаток
|
||||
дерева.
|
||||
|
||||
Он возвращает **план задачи**:
|
||||
|
||||
- **размер** (малое / среднее / крупное) и **сложность** (знакомое /
|
||||
незнакомое), каждое с обоснованием по факту;
|
||||
- **метку** как максимум по двум осям: `small`, `medium` или `large`;
|
||||
- **таблицу тем** «тема → дом → глубина → кто закрывает» — для шага 6;
|
||||
- разнесение документов проекта по трём категориям и строку про директивы.
|
||||
|
||||
**Метку выбираешь не ты, и это правило держится разведённостью.** Код только что
|
||||
написан по твоему заданию, и решать, насколько глубоко его проверять, тебе нельзя:
|
||||
под давлением «я почти закончил» решение известно заранее. Разметчик работу не
|
||||
писал, а обе оси выводит из фактов — из диффа и из постановки, — и обязан назвать
|
||||
признак по каждой.
|
||||
|
||||
**План держи в контексте до конца задачи.** На диск он не пишется: файл-план стал
|
||||
бы четвёртым артефактом рядом с `proposal.md`, `tasks.md` и `design.md`, пережил
|
||||
бы задачу и разошёлся бы с ней молча. Прервался прогон — повтори шаг 5, это самый
|
||||
дешёвый его проход.
|
||||
|
||||
**Разметка повторяется ровно в одном случае** — если правки изменили сами
|
||||
**дельта-спеки**: план выведен из задачи, и план по отменённым требованиям назовёт
|
||||
не те темы. Во всех прочих случаях, включая отработку находок инлайна на шаге 6,
|
||||
метка остаётся прежней: дифф от правок по находкам растёт, а задача — нет.
|
||||
|
||||
### 6. Ревью кода — по метке разметки
|
||||
|
||||
Вызови Skill **`av-dev:code-review`**, дав ссылку на change `<id>`,
|
||||
базу диффа, **план разметки с шага 5**, режим запуска и **исход гейта с шага 4** —
|
||||
сводку, путь к логам шагов и отпечаток дерева.
|
||||
|
||||
**Метку ты не выбираешь, и это правило, а не упрощение.** Её назвал
|
||||
`review-scope` шагом раньше — по размеру и сложности, с обоснованием по каждой
|
||||
оси; причина в разведённости, и она разобрана там же. Правило выбора живёт в
|
||||
скилле конвейера — `av-dev:code-review`, `references/review-levels.md`; проектные
|
||||
триггеры — в `docs/review.*`, подраздел «Триггеры метки».
|
||||
|
||||
**Метка, названная по диффу, внутри прогона больше не пересматривается.**
|
||||
Разметчик видел дифф целиком и посчитал по нему обе оси; второй запуск на том же
|
||||
дереве вернул бы то же самое.
|
||||
|
||||
**Считаешь метку заниженной — скажи это в докладе строкой, а не переспорь.**
|
||||
Разметчик вправе и поднять, и понизить; твоё несогласие это факт для человека, а
|
||||
не команда конвейеру. Место, где такое несогласие превращается в изменение
|
||||
правил, — журнал дефектов `docs/review.md`, и только постфактум.
|
||||
|
||||
**Плана нет — ревью кода не запускается.** Триаж требует план обязательным
|
||||
входом: без него он не может сверить, все ли размеченные темы вернули отчёт, а
|
||||
эта сверка — единственная защита от молчащего пропуска. Потерял план (прервалась
|
||||
сессия, ушёл контекст) — повтори шаг 5, а не гони прогон без него.
|
||||
**Выбирать и размечать нечего.** Состав прогона один и тот же на всякой задаче:
|
||||
гейт, сверка со спекой, разбор кода, триаж; приёмник тем идёт, когда у проекта
|
||||
есть свои темы. Прежде между кодом и ревью стоял отдельный проход разметки — он
|
||||
считал размер по диффу, сложность по постановке и выдавал метку, из которой
|
||||
выводился состав. Метка снята вместе с ним: цикл задачи проверяет корректность и
|
||||
механику, а этой работе нечего добавить и нечего убавить от размера изменения.
|
||||
|
||||
**Режим по умолчанию — `по графу`, и обосновывать его не надо.** Конвейер сам
|
||||
знает свои рёбра: гейт открывает проходы с мнением, проходы с пометкой «держит
|
||||
машину» идут цепочкой (иначе замеры портят друг друга и находка выглядит
|
||||
доказанной), триаж — сток. Просить **`линейно`** нужно только по причине, и она
|
||||
называется строкой: так сказал оператор; машина занята чем-то ещё; идёт разбор
|
||||
самого конвейера.
|
||||
знает свои рёбра: гейт открывает проходы с мнением, триаж — сток. Просить
|
||||
**`линейно`** нужно только по причине, и она называется строкой: так сказал
|
||||
оператор; машина занята чем-то ещё; идёт разбор самого конвейера.
|
||||
|
||||
Скилл сам гоняет гейт, нужные проходы и обязательный триаж. Возвращает отчёт с
|
||||
потолком 7 пунктов, разметкой `Действие: инлайн | развилка` и секцией границ
|
||||
покрытия.
|
||||
потолком 7 пунктов, разметкой `Действие: инлайн | развилка`, секцией `Урожай`,
|
||||
секцией отложенного в глубокое ревью и границами покрытия.
|
||||
|
||||
**Сверь план прогона с исходом, прежде чем коммитить.** Отчёт начинается планом
|
||||
разметчика — таблицей «тема → дом → глубина → кто закрывает», — и против каждой
|
||||
темы обязан стоять исход. Тема без отчёта и тема без дома — разные вещи, и обе
|
||||
должны быть названы. Реестр короткий — темы ядра плюс свои проекта, — и сверка стоит
|
||||
одного взгляда.
|
||||
**Сверь перечень тем с исходом, прежде чем коммитить.** Отчёт начинается таблицей
|
||||
«тема → кто закрывает → против чего», и против каждой темы обязан стоять исход.
|
||||
Тема без отчёта и тема без дома — разные вещи, и обе должны быть названы.
|
||||
Реестр постоянный и короткий, сверка стоит одного взгляда.
|
||||
|
||||
#### Отработка, и здесь появляется одно новое правило
|
||||
#### Отработка — чинится молча, спрашивается редко
|
||||
|
||||
Помеченное `инлайн` чинит **агент** (SKILL.md, «Кто пишет»): находки уходят ему
|
||||
**дословно, вместе с оракулом**, одним заданием на весь урожай инлайна, и гейт
|
||||
после правок гоняет он же. Логировать их по-прежнему не надо. `развилка` —
|
||||
вопросом в запись (он уже сформулирован триажем, его остаётся перенести), и
|
||||
агенту она не отдаётся.
|
||||
после правок гоняет он же. Логировать их не надо. **Это умолчание, и оно
|
||||
широкое** — прогон, вернувший человеку список замечаний вместо готового
|
||||
результата, свою работу не сделал.
|
||||
|
||||
`развилка` — вопросом в запись (он уже сформулирован триажем, его остаётся
|
||||
перенести), и агенту она не отдаётся. Оснований у неё три, и все узкие: правка
|
||||
меняет **дельта-спеки**, находка сидит в **необратимом** месте (миграция, формат
|
||||
на диске, публичный контракт), находка трогает **инвариант** `CLAUDE.md`.
|
||||
Развилок больше двух на задачу — это факт для доклада: либо задача не та, либо
|
||||
разметка действий съехала.
|
||||
|
||||
**Находка, отменяющая одобренный дизайн, отменяет и одобрение.** Признак
|
||||
проверяемый: **меняются ли дельта-спеки**.
|
||||
@@ -296,8 +259,8 @@ flowchart TD
|
||||
- не меняются — находка внутри дизайна, дожимай сам, это обычная отработка;
|
||||
- меняются — решение стало другим, а одобрено было прежнее. **Вернись на чекпоинт
|
||||
шага 3** с тем, что изменилось и почему; дальше задача идёт своим ходом заново —
|
||||
код, разметка, ревью. Такая находка агенту не отдаётся ни при каких условиях:
|
||||
она отменяет одобрение, а это разговор с человеком.
|
||||
код, ревью. Такая находка агенту не отдаётся ни при каких условиях: она отменяет
|
||||
одобрение, а это разговор с человеком.
|
||||
|
||||
**Это правило старше правила о развилке.** Находка класса `развилка`, чьё
|
||||
основание — «надо менять спеку», подпадает под оба; побеждает возврат на
|
||||
@@ -308,31 +271,44 @@ flowchart TD
|
||||
ревью, не значит ничего, а человек при этом уверен, что одобрил именно то, что
|
||||
уехало в коммит.
|
||||
|
||||
**Урожай — списком, не задачами.** Отложенные находки (реальный `major` не для
|
||||
этого мерджа, развилка, решённая «потом», пачка `nit`) собери в секцию доклада
|
||||
`Урожай`: формулировка, оракул, откуда взялась. Задачи из него **заводит не этот
|
||||
скилл** — их заводит `av-dev:task-track` своим сценарием «задачи из ревью и
|
||||
аудита»: своя нарезка, свой формат, свои правила дублей. Твоя обязанность — не
|
||||
потерять и передать.
|
||||
#### Урожай — список в докладе, задачи только по слову человека
|
||||
|
||||
Отложенные находки (реальный `major` не для этого мерджа, развилка, решённая
|
||||
«потом», пачка `nit`) собери в секцию доклада `Урожай`: формулировка, оракул,
|
||||
откуда взялась.
|
||||
|
||||
**Задачи из урожая заводятся только тогда, когда человек сказал «заводим».**
|
||||
Покажи список одной репликой и спроси. Сказал — зови `av-dev:task-track`, у него
|
||||
на этот вход отдельный сценарий «задачи из ревью и аудита»: своя нарезка, свой
|
||||
формат, свои правила дублей, и передавать находку туда надо дословно. Не сказал —
|
||||
урожай остаётся строками доклада, и это исход, а не потеря.
|
||||
|
||||
**Молча беклог не наполняется.** Очередь работ ведёт человек, и задача, заведённая
|
||||
за него по ходу чужого прогона, отнимает у него ровно то решение, ради которого
|
||||
очередь и существует. Прежде вызов `av-dev:task-track` был обязательным шагом —
|
||||
теперь он шаг по ответу.
|
||||
|
||||
**Границы покрытия из отчёта не выбрасывай** — они уезжают в финальный доклад
|
||||
сжатой строкой. Отчёт, из которого исчезло «что проверить было невозможно»,
|
||||
превращается в ложное ощущение проверенности.
|
||||
|
||||
**Строку «отложено в `av-dev:code-deep-review`» перенеси дословно.** Проход
|
||||
`review-proof` называет в ней тему, место и запуск, которым это проверяется, —
|
||||
всё, что доказывается только прогоном и замером, цикл задачи не доказывает ни на
|
||||
одной метке. Эти строки копятся и однажды становятся поводом позвать глубокое
|
||||
ревью области; пересказанные своими словами, они теряют оракул и перестают быть
|
||||
поводом.
|
||||
**Строки «отложено в `av-dev:code-deep-review`» перенеси дословно.** Их пишут
|
||||
проходы, упёршиеся в предел цикла: нужен замер, нужен прогнанный путь, нужен вход
|
||||
шире диффа. В цикле задачи это не доказывается ничем, а строки копятся и однажды
|
||||
становятся поводом позвать глубокое ревью области; пересказанные своими словами,
|
||||
они теряют оракул и перестают быть поводом.
|
||||
|
||||
**Отчёт триажа сохрани вместе с change (`openspec/changes/<id>/review/`; шаг 7
|
||||
**Сигнал «это изменение просит глубокого ревью»** приходит от `review-code` и
|
||||
подтверждается `review-basics`. Он не команда и не стоп — строка доклада: когда
|
||||
звать глубокий прогон, решает человек.
|
||||
|
||||
**Отчёт триажа сохрани вместе с change (`openspec/changes/<id>/review/`; шаг 6
|
||||
унесёт его в архив вместе с change) — это обязательно, а не «если удобно».** По
|
||||
нему потом видно, что было найдено и что из этого осталось в урожае. И это
|
||||
единственный **независимый** артефакт о составе прогона: своей прозе здесь верить
|
||||
нельзя — она написана тем же, кто мог проход и пропустить.
|
||||
нельзя — её написал тот, кто мог проход и пропустить.
|
||||
|
||||
### 7. Архивация и синк документации — одним агентом
|
||||
### 6. Архивация и синк документации — одним агентом
|
||||
|
||||
**Оба шага уходят одному агенту, и это один запуск** (SKILL.md, «Кто пишет»).
|
||||
Работа здесь письменная от начала до конца: `opsx:archive` вливает дельты в
|
||||
@@ -373,7 +349,7 @@ flowchart TD
|
||||
задачу нельзя: документ, заведённый мимо канона, окажется вторым домом ровно
|
||||
тому, что канон потом заведёт своим.
|
||||
|
||||
### 8. Коммит
|
||||
### 7. Коммит
|
||||
|
||||
Коммить **в текущую ветку** (`git rev-parse --abbrev-ref HEAD`), сам ветку не
|
||||
создавай и не переключай, ничего не пушь.
|
||||
@@ -383,14 +359,14 @@ flowchart TD
|
||||
напиши сообщение сам и скажи строкой доклада, что форму коммита не сверял никто.
|
||||
Одна задача — один осмысленный коммит.
|
||||
|
||||
### 9. Закрыть задачу — **после коммита, не раньше**
|
||||
### 8. Закрыть задачу — **после коммита, не раньше**
|
||||
|
||||
**Вызови Skill `av-dev:task-track`** и попроси закрыть задачу как реализованную —
|
||||
он владеет форматом и двигает строку индекса сам. Путь к его скрипту не выясняй и
|
||||
индексы руками не правь: мост между плагинами — вызов скилла, а не путь.
|
||||
|
||||
**Порядок обязателен.** Закрытие удаляет файл задачи; сделанное до коммита оно
|
||||
оставило бы задачу закрытой без единого следа работы, если шаг 8 упадёт.
|
||||
оставило бы задачу закрытой без единого следа работы, если шаг 7 упадёт.
|
||||
|
||||
**Закрытие тоже коммитится — вторым коммитом, тут же.** Удаление файла задачи и
|
||||
правка индексов (их имена знает `av-dev:task-track`, не ты) — это правки в рабочем
|
||||
@@ -418,8 +394,12 @@ change. Заводить запись задним числом, чтобы её
|
||||
- ссылка на архивный change и хеш коммита;
|
||||
- по каждому критерию приёмки, если они были: **оракул и наблюдаемый исход** —
|
||||
это доклад приёмщику, а не отметка «принято»;
|
||||
- **`Урожай`** — отложенные находки списком (формулировка, оракул, откуда взялась);
|
||||
- **одна строка границ покрытия**: какая метка и режим гонялись, какие проходы не
|
||||
- **`Урожай`** — отложенные находки списком (формулировка, оракул, откуда
|
||||
взялась) и **что человек по нему решил**: заведены задачи или список остался в
|
||||
докладе;
|
||||
- **сколько находок ушло инлайном и сколько развилкой** — числом. По нему видно,
|
||||
во что прогон обошёлся человеку;
|
||||
- **одна строка границ покрытия**: какой режим гонялся, какие проходы не
|
||||
запускались и что проверить было невозможно;
|
||||
- **отложенное в `av-dev:code-deep-review`** — дословно из отчёта, либо «нечего». Доклад без неё сообщает
|
||||
«проверено», не сообщая, что именно.
|
||||
@@ -430,14 +410,15 @@ change. Заводить запись задним числом, чтобы её
|
||||
перезапускать, а не «посмотреть заодно».
|
||||
- Стиль правок — заточка под проект и конвенции, по размеру задачи, без
|
||||
улучшений заодно.
|
||||
- **Занизить метку ревью, пропустить тему или проскочить чекпоинт — самый дешёвый
|
||||
способ «ускориться», и он же самый дорогой по последствиям.** Защита устроена
|
||||
так, что регулятора у тебя нет: метку выбирает **не ты, а разметчик, и выводит
|
||||
её из диффа**, план сверяется по темам, непокрытое называется строкой, а
|
||||
расхождение с одобренным — отдельным пунктом доклада.
|
||||
- **Заведение задач из урожая ревью — не твоя работа.** Отложенные находки
|
||||
отдаются **списком**; превращает их в задачи `av-dev:task-track`, у него на
|
||||
этот вход отдельный сценарий «задачи из ревью и аудита». Каталога задач в
|
||||
- **Пропустить тему или проскочить чекпоинт — самый дешёвый способ «ускориться»,
|
||||
и он же самый дорогой по последствиям.** Защита устроена так, что регулятора у
|
||||
тебя нет: состав прогона постоянный и сокращению не подлежит, перечень тем
|
||||
сверяется по исходу, непокрытое называется строкой, а расхождение с одобренным
|
||||
— отдельным пунктом доклада.
|
||||
- **Заведение задач из урожая ревью — не твоя работа и не работа этого прогона по
|
||||
умолчанию.** Отложенные находки отдаются **списком**, и в задачи их превращает
|
||||
`av-dev:task-track` — по слову человека, у него на этот вход отдельный сценарий
|
||||
«задачи из ревью и аудита». Каталога задач в
|
||||
проекте нет — урожай остаётся списком в докладе, и это говорится строкой.
|
||||
- **Способ решения ты не выбираешь.** Он приходит известным: из постановки, из
|
||||
разведки, от человека. Выбор между двумя подходами с разной ценой делается в
|
||||
|
||||
Reference in New Issue
Block a user