Require manifest-backed local artifacts

This commit is contained in:
2026-09-02 14:09:32 +00:00
parent 62b1f9b0ae
commit 57719b7d81
28 changed files with 392 additions and 179 deletions

View File

@@ -156,7 +156,7 @@ func TestExtractLifecyclePrepareBindsVerifiedReferenceSnapshots(t *testing.T) {
if err != nil {
t.Fatalf("executeStages() error = %v", err)
}
if len(summary.Executed) != 2 || len(runner.requests) != 1 {
if len(summary.Executed) != 3 || len(runner.requests) != 1 {
t.Fatalf("summary = %#v requests=%d", summary, len(runner.requests))
}
paths, err := artifacts.NewLocalStore(cfg.Pipeline.Workspace.Root).EnsureLayoutFor(cfg.Session.Campaign, cfg.Session.SessionID)
@@ -510,12 +510,12 @@ func TestExtractLifecycleRerunsAfterDirectTranscriptChange(t *testing.T) {
t.Fatalf("Save(mutated) error = %v", err)
}
rerun, err := executeStages(context.Background(), cfg, plan, RunOptions{Env: env})
if err != nil {
t.Fatalf("rerun executeStages() error = %v", err)
_, err := executeStages(context.Background(), cfg, plan, RunOptions{Env: env})
if err == nil || !strings.Contains(err.Error(), "checksum mismatch") {
t.Fatalf("rerun executeStages() error = %v, want stale transcript evidence rejection", err)
}
if len(rerun.Executed) != 2 || len(rerun.Skipped) != 0 || len(runner.requests) != 2 || analyzeRuns != 2 {
t.Fatalf("rerun summary = %#v requests=%d analyze=%d", rerun, len(runner.requests), analyzeRuns)
if len(runner.requests) != 1 || analyzeRuns != 1 {
t.Fatalf("stale transcript should prevent extraction, requests=%d analyze=%d", len(runner.requests), analyzeRuns)
}
}
@@ -645,7 +645,24 @@ func prepareExtractLifecyclePlan(t *testing.T) []stage.Stage {
if err != nil {
t.Fatalf("BuildSingleStagePlan(extract) error = %v", err)
}
return append(prepare, extract...)
return append(append(prepare, lifecycleTrimEvidenceStage{}), extract...)
}
type lifecycleTrimEvidenceStage struct{}
func (lifecycleTrimEvidenceStage) Name() string { return "trim" }
func (lifecycleTrimEvidenceStage) Run(_ context.Context, env *stage.Env, m *manifest.Manifest) (*stage.StageResult, error) {
paths := artifacts.NewLocalStore(env.Config.Pipeline.Workspace.Root).SessionPathsFor(m.Campaign, m.SessionID)
path := filepath.Join(paths.ArtifactsDir, "trimmed.from-manifest.json")
checksum, err := artifacts.SHA256File(path)
if err != nil {
return nil, err
}
return &stage.StageResult{Outputs: []artifacts.Ref{{
Kind: artifactmodel.TranscriptOutputKindFinalTrimmed, SourceID: artifactmodel.SourceTranscriptFinalTrimmed,
AbsolutePath: path, Checksum: checksum,
}}}, nil
}
func configureLifecycleReferences(t *testing.T, cfg *config.Config) map[string]string {
@@ -738,9 +755,13 @@ func extractionLifecycleFixture(t *testing.T, enabled bool) (*config.Config, *st
}
m := manifest.New(cfg.Session.SessionID, time.Now().UTC())
m.Campaign = cfg.Session.Campaign
inputChecksum, err := artifacts.SHA256File(inputPath)
if err != nil {
t.Fatalf("SHA256File(input) error = %v", err)
}
m.MarkStageSucceeded("trim", time.Now().UTC(), []manifest.ArtifactRecord{{
Kind: artifactmodel.TranscriptOutputKindFinalTrimmed, SourceID: artifactmodel.SourceTranscriptFinalTrimmed,
LocalPath: inputPath,
LocalPath: inputPath, ProducerRunID: "trim-run", Checksum: inputChecksum,
}})
if err := (&manifest.LocalStore{}).Save(context.Background(), paths.ManifestPath, m); err != nil {
t.Fatalf("Save(seed) error = %v", err)