From 0ef861ed8f54765b513796c4ce8b021a57b4a422 Mon Sep 17 00:00:00 2001 From: Eric Rakestraw Date: Sat, 20 Jun 2026 13:31:22 +0000 Subject: [PATCH] Discover metadata with new workspace filenames --- internal/state/filesystem.go | 6 ++- internal/state/filesystem_test.go | 68 +++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 1 deletion(-) diff --git a/internal/state/filesystem.go b/internal/state/filesystem.go index 0353c21..0f6fb0b 100644 --- a/internal/state/filesystem.go +++ b/internal/state/filesystem.go @@ -517,7 +517,11 @@ func validatePathSegment(name string, value string) error { } func isMetadataFilename(name string) bool { - return strings.HasPrefix(name, "metadata.") && strings.HasSuffix(name, ".json") && len(name) > len("metadata..json") + if !strings.HasPrefix(name, "metadata.") || !strings.HasSuffix(name, ".json") { + return false + } + runID := strings.TrimSuffix(strings.TrimPrefix(name, "metadata."), ".json") + return strings.TrimSpace(runID) != "" && !strings.ContainsAny(runID, `/\`) && runID != "." && runID != ".." } func readJSON(path string, target any) error { diff --git a/internal/state/filesystem_test.go b/internal/state/filesystem_test.go index d764fbd..3835796 100644 --- a/internal/state/filesystem_test.go +++ b/internal/state/filesystem_test.go @@ -642,11 +642,79 @@ func TestSaveMetadataUsesExplicitMetadataPath(t *testing.T) { } } +func TestListReportsDiscoversNewMetadataFilename(t *testing.T) { + store := newTestStore(t) + older := resolveDailyAt(t, "2026-05-29T05:00:00-05:00") + newer := resolveTodayAt(t, "2026-05-29T08:00:00-05:00") + olderPaths := savePriorMetadata(t, store, older, stateBriefingMetadata(older)) + newerPaths := savePriorMetadata(t, store, newer, stateBriefingMetadata(newer)) + + records, err := store.ListReports(context.Background(), 0) + if err != nil { + t.Fatalf("ListReports() error = %v", err) + } + if len(records) != 2 { + t.Fatalf("ListReports() len = %d, want 2: %#v", len(records), records) + } + if records[0].RunID != newer.Metadata().RunID || records[0].MetadataPath != newerPaths.Metadata { + t.Fatalf("first record = %#v, want newer metadata path %q", records[0], newerPaths.Metadata) + } + if records[1].RunID != older.Metadata().RunID || records[1].MetadataPath != olderPaths.Metadata { + t.Fatalf("second record = %#v, want older metadata path %q", records[1], olderPaths.Metadata) + } + + metadata, metadataPath, err := store.LoadMetadataByRunID(context.Background(), older.Metadata().RunID) + if err != nil { + t.Fatalf("LoadMetadataByRunID() error = %v", err) + } + if metadata.RunID != older.Metadata().RunID || metadataPath != olderPaths.Metadata { + t.Fatalf("loaded metadata = %#v path %q, want run %q path %q", metadata, metadataPath, older.Metadata().RunID, olderPaths.Metadata) + } + if want := "metadata." + older.Metadata().RunID + ".json"; filepath.Base(metadataPath) != want { + t.Fatalf("metadata filename = %q, want %q", filepath.Base(metadataPath), want) + } +} + +func TestListReportsIgnoresNonMetadataJSON(t *testing.T) { + store := newTestStore(t) + resolved := resolveDailyAt(t, "2026-05-29T05:00:00-05:00") + paths := savePriorMetadata(t, store, resolved, stateBriefingMetadata(resolved)) + for _, path := range []string{ + paths.ModuleSnapshot, + paths.GeneratedTextRaw, + paths.GeneratedTextResult, + paths.GeneratedText, + paths.RenderContext, + filepath.Join(filepath.Dir(paths.Metadata), resolved.Metadata().RunID+".metadata.json"), + } { + if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil { + t.Fatalf("create non-metadata artifact directory: %v", err) + } + if err := os.WriteFile(path, []byte(`{not json`), 0o600); err != nil { + t.Fatalf("write non-metadata artifact %q: %v", path, err) + } + } + + records, err := store.ListReports(context.Background(), 0) + if err != nil { + t.Fatalf("ListReports() error = %v", err) + } + if len(records) != 1 { + t.Fatalf("ListReports() len = %d, want only metadata record: %#v", len(records), records) + } + if records[0].MetadataPath != paths.Metadata { + t.Fatalf("MetadataPath = %q, want %q", records[0].MetadataPath, paths.Metadata) + } +} + func TestFindPriorSnapshot(t *testing.T) { store := newTestStore(t) first := resolveDailyAt(t, "2026-05-29T05:00:00-05:00") second := resolveDailyAt(t, "2026-05-29T08:00:00-05:00") paths := savePriorMetadata(t, store, first, stateBriefingMetadata(first)) + if want := "metadata." + first.Metadata().RunID + ".json"; filepath.Base(paths.Metadata) != want { + t.Fatalf("metadata filename = %q, want %q", filepath.Base(paths.Metadata), want) + } prior, err := store.FindPriorSnapshot(context.Background(), second) if err != nil {