Skip to documentation
Documentation navigation

Documentation navigation

Documentation / guides

Define a Hustle

Describe hustle.Define and immutable Hustle configuration without a public run method.

developer

hustle.Define validates one immutable definition. The definition is a configuration and policy identity. A supported Harness facility binds it to a session; application code does not execute an arbitrary definition directly.

// Every option is explicit. The definition retains no caller-owned slices.
summary, err := hustle.Define(
	hustle.WithName("context.compact"),
	hustle.WithParticipation(hustle.ParticipationBlocking),
	hustle.WithTimeout(5*time.Second),
	hustle.WithLimits(hustle.Limits{InputBytes: 1 << 20, OutputBytes: 1 << 20}),
	hustle.WithCurrentLoopModel(),
	hustle.WithSystemPrompt("Summarize the earlier conversation.", "prompt-v1"),
	hustle.WithPolicyRevision("policy-v1"),
)
if err != nil {
	return fmt.Errorf("define hustle: %w", err)
}
_ = summary

Constructor APIs

APIPurpose
hustle.Define(opts ...hustle.Option) (hustle.Definition, error)Validates and freezes the definition.
hustle.WithName(hustle.Name) hustle.OptionStable registration name; trimmed emptiness and _looprig. names are rejected.
hustle.WithParticipation(hustle.Participation) hustle.OptionSelects blocking or background lane.
hustle.WithTimeout(time.Duration) hustle.OptionRequires a positive per-invocation timeout.
hustle.WithLimits(hustle.Limits) hustle.OptionRequires positive serialized input and output byte bounds.
hustle.WithCurrentLoopModel() hustle.OptionResolves the originating Loop model for every invocation.
hustle.WithNamedInference(inference.Client, model.Model) hustle.OptionFreezes a validated client and model.
hustle.WithSystemPrompt(string, string) hustle.OptionFreezes prompt bytes and a public prompt revision.
hustle.WithPolicyRevision(string) hustle.OptionNames parser, policy, and finalization behavior.
hustle.WithOutputSchema(inference.OutputSchema) hustle.OptionFreezes optional structured-output policy.
hustle.WithEvidenceTools(hustle.EvidenceToolPolicy) hustle.OptionEnables a bounded, read-only evidence loop.
hustle.WithRetryPolicy(hustle.RetryPolicy) hustle.OptionEnables the one classified retry only for eligible evidence definitions.

Proof: Hustle options and Define and definition validation tests.

Definition descriptor

Definition.Descriptor() is the secret-free identity used by Rig validation and internal audit. It contains these exact fields:

Field groupFields
RegistrationName, Participation, ModelSource, PolicyRevision, TimeoutNanos, Limits
Named modelNamedModelKey, NamedModelPolicyRevision
Prompt and outputPromptRevision, PromptSHA256, OutputSchemaName, OutputSchemaSHA256, StructuredOutputRevision
EvidenceEvidenceToolPolicyRevision, EvidenceToolDefinitionsSHA256, EvidenceProducedToolNamesSHA256, EvidenceToolLimits, EvidenceToolDefinitionCount, StructuredOutputWithTools
RetryRetryPolicy

The descriptor contains hashes and revisions, not raw prompts, provider clients, endpoints, or output bytes. Definition.PolicyRevision() is the frozen digest of this behavior.

Proof: DefinitionDescriptor and descriptor tests.

Bind before a facility uses it

// package hustle
type Bindings struct {
	Models ModelResolver
}

type BoundDefinition interface {
	Name() Name
	Participation() Participation
	Timeout() time.Duration
	Limits() Limits
	Descriptor() DefinitionDescriptor
	ResolveInference(context.Context, uuid.UUID) (InferenceBinding, error)
	SystemPrompt() string
	OutputSchema() (*inference.OutputSchema, bool)
	EvidenceToolPolicy() (EvidenceToolPolicy, bool)
	RetryPolicy() RetryPolicy
	BindEvidenceTools(context.Context, EvidenceBindings) ([]BoundEvidenceTool, error)
}

Definition.Bind validates context and requires a model resolver for current Loop definitions. The bound view clones mutable model and output policy values. Its sealed interface prevents application implementations from substituting a definition with different policy identity.

Proof: binding interface and clone behavior and binding tests.

Source and proof

← back to documentation