MCPcopy Create free account
hub / github.com/compozy/agh / RecoverRun

Method RecoverRun

internal/task/force_ops.go:282–362  ·  view source on GitHub ↗

RecoverRun terminalizes a needs_attention run and queues one fresh child to resume work.

(
	ctx context.Context,
	runID string,
	req RecoverRunRequest,
	actor ActorContext,
)

Source from the content-addressed store, hash-verified

280
281// RecoverRun terminalizes a needs_attention run and queues one fresh child to resume work.
282func (m *Service) RecoverRun(
283 ctx context.Context,
284 runID string,
285 req RecoverRunRequest,
286 actor ActorContext,
287) (*RetryRunResult, error) {
288 if err := m.requireForceRunAuthority(actor); err != nil {
289 return nil, err
290 }
291 normalized, err := normalizeRecoverRunRequest(req)
292 if err != nil {
293 return nil, err
294 }
295 source, taskRecord, err := m.loadRunWithTask(ctx, runID)
296 if err != nil {
297 return nil, err
298 }
299 if err := m.requireForceRunRate(actor, taskRecord.ID); err != nil {
300 return nil, err
301 }
302 if source.Status.Normalize() != TaskRunStatusNeedsAttention {
303 suggested := fmt.Sprintf("agh task inspect %s", source.ID)
304 if source.Status.Normalize() == TaskRunStatusFailed {
305 suggested = fmt.Sprintf("agh task retry %s", source.ID)
306 }
307 return nil, forceRunDiagnosticError(
308 diagnosticcontract.CodeTaskRunNotRecoverable,
309 "Task run cannot be recovered",
310 fmt.Sprintf(
311 "Run %s is %s; only needs_attention runs can be recovered.",
312 source.ID,
313 source.Status.Normalize(),
314 ),
315 diagnosticcontract.SeverityError,
316 suggested,
317 map[string]any{runEvidenceIDKey: source.ID, leaseStatusKey: string(source.Status.Normalize())},
318 ErrInvalidStatusTransition,
319 )
320 }
321 if err := m.requireRetryChainDepth(ctx, source); err != nil {
322 return nil, err
323 }
324
325 result, err := m.store.RecoverTaskRun(ctx, RecoverRunMutation{
326 SourceRunID: source.ID,
327 NewRunID: m.newID("run"),
328 Origin: actor.Origin,
329 Reason: normalized.Reason,
330 Metadata: normalized.Metadata,
331 QueuedAt: m.now().UTC(),
332 })
333 if err != nil {
334 return nil, err
335 }
336 reconciledTask, err := m.reconcileTaskCascade(ctx, taskRecord.ID)
337 if err != nil {
338 return nil, err
339 }

Callers

nothing calls this directly

Calls 12

loadRunWithTaskMethod · 0.95
requireForceRunRateMethod · 0.95
reconcileTaskCascadeMethod · 0.95
recordTaskEventMethod · 0.95
forceRunDiagnosticErrorFunction · 0.85
RecoverTaskRunMethod · 0.65
NormalizeMethod · 0.45
nowMethod · 0.45

Tested by

no test coverage detected