UNPKG

aios-core

Version:

Synkra AIOS: AI-Orchestrated System for Full Stack Development - Core Framework

444 lines (353 loc) 18.7 kB
workflow: id: qa-loop name: QA Loop Orchestrator - Review Fix Re-review Cycle version: "1.0" description: >- Automated QA loop that orchestrates the review → fix → re-review cycle. Runs up to maxIterations (default 5), tracking each iteration's results. Escalates to human when max iterations reached or manual stop requested. Part of Epic 6 - QA Evolution: Autonomous Development Engine (ADE). type: loop project_types: - aios-development - autonomous-development - qa-automation # ═══════════════════════════════════════════════════════════════════════════════════ # TRIGGER CONFIGURATION # ═══════════════════════════════════════════════════════════════════════════════════ triggers: # Primary trigger: Explicit command to start loop - event: command command: "*qa-loop" action: start_loop # Start from specific phase - event: command command: "*qa-loop-review" action: run_step step: review - event: command command: "*qa-loop-fix" action: run_step step: fix # Stop command (AC5) - event: command command: "*stop-qa-loop" action: stop_loop # Resume command - event: command command: "*resume-qa-loop" action: resume_loop # Force escalation - event: command command: "*escalate-qa-loop" action: escalate # ═══════════════════════════════════════════════════════════════════════════════════ # CONFIGURATION # ═══════════════════════════════════════════════════════════════════════════════════ config: # AC2: Maximum iterations (configurable) maxIterations: 5 configPath: autoClaude.qaLoop.maxIterations # Progress tracking showProgress: true verbose: true # Status file location (AC4) statusFile: qa/loop-status.json # Dashboard integration (AC7) dashboardStatusPath: .aios/dashboard/status.json legacyStatusPath: .aios/status.json # Timeout per phase (milliseconds) reviewTimeout: 1800000 # 30 minutes fixTimeout: 3600000 # 60 minutes # Retry configuration maxRetries: 2 retryDelay: 5000 # ═══════════════════════════════════════════════════════════════════════════════════ # LOOP STATUS SCHEMA (AC4) # ═══════════════════════════════════════════════════════════════════════════════════ status_schema: storyId: string currentIteration: number maxIterations: number status: "pending | in_progress | completed | stopped | escalated" startedAt: ISO-8601 updatedAt: ISO-8601 history: - iteration: number reviewedAt: ISO-8601 verdict: "APPROVE | REJECT | BLOCKED" issuesFound: number fixedAt: ISO-8601 | null issuesFixed: number | null duration: number # milliseconds # ═══════════════════════════════════════════════════════════════════════════════════ # WORKFLOW SEQUENCE # ═══════════════════════════════════════════════════════════════════════════════════ sequence: # ═════════════════════════════════════════════════════════════════════════════════ # STEP 1: REVIEW (QA Agent) # ═════════════════════════════════════════════════════════════════════════════════ - step: review phase: 1 phase_name: "QA Review" agent: qa description: >- Execute comprehensive QA review of the story implementation. Produces a verdict: APPROVE, REJECT, or BLOCKED. task: qa-review-story.md inputs: storyId: "{storyId}" iteration: "{currentIteration}" previousIssues: "{history[-1].issuesFound|0}" outputs: - gate-file.yaml - verdict - issuesFound timeout: "{config.reviewTimeout}" on_success: log: "Review complete: {verdict} ({issuesFound} issues)" next: check_verdict on_failure: action: retry max_retries: "{config.maxRetries}" on_exhausted: escalate # ═════════════════════════════════════════════════════════════════════════════════ # STEP 2: CHECK VERDICT (AC1) # ═════════════════════════════════════════════════════════════════════════════════ - step: check_verdict phase: 2 phase_name: "Verdict Check" agent: system description: >- Evaluate the review verdict and determine next action. APPROVE = complete, REJECT = continue to fix, BLOCKED = escalate. condition_check: - condition: verdict == "APPROVE" action: complete log: "Story APPROVED after {currentIteration} iteration(s)" - condition: verdict == "BLOCKED" action: escalate reason: "QA review BLOCKED - requires human intervention" - condition: verdict == "REJECT" action: continue next: create_fix_request # ═════════════════════════════════════════════════════════════════════════════════ # STEP 3: CREATE FIX REQUEST (QA Agent) # ═════════════════════════════════════════════════════════════════════════════════ - step: create_fix_request phase: 3 phase_name: "Create Fix Request" agent: qa description: >- Generate a structured fix request document from review findings. Prioritizes issues and provides actionable fix instructions. task: qa-create-fix-request.md inputs: storyId: "{storyId}" gateFile: "{outputs.review.gate-file}" iteration: "{currentIteration}" outputs: - fix-request.md - prioritizedIssues on_success: log: "Fix request created with {prioritizedIssues.length} prioritized issues" next: fix_issues on_failure: action: continue fallback: "Use raw gate file for fixes" # ═════════════════════════════════════════════════════════════════════════════════ # STEP 4: FIX ISSUES (Dev Agent) # ═════════════════════════════════════════════════════════════════════════════════ - step: fix_issues phase: 4 phase_name: "Apply Fixes" agent: dev description: >- Developer agent applies fixes based on the fix request. Runs tests and validates changes. task: dev-apply-qa-fixes.md inputs: storyId: "{storyId}" fixRequest: "{outputs.create_fix_request.fix-request}" iteration: "{currentIteration}" outputs: - fixes-applied.json - issuesFixed timeout: "{config.fixTimeout}" on_success: log: "Fixed {issuesFixed} of {issuesFound} issues" next: increment_iteration on_failure: action: retry max_retries: "{config.maxRetries}" on_exhausted: action: escalate reason: "Dev agent unable to apply fixes after retries" # ═════════════════════════════════════════════════════════════════════════════════ # STEP 5: INCREMENT ITERATION (AC2) # ═════════════════════════════════════════════════════════════════════════════════ - step: increment_iteration phase: 5 phase_name: "Check Iteration" agent: system description: >- Increment iteration counter and check against max. If max reached, escalate to human (AC3). action: increment_and_check condition_check: - condition: currentIteration >= maxIterations action: escalate reason: "Max iterations ({maxIterations}) reached without APPROVE" log: "Max iterations reached - escalating to human" - condition: currentIteration < maxIterations action: continue next: review log: "Starting iteration {currentIteration + 1}/{maxIterations}" # ═══════════════════════════════════════════════════════════════════════════════════ # ESCALATION (AC3) # ═══════════════════════════════════════════════════════════════════════════════════ escalation: enabled: true triggers: - max_iterations_reached - verdict_blocked - fix_failure - manual_escalate action: log: "Escalating to human with full context" status: "escalated" context_package: - loop-status.json - all gate files from history - all fix requests - summary of iterations notification: message: | QA Loop Escalation for {storyId} Reason: {escalation.reason} Iterations completed: {currentIteration} Last verdict: {history[-1].verdict} Outstanding issues: {history[-1].issuesFound - history[-1].issuesFixed} Review the context package and decide: 1. Resume loop: *resume-qa-loop {storyId} 2. Manually fix and approve 3. Reject story and create follow-up channels: [log, console] # ═══════════════════════════════════════════════════════════════════════════════════ # WORKFLOW COMPLETION (AC6) # ═══════════════════════════════════════════════════════════════════════════════════ completion: success_message: | ╔══════════════════════════════════════════════════════════════╗ ║ QA Loop Complete ║ ╚══════════════════════════════════════════════════════════════╝ Story: {storyId} Status: {status} Iterations: {currentIteration}/{maxIterations} Final Verdict: {history[-1].verdict} Iteration History: {history.map(h => ` ${h.iteration}. ${h.verdict} - ${h.issuesFound} found, ${h.issuesFixed || 0} fixed`).join('\n')} Duration: {totalDuration} summary: storyId: "{storyId}" status: "{status}" iterations: "{currentIteration}" finalVerdict: "{history[-1].verdict}" totalIssuesFound: "{history.reduce((sum, h) => sum + h.issuesFound, 0)}" totalIssuesFixed: "{history.reduce((sum, h) => sum + (h.issuesFixed || 0), 0)}" duration: "{totalDuration}" outputs: - loop-status.json - summary.md # ═══════════════════════════════════════════════════════════════════════════════════ # ERROR HANDLING # ═══════════════════════════════════════════════════════════════════════════════════ error_handling: missing_story_id: message: "Story ID is required" suggestion: "Usage: *qa-loop STORY-42" action: prompt review_timeout: message: "Review phase timed out" suggestion: "Check QA agent status and retry: *resume-qa-loop {storyId}" action: escalate fix_timeout: message: "Fix phase timed out" suggestion: "Check Dev agent status and retry: *resume-qa-loop {storyId}" action: escalate invalid_status: message: "Loop status file is corrupted or invalid" suggestion: "Reset loop: *qa-loop {storyId} --reset" action: halt # ═══════════════════════════════════════════════════════════════════════════════════ # STOP/RESUME SUPPORT (AC5) # ═══════════════════════════════════════════════════════════════════════════════════ control: stop: command: "*stop-qa-loop" action: | - Set status to "stopped" - Save current state to loop-status.json - Log: "QA loop stopped at iteration {currentIteration}" - Allow resume later resume: command: "*resume-qa-loop" action: | - Load state from loop-status.json - Verify status was "stopped" or "escalated" - Set status to "in_progress" - Continue from last step - Log: "QA loop resumed at iteration {currentIteration}" reset: command: "*qa-loop --reset" action: | - Delete loop-status.json - Start fresh loop - Log: "QA loop reset for {storyId}" # ═══════════════════════════════════════════════════════════════════════════════════ # DASHBOARD INTEGRATION (AC7) # ═══════════════════════════════════════════════════════════════════════════════════ integration: status_json: track_loop: true field: qaLoop update_on_each_iteration: true schema: storyId: string status: string currentIteration: number maxIterations: number lastVerdict: string lastIssuesFound: number updatedAt: ISO-8601 project_status: update_story_status: true status_field: qaLoopStatus notifications: on_approve: message: "QA Loop APPROVED: {storyId}" channels: [log] on_escalate: message: "QA Loop ESCALATED: {storyId} - needs attention" channels: [log] on_stop: message: "QA Loop STOPPED: {storyId}" channels: [log] # ═══════════════════════════════════════════════════════════════════════════════════ # METADATA # ═══════════════════════════════════════════════════════════════════════════════════ metadata: story: "6.5" epic: "Epic 6 - QA Evolution" created: "2026-01-29" author: "@architect (Aria)" dependencies: - qa-review-story.md - qa-create-fix-request.md - dev-apply-qa-fixes.md tags: - qa-loop - workflow - orchestration - ade - autonomous