package ports import ( "context" "time" "github.com/dtoro/oikos/internal/core/domain" ) // SignalUpsertInput is the observe-pass signal write: open/resolve // transitions with their triggers, committed atomically. type SignalUpsertInput struct { Signal domain.Signal Triggers []SignalTrigger Audit []AuditEntry Event *Event } // SignalTrigger is an automatic follow-up fired on a signal transition // (payload firm; shapes firm up with the Phase 5 observation slice). type SignalTrigger struct { Kind string EntityID domain.UUID Parameters map[string]any } // SignalTransitionInput acks/resolves/mutes a signal (check-then-act on the // signal's current state inside the transaction). type SignalTransitionInput struct { SignalID domain.UUID Action string // "ack", "resolve", "mute" Note string MuteFor time.Duration Actor string Audit []AuditEntry Event *Event } // SignalRepository is the signal aggregate. type SignalRepository interface { Open(ctx context.Context) ([]domain.Signal, error) History(ctx context.Context, entityID domain.UUID, limit int) ([]domain.Signal, error) UpsertWithTriggers(ctx context.Context, input SignalUpsertInput) error Transition(ctx context.Context, input SignalTransitionInput) (domain.Signal, error) } // ExecutionSubmitInput is the queued-execution write: execution row, // approval (for gated risk classes), audit, and event — one transaction. type ExecutionSubmitInput struct { Execution domain.Execution Approval *domain.Approval Audit []AuditEntry Event *Event } // ExecutionCompleteInput closes out an execution: final status, output // summary, audit, event. type ExecutionCompleteInput struct { ExecutionID domain.UUID Status string Output string ExitCode int Audit []AuditEntry Event *Event } // ExecutionRepository is the execution aggregate. Claim uses an advisory // lock so exactly one worker claims a queued execution. type ExecutionRepository interface { List(ctx context.Context, cursor string, limit int) ([]domain.Execution, error) ReadLog(ctx context.Context, executionID domain.UUID) ([]string, error) SubmitQueued(ctx context.Context, input ExecutionSubmitInput) (domain.Execution, error) Claim(ctx context.Context) (*domain.Execution, error) AppendLog(ctx context.Context, executionID domain.UUID, chunk string) error Complete(ctx context.Context, input ExecutionCompleteInput) error } // ApprovalDecideInput verifies the HMAC token (check-then-act), flips the // approval, un-gates the execution, and appends audit — one transaction. // Double-approve must not double-execute. type ApprovalDecideInput struct { ApprovalID domain.UUID Token string Approved bool Actor string Audit []AuditEntry Event *Event } // ApprovalRepository is the approval aggregate. type ApprovalRepository interface { ListPending(ctx context.Context, entityID domain.UUID, limit int) ([]domain.Approval, error) Decide(ctx context.Context, input ApprovalDecideInput) (domain.Approval, error) }