Protect transcript refinement resume semantics
This commit is contained in:
@@ -130,7 +130,7 @@ func TestRunArtifactsWithSucceededAnalyzeSkipsUnlessForced(t *testing.T) {
|
||||
seed.MarkStageSucceeded(stageName, time.Date(2026, 5, 3, 10, 1, 0, 0, time.UTC), nil)
|
||||
}
|
||||
seed.MarkStageSkipped("extract", time.Date(2026, 5, 3, 10, 1, 0, 0, time.UTC), "notarius_disabled")
|
||||
seedCurrentSemanticEvidence(t, loadConfigForSemanticEvidence(t, pipelinePath, campaignPath, sessionPath), seed, "prepare", "transcribe", "merge")
|
||||
seedCurrentSemanticEvidence(t, loadConfigForSemanticEvidence(t, pipelinePath, campaignPath, sessionPath), seed, "prepare", "transcribe", "merge", "polish", "normalize", "trim", "render")
|
||||
if err := store.Save(context.Background(), manifestPath, seed); err != nil {
|
||||
t.Fatalf("save manifest: %v", err)
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ func TestRunNoRemainingStagesRecordsSkippedStages(t *testing.T) {
|
||||
m.MarkStageSucceeded(name, time.Date(2026, 5, 3, 10, 1, 0, 0, time.UTC), nil)
|
||||
}
|
||||
m.MarkStageSkipped("extract", time.Date(2026, 5, 3, 10, 1, 0, 0, time.UTC), "notarius_disabled")
|
||||
seedCurrentSemanticEvidence(t, loadConfigForSemanticEvidence(t, pipelinePath, campaignPath, sessionPath), m, "prepare", "transcribe", "merge")
|
||||
seedCurrentSemanticEvidence(t, loadConfigForSemanticEvidence(t, pipelinePath, campaignPath, sessionPath), m, "prepare", "transcribe", "merge", "polish", "normalize", "trim", "render")
|
||||
if err := store.Save(context.Background(), manifestPath, m); err != nil {
|
||||
t.Fatalf("save manifest: %v", err)
|
||||
}
|
||||
@@ -174,6 +174,7 @@ func TestRunStageSkipAndForce(t *testing.T) {
|
||||
store := &manifest.LocalStore{}
|
||||
m := manifest.New("2026-05-03", time.Date(2026, 5, 3, 10, 0, 0, 0, time.UTC))
|
||||
m.MarkStageSucceeded("polish", time.Date(2026, 5, 3, 10, 1, 0, 0, time.UTC), nil)
|
||||
seedCurrentSemanticEvidence(t, loadConfigForSemanticEvidence(t, pipelinePath, campaignPath, sessionPath), m, "polish")
|
||||
if err := store.Save(context.Background(), manifestPath, m); err != nil {
|
||||
t.Fatalf("save manifest: %v", err)
|
||||
}
|
||||
|
||||
@@ -367,6 +367,74 @@ func TestInitialPipelineSemanticChangesRerunOnlyAffectedLineage(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRefinementSemanticChangesRespectDependencyBranches(t *testing.T) {
|
||||
names := []string{"prepare", "transcribe", "merge", "polish", "normalize", "trim", "render"}
|
||||
for _, test := range []struct {
|
||||
name string
|
||||
mutate func(*config.Config)
|
||||
wantRuns [7]int
|
||||
wantExtractStatus manifest.StageStatus
|
||||
}{
|
||||
{name: "polish model", mutate: func(cfg *config.Config) {
|
||||
cfg.Pipeline.Audita.Model = "production"
|
||||
}, wantRuns: [7]int{0, 0, 0, 1, 1, 1, 1}, wantExtractStatus: manifest.StatusStale},
|
||||
{name: "normalize schema", mutate: func(cfg *config.Config) {
|
||||
cfg.Pipeline.Normalize = &config.NormalizeConfig{OutputSchema: "seriatim.transcript.v2"}
|
||||
}, wantRuns: [7]int{0, 0, 0, 0, 1, 1, 1}, wantExtractStatus: manifest.StatusStale},
|
||||
{name: "trim prompt", mutate: func(cfg *config.Config) {
|
||||
enabled := true
|
||||
cfg.Pipeline.Trim = &config.TrimConfig{
|
||||
Enabled: &enabled,
|
||||
Bounds: config.TrimBoundsConfig{PromptID: "session-bounds-v2"},
|
||||
}
|
||||
}, wantRuns: [7]int{0, 0, 0, 0, 0, 1, 1}, wantExtractStatus: manifest.StatusStale},
|
||||
{name: "render format", mutate: func(cfg *config.Config) {
|
||||
cfg.Pipeline.Render = &config.RenderConfig{Format: "html"}
|
||||
}, wantRuns: [7]int{0, 0, 0, 0, 0, 0, 1}, wantExtractStatus: manifest.StatusSucceeded},
|
||||
} {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
cfg := testConfig(t)
|
||||
providers := make([]stage.SemanticConfigFingerprinter, len(names))
|
||||
seed := manifest.New(cfg.Session.SessionID, time.Now().UTC())
|
||||
for _, candidate := range stage.All() {
|
||||
seed.MarkStageSucceeded(candidate.Name(), time.Now().UTC(), nil)
|
||||
}
|
||||
for index, name := range names {
|
||||
providers[index] = canonicalSemanticProvider(t, name)
|
||||
fingerprint, err := providers[index].SemanticConfigFingerprint(&stage.Env{Config: cfg})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
seed.Stages[name].SemanticConfig = &fingerprint
|
||||
}
|
||||
store := &manifest.LocalStore{}
|
||||
if err := store.Save(context.Background(), manifestPathFor(cfg), seed); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
test.mutate(cfg)
|
||||
|
||||
runs := [7]int{}
|
||||
selected := make([]stage.Stage, 0, len(names))
|
||||
for index, name := range names {
|
||||
selected = append(selected, semanticContractRunStub{name: name, provider: providers[index], runs: &runs[index]})
|
||||
}
|
||||
if _, err := executeStages(context.Background(), cfg, selected, RunOptions{}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if runs != test.wantRuns {
|
||||
t.Fatalf("runs = %v, want %v", runs, test.wantRuns)
|
||||
}
|
||||
loaded, err := store.Load(context.Background(), manifestPathFor(cfg))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if got := loaded.Stages["extract"].Status; got != test.wantExtractStatus {
|
||||
t.Fatalf("extract status = %q, want %q", got, test.wantExtractStatus)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func canonicalSemanticProvider(t *testing.T, name string) stage.SemanticConfigFingerprinter {
|
||||
t.Helper()
|
||||
for _, candidate := range stage.All() {
|
||||
|
||||
Reference in New Issue
Block a user