Exclude staged Notarius bundles from publish uploads

This commit is contained in:
2026-08-10 01:43:43 +00:00
parent 0d6f2dd0ce
commit d01775b68a
3 changed files with 71 additions and 15 deletions

View File

@@ -28,7 +28,7 @@ implementation sequence.
| Stage 8 | Complete | | Stage 8 | Complete |
| Stage 9 | Complete | | Stage 9 | Complete |
| Stage 10 | Complete | | Stage 10 | Complete |
| Stage 11 | Pending | | Stage 11 | Complete |
| Stage 12 | Pending | | Stage 12 | Pending |
| Stage 13 | Pending | | Stage 13 | Pending |
| Stage 14 | Pending | | Stage 14 | Pending |

View File

@@ -573,26 +573,23 @@ func collectPublishRunFiles(runRoot, manifestPath string) ([]publishUploadFile,
if walkErr != nil { if walkErr != nil {
return walkErr return walkErr
} }
if d.IsDir() {
if path == runRoot { if path == runRoot {
return nil return nil
} }
relDir, err := filepath.Rel(runRoot, path)
if err != nil {
return fmt.Errorf("relative dir from %q to %q: %w", runRoot, path, err)
}
relDir = filepath.ToSlash(relDir)
// Preserve existing behavior: audio is not uploaded in publish run record.
if relDir == "audio" || strings.HasPrefix(relDir, "audio/") {
return filepath.SkipDir
}
return nil
}
rel, err := filepath.Rel(runRoot, path) rel, err := filepath.Rel(runRoot, path)
if err != nil { if err != nil {
return fmt.Errorf("relative path from %q to %q: %w", runRoot, path, err) return fmt.Errorf("relative path from %q to %q: %w", runRoot, path, err)
} }
rel = filepath.ToSlash(rel) rel = filepath.ToSlash(rel)
if publishRunPathExcluded(rel) {
if d.IsDir() {
return filepath.SkipDir
}
return nil
}
if d.IsDir() {
return nil
}
files = append(files, publishUploadFile{ files = append(files, publishUploadFile{
RelativePath: rel, RelativePath: rel,
LocalPath: path, LocalPath: path,
@@ -632,6 +629,11 @@ func collectPublishRunFiles(runRoot, manifestPath string) ([]publishUploadFile,
return files, nil return files, nil
} }
func publishRunPathExcluded(rel string) bool {
return rel == "audio" || strings.HasPrefix(rel, "audio/") ||
rel == "extract/notarius-output" || strings.HasPrefix(rel, "extract/notarius-output/")
}
func collectPublishPreviousFiles(previousDir string) ([]publishUploadFile, error) { func collectPublishPreviousFiles(previousDir string) ([]publishUploadFile, error) {
previousDir = filepath.Clean(strings.TrimSpace(previousDir)) previousDir = filepath.Clean(strings.TrimSpace(previousDir))
if previousDir == "" { if previousDir == "" {

View File

@@ -7,6 +7,7 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"reflect" "reflect"
"sort"
"strings" "strings"
"testing" "testing"
"time" "time"
@@ -64,8 +65,27 @@ func TestPublishFailsWhenPrerequisiteNotSucceeded(t *testing.T) {
} }
func TestPublishUploadsRunRecordPublishedOutputsAndCurrentPointer(t *testing.T) { func TestPublishUploadsRunRecordPublishedOutputsAndCurrentPointer(t *testing.T) {
env, m, _ := publishFixture(t) env, m, runRoot := publishFixture(t)
fake := env.ObjectStore.(*storage.FakeBackend) fake := env.ObjectStore.(*storage.FakeBackend)
lanePath := configurePublishExtractionFixture(t, env, m)
durableBundleRoot := filepath.Dir(filepath.Dir(lanePath))
runBundleRoot := filepath.Join(runRoot, "extract", "notarius-output", "notarius-run-1")
for rel, contents := range map[string]string{
"index.json": `{"lanes":[]}`,
"manifest.json": `{"run_id":"notarius-run-1"}`,
"rejected.json": `[]`,
"warnings.json": `[]`,
"lanes/encounters.json": `{"encounters":[]}`,
"pipeline/chunk-map.json": `{"chunks":[]}`,
"pipeline/evidence-context.json": `{"evidence":[]}`,
"unknown/notes.txt": "internal bundle note\n",
} {
writeStageTestFile(t, filepath.Join(runBundleRoot, filepath.FromSlash(rel)), contents)
}
writeStageTestFile(t, filepath.Join(runRoot, "extract", "notarius.receipt.json"), `{"run_id":"notarius-run-1"}`)
writeStageTestFile(t, filepath.Join(runRoot, "extract", "notarius.stderr.log"), "notarius diagnostic\n")
writeStageTestFile(t, filepath.Join(runRoot, "extract", "notarius-output-copy", "keep.json"), "{}\n")
writeStageTestFile(t, filepath.Join(runRoot, "archive", "notarius-output", "keep.json"), "{}\n")
result, err := publishStage{}.Run(context.Background(), env, m) result, err := publishStage{}.Run(context.Background(), env, m)
if err != nil { if err != nil {
@@ -76,6 +96,10 @@ func TestPublishUploadsRunRecordPublishedOutputsAndCurrentPointer(t *testing.T)
sessionPrefix := m.S3SessionPrefix sessionPrefix := m.S3SessionPrefix
wantRunUploads := []string{ wantRunUploads := []string{
"analyze/outputs/artifacts/session_recap.md", "analyze/outputs/artifacts/session_recap.md",
"archive/notarius-output/keep.json",
"extract/notarius-output-copy/keep.json",
"extract/notarius.receipt.json",
"extract/notarius.stderr.log",
"merge/config/seriatim.generated.yml", "merge/config/seriatim.generated.yml",
"prepare/inputs/session.yml", "prepare/inputs/session.yml",
"prepare/outputs/audio/speaker.flac", "prepare/outputs/audio/speaker.flac",
@@ -85,12 +109,24 @@ func TestPublishUploadsRunRecordPublishedOutputsAndCurrentPointer(t *testing.T)
"transcribe/outputs/transcripts/raw/speaker.json", "transcribe/outputs/transcripts/raw/speaker.json",
"trim/outputs/transcripts/final.trimmed.json", "trim/outputs/transcripts/final.trimmed.json",
} }
sort.Strings(wantRunUploads)
for _, rel := range wantRunUploads { for _, rel := range wantRunUploads {
key := runPrefix + rel key := runPrefix + rel
if _, ok := fake.Objects[key]; !ok { if _, ok := fake.Objects[key]; !ok {
t.Fatalf("missing run upload key %q", key) t.Fatalf("missing run upload key %q", key)
} }
} }
for key := range fake.Objects {
if strings.HasPrefix(key, runPrefix+"extract/notarius-output/") {
t.Fatalf("run-local Notarius bundle member was uploaded at %q", key)
}
}
for _, upload := range fake.Uploads {
localPath := filepath.Clean(upload.LocalPath)
if localPath == durableBundleRoot || strings.HasPrefix(localPath, durableBundleRoot+string(filepath.Separator)) {
t.Fatalf("durable Notarius bundle member was implicitly uploaded from %q", upload.LocalPath)
}
}
trimmedKey := sessionPrefix + "transcripts/final.trimmed.json" trimmedKey := sessionPrefix + "transcripts/final.trimmed.json"
recapKey := sessionPrefix + "artifacts/session_recap.md" recapKey := sessionPrefix + "artifacts/session_recap.md"
@@ -135,6 +171,12 @@ func TestPublishUploadsRunRecordPublishedOutputsAndCurrentPointer(t *testing.T)
if result.Metadata["previous_files_uploaded"] != 0 { if result.Metadata["previous_files_uploaded"] != 0 {
t.Fatalf("metadata previous_files_uploaded = %#v, want 0", result.Metadata["previous_files_uploaded"]) t.Fatalf("metadata previous_files_uploaded = %#v, want 0", result.Metadata["previous_files_uploaded"])
} }
if result.Metadata["run_files_uploaded"] != len(wantRunUploads) {
t.Fatalf("metadata run_files_uploaded = %#v, want %d", result.Metadata["run_files_uploaded"], len(wantRunUploads))
}
if got := result.Metadata["run_uploaded_paths"]; !reflect.DeepEqual(got, wantRunUploads) {
t.Fatalf("metadata run_uploaded_paths = %#v, want %#v", got, wantRunUploads)
}
} }
func TestPublishUploadsPreviousCacheWhenPresent(t *testing.T) { func TestPublishUploadsPreviousCacheWhenPresent(t *testing.T) {
@@ -212,6 +254,7 @@ func TestPublishUploadsExplicitExtractionAndPreservesManifestMetadata(t *testing
t.Fatalf("Run() error = %v", err) t.Fatalf("Run() error = %v", err)
} }
fake := env.ObjectStore.(*storage.FakeBackend) fake := env.ObjectStore.(*storage.FakeBackend)
durableBundleRoot := filepath.Dir(filepath.Dir(lanePath))
publishedKey := m.S3SessionPrefix + "artifacts/encounters.json" publishedKey := m.S3SessionPrefix + "artifacts/encounters.json"
if got := string(fake.Objects[publishedKey].Data); got != `{"encounters":[]}` { if got := string(fake.Objects[publishedKey].Data); got != `{"encounters":[]}` {
t.Fatalf("published extraction = %q", got) t.Fatalf("published extraction = %q", got)
@@ -224,6 +267,12 @@ func TestPublishUploadsExplicitExtractionAndPreservesManifestMetadata(t *testing
t.Fatalf("Notarius bundle member was implicitly published at %q", key) t.Fatalf("Notarius bundle member was implicitly published at %q", key)
} }
} }
for _, upload := range fake.Uploads {
localPath := filepath.Clean(upload.LocalPath)
if (localPath == durableBundleRoot || strings.HasPrefix(localPath, durableBundleRoot+string(filepath.Separator))) && localPath != filepath.Clean(lanePath) {
t.Fatalf("durable Notarius bundle member other than selected lane was uploaded from %q", upload.LocalPath)
}
}
if result.Metadata["published_files_uploaded"] != 1 { if result.Metadata["published_files_uploaded"] != 1 {
t.Fatalf("published_files_uploaded = %#v, want 1", result.Metadata["published_files_uploaded"]) t.Fatalf("published_files_uploaded = %#v, want 1", result.Metadata["published_files_uploaded"])
} }
@@ -723,6 +772,11 @@ func configurePublishExtractionFixture(t *testing.T, env *Env, m *manifest.Manif
indexPath := filepath.Join(bundleRoot, "index.json") indexPath := filepath.Join(bundleRoot, "index.json")
writeStageTestFile(t, lanePath, `{"encounters":[]}`) writeStageTestFile(t, lanePath, `{"encounters":[]}`)
writeStageTestFile(t, indexPath, `{"lanes":[]}`) writeStageTestFile(t, indexPath, `{"lanes":[]}`)
writeStageTestFile(t, filepath.Join(bundleRoot, "manifest.json"), `{"run_id":"notarius-run-1"}`)
writeStageTestFile(t, filepath.Join(bundleRoot, "rejected.json"), `[]`)
writeStageTestFile(t, filepath.Join(bundleRoot, "warnings.json"), `[]`)
writeStageTestFile(t, filepath.Join(bundleRoot, "pipeline", "chunk-map.json"), `{"chunks":[]}`)
writeStageTestFile(t, filepath.Join(bundleRoot, "unknown", "notes.txt"), "internal bundle note\n")
laneChecksum, err := artifacts.SHA256File(lanePath) laneChecksum, err := artifacts.SHA256File(lanePath)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)