Iteracyjny proces doprecyzowywania zadań z Jira
Przegląd
System działa w pętli iteracyjnej dopóki zadanie nie będzie w 100% jasne:
TODO → Analiza → Pytania → Komentarz Jira → CZEKA
↓
User odpowiada
↓
TODO ← n8n modyfikuje start_commands ← n8n wykrywa odpowiedź
↓
Analiza odpowiedzi → Decyzja Claude:
• Są jeszcze pytania? → Kolejna iteracja (wróć do góry)
• Wszystko jasne? → Podsumowanie + task.md → GOTOWEWorkflow n8n (Kluczowe!)
n8n zarządza całym procesem i modyfikuje task.json między iteracjami.
Trigger 1: Nowy komentarz w Jira z pytaniami
Gdy: Claude wysyła webhook z pytaniami
Akcje n8n:
- Utwórz komentarz w Jira z pytaniami
- Wyślij powiadomienie na Mattermost
- NIE PRZENOSI zadania - pozostaje w bieżącym statusie
- Czeka na odpowiedź
Trigger 2: User odpowiedział na pytania
Gdy: User dodaje komentarz w Jira (odpowiedź na pytania)
Warunek: Komentarz zawiera odpowiedzi (Q1:, Q2:, lub "Odpowiedzi:")
Akcje n8n:
- Odczytaj task.json z filesystem lub API
- Zmodyfikuj start_commands (szczegóły niżej)
- Zapisz task.json z powrotem
- Przenieś zadanie do TODO (jeśli było w innym statusie)
- Powiadomienie na Mattermost: "Zadanie {ID} - otrzymano odpowiedzi, wznowienie analizy"
Trigger 3: Claude wysłał finalne podsumowanie
Gdy: Webhook z event: "jira_enrichment_completed"
Akcje n8n:
- Utwórz komentarz w Jira z podsumowaniem + task.md
- Oznacz zadanie jako gotowe do implementacji (label:
ready-for-implementation) - Powiadomienie: "Zadanie {ID} - analiza zakończona, gotowe do implementacji"
start_commands - Wersje
Wersja 1: INITIAL (pierwsza iteracja)
Kiedy: Zadanie świeżo utworzone, nigdy nie było przetwarzane
{
"ai": {
"start_commands": [
{
"id": "init_workspace",
"catalog": "START",
"executor": "bash",
"command": "bash /workspace/files/helpers/init_workspace.sh",
"dependencies": []
},
{
"id": "jira_fetch",
"catalog": "START",
"executor": "bash",
"command": "bash /workspace/files/helpers/jira_fetch.sh \"$(jq -r '.issue.url' /task/task.json)\" \"/task/.spec/jira\"",
"dependencies": ["init_workspace"]
},
{
"id": "jira_enrich_initial",
"catalog": "START",
"executor": "claude",
"command": "/plugin-codegen:jira-enrich /task --mode=initial",
"dependencies": ["jira_fetch"]
}
]
},
"jira_enrichment": {
"iteration": 1,
"status": "awaiting_answers",
"questions_sent": true,
"last_comment_id": null
}
}Co robi /jira-enrich --mode=initial:
- Eksploruje codebase
- Analizuje JIRA_CONTEXT.md
- Generuje pytania
- Wysyła webhook
- ZATRZYMUJE SIĘ (nie kontynuuje do implementacji)
Wersja 2: ITERATION (kolejne iteracje)
Kiedy: n8n wykrył odpowiedź i zmodyfikował task.json
{
"ai": {
"start_commands": [
{
"id": "init_workspace",
"catalog": "START",
"executor": "bash",
"command": "bash /workspace/files/helpers/init_workspace.sh",
"dependencies": []
},
{
"id": "jira_fetch_refresh",
"catalog": "START",
"executor": "bash",
"command": "bash /workspace/files/helpers/jira_fetch.sh \"$(jq -r '.issue.url' /task/task.json)\" \"/task/.spec/jira\"",
"dependencies": ["init_workspace"]
},
{
"id": "jira_enrich_iteration",
"catalog": "START",
"executor": "claude",
"command": "/plugin-codegen:jira-enrich /task --mode=iteration --iteration=$(jq -r '.jira_enrichment.iteration' /task/task.json)",
"dependencies": ["jira_fetch_refresh"]
}
]
},
"jira_enrichment": {
"iteration": 2, // n8n zwiększa counter
"status": "processing_answers",
"questions_sent": true,
"last_comment_id": "10001" // ID komentarza z pytaniami
}
}Co robi /jira-enrich --mode=iteration:
- Czyta QUESTIONS.md + comments.json (wszystkie komentarze z Jira)
- Czyta jira_comment_id.txt (ID ostatniego komentarza z pytaniami)
- Filtruje nowe komentarze (gdzie id > last_comment_id)
- Przetwarza odpowiedzi → wyodrębnia decyzje projektowe
- Aktualizuje task.md o decyzje
- DECYDUJE (analiza kompletności):
- Jeśli są jeszcze pytania → generuje → webhook → STOP
- Jeśli wszystko jasne → wysyła finalne podsumowanie → webhook
Wersja 3: READY (analiza zakończona)
Kiedy: Claude wysłał finalne podsumowanie
{
"ai": {
"start_commands": [
{
"id": "init_workspace",
"catalog": "START",
"executor": "bash",
"command": "bash /workspace/files/helpers/init_workspace.sh",
"dependencies": []
},
{
"id": "prepare_task_spec",
"catalog": "START",
"executor": "bash",
"command": "bash /workspace/files/helpers/prepare_task_spec.sh",
"dependencies": ["init_workspace"]
},
{
"id": "team_implement",
"catalog": "START",
"executor": "claude",
"command": "/plugin-codegen:team .spec/{TASK_ID}/task.md",
"dependencies": ["prepare_task_spec"]
}
// ... reszta flow implementacji
]
},
"jira_enrichment": {
"iteration": 3,
"status": "completed",
"questions_sent": true,
"last_comment_id": "10005",
"completed_at": "2024-01-20T15:30:00Z"
}
}Co robi: Standardowy flow implementacji (bez jira_enrich)
Logika n8n: Modyfikacja task.json
Pseudokod workflow n8n
// Trigger: Nowy komentarz w Jira
ON jira_comment_added(issue_key, comment) {
// Sprawdź czy to odpowiedź na pytania
if (isAnswerToQuestions(comment)) {
// 1. Pobierz task.json
task_json = readFile(`/workspace/tasks/_sembot/${issue_key}/task.json`)
// 2. Sprawdź status wzbogacania
if (task_json.jira_enrichment.status === "awaiting_answers") {
// 3. Zwiększ licznik iteracji
task_json.jira_enrichment.iteration += 1
task_json.jira_enrichment.status = "processing_answers"
task_json.jira_enrichment.last_comment_id = comment.id
// 4. Zmień start_commands na ITERATION mode
task_json.ai.start_commands = [
{
id: "init_workspace",
catalog: "START",
executor: "bash",
command: "bash /workspace/files/helpers/init_workspace.sh",
dependencies: []
},
{
id: "jira_fetch_refresh",
catalog: "START",
executor: "bash",
command: `bash /workspace/files/helpers/jira_fetch.sh "$(jq -r '.issue.url' /task/task.json)" "/task/.spec/jira"`,
dependencies: ["init_workspace"]
},
{
id: "jira_enrich_iteration",
catalog: "START",
executor: "claude",
command: `/plugin-codegen:jira-enrich /task --mode=iteration --iteration=${task_json.jira_enrichment.iteration}`,
dependencies: ["jira_fetch_refresh"]
}
]
// 5. Zapisz task.json
writeFile(`/workspace/tasks/_sembot/${issue_key}/task.json`, task_json)
// 6. Przenieś zadanie do TODO (wznów przetwarzanie)
moveTaskToTodo(issue_key)
// 7. Powiadomienie
sendMattermostNotification({
channel: "dev-notifications",
message: `📬 Zadanie ${issue_key} - otrzymano odpowiedzi (iteracja ${task_json.jira_enrichment.iteration}), wznowienie analizy`
})
}
}
}Komenda Claude: /jira-enrich (rozszerzona)
Parametry
/jira-enrich <task_path> [--mode=initial|iteration] [--iteration=N]Mode: initial (pierwsza iteracja)
Przepływ:
1. Read JIRA_CONTEXT.md
2. Eksploruj codebase (READ-ONLY)
3. Przeanalizuj kompletność
4. Wygeneruj pytania → QUESTIONS.md
5. Wyślij webhook z pytaniami
6. Zaktualizuj task.md o kontekst z Jira
7. **ZATRZYMAJ** (exit, nie kontynuuj)Webhook payload:
{
"event": "jira_questions_generated",
"iteration": 1,
"task": { ... },
"questions": { ... },
"actions_requested": {
"jira": { "create_comment": true },
"mattermost": { "send_notification": true }
}
}Mode: iteration (kolejne iteracje)
Przepływ:
1. Read JIRA_CONTEXT.md (odświeżony przez jira_fetch)
2. Read QUESTIONS.md (poprzednie pytania z iteracji poprzedniej)
3. Read comments.json (WSZYSTKIE komentarze z Jira)
4. Read jira_comment_id.txt (ID ostatniego komentarza z pytaniami)
5. Filtruj nowe komentarze (Claude: gdzie id > last_comment_id)
6. Przetwórz odpowiedzi → wyodrębnij decyzje
7. Zaktualizuj task.md:
- Dodaj sekcję "Decyzje projektowe"
- Rozszerz kryteria akceptacji
8. **DECYZJA CLAUDE:** Analiza kompletności
JEŚLI są jeszcze niejasności:
→ Wygeneruj kolejne pytania → QUESTIONS_iteration_N.md
→ Wyślij webhook z pytaniami
→ **ZATRZYMAJ** (czekaj na odpowiedzi)
W PRZECIWNYM RAZIE:
→ Wygeneruj finalne podsumowanie
→ Wyślij webhook z podsumowaniem
→ **ZAKOŃCZ WZBOGACANIE**Decyzja Claude - Logika:
def should_ask_more_questions(task_md, decisions, codebase_analysis):
"""
Czy Claude powinien zadać kolejne pytania?
"""
# Sprawdź kompletność wymagań funkcjonalnych
functional_completeness = analyze_functional_requirements(task_md)
if functional_completeness < 0.9: # < 90%
return True, "Niekompletne wymagania funkcjonalne"
# Sprawdź czy są konflikty w decyzjach
conflicts = find_conflicts_in_decisions(decisions)
if conflicts:
return True, f"Konflikty: {conflicts}"
# Sprawdź czy architektura jest jasna
architectural_clarity = analyze_architecture_clarity(task_md, codebase_analysis)
if architectural_clarity < 0.85: # < 85%
return True, "Niejasna architektura implementacji"
# Sprawdź edge cases
edge_cases_covered = analyze_edge_cases(task_md)
if edge_cases_covered < 0.8: # < 80%
return True, "Niewystarczająco opisane edge cases"
# Wszystko OK - można implementować
return False, "Wszystko jasne, gotowe do implementacji"Webhook gdy są jeszcze pytania:
{
"event": "jira_questions_generated",
"iteration": 2,
"task": { ... },
"questions": {
"content": "...",
"reason": "Niejasna architektura implementacji",
"stats": {
"total": 3,
"critical": 1,
"important": 2
}
},
"previous_decisions": [
"Menu UI - Ikony + tooltip",
"Submenu UX - Flyout menu"
]
}Webhook gdy wszystko jasne (FINALNE):
{
"event": "jira_enrichment_completed",
"iteration": 2,
"task": {
"task_id": "DEV-1_30",
"issue_key": "DEV-7353",
"issue_url": "..."
},
"summary": {
"total_iterations": 2,
"questions_asked": 6,
"decisions_made": 6,
"completeness": "100%",
"ready_for_implementation": true
},
"final_comment": {
"title": "✅ Analiza zakończona - Gotowe do implementacji",
"content": "# Podsumowanie analizy zadania DEV-7353\n\n## 📊 Statystyki\n...",
"task_md": "# DEV-7353 - Kolor paska navbar\n\n## Opis...\n\n..."
},
"actions_requested": {
"jira": {
"create_comment": true,
"add_label": "ready-for-implementation"
},
"mattermost": {
"send_notification": true,
"message": "✅ Zadanie DEV-7353 przeanalizowane (2 iteracje, 6 decyzji). Gotowe do implementacji!"
}
}
}Format finalnego komentarza w Jira
Gdy Claude uzna że wszystko jest jasne, wysyła webhook z finalnym komentarzem:
# ✅ Analiza zakończona - Gotowe do implementacji
## 📊 Statystyki analizy
- **Iteracji:** 2
- **Pytań zadanych:** 6 (🔴 3 krytyczne, 🟡 2 ważne, 🟢 1 nice-to-have)
- **Decyzji podjętych:** 6
- **Kompletność:** 100%
- **Status:** ✅ Gotowe do implementacji
## 🎨 Podjęte decyzje projektowe
### 1. Menu UI - Widoczność po zwinięciu
**Decyzja:** Ikony + tooltip z skrótem klawiszowym
**Implikacja:** Komponent tooltip + keyboard shortcuts service
### 2. Submenu UX - Dostęp po zwinięciu
**Decyzja:** Flyout menu z animacją fade
**Implikacja:** CSS transitions + positioning logic
### 3. Persystencja stanu
**Decyzja:** SessionStorage (reset po zamknięciu przeglądarki)
**Implikacja:** MenuStateService + session storage API
[... wszystkie decyzje]
## 📝 Zaktualizowany opis zadania
<details>
<summary>Kliknij aby rozwinąć pełny task.md</summary>
\`\`\`markdown
# DEV-7353 - Kolor paska pod navbar dla super administratora
## 📋 Opis zadania
Zmiana koloru paska administracyjnego wyświetlanego pod głównym paskiem
nawigacyjnym dla użytkowników z rolą super administratora...
## ✅ Kryteria akceptacji
- [ ] Pasek ma kolor ciemnoniebieski (#1a3a5c)
- [ ] Zmiana dotyczy tylko roli super administrator
- [ ] Menu po zwinięciu pokazuje ikony z tooltip
- [ ] Tooltip pokazuje nazwę + skrót klawiszowy
- [ ] Flyout submenu z animacją fade
- [ ] Stan menu zapisany w sessionStorage
...
## 🎨 Decyzje projektowe
[Pełna sekcja z wszystkimi decyzjami]
## 🔧 Komponenty do modyfikacji
### Identyfikowane przez eksplorację codebase:
- `src/app/shared/components/navbar/navbar.component.ts`
- `src/app/shared/components/navbar/navbar.component.scss`
- `src/app/core/services/auth.service.ts` (sprawdzanie roli)
- `src/app/core/services/menu-state.service.ts` (nowy - do stworzenia)
...
\`\`\`
</details>
## 🚀 Następne kroki
Zadanie jest w 100% gotowe do implementacji. Można rozpocząć:
1. `/plan` - Szczegółowy plan implementacji
2. `/team` - Implementacja z pełnym kontekstem
---
🤖 **Wygenerowano automatycznie przez AI Code Generator**
📅 **Data:** 2024-01-20 15:30:00
🔄 **Iteracji:** 2Przykład pełnego procesu
Iteracja 1
1. Zadanie DEV-7353 w TODO
{
"status": "todo",
"jira_enrichment": {
"iteration": 1,
"status": "initial"
}
}2. System uruchamia: init → jira_fetch → jira_enrich (mode=initial)
3. Claude:
- Eksploruje codebase
- Znajduje: navbar component, auth service, styles
- Identyfikuje 6 niejasności
- Generuje pytania
4. Webhook → n8n:
{
"event": "jira_questions_generated",
"iteration": 1,
"questions": { "total": 6 }
}5. n8n:
- Tworzy komentarz w Jira z pytaniami
- Powiadomienie Mattermost
- Zadanie pozostaje w TODO (ale czeka na odpowiedzi)
6. User odpowiada w Jira
Iteracja 2
7. n8n wykrywa odpowiedź:
- Odczytuje task.json
- Modyfikuje start_commands (mode=iteration)
- Zwiększa iteration: 2
- Zapisuje task.json
- Przesuwa zadanie do TODO (wznawia)
8. System uruchamia: init → jira_fetch (refresh) → jira_enrich (mode=iteration, iteration=2)
9. Claude:
- Czyta poprzednie pytania (QUESTIONS.md)
- Czyta WSZYSTKIE komentarze (comments.json)
- Czyta ID ostatniego pytania (jira_comment_id.txt)
- Filtruje nowe komentarze (id > last_comment_id = 6 odpowiedzi)
- Przetwarza odpowiedzi → 6 decyzji projektowych
- Aktualizuje task.md
- DECYDUJE: Sprawdza kompletność
- Wymagania funkcjonalne: 95% ✅
- Architektura: 90% ✅
- Edge cases: 85% ✅
- Conclusion: Wszystko jasne! Można implementować
10. Webhook → n8n:
{
"event": "jira_enrichment_completed",
"iteration": 2,
"summary": { "completeness": "100%" },
"final_comment": "..."
}11. n8n:
- Tworzy finlany komentarz w Jira (z podsumowaniem + task.md)
- Dodaje label: "ready-for-implementation"
- Powiadomienie: "✅ DEV-7353 gotowe do implementacji"
- Modyfikuje start_commands → READY mode (implementacja)
Implementacja
12. System (jeśli automatyczny) lub ręcznie:
- Uruchamia plan → team → ...
- Implementuje z pełnym kontekstem
Komponenty systemu
1. Skrypty Bash (deterministyczne)
jira_fetch.sh
- Lokalizacja:
docker/{worker}/files/helpers/jira_fetch.sh - Pobiera WSZYSTKO z Jira (opis, komentarze, załączniki, linki, changelog, subtaski)
- Generuje
JIRA_CONTEXT.md- gotowy kontekst do analizy - Konwertuje ADF (Atlassian Document Format) na markdown
- Deterministyczny - ZAWSZE pobiera te same dane
send_questions_webhook.sh
- Lokalizacja:
docker/{worker}/files/helpers/send_questions_webhook.sh - Wysyła pytania przez webhook do n8n
- Parametry: TASK_ID, ISSUE_URL, QUESTIONS_FILE, ASSIGNEE_ID, ITERATION
- Zlicza pytania według priorytetów (🔴🟡🟢)
- Zapisuje webhook_payload.json i webhook_response.json
- Wyodrębnia jira_comment_id.txt z response
send_completion_webhook.sh
- Lokalizacja:
docker/{worker}/files/helpers/send_completion_webhook.sh - Wysyła finalne podsumowanie gdy analiza zakończona
- Event:
jira_enrichment_completed - Payload zawiera pełny task.md do umieszczenia w Jira
- Akcje: komentarz + label
ready-for-implementation
2. Komenda Claude
/jira-enrich
- Lokalizacja:
plugins/plugin-codegen/commands/jira_enrich.md - Parametry:
--mode=initial|iteration --iteration=N - Mode initial: eksploracja codebase + pytania
- Mode iteration: przetwarzanie odpowiedzi + decyzja
- Logika decyzyjna z thresholdami (90% functional, 85% architectural, etc.)
3. n8n Workflow (do implementacji)
Trzy triggery:
Webhook z pytaniami (
jira_questions_generated)- Tworzy komentarz w Jira
- Powiadomienie Mattermost
- Zmienia assignee (tylko iteracja 1)
Nowy komentarz w Jira (odpowiedź)
- Wykrywa odpowiedzi
- Modyfikuje task.json (zwiększa iteration, zmienia start_commands)
- Przenosi zadanie do TODO
Webhook completion (
jira_enrichment_completed)- Tworzy finalny komentarz w Jira (z task.md)
- Dodaje label
ready-for-implementation - Modyfikuje start_commands → READY mode
4. Dokumentacja
plugins/plugin-codegen/commands/jira_enrich.md- Specyfikacja komendydocker/{worker}/files/helpers/README.md- Dokumentacja skryptów- Ten plik - Proces iteracyjny
FAQ
Q: Co jeśli user nie odpowie na pytania? A: Zadanie pozostaje w TODO z status: "awaiting_answers". Można ustawić timeout w n8n.
Q: Jak długo czekać między iteracjami? A: n8n reaguje natychmiast na nowy komentarz. Brak limitu czasu.
Q: Co jeśli Claude nigdy nie uzna że jest gotowe? A: Max iteracji: 5. Po 5 iteracjach automatycznie kończy z ostrzeżeniem.
Q: Czy można pominąć iteracje i od razu implementować? A: Tak - ustaw w task.json "skip_enrichment": true i użyj READY start_commands.
Q: Co się stało z process_jira_answers.sh i new_comments.json? A: Zostały usunięte. n8n wykrywa odpowiedzi bezpośrednio przez Jira API/webhooks, a Claude sam filtruje komentarze czytając comments.json + jira_comment_id.txt.
Q: Gdzie są skrypty Jira? A: W każdym workerze: docker/{sembot_frontend|sembot_backend|sembot_go|sembot_qa}/files/helpers/
jira_fetch.sh- pobieranie z Jirasend_questions_webhook.sh- wysyłanie pytańsend_completion_webhook.sh- wysyłanie completion