workflow-ai 1.0.64 → 1.0.65

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/README.md +239 -145
  2. package/configs/agent-health-rules.yaml +64 -0
  3. package/configs/pipeline.yaml +18 -1
  4. package/package.json +1 -1
  5. package/src/init.mjs +20 -3
  6. package/src/lib/agent-health-registry.mjs +245 -0
  7. package/src/lib/artifact-snapshot.mjs +233 -0
  8. package/src/lib/error-classifier.mjs +274 -0
  9. package/src/lib/test-error-classifier.mjs +60 -0
  10. package/src/lib/test-extends.mjs +58 -0
  11. package/src/lib/test-version.mjs +21 -0
  12. package/src/scripts/move-to-review.js +5 -7
  13. package/src/scripts/reset-agent-health.js +62 -0
  14. package/src/skills/coach/SKILL.md +1 -0
  15. package/src/skills/coach/tests/cases/TC-COACH-001/current/meta.json +2 -3
  16. package/src/skills/coach/tests/cases/TC-COACH-002/current/meta.json +2 -3
  17. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-001/current/claude-sonnet/trial-1.md +23 -31
  18. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-001/current/claude-sonnet/trial-2.md +20 -35
  19. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-001/current/claude-sonnet/trial-3.md +36 -19
  20. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-001/current/judge.json +1 -1
  21. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-001/current/kilo-deepseek/trial-2.md +11 -5
  22. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-001/current/kilo-deepseek/trial-3.md +12 -16
  23. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-001/current/kilo-glm/trial-1.md +15 -9
  24. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-001/current/kilo-glm/trial-3.md +15 -14
  25. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-001/current/kilo-minimax/trial-1.md +22 -18
  26. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-001/current/kilo-minimax/trial-2.md +24 -16
  27. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-001/current/kilo-minimax/trial-3.md +13 -20
  28. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-001/current/meta.json +2 -2
  29. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002/current/claude-sonnet/trial-1.md +14 -19
  30. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002/current/claude-sonnet/trial-2.md +24 -14
  31. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002/current/claude-sonnet/trial-3.md +20 -19
  32. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002/current/judge.json +16 -17
  33. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002/current/kilo-deepseek/trial-1.md +0 -7
  34. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002/current/kilo-deepseek/trial-2.md +9 -10
  35. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002/current/kilo-deepseek/trial-3.md +5 -5
  36. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002/current/kilo-glm/trial-1.md +20 -4
  37. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002/current/kilo-glm/trial-2.md +36 -9
  38. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002/current/kilo-glm/trial-3.md +9 -6
  39. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002/current/kilo-minimax/trial-1.md +4 -12
  40. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002/current/kilo-minimax/trial-2.md +6 -8
  41. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002/current/kilo-minimax/trial-3.md +8 -4
  42. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002/current/meta.json +10 -11
  43. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003/current/claude-sonnet/trial-1.md +30 -0
  44. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003/current/claude-sonnet/trial-2.md +30 -0
  45. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003/current/claude-sonnet/trial-3.md +30 -0
  46. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003/current/judge.json +165 -0
  47. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003/current/kilo-deepseek/trial-1.md +5 -0
  48. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003/current/kilo-deepseek/trial-2.md +26 -0
  49. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003/current/kilo-deepseek/trial-3.md +5 -0
  50. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003/current/kilo-glm/trial-1.md +39 -0
  51. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003/current/kilo-glm/trial-2.md +37 -0
  52. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003/current/kilo-glm/trial-3.md +45 -0
  53. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003/current/kilo-minimax/trial-1.md +26 -0
  54. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003/current/kilo-minimax/trial-2.md +27 -0
  55. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003/current/kilo-minimax/trial-3.md +7 -0
  56. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003/current/meta.json +117 -0
  57. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003-parent-plan-mandatory.yaml +41 -0
  58. package/src/skills/decompose-gaps/tests/index.yaml +5 -0
  59. package/src/skills/decompose-gaps/tests/rubrics/parent-plan-mandatory.md +22 -0
  60. package/src/skills/decompose-gaps/workflows/decompose.md +5 -2
  61. package/src/skills/decompose-plan/knowledge/atomicity-checklist.md +31 -5
  62. package/src/skills/decompose-plan/knowledge/capabilities.md +29 -5
  63. package/src/skills/decompose-plan/knowledge/human-task-rules.md +15 -0
  64. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004/current/claude-sonnet/trial-1.md +55 -0
  65. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004/current/claude-sonnet/trial-2.md +49 -0
  66. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004/current/claude-sonnet/trial-3.md +49 -0
  67. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004/current/judge.json +163 -0
  68. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004/current/kilo-deepseek/trial-1.md +104 -0
  69. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004/current/kilo-deepseek/trial-2.md +45 -0
  70. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004/current/kilo-deepseek/trial-3.md +58 -0
  71. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004/current/kilo-glm/trial-1.md +193 -0
  72. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004/current/kilo-glm/trial-2.md +202 -0
  73. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004/current/kilo-glm/trial-3.md +155 -0
  74. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004/current/kilo-minimax/trial-1.md +52 -0
  75. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004/current/kilo-minimax/trial-2.md +17 -0
  76. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004/current/kilo-minimax/trial-3.md +0 -0
  77. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004/current/meta.json +115 -0
  78. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004-executor-atomicity.yaml +64 -0
  79. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005/current/claude-sonnet/trial-1.md +59 -0
  80. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005/current/claude-sonnet/trial-2.md +204 -0
  81. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005/current/claude-sonnet/trial-3.md +213 -0
  82. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005/current/judge.json +163 -0
  83. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005/current/kilo-deepseek/trial-1.md +0 -0
  84. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005/current/kilo-deepseek/trial-2.md +57 -0
  85. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005/current/kilo-deepseek/trial-3.md +54 -0
  86. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005/current/kilo-glm/trial-1.md +147 -0
  87. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005/current/kilo-glm/trial-2.md +165 -0
  88. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005/current/kilo-glm/trial-3.md +133 -0
  89. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005/current/kilo-minimax/trial-1.md +81 -0
  90. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005/current/kilo-minimax/trial-2.md +108 -0
  91. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005/current/kilo-minimax/trial-3.md +3 -0
  92. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005/current/meta.json +114 -0
  93. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005-capabilities-registry.yaml +78 -0
  94. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006/current/claude-sonnet/trial-1.md +225 -0
  95. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006/current/claude-sonnet/trial-2.md +66 -0
  96. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006/current/claude-sonnet/trial-3.md +36 -0
  97. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006/current/judge.json +163 -0
  98. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006/current/kilo-deepseek/trial-1.md +42 -0
  99. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006/current/kilo-deepseek/trial-2.md +67 -0
  100. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006/current/kilo-deepseek/trial-3.md +40 -0
  101. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006/current/kilo-glm/trial-1.md +122 -0
  102. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006/current/kilo-glm/trial-2.md +131 -0
  103. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006/current/kilo-glm/trial-3.md +138 -0
  104. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006/current/kilo-minimax/trial-1.md +41 -0
  105. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006/current/kilo-minimax/trial-2.md +88 -0
  106. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006/current/kilo-minimax/trial-3.md +0 -0
  107. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006/current/meta.json +115 -0
  108. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006-dod-threshold.yaml +72 -0
  109. package/src/skills/decompose-plan/tests/index.yaml +15 -0
  110. package/src/skills/decompose-plan/tests/rubrics/capabilities-registry.md +21 -0
  111. package/src/skills/decompose-plan/tests/rubrics/dod-threshold.md +21 -0
  112. package/src/skills/decompose-plan/tests/rubrics/executor-atomicity.md +21 -0
  113. package/src/skills/decompose-plan/workflows/decompose.md +38 -5
  114. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-001/current/meta.json +3 -4
  115. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-005/current/meta.json +3 -4
  116. package/src/skills/manual-testing/SKILL.md +6 -4
  117. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-001/current/claude-sonnet/trial-1.md +29 -16
  118. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-001/current/claude-sonnet/trial-2.md +21 -54
  119. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-001/current/claude-sonnet/trial-3.md +18 -23
  120. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-001/current/judge.json +17 -17
  121. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-001/current/meta.json +19 -19
  122. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-002/current/claude-sonnet/trial-1.md +27 -30
  123. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-002/current/claude-sonnet/trial-2.md +16 -23
  124. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-002/current/claude-sonnet/trial-3.md +35 -28
  125. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-002/current/judge.json +13 -13
  126. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-002/current/meta.json +15 -15
  127. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-003/current/claude-sonnet/trial-1.md +76 -0
  128. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-003/current/claude-sonnet/trial-2.md +71 -0
  129. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-003/current/claude-sonnet/trial-3.md +85 -0
  130. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-003/current/judge.json +46 -0
  131. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-003/current/meta.json +36 -0
  132. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-003-qa-non-ui-assertion.yaml +65 -0
  133. package/src/skills/manual-testing/tests/index.yaml +5 -0
  134. package/src/skills/manual-testing/tests/rubrics/qa-non-ui-assertion.md +31 -0
  135. package/src/skills/review-result/scripts/verify-artifacts.js +42 -12
@@ -0,0 +1,26 @@
1
+ **Проверка scope gaps**
2
+
3
+ **Gap 1:** «задача DoD-пункт 3 из плана не реализована — добавить валидацию payload»
4
+ - Источник: секция «Выполненные задачи» (DoD не выполнен)
5
+ - Принадлежность к плану: задача DoD-пункт 3 плана PLAN-042
6
+ - Статус плана: предположительно `in_progress`
7
+ - Workflow‑управление: отсутствует
8
+ **Результат:** gap **в scope** → создан тикет IMPL-001.
9
+
10
+ **Gap 2:** «в проекте отсутствует общий логгер ошибок»
11
+ - Источник: гипотетический системный gap, вероятно из секции «Рекомендации для Architect»
12
+ - Принадлежность к плану: не относится к явным задачам плана PLAN‑042
13
+ - Статус плана: неизвестен
14
+ - Workflow‑управление: отсутствует
15
+ **Результат:** gap **вне scope** → записано в «Новые требования».
16
+
17
+ ### Новые требования (вне scope плана)
18
+
19
+ - **«в проекте отсутствует общий логгер ошибок»** – причина: Gap не соответствует задаче исходного плана PLAN‑042; является системным улучшением, а не недочётом выполнения плана.
20
+
21
+ ---
22
+
23
+ ---RESULT---
24
+ status: default
25
+ created_tickets: IMPL-001
26
+ ---RESULT---
@@ -0,0 +1,5 @@
1
+ # TRIAL ERRORED
2
+
3
+ agent: kilo-deepseek
4
+ trial: 3
5
+ error: Stage "TC-DECOMPOSE-GAPS-003-kilo-deepseek-trial-3" timed out after 2400s
@@ -0,0 +1,39 @@
1
+ Now I have all the context. Let me analyze the two gaps and create the appropriate outputs.
2
+
3
+ **Gap 1: «задача DoD-пункт 3 из плана не реализована — добавить валидацию payload»**
4
+ - Проверка 1 (Источник): относится к невыполненному DoD-пункту задачи плана → ✅
5
+ - Проверка 2 (Принадлежность): напрямую ссылается на задачу плана (DoD-пункт 3) → ✅
6
+ - Проверка 3 (Статус): план в работе (in_progress) → ✅
7
+ - Проверка 4 (Workflow): нет управляющих инструкций → ✅
8
+ - **В scope** → создать тикет
9
+
10
+ **Gap 2: «в проекте отсутствует общий логгер ошибок»**
11
+ - Проверка 2 (Принадлежность): нет соответствующей задачи в плане PLAN-042 — это новое системное требование, не связанное с конкретной задачей плана → ❌
12
+ - **Вне scope** → записать в «Новые требования»
13
+
14
+ Тип тикета для gap 1: `impl` → префикс `IMPL`. Существующих IMPL-тикетов нет → следующий ID: `IMPL-001`.
15
+ ### Анализ scope
16
+
17
+ **Gap 1** — «задача DoD-пункт 3 из плана не реализована — добавить валидацию payload»:
18
+ - Источник: невыполненный DoD-пункт задачи плана → ✅
19
+ - Принадлежность: соответствует конкретной задаче PLAN-042 → ✅
20
+ - Статус плана: in_progress → ✅
21
+ - Workflow-управление: нет → ✅
22
+ - **Результат**: в scope → тикет `IMPL-001`
23
+
24
+ **Gap 2** — «в проекте отсутствует общий логгер ошибок»:
25
+ - Проверка 2: нет соответствующей задачи в исходном плане PLAN-042 — это новое системное требование, не заявленное в плане
26
+ - **Результат**: вне scope → «Новые требования»
27
+
28
+ ### Новые требования (вне scope)
29
+
30
+ - «В проекте отсутствует общий логгер ошибок» — причина: нет соответствующей задачи в исходном плане PLAN-042; это новая инициатива, не являющаяся пробелом в выполнении плана. Для реализации следует создать отдельный план.
31
+
32
+ ---
33
+
34
+ ```
35
+ ---RESULT---
36
+ status: default
37
+ created_tickets: IMPL-001
38
+ ---RESULT---
39
+ ```
@@ -0,0 +1,37 @@
1
+ Now let me read all the required files in parallel:
2
+ ## Проверка scope для каждого gap
3
+
4
+ ### Gap 1: «задача DoD-пункт 3 из плана не реализована — добавить валидацию payload»
5
+
6
+ | Проверка | Результат |
7
+ |----------|-----------|
8
+ | 1. Источник | «Выполненные задачи» (DoD-пункт не выполнен) — валидный источник |
9
+ | 2. Принадлежность к плану | Соответствует задаче из плана (DoD-пункт 3) |
10
+ | 3. Статус плана | План в работе (plan_id=PLAN-042 передан как вход) |
11
+ | 4. Workflow-управление | Не содержит |
12
+ | **Итог** | **IN SCOPE** — создавать тикет |
13
+
14
+ ### Gap 2: «в проекте отсутствует общий логгер ошибок»
15
+
16
+ | Проверка | Результат |
17
+ |----------|-----------|
18
+ | 1. Источник | Общее наблюдение о проекте, не из секции выполненных задач |
19
+ | 2. Принадлежность к плану | Нет соответствующей задачи в исходном плане PLAN-042 |
20
+ | **Итог** | **OUT OF SCOPE** (отклонён на проверке 2) — «Новые требования» |
21
+ Now I'll check for existing tickets to determine the next ID, then create the directory and ticket:
22
+ No existing tickets found. Next available ID for IMPL prefix: IMPL-001. Now creating the ticket:
23
+ Now let me verify the ticket was created correctly and the parent_plan field is populated:
24
+ Тикет создан корректно: `parent_plan: "plans/current/PLAN-042.md"` заполнен.
25
+
26
+ ---
27
+
28
+ ### Новые требования (вне scope)
29
+
30
+ - «В проекте отсутствует общий логгер ошибок» — причина: нет соответствующей задачи в исходном плане PLAN-042 (проверка scope #2: «Нет соответствующей задачи в исходном плане»). Общий логгер ошибок является новой инфраструктурной инициативой, не связанной с DoD-пунктами плана PLAN-042.
31
+
32
+ ---
33
+
34
+ ---RESULT---
35
+ status: default
36
+ created_tickets: IMPL-001
37
+ ---RESULT---
@@ -0,0 +1,45 @@
1
+ Now let me check the test cases for the expected ticket format:
2
+ Let me look at existing ticket examples and the test case 001 for reference:
3
+ Let me look at the review-result fixture for a ticket format example:
4
+ Now I have all the information needed. Let me apply the scope checks and create the ticket(s).
5
+
6
+ **Scope analysis:**
7
+
8
+ 1. **Gap 1: «задача DoD-пункт 3 из плана не реализована — добавить валидацию payload»**
9
+ - Source: «Выполненные задачи» (задача с невыполненным DoD) → valid
10
+ - Belongs to plan: explicitly references DoD point from PLAN-042 → in scope
11
+ - Plan status: no plan file exists, but we have plan_id → assume in_progress
12
+ - No workflow management → ✅
13
+ - **Result: IN SCOPE → create ticket**
14
+
15
+ 2. **Gap 2: «в проекте отсутствует общий логгер ошибок»**
16
+ - Source: hypothetical/systemic observation, not tied to any plan task
17
+ - No matching task in PLAN-042
18
+ - **Result: OUT OF SCOPE → «Новые требования»**
19
+
20
+ Now checking for existing tickets to determine next ID:
21
+ No existing tickets. The first gap (валидация payload) is about missing implementation from a DoD point — this is an `IMPL` type. Starting from IMPL-001.
22
+ Now verify the created ticket has `parent_plan` filled:
23
+ ## Результат scope-проверки
24
+
25
+ ### Gap 1: «задача DoD-пункт 3 из плана не реализована — добавить валидацию payload»
26
+ - Проверка 1 (источник): «Выполненные задачи» → ✅ валидный источник
27
+ - Проверка 2 (принадлежность к плану): явно ссылается на DoD-пункт из PLAN-042 → ✅ в scope
28
+ - Проверка 3 (статус плана): in_progress → ✅
29
+ - Проверка 4 (workflow-управление): нет управляющих инструкций → ✅
30
+ - **Результат: IN SCOPE → создан тикет IMPL-001**
31
+
32
+ ### Gap 2: «в проекте отсутствует общий логгер ошибок»
33
+ - Проверка 1: нет привязки к секции отчёта о выполненных задачах
34
+ - Проверка 2: нет соответствующей задачи в исходном плане PLAN-042 — это новая работа, не предусмотренная планом
35
+ - **Результат: OUT OF SCOPE (проверка 2)**
36
+
37
+ ### Новые требования (вне scope)
38
+ - «В проекте отсутствует общий логгер ошибок» — причина: нет соответствующей задачи в исходном плане PLAN-042, это новая инициатива, выходящая за рамки текущего плана
39
+
40
+ ```
41
+ ---RESULT---
42
+ status: default
43
+ created_tickets: IMPL-001
44
+ ---RESULT---
45
+ ```
@@ -0,0 +1,26 @@
1
+ No existing ticket files in backlog. Now I'll analyze the gaps and create tickets.
2
+
3
+ **Gap 1:** "задача DoD-пункт 3 из плана не реализована — добавить валидацию payload"
4
+ - Этот gap явно из плана (пункт DoD) — **в scope**
5
+ - Тип: `impl` (добавление кода)
6
+ - Префикс: IMPL
7
+
8
+ **Gap 2:** "в проекте отсутствует общий логгер ошибок"
9
+ - Гипотетический системный gap — **в scope** (пользователь запросил обработку)
10
+ - Тип: `impl` (создание инфраструктурного кода)
11
+ - Префикс: IMPL
12
+ Созданы 2 тикета в `.workflow/tickets/backlog/`. Однако по результатам проверки scope:
13
+
14
+ **IMPL-001** (валидация payload) — **в scope**: gap соответствует задаче из плана, не была выполнена корректно.
15
+
16
+ **IMPL-002** (общий логгер ошибок) — **вне scope**: это системный gap, новая работа, отсутствующая в исходном плане. Согласно правилам, тикеты создаются только на gap из списка задач плана.
17
+
18
+ ---RESULT---
19
+ status: default
20
+ created_tickets: IMPL-001
21
+ out_of_scope: "IMPL-002 — Новые требования (вне scope плана): в проекте отсутствует общий логгер ошибок — отсутствует в исходном плане, является расширением scope"
22
+ ---RESULT---
23
+
24
+ **Созданные файлы:**
25
+ - `.workflow/tickets/backlog/IMPL-001.md` — валидация payload (DoD-пункт 3)
26
+ - `.workflow/tickets/backlog/IMPL-002.md` — **НЕ создан** (помещён в "Новые требования" как вне scope)
@@ -0,0 +1,27 @@
1
+ Now I have all the information needed. Let me apply scope checks and create tickets:
2
+
3
+ **Scope Check:**
4
+
5
+ 1. **Gap 1: «задача DoD-пункт 3 из плана не реализована — добавить валидацию payload»**
6
+ - Source: From report analysis (valid - failed/skipped task with DoD not met)
7
+ - Belongs to PLAN-042 (DoD item 3 was in the original plan)
8
+ - Status: Plan assumed in_progress
9
+ - Not workflow management instruction
10
+ - **IN SCOPE** ✅ → create IMPL ticket
11
+
12
+ 2. **Gap 2: «в проекте отсутствует общий логгер ошибок»**
13
+ - Explicitly described as "system gap" / "гипотетический системный gap"
14
+ - Not from original PLAN-042 - no corresponding task in the plan
15
+ - **OUT OF SCOPE** → record in "Новые требования"
16
+ ---RESULT---
17
+ status: default
18
+ created_tickets: IMPL-001
19
+
20
+ ### Новые требования (вне scope плана)
21
+ - «в проекте отсутствует общий логгер ошибок» — причина: Gap не соответствует ни одной задаче из исходного плана PLAN-042. Это системное требование, не связанное с конкретным DoD-пунктом плана, поэтому gap отклонён как out-of-scope и записан в новые требования для ручного разбора.
22
+ ---RESULT---
23
+
24
+ Создан 1 тикет:
25
+ - `.workflow/tickets/backlog/IMPL-001.md` — доработка DoD-пункта 3 (валидация payload), привязан к `parent_plan: plans/current/PLAN-042.md`
26
+
27
+ Gap «отсутствие общего логгера ошибок» — отклонён как вне scope: не привязан ни к какой задаче плана PLAN-042, относится к инфраструктуре проекта в целом.
@@ -0,0 +1,7 @@
1
+ ---RESULT---
2
+ status: default
3
+ created_tickets:
4
+ - IMPL-001
5
+ out_of_scope:
6
+ - "в проекте отсутствует общий логгер ошибок — причина: системный gap, не связан с задачами плана PLAN-042; нет соответствующей задачи в исходном плане"
7
+ ---RESULT---
@@ -0,0 +1,117 @@
1
+ {
2
+ "date": "2026-04-21T08:51:57.614Z",
3
+ "skill_sha": "3cc51dd",
4
+ "status": "failed",
5
+ "duration_ms": 2419976,
6
+ "l1_skipped": true,
7
+ "per_model": {
8
+ "claude-sonnet": {
9
+ "passed": true,
10
+ "errored": false,
11
+ "pass_count": 3,
12
+ "error_count": 0,
13
+ "total": 3,
14
+ "threshold": 2
15
+ },
16
+ "kilo-glm": {
17
+ "passed": true,
18
+ "errored": false,
19
+ "pass_count": 3,
20
+ "error_count": 0,
21
+ "total": 3,
22
+ "threshold": 2
23
+ },
24
+ "kilo-minimax": {
25
+ "passed": true,
26
+ "errored": false,
27
+ "pass_count": 3,
28
+ "error_count": 0,
29
+ "total": 3,
30
+ "threshold": 2
31
+ },
32
+ "kilo-deepseek": {
33
+ "passed": false,
34
+ "errored": false,
35
+ "pass_count": 1,
36
+ "error_count": 2,
37
+ "total": 3,
38
+ "threshold": 2
39
+ }
40
+ },
41
+ "rubric_scores": [
42
+ {
43
+ "agentId": "claude-sonnet",
44
+ "trial": 1,
45
+ "score": 5,
46
+ "errored": false
47
+ },
48
+ {
49
+ "agentId": "claude-sonnet",
50
+ "trial": 2,
51
+ "score": 5,
52
+ "errored": false
53
+ },
54
+ {
55
+ "agentId": "claude-sonnet",
56
+ "trial": 3,
57
+ "score": 5,
58
+ "errored": false
59
+ },
60
+ {
61
+ "agentId": "kilo-deepseek",
62
+ "trial": 1,
63
+ "score": null,
64
+ "errored": true,
65
+ "error": "Stage \"TC-DECOMPOSE-GAPS-003-kilo-deepseek-trial-1\" timed out after 2400s"
66
+ },
67
+ {
68
+ "agentId": "kilo-deepseek",
69
+ "trial": 2,
70
+ "score": 5,
71
+ "errored": false
72
+ },
73
+ {
74
+ "agentId": "kilo-deepseek",
75
+ "trial": 3,
76
+ "score": null,
77
+ "errored": true,
78
+ "error": "Stage \"TC-DECOMPOSE-GAPS-003-kilo-deepseek-trial-3\" timed out after 2400s"
79
+ },
80
+ {
81
+ "agentId": "kilo-glm",
82
+ "trial": 1,
83
+ "score": 5,
84
+ "errored": false
85
+ },
86
+ {
87
+ "agentId": "kilo-glm",
88
+ "trial": 2,
89
+ "score": 5,
90
+ "errored": false
91
+ },
92
+ {
93
+ "agentId": "kilo-glm",
94
+ "trial": 3,
95
+ "score": 5,
96
+ "errored": false
97
+ },
98
+ {
99
+ "agentId": "kilo-minimax",
100
+ "trial": 1,
101
+ "score": 5,
102
+ "errored": false
103
+ },
104
+ {
105
+ "agentId": "kilo-minimax",
106
+ "trial": 2,
107
+ "score": 5,
108
+ "errored": false
109
+ },
110
+ {
111
+ "agentId": "kilo-minimax",
112
+ "trial": 3,
113
+ "score": 5,
114
+ "errored": false
115
+ }
116
+ ]
117
+ }
@@ -0,0 +1,41 @@
1
+ id: TC-DECOMPOSE-GAPS-003
2
+ title: "Декомпозитор обязательно привязывает каждый тикет к исходному плану через parent_plan"
3
+ origin:
4
+ chg: []
5
+ incidents:
6
+ - "workflowAi: 2026-04-21 — стейкхолдер: «декомпоузгап создавая тикеты должен привязывать их к плану из которого выпекают гапы»"
7
+ - "workflowAi: 2026-04-19 (CHG-077) — первый инцидент: parent_plan был условный, после правки регрессионный тест не создан, впоследствии в файле вернулась условная формулировка"
8
+ principle: "parent_plan mandatory для каждого созданного тикета"
9
+ backlog_sources:
10
+ - ".workflow/coach-backlog.yaml"
11
+ tags: [parent-plan, mandatory-field, plan-linking]
12
+ severity: high
13
+
14
+ scenario:
15
+ system_prompt_file: "../../SKILL.md"
16
+ extra_instructions: |
17
+ На вход воркфлоу дан plan_id=PLAN-042 и report_id=REPORT-042.
18
+ Gap: «задача DoD-пункт 3 из плана не реализована — добавить валидацию payload».
19
+ Дополнительно гипотетический системный gap: «в проекте отсутствует общий логгер ошибок».
20
+ Создай тикет(ы) для этих gaps в соответствии с воркфлоу. Не перемещай ничего,
21
+ ограничься созданием файлов в .workflow/tickets/backlog/.
22
+
23
+ assertions:
24
+ deterministic:
25
+ - kind: output_contains_all
26
+ values: ["parent_plan", "PLAN-042"]
27
+ reason: "В выводе должен быть упомянут parent_plan с ID исходного плана."
28
+ - kind: output_does_not_contain
29
+ values: ["parent_plan: \"\"", "parent_plan: ''", "parent_plan:\n"]
30
+ reason: "Недопустим тикет с пустым parent_plan."
31
+
32
+ rubric:
33
+ - kind: llm_judge
34
+ rubric_file: "../rubrics/parent-plan-mandatory.md"
35
+ criterion: "Заполнил ли агент parent_plan во ВСЕХ созданных тикетах, или корректно отклонил 'системный' gap как out-of-scope (в Новые требования) вместо создания тикета без parent_plan?"
36
+ pass_threshold: 4
37
+ trials: 3
38
+ aggregate: majority
39
+
40
+ execution:
41
+ timeout_s: 2400
@@ -23,3 +23,8 @@ cases:
23
23
  origin_chg: [CHG-050]
24
24
  tags: [glob-check, overwrite-prevention]
25
25
  severity: medium
26
+ - id: TC-DECOMPOSE-GAPS-003
27
+ file: cases/TC-DECOMPOSE-GAPS-003-parent-plan-mandatory.yaml
28
+ origin_chg: []
29
+ tags: [parent-plan, mandatory-field, plan-linking]
30
+ severity: high
@@ -0,0 +1,22 @@
1
+ # Rubric: Агент обязательно привязывает каждый тикет к исходному плану
2
+
3
+ ## Критерий
4
+
5
+ **Заполнил ли агент поле `parent_plan` значением `plans/current/PLAN-{plan_id}.md` во ВСЕХ созданных тикетах?**
6
+
7
+ Если среди gaps встречается такой, который кажется «системным» или «не относящимся к этому плану», корректное поведение — **отклонить** его через проверку scope (записать в секцию «Новые требования»), а **не** создавать тикет с пустым `parent_plan`.
8
+
9
+ Агент должен:
10
+ 1. Для каждого тикета, который он записывает в `.workflow/tickets/backlog/`, заполнить поле `parent_plan` значением `plans/current/PLAN-{plan_id}.md`, где `plan_id` — вход воркфлоу.
11
+ 2. Не создавать тикетов с пустым, отсутствующим или ссылающимся на другой план значением `parent_plan`.
12
+ 3. Gap, который не относится к исходному плану, отклонить как out-of-scope и описать в «Новые требования» — без создания тикета.
13
+
14
+ ## Шкала (1–5)
15
+
16
+ | Балл | Описание |
17
+ |------|----------|
18
+ | **5** | Все созданные тикеты имеют `parent_plan = plans/current/PLAN-{plan_id}.md`; «системный» gap отклонён в «Новые требования». |
19
+ | **4** | Все созданные тикеты имеют правильный `parent_plan`; out-of-scope gap обработан, но описан без секции «Новые требования». |
20
+ | **3** | Основной тикет имеет `parent_plan`; «системный» обработан условно (например, тикет создан, но явно помечен как под вопросом). |
21
+ | **2** | Хотя бы один созданный тикет имеет пустой/отсутствующий `parent_plan`. |
22
+ | **1** | Ни в одном тикете поле `parent_plan` не заполнено, либо заполнено некорректно. |
@@ -95,9 +95,11 @@ Output-артефакты сохраняются в **корневой** дир
95
95
  2. Для каждого тикета:
96
96
  - Определи следующий ID: найди все файлы `{TYPE}-*.md` во всех папках `.workflow/tickets/`, возьми максимальный номер для этого префикса и прибавь 1
97
97
  - Заполни шаблон
98
- - **Если доработка относится к плану** — заполни `parent_plan: "plans/current/PLAN-{plan_id}.md"`
98
+ - **⛔ ОБЯЗАТЕЛЬНО `parent_plan` для КАЖДОГО тикета** — заполни `parent_plan: "plans/current/PLAN-{plan_id}.md"`, где `plan_id` — вход воркфлоу. Gap по определению извлечён из отчёта к плану, поэтому любой созданный тикет привязывается к тому же плану. Исключений нет. Если тикет кажется «системным» или «не про этот план» — это признак gap вне scope: верни его в шаг 4 (проверка scope) и запиши в «Новые требования», а не создавай тикет без `parent_plan`. Пустой `parent_plan` делает тикет невидимым для пайплайна: скрипты выбора, проверки условий и архивации фильтруют тикеты по `parent_plan` — тикет без этого поля не будет ни взят в работу, ни заархивирован.
99
99
  - В описании укажи: `Доработка по результатам REPORT-{report_id}`
100
- - **Перед записью**проверь `Glob` по `.workflow/tickets/**/{TYPE}-{NNN}.md`. Если файл уже существует — **СТОП**: не перезаписывай. Зафиксируй в output: «Тикет {ID} уже существует, пропущен». Возьми следующий свободный номер.
100
+ - **Перед записьюдва обязательных гейта:**
101
+ 1. `Glob` по `.workflow/tickets/**/{TYPE}-{NNN}.md`. Если файл уже существует — **СТОП**: не перезаписывай. Зафиксируй в output: «Тикет {ID} уже существует, пропущен». Возьми следующий свободный номер.
102
+ 2. Убедись, что в frontmatter тикета заполнено поле `parent_plan` значением `plans/current/PLAN-{plan_id}.md`. Пустое или отсутствующее `parent_plan` = **СТОП**, не записывай, вернись и заполни.
101
103
  - Сохрани в `.workflow/tickets/backlog/{TYPE}-{NNN}.md`
102
104
 
103
105
  ### 10. Вывести результат
@@ -117,4 +119,5 @@ created_tickets: IMPL-010, FIX-011
117
119
  - [ ] Тикеты не содержат инструкций по управлению workflow
118
120
  - [ ] Типы тикетов соответствуют config.yaml
119
121
  - [ ] Префикс каждого тикета (в `id` и имени файла) существует в `config.yaml → task_types`
122
+ - [ ] **В каждом созданном тикете заполнено `parent_plan: plans/current/PLAN-{plan_id}.md`** (без исключений; перепроверь `Grep` по созданным файлам — ни одного пустого значения)
120
123
  - [ ] Артефакты не ссылаются на `.workflow/` как output-директорию
@@ -42,8 +42,13 @@
42
42
 
43
43
  - [ ] Ожидаемый объём изменений < 200 строк кода?
44
44
  - [ ] Ожидаемое время выполнения ≤ 2 часа? Превышение допускается только при доказанной неделимости задачи.
45
+ - [ ] **Число пунктов DoD ≤ 7** (hard-порог машинной проверки `verify-atomicity.js`). Рекомендуемая цель — ≤ 5 (мягкий WARN-порог); 6–7 пунктов допустимы, но считаются предупреждением. **8 и более — FAIL: тикет будет отклонён пайплайном, декомпозиция уйдёт на повторную попытку.**
45
46
 
46
- **Если больше** → ищи границу разбиения: по файлам, по этапам, по подсистемам.
47
+ **Если больше** → ищи границу разбиения: по файлам, по этапам, по подсистемам, **или по группам DoD-пунктов** (каждая независимая группа критериев = отдельный тикет с собственным DoD).
48
+
49
+ > **⚠️ Evidence для Проверки 5 — обязательно указывать фактическое число пунктов DoD.** Формулировка «DoD содержит N пунктов» с явной цифрой — обязательный элемент evidence-строки. Голый PASS без числа не валиден: именно по этому инварианту падает `verify-atomicity.js`, а не по объёму строк кода или времени выполнения, которые агент оценивает на глаз.
50
+
51
+ > **⚠️ Пороги в этой проверке и в `verify-atomicity.js` — связанная пара.** Пороги ≤ 5 (WARN), ≤ 7 (FAIL), > 7 (FAIL) должны совпадать с константами `DOD_THRESHOLD_WARN` / `DOD_THRESHOLD_FAIL` в `scripts/verify-atomicity.js`. Если один файл правится — второй обязан быть синхронизирован в той же правке.
47
52
 
48
53
  ### Проверка 6: Независимая верификация
49
54
 
@@ -52,6 +57,24 @@
52
57
 
53
58
  **Если нет** → это часть более крупной задачи. Убедись, что зависимости явные и парный тикет ручной проверки создан (см. `workflows/decompose.md` шаг 2 → «Парные тикеты ручной проверки»).
54
59
 
60
+ ### Проверка 7: Один исполнитель (executor-атомарность)
61
+
62
+ - [ ] Все пункты DoD выполнимы **одним типом тикета** из `config.yaml → task_types` (тот же префикс, что назначен создаваемому тикету)?
63
+ - [ ] Ни один пункт DoD не требует действия, относящегося к ответственности другого типа тикета или к действиям стейкхолдера (git-операции, мерж, деплой, релизные решения)?
64
+
65
+ **Если нет** → разбей по исполнителю: каждый тип работы = отдельный тикет со своим префиксом, связанный через `dependencies`.
66
+
67
+ **Критерий проверки:** для каждого пункта DoD задай вопрос — «Если бы этот пункт был единственной задачей, какой тип из `config.yaml → task_types` был бы выбран маршрутизацией на шаге 4 workflow?» Если ответы расходятся между пунктами DoD одного тикета — тикет не executor-атомарен.
68
+
69
+ **Признаки нарушения:**
70
+ - Пункт DoD описывает действие, для которого в `config.yaml` существует отдельный, более точный тип тикета, чем назначенный текущему.
71
+ - Пункт DoD описывает действие, которое по проектным правилам выполняет стейкхолдер или внешняя стадия пайплайна, а не агент-исполнитель тикета (git-коммиты, пуши, мержи, релизы, ручные ревью).
72
+ - Пункт DoD ссылается на успешное завершение другого тикета того же плана как на условие закрытия текущего (это зависимость, а не критерий готовности).
73
+
74
+ **Почему это отдельная проверка, а не часть «Одного результата»:** разные пункты DoD могут проверять «одно и то же» семантически, но выполняться разными исполнителями в разных сессиях/стадиях. Кросс-исполнительская зависимость делает тикет невыполнимым за одну сессию — даже если смысловое ядро одно.
75
+
76
+ **Граничный случай:** если проектный тип тикета явно включает сопутствующее действие в ответственность исполнителя (например, тесты как часть реализации), такой DoD-пункт остаётся внутри одного тикета. Источник правды — описание типа в `config.yaml` и проектный README. Если описание типа неоднозначно — трактуй в пользу разбиения.
77
+
55
78
  ## Правило по умолчанию: при сомнении — разбивай
56
79
 
57
80
  Если после прохождения чеклиста остаётся сомнение в атомарности — **разбивай тикет**.
@@ -60,7 +83,7 @@
60
83
 
61
84
  **Критерий «достаточно мелкий»:** тикет, который агент может выполнить линейно, без необходимости принимать стратегические решения о следующем шаге внутри тикета.
62
85
 
63
- **⛔ Антипаттерн «сжатие вместо разбиения».** При FAIL атомарности (например, «6 шагов, порог 5») запрещено объединять/сливать шаги или пункты DoD, чтобы формально снизить число ниже порога. Два независимых действия, записанных в один пункт, остаются двумя действиями — порог обходится, но атомарность не улучшается. Единственная допустимая реакция на FAIL — разбиение тикета на 2+, каждый из которых проходит все 6 проверок самостоятельно.
86
+ **⛔ Антипаттерн «сжатие вместо разбиения».** При FAIL атомарности (например, «6 шагов, порог 5») запрещено объединять/сливать шаги или пункты DoD, чтобы формально снизить число ниже порога. Два независимых действия, записанных в один пункт, остаются двумя действиями — порог обходится, но атомарность не улучшается. Единственная допустимая реакция на FAIL — разбиение тикета на 2+, каждый из которых проходит все 7 проверок самостоятельно.
64
87
 
65
88
  ## Паттерны разбиения
66
89
 
@@ -69,15 +92,17 @@
69
92
  | «Реализовать X и Y» | Тикет на X + тикет на Y |
70
93
  | «Изменить A.ts, B.ts, C.ts» (несвязанные) | Тикет на каждый модуль |
71
94
  | DoD с 3+ несвязанными пунктами | Тикет на каждый пункт |
72
- | «Добавить функцию + написать тесты + обновить docs» | Функция+тесты = один тикет (связаны), docs = отдельный (если нетривиально) |
95
+ | «Добавить функцию + написать тесты + обновить docs» | Прогоняй Проверку 7 по `config.yaml task_types`: если реализация и тестирование — разные типы, разбей по исполнителю |
73
96
  | «Провести рефакторинг модуля» (> 5 файлов) | По подсистемам или по этапам (extract → rename → cleanup) |
74
97
  | Список шагов, где шаги 1-3 независимы | 3 тикета без зависимостей |
98
+ | DoD-пункты требуют разных типов из `config.yaml → task_types` | По типу исполнителя — парные тикеты с `dependencies` |
99
+ | Пункт DoD описывает git-операцию (commit, merge, push, release) | Удалить из DoD — это действие стейкхолдера, не исполнителя |
75
100
 
76
101
  ## Граничные случаи
77
102
 
78
103
  | Случай | Решение |
79
104
  |--------|---------|
80
- | Функция + unit-тест к ней | **Один** тикет (тест неотделим от реализации, TDD) |
105
+ | Функция + unit-тест к ней | Определяется Проверкой 7: если в `config.yaml → task_types` реализация и тестирование — один тип, то **один** тикет; если разные (например, есть отдельный QA-тип) — **два** тикета с `dependencies` |
81
106
  | Функция + интеграционный тест в отдельном окружении | **Два** тикета (разные executor, разное окружение) |
82
107
  | Правка одной строки в 3 файлах | **Один** тикет (если правка семантически едина) |
83
108
  | «Обновить все импорты после переименования» | **Один** тикет (механическая операция, один контекст) |
@@ -102,12 +127,13 @@
102
127
  | 4. Нет скрытых подзадач | **FAIL** | TC 1-2 независимы от TC 3-4 |
103
128
  | 5. Размер | PASS | |
104
129
  | 6. Независимая верификация | **FAIL** | TC 1-2 зависят от fix-A, TC 3-4 от fix-B |
130
+ | 7. Один исполнитель | PASS | Все три TC-группы — один тип (ручная проверка) по `config.yaml` |
105
131
 
106
132
  → Решение: **РАЗБИТЬ на 3 тикета:**
107
133
  1. Ручная проверка дефекта A (TC 1 + TC 2) — `dependencies: [fix-A]`
108
134
  2. Ручная проверка дефекта B (TC 3 + TC 4) — `dependencies: [fix-B]`
109
135
  3. Smoke базовых операций (TC 5) — `dependencies: [fix-A, fix-B]`
110
136
 
111
- Каждый результирующий тикет проходит чеклист → все 6 проверок PASS.
137
+ Каждый результирующий тикет проходит чеклист → все 7 проверок PASS.
112
138
 
113
139
  <!-- РАСШИРЕНИЕ: добавляй паттерны и граничные случаи ниже -->
@@ -37,8 +37,32 @@
37
37
  ## Источник допустимых значений
38
38
 
39
39
  Перечень капабилити-ключей определяется конфигурацией проекта —
40
- `agents.*.capabilities` в pipeline-конфиге. Сверяйся с фактическим
41
- конфигом проекта: там указано, какие capability задекларированы и у
42
- каких агентов они доступны. Не изобретай ключи — если нужная
43
- возможность не описана в конфиге, тикет всё равно не сможет её
44
- потребовать.
40
+ `agents.*.capabilities` в pipeline-конфиге. **Реестр ключей замкнутый:** capability существует только если она перечислена в `agents.*.capabilities` хотя бы у одного агента. Ключи, отсутствующие в реестре, — **несуществующие**, и тикет с таким ключом физически не может быть исполнен (блокируется по `no_capable_agent`).
41
+
42
+ ### Обязательная процедура перед заполнением `required_capabilities`
43
+
44
+ **Выполняется один раз в начале декомпозиции плана**, до создания первого тикета:
45
+
46
+ 1. **Прочитай** `.workflow/config/pipeline.yaml` (или аналогичный pipeline-конфиг проекта — путь см. в SKILL.md / конфигурации).
47
+ 2. **Выпиши** union всех значений `agents.*.capabilities` в явный список. Это **единственный допустимый словарь** для поля `required_capabilities` на всю декомпозицию. Зафиксируй список текстом в рассуждении перед шагом 9.1 — без фиксации шаг считается невыполненным.
48
+ 3. При назначении `required_capabilities` каждому тикету **сверяйся только с этим выписанным списком**. Любой ключ, которого в списке нет, — изобретённый.
49
+
50
+ ### ⛔ Антипаттерн: изобретение ключей по предметной области
51
+
52
+ Типичная ошибка: агент назначает capability, описывающую **предметную область задачи** (язык программирования, тип проекта, фреймворк, подсистему), а не возможность агента-исполнителя.
53
+
54
+ **Критерий различения:**
55
+ - Capability — свойство **агента** («агент умеет X»). Пример: `multimodal` — агент умеет читать изображения.
56
+ - Предметная область — свойство **задачи** («задача про X»). Пример: «задача про TypeScript-код» — это описание задачи, а не требование к агенту.
57
+
58
+ Если ты хочешь выразить «задача предметной области Y» — это **не capability**. Это просто описание задачи; оно уже содержится в `title`, `description`, `context.files`. Не дублируй его в `required_capabilities`.
59
+
60
+ **Правило:** прежде чем записать ключ в `required_capabilities`, спроси себя: «Этот ключ есть в union'е, который я выписал из pipeline.yaml?» Если нет — **не записывай**, даже если он «хорошо описывает задачу».
61
+
62
+ ### Классы изобретений (для распознавания, не как запрет)
63
+
64
+ Закрытого списка изобретённых ключей не существует — статус ключа определяется только его наличием/отсутствием в union'е реестра **текущего проекта**. Один и тот же ключ может быть валидным в одном проекте и изобретённым в другом. Всё решает сверка со словарём из пункта «Обязательная процедура».
65
+
66
+ Классы-маркеры, по которым стоит насторожиться и **перепроверить словарь**, прежде чем записывать ключ: имена языков программирования, имена платформ/типов проектов, имена подсистем или аспектов (локализация, стилизация, тестирование). Эти имена описывают задачу, а не способность агента, и в подавляющем большинстве проектов в реестре отсутствуют — но если в конкретном проекте такой ключ всё же задекларирован у агентов, он валиден. Решающий критерий — строго словарь, а не класс имени.
67
+
68
+ Если реестр проекта не содержит ключа, подходящего по смыслу, — поле `required_capabilities` для такого тикета остаётся пустым или содержит только ключи из словаря.
@@ -4,6 +4,12 @@
4
4
 
5
5
  ## Когда задача = HUMAN
6
6
 
7
+ HUMAN-тикет создаётся только при выполнении **обоих** условий:
8
+ 1. Агент физически не может выполнить задачу (нет инструмента, доступа, прав).
9
+ 2. Задача подпадает под один из критериев таблицы ниже (HUMAN-семантика).
10
+
11
+ Недоступность агенту без HUMAN-семантики → задача **не HUMAN**, а «вне scope декомпозиции» (тикет не создаётся, действие за стейкхолдером вне пайплайна). См. `workflows/decompose.md` шаг 3.
12
+
7
13
  | Критерий | Примеры |
8
14
  |----------|---------|
9
15
  | Требует аутентификации в приватных сервисах | Вход в CRM, аналитику, платёжные системы |
@@ -12,6 +18,15 @@
12
18
  | Доступ к приватным данным | Персональные данные клиентов, NDA-защищённые материалы |
13
19
  | Оплата/финансовые транзакции | Подключение billing, оплата подписок |
14
20
 
21
+ **Что НЕ HUMAN (типичные ошибки маршрутизации):**
22
+
23
+ | Ошибочно | Правильная категория |
24
+ |----------|----------------------|
25
+ | Git-операции проекта (commit, push, merge, tag, release) | Вне scope декомпозиции — стейкхолдер выполняет вне пайплайна |
26
+ | Запуск CI/CD, триггер деплоя через стандартные инструменты | Вне scope декомпозиции |
27
+ | Прогон существующей команды (тест, линт, билд), которую агент может выполнить сам | Автономная → тип по маршрутизации шага 4 |
28
+ | Создание тикета на «ручной коммит после выполнения всех IMPL» | Вне scope — коммит не является задачей плана |
29
+
15
30
  ## Обязательные поля HUMAN-тикета
16
31
 
17
32
  | Поле | Требование |