workflow-ai 1.0.64 → 1.0.66

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 (160) hide show
  1. package/README.md +377 -277
  2. package/configs/agent-health-rules.yaml +75 -0
  3. package/configs/pipeline.yaml +24 -7
  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/agent-spawner.mjs +47 -6
  8. package/src/lib/artifact-snapshot.mjs +233 -0
  9. package/src/lib/error-classifier.mjs +311 -0
  10. package/src/lib/test-error-classifier.mjs +60 -0
  11. package/src/lib/test-extends.mjs +58 -0
  12. package/src/lib/test-version.mjs +21 -0
  13. package/src/runner.mjs +215 -58
  14. package/src/scripts/move-to-review.js +5 -7
  15. package/src/scripts/reset-agent-health.js +62 -0
  16. package/src/skills/coach/SKILL.md +1 -0
  17. package/src/skills/coach/tests/cases/TC-COACH-001/current/meta.json +93 -94
  18. package/src/skills/coach/tests/cases/TC-COACH-002/current/meta.json +93 -94
  19. package/src/skills/create-plan/SKILL.md +1 -0
  20. package/src/skills/create-plan/knowledge/test-hygiene.md +47 -0
  21. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-001/current/claude-sonnet/trial-1.md +23 -31
  22. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-001/current/claude-sonnet/trial-2.md +20 -35
  23. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-001/current/claude-sonnet/trial-3.md +36 -19
  24. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-001/current/judge.json +1 -1
  25. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-001/current/kilo-deepseek/trial-2.md +11 -5
  26. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-001/current/kilo-deepseek/trial-3.md +12 -16
  27. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-001/current/kilo-glm/trial-1.md +15 -9
  28. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-001/current/kilo-glm/trial-3.md +15 -14
  29. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-001/current/kilo-minimax/trial-1.md +22 -18
  30. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-001/current/kilo-minimax/trial-2.md +24 -16
  31. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-001/current/kilo-minimax/trial-3.md +13 -20
  32. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-001/current/meta.json +2 -2
  33. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002/current/claude-sonnet/trial-1.md +14 -19
  34. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002/current/claude-sonnet/trial-2.md +24 -14
  35. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002/current/claude-sonnet/trial-3.md +20 -19
  36. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002/current/judge.json +16 -17
  37. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002/current/kilo-deepseek/trial-1.md +0 -7
  38. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002/current/kilo-deepseek/trial-2.md +9 -10
  39. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002/current/kilo-deepseek/trial-3.md +5 -5
  40. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002/current/kilo-glm/trial-1.md +20 -4
  41. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002/current/kilo-glm/trial-2.md +36 -9
  42. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002/current/kilo-glm/trial-3.md +9 -6
  43. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002/current/kilo-minimax/trial-1.md +4 -12
  44. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002/current/kilo-minimax/trial-2.md +6 -8
  45. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002/current/kilo-minimax/trial-3.md +8 -4
  46. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002/current/meta.json +10 -11
  47. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003/current/claude-sonnet/trial-1.md +30 -0
  48. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003/current/claude-sonnet/trial-2.md +30 -0
  49. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003/current/claude-sonnet/trial-3.md +30 -0
  50. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003/current/judge.json +165 -0
  51. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003/current/kilo-deepseek/trial-1.md +5 -0
  52. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003/current/kilo-deepseek/trial-2.md +26 -0
  53. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003/current/kilo-deepseek/trial-3.md +5 -0
  54. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003/current/kilo-glm/trial-1.md +39 -0
  55. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003/current/kilo-glm/trial-2.md +37 -0
  56. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003/current/kilo-glm/trial-3.md +45 -0
  57. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003/current/kilo-minimax/trial-1.md +26 -0
  58. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003/current/kilo-minimax/trial-2.md +27 -0
  59. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003/current/kilo-minimax/trial-3.md +7 -0
  60. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003/current/meta.json +117 -0
  61. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003-parent-plan-mandatory.yaml +41 -0
  62. package/src/skills/decompose-gaps/tests/index.yaml +5 -0
  63. package/src/skills/decompose-gaps/tests/rubrics/parent-plan-mandatory.md +22 -0
  64. package/src/skills/decompose-gaps/workflows/decompose.md +5 -2
  65. package/src/skills/decompose-plan/knowledge/atomicity-checklist.md +31 -5
  66. package/src/skills/decompose-plan/knowledge/capabilities.md +29 -5
  67. package/src/skills/decompose-plan/knowledge/human-task-rules.md +15 -0
  68. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004/current/claude-sonnet/trial-1.md +55 -0
  69. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004/current/claude-sonnet/trial-2.md +49 -0
  70. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004/current/claude-sonnet/trial-3.md +49 -0
  71. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004/current/judge.json +163 -0
  72. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004/current/kilo-deepseek/trial-1.md +104 -0
  73. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004/current/kilo-deepseek/trial-2.md +45 -0
  74. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004/current/kilo-deepseek/trial-3.md +58 -0
  75. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004/current/kilo-glm/trial-1.md +193 -0
  76. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004/current/kilo-glm/trial-2.md +202 -0
  77. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004/current/kilo-glm/trial-3.md +155 -0
  78. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004/current/kilo-minimax/trial-1.md +52 -0
  79. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004/current/kilo-minimax/trial-2.md +17 -0
  80. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004/current/kilo-minimax/trial-3.md +0 -0
  81. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004/current/meta.json +115 -0
  82. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004-executor-atomicity.yaml +64 -0
  83. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005/current/claude-sonnet/trial-1.md +59 -0
  84. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005/current/claude-sonnet/trial-2.md +204 -0
  85. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005/current/claude-sonnet/trial-3.md +213 -0
  86. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005/current/judge.json +163 -0
  87. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005/current/kilo-deepseek/trial-1.md +0 -0
  88. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005/current/kilo-deepseek/trial-2.md +57 -0
  89. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005/current/kilo-deepseek/trial-3.md +54 -0
  90. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005/current/kilo-glm/trial-1.md +147 -0
  91. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005/current/kilo-glm/trial-2.md +165 -0
  92. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005/current/kilo-glm/trial-3.md +133 -0
  93. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005/current/kilo-minimax/trial-1.md +81 -0
  94. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005/current/kilo-minimax/trial-2.md +108 -0
  95. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005/current/kilo-minimax/trial-3.md +3 -0
  96. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005/current/meta.json +114 -0
  97. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005-capabilities-registry.yaml +78 -0
  98. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006/current/claude-sonnet/trial-1.md +225 -0
  99. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006/current/claude-sonnet/trial-2.md +66 -0
  100. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006/current/claude-sonnet/trial-3.md +36 -0
  101. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006/current/judge.json +163 -0
  102. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006/current/kilo-deepseek/trial-1.md +42 -0
  103. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006/current/kilo-deepseek/trial-2.md +67 -0
  104. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006/current/kilo-deepseek/trial-3.md +40 -0
  105. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006/current/kilo-glm/trial-1.md +122 -0
  106. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006/current/kilo-glm/trial-2.md +131 -0
  107. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006/current/kilo-glm/trial-3.md +138 -0
  108. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006/current/kilo-minimax/trial-1.md +41 -0
  109. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006/current/kilo-minimax/trial-2.md +88 -0
  110. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006/current/kilo-minimax/trial-3.md +0 -0
  111. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006/current/meta.json +115 -0
  112. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006-dod-threshold.yaml +72 -0
  113. package/src/skills/decompose-plan/tests/index.yaml +15 -0
  114. package/src/skills/decompose-plan/tests/rubrics/capabilities-registry.md +21 -0
  115. package/src/skills/decompose-plan/tests/rubrics/dod-threshold.md +21 -0
  116. package/src/skills/decompose-plan/tests/rubrics/executor-atomicity.md +21 -0
  117. package/src/skills/decompose-plan/workflows/decompose.md +38 -5
  118. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-001/current/meta.json +87 -88
  119. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-005/current/meta.json +87 -88
  120. package/src/skills/manual-testing/SKILL.md +6 -4
  121. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-001/current/claude-sonnet/trial-1.md +29 -16
  122. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-001/current/claude-sonnet/trial-2.md +21 -54
  123. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-001/current/claude-sonnet/trial-3.md +18 -23
  124. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-001/current/judge.json +17 -17
  125. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-001/current/meta.json +19 -19
  126. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-002/current/claude-sonnet/trial-1.md +27 -30
  127. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-002/current/claude-sonnet/trial-2.md +16 -23
  128. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-002/current/claude-sonnet/trial-3.md +35 -28
  129. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-002/current/judge.json +13 -13
  130. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-002/current/meta.json +15 -15
  131. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-003/current/claude-sonnet/trial-1.md +76 -0
  132. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-003/current/claude-sonnet/trial-2.md +71 -0
  133. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-003/current/claude-sonnet/trial-3.md +85 -0
  134. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-003/current/judge.json +46 -0
  135. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-003/current/meta.json +36 -0
  136. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-003-qa-non-ui-assertion.yaml +65 -0
  137. package/src/skills/manual-testing/tests/index.yaml +5 -0
  138. package/src/skills/manual-testing/tests/rubrics/qa-non-ui-assertion.md +31 -0
  139. package/src/skills/review-result/SKILL.md +1 -0
  140. package/src/skills/review-result/knowledge/test-hygiene.md +44 -0
  141. package/src/skills/review-result/scripts/verify-artifacts.js +157 -14
  142. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-003/current/claude-sonnet/trial-1.md +7 -0
  143. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-003/current/claude-sonnet/trial-2.md +7 -0
  144. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-003/current/claude-sonnet/trial-3.md +7 -0
  145. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-003/current/judge.json +163 -0
  146. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-003/current/kilo-deepseek/trial-1.md +5 -0
  147. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-003/current/kilo-deepseek/trial-2.md +5 -0
  148. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-003/current/kilo-deepseek/trial-3.md +11 -0
  149. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-003/current/kilo-glm/trial-1.md +16 -0
  150. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-003/current/kilo-glm/trial-2.md +18 -0
  151. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-003/current/kilo-glm/trial-3.md +17 -0
  152. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-003/current/kilo-minimax/trial-1.md +17 -0
  153. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-003/current/kilo-minimax/trial-2.md +31 -0
  154. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-003/current/kilo-minimax/trial-3.md +5 -0
  155. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-003/current/meta.json +115 -0
  156. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-003-test-isolation.yaml +50 -0
  157. package/src/skills/review-result/tests/fixtures/QA-904-test-isolation-violation/QA-904.md +51 -0
  158. package/src/skills/review-result/tests/fixtures/QA-904-test-isolation-violation/example-test.mjs +36 -0
  159. package/src/skills/review-result/tests/index.yaml +5 -0
  160. package/src/skills/review-result/tests/rubrics/test-isolation.md +20 -0
@@ -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
  | Поле | Требование |
@@ -0,0 +1,55 @@
1
+ ---
2
+
3
+ ## Декомпозиция выполнена
4
+
5
+ ### Анализ плана
6
+
7
+ DoD плана содержит 4 пункта. Проверка 7 (executor-атомарность) против `config.yaml → task_types`:
8
+
9
+ | DoD-пункт | Тип исполнителя | Решение |
10
+ |-----------|----------------|---------|
11
+ | `buildTargetPrompt()` реализована | IMPL | → тикет IMPL-043 |
12
+ | Юнит-тест TC-PROMPT-001 написан и зелёный | QA (отдельный тип) | → тикет QA-090 |
13
+ | README обновлён разделом про prompt assembly | DOCS (отдельный тип) | → тикет DOCS-006 |
14
+ | Коммит `feat(runner): buildTargetPrompt создан` | git-операция стейкхолдера | ❌ тикет не создаётся |
15
+
16
+ ### Созданные тикеты
17
+
18
+ | ID | Тип | Название | Зависимости |
19
+ |----|-----|----------|-------------|
20
+ | IMPL-043 | impl | Реализовать функцию buildTargetPrompt() в run-skill-tests.js | — |
21
+ | QA-090 | qa | Написать юнит-тест TC-PROMPT-001 для buildTargetPrompt() | IMPL-043 |
22
+ | DOCS-006 | docs | Обновить README разделом про prompt assembly | — |
23
+
24
+ ### Рекомендации для следующего плана (вне scope)
25
+
26
+ - Создание git-коммита `feat(runner): buildTargetPrompt` — причина: git-операции выполняет стейкхолдер, а не агент-исполнитель. Коммит создаётся стейкхолдером после прохождения QA-090 и DOCS-006.
27
+
28
+ ---
29
+
30
+ ```
31
+ ---RESULT---
32
+ status: success
33
+ tickets_created:
34
+ - id: IMPL-043
35
+ path: .workflow/tickets/backlog/IMPL-043.md
36
+ type: impl
37
+ title: "Реализовать функцию buildTargetPrompt() в run-skill-tests.js"
38
+ dependencies: []
39
+ - id: QA-090
40
+ path: .workflow/tickets/backlog/QA-090.md
41
+ type: qa
42
+ title: "Написать юнит-тест TC-PROMPT-001 для buildTargetPrompt()"
43
+ dependencies: [IMPL-043]
44
+ - id: DOCS-006
45
+ path: .workflow/tickets/backlog/DOCS-006.md
46
+ type: docs
47
+ title: "Обновить README разделом про prompt assembly"
48
+ dependencies: []
49
+ tickets_skipped:
50
+ - reason: "git-операция (коммит) — выполняет стейкхолдер, не агент"
51
+ source: "DoD: Коммит feat(runner): buildTargetPrompt создан"
52
+ out_of_scope:
53
+ - "Создание git-коммита feat(runner): buildTargetPrompt — git-операции выполняет стейкхолдер"
54
+ ---RESULT---
55
+ ```
@@ -0,0 +1,49 @@
1
+ Один файл — коллизий нет.
2
+
3
+ ---
4
+
5
+ ## Итог декомпозиции
6
+
7
+ Создано **3 тикета** в `.workflow/tickets/backlog/`:
8
+
9
+ | Тикет | Тип | Executor | Приоритет | Зависимости | DoD (дословно из плана) |
10
+ |-------|-----|----------|-----------|-------------|------------------------|
11
+ | IMPL-001 | impl | agent | 2 (High) | — | Функция buildTargetPrompt() реализована в src/scripts/run-skill-tests.js |
12
+ | QA-001 | qa | agent | 2 (High) | IMPL-001 | Юнит-тест TC-PROMPT-001 написан и зелёный |
13
+ | DOCS-001 | docs | agent | 3 (Medium) | — | README обновлён разделом про prompt assembly |
14
+
15
+ **Цепочка:** IMPL-001 → QA-001; DOCS-001 параллельно IMPL-001.
16
+
17
+ **Исключено из DoD всех тикетов:** «Коммит feat(runner): buildTargetPrompt создан» — git-операция стейкхолдера, не агента-исполнителя (Проверка 7 executor-атомарности; git-операции не соответствуют HUMAN-семантике → тикет не создаётся, действие вне scope декомпозиции).
18
+
19
+ ---
20
+
21
+ ### Рекомендации для следующего плана (вне scope)
22
+
23
+ - Создать `../shared/README.md` с реестром observable-инвариантов — причина: отсутствие реестра делает невозможным применение Условий Б и В (парные тикеты ручной проверки по observable-зоне) при декомпозиции будущих планов.
24
+
25
+ ---
26
+
27
+ ```
28
+ ---RESULT---
29
+ status: default
30
+ tickets_created:
31
+ - .workflow/tickets/backlog/IMPL-001.md
32
+ - .workflow/tickets/backlog/QA-001.md
33
+ - .workflow/tickets/backlog/DOCS-001.md
34
+ decomposition_summary:
35
+ plan_dod_items: 4
36
+ tickets_created: 3
37
+ git_ops_excluded: 1
38
+ breakdown:
39
+ DoD-1 (реализация функции) → IMPL-001
40
+ DoD-2 (юнит-тест TC-PROMPT-001) → QA-001 (depends: IMPL-001)
41
+ DoD-3 (README раздел) → DOCS-001
42
+ DoD-4 (коммит) → ИСКЛЮЧЁН (git-операция стейкхолдера, Проверка 7 executor-атомарности)
43
+ ids_allocated_from:
44
+ IMPL: 1
45
+ QA: 1
46
+ DOCS: 1
47
+ note: "id_ranges_json не передан — инфраструктурная ошибка стадии allocate-ticket-ids. Нумерация начата с 001: все поддиректории .workflow/tickets/ пусты, коллизий нет."
48
+ ---RESULT---
49
+ ```
@@ -0,0 +1,49 @@
1
+ По одному совпадению для каждого тикета — коллизий нет.
2
+
3
+ ---
4
+
5
+ ## Итог декомпозиции
6
+
7
+ Создано **3 тикета** в `.workflow/tickets/backlog/`:
8
+
9
+ | Тикет | Тип | Executor | Приоритет | Зависимости | DoD (дословно из плана) |
10
+ |-------|-----|----------|-----------|-------------|------------------------|
11
+ | IMPL-1 | impl | agent | 2 (high) | — | Функция buildTargetPrompt() реализована в src/scripts/run-skill-tests.js |
12
+ | QA-1 | qa | agent | 2 (high) | IMPL-1 | Юнит-тест TC-PROMPT-001 написан и зелёный |
13
+ | DOCS-1 | docs | agent | 3 (medium) | — | README обновлён разделом про prompt assembly |
14
+
15
+ **Цепочка:** IMPL-1 → QA-1 (DOCS-1 параллельно)
16
+
17
+ **Исключено из DoD всех тикетов:** «Коммит feat(runner): buildTargetPrompt создан» — git-операция проекта, выполняется стейкхолдером вне пайплайна. Двухступенчатая проверка HUMAN: агент не может (условие 1 — да), но HUMAN-семантика из `knowledge/human-task-rules.md` не подтверждена (условие 2 — нет). Тикет **не создаётся**, тип HUMAN не назначается.
18
+
19
+ ---
20
+
21
+ ### Рекомендации для следующего плана (вне scope)
22
+
23
+ - Создать `../shared/README.md` с реестром observable-инвариантов — причина: отсутствие реестра делает невозможным применение Условий Б и В (парные тикеты ручной проверки по observable-зоне) при декомпозиции будущих планов.
24
+
25
+ ---
26
+
27
+ ```
28
+ ---RESULT---
29
+ status: default
30
+ tickets_created:
31
+ - .workflow/tickets/backlog/IMPL-1.md
32
+ - .workflow/tickets/backlog/QA-1.md
33
+ - .workflow/tickets/backlog/DOCS-1.md
34
+ decomposition_summary:
35
+ plan_dod_items: 4
36
+ tickets_created: 3
37
+ git_ops_excluded: 1
38
+ breakdown:
39
+ DoD-1 (реализация функции) → IMPL-1
40
+ DoD-2 (юнит-тест TC-PROMPT-001) → QA-1 (depends: IMPL-1)
41
+ DoD-3 (README раздел) → DOCS-1
42
+ DoD-4 (коммит) → ИСКЛЮЧЁН (git-операция стейкхолдера, Проверка 7, вне scope декомпозиции)
43
+ ids_allocated_from:
44
+ IMPL: 1
45
+ QA: 1
46
+ DOCS: 1
47
+ note: "id_ranges_json не был передан — инфраструктурная ошибка стадии allocate-ticket-ids. Нумерация начата с 1, так как .workflow/tickets/ полностью пуст."
48
+ ---RESULT---
49
+ ```