turnjournal

package
v0.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 9, 2026 License: Apache-2.0 Imports: 19 Imported by: 0

Documentation

Overview

Package turnjournal provides durable, workspace-scoped checkpoints for an in-progress parent model/tool loop. It is deliberately separate from chat history: history records what was said, while this journal records which execution mutation is safe to perform next after a process restart.

Index

Constants

View Source
const (
	Schema         = "agent-harness.turn.execution"
	SchemaRevision = 3
)

Variables

View Source
var (
	ErrNotFound          = errors.New("turnjournal: execution not found")
	ErrAlreadyExists     = errors.New("turnjournal: execution already exists")
	ErrConflict          = errors.New("turnjournal: revision conflict")
	ErrInvalidRecord     = errors.New("turnjournal: invalid execution record")
	ErrInvalidTransition = errors.New("turnjournal: invalid execution transition")
	ErrCorruptStore      = errors.New("turnjournal: corrupt execution store")
)
View Source
var ErrCASRetryLimit = errors.New("turnjournal: distributed update retry limit exceeded")

Functions

This section is empty.

Types

type CASStore

type CASStore struct {
	// contains filtered or unexported fields
}

CASStore persists the same complete Record over a multi-writer CAS blob backend. A small CAS-maintained identity index supports owner-scoped startup recovery without assuming the backend can scan keys.

func NewCASStore

func NewCASStore(config CASStoreConfig) (*CASStore, error)

func (*CASStore) Create

func (s *CASStore) Create(ctx context.Context, record Record) (Record, error)

func (*CASStore) Get

func (s *CASStore) Get(ctx context.Context, workspaceID, taskID string) (Record, error)

func (*CASStore) ListActive

func (s *CASStore) ListActive(ctx context.Context, ownerIdentity string) ([]Record, error)

func (*CASStore) Update

func (s *CASStore) Update(ctx context.Context, record Record, expectedRevision uint64) (Record, error)

type CASStoreConfig

type CASStoreConfig struct {
	Blobs      casblob.Store
	Prefix     string
	MaxRetries int
	Now        func() time.Time
}

type ExternalChildRef

type ExternalChildRef struct {
	TaskID           string          `json:"task_id"`
	ExecutionID      string          `json:"execution_id"`
	ChildSessionID   string          `json:"child_session_id"`
	Descriptor       json.RawMessage `json:"descriptor"`
	DescriptorDigest string          `json:"descriptor_digest"`
}

ExternalChildRef binds one pending spawn invocation to the authoritative task and immutable child execution descriptor/result location.

func NewExternalChildRef

func NewExternalChildRef(taskID, executionID, childSessionID string, descriptor []byte) (ExternalChildRef, error)

NewExternalChildRef binds an admitted task to the exact opaque execution descriptor needed to resolve its durable result after the original assignment delivery has already been acknowledged. The journal never interprets the descriptor and does not carry credentials in it.

type FileStore

type FileStore struct {
	// contains filtered or unexported fields
}

FileStore persists one complete record per parent task. It is safe for concurrent use within one process; a state directory has one writing process. Distributed hosts use the same Store contract over CAS storage.

func NewFileStore

func NewFileStore(stateDir string) (*FileStore, error)

func (*FileStore) Create

func (s *FileStore) Create(ctx context.Context, record Record) (Record, error)

func (*FileStore) Get

func (s *FileStore) Get(ctx context.Context, workspaceID, taskID string) (Record, error)

func (*FileStore) ListActive

func (s *FileStore) ListActive(ctx context.Context, ownerIdentity string) ([]Record, error)

func (*FileStore) Update

func (s *FileStore) Update(ctx context.Context, record Record, expectedRevision uint64) (Record, error)

type HistoryMessageRef

type HistoryMessageRef struct {
	WorkspaceID string `json:"workspace_id"`
	SessionID   string `json:"session_id"`
	MessageID   string `json:"message_id"`
	Digest      string `json:"digest"`
}

HistoryMessageRef names an immutable message already persisted in the workspace/session transcript. Digest is the lowercase SHA-256 of its canonical encoded form as defined by the caller; the journal validates shape, while the recovery layer resolves and verifies content.

type Phase

type Phase string

Phase identifies the last durably confirmed boundary in a parent turn. Only WaitingExternalChild and ChildResolved may resume model/tool execution. Completing/Failing/Interrupting are an outbox boundary: the turn-side outcome is durable, but the authoritative task host has not yet acknowledged the corresponding terminal state. Recovery may finish that idempotent handshake without replaying the model or tools.

const (
	PhasePrepared             Phase = "prepared"
	PhaseProviderPending      Phase = "provider_pending"
	PhaseToolPending          Phase = "tool_pending"
	PhaseWaitingExternalChild Phase = "waiting_external_child"
	PhaseChildResolved        Phase = "child_resolved"
	PhaseCompleting           Phase = "completing"
	PhaseFailing              Phase = "failing"
	PhaseInterrupting         Phase = "interrupting"
	PhaseCompleted            Phase = "completed"
	PhaseFailed               Phase = "failed"
	PhaseInterrupted          Phase = "interrupted"
)

type Record

type Record struct {
	SchemaRevision uint32               `json:"schema_revision"`
	Schema         string               `json:"schema"`
	Revision       uint64               `json:"revision"`
	WorkspaceID    string               `json:"workspace_id"`
	SessionID      string               `json:"session_id"`
	TaskID         string               `json:"task_id"`
	OwnerIdentity  string               `json:"owner_identity"`
	Phase          Phase                `json:"phase"`
	Input          HistoryMessageRef    `json:"input"`
	Iteration      uint32               `json:"iteration"`
	LastMessageID  string               `json:"last_message_id,omitempty"`
	ToolBatch      *ToolBatchCheckpoint `json:"tool_batch,omitempty"`
	FailureReason  string               `json:"failure_reason,omitempty"`
	CreatedAt      time.Time            `json:"created_at"`
	UpdatedAt      time.Time            `json:"updated_at"`
	CompletedAt    *time.Time           `json:"completed_at,omitempty"`
}

Record is the complete, versioned checkpoint for one parent task. Revision is store-owned and monotonically increments on every successful transition. OwnerIdentity is the stable runtime identity permitted to reconcile it.

func (Record) AcknowledgedPhase

func (r Record) AcknowledgedPhase() (Phase, bool)

AcknowledgedPhase returns the immutable local terminal phase that follows a successful authoritative task transition.

func (Record) PendingTerminal

func (r Record) PendingTerminal() bool

PendingTerminal reports whether the local outcome is durable but still awaits acknowledgment from the authoritative task host.

func (Record) Terminal

func (r Record) Terminal() bool

func (Record) Validate

func (r Record) Validate() error

type Store

type Store interface {
	Create(ctx context.Context, record Record) (Record, error)
	Get(ctx context.Context, workspaceID, taskID string) (Record, error)
	Update(ctx context.Context, record Record, expectedRevision uint64) (Record, error)
	ListActive(ctx context.Context, ownerIdentity string) ([]Record, error)
}

Store is the backend-neutral optimistic journal contract. expectedRevision must be the Revision returned by Get/Create; exactly one concurrent writer can advance it. ListActive is the startup-recovery scan for a stable owner.

type ToolBatchCheckpoint

type ToolBatchCheckpoint struct {
	Assistant HistoryMessageRef `json:"assistant"`
	Calls     []ToolCheckpoint  `json:"calls"`
}

ToolBatchCheckpoint durably records every call from one persisted assistant message in source order. Even sequential batches use this shape, so recovery never has to infer whether an omitted sibling call existed.

type ToolCheckpoint

type ToolCheckpoint struct {
	InvocationID string             `json:"invocation_id"`
	Name         string             `json:"name"`
	ArgsDigest   string             `json:"args_digest"`
	Outcome      ToolOutcome        `json:"outcome"`
	External     *ExternalChildRef  `json:"external,omitempty"`
	Result       *HistoryMessageRef `json:"result,omitempty"`
}

ToolCheckpoint is one source-ordered call in a durable assistant tool batch. Result is set only after the corresponding tool-result message is durable.

type ToolOutcome

type ToolOutcome string

ToolOutcome distinguishes a requested mutation from an externally admitted child and a confirmed result. Requested/uncertain mutations are never replayed automatically.

const (
	ToolOutcomeRequested ToolOutcome = "requested"
	ToolOutcomeAdmitted  ToolOutcome = "admitted"
	ToolOutcomeConfirmed ToolOutcome = "confirmed"
	ToolOutcomeUncertain ToolOutcome = "uncertain"
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL