package artifacts import ( "context" "fmt" "os" "strings" "gitea.maximumdirect.net/eric/narratio/internal/adapters/storage" "gitea.maximumdirect.net/eric/narratio/internal/manifest" ) // This file is temporary compatibility support for sessions published before // immutable current commits. It can be removed after legacy remote state is migrated. func loadLegacyCurrentState( ctx context.Context, store storage.ObjectStore, sessionPrefix string, validation CurrentStateValidation, ) (*CurrentState, error) { currentManifestKey, currentRunIDKey := ResolveCurrentStateKeys(sessionPrefix) runID, err := loadLegacyCurrentRunPointer(ctx, store, currentRunIDKey) if err != nil { return nil, err } m, err := loadLegacyCurrentManifest(ctx, store, currentManifestKey) if err != nil { return nil, err } state := &CurrentState{ SessionPrefix: sessionPrefix, CurrentRunIDKey: currentRunIDKey, CurrentManifestKey: currentManifestKey, RunID: runID, Manifest: m, } if err := ValidateCurrentStateIdentity(state, validation); err != nil { return nil, err } return state, nil } func loadLegacyCurrentRunPointer(ctx context.Context, store storage.ObjectStore, currentRunIDKey string) (string, error) { key := strings.TrimSpace(currentRunIDKey) if key == "" { return "", fmt.Errorf("current run pointer key is required") } exists, err := store.Exists(ctx, key) if err != nil { return "", fmt.Errorf("check current run pointer %q: %w", key, err) } if !exists { return "", &CurrentRunPointerMissingError{Key: key} } data, err := downloadRemoteObject(ctx, store, key, "narratio-legacy-current-run-id-*.txt") if err != nil { return "", fmt.Errorf("download current run pointer %q: %w", key, err) } runID := strings.TrimSpace(string(data)) if runID == "" { return "", fmt.Errorf("current run pointer %q is empty", key) } if err := ValidateRunIdentity(runID); err != nil { return "", fmt.Errorf("current run pointer %q contains an unsafe legacy run id; migrate remote state before use: %w", key, err) } return runID, nil } func loadLegacyCurrentManifest(ctx context.Context, store storage.ObjectStore, currentManifestKey string) (*manifest.Manifest, error) { key := strings.TrimSpace(currentManifestKey) if key == "" { return nil, fmt.Errorf("current manifest key is required") } exists, err := store.Exists(ctx, key) if err != nil { return nil, fmt.Errorf("check current manifest %q: %w", key, err) } if !exists { return nil, &CurrentManifestMissingError{Key: key} } localPath, err := storage.DownloadObjectToTemp(ctx, store, key, "narratio-legacy-current-manifest-*.json") if err != nil { return nil, fmt.Errorf("download current manifest %q: %w", key, err) } defer func() { _ = os.Remove(localPath) }() m, err := (&manifest.LocalStore{}).Load(ctx, localPath) if err != nil { return nil, fmt.Errorf("current manifest decode failed: %w", err) } return m, nil }