Commit 205829a
fix: scheduler picks next free run-number suffix to avoid ghost runs
Resolves a bug where re-enabling a PersonaPack (or otherwise recreating
a SympoziumSchedule after its AgentRun children were left behind) caused
the scheduler to silently no-op instead of creating real runs.
Root cause: the scheduler computed AgentRun names as
{schedule}-{status.TotalRuns+1}
When the SympoziumSchedule was deleted, its `status.TotalRuns` counter
went with it — but the AgentRun resources owned by the schedule had
already been severed from their owner by earlier cleanup, so they
persisted as orphans. On recreation, TotalRuns reset to 0, the
scheduler tried to create `{schedule}-1` which already existed, the
apiserver returned AlreadyExists, the scheduler swallowed the error
and logged "Created scheduled AgentRun" anyway, incremented
TotalRuns, and advanced LastRunTime/NextRunTime. The user saw the
schedule claim it was firing but no new runs ever appeared — the
status was pointing at 14-hour-old orphan runs.
Fix:
- New nextScheduledRunNumber() helper lists AgentRuns labelled with
sympozium.ai/schedule=<name>, finds the maximum numeric suffix
actually present, and picks max(TotalRuns+1, maxObserved+1). This
is self-healing: if the schedule has been recreated N times, it
still picks a unique suffix on the first attempt.
- Added a bounded collision-retry loop (up to 100 attempts). On
AlreadyExists it bumps the suffix and tries again, logging each
collision. This guards against races with concurrent reconciles
or with any other actor creating runs against the schedule's
label namespace.
- TotalRuns is now set to the actual suffix used (not blindly
incremented), keeping it aligned with observable state.
Verified live: forcing a reconcile against the
platform-team-security-guardian-schedule (which had orphans at
suffixes 1..5) correctly created schedule-6 and schedule-7.
Adds 5 targeted unit tests (sympoziumschedule_collision_test.go):
- NoExistingRuns: baseline — honours TotalRuns+1
- RecoversFromOrphanedRuns: the regression, picks 10 past 1..9
- HonoursHigherTotalRuns: counter wins when it's ahead of orphans
- IgnoresOtherSchedulesRuns: label filtering works
- IgnoresMalformedSuffixes: non-numeric names don't confuse the
max-suffix scan
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>1 parent ac1d3b7 commit 205829a
File tree
2 files changed
+225
-4
lines changed- internal/controller
2 files changed
+225
-4
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
| 6 | + | |
| 7 | + | |
6 | 8 | | |
7 | 9 | | |
8 | 10 | | |
| |||
19 | 21 | | |
20 | 22 | | |
21 | 23 | | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
22 | 29 | | |
23 | 30 | | |
24 | 31 | | |
| |||
164 | 171 | | |
165 | 172 | | |
166 | 173 | | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
167 | 186 | | |
168 | | - | |
| 187 | + | |
169 | 188 | | |
170 | 189 | | |
171 | 190 | | |
| |||
212 | 231 | | |
213 | 232 | | |
214 | 233 | | |
215 | | - | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
216 | 242 | | |
217 | 243 | | |
218 | 244 | | |
219 | 245 | | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
220 | 256 | | |
221 | 257 | | |
222 | 258 | | |
223 | 259 | | |
224 | | - | |
| 260 | + | |
| 261 | + | |
225 | 262 | | |
226 | 263 | | |
227 | 264 | | |
228 | | - | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
229 | 268 | | |
230 | 269 | | |
231 | 270 | | |
| |||
241 | 280 | | |
242 | 281 | | |
243 | 282 | | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
244 | 327 | | |
245 | 328 | | |
246 | 329 | | |
| |||
0 commit comments