Files
Agent-System-Backend/internal/wfcompile/project_backend.go
T
weichen ecb86f4309 Recheck project workflow sources without storing prompts
Why: Goal-sensitive workflow verification persisted model prompts and prior output text in trusted receipt rows, while cross-step model inputs could reuse stale machine output.

Evidence: RED receipt privacy test; full Go suite, targeted race, isolated PostgreSQL store/runmgr/storage-migrate tests, vet, and static build passed locally before commit. A known unrelated TempDir cleanup flake failed once and passed on targeted and serial full replay.

Impact: Add optional same-provider source recheck, verify every included item and evidence body before reuse, gate cross-step outputs, reject unsettled attempts, remove raw scope columns, scrub isolated candidate v34 SQLite/PG schemas, and reject unsafe backups.

Refs: Approved RDM stage6 W6 source-recheck design adjustment r1; W6 independent review.
2026-10-14 05:38:11 +00:00

49 lines
1.6 KiB
Go

package wfcompile
import (
"context"
"path/filepath"
"agent-squad/squad"
"agent-system-backend/internal/projectcontext"
)
// projectStepBackends carries the engine-generated execution ID through the
// executor's request context into each model manifest. This associates a
// responded model request with exactly one workflow step attempt.
func projectStepBackends(base *squad.BackendResolver, rc ProjectStepProvenance, subOf, kinds map[string]string) *squad.BackendResolver {
wrapped := squad.NewBackendResolver()
for _, name := range base.ListBackends() {
backendName := name
wrapped.Register(backendName, func(role squad.RoleSpec) (squad.Executor, error) {
backend, _, err := base.Resolve(role, backendName)
if err != nil {
return nil, err
}
return &projectStepExecutor{next: backend, rc: rc, subOf: subOf, kinds: kinds}, nil
})
}
return wrapped
}
type projectStepExecutor struct {
next squad.Executor
rc ProjectStepProvenance
subOf, kinds map[string]string
}
func (e *projectStepExecutor) Name() string { return e.next.Name() }
func (e *projectStepExecutor) Execute(ctx context.Context, req squad.ExecRequest) (*squad.ExecResult, error) {
if req.ExecutionID == "" {
return &squad.ExecResult{Success: false, ErrorReason: "project workflow step attempt unavailable"}, nil
}
if e.rc != nil {
wsDir := filepath.Dir(filepath.Dir(req.WorkDir))
if err := verifyPriorWorkflowOutputs(ctx, e.rc, wsDir, e.subOf, e.kinds, true); err != nil {
return &squad.ExecResult{Success: false, ErrorReason: err.Error()}, nil
}
}
return e.next.Execute(projectcontext.WithWorkflowStepAttempt(ctx, req.ExecutionID), req)
}