hustleruntime

package
v0.33.0 Latest Latest
Warning

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

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

Documentation

Index

Constants

MaxObservationsPerRun caps how many ObservationRequirement values a single ObservationCollector retains across one Hustle run's whole evidence catalog, independent of gate.MaxObservationRequirementsPerAssessment (which bounds the same slice again at the outcome-validation boundary in pkg/gate). Both bounds exist for the same reason at two different layers — defense in depth, never trust a single call site.

Variables

This section is empty.

Functions

func WithObservationCollector

func WithObservationCollector(ctx context.Context, collector *ObservationCollector) context.Context

WithObservationCollector attaches collector to ctx so evidence execution deep inside RunAndFinalize (evidenceRunner.run, several call frames below where this context originates) can record onto it without RunAndFinalize's own signature changing — the same context-capability convention withPreparedEvidenceCall/loop.WithPreparedCall already uses for per-call prepared-artifact access. A nil collector leaves ctx unchanged.

Types

type ActivityError

type ActivityError struct {
	RunID     hustle.RunID
	Operation ActivityOperation
	Cause     error
}

ActivityError reports blocking-activity acquisition or release failure.

func (*ActivityError) Error

func (e *ActivityError) Error() string

func (*ActivityError) Unwrap

func (e *ActivityError) Unwrap() error

type ActivityLease

type ActivityLease interface {
	Release(context.Context) error
}

ActivityLease retains blocking activity through finalization.

type ActivityOperation

type ActivityOperation string

ActivityOperation identifies the activity edge which failed.

const (
	ActivityAcquire ActivityOperation = "acquire"
	ActivityRelease ActivityOperation = "release"
)

type ActivityTracker

type ActivityTracker interface {
	AcquireHustleActivity(context.Context, hustle.RunID) (ActivityLease, error)
}

ActivityTracker acquires blocking session activity for one owned run.

type AdmissionError

type AdmissionError struct {
	Reason        AdmissionErrorReason
	Participation hustle.Participation
	Cause         error
}

AdmissionError has no RunID because admission failures are pre-ownership.

func (*AdmissionError) Error

func (e *AdmissionError) Error() string

func (*AdmissionError) Unwrap

func (e *AdmissionError) Unwrap() error

type AdmissionErrorReason

type AdmissionErrorReason string

AdmissionErrorReason identifies a rejection before lane ownership commits.

const (
	AdmissionInvalidContext       AdmissionErrorReason = "invalid_context"
	AdmissionInvalidParticipation AdmissionErrorReason = "invalid_participation"
	AdmissionNilFinalizer         AdmissionErrorReason = "nil_finalizer"
	AdmissionRunID                AdmissionErrorReason = "run_id"
	AdmissionFull                 AdmissionErrorReason = "full"
	AdmissionClosed               AdmissionErrorReason = "closed"
	AdmissionPoisoned             AdmissionErrorReason = "poisoned"
)

type AuditError

type AuditError struct {
	Operation  AuditOperation
	Stage      hustle.Stage
	ReasonCode hustle.ReasonCode
	Cause      error
}

AuditError reports one bounded internal lifecycle publication failure.

func (*AuditError) Error

func (e *AuditError) Error() string

func (*AuditError) Unwrap

func (e *AuditError) Unwrap() error

type AuditOperation

type AuditOperation string

AuditOperation identifies the checked lifecycle publication step which failed.

const (
	AuditStamp   AuditOperation = "stamp"
	AuditPublish AuditOperation = "publish"
)

type AuditPublisher

type AuditPublisher interface {
	PublishInternalEventChecked(context.Context, event.Event) error
}

AuditPublisher owns the checked private durable lifecycle path.

type CallbackPanicError

type CallbackPanicError struct {
	Stage hustle.Stage
}

CallbackPanicError is the redacted recovery product for a consumer callback. It deliberately retains no panic value.

func (*CallbackPanicError) Error

func (e *CallbackPanicError) Error() string

type CloseError

type CloseError struct {
	Failures []*FinalizerError
}

CloseError reports finalizer failures encountered while resolving queued nodes.

func (*CloseError) Error

func (e *CloseError) Error() string

func (*CloseError) Unwrap

func (e *CloseError) Unwrap() []error

type Config

type Config struct {
	Blocking   LaneLimits
	Background LaneLimits
	NewRunID   RunIDFactory
	Runtime    *RuntimeConfig
}

Config owns only the two scheduler lanes and the identifier seam needed at the ownership boundary. Task-specific execution and audit collaborators are layered onto Controller separately.

type ConfigError

type ConfigError struct {
	Reason ConfigErrorReason
	Field  string
}

ConfigError reports invalid scheduler limits without retaining collaborators.

func (*ConfigError) Error

func (e *ConfigError) Error() string

type ConfigErrorReason

type ConfigErrorReason string

ConfigErrorReason identifies an invalid controller construction boundary.

const (
	ConfigInvalidContext      ConfigErrorReason = "invalid_context"
	ConfigInvalidConcurrent   ConfigErrorReason = "invalid_concurrent"
	ConfigInvalidQueued       ConfigErrorReason = "invalid_queued"
	ConfigCapacityOverflow    ConfigErrorReason = "capacity_overflow"
	ConfigInvalidSessionID    ConfigErrorReason = "invalid_session_id"
	ConfigInvalidDefinitions  ConfigErrorReason = "invalid_definitions"
	ConfigInvalidTimeout      ConfigErrorReason = "invalid_timeout"
	ConfigMissingCollaborator ConfigErrorReason = "missing_collaborator"
)

type ConfigEvidenceKindError

type ConfigEvidenceKindError struct {
	Name hustle.Name
	Kind string
}

ConfigEvidenceKindError reports that a registered hustle definition's evidence tools may declare a Requirement.Kind the consumer's runtime.evidence.AllowedKinds allowlist does not cover. It is raised at controller CONSTRUCTION (newRuntimeController), not on the definition's first real evidence-tool call, so a missing kind names itself immediately rather than surfacing later as an opaque EvidenceFailureForbiddenCapability deep inside a live classifier review.

func (*ConfigEvidenceKindError) Error

func (e *ConfigEvidenceKindError) Error() string

type Controller

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

Controller owns the two independent participation lanes. Task 19 layers the inference and audit state machine over the ownership seam in this file.

func New

func New(sessionCtx context.Context, config Config) (*Controller, error)

New validates and constructs the two bounded lanes without starting workers.

func (*Controller) Close

func (c *Controller) Close(ctx context.Context) error

Close atomically closes both admissions, cancels execution, and resolves every queued-owned node. Drained joins executing finalizers and cleanup.

func (*Controller) Drained

func (c *Controller) Drained() <-chan struct{}

Drained closes after admission is closed or poisoned and every owned run has completed terminal audit, finalization, and activity cleanup.

func (*Controller) RunAndFinalize

func (c *Controller) RunAndFinalize(ctx context.Context, request hustle.Request, validate ValidateResult, finalizer Finalizer) error

RunAndFinalize executes one registered definition and retains ownership until the consumer's required finalizer returns.

type EvidenceError

type EvidenceError struct {
	Reason EvidenceFailureReason
}

EvidenceError deliberately retains no tool arguments, results, dependency errors, or panic values.

func (*EvidenceError) Error

func (e *EvidenceError) Error() string

func (*EvidenceError) Valid

func (e *EvidenceError) Valid() bool

type EvidenceExecutionIDFactory

type EvidenceExecutionIDFactory func() (uuid.UUID, error)

EvidenceExecutionIDFactory mints one candidate identifier for an evidence tool call before authorization. It is a purely internal, Harness-owned seam (uuid.New in production) — never consumer-supplied — so unlike EvidenceAccessEvaluator/EvidenceContainmentVerifier it is not re-exported from pkg/gate.

type EvidenceFailureReason

type EvidenceFailureReason string

EvidenceFailureReason is a closed, security-safe classification for evidence binding, preparation, authorization, and execution failures.

const (
	EvidenceFailureInvalidBinding        EvidenceFailureReason = "invalid_binding"
	EvidenceFailureUnknownTool           EvidenceFailureReason = "unknown_tool"
	EvidenceFailureUnprepared            EvidenceFailureReason = "unprepared"
	EvidenceFailurePreparation           EvidenceFailureReason = "preparation"
	EvidenceFailureInvalidRequest        EvidenceFailureReason = "invalid_request"
	EvidenceFailureAmbiguousIdentity     EvidenceFailureReason = "ambiguous_identity"
	EvidenceFailureForbiddenCapability   EvidenceFailureReason = "forbidden_capability"
	EvidenceFailureContainmentRefused    EvidenceFailureReason = "containment_refused"
	EvidenceFailureAccessRefused         EvidenceFailureReason = "access_refused"
	EvidenceFailureExecution             EvidenceFailureReason = "execution"
	EvidenceFailureInvalidResult         EvidenceFailureReason = "invalid_result"
	EvidenceFailureResultTooLarge        EvidenceFailureReason = "result_too_large"
	EvidenceFailureEvidenceTooLarge      EvidenceFailureReason = "evidence_too_large"
	EvidenceFailureRoundsExceeded        EvidenceFailureReason = "rounds_exceeded"
	EvidenceFailureCallsExceeded         EvidenceFailureReason = "calls_exceeded"
	EvidenceFailureCallsPerRoundExceeded EvidenceFailureReason = "calls_per_round_exceeded"
	EvidenceFailureCanceled              EvidenceFailureReason = "canceled"
	EvidenceFailureDeadline              EvidenceFailureReason = "deadline"
	EvidenceFailureInternal              EvidenceFailureReason = "internal"
)

func (EvidenceFailureReason) Valid

func (r EvidenceFailureReason) Valid() bool

Valid reports whether the reason is a recognized evidence failure.

type EvidenceRuntimeConfig

type EvidenceRuntimeConfig struct {
	Access         gate.EvidenceAccessEvaluator
	Containment    gate.EvidenceContainmentVerifier
	AllowedKinds   []string
	ReadWorkspace  *tool.ReadWorkspaceBinding
	NewExecutionID EvidenceExecutionIDFactory
}

EvidenceRuntimeConfig supplies only the headless, read-only capabilities needed by opt-in evidence-tool definitions. There is deliberately no controller-wide SecurityCeiling field here: the ceiling is bound PER RunAndFinalize call from that call's own hustle.Request.SecurityCeiling (execution.go), never frozen at controller construction — see hustle.Request.SecurityCeiling's doc comment for why a construction-time constant would be a real staleness bug for a long-running session.

type EvidenceWorkerPanicError

type EvidenceWorkerPanicError struct {
	RunID hustle.RunID
}

EvidenceWorkerPanicError is the redacted recovery product for an unexpected panic anywhere inside evidence catalog binding or evidence execution.

func (*EvidenceWorkerPanicError) Error

func (e *EvidenceWorkerPanicError) Error() string

type FaultReporter

type FaultReporter interface {
	ReportFault(context.Context, error)
}

FaultReporter receives bounded typed controller faults.

type Finalizer

type Finalizer func(context.Context, hustle.Outcome) error

Finalizer is the consumer-owned product commit callback. Every owned run calls it exactly once; a pre-ownership rejection never calls it. Trusted production adapters must preserve and honor the supplied context when delegating. They are built from focused product capability and must never capture a Session, Shutdown function, or other generic session-control capability.

type FinalizerContextDecorator

type FinalizerContextDecorator interface {
	DecorateFinalizerContext(context.Context) context.Context
}

FinalizerContextDecorator adds consumer-owned, non-capability metadata while preserving the supplied trusted context's values and deadline. The runtime never receives the consumer object that interprets the marker.

type FinalizerError

type FinalizerError struct {
	RunID      hustle.RunID
	Cause      error
	CleanupErr error
}

FinalizerError preserves a consumer callback failure with owned-run identity.

func (*FinalizerError) Error

func (e *FinalizerError) Error() string

func (*FinalizerError) Unwrap

func (e *FinalizerError) Unwrap() []error

type HeaderStamper

type HeaderStamper interface {
	Stamp(event.Header) (event.Header, error)
}

HeaderStamper mints the identity fields of one internal lifecycle event.

type LaneLimits

type LaneLimits struct {
	Concurrent int
	Queued     int
}

LaneLimits bounds one participation lane. Concurrent limits executing runs; Queued adds waiting ownership capacity. Their sum is the total ownership cap.

type ObservationCollector

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

ObservationCollector accumulates the ObservationRequirement values target-sensitive evidence tools record while executing during ONE classifier's Hustle run (design §13.4, TOCTOU). It is created fresh per run by the review adapter (internal/sessionruntime/review_adapter.go), attached to that run's context via WithObservationCollector, and read back after RunAndFinalize returns — never shared across runs, never persisted. A nil *ObservationCollector is a safe no-op receiver everywhere below, so a Hustle run with no collector attached (every non-review Hustle, and any review whose evidence tools recorded nothing) never allocates one.

func NewObservationCollector

func NewObservationCollector() *ObservationCollector

NewObservationCollector returns an empty collector ready to attach to one run's context.

func (*ObservationCollector) Observations

func (c *ObservationCollector) Observations() []gate.ObservationRequirement

Observations returns an independent copy of every requirement recorded so far. Safe to call at any time, including concurrently with recording.

type OutputError

type OutputError struct {
	Reason OutputFailureReason
	Cause  error
}

OutputError reports an invalid provider response or consumer validation result without retaining response content. Reason is populated for generic extraction failures; callback failures retain their typed Cause instead.

func (*OutputError) Error

func (e *OutputError) Error() string

func (*OutputError) Unwrap

func (e *OutputError) Unwrap() error

func (*OutputError) Valid

func (e *OutputError) Valid() bool

Valid reports whether exactly one bounded failure classification or wrapped validation cause is present.

type OutputFailureReason

type OutputFailureReason string

OutputFailureReason is the closed, security-safe generic extraction failure.

const (
	OutputFailureInvalidShape OutputFailureReason = "invalid_shape"
	OutputFailureEmptyText    OutputFailureReason = "empty_text"
	OutputFailureTooLarge     OutputFailureReason = "too_large"
	OutputFailureInvalidJSON  OutputFailureReason = "invalid_json"
	// OutputFailureRefused reports that the model DECLINED to produce the
	// output. It is distinct from invalid_shape for the same reason
	// ToolResponseFailureRefused is: the response is not defective, the request
	// was refused, and only the latter is worth surfacing to a human. It names
	// the outcome, never the provider's wording.
	OutputFailureRefused OutputFailureReason = "refused"
)

func (OutputFailureReason) Valid

func (r OutputFailureReason) Valid() bool

Valid reports whether the reason is a recognized extraction failure.

type QueueFailureError

type QueueFailureError struct {
	RunID         hustle.RunID
	Participation hustle.Participation
	Stage         hustle.Stage
	Reason        QueueFailureReason
	Cause         error
	FinalizerErr  *FinalizerError
	TerminalErr   error
	CleanupErr    error
}

QueueFailureError is both the returned owned-run failure and the exact error supplied to its finalizer.

func (*QueueFailureError) Error

func (e *QueueFailureError) Error() string

func (*QueueFailureError) Unwrap

func (e *QueueFailureError) Unwrap() []error

type QueueFailureReason

type QueueFailureReason string

QueueFailureReason classifies a terminal failure while an owned node waits for an execution slot.

const (
	QueueFailureCanceled QueueFailureReason = "canceled"
	QueueFailureTimeout  QueueFailureReason = "timeout"
	QueueFailureClosed   QueueFailureReason = "closed"
	QueueFailurePoisoned QueueFailureReason = "poisoned"
)

type RequestError

type RequestError struct {
	Reason RequestErrorReason
	Name   hustle.Name
	Cause  error
}

RequestError reports a rejection before a run owns capacity or a RunID.

func (*RequestError) Error

func (e *RequestError) Error() string

func (*RequestError) Unwrap

func (e *RequestError) Unwrap() error

type RequestErrorReason

type RequestErrorReason string

RequestErrorReason identifies a pre-ownership runtime request rejection.

const (
	RequestInvalidContext     RequestErrorReason = "invalid_context"
	RequestRuntimeUnavailable RequestErrorReason = "runtime_unavailable"
	RequestUnknownDefinition  RequestErrorReason = "unknown_definition"
	RequestInvalidCause       RequestErrorReason = "invalid_cause"
	RequestInvalidInput       RequestErrorReason = "invalid_input"
	RequestInputTooLarge      RequestErrorReason = "input_too_large"
	RequestNilValidator       RequestErrorReason = "nil_validator"
)

type RunError

type RunError struct {
	Name         hustle.Name
	RunID        hustle.RunID
	Stage        hustle.Stage
	ReasonCode   hustle.ReasonCode
	Cause        error
	TerminalErr  error
	FinalizerErr *FinalizerError
	CleanupErr   error
}

RunError is the primary typed failure of an owned run after admission.

func (*RunError) Error

func (e *RunError) Error() string

func (*RunError) Unwrap

func (e *RunError) Unwrap() []error

type RunIDFactory

type RunIDFactory func() (uuid.UUID, error)

RunIDFactory mints one candidate identifier before ownership commits.

type RunStateError

type RunStateError struct {
	RunID hustle.RunID
	State runState
}

RunStateError reports misuse of the internal ownership seam without silently corrupting lane accounting.

func (*RunStateError) Error

func (e *RunStateError) Error() string

type RuntimeConfig

type RuntimeConfig struct {
	SessionID           uuid.UUID
	Definitions         []hustle.BoundDefinition
	AuditTimeout        time.Duration
	FinalizationTimeout time.Duration
	WorkerDrainTimeout  time.Duration
	Stamper             HeaderStamper
	Audit               AuditPublisher
	Faults              FaultReporter
	Activity            ActivityTracker
	FinalizerContext    FinalizerContextDecorator
	Evidence            *EvidenceRuntimeConfig
}

RuntimeConfig supplies the immutable definitions and narrow controller-owned capabilities used by RunAndFinalize. Nil preserves the Task 18 ownership-only construction seam.

type ToolResponseError

type ToolResponseError struct {
	Reason ToolResponseFailureReason
}

ToolResponseError reports one bounded response-shape classification. It deliberately has no cause or caller-controlled metadata.

func (*ToolResponseError) Error

func (e *ToolResponseError) Error() string

func (*ToolResponseError) Valid

func (e *ToolResponseError) Valid() bool

Valid reports whether the error contains exactly one recognized reason.

type ToolResponseFailureReason

type ToolResponseFailureReason string

ToolResponseFailureReason is a closed, security-safe classification for an invalid structured-output-with-tools response. Values describe only the response shape; they never retain provider-controlled content.

const (
	ToolResponseFailureInvalidShape       ToolResponseFailureReason = "invalid_shape"
	ToolResponseFailureFinishReason       ToolResponseFailureReason = "finish_reason"
	ToolResponseFailureUnknownTool        ToolResponseFailureReason = "unknown_tool"
	ToolResponseFailureMalformedArguments ToolResponseFailureReason = "malformed_arguments"
	ToolResponseFailureMissingCallID      ToolResponseFailureReason = "missing_call_id"
	ToolResponseFailureDuplicateCallID    ToolResponseFailureReason = "duplicate_call_id"
	ToolResponseFailureMixed              ToolResponseFailureReason = "mixed_response"
	ToolResponseFailureDuplicateTerminal  ToolResponseFailureReason = "duplicate_terminal"
	ToolResponseFailureInvalidTerminal    ToolResponseFailureReason = "invalid_terminal"
	ToolResponseFailureTooLarge           ToolResponseFailureReason = "too_large"
	// ToolResponseFailureRefused reports that the model DECLINED to answer,
	// which is a fact about the request and not a defect in the response. It is
	// kept distinct from invalid_shape because the two lead somewhere different:
	// a malformed response is a bug to investigate, a refusal is a decision to
	// surface. Like every other reason it names only the shape, never the
	// provider's wording.
	ToolResponseFailureRefused ToolResponseFailureReason = "refused"
)

func (ToolResponseFailureReason) Valid

func (r ToolResponseFailureReason) Valid() bool

Valid reports whether the reason is a recognized response-shape failure.

type ValidateResult

type ValidateResult func(context.Context, hustle.Result) error

ValidateResult performs consumer-owned decoding and domain validation before HustleCompleted can commit.

type WorkerPanicError

type WorkerPanicError struct {
	RunID hustle.RunID
}

WorkerPanicError is the redacted recovery product for an inference client panic. It deliberately retains no panic value.

func (*WorkerPanicError) Error

func (e *WorkerPanicError) Error() string

type WorkerPoisonError

type WorkerPoisonError struct {
	RunID hustle.RunID
	Cause error
}

WorkerPoisonError reports that an inference worker ignored cancellation long enough to disable both lanes. It retains no provider response or request.

func (*WorkerPoisonError) Error

func (e *WorkerPoisonError) Error() string

func (*WorkerPoisonError) Unwrap

func (e *WorkerPoisonError) Unwrap() error

Jump to

Keyboard shortcuts

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