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

Function validateRunLeaseMetadata

internal/task/validate.go:626–651  ·  view source on GitHub ↗
(r Run)

Source from the content-addressed store, hash-verified

624}
625
626func validateRunLeaseMetadata(r Run) error {
627 claimToken := strings.TrimSpace(r.ClaimToken)
628 claimTokenHash := strings.TrimSpace(r.ClaimTokenHash)
629 if claimToken != "" && claimTokenHash == "" {
630 return fmt.Errorf("%w: task_run.claim_token_hash is required when claim_token is set", ErrValidation)
631 }
632 if claimTokenHash != "" && !isCanonicalClaimTokenHash(claimTokenHash) {
633 return fmt.Errorf("%w: task_run.claim_token_hash must be a lowercase sha256 hex hash", ErrValidation)
634 }
635 if !r.LeaseUntil.IsZero() && claimTokenHash == "" {
636 return fmt.Errorf("%w: task_run.claim_token_hash is required when lease_until is set", ErrValidation)
637 }
638 if !r.HeartbeatAt.IsZero() && claimTokenHash == "" {
639 return fmt.Errorf("%w: task_run.claim_token_hash is required when heartbeat_at is set", ErrValidation)
640 }
641 if !r.ClaimedAt.IsZero() && !r.LeaseUntil.IsZero() && !r.LeaseUntil.After(r.ClaimedAt) {
642 return fmt.Errorf("%w: task_run.lease_until must be after claimed_at", ErrValidation)
643 }
644 if !r.HeartbeatAt.IsZero() && !r.LeaseUntil.IsZero() && r.HeartbeatAt.After(r.LeaseUntil) {
645 return fmt.Errorf("%w: task_run.heartbeat_at must not be after lease_until", ErrValidation)
646 }
647 if !r.ClaimedAt.IsZero() && !r.HeartbeatAt.IsZero() && r.HeartbeatAt.Before(r.ClaimedAt) {
648 return fmt.Errorf("%w: task_run.heartbeat_at must not be before claimed_at", ErrValidation)
649 }
650 return nil
651}
652
653func isCanonicalClaimTokenHash(value string) bool {
654 hash := strings.TrimSpace(value)

Callers 1

ValidateMethod · 0.85

Calls 2

IsZeroMethod · 0.45

Tested by

no test coverage detected