claude-flow-novice 2.14.14 → 2.14.15

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.
@@ -1,350 +1,350 @@
1
- #!/bin/bash
2
-
3
- set -euo pipefail
4
-
5
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6
-
7
- # Configuration
8
- DEFAULT_PHASE_TIMEOUT=1800 # 30 minutes per phase
9
- DEFAULT_ROLLBACK_TIMEOUT=600 # 10 minutes for rollback
10
- SUCCESS_THRESHOLD=0.85
11
-
12
- # Colors
13
- RED='\033[0;31m'
14
- GREEN='\033[0;32m'
15
- YELLOW='\033[1;33m'
16
- BLUE='\033[0;34m'
17
- NC='\033[0m'
18
-
19
- log() {
20
- echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')] $1${NC}"
21
- }
22
-
23
- warn() {
24
- echo -e "${YELLOW}[$(date '+%Y-%m-%d %H:%M:%S')] WARNING: $1${NC}"
25
- }
26
-
27
- error() {
28
- echo -e "${RED}[$(date '+%Y-%m-%d %H:%M:%S')] ERROR: $1${NC}"
29
- exit 1
30
- }
31
-
32
- info() {
33
- echo -e "${BLUE}[$(date '+%Y-%m-%d %H:%M:%S')] INFO: $1${NC}"
34
- }
35
-
36
- calculate_zone_complexity() {
37
- local zone_data="$1"
38
- local complexity_score=0
39
-
40
- # Base complexity from agent count
41
- local agent_count
42
- agent_count=$(echo "$zone_data" | jq -r '.agent_types | length // 0')
43
- complexity_score=$((complexity_score + agent_count * 10))
44
-
45
- # Complexity from deliverable count
46
- local deliverable_count
47
- deliverable_count=$(echo "$zone_data" | jq -r '.deliverables | length // 0')
48
- complexity_score=$((complexity_score + deliverable_count * 5))
49
-
50
- # Complexity from task description length (longer = more complex)
51
- local task_description
52
- task_description=$(echo "$zone_data" | jq -r '.task_description // ""')
53
- local description_length=${#task_description}
54
- if [[ $description_length -gt 100 ]]; then
55
- complexity_score=$((complexity_score + 15))
56
- elif [[ $description_length -gt 50 ]]; then
57
- complexity_score=$((complexity_score + 10))
58
- fi
59
-
60
- # Complexity from acceptance criteria
61
- local acceptance_count
62
- acceptance_count=$(echo "$zone_data" | jq -r '.acceptance_criteria | length // 0')
63
- complexity_score=$((complexity_score + acceptance_count * 8))
64
-
65
- # Risk factors
66
- if echo "$zone_data" | jq -e '.risk_factors' >/dev/null 2>&1; then
67
- local risk_factors
68
- risk_factors=$(echo "$zone_data" | jq -r '.risk_factors | length // 0')
69
- complexity_score=$((complexity_score + risk_factors * 20))
70
- fi
71
-
72
- echo "$complexity_score"
73
- }
74
-
75
- rank_zones_by_complexity() {
76
- local zone_config="$1"
77
- local zones_with_complexity="[]"
78
-
79
- local i=0
80
- while IFS= read -r zone_name; do
81
- local zone_data
82
- zone_data=$(echo "$zone_config" | jq -r ".zones[$i]")
83
-
84
- local complexity
85
- complexity=$(calculate_zone_complexity "$zone_data")
86
-
87
- local zone_entry="{
88
- \"name\": \"$zone_name\",
89
- \"complexity_score\": $complexity,
90
- \"data\": $zone_data
91
- }"
92
-
93
- zones_with_complexity=$(echo "$zones_with_complexity" | jq ". + [$zone_entry]")
94
- ((i++))
95
- done < <(echo "$zone_config" | jq -r '.zones[].name')
96
-
97
- # Sort by complexity score (ascending)
98
- echo "$zones_with_complexity" | jq 'sort_by(.complexity_score)'
99
- }
100
-
101
- create_rollout_phases() {
102
- local ranked_zones="$1"
103
- local max_zones_per_phase="${2:-2}"
104
-
105
- local rollout_phases="[]"
106
- local phase_number=1
107
- local i=0
108
-
109
- while true; do
110
- local phase_zones="[]"
111
- local zones_in_phase=0
112
-
113
- while [[ $zones_in_phase -lt $max_zones_per_phase ]]; do
114
- local zone_data
115
- zone_data=$(echo "$ranked_zones" | jq ".[$i] // empty")
116
-
117
- if [[ "$zone_data" == "null" || "$zone_data" == "" ]]; then
118
- break 2
119
- fi
120
-
121
- phase_zones=$(echo "$phase_zones" | jq ". + [$zone_data]")
122
- ((i++))
123
- ((zones_in_phase++))
124
- done
125
-
126
- if [[ $zones_in_phase -eq 0 ]]; then
127
- break
128
- fi
129
-
130
- local phase_entry="{
131
- \"phase\": $phase_number,
132
- \"zones\": $phase_zones,
133
- \"max_execution_time\": $DEFAULT_PHASE_TIMEOUT,
134
- \"success_threshold\": $SUCCESS_THRESHOLD,
135
- \"rollback_timeout\": $DEFAULT_ROLLBACK_TIMEOUT
136
- }"
137
-
138
- rollout_phases=$(echo "$rollout_phases" | jq ". + [$phase_entry]")
139
- ((phase_number++))
140
- done
141
-
142
- echo "$rollout_phases"
143
- }
144
-
145
- create_success_criteria() {
146
- local rollout_phases="$1"
147
-
148
- local success_criteria="[]"
149
-
150
- local phase_count
151
- phase_count=$(echo "$rollout_phases" | jq 'length')
152
-
153
- for ((i=0; i<phase_count; i++)); do
154
- local phase_data
155
- phase_data=$(echo "$rollout_phases" | jq ".[$i]")
156
-
157
- local zone_names
158
- zone_names=$(echo "$phase_data" | jq -r '.zones[].name')
159
-
160
- local phase_criteria="{
161
- \"phase\": $((i + 1)),
162
- \"required_success_zones\": [],
163
- \"minimum_confidence_threshold\": $SUCCESS_THRESHOLD,
164
- \"all_zones_must_complete\": true,
165
- \"validation_checks\": [
166
- \"redis_namespace_isolation\",
167
- \"agent_completion_signaling\",
168
- \"coordinator_lifecycle_management\",
169
- \"deliverable_verification\"
170
- ]
171
- }"
172
-
173
- # Add required zone names
174
- local zones_array="[]"
175
- while IFS= read -r zone_name; do
176
- zones_array=$(echo "$zones_array" | jq ". + [\"$zone_name\"]")
177
- done <<< "$zone_names"
178
-
179
- phase_criteria=$(echo "$phase_criteria" | jq ".required_success_zones = $zones_array")
180
- success_criteria=$(echo "$success_criteria" | jq ". + [$phase_criteria]")
181
- done
182
-
183
- echo "$success_criteria"
184
- }
185
-
186
- create_rollback_triggers() {
187
- local rollout_phases="$1"
188
-
189
- local rollback_triggers="[]"
190
-
191
- local phase_count
192
- phase_count=$(echo "$rollout_phases" | jq 'length')
193
-
194
- # Global rollback triggers
195
- local global_triggers="[
196
- {
197
- \"trigger\": \"any_zone_critical_failure\",
198
- \"action\": \"immediate_rollback_all\",
199
- \"description\": \"Critical system failure in any zone\"
200
- },
201
- {
202
- \"trigger\": \"redis_namespace_corruption\",
203
- \"action\": \"emergency_stop_and_cleanup\",
204
- \"description\": \"Redis namespace isolation breach\"
205
- },
206
- {
207
- \"trigger\": \"resource_exhaustion\",
208
- \"action\": \"scale_back_and_retry\",
209
- \"description\": \"System resources exhausted\"
210
- }
211
- ]"
212
-
213
- # Phase-specific rollback triggers
214
- local i=0
215
- for ((i=0; i<phase_count; i++)); do
216
- local phase_zones
217
- phase_zones=$(echo "$rollout_phases" | jq -r ".[$i].zones[].name")
218
-
219
- while IFS= read -r zone_name; do
220
- local trigger="{
221
- \"trigger\": \"zone_${zone_name}_completion_failure\",
222
- \"phase\": $((i + 1)),
223
- \"action\": \"rollback_current_phase\",
224
- \"description\": \"Zone $zone_name failed to complete in phase $((i + 1))\"
225
- }"
226
-
227
- rollback_triggers=$(echo "$rollback_triggers" | jq ". + [$trigger]")
228
- done <<< "$phase_zones"
229
- done
230
-
231
- # Combine global and specific triggers
232
- echo "$global_triggers" | jq ". + $rollback_triggers"
233
- }
234
-
235
- generate_rollout_plan() {
236
- local zone_config="$1"
237
- local max_zones_per_phase="${2:-2}"
238
-
239
- info "Analyzing zone complexity for rollout planning"
240
-
241
- # Rank zones by complexity
242
- local ranked_zones
243
- ranked_zones=$(rank_zones_by_complexity "$zone_config")
244
-
245
- # Create rollout phases
246
- local rollout_phases
247
- rollout_phases=$(create_rollout_phases "$ranked_zones" "$max_zones_per_phase")
248
-
249
- # Create success criteria
250
- local success_criteria
251
- success_criteria=$(create_success_criteria "$rollout_phases")
252
-
253
- # Create rollback triggers
254
- local rollback_triggers
255
- rollback_triggers=$(create_rollback_triggers "$rollout_phases")
256
-
257
- # Generate complete rollout plan
258
- local rollout_plan="{
259
- \"timestamp\": $(date '+%s'),
260
- \"total_zones\": $(echo "$zone_config" | jq '.zones | length'),
261
- \"max_zones_per_phase\": $max_zones_per_phase,
262
- \"phases\": $rollout_phases,
263
- \"success_criteria\": $success_criteria,
264
- \"rollback_triggers\": $rollback_triggers,
265
- \"execution_strategy\": {
266
- \"type\": \"graduated_rollout\",
267
- \"monitoring_level\": \"enhanced\",
268
- \"auto_rollback_enabled\": true,
269
- \"manual_approval_required\": false
270
- }
271
- }"
272
-
273
- echo "$rollout_plan"
274
- }
275
-
276
- display_rollout_summary() {
277
- local rollout_plan="$1"
278
-
279
- echo
280
- info "=== Risk-Based Rollout Plan ==="
281
- echo "Total zones: $(echo "$rollout_plan" | jq -r '.total_zones')"
282
- echo "Maximum zones per phase: $(echo "$rollout_plan" | jq -r '.max_zones_per_phase')"
283
- echo
284
-
285
- local phase_count
286
- phase_count=$(echo "$rollout_plan" | jq '.phases | length')
287
-
288
- echo "Rollout Phases:"
289
- for ((i=0; i<phase_count; i++)); do
290
- local phase_data
291
- phase_data=$(echo "$rollout_plan" | jq ".phases[$i]")
292
- local phase_number=$((i + 1))
293
- local zone_count
294
- zone_count=$(echo "$phase_data" | jq '.zones | length')
295
- local zone_names
296
- zone_names=$(echo "$phase_data" | jq -r '.zones[].name' | tr '\n' ', ' | sed 's/,$//')
297
-
298
- echo " Phase $phase_number: $zone_names ($zone_count zones)"
299
- done
300
- echo
301
-
302
- echo "Success Criteria:"
303
- echo " - Minimum confidence threshold: $(echo "$rollout_plan" | jq -r '.success_criteria[0].minimum_confidence_threshold')"
304
- echo " - All zones must complete: $(echo "$rollout_plan" | jq -r '.success_criteria[0].all_zones_must_complete')"
305
- echo " - Validation checks: $(echo "$rollout_plan" | jq -r '.success_criteria[0].validation_checks | length') checks"
306
- echo
307
-
308
- echo "Rollback Triggers:"
309
- echo " - Global triggers: 3"
310
- echo " - Phase-specific triggers: $(echo "$rollout_plan" | jq '.rollback_triggers | length - 3')"
311
- echo
312
- }
313
-
314
- main() {
315
- local config_file="$1"
316
- local max_zones_per_phase="${2:-2}"
317
-
318
- if [[ -z "$config_file" ]]; then
319
- error "Usage: $0 <zone-config-file> [max-zones-per-phase]"
320
- fi
321
-
322
- if [[ ! -f "$config_file" ]]; then
323
- error "Configuration file not found: $config_file"
324
- fi
325
-
326
- log "Starting risk-based rollout planning for: $config_file"
327
-
328
- # Read configuration
329
- local zone_config
330
- if ! zone_config=$(jq . "$config_file" 2>/dev/null); then
331
- error "Invalid JSON in configuration file: $config_file"
332
- fi
333
-
334
- # Generate rollout plan
335
- local rollout_plan
336
- rollout_plan=$(generate_rollout_plan "$zone_config" "$max_zones_per_phase")
337
-
338
- # Save rollout plan
339
- local output_file="/tmp/rollout-plan-$(date '+%s').json"
340
- echo "$rollout_plan" > "$output_file"
341
-
342
- log "✅ Risk-based rollout planning completed"
343
- log "Rollout plan saved to: $output_file"
344
-
345
- # Display summary
346
- display_rollout_summary "$rollout_plan"
347
- }
348
-
349
- # Execute main function with all arguments
1
+ #!/bin/bash
2
+
3
+ set -euo pipefail
4
+
5
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6
+
7
+ # Configuration
8
+ DEFAULT_PHASE_TIMEOUT=1800 # 30 minutes per phase
9
+ DEFAULT_ROLLBACK_TIMEOUT=600 # 10 minutes for rollback
10
+ SUCCESS_THRESHOLD=0.85
11
+
12
+ # Colors
13
+ RED='\033[0;31m'
14
+ GREEN='\033[0;32m'
15
+ YELLOW='\033[1;33m'
16
+ BLUE='\033[0;34m'
17
+ NC='\033[0m'
18
+
19
+ log() {
20
+ echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')] $1${NC}"
21
+ }
22
+
23
+ warn() {
24
+ echo -e "${YELLOW}[$(date '+%Y-%m-%d %H:%M:%S')] WARNING: $1${NC}"
25
+ }
26
+
27
+ error() {
28
+ echo -e "${RED}[$(date '+%Y-%m-%d %H:%M:%S')] ERROR: $1${NC}"
29
+ exit 1
30
+ }
31
+
32
+ info() {
33
+ echo -e "${BLUE}[$(date '+%Y-%m-%d %H:%M:%S')] INFO: $1${NC}"
34
+ }
35
+
36
+ calculate_zone_complexity() {
37
+ local zone_data="$1"
38
+ local complexity_score=0
39
+
40
+ # Base complexity from agent count
41
+ local agent_count
42
+ agent_count=$(echo "$zone_data" | jq -r '.agent_types | length // 0')
43
+ complexity_score=$((complexity_score + agent_count * 10))
44
+
45
+ # Complexity from deliverable count
46
+ local deliverable_count
47
+ deliverable_count=$(echo "$zone_data" | jq -r '.deliverables | length // 0')
48
+ complexity_score=$((complexity_score + deliverable_count * 5))
49
+
50
+ # Complexity from task description length (longer = more complex)
51
+ local task_description
52
+ task_description=$(echo "$zone_data" | jq -r '.task_description // ""')
53
+ local description_length=${#task_description}
54
+ if [[ $description_length -gt 100 ]]; then
55
+ complexity_score=$((complexity_score + 15))
56
+ elif [[ $description_length -gt 50 ]]; then
57
+ complexity_score=$((complexity_score + 10))
58
+ fi
59
+
60
+ # Complexity from acceptance criteria
61
+ local acceptance_count
62
+ acceptance_count=$(echo "$zone_data" | jq -r '.acceptance_criteria | length // 0')
63
+ complexity_score=$((complexity_score + acceptance_count * 8))
64
+
65
+ # Risk factors
66
+ if echo "$zone_data" | jq -e '.risk_factors' >/dev/null 2>&1; then
67
+ local risk_factors
68
+ risk_factors=$(echo "$zone_data" | jq -r '.risk_factors | length // 0')
69
+ complexity_score=$((complexity_score + risk_factors * 20))
70
+ fi
71
+
72
+ echo "$complexity_score"
73
+ }
74
+
75
+ rank_zones_by_complexity() {
76
+ local zone_config="$1"
77
+ local zones_with_complexity="[]"
78
+
79
+ local i=0
80
+ while IFS= read -r zone_name; do
81
+ local zone_data
82
+ zone_data=$(echo "$zone_config" | jq -r ".zones[$i]")
83
+
84
+ local complexity
85
+ complexity=$(calculate_zone_complexity "$zone_data")
86
+
87
+ local zone_entry="{
88
+ \"name\": \"$zone_name\",
89
+ \"complexity_score\": $complexity,
90
+ \"data\": $zone_data
91
+ }"
92
+
93
+ zones_with_complexity=$(echo "$zones_with_complexity" | jq ". + [$zone_entry]")
94
+ ((i++))
95
+ done < <(echo "$zone_config" | jq -r '.zones[].name')
96
+
97
+ # Sort by complexity score (ascending)
98
+ echo "$zones_with_complexity" | jq 'sort_by(.complexity_score)'
99
+ }
100
+
101
+ create_rollout_phases() {
102
+ local ranked_zones="$1"
103
+ local max_zones_per_phase="${2:-2}"
104
+
105
+ local rollout_phases="[]"
106
+ local phase_number=1
107
+ local i=0
108
+
109
+ while true; do
110
+ local phase_zones="[]"
111
+ local zones_in_phase=0
112
+
113
+ while [[ $zones_in_phase -lt $max_zones_per_phase ]]; do
114
+ local zone_data
115
+ zone_data=$(echo "$ranked_zones" | jq ".[$i] // empty")
116
+
117
+ if [[ "$zone_data" == "null" || "$zone_data" == "" ]]; then
118
+ break 2
119
+ fi
120
+
121
+ phase_zones=$(echo "$phase_zones" | jq ". + [$zone_data]")
122
+ ((i++))
123
+ ((zones_in_phase++))
124
+ done
125
+
126
+ if [[ $zones_in_phase -eq 0 ]]; then
127
+ break
128
+ fi
129
+
130
+ local phase_entry="{
131
+ \"phase\": $phase_number,
132
+ \"zones\": $phase_zones,
133
+ \"max_execution_time\": $DEFAULT_PHASE_TIMEOUT,
134
+ \"success_threshold\": $SUCCESS_THRESHOLD,
135
+ \"rollback_timeout\": $DEFAULT_ROLLBACK_TIMEOUT
136
+ }"
137
+
138
+ rollout_phases=$(echo "$rollout_phases" | jq ". + [$phase_entry]")
139
+ ((phase_number++))
140
+ done
141
+
142
+ echo "$rollout_phases"
143
+ }
144
+
145
+ create_success_criteria() {
146
+ local rollout_phases="$1"
147
+
148
+ local success_criteria="[]"
149
+
150
+ local phase_count
151
+ phase_count=$(echo "$rollout_phases" | jq 'length')
152
+
153
+ for ((i=0; i<phase_count; i++)); do
154
+ local phase_data
155
+ phase_data=$(echo "$rollout_phases" | jq ".[$i]")
156
+
157
+ local zone_names
158
+ zone_names=$(echo "$phase_data" | jq -r '.zones[].name')
159
+
160
+ local phase_criteria="{
161
+ \"phase\": $((i + 1)),
162
+ \"required_success_zones\": [],
163
+ \"minimum_confidence_threshold\": $SUCCESS_THRESHOLD,
164
+ \"all_zones_must_complete\": true,
165
+ \"validation_checks\": [
166
+ \"redis_namespace_isolation\",
167
+ \"agent_completion_signaling\",
168
+ \"coordinator_lifecycle_management\",
169
+ \"deliverable_verification\"
170
+ ]
171
+ }"
172
+
173
+ # Add required zone names
174
+ local zones_array="[]"
175
+ while IFS= read -r zone_name; do
176
+ zones_array=$(echo "$zones_array" | jq ". + [\"$zone_name\"]")
177
+ done <<< "$zone_names"
178
+
179
+ phase_criteria=$(echo "$phase_criteria" | jq ".required_success_zones = $zones_array")
180
+ success_criteria=$(echo "$success_criteria" | jq ". + [$phase_criteria]")
181
+ done
182
+
183
+ echo "$success_criteria"
184
+ }
185
+
186
+ create_rollback_triggers() {
187
+ local rollout_phases="$1"
188
+
189
+ local rollback_triggers="[]"
190
+
191
+ local phase_count
192
+ phase_count=$(echo "$rollout_phases" | jq 'length')
193
+
194
+ # Global rollback triggers
195
+ local global_triggers="[
196
+ {
197
+ \"trigger\": \"any_zone_critical_failure\",
198
+ \"action\": \"immediate_rollback_all\",
199
+ \"description\": \"Critical system failure in any zone\"
200
+ },
201
+ {
202
+ \"trigger\": \"redis_namespace_corruption\",
203
+ \"action\": \"emergency_stop_and_cleanup\",
204
+ \"description\": \"Redis namespace isolation breach\"
205
+ },
206
+ {
207
+ \"trigger\": \"resource_exhaustion\",
208
+ \"action\": \"scale_back_and_retry\",
209
+ \"description\": \"System resources exhausted\"
210
+ }
211
+ ]"
212
+
213
+ # Phase-specific rollback triggers
214
+ local i=0
215
+ for ((i=0; i<phase_count; i++)); do
216
+ local phase_zones
217
+ phase_zones=$(echo "$rollout_phases" | jq -r ".[$i].zones[].name")
218
+
219
+ while IFS= read -r zone_name; do
220
+ local trigger="{
221
+ \"trigger\": \"zone_${zone_name}_completion_failure\",
222
+ \"phase\": $((i + 1)),
223
+ \"action\": \"rollback_current_phase\",
224
+ \"description\": \"Zone $zone_name failed to complete in phase $((i + 1))\"
225
+ }"
226
+
227
+ rollback_triggers=$(echo "$rollback_triggers" | jq ". + [$trigger]")
228
+ done <<< "$phase_zones"
229
+ done
230
+
231
+ # Combine global and specific triggers
232
+ echo "$global_triggers" | jq ". + $rollback_triggers"
233
+ }
234
+
235
+ generate_rollout_plan() {
236
+ local zone_config="$1"
237
+ local max_zones_per_phase="${2:-2}"
238
+
239
+ info "Analyzing zone complexity for rollout planning"
240
+
241
+ # Rank zones by complexity
242
+ local ranked_zones
243
+ ranked_zones=$(rank_zones_by_complexity "$zone_config")
244
+
245
+ # Create rollout phases
246
+ local rollout_phases
247
+ rollout_phases=$(create_rollout_phases "$ranked_zones" "$max_zones_per_phase")
248
+
249
+ # Create success criteria
250
+ local success_criteria
251
+ success_criteria=$(create_success_criteria "$rollout_phases")
252
+
253
+ # Create rollback triggers
254
+ local rollback_triggers
255
+ rollback_triggers=$(create_rollback_triggers "$rollout_phases")
256
+
257
+ # Generate complete rollout plan
258
+ local rollout_plan="{
259
+ \"timestamp\": $(date '+%s'),
260
+ \"total_zones\": $(echo "$zone_config" | jq '.zones | length'),
261
+ \"max_zones_per_phase\": $max_zones_per_phase,
262
+ \"phases\": $rollout_phases,
263
+ \"success_criteria\": $success_criteria,
264
+ \"rollback_triggers\": $rollback_triggers,
265
+ \"execution_strategy\": {
266
+ \"type\": \"graduated_rollout\",
267
+ \"monitoring_level\": \"enhanced\",
268
+ \"auto_rollback_enabled\": true,
269
+ \"manual_approval_required\": false
270
+ }
271
+ }"
272
+
273
+ echo "$rollout_plan"
274
+ }
275
+
276
+ display_rollout_summary() {
277
+ local rollout_plan="$1"
278
+
279
+ echo
280
+ info "=== Risk-Based Rollout Plan ==="
281
+ echo "Total zones: $(echo "$rollout_plan" | jq -r '.total_zones')"
282
+ echo "Maximum zones per phase: $(echo "$rollout_plan" | jq -r '.max_zones_per_phase')"
283
+ echo
284
+
285
+ local phase_count
286
+ phase_count=$(echo "$rollout_plan" | jq '.phases | length')
287
+
288
+ echo "Rollout Phases:"
289
+ for ((i=0; i<phase_count; i++)); do
290
+ local phase_data
291
+ phase_data=$(echo "$rollout_plan" | jq ".phases[$i]")
292
+ local phase_number=$((i + 1))
293
+ local zone_count
294
+ zone_count=$(echo "$phase_data" | jq '.zones | length')
295
+ local zone_names
296
+ zone_names=$(echo "$phase_data" | jq -r '.zones[].name' | tr '\n' ', ' | sed 's/,$//')
297
+
298
+ echo " Phase $phase_number: $zone_names ($zone_count zones)"
299
+ done
300
+ echo
301
+
302
+ echo "Success Criteria:"
303
+ echo " - Minimum confidence threshold: $(echo "$rollout_plan" | jq -r '.success_criteria[0].minimum_confidence_threshold')"
304
+ echo " - All zones must complete: $(echo "$rollout_plan" | jq -r '.success_criteria[0].all_zones_must_complete')"
305
+ echo " - Validation checks: $(echo "$rollout_plan" | jq -r '.success_criteria[0].validation_checks | length') checks"
306
+ echo
307
+
308
+ echo "Rollback Triggers:"
309
+ echo " - Global triggers: 3"
310
+ echo " - Phase-specific triggers: $(echo "$rollout_plan" | jq '.rollback_triggers | length - 3')"
311
+ echo
312
+ }
313
+
314
+ main() {
315
+ local config_file="$1"
316
+ local max_zones_per_phase="${2:-2}"
317
+
318
+ if [[ -z "$config_file" ]]; then
319
+ error "Usage: $0 <zone-config-file> [max-zones-per-phase]"
320
+ fi
321
+
322
+ if [[ ! -f "$config_file" ]]; then
323
+ error "Configuration file not found: $config_file"
324
+ fi
325
+
326
+ log "Starting risk-based rollout planning for: $config_file"
327
+
328
+ # Read configuration
329
+ local zone_config
330
+ if ! zone_config=$(jq . "$config_file" 2>/dev/null); then
331
+ error "Invalid JSON in configuration file: $config_file"
332
+ fi
333
+
334
+ # Generate rollout plan
335
+ local rollout_plan
336
+ rollout_plan=$(generate_rollout_plan "$zone_config" "$max_zones_per_phase")
337
+
338
+ # Save rollout plan
339
+ local output_file="/tmp/rollout-plan-$(date '+%s').json"
340
+ echo "$rollout_plan" > "$output_file"
341
+
342
+ log "✅ Risk-based rollout planning completed"
343
+ log "Rollout plan saved to: $output_file"
344
+
345
+ # Display summary
346
+ display_rollout_summary "$rollout_plan"
347
+ }
348
+
349
+ # Execute main function with all arguments
350
350
  main "$@"