Files
agent-radar 2ed3415fb7
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

1604 lines
54 KiB
Go

package tuttimodeexecution_test
import (
"context"
"database/sql"
"errors"
"fmt"
"path/filepath"
"slices"
"strings"
"sync"
"testing"
"time"
workspaceissues "github.com/tutti-os/tutti/packages/workspace/issues"
executionbiz "github.com/tutti-os/tutti/services/tuttid/biz/tuttimodeexecution"
workspacebiz "github.com/tutti-os/tutti/services/tuttid/biz/workspace"
workflowbiz "github.com/tutti-os/tutti/services/tuttid/biz/workspaceworkflow"
workspacedata "github.com/tutti-os/tutti/services/tuttid/data/workspace"
tuttimodeexecutionservice "github.com/tutti-os/tutti/services/tuttid/service/tuttimodeexecution"
tuttimodeexecutionconformance "github.com/tutti-os/tutti/services/tuttid/service/tuttimodeexecution/conformance"
tuttimodeplanservice "github.com/tutti-os/tutti/services/tuttid/service/tuttimodeplan"
workspaceservice "github.com/tutti-os/tutti/services/tuttid/service/workspace"
"gopkg.in/yaml.v3"
)
type sqliteConformanceDriver struct {
dbPath string
store *workspacedata.SQLiteStore
issues workspaceservice.IssueManagerService
executions *tuttimodeexecutionservice.Service
plans *tuttimodeplanservice.Service
revisions workspacedata.WorkflowRevisionFiles
clock *controlledClock
launcher *recordingLauncher
renewals *manualLeaseRenewalScheduler
canceller *recordingRunCanceller
wakeTarget *recordingMainWakeTarget
wakeStore *injectableWakeStore
reviewer *recordingReviewerTarget
automationTurns *recordingAutomationTurnCanceller
reviewMu sync.Mutex
failReviewStep string
deletionAdmissions map[string]executionbiz.SourceSessionDeletionAdmission
cancelAuto context.CancelFunc
}
type conformanceSourceSessionContextResolver struct{}
func (conformanceSourceSessionContextResolver) ResolveSourceSessionContext(
_ string,
_ string,
) (workspaceservice.IssueSourceSessionContext, bool) {
return workspaceservice.IssueSourceSessionContext{}, true
}
type controlledClock struct {
mu sync.Mutex
now time.Time
}
type recordingAutomationTurnCanceller struct {
mu sync.Mutex
cancellations []tuttimodeexecutionconformance.AutomationTurnCancellation
failNext bool
}
func (canceller *recordingAutomationTurnCanceller) CancelAutomationTurn(
_ context.Context,
_ string,
sessionID string,
turnID string,
) error {
canceller.mu.Lock()
defer canceller.mu.Unlock()
if canceller.failNext {
canceller.failNext = false
return errors.New("injected automation Turn cancellation failure")
}
canceller.cancellations = append(
canceller.cancellations,
tuttimodeexecutionconformance.AutomationTurnCancellation{
SessionID: sessionID, TurnID: turnID,
},
)
return nil
}
func (driver *sqliteConformanceDriver) FailNextAutomationTurnCancellation() {
driver.automationTurns.mu.Lock()
defer driver.automationTurns.mu.Unlock()
driver.automationTurns.failNext = true
}
func (clock *controlledClock) Now() time.Time {
clock.mu.Lock()
defer clock.mu.Unlock()
return clock.now
}
func (clock *controlledClock) Advance(duration time.Duration) {
clock.mu.Lock()
defer clock.mu.Unlock()
clock.now = clock.now.Add(duration)
}
func (clock *controlledClock) Set(now time.Time) {
clock.mu.Lock()
defer clock.mu.Unlock()
clock.now = now
}
type manualLeaseRenewalScheduler struct {
mu sync.Mutex
generation uint64
renew func() error
}
func (scheduler *manualLeaseRenewalScheduler) Start(
_ context.Context,
_ time.Duration,
renew func() error,
) func() {
scheduler.mu.Lock()
scheduler.generation++
generation := scheduler.generation
scheduler.renew = renew
scheduler.mu.Unlock()
var once sync.Once
return func() {
once.Do(func() {
scheduler.mu.Lock()
defer scheduler.mu.Unlock()
if scheduler.generation == generation {
scheduler.renew = nil
}
})
}
}
func (scheduler *manualLeaseRenewalScheduler) Tick() error {
scheduler.mu.Lock()
renew := scheduler.renew
scheduler.mu.Unlock()
if renew == nil {
return fmt.Errorf("no in-flight launch lease to renew")
}
return renew()
}
func (scheduler *manualLeaseRenewalScheduler) StopCurrent() {
scheduler.mu.Lock()
defer scheduler.mu.Unlock()
scheduler.renew = nil
}
type recordingLauncher struct {
mu sync.Mutex
calls int
callSignal chan struct{}
failNext bool
failBeforeCanonical bool
failAfterBlock bool
clientSubmitIDs []string
canonicalByClientSubmit map[string]string
blockNext bool
started chan struct{}
release chan struct{}
}
type recordingReviewerTarget struct {
mu sync.Mutex
calls int
failBeforeCanonical bool
failAfterCanonical bool
busyBySession map[string]bool
canonicalByClientSubmit map[string]tuttimodeexecutionservice.ReviewerDelivery
capabilities []string
onNextSend func(
tuttimodeexecutionservice.ReviewerLaunch,
tuttimodeexecutionservice.ReviewerDelivery,
) error
settleNext bool
}
func (target *recordingReviewerTarget) ObserveReviewerSession(
_ context.Context,
_ string,
sessionID string,
) (tuttimodeexecutionservice.ReviewerSessionObservation, error) {
target.mu.Lock()
defer target.mu.Unlock()
return tuttimodeexecutionservice.ReviewerSessionObservation{
Busy: target.busyBySession[sessionID],
}, nil
}
func (target *recordingReviewerTarget) SendReviewer(
_ context.Context,
launch tuttimodeexecutionservice.ReviewerLaunch,
) (tuttimodeexecutionservice.ReviewerDelivery, error) {
target.mu.Lock()
target.calls++
target.capabilities = append([]string(nil), launch.Capabilities...)
if target.failBeforeCanonical {
target.failBeforeCanonical = false
target.mu.Unlock()
return tuttimodeexecutionservice.ReviewerDelivery{}, errors.New("injected reviewer failure before canonical Turn")
}
if target.canonicalByClientSubmit == nil {
target.canonicalByClientSubmit = make(map[string]tuttimodeexecutionservice.ReviewerDelivery)
}
delivery, found := target.canonicalByClientSubmit[launch.ClientSubmitID]
if !found {
delivery = tuttimodeexecutionservice.ReviewerDelivery{
CanonicalSessionID: launch.SessionID,
CanonicalTurnID: fmt.Sprintf("review-turn-%d", len(target.canonicalByClientSubmit)+1),
}
target.canonicalByClientSubmit[launch.ClientSubmitID] = delivery
}
if target.settleNext {
target.settleNext = false
delivery.Settled = true
target.canonicalByClientSubmit[launch.ClientSubmitID] = delivery
}
onSend := target.onNextSend
target.onNextSend = nil
if target.failAfterCanonical {
target.failAfterCanonical = false
target.mu.Unlock()
return tuttimodeexecutionservice.ReviewerDelivery{}, errors.New("injected reviewer response loss after canonical Turn")
}
target.mu.Unlock()
if onSend != nil {
if err := onSend(launch, delivery); err != nil {
return tuttimodeexecutionservice.ReviewerDelivery{}, err
}
}
return delivery, nil
}
func (target *recordingReviewerTarget) ReadReviewer(
_ context.Context,
launch tuttimodeexecutionservice.ReviewerLaunch,
) (tuttimodeexecutionservice.ReviewerDelivery, bool, error) {
target.mu.Lock()
defer target.mu.Unlock()
delivery, found := target.canonicalByClientSubmit[launch.ClientSubmitID]
return delivery, found, nil
}
func (launcher *recordingLauncher) Launch(_ context.Context, launch workspaceservice.IssueRunLaunch) error {
launcher.mu.Lock()
launcher.calls++
if launcher.callSignal != nil {
close(launcher.callSignal)
launcher.callSignal = make(chan struct{})
}
launcher.clientSubmitIDs = append(launcher.clientSubmitIDs, launch.ClientSubmitID)
failBeforeCanonical := launcher.failBeforeCanonical
launcher.failBeforeCanonical = false
if failBeforeCanonical {
launcher.mu.Unlock()
return workspaceservice.NewIssueRunLaunchNotStartedError(
fmt.Errorf("injected authoritative launch failure before canonical Turn creation"),
)
}
fail := launcher.failNext
if launcher.failNext {
launcher.failNext = false
}
block := launcher.blockNext
failAfterBlock := launcher.failAfterBlock
launcher.failAfterBlock = false
started := launcher.started
release := launcher.release
launcher.blockNext = false
launcher.mu.Unlock()
if block {
close(started)
<-release
}
if failAfterBlock {
return workspaceservice.NewIssueRunLaunchNotStartedError(
fmt.Errorf("injected stale authoritative launch failure"),
)
}
launcher.mu.Lock()
if launcher.canonicalByClientSubmit == nil {
launcher.canonicalByClientSubmit = make(map[string]string)
}
if _, exists := launcher.canonicalByClientSubmit[launch.ClientSubmitID]; !exists {
launcher.canonicalByClientSubmit[launch.ClientSubmitID] = fmt.Sprintf(
"turn-%d", len(launcher.canonicalByClientSubmit)+1,
)
}
launcher.mu.Unlock()
if fail {
return fmt.Errorf("injected launch failure after canonical Turn creation")
}
return nil
}
func newSQLiteConformanceDriver(t *testing.T) *sqliteConformanceDriver {
t.Helper()
dbPath := filepath.Join(t.TempDir(), "tutti.sqlite")
store, err := workspacedata.OpenSQLiteStore(dbPath)
if err != nil {
t.Fatalf("OpenSQLiteStore() error = %v", err)
}
t.Cleanup(func() {
_ = store.Close()
})
if err := store.Migrate(context.Background()); err != nil {
t.Fatalf("Migrate() error = %v", err)
}
if err := store.Create(context.Background(), workspacebiz.Summary{
ID: "workspace-materialization",
Name: "Materialization",
}); err != nil {
t.Fatalf("Create() workspace error = %v", err)
}
now := time.Date(2026, 7, 28, 12, 0, 0, 0, time.UTC)
clock := &controlledClock{now: now}
launcher := &recordingLauncher{}
renewals := &manualLeaseRenewalScheduler{}
canceller := &recordingRunCanceller{}
wakeTarget := newRecordingMainWakeTarget()
wakeStore := newInjectableWakeStore(store)
reviewer := &recordingReviewerTarget{
busyBySession: make(map[string]bool),
canonicalByClientSubmit: make(map[string]tuttimodeexecutionservice.ReviewerDelivery),
}
automationTurns := &recordingAutomationTurnCanceller{}
executions := &tuttimodeexecutionservice.Service{
Store: store, Wakes: wakeStore, MainWakeTargets: wakeTarget,
ReviewerActivity: store, ReviewerTargets: reviewer, Clock: clock.Now,
ArchiveAutomationTurns: automationTurns,
}
driver := &sqliteConformanceDriver{
dbPath: dbPath, store: store,
issues: workspaceservice.IssueManagerService{
Store: store, RunLauncher: launcher, TuttiModeExecutions: executions,
SourceSessionContextResolver: conformanceSourceSessionContextResolver{},
MutationLocks: workspaceservice.NewIssueMutationLocks(),
TuttiModeRunLaunchLeaseDuration: time.Minute,
RunLaunchLeaseRenewalScheduler: renewals,
RunCancellationRequester: canceller,
},
executions: executions,
revisions: workspacedata.WorkflowRevisionFiles{StateDir: t.TempDir()},
clock: clock,
launcher: launcher,
renewals: renewals,
canceller: canceller,
wakeTarget: wakeTarget,
wakeStore: wakeStore,
reviewer: reviewer,
automationTurns: automationTurns,
deletionAdmissions: make(map[string]executionbiz.SourceSessionDeletionAdmission),
}
driver.executions.Archives = store
driver.executions.ArchiveRuns = &workspaceservice.IssueExecutionCoordinator{
Issues: &driver.issues, RunSessionCanceller: canceller,
}
executions.BeforeGoalReviewCommitStep = driver.beforeGoalReviewCommitStep
driver.plans = &tuttimodeplanservice.Service{
Store: store,
Revisions: driver.revisions,
IssueMaterializer: tuttimodeplanservice.WorkspaceIssueMaterializer{Issues: &driver.issues},
Now: clock.Now,
}
return driver
}
func (driver *sqliteConformanceDriver) AcceptPlan(
ctx context.Context,
input tuttimodeexecutionconformance.AcceptPlanInput,
) (string, error) {
now := driver.clock.Now()
tasks := make([]tuttimodeplanservice.PlanTask, 0, len(input.Tasks))
for _, task := range input.Tasks {
tasks = append(tasks, tuttimodeplanservice.PlanTask{
ID: task.TaskID,
Title: task.Title,
Content: task.Content,
Priority: task.Priority,
AgentTargetID: task.AgentTargetID,
Model: task.Model,
PermissionModeID: task.PermissionModeID,
ExecutionDirectory: task.ExecutionDirectory,
DependsOn: append([]string(nil), task.DependencyTaskIDs...),
Parallelizable: task.Parallelizable,
AutoAccept: task.AutoAccept,
})
}
frontmatter, err := yaml.Marshal(tuttimodeplanservice.PlanDocument{
Schema: tuttimodeplanservice.SchemaV1,
Phase: tuttimodeplanservice.PhaseTaskGraph,
Title: input.Title,
TopicID: input.TopicID,
Execution: tuttimodeplanservice.PlanExecution{
Mode: "sequential",
ReasoningIntensity: 50,
OrchestrationIntensity: 50,
},
Budget: tuttimodeplanservice.PlanBudget{
Mode: firstNonEmptyConformance(input.BudgetMode, "auto"),
TokenLimit: input.TokenLimit,
},
Review: tuttimodeplanservice.PlanReview{
Mode: input.ReviewMode,
AgentTargetID: input.ReviewAgentTargetID,
},
Tasks: tasks,
})
if err != nil {
return "", fmt.Errorf("encode plan revision: %w", err)
}
raw := []byte("---\n" + string(frontmatter) + "---\n" + input.Content + "\n")
documentPath, digest, err := driver.revisions.Write(input.WorkflowID, raw)
if err != nil {
return "", fmt.Errorf("write plan revision: %w", err)
}
if err := driver.store.CreateWorkspaceWorkflowProposal(ctx, workflowbiz.ProposalAggregate{
Workflow: workflowbiz.Workflow{
ID: input.WorkflowID,
WorkspaceID: input.WorkspaceID,
Type: workflowbiz.WorkflowTypeTuttiModePlan,
Owner: workflowbiz.WorkflowOwnerTutti,
TriggerKind: workflowbiz.TriggerKindAgentCLI,
SourceSessionID: input.SourceSessionID,
Status: workflowbiz.WorkflowStatusPendingReview,
CurrentRevisionID: input.RevisionID,
CreatedAt: now,
UpdatedAt: now,
},
Plan: workflowbiz.TuttiModePlan{WorkflowID: input.WorkflowID},
Revision: workflowbiz.PlanRevision{
ID: input.RevisionID,
WorkflowID: input.WorkflowID,
Sequence: 1,
SchemaVersion: tuttimodeplanservice.SchemaV1,
DocumentPath: documentPath,
SHA256: digest,
CreatedAt: now,
},
Checkpoint: workflowbiz.WorkflowCheckpoint{
ID: input.CheckpointID,
WorkflowID: input.WorkflowID,
Kind: workflowbiz.CheckpointKindTaskReview,
RevisionID: input.RevisionID,
Status: workflowbiz.CheckpointStatusPending,
CreatedAt: now,
UpdatedAt: now,
},
}); err != nil {
return "", fmt.Errorf("seed pending plan review: %w", err)
}
result, err := driver.plans.Decide(ctx, tuttimodeplanservice.DecideInput{
WorkspaceID: input.WorkspaceID,
WorkflowID: input.WorkflowID,
CheckpointID: input.CheckpointID,
Decision: workflowbiz.CheckpointStatusAccepted,
DecidedBy: "conformance-user",
})
if err != nil {
return "", err
}
if result.Operation == nil ||
result.Operation.Status != workflowbiz.OperationStatusSucceeded ||
result.Operation.IssueID == "" {
return "", fmt.Errorf("accept plan operation = %#v, want succeeded create_issue", result.Operation)
}
return result.Operation.IssueID, nil
}
func (driver *sqliteConformanceDriver) GetIssueByID(
ctx context.Context,
workspaceID string,
issueID string,
) (tuttimodeexecutionconformance.Issue, []tuttimodeexecutionconformance.Task, error) {
detail, err := driver.issues.GetIssueDetail(ctx, workspaceID, issueID)
if err != nil {
return tuttimodeexecutionconformance.Issue{}, nil, err
}
issue := tuttimodeexecutionconformance.Issue{
WorkspaceID: detail.Issue.WorkspaceID,
IssueID: detail.Issue.IssueID,
TopicID: detail.Issue.TopicID,
Title: detail.Issue.Title,
Content: detail.Issue.Content,
Status: string(detail.Issue.Status),
TaskCount: detail.Issue.TaskCount,
CompletedCount: detail.Issue.CompletedCount,
CanceledCount: detail.Issue.CanceledCount,
PlanningSource: string(detail.Issue.PlanningSource),
SourceSessionID: detail.Issue.SourceSessionID,
}
tasks := make([]tuttimodeexecutionconformance.Task, 0, len(detail.Tasks))
for _, task := range detail.Tasks {
tasks = append(tasks, tuttimodeexecutionconformance.Task{
TaskID: task.TaskID,
Title: task.Title,
Content: task.Content,
Status: string(task.Status),
AcceptanceState: string(task.AcceptanceState),
Priority: string(task.Priority),
SortIndex: task.SortIndex,
AgentTargetID: task.AgentTargetID,
Model: task.Model,
PermissionModeID: task.PermissionModeID,
ExecutionDirectory: task.ExecutionDirectory,
DependencyTaskIDs: append([]string(nil), task.DependencyTaskIDs...),
Parallelizable: task.Parallelizable,
AutoAccept: task.AutoAccept,
SupersededAtUnixMS: task.SupersededAtUnixMS,
SupersededByTaskID: task.SupersededByTaskID,
})
}
return issue, tasks, nil
}
func (driver *sqliteConformanceDriver) Mutate(
ctx context.Context,
input tuttimodeexecutionconformance.MutateInput,
) (tuttimodeexecutionconformance.MutateResult, error) {
return driver.mutateWith(ctx, driver.executions, input)
}
func (driver *sqliteConformanceDriver) MutateReplica(
ctx context.Context,
input tuttimodeexecutionconformance.MutateInput,
) (tuttimodeexecutionconformance.MutateResult, error) {
replica := &tuttimodeexecutionservice.Service{
Store: driver.store, Wakes: driver.wakeStore, Clock: driver.clock.Now,
}
return driver.mutateWith(ctx, replica, input)
}
func (*sqliteConformanceDriver) mutateWith(
ctx context.Context,
service *tuttimodeexecutionservice.Service,
input tuttimodeexecutionconformance.MutateInput,
) (tuttimodeexecutionconformance.MutateResult, error) {
operations := make([]executionbiz.MutationOperation, 0, len(input.Operations))
for _, operation := range input.Operations {
taskFields := executionbiz.MutationTaskFields{
Title: operation.Task.Title != "",
Content: operation.Task.Content != "",
Priority: operation.Task.Priority != "",
AgentTargetID: operation.Task.AgentTargetID != "",
Model: operation.Task.Model != "",
PermissionModeID: operation.Task.PermissionModeID != "",
ExecutionDirectory: operation.Task.ExecutionDirectory != "",
DependencyTaskIDs: operation.Task.DependencyTaskIDs != nil,
Parallelizable: operation.Task.Parallelizable,
AutoAccept: operation.Task.AutoAccept,
}
operations = append(operations, executionbiz.MutationOperation{
Kind: executionbiz.MutationOperationKind(operation.Kind),
TaskID: operation.TaskID,
Task: workspaceissues.Task{
TaskID: operation.Task.TaskID, Title: operation.Task.Title,
Content: operation.Task.Content, Priority: workspaceissues.Priority(operation.Task.Priority),
AgentTargetID: operation.Task.AgentTargetID, Model: operation.Task.Model,
PermissionModeID: operation.Task.PermissionModeID,
ExecutionDirectory: operation.Task.ExecutionDirectory,
DependencyTaskIDs: append([]string(nil), operation.Task.DependencyTaskIDs...),
Parallelizable: operation.Task.Parallelizable,
AutoAccept: operation.Task.AutoAccept,
},
TaskFields: taskFields,
})
}
result, err := service.Mutate(ctx, tuttimodeexecutionservice.MutateInput{
WorkspaceID: input.WorkspaceID, IssueID: input.IssueID,
SourceSessionID: input.SourceSessionID, CheckpointID: input.CheckpointID,
ExpectedGraphRevision: input.ExpectedGraphRevision,
Operations: operations, RequestID: input.RequestID,
})
if err != nil {
return tuttimodeexecutionconformance.MutateResult{}, err
}
return tuttimodeexecutionconformance.MutateResult{
ExecutionID: result.ExecutionID, CheckpointID: result.CheckpointID,
GraphRevision: result.GraphRevision,
AddedTaskIDs: append([]string(nil), result.AddedTaskIDs...),
UpdatedTaskIDs: append([]string(nil), result.UpdatedTaskIDs...),
SupersededTaskIDs: append([]string(nil), result.SupersededTaskIDs...),
Replayed: result.Replayed,
}, nil
}
func (driver *sqliteConformanceDriver) GetSnapshot(
ctx context.Context,
workspaceID string,
issueID string,
) (tuttimodeexecutionconformance.Snapshot, error) {
issue, tasks, err := driver.GetIssueByID(ctx, workspaceID, issueID)
if err != nil {
return tuttimodeexecutionconformance.Snapshot{}, err
}
execution, checkpoints, err := driver.GetExecutionByIssue(ctx, workspaceID, issueID)
if err != nil {
return tuttimodeexecutionconformance.Snapshot{}, err
}
runCount, err := driver.CountRuns(ctx, workspaceID, issueID)
if err != nil {
return tuttimodeexecutionconformance.Snapshot{}, err
}
runs, err := driver.issues.ListRuns(ctx, workspaceID, issueID, "")
if err != nil {
return tuttimodeexecutionconformance.Snapshot{}, err
}
snapshotRuns := make([]tuttimodeexecutionconformance.RunSnapshot, 0, len(runs))
outputCount := 0
for _, run := range runs {
snapshotRuns = append(snapshotRuns, tuttimodeexecutionconformance.RunSnapshot{
RunID: run.RunID, TaskID: run.TaskID, Status: string(run.Status),
})
outputs, outputErr := driver.store.ListRunOutputs(
ctx, workspaceID, issueID, run.TaskID, run.RunID,
)
if outputErr != nil {
return tuttimodeexecutionconformance.Snapshot{}, outputErr
}
outputCount += len(outputs)
}
reviews, err := driver.executions.ListGoalReviews(ctx, workspaceID, issueID)
if err != nil {
return tuttimodeexecutionconformance.Snapshot{}, err
}
audit, err := driver.executions.ListGoalReviewAudit(ctx, workspaceID, issueID)
if err != nil {
return tuttimodeexecutionconformance.Snapshot{}, err
}
snapshotReviews := make([]tuttimodeexecutionconformance.GoalReview, 0, len(reviews))
for _, review := range reviews {
snapshotReviews = append(snapshotReviews, tuttimodeexecutionconformance.GoalReview{
ReviewID: review.ID, CheckpointID: review.CheckpointID,
AgentTargetID: review.AgentTargetID, ClientSubmitID: review.ClientSubmitID,
SessionID: review.SessionID, TurnID: review.TurnID,
Status: string(review.Status), Verdict: string(review.Verdict),
Summary: review.Summary, FailureReason: review.FailureReason,
AttemptCount: review.AttemptCount, LeaseOwner: review.LeaseOwner,
LeaseExpiresAt: review.LeaseExpiresAt,
})
}
snapshotAudit := make([]tuttimodeexecutionconformance.ReviewAuditEntry, 0, len(audit))
for _, entry := range audit {
snapshotAudit = append(snapshotAudit, tuttimodeexecutionconformance.ReviewAuditEntry{
Kind: entry.Kind, ActorID: entry.ActorID, Reason: entry.Reason,
ReviewID: entry.ReviewID, CreatedAt: entry.CreatedAt,
})
}
return tuttimodeexecutionconformance.Snapshot{
Issue: issue,
Tasks: tasks,
Execution: execution,
Checkpoints: checkpoints,
RunCount: runCount,
Runs: snapshotRuns,
OutputCount: outputCount,
Reviews: snapshotReviews,
Audit: snapshotAudit,
}, nil
}
func (driver *sqliteConformanceDriver) Schedule(
ctx context.Context,
input tuttimodeexecutionconformance.ScheduleInput,
) (tuttimodeexecutionconformance.ScheduleResult, error) {
result, err := driver.issues.ScheduleTuttiModeIssue(ctx, input.WorkspaceID, workspaceservice.ScheduleTuttiModeIssueInput{
IssueID: input.IssueID,
SourceSessionID: input.SourceSessionID,
CheckpointID: input.CheckpointID,
ExpectedGraphRevision: input.ExpectedGraphRevision,
TaskIDs: append([]string(nil), input.TaskIDs...),
RequestID: input.RequestID,
})
if err != nil {
return tuttimodeexecutionconformance.ScheduleResult{}, err
}
return tuttimodeexecutionconformance.ScheduleResult{
ExecutionID: result.ExecutionID,
CheckpointID: result.CheckpointID,
GraphRevision: result.GraphRevision,
RunIDs: append([]string(nil), result.RunIDs...),
Replayed: result.Replayed,
}, nil
}
func (driver *sqliteConformanceDriver) ScheduleReplica(
ctx context.Context,
input tuttimodeexecutionconformance.ScheduleInput,
) (tuttimodeexecutionconformance.ScheduleResult, error) {
replica := driver.issues
replica.MutationLocks = workspaceservice.NewIssueMutationLocks()
replica.RunLaunchGate = workspaceservice.NewIssueRunLaunchGate()
result, err := replica.ScheduleTuttiModeIssue(ctx, input.WorkspaceID, workspaceservice.ScheduleTuttiModeIssueInput{
IssueID: input.IssueID,
SourceSessionID: input.SourceSessionID,
CheckpointID: input.CheckpointID,
ExpectedGraphRevision: input.ExpectedGraphRevision,
TaskIDs: append([]string(nil), input.TaskIDs...),
RequestID: input.RequestID,
})
if err != nil {
return tuttimodeexecutionconformance.ScheduleResult{}, err
}
return tuttimodeexecutionconformance.ScheduleResult{
ExecutionID: result.ExecutionID, CheckpointID: result.CheckpointID,
GraphRevision: result.GraphRevision, RunIDs: append([]string(nil), result.RunIDs...),
Replayed: result.Replayed,
}, nil
}
func (driver *sqliteConformanceDriver) SettleRun(
ctx context.Context,
input tuttimodeexecutionconformance.SettleRunInput,
) error {
completeInput := workspaceservice.CompleteIssueManagerRunInput{Status: input.Status}
if input.Status == string(workspaceissues.StatusCompleted) {
completeInput.Outputs = []workspaceissues.CompleteRunOutputInput{{
OutputID: "output-" + input.RunID, Path: "result.txt",
DisplayName: "Result", MediaType: "text/plain", SizeBytes: 6,
}}
}
_, err := driver.issues.CompleteRun(
ctx,
input.WorkspaceID,
input.IssueID,
input.TaskID,
input.RunID,
completeInput,
)
return err
}
func (driver *sqliteConformanceDriver) SettleRunReplica(
ctx context.Context,
input tuttimodeexecutionconformance.SettleRunInput,
) error {
replica := driver.issues
replica.MutationLocks = workspaceservice.NewIssueMutationLocks()
replica.RunLaunchGate = workspaceservice.NewIssueRunLaunchGate()
_, err := replica.CompleteRun(
ctx,
input.WorkspaceID,
input.IssueID,
input.TaskID,
input.RunID,
workspaceservice.CompleteIssueManagerRunInput{Status: input.Status},
)
return err
}
func (driver *sqliteConformanceDriver) TimeoutRun(
ctx context.Context,
input tuttimodeexecutionconformance.SettleRunInput,
) error {
detail, err := driver.issues.GetRunDetail(
ctx,
input.WorkspaceID,
input.IssueID,
input.TaskID,
input.RunID,
)
if err != nil {
return fmt.Errorf("get Run before timeout reconciliation: %w", err)
}
startedAtUnixMS := detail.Run.StartedAtUnixMS
if startedAtUnixMS <= 0 {
startedAtUnixMS = detail.Run.CreatedAtUnixMS
}
driver.clock.Set(time.UnixMilli(startedAtUnixMS).UTC().Add(46 * time.Minute))
coordinator := &workspaceservice.IssueExecutionCoordinator{
Issues: &driver.issues,
RunSessionCanceller: driver.canceller,
Clock: driver.clock.Now,
}
_, err = coordinator.ReconcileRunningRuns(ctx, input.WorkspaceID)
return err
}
func (driver *sqliteConformanceDriver) ClaimRunLaunchReplica(
ctx context.Context,
workspaceID string,
issueID string,
runID string,
) (bool, error) {
return driver.executions.ClaimRunLaunch(
ctx, workspaceID, issueID, runID, "replica-claim", time.Minute,
)
}
func (driver *sqliteConformanceDriver) FailNextLaunchAuthoritatively() {
driver.launcher.mu.Lock()
defer driver.launcher.mu.Unlock()
driver.launcher.failBeforeCanonical = true
}
func (driver *sqliteConformanceDriver) HoldNextLaunchThenFailAuthoritatively() (<-chan struct{}, func()) {
driver.launcher.mu.Lock()
defer driver.launcher.mu.Unlock()
driver.launcher.blockNext = true
driver.launcher.failAfterBlock = true
driver.launcher.started = make(chan struct{})
driver.launcher.release = make(chan struct{})
started := driver.launcher.started
release := driver.launcher.release
var once sync.Once
return started, func() {
once.Do(func() { close(release) })
}
}
func (driver *sqliteConformanceDriver) PersistTerminalRunWithoutCheckpoint(
ctx context.Context,
input tuttimodeexecutionconformance.SettleRunInput,
) error {
run, err := driver.store.GetRun(ctx, input.WorkspaceID, input.IssueID, input.TaskID, input.RunID)
if err != nil {
return err
}
run.Status = workspaceissues.Status(input.Status)
run.CompletedAtUnixMS = driver.clock.Now().UnixMilli()
run.UpdatedAtUnixMS = run.CompletedAtUnixMS
if _, _, err := driver.store.CompleteRun(ctx, run, nil); err != nil {
return err
}
task, err := driver.store.GetTask(ctx, input.WorkspaceID, input.IssueID, input.TaskID)
if err != nil {
return err
}
switch run.Status {
case workspaceissues.StatusCompleted:
task.Status = workspaceissues.StatusPendingAcceptance
case workspaceissues.StatusFailed:
task.Status = workspaceissues.StatusFailed
case workspaceissues.StatusCanceled:
task.Status = workspaceissues.StatusCanceled
}
task.UpdatedAtUnixMS = run.UpdatedAtUnixMS
if _, err := driver.store.UpdateTask(ctx, task); err != nil {
return err
}
_, err = driver.store.RecalculateIssueProjection(ctx, input.WorkspaceID, input.IssueID)
return err
}
func (driver *sqliteConformanceDriver) SupersedeTerminalCheckpointForRecovery(
ctx context.Context,
workspaceID string,
issueID string,
) error {
db, err := sql.Open("sqlite", "file:"+driver.dbPath)
if err != nil {
return err
}
defer func() { _ = db.Close() }()
result, err := db.ExecContext(ctx, `
UPDATE workspace_tutti_execution_checkpoints
SET status = 'superseded', updated_at_unix_ms = ?
WHERE workspace_id = ?
AND execution_id = (
SELECT execution_id FROM workspace_tutti_executions
WHERE workspace_id = ? AND issue_id = ?
)
AND kind = 'all_tasks_terminal' AND status = 'pending'
`, driver.clock.Now().UnixMilli(), workspaceID, workspaceID, issueID)
if err != nil {
return err
}
rows, err := result.RowsAffected()
if err != nil {
return err
}
if rows != 1 {
return fmt.Errorf("supersede terminal checkpoint rows = %d, want 1", rows)
}
return nil
}
func (driver *sqliteConformanceDriver) RepairSettlements(
ctx context.Context,
workspaceID string,
) error {
_, err := driver.executions.RepairRunSettlements(ctx, workspaceID)
return err
}
func (driver *sqliteConformanceDriver) Acknowledge(
ctx context.Context,
input tuttimodeexecutionconformance.AcknowledgeInput,
) (tuttimodeexecutionconformance.AcknowledgeResult, error) {
result, err := driver.executions.Acknowledge(ctx, tuttimodeexecutionservice.AcknowledgeInput{
WorkspaceID: input.WorkspaceID, IssueID: input.IssueID,
SourceSessionID: input.SourceSessionID, CheckpointID: input.CheckpointID,
ExpectedGraphRevision: input.ExpectedGraphRevision, RequestID: input.RequestID,
})
if err != nil {
return tuttimodeexecutionconformance.AcknowledgeResult{}, err
}
return tuttimodeexecutionconformance.AcknowledgeResult{
ExecutionID: result.ExecutionID, CheckpointID: result.CheckpointID,
GraphRevision: result.GraphRevision, NextCheckpointID: result.NextCheckpointID,
NextCheckpointKind: string(result.NextCheckpointKind),
NextCheckpointState: string(result.NextCheckpointState),
Replayed: result.Replayed,
}, nil
}
func (driver *sqliteConformanceDriver) AcknowledgeReplica(
ctx context.Context,
input tuttimodeexecutionconformance.AcknowledgeInput,
) (tuttimodeexecutionconformance.AcknowledgeResult, error) {
return driver.Acknowledge(ctx, input)
}
func (driver *sqliteConformanceDriver) Complete(
ctx context.Context,
input tuttimodeexecutionconformance.CompleteInput,
) (tuttimodeexecutionconformance.CompleteResult, error) {
result, err := driver.executions.Complete(ctx, tuttimodeexecutionservice.CompleteInput{
WorkspaceID: input.WorkspaceID, IssueID: input.IssueID,
SourceSessionID: input.SourceSessionID, CheckpointID: input.CheckpointID,
ExpectedGraphRevision: input.ExpectedGraphRevision,
RequestID: input.RequestID, Decision: input.Decision,
DisagreementReason: input.DisagreementReason,
})
if err != nil {
return tuttimodeexecutionconformance.CompleteResult{}, err
}
return tuttimodeexecutionconformance.CompleteResult{
ExecutionID: result.ExecutionID, CheckpointID: result.CheckpointID,
GraphRevision: result.GraphRevision, Decision: result.Decision,
Replayed: result.Replayed,
}, nil
}
func (driver *sqliteConformanceDriver) CompleteReplica(
ctx context.Context,
input tuttimodeexecutionconformance.CompleteInput,
) (tuttimodeexecutionconformance.CompleteResult, error) {
return driver.Complete(ctx, input)
}
func (driver *sqliteConformanceDriver) SubmitReviewerVerdict(
ctx context.Context,
input tuttimodeexecutionconformance.ReviewerVerdictInput,
) (tuttimodeexecutionconformance.ReviewerVerdictResult, error) {
result, err := driver.executions.SubmitReviewerVerdict(ctx, tuttimodeexecutionservice.ReviewerVerdictInput{
WorkspaceID: input.WorkspaceID, IssueID: input.IssueID,
ReviewID: input.ReviewID, ReviewSessionID: input.ReviewSessionID,
ReviewTurnID: input.ReviewTurnID, CheckpointID: input.CheckpointID,
ExpectedGraphRevision: input.ExpectedGraphRevision,
RequestID: input.RequestID, Verdict: input.Verdict, Summary: input.Summary,
})
if err != nil {
return tuttimodeexecutionconformance.ReviewerVerdictResult{}, err
}
return tuttimodeexecutionconformance.ReviewerVerdictResult{
ReviewID: result.ReviewID, Verdict: result.Verdict, Replayed: result.Replayed,
}, nil
}
func (driver *sqliteConformanceDriver) SubmitReviewerVerdictReplica(
ctx context.Context,
input tuttimodeexecutionconformance.ReviewerVerdictInput,
) (tuttimodeexecutionconformance.ReviewerVerdictResult, error) {
return driver.SubmitReviewerVerdict(ctx, input)
}
func (driver *sqliteConformanceDriver) SwitchReviewToSelf(
ctx context.Context,
input tuttimodeexecutionconformance.SwitchReviewToSelfInput,
) (tuttimodeexecutionconformance.SwitchReviewToSelfResult, error) {
result, err := driver.executions.SwitchReviewToSelf(ctx, tuttimodeexecutionservice.SwitchReviewToSelfInput{
WorkspaceID: input.WorkspaceID, IssueID: input.IssueID,
CheckpointID: input.CheckpointID,
ExpectedGraphRevision: input.ExpectedGraphRevision,
RequestID: input.RequestID, Reason: input.Reason,
RequestedByActorID: input.RequestedBy,
})
if err != nil {
return tuttimodeexecutionconformance.SwitchReviewToSelfResult{}, err
}
return tuttimodeexecutionconformance.SwitchReviewToSelfResult{
ExecutionID: result.ExecutionID, ReviewID: result.ReviewID,
Replayed: result.Replayed,
}, nil
}
func (driver *sqliteConformanceDriver) SwitchReviewToSelfReplica(
ctx context.Context,
input tuttimodeexecutionconformance.SwitchReviewToSelfInput,
) (tuttimodeexecutionconformance.SwitchReviewToSelfResult, error) {
return driver.SwitchReviewToSelf(ctx, input)
}
func (driver *sqliteConformanceDriver) ClaimReviewer(
ctx context.Context,
workspaceID string,
reviewID string,
leaseOwner string,
duration time.Duration,
) (bool, error) {
return driver.executions.ClaimReviewer(
ctx, workspaceID, reviewID, leaseOwner, duration,
)
}
func (driver *sqliteConformanceDriver) RecoverReviewers(ctx context.Context, workspaceID string, owner string) error {
return driver.executions.RecoverReviewers(ctx, workspaceID, owner)
}
func (driver *sqliteConformanceDriver) StartupRecoverReviewers(ctx context.Context, workspaceID string, owner string) error {
replica := &tuttimodeexecutionservice.Service{
Store: driver.store, ReviewerTargets: driver.reviewer,
ReviewerActivity: driver.store, Clock: driver.clock.Now,
BeforeGoalReviewCommitStep: driver.beforeGoalReviewCommitStep,
}
return replica.RecoverReviewers(ctx, workspaceID, owner)
}
func (driver *sqliteConformanceDriver) SettleReviewerTurnWithoutVerdict(
ctx context.Context,
workspaceID string,
sessionID string,
turnID string,
finalText string,
) error {
return driver.executions.SettleReviewerTurnWithoutVerdict(
ctx, workspaceID, sessionID, turnID, finalText,
)
}
func (driver *sqliteConformanceDriver) SetReviewerSessionBusy(sessionID string, busy bool) {
driver.reviewer.mu.Lock()
defer driver.reviewer.mu.Unlock()
driver.reviewer.busyBySession[sessionID] = busy
}
func (driver *sqliteConformanceDriver) FailNextGoalReviewCommit(step string) {
driver.reviewMu.Lock()
defer driver.reviewMu.Unlock()
driver.failReviewStep = step
}
func (driver *sqliteConformanceDriver) beforeGoalReviewCommitStep(step string) error {
driver.reviewMu.Lock()
defer driver.reviewMu.Unlock()
if driver.failReviewStep != step {
return nil
}
driver.failReviewStep = ""
return fmt.Errorf("injected Goal Review %s transaction failure", step)
}
func (driver *sqliteConformanceDriver) FailNextReviewerBeforeCanonical() {
driver.reviewer.mu.Lock()
defer driver.reviewer.mu.Unlock()
driver.reviewer.failBeforeCanonical = true
}
func (driver *sqliteConformanceDriver) FailNextReviewerAfterCanonical() {
driver.reviewer.mu.Lock()
defer driver.reviewer.mu.Unlock()
driver.reviewer.failAfterCanonical = true
}
func (driver *sqliteConformanceDriver) SubmitReviewerVerdictOnNextSend(
input tuttimodeexecutionconformance.ReviewerVerdictInput,
) {
driver.reviewer.mu.Lock()
defer driver.reviewer.mu.Unlock()
driver.reviewer.onNextSend = func(
_ tuttimodeexecutionservice.ReviewerLaunch,
delivery tuttimodeexecutionservice.ReviewerDelivery,
) error {
_, err := driver.executions.SubmitReviewerVerdict(
context.Background(),
tuttimodeexecutionservice.ReviewerVerdictInput{
WorkspaceID: input.WorkspaceID, IssueID: input.IssueID,
ReviewID: input.ReviewID,
ReviewSessionID: delivery.CanonicalSessionID,
ReviewTurnID: delivery.CanonicalTurnID,
CheckpointID: input.CheckpointID,
ExpectedGraphRevision: input.ExpectedGraphRevision,
RequestID: input.RequestID, Verdict: input.Verdict,
Summary: input.Summary,
},
)
return err
}
}
func (driver *sqliteConformanceDriver) SettleReviewerOnNextSend() {
driver.reviewer.mu.Lock()
defer driver.reviewer.mu.Unlock()
driver.reviewer.settleNext = true
}
func (driver *sqliteConformanceDriver) ReviewerLaunchCallCount() int {
driver.reviewer.mu.Lock()
defer driver.reviewer.mu.Unlock()
return driver.reviewer.calls
}
func (driver *sqliteConformanceDriver) ReviewerCanonicalTurnCount() int {
driver.reviewer.mu.Lock()
defer driver.reviewer.mu.Unlock()
return len(driver.reviewer.canonicalByClientSubmit)
}
func (driver *sqliteConformanceDriver) ReviewerCanonicalIdentity(clientSubmitID string) (string, string, bool) {
driver.reviewer.mu.Lock()
defer driver.reviewer.mu.Unlock()
delivery, found := driver.reviewer.canonicalByClientSubmit[clientSubmitID]
return delivery.CanonicalSessionID, delivery.CanonicalTurnID, found
}
func (driver *sqliteConformanceDriver) ReviewerCapabilities() []string {
driver.reviewer.mu.Lock()
defer driver.reviewer.mu.Unlock()
return append([]string(nil), driver.reviewer.capabilities...)
}
func (driver *sqliteConformanceDriver) Archive(
ctx context.Context,
input tuttimodeexecutionconformance.ArchiveInput,
) (tuttimodeexecutionconformance.ArchiveOperation, error) {
operation, err := driver.executions.Archive(ctx, tuttimodeexecutionservice.ArchiveInput{
WorkspaceID: input.WorkspaceID, IssueID: input.IssueID,
RequestID: input.RequestID, RequestedBy: input.RequestedBy, Reason: input.Reason,
SourceSessionID: input.SourceSessionID, CheckpointID: input.CheckpointID,
ExpectedGraphRevision: input.ExpectedGraphRevision,
})
return conformanceArchiveOperation(operation), err
}
func (driver *sqliteConformanceDriver) GetArchive(
ctx context.Context, workspaceID, operationID string,
) (tuttimodeexecutionconformance.ArchiveOperation, error) {
operation, err := driver.executions.GetArchive(ctx, workspaceID, operationID)
return conformanceArchiveOperation(operation), err
}
func (driver *sqliteConformanceDriver) RestartRecoverArchives(
ctx context.Context, workspaceID string,
) error {
replica := &tuttimodeexecutionservice.Service{
Store: driver.store, Wakes: driver.wakeStore, Archives: driver.store,
ArchiveAutomationTurns: driver.automationTurns,
ArchiveRuns: &workspaceservice.IssueExecutionCoordinator{
Issues: &driver.issues, RunSessionCanceller: driver.canceller,
},
Clock: driver.clock.Now,
}
return replica.RecoverArchives(ctx, workspaceID)
}
func (driver *sqliteConformanceDriver) AutomationTurnCancellations() []tuttimodeexecutionconformance.AutomationTurnCancellation {
driver.automationTurns.mu.Lock()
defer driver.automationTurns.mu.Unlock()
return append(
[]tuttimodeexecutionconformance.AutomationTurnCancellation(nil),
driver.automationTurns.cancellations...,
)
}
func (driver *sqliteConformanceDriver) StopSourceSession(
ctx context.Context,
workspaceID string,
sourceSessionID string,
) (int, error) {
return driver.executions.StopSourceSession(
ctx,
tuttimodeexecutionservice.StopSourceSessionInput{
WorkspaceID: workspaceID, SourceSessionID: sourceSessionID,
},
)
}
func (driver *sqliteConformanceDriver) StopSourceSessionDuringNextReviewerSend(
workspaceID string,
sourceSessionID string,
) {
driver.reviewer.mu.Lock()
defer driver.reviewer.mu.Unlock()
driver.reviewer.onNextSend = func(
tuttimodeexecutionservice.ReviewerLaunch,
tuttimodeexecutionservice.ReviewerDelivery,
) error {
_, err := driver.StopSourceSession(
context.Background(), workspaceID, sourceSessionID,
)
return err
}
}
func (driver *sqliteConformanceDriver) AdmitSourceDeletion(
ctx context.Context, workspaceID string, sessionIDs []string,
) error {
normalized := append([]string(nil), sessionIDs...)
slices.Sort(normalized)
admission, err := driver.store.AdmitSourceSessionDeletion(ctx, executionbiz.SourceSessionDeletionAdmission{
WorkspaceID: workspaceID, SessionIDs: normalized, Now: driver.clock.Now(),
})
if err == nil {
driver.deletionAdmissions[workspaceID+"|"+strings.Join(normalized, "\x00")] = admission
}
return err
}
func (driver *sqliteConformanceDriver) ReleaseSourceDeletion(
ctx context.Context, workspaceID string, sessionIDs []string, succeeded bool,
) error {
normalized := append([]string(nil), sessionIDs...)
slices.Sort(normalized)
key := workspaceID + "|" + strings.Join(normalized, "\x00")
admission := driver.deletionAdmissions[key]
if admission.AdmissionID == "" {
return fmt.Errorf("source deletion admission not found")
}
return driver.store.ReportSourceSessionDeletion(ctx, admission, succeeded, driver.clock.Now())
}
func conformanceArchiveOperation(
operation executionbiz.ArchiveOperation,
) tuttimodeexecutionconformance.ArchiveOperation {
return tuttimodeexecutionconformance.ArchiveOperation{
OperationID: operation.OperationID, Status: string(operation.Status),
RequestedBy: operation.RequestedBy, Reason: operation.Reason,
LastError: operation.LastError, CompletedAt: operation.CompletedAt,
}
}
func (driver *sqliteConformanceDriver) SeedActiveRun(
ctx context.Context,
workspaceID string,
issueID string,
taskID string,
) error {
task, err := driver.store.GetTask(ctx, workspaceID, issueID, taskID)
if err != nil {
return err
}
now := driver.clock.Now().UnixMilli()
run, err := driver.store.CreateRun(ctx, workspaceissues.Run{
RunID: "seed-run-" + taskID, TaskID: taskID, IssueID: issueID,
WorkspaceID: workspaceID, RequesterUserID: "conformance",
AgentUserID: "conformance", AgentTargetID: task.AgentTargetID,
AgentSessionID: "seed-session-" + taskID, Status: workspaceissues.StatusRunning,
CreatedAtUnixMS: now, StartedAtUnixMS: now, UpdatedAtUnixMS: now,
})
if err != nil {
return err
}
task.Status = workspaceissues.StatusRunning
task.LatestRunID = run.RunID
task.UpdatedAtUnixMS = now
if _, err := driver.store.UpdateTask(ctx, task); err != nil {
return err
}
_, err = driver.store.RecalculateIssueProjection(ctx, workspaceID, issueID)
return err
}
func (driver *sqliteConformanceDriver) GetExecutionByIssue(
ctx context.Context,
workspaceID string,
issueID string,
) (tuttimodeexecutionconformance.Execution, []tuttimodeexecutionconformance.Checkpoint, error) {
aggregate, err := driver.executions.GetByIssue(ctx, workspaceID, issueID)
if err != nil {
return tuttimodeexecutionconformance.Execution{}, nil, err
}
execution := tuttimodeexecutionconformance.Execution{
WorkspaceID: aggregate.Execution.WorkspaceID,
IssueID: aggregate.Execution.IssueID,
WorkflowID: aggregate.Execution.WorkflowID,
SourceSessionID: aggregate.Execution.SourceSessionID,
Status: string(aggregate.Execution.Status),
GraphRevision: aggregate.Execution.GraphRevision,
LastOrchestratorActivityAt: aggregate.Execution.LastOrchestratorActivityAt,
WatchdogDueAt: aggregate.Execution.WatchdogDueAt,
ReviewMode: string(aggregate.Execution.ReviewMode),
ReviewAgentTargetID: aggregate.Execution.ReviewAgentTargetID,
CompletedAt: aggregate.Execution.CompletedAt,
ArchivedAt: aggregate.Execution.ArchivedAt,
ArchivedBy: aggregate.Execution.ArchivedBy,
ArchiveReason: aggregate.Execution.ArchiveReason,
}
checkpoints := make([]tuttimodeexecutionconformance.Checkpoint, 0, len(aggregate.Checkpoints))
for _, checkpoint := range aggregate.Checkpoints {
checkpoints = append(checkpoints, tuttimodeexecutionconformance.Checkpoint{
CheckpointID: checkpoint.ID,
Kind: string(checkpoint.Kind),
Status: string(checkpoint.Status),
Sequence: checkpoint.Sequence,
GraphRevision: checkpoint.GraphRevision,
SubjectTaskID: checkpoint.SubjectTaskID,
SubjectRunID: checkpoint.SubjectRunID,
})
}
return execution, checkpoints, nil
}
func (driver *sqliteConformanceDriver) CountRuns(ctx context.Context, workspaceID, issueID string) (int, error) {
runs, err := driver.issues.ListRuns(ctx, workspaceID, issueID, "")
return len(runs), err
}
func (driver *sqliteConformanceDriver) LauncherCallCount() int {
driver.launcher.mu.Lock()
defer driver.launcher.mu.Unlock()
return driver.launcher.calls
}
func (driver *sqliteConformanceDriver) FailNextLaunch() {
driver.launcher.mu.Lock()
defer driver.launcher.mu.Unlock()
driver.launcher.failNext = true
}
func (driver *sqliteConformanceDriver) HoldNextLaunch() (<-chan struct{}, func()) {
driver.launcher.mu.Lock()
defer driver.launcher.mu.Unlock()
driver.launcher.blockNext = true
driver.launcher.started = make(chan struct{})
driver.launcher.release = make(chan struct{})
started := driver.launcher.started
release := driver.launcher.release
var once sync.Once
return started, func() {
once.Do(func() { close(release) })
}
}
func (driver *sqliteConformanceDriver) AdvanceClock(duration time.Duration) error {
driver.clock.Advance(duration)
return driver.renewals.Tick()
}
func (driver *sqliteConformanceDriver) StopLeaseRenewal() {
driver.renewals.StopCurrent()
}
func (driver *sqliteConformanceDriver) AdvanceClockWithoutRenewal(duration time.Duration) {
driver.clock.Advance(duration)
}
func (driver *sqliteConformanceDriver) RecoverLaunches(ctx context.Context, workspaceID string) error {
return driver.issues.RecoverTuttiModeRunLaunchIntents(ctx, workspaceID)
}
func (driver *sqliteConformanceDriver) EnableAutomaticRecovery(ctx context.Context) {
queueCtx, cancel := context.WithCancel(ctx)
driver.cancelAuto = cancel
coordinator := &workspaceservice.IssueExecutionCoordinator{
Issues: &driver.issues, RunSessionCanceller: driver.canceller,
}
driver.issues.ExecutionRecoveryQueue = workspaceservice.NewWorkspaceExecutionRecoveryQueue(
workspaceservice.WorkspaceExecutionRecoveryQueueOptions{
Context: queueCtx,
Delay: time.Millisecond,
Interval: time.Millisecond,
Reconcile: func(
ctx context.Context, workspaceID string,
) (workspaceservice.WorkspaceExecutionRecoveryResult, error) {
runResult, err := coordinator.ReconcileIssueExecutions(ctx, workspaceID)
if err != nil {
return workspaceservice.WorkspaceExecutionRecoveryResult{}, err
}
pendingArchives, err := driver.executions.RecoverArchivesAndCount(ctx, workspaceID)
return workspaceservice.WorkspaceExecutionRecoveryResult{
Pending: runResult.RunningCount > runResult.CompletedCount ||
pendingArchives > 0,
}, err
},
},
)
driver.executions.ArchiveRecoveryQueue = driver.issues.ExecutionRecoveryQueue
}
func (driver *sqliteConformanceDriver) AwaitLauncherCalls(ctx context.Context, want int) error {
for {
driver.launcher.mu.Lock()
calls := driver.launcher.calls
if calls >= want {
driver.launcher.mu.Unlock()
if driver.cancelAuto != nil {
driver.cancelAuto()
driver.cancelAuto = nil
}
return nil
}
if driver.launcher.callSignal == nil {
driver.launcher.callSignal = make(chan struct{})
}
signal := driver.launcher.callSignal
driver.launcher.mu.Unlock()
select {
case <-ctx.Done():
if driver.cancelAuto != nil {
driver.cancelAuto()
driver.cancelAuto = nil
}
return fmt.Errorf("launcher calls = %d, want at least %d: %w", calls, want, ctx.Err())
case <-signal:
}
}
}
func (driver *sqliteConformanceDriver) StartupRecoverReplica(ctx context.Context, workspaceID string) error {
replica := driver.issues
replica.MutationLocks = workspaceservice.NewIssueMutationLocks()
replica.RunLaunchGate = workspaceservice.NewIssueRunLaunchGate()
return replica.RecoverTuttiModeRunLaunches(ctx, workspaceID)
}
func (driver *sqliteConformanceDriver) StartupReconcileReplica(ctx context.Context, workspaceID string) error {
replica := driver.issues
replica.MutationLocks = workspaceservice.NewIssueMutationLocks()
replica.RunLaunchGate = workspaceservice.NewIssueRunLaunchGate()
coordinator := workspaceservice.IssueExecutionCoordinator{
Issues: &replica,
RunSessionCanceller: driver.canceller,
Clock: driver.clock.Now,
}
_, err := coordinator.ReconcileIssueExecutions(
ctx, workspaceID,
)
return err
}
func (driver *sqliteConformanceDriver) PeriodicRecoverReplica(ctx context.Context, workspaceID string) error {
replica := driver.issues
replica.MutationLocks = workspaceservice.NewIssueMutationLocks()
replica.RunLaunchGate = workspaceservice.NewIssueRunLaunchGate()
coordinator := workspaceservice.IssueExecutionCoordinator{Issues: &replica}
_, err := coordinator.ReconcileIssueExecutions(ctx, workspaceID)
return err
}
func (driver *sqliteConformanceDriver) LauncherClientSubmitIDs() []string {
driver.launcher.mu.Lock()
defer driver.launcher.mu.Unlock()
return append([]string(nil), driver.launcher.clientSubmitIDs...)
}
func (driver *sqliteConformanceDriver) LauncherCanonicalTurnCount() int {
driver.launcher.mu.Lock()
defer driver.launcher.mu.Unlock()
return len(driver.launcher.canonicalByClientSubmit)
}
func TestMaterializationSQLiteServiceConformance(t *testing.T) {
for _, scenario := range tuttimodeexecutionconformance.MaterializationCatalog() {
scenario := scenario
t.Run(scenario.Name, func(t *testing.T) {
if err := tuttimodeexecutionconformance.Run(
context.Background(),
newSQLiteConformanceDriver(t),
scenario,
); err != nil {
t.Fatal(err)
}
})
}
}
func TestScheduleSQLiteServiceConformance(t *testing.T) {
for _, scenario := range tuttimodeexecutionconformance.ScheduleCatalog() {
scenario := scenario
t.Run(scenario.Name, func(t *testing.T) {
if err := tuttimodeexecutionconformance.Run(
context.Background(),
newSQLiteConformanceDriver(t),
scenario,
); err != nil {
t.Fatal(err)
}
})
}
}
func TestMutationSQLiteServiceConformance(t *testing.T) {
for _, scenario := range tuttimodeexecutionconformance.MutationCatalog() {
scenario := scenario
t.Run(scenario.Name, func(t *testing.T) {
if err := tuttimodeexecutionconformance.Run(
context.Background(),
newSQLiteConformanceDriver(t),
scenario,
); err != nil {
t.Fatal(err)
}
})
}
}
func TestSettlementSQLiteServiceConformance(t *testing.T) {
for _, scenario := range tuttimodeexecutionconformance.SettlementCatalog() {
scenario := scenario
t.Run(scenario.Name, func(t *testing.T) {
if err := tuttimodeexecutionconformance.Run(
context.Background(),
newSQLiteConformanceDriver(t),
scenario,
); err != nil {
t.Fatal(err)
}
})
}
}
func TestWakeSQLiteServiceConformance(t *testing.T) {
for _, scenario := range tuttimodeexecutionconformance.WakeCatalog() {
scenario := scenario
t.Run(scenario.Name, func(t *testing.T) {
if err := tuttimodeexecutionconformance.Run(
context.Background(),
newSQLiteConformanceDriver(t),
scenario,
); err != nil {
t.Fatal(err)
}
})
}
}
func TestWatchdogSQLiteServiceConformance(t *testing.T) {
for _, scenario := range tuttimodeexecutionconformance.WatchdogCatalog() {
scenario := scenario
t.Run(scenario.Name, func(t *testing.T) {
if err := tuttimodeexecutionconformance.Run(
context.Background(),
newSQLiteConformanceDriver(t),
scenario,
); err != nil {
t.Fatal(err)
}
})
}
}
func TestGoalReviewSQLiteServiceConformance(t *testing.T) {
for _, scenario := range tuttimodeexecutionconformance.ReviewCatalog() {
scenario := scenario
t.Run(scenario.Name, func(t *testing.T) {
if err := tuttimodeexecutionconformance.Run(
context.Background(),
newSQLiteConformanceDriver(t),
scenario,
); err != nil {
t.Fatal(err)
}
})
}
}
func TestArchiveSQLiteServiceConformance(t *testing.T) {
for _, scenario := range tuttimodeexecutionconformance.ArchiveCatalog() {
scenario := scenario
t.Run(scenario.Name, func(t *testing.T) {
if err := tuttimodeexecutionconformance.Run(
context.Background(),
newSQLiteConformanceDriver(t),
scenario,
); err != nil {
t.Fatal(err)
}
})
}
}
func TestDeletionSQLiteServiceConformance(t *testing.T) {
for _, scenario := range tuttimodeexecutionconformance.DeletionCatalog() {
scenario := scenario
t.Run(scenario.Name, func(t *testing.T) {
if err := tuttimodeexecutionconformance.Run(
context.Background(),
newSQLiteConformanceDriver(t),
scenario,
); err != nil {
t.Fatal(err)
}
})
}
}
func firstNonEmptyConformance(values ...string) string {
for _, value := range values {
if value != "" {
return value
}
}
return ""
}