package app import ( "context" "fmt" "gitea.maximumdirect.net/eric/narratio/internal/artifacts" "gitea.maximumdirect.net/eric/narratio/internal/config" "gitea.maximumdirect.net/eric/narratio/internal/manifest" ) func validateBoundedPrerequisites(plan BoundedPlan, m *manifest.Manifest) error { if !plan.HasExplicitBounds() { return nil } for _, name := range plan.PrefixNames() { status := "absent" if m != nil && m.Stages != nil && m.Stages[name] != nil { stageStatus := m.Stages[name].Status if stageStatus == manifest.StatusSucceeded || stageStatus == manifest.StatusSkipped { continue } if stageStatus != "" { status = string(stageStatus) } } return fmt.Errorf( "prerequisite stage %q has unusable status %q before selected start %q; widen the range with --from %s or recover %s explicitly", name, status, plan.From(), name, name, ) } return nil } func inspectBoundedPrerequisites(ctx context.Context, cfg *config.Config, plan BoundedPlan, store manifest.Store) error { if !plan.HasExplicitBounds() || len(plan.PrefixNames()) == 0 { return nil } if cfg == nil || cfg.Pipeline == nil || cfg.Session == nil { return fmt.Errorf("bounded prerequisite inspection requires resolved pipeline and session configuration") } if store == nil { store = &manifest.LocalStore{} } path := artifacts.SessionManifestPathForCampaign( cfg.Pipeline.Workspace.Root, cfg.Session.Campaign, cfg.Session.SessionID, ) m, present, err := loadManifestAtPathIfPresent(ctx, store, path) if err != nil { return err } if !present { m = nil } return validateBoundedPrerequisites(plan, m) }