89d8433d17
Closes the biggest gap between the running execution engine and ECOSYSTEM-SPEC.md §4.3: confirmations were entirely unmodeled, so any capability could execute unconfirmed regardless of requires_confirmation. - New confirmations table + Confirmation domain type; POST /api/v1/confirmations mints a TTL-bound (120s) confirmation binding capability id+version, target entity, and a sorted-key args hash. - Execute() now requires a valid pending confirmation when the capability demands one: rejects missing, expired, consumed, or args/version-mismatched confirmations; consumes on success. - Capabilities gain enabled (destructive risk defaults to disabled, matching "must be turned on explicitly") and timeout_seconds. - One in-flight execution per (capability_id, target_entity_id); a second concurrent attempt is rejected (surfaced as 409 over HTTP). - Wall-clock timeout per capability now wraps the provider call; on timeout the outcome is "unknown" (new ExecutionStatus), never "failed", and the run is never auto-retried. - 9 new engine tests cover each guard from the spec's Phase 6 gate. Vikunja #274.
27 lines
966 B
Go
27 lines
966 B
Go
package storage
|
|
|
|
import "github.com/kami/hexis/internal/domain"
|
|
|
|
type Interface interface {
|
|
Close() error
|
|
CreateCapability(c *domain.Capability) error
|
|
GetCapability(id string) (*domain.Capability, error)
|
|
UpdateCapability(c *domain.Capability) error
|
|
ListCapabilities(entityID string) ([]*domain.Capability, error)
|
|
DeleteCapability(id string) error
|
|
|
|
CreateExecution(e *domain.Execution) error
|
|
GetExecution(id string) (*domain.Execution, error)
|
|
UpdateExecution(e *domain.Execution) error
|
|
GetExecutionByIdempotencyKey(key string) (*domain.Execution, error)
|
|
GetInFlightExecution(capabilityID, targetEntityID string) (*domain.Execution, error)
|
|
|
|
CreateConfirmation(c *domain.Confirmation) error
|
|
GetConfirmation(id string) (*domain.Confirmation, error)
|
|
UpdateConfirmationState(id string, state domain.ConfirmationState) error
|
|
|
|
AppendEvent(evt *domain.Event) error
|
|
EventsAfter(seq int64, limit int) ([]*domain.Event, error)
|
|
LatestSequence() (int64, error)
|
|
}
|