Isolate runner finalization

This commit is contained in:
2026-09-04 01:15:07 +00:00
parent 2ee64f2eb1
commit dbda2a0161
3 changed files with 64 additions and 45 deletions

View File

@@ -360,7 +360,7 @@ preserving every durable transition and failure boundary.
## Stage 5 — Isolate Finalization And Simplify The Lifecycle Owner
**Status: Pending**
**Status: Completed**
### Goal

View File

@@ -71,10 +71,6 @@ func executePlanWithDependencies(ctx context.Context, cfg *config.Config, plan B
return nil, err
}
env := runtime.env
manifestPath := runtime.manifestPath
m := runtime.manifest
runID := runtime.identity.RunID
for _, selected := range runtime.stages {
runtime.stageNames = append(runtime.stageNames, selected.Name())
outcome, err := executeSelectedStage(runtime, selected)
@@ -88,25 +84,7 @@ func executePlanWithDependencies(ctx context.Context, cfg *config.Config, plan B
runtime.skipped = append(runtime.skipped, selected.Name())
}
}
if containsStage(runtime.executed, "publish") {
if err := runPostPublishCleanup(ctx, env, manifestPath, m, runtime.executed, runtime.dependencies.removeScopedDir); err != nil {
return nil, persistPostPublishCleanupFailure(
ctx, env.ManifestStore, manifestPath, m,
fmt.Errorf("post-publish cleanup incomplete: %w", err),
runtime.dependencies.now(),
)
}
}
return &RunSummary{
SessionID: cfg.Session.SessionID,
RunID: runID,
ManifestPath: manifestPath,
StageNames: runtime.stageNames,
Executed: runtime.executed,
Skipped: runtime.skipped,
}, nil
return finalizeInvocation(runtime)
}
func stagesContainAny(stages []stage.Stage, names ...string) bool {
@@ -125,27 +103,6 @@ func stagesContainAny(stages []stage.Stage, names ...string) bool {
return false
}
func persistPostPublishCleanupFailure(
ctx context.Context,
sessionStore manifest.Store,
sessionManifestPath string,
sessionManifest *manifest.Manifest,
operationErr error,
at time.Time,
) error {
if operationErr == nil {
return nil
}
if sessionManifest != nil {
sessionManifest.RecordFailure(at, operationErr.Error())
}
// Cleanup may have deliberately removed the selected run directory. The
// committed remote snapshot remains authoritative, while the session
// manifest records the outstanding local cleanup for the next invocation.
sessionErr := sessionStore.Save(ctx, sessionManifestPath, sessionManifest)
return errors.Join(operationErr, wrapTerminalPersistenceError("save terminal session manifest", sessionErr))
}
func persistSessionTerminalFailure(
ctx context.Context,
sessionStore manifest.Store,

View File

@@ -0,0 +1,62 @@
package app
import (
"context"
"errors"
"fmt"
"time"
"gitea.maximumdirect.net/eric/narratio/internal/manifest"
)
func finalizeInvocation(runtime *invocationRuntime) (*RunSummary, error) {
if containsStage(runtime.executed, "publish") {
if err := runPostPublishCleanup(
runtime.ctx,
runtime.env,
runtime.manifestPath,
runtime.manifest,
runtime.executed,
runtime.dependencies.removeScopedDir,
); err != nil {
return nil, persistPostPublishCleanupFailure(
runtime.ctx,
runtime.manifestStore,
runtime.manifestPath,
runtime.manifest,
fmt.Errorf("post-publish cleanup incomplete: %w", err),
runtime.dependencies.now(),
)
}
}
return &RunSummary{
SessionID: runtime.identity.SessionID,
RunID: runtime.identity.RunID,
ManifestPath: runtime.manifestPath,
StageNames: runtime.stageNames,
Executed: runtime.executed,
Skipped: runtime.skipped,
}, nil
}
func persistPostPublishCleanupFailure(
ctx context.Context,
sessionStore manifest.Store,
sessionManifestPath string,
sessionManifest *manifest.Manifest,
operationErr error,
at time.Time,
) error {
if operationErr == nil {
return nil
}
if sessionManifest != nil {
sessionManifest.RecordFailure(at, operationErr.Error())
}
// Cleanup may have deliberately removed the selected run directory. The
// committed remote snapshot remains authoritative, while the session
// manifest records the outstanding local cleanup for the next invocation.
sessionErr := sessionStore.Save(ctx, sessionManifestPath, sessionManifest)
return errors.Join(operationErr, wrapTerminalPersistenceError("save terminal session manifest", sessionErr))
}