Removed legacy interfaces and old documentation references to the previous on-disk layout

This commit is contained in:
2026-05-18 03:02:22 +00:00
parent 1054b64d9f
commit 2356688cb9
20 changed files with 150 additions and 759 deletions

View File

@@ -60,14 +60,6 @@ func runPostArchiveCleanup(ctx context.Context, env *Env, manifestPath string, m
strings.TrimSpace(env.Config.Session.SessionID),
strings.TrimSpace(m.RunID),
)
if info, err := os.Stat(workDir); err != nil || !info.IsDir() {
workDir = artifacts.SessionRunWorkDir(
env.Config.Pipeline.Workspace.Root,
strings.TrimSpace(env.Config.Session.Campaign),
strings.TrimSpace(env.Config.Session.SessionID),
strings.TrimSpace(m.RunID),
)
}
}
if spoolRequested {

View File

@@ -210,7 +210,7 @@ func TestPostArchiveCleanupNotRunWhenPromotionIsMissing(t *testing.T) {
assertExists(t, seed.spoolAudioDir)
assertExists(t, seed.runWorkDir)
assertExists(t, filepath.Join(seed.runWorkDir, "manifest.json"))
assertExists(t, artifacts.SessionRunWorkDir(cfg.Pipeline.Workspace.Root, cfg.Session.Campaign, cfg.Session.SessionID, runID))
assertExists(t, artifacts.SessionRunRootForCampaign(cfg.Pipeline.Workspace.Root, cfg.Session.Campaign, cfg.Session.SessionID, runID))
}
func TestPostArchiveCleanupNotRunWhenCurrentManifestUploadFails(t *testing.T) {
@@ -271,8 +271,8 @@ func cleanupFixtureConfig(t *testing.T) (*config.Config, cleanupSeed) {
cfg.Pipeline.Spool.Root = filepath.Join(t.TempDir(), "spool")
runID := "20260516T010203Z-1a2b3c4d"
runWorkDir := artifacts.SessionRunWorkDir(cfg.Pipeline.Workspace.Root, cfg.Session.Campaign, cfg.Session.SessionID, runID)
otherRunDir := artifacts.SessionRunWorkDir(cfg.Pipeline.Workspace.Root, cfg.Session.Campaign, cfg.Session.SessionID, "20260516T010204Z-5e6f7a8b")
runWorkDir := artifacts.SessionRunRootForCampaign(cfg.Pipeline.Workspace.Root, cfg.Session.Campaign, cfg.Session.SessionID, runID)
otherRunDir := artifacts.SessionRunRootForCampaign(cfg.Pipeline.Workspace.Root, cfg.Session.Campaign, cfg.Session.SessionID, "20260516T010204Z-5e6f7a8b")
spoolAudioDir := artifacts.SessionSpoolAudioDir(cfg.Pipeline.Spool.Root, cfg.Session.Campaign, cfg.Session.SessionID, runID)
mustWriteFile(t, filepath.Join(runWorkDir, "manifest.json"), "{}\n")

View File

@@ -84,12 +84,11 @@ func Resume(ctx context.Context, args []string, out io.Writer) error {
}
func loadManifestIfPresent(ctx context.Context, cfg *config.Config) (*manifest.Manifest, error) {
localStore := artifacts.NewLocalStore(cfg.Pipeline.Workspace.Root)
paths, err := localStore.ResolveSessionPathsFor(cfg.Session.Campaign, cfg.Session.SessionID)
if err != nil {
return nil, fmt.Errorf("resolve session workspace paths: %w", err)
}
path := paths.ManifestPath
path := artifacts.SessionManifestPathForCampaign(
cfg.Pipeline.Workspace.Root,
cfg.Session.Campaign,
cfg.Session.SessionID,
)
exists, err := fileExists(path)
if err != nil {
return nil, fmt.Errorf("check manifest %q: %w", path, err)

View File

@@ -30,18 +30,13 @@ func NewLocalStore(workspaceRoot string) *LocalStore {
return &LocalStore{WorkspaceRoot: workspaceRoot}
}
// SessionPaths resolves legacy paths for a session workdir.
func (s *LocalStore) SessionPaths(sessionID string) SessionPaths {
return buildLegacySessionPaths(s.WorkspaceRoot, sessionID)
}
// SessionPathsFor resolves canonical campaign-aware paths for a session workdir.
func (s *LocalStore) SessionPathsFor(campaign, sessionID string) SessionPaths {
return buildSessionPaths(s.WorkspaceRoot, campaign, sessionID)
}
// ResolveSessionPathsFor resolves the active session path with legacy compatibility.
func (s *LocalStore) ResolveSessionPathsFor(campaign, sessionID string) (SessionPaths, error) {
// EnsureLayoutFor creates and verifies campaign-aware session layout.
func (s *LocalStore) EnsureLayoutFor(campaign, sessionID string) (SessionPaths, error) {
if strings.TrimSpace(s.WorkspaceRoot) == "" {
return SessionPaths{}, fmt.Errorf("workspace root is required")
}
@@ -51,50 +46,10 @@ func (s *LocalStore) ResolveSessionPathsFor(campaign, sessionID string) (Session
campaign = strings.TrimSpace(campaign)
if campaign == "" {
return s.SessionPaths(sessionID), nil
return SessionPaths{}, fmt.Errorf("campaign is required")
}
canonical := s.SessionPathsFor(campaign, sessionID)
legacy := s.SessionPaths(sessionID)
canonicalExists, err := dirExists(canonical.Root)
if err != nil {
return SessionPaths{}, fmt.Errorf("check canonical session root %q: %w", canonical.Root, err)
}
legacyExists, err := dirExists(legacy.Root)
if err != nil {
return SessionPaths{}, fmt.Errorf("check legacy session root %q: %w", legacy.Root, err)
}
switch {
case canonicalExists && legacyExists:
return SessionPaths{}, fmt.Errorf(
"ambiguous session workspace roots for campaign %q session %q: canonical=%q legacy=%q",
campaign,
sessionID,
canonical.Root,
legacy.Root,
)
case canonicalExists:
return canonical, nil
case legacyExists:
return legacy, nil
default:
return canonical, nil
}
}
// EnsureLayout creates and verifies the canonical session workdir directory layout.
func (s *LocalStore) EnsureLayout(sessionID string) (SessionPaths, error) {
return s.ensureLayout(s.SessionPaths(sessionID))
}
// EnsureLayoutFor creates and verifies campaign-aware session layout, with controlled legacy compatibility.
func (s *LocalStore) EnsureLayoutFor(campaign, sessionID string) (SessionPaths, error) {
paths, err := s.ResolveSessionPathsFor(campaign, sessionID)
if err != nil {
return SessionPaths{}, err
}
return s.ensureLayout(paths)
return s.ensureLayout(s.SessionPathsFor(campaign, sessionID))
}
func (s *LocalStore) ensureLayout(paths SessionPaths) (SessionPaths, error) {
@@ -129,15 +84,6 @@ func (s *LocalStore) ensureLayout(paths SessionPaths) (SessionPaths, error) {
return paths, nil
}
// CopyInput copies an input file into the session workdir under destRelativePath.
func (s *LocalStore) CopyInput(sessionID, srcPath, destRelativePath string) (Ref, error) {
paths, err := s.EnsureLayout(sessionID)
if err != nil {
return Ref{}, err
}
return s.copyInputWithPaths(paths, sessionID, srcPath, destRelativePath)
}
// CopyInputFor copies an input file into the campaign-aware session workdir under destRelativePath.
func (s *LocalStore) CopyInputFor(campaign, sessionID, srcPath, destRelativePath string) (Ref, error) {
paths, err := s.EnsureLayoutFor(campaign, sessionID)
@@ -248,15 +194,6 @@ func (s *LocalStore) Checksum(path string) (string, error) {
return digest, nil
}
// AcquireSessionLock acquires an exclusive lock file for a session workdir.
func (s *LocalStore) AcquireSessionLock(sessionID string) (*LockHandle, error) {
paths, err := s.EnsureLayout(sessionID)
if err != nil {
return nil, err
}
return s.acquireSessionLockForPaths(paths)
}
// AcquireSessionLockFor acquires an exclusive lock file for a campaign/session workdir.
func (s *LocalStore) AcquireSessionLockFor(campaign, sessionID string) (*LockHandle, error) {
paths, err := s.EnsureLayoutFor(campaign, sessionID)
@@ -290,17 +227,6 @@ func (s *LocalStore) acquireSessionLockForPaths(paths SessionPaths) (*LockHandle
return &LockHandle{path: paths.LockPath, file: f}, nil
}
func dirExists(path string) (bool, error) {
info, err := os.Stat(path)
if err == nil {
return info.IsDir(), nil
}
if errors.Is(err, os.ErrNotExist) {
return false, nil
}
return false, err
}
// ReleaseSessionLock releases a previously acquired session lock.
func (s *LocalStore) ReleaseSessionLock(lock *LockHandle) error {
if lock == nil {

View File

@@ -36,40 +36,14 @@ func TestEnsureLayoutCreatesExpectedDirectories(t *testing.T) {
}
}
func TestResolveSessionPathsForLegacyFallback(t *testing.T) {
root := t.TempDir()
store := NewLocalStore(root)
legacyRoot := SessionWorkDir(root, "session-1")
if err := os.MkdirAll(legacyRoot, 0o755); err != nil {
t.Fatalf("MkdirAll() error = %v", err)
}
paths, err := store.ResolveSessionPathsFor("sample-campaign", "session-1")
if err != nil {
t.Fatalf("ResolveSessionPathsFor() error = %v", err)
}
if paths.Root != legacyRoot {
t.Fatalf("paths.Root = %q, want legacy root %q", paths.Root, legacyRoot)
}
}
func TestResolveSessionPathsForAmbiguousRoots(t *testing.T) {
root := t.TempDir()
store := NewLocalStore(root)
legacyRoot := SessionWorkDir(root, "session-1")
canonicalRoot := SessionWorkDirForCampaign(root, "sample-campaign", "session-1")
for _, dir := range []string{legacyRoot, canonicalRoot} {
if err := os.MkdirAll(dir, 0o755); err != nil {
t.Fatalf("MkdirAll(%q) error = %v", dir, err)
}
}
_, err := store.ResolveSessionPathsFor("sample-campaign", "session-1")
func TestEnsureLayoutForRequiresCampaign(t *testing.T) {
store := NewLocalStore(t.TempDir())
_, err := store.EnsureLayoutFor("", "session-1")
if err == nil {
t.Fatal("expected ambiguity error, got nil")
t.Fatal("expected campaign-required error, got nil")
}
if !strings.Contains(err.Error(), "ambiguous session workspace roots") {
t.Fatalf("error = %v, want ambiguity message", err)
if !strings.Contains(err.Error(), "campaign is required") {
t.Fatalf("error = %v, want campaign-required error", err)
}
}

View File

@@ -27,11 +27,6 @@ type SessionPaths struct {
LockPath string
}
// SessionWorkDir returns the legacy work directory for one session.
func SessionWorkDir(rootDir, sessionID string) string {
return filepath.Join(rootDir, config.PathWorkDirSegment, sessionID)
}
// SessionWorkDirForCampaign returns the canonical campaign-aware work directory for one session.
func SessionWorkDirForCampaign(rootDir, campaign, sessionID string) string {
return filepath.Join(rootDir, config.PathWorkDirSegment, campaign, sessionID)
@@ -62,21 +57,11 @@ func SessionRunStageDirForCampaign(rootDir, campaign, sessionID, runID, stageNam
return filepath.Join(SessionRunRootForCampaign(rootDir, campaign, sessionID, runID), stageName)
}
// SessionRunWorkDir returns the legacy campaign/session/run scoped local work directory.
func SessionRunWorkDir(rootDir, campaign, sessionID, runID string) string {
return filepath.Join(rootDir, config.PathWorkDirSegment, campaign, sessionID, runID)
}
// SessionSpoolAudioDir returns the campaign/session/run scoped local spool audio path.
func SessionSpoolAudioDir(spoolRoot, campaign, sessionID, runID string) string {
return filepath.Join(spoolRoot, campaign, sessionID, runID, config.PathAudioDirSegment)
}
func buildLegacySessionPaths(workspaceRoot, sessionID string) SessionPaths {
root := SessionWorkDir(workspaceRoot, sessionID)
return buildSessionPathsFromRoot(workspaceRoot, "", sessionID, root)
}
func buildSessionPaths(workspaceRoot, campaign, sessionID string) SessionPaths {
root := SessionWorkDirForCampaign(workspaceRoot, campaign, sessionID)
return buildSessionPathsFromRoot(workspaceRoot, campaign, sessionID, root)

View File

@@ -5,15 +5,6 @@ import (
"testing"
)
func TestSessionRunWorkDir(t *testing.T) {
root := "/tmp/workspace"
got := SessionRunWorkDir(root, "forsaken", "2026-04-19", "20260515T031522Z-a1b2c3d4")
want := filepath.Join(root, "work", "forsaken", "2026-04-19", "20260515T031522Z-a1b2c3d4")
if got != want {
t.Fatalf("SessionRunWorkDir() = %q, want %q", got, want)
}
}
func TestSessionWorkDirForCampaign(t *testing.T) {
root := "/tmp/workspace"
got := SessionWorkDirForCampaign(root, "forsaken", "2026-04-19")

View File

@@ -11,36 +11,16 @@ type S3Store struct {
Prefix string
}
// SessionPaths is not implemented for S3-backed storage.
func (s *S3Store) SessionPaths(_ string) SessionPaths {
return SessionPaths{}
}
// SessionPathsFor is not implemented for S3-backed storage.
func (s *S3Store) SessionPathsFor(_, _ string) SessionPaths {
return SessionPaths{}
}
// ResolveSessionPathsFor is not implemented for S3-backed storage.
func (s *S3Store) ResolveSessionPathsFor(_, _ string) (SessionPaths, error) {
return SessionPaths{}, fmt.Errorf("artifacts s3 resolve session paths: not yet implemented")
}
// EnsureLayout returns a not-yet-implemented error in the scaffold.
func (s *S3Store) EnsureLayout(_ string) (SessionPaths, error) {
return SessionPaths{}, fmt.Errorf("artifacts s3 ensure layout: not yet implemented")
}
// EnsureLayoutFor returns a not-yet-implemented error in the scaffold.
func (s *S3Store) EnsureLayoutFor(_, _ string) (SessionPaths, error) {
return SessionPaths{}, fmt.Errorf("artifacts s3 ensure layout for campaign/session: not yet implemented")
}
// CopyInput returns a not-yet-implemented error in the scaffold.
func (s *S3Store) CopyInput(_, _, _ string) (Ref, error) {
return Ref{}, fmt.Errorf("artifacts s3 copy input: not yet implemented")
}
// CopyInputFor returns a not-yet-implemented error in the scaffold.
func (s *S3Store) CopyInputFor(_, _, _, _ string) (Ref, error) {
return Ref{}, fmt.Errorf("artifacts s3 copy input for campaign/session: not yet implemented")
@@ -66,11 +46,6 @@ func (s *S3Store) Checksum(_ string) (string, error) {
return "", fmt.Errorf("artifacts s3 checksum: not yet implemented")
}
// AcquireSessionLock returns a not-yet-implemented error in the scaffold.
func (s *S3Store) AcquireSessionLock(_ string) (*LockHandle, error) {
return nil, fmt.Errorf("artifacts s3 acquire lock: not yet implemented")
}
// AcquireSessionLockFor returns a not-yet-implemented error in the scaffold.
func (s *S3Store) AcquireSessionLockFor(_, _ string) (*LockHandle, error) {
return nil, fmt.Errorf("artifacts s3 acquire lock for campaign/session: not yet implemented")

View File

@@ -15,18 +15,13 @@ type Ref struct {
// Store is the local artifact/workdir abstraction used by orchestration code.
type Store interface {
SessionPaths(sessionID string) SessionPaths
SessionPathsFor(campaign, sessionID string) SessionPaths
ResolveSessionPathsFor(campaign, sessionID string) (SessionPaths, error)
EnsureLayout(sessionID string) (SessionPaths, error)
EnsureLayoutFor(campaign, sessionID string) (SessionPaths, error)
CopyInput(sessionID, srcPath, destRelativePath string) (Ref, error)
CopyInputFor(campaign, sessionID, srcPath, destRelativePath string) (Ref, error)
Exists(path string) (bool, error)
ExistsRef(ref Ref) (bool, error)
WriteFileAtomic(path string, data []byte, perm os.FileMode) error
Checksum(path string) (string, error)
AcquireSessionLock(sessionID string) (*LockHandle, error)
AcquireSessionLockFor(campaign, sessionID string) (*LockHandle, error)
ReleaseSessionLock(lock *LockHandle) error
}

View File

@@ -264,27 +264,14 @@ func resolveArchiveRunRoot(env *Env, m *manifest.Manifest) (string, error) {
}
canonical := filepath.Clean(artifacts.SessionRunRootForCampaign(env.Config.Pipeline.Workspace.Root, campaign, sessionID, runID))
legacy := filepath.Clean(artifacts.SessionRunWorkDir(env.Config.Pipeline.Workspace.Root, campaign, sessionID, runID))
canonicalExists, err := directoryExists(canonical)
if err != nil {
return "", fmt.Errorf("check canonical run root %q: %w", canonical, err)
}
legacyExists, err := directoryExists(legacy)
if err != nil {
return "", fmt.Errorf("check legacy run root %q: %w", legacy, err)
}
switch {
case canonicalExists && legacyExists && canonical != legacy:
return "", fmt.Errorf("ambiguous run roots for campaign %q session %q run %q: canonical=%q legacy=%q", campaign, sessionID, runID, canonical, legacy)
case canonicalExists:
return canonical, nil
case legacyExists:
return legacy, nil
default:
return "", fmt.Errorf("run root not found for campaign %q session %q run %q (checked canonical=%q legacy=%q)", campaign, sessionID, runID, canonical, legacy)
if !canonicalExists {
return "", fmt.Errorf("run root not found for campaign %q session %q run %q at canonical path %q", campaign, sessionID, runID, canonical)
}
return canonical, nil
}
func resolveArchiveSessionRoot(env *Env, m *manifest.Manifest) (string, error) {
@@ -299,11 +286,10 @@ func resolveArchiveSessionRoot(env *Env, m *manifest.Manifest) (string, error) {
if sessionID == "" {
return "", fmt.Errorf("session id is required")
}
paths, err := artifacts.NewLocalStore(env.Config.Pipeline.Workspace.Root).ResolveSessionPathsFor(campaign, sessionID)
if err != nil {
return "", err
if campaign == "" {
return "", fmt.Errorf("campaign is required")
}
return filepath.Clean(paths.Root), nil
return filepath.Clean(artifacts.SessionWorkDirForCampaign(env.Config.Pipeline.Workspace.Root, campaign, sessionID)), nil
}
func archiveRunPrefix(env *Env, m *manifest.Manifest) (string, error) {

View File

@@ -183,61 +183,18 @@ func TestArchiveFailsWhenRequiredPromotionMissing(t *testing.T) {
}
}
func TestArchivePromotionFailsOnAmbiguousSessionRoots(t *testing.T) {
env, m, _ := archiveFixture(t)
sessionWorkDir := artifacts.SessionWorkDir(env.Config.Pipeline.Workspace.Root, m.SessionID)
writeStageTestFile(t, filepath.Join(sessionWorkDir, "transcripts", "trimmed.json"), "{}\n")
_, err := archiveStage{}.Run(context.Background(), env, m)
if err == nil {
t.Fatal("expected ambiguity error, got nil")
}
if !strings.Contains(err.Error(), "ambiguous session workspace roots") {
t.Fatalf("error = %v, want ambiguity error", err)
}
}
func TestArchiveFallsBackToLegacyRunRootWhenCanonicalMissing(t *testing.T) {
func TestArchiveFailsWhenCanonicalRunRootMissing(t *testing.T) {
env, m, runRoot := archiveFixture(t)
legacyRoot := artifacts.SessionRunWorkDir(
env.Config.Pipeline.Workspace.Root,
env.Config.Session.Campaign,
env.Config.Session.SessionID,
m.RunID,
)
if err := os.MkdirAll(filepath.Dir(legacyRoot), 0o755); err != nil {
t.Fatalf("create legacy run-root parent: %v", err)
}
if err := os.Rename(runRoot, legacyRoot); err != nil {
t.Fatalf("move canonical run root to legacy root: %v", err)
}
m.LocalWorkDir = legacyRoot
if _, err := (archiveStage{}).Run(context.Background(), env, m); err != nil {
t.Fatalf("Run() error = %v", err)
}
}
func TestArchiveFailsOnAmbiguousCanonicalAndLegacyRunRoots(t *testing.T) {
env, m, runRoot := archiveFixture(t)
legacyRoot := artifacts.SessionRunWorkDir(
env.Config.Pipeline.Workspace.Root,
env.Config.Session.Campaign,
env.Config.Session.SessionID,
m.RunID,
)
writeStageTestFile(t, filepath.Join(legacyRoot, "manifest.json"), "{}\n")
writeStageTestFile(t, filepath.Join(legacyRoot, "prepare", "inputs", "session.yml"), "session_id: 2026-04-19\n")
if runRoot == legacyRoot {
t.Fatalf("test requires distinct canonical and legacy run roots, got %q", runRoot)
if err := os.RemoveAll(runRoot); err != nil {
t.Fatalf("remove run root: %v", err)
}
_, err := archiveStage{}.Run(context.Background(), env, m)
if err == nil {
t.Fatal("expected ambiguity error, got nil")
t.Fatal("expected missing run-root error, got nil")
}
if !strings.Contains(err.Error(), "ambiguous run roots") {
t.Fatalf("error = %v, want run-root ambiguity", err)
if !strings.Contains(err.Error(), "run root not found") {
t.Fatalf("error = %v, want missing run-root error", err)
}
}

View File

@@ -358,6 +358,10 @@ func pathsWorkDirForManifest(env *Env, m *manifest.Manifest, sessionID string) s
if env == nil || env.Config == nil || env.Config.Pipeline == nil || env.Config.Session == nil {
return ""
}
campaign := strings.TrimSpace(env.Config.Session.Campaign)
if campaign == "" {
return ""
}
if m != nil && strings.TrimSpace(m.LocalWorkDir) != "" {
return strings.TrimSpace(m.LocalWorkDir)
}
@@ -366,15 +370,7 @@ func pathsWorkDirForManifest(env *Env, m *manifest.Manifest, sessionID string) s
runID = strings.TrimSpace(m.RunID)
}
if runID != "" {
campaign := strings.TrimSpace(env.Config.Session.Campaign)
if campaign != "" {
return artifacts.SessionRunRootForCampaign(env.Config.Pipeline.Workspace.Root, campaign, sessionID, runID)
}
return artifacts.SessionRunWorkDir(env.Config.Pipeline.Workspace.Root, campaign, sessionID, runID)
}
campaign := strings.TrimSpace(env.Config.Session.Campaign)
if campaign == "" {
return artifacts.SessionWorkDir(env.Config.Pipeline.Workspace.Root, sessionID)
return artifacts.SessionRunRootForCampaign(env.Config.Pipeline.Workspace.Root, campaign, sessionID, runID)
}
return artifacts.SessionWorkDirForCampaign(env.Config.Pipeline.Workspace.Root, campaign, sessionID)
}

View File

@@ -160,7 +160,7 @@ func TestPrepareStageS3AudioDownloadAndMaterialization(t *testing.T) {
env.Config.Pipeline.Spool = config.SpoolConfig{Root: filepath.Join(t.TempDir(), "spool")}
env.Config.Pipeline.Storage.S3 = &config.StorageS3Config{Bucket: "my-dnd-archive", RootPrefix: "dnd"}
m.RunID = "20260515T031522Z-a1b2c3d4"
m.LocalWorkDir = artifacts.SessionRunWorkDir(env.Config.Pipeline.Workspace.Root, "forsaken", m.SessionID, m.RunID)
m.LocalWorkDir = artifacts.SessionRunRootForCampaign(env.Config.Pipeline.Workspace.Root, "forsaken", m.SessionID, m.RunID)
m.LocalSpoolDir = artifacts.SessionSpoolAudioDir(env.Config.Pipeline.Spool.Root, "forsaken", m.SessionID, m.RunID)
fake := &storage.FakeBackend{}
@@ -256,7 +256,7 @@ func TestPrepareStageS3AudioFailures(t *testing.T) {
env.Config.Pipeline.Spool = config.SpoolConfig{Root: filepath.Join(t.TempDir(), "spool")}
env.Config.Pipeline.Storage.S3 = &config.StorageS3Config{Bucket: "my-dnd-archive", RootPrefix: "dnd"}
m.RunID = "20260515T031522Z-a1b2c3d4"
m.LocalWorkDir = artifacts.SessionRunWorkDir(env.Config.Pipeline.Workspace.Root, "forsaken", m.SessionID, m.RunID)
m.LocalWorkDir = artifacts.SessionRunRootForCampaign(env.Config.Pipeline.Workspace.Root, "forsaken", m.SessionID, m.RunID)
m.LocalSpoolDir = artifacts.SessionSpoolAudioDir(env.Config.Pipeline.Spool.Root, "forsaken", m.SessionID, m.RunID)
fake := &storage.FakeBackend{}

View File

@@ -11,9 +11,6 @@ func sessionPathsForEnv(env *Env, sessionID string) artifacts.SessionPaths {
if env != nil && env.Config != nil && env.Config.Session != nil {
campaign = strings.TrimSpace(env.Config.Session.Campaign)
}
if campaign == "" {
return env.ArtifactStore.SessionPaths(sessionID)
}
return env.ArtifactStore.SessionPathsFor(campaign, sessionID)
}
@@ -22,8 +19,5 @@ func ensureLayoutForEnv(env *Env, sessionID string) (artifacts.SessionPaths, err
if env != nil && env.Config != nil && env.Config.Session != nil {
campaign = strings.TrimSpace(env.Config.Session.Campaign)
}
if campaign == "" {
return env.ArtifactStore.EnsureLayout(sessionID)
}
return env.ArtifactStore.EnsureLayoutFor(campaign, sessionID)
}

View File

@@ -233,7 +233,7 @@ func setupTranscribeEnv(t *testing.T, audioFiles []string) (*Env, *manifest.Mani
sessionPath := filepath.Join(cfgDir, "session.yml")
pipelinePath := filepath.Join(cfgDir, "pipeline.yml")
writeFile(t, sessionPath, "session_id: 2026-05-03\n")
writeFile(t, sessionPath, "session_id: 2026-05-03\ncampaign: sample-campaign\n")
writeFile(t, pipelinePath, "workspace:\n root: "+workspace+"\n")
writeFile(t, filepath.Join(cfgDir, "speakers.yml"), "alice: alice.flac\n")
writeFile(t, filepath.Join(cfgDir, "autocorrect.yml"), "[]\n")
@@ -257,6 +257,7 @@ func setupTranscribeEnv(t *testing.T, audioFiles []string) (*Env, *manifest.Mani
},
Session: &config.SessionConfig{
SessionID: "2026-05-03",
Campaign: "sample-campaign",
Inputs: config.SessionInputsConfig{
AudioDir: "./audio",
SpeakersFile: "./speakers.yml",