Documentation
¶
Overview ¶
Package contract provides import-isolated machine contracts for ax-go consumers.
It owns deterministic exit codes, output mode resolution, context metadata, success envelopes, strict JSON writers, and the structured error envelope. The package does not import the root ax facade or runtime telemetry, logging, transport, or execution adapters.
Consequently this package provides no live tracing: TraceIDFromContext and SpanIDFromContext read back metadata a caller already stored with WithMetadata, never an active OpenTelemetry span context. Real trace IDs come from the root ax package, where StartTelemetry installs W3C propagation and Execute opens a recording root span.
Index ¶
- Constants
- func ApprovalFromContext(ctx context.Context) bool
- func DryRunFromContext(ctx context.Context) bool
- func ErrorExitCode(err error) int
- func IdempotencyKeyFromContext(ctx context.Context) (string, bool)
- func SpanIDFromContext(ctx context.Context) string
- func TraceIDFromContext(ctx context.Context) string
- func WithApproval(ctx context.Context, granted bool) context.Context
- func WithDryRun(ctx context.Context, dryRun bool) context.Context
- func WithIdempotencyKey(ctx context.Context, key string) context.Context
- func WithMetadata(ctx context.Context, metadata Metadata) context.Context
- func WithMode(ctx context.Context, mode Mode) context.Context
- func WriteError(w io.Writer, err error) error
- func WriteJSON(w io.Writer, v any) error
- func WriteJSONLine(w io.Writer, v any) error
- type Envelope
- type Error
- type ErrorOption
- func WithActionableFix(fix string) ErrorOption
- func WithErrorCause(err error) ErrorOption
- func WithErrorContext(fields map[string]any) ErrorOption
- func WithErrorExitCode(code int) ErrorOption
- func WithErrorTool(tool string) ErrorOption
- func WithErrorVersion(version string) ErrorOption
- func WithRetryAfterSeconds(seconds int64) ErrorOption
- func WithRetryable(retryable bool) ErrorOption
- func WithSuggestions(suggestions ...string) ErrorOption
- type Metadata
- type Mode
Examples ¶
Constants ¶
const ( // ExitSuccess indicates successful completion. ExitSuccess = 0 // ExitInternal indicates an unknown or internal error. ExitInternal = 1 // ExitValidation indicates invalid input or failed validation. ExitValidation = 2 // ExitNetwork indicates a network failure or timeout. ExitNetwork = 3 // ExitAuth indicates an authentication or permission failure. ExitAuth = 4 )
const ( // ZeroTraceID is a valid zero-value W3C trace ID for no-active-span cases. ZeroTraceID = "00000000000000000000000000000000" // ZeroSpanID is a valid zero-value W3C span ID for no-active-span cases. ZeroSpanID = "0000000000000000" )
const (
// ErrorSchemaVersion is the current SemVer version of the error envelope.
ErrorSchemaVersion = "1.0.0"
)
const ModeDetectionRule = "--format flag > AGENT_MODE env > TTY detection"
ModeDetectionRule documents the output-mode resolution precedence applied by ResolveMode. It is surfaced verbatim in schema output.
Variables ¶
This section is empty.
Functions ¶
func ApprovalFromContext ¶ added in v0.5.0
ApprovalFromContext reports whether explicit confirmation was granted.
func DryRunFromContext ¶
DryRunFromContext reports whether dry-run behavior is active.
func ErrorExitCode ¶
ErrorExitCode maps an error to the deterministic ax-go process exit code.
func IdempotencyKeyFromContext ¶
IdempotencyKeyFromContext returns the idempotency key stored in ctx.
func SpanIDFromContext ¶
SpanIDFromContext returns the explicit span ID stored in ctx or ZeroSpanID when no span metadata is present.
Like TraceIDFromContext, this reads back metadata a caller already stored with WithMetadata rather than resolving an active OpenTelemetry span context. This package provides no live tracing; the root ax package does.
func TraceIDFromContext ¶
TraceIDFromContext returns the explicit trace ID stored in ctx or ZeroTraceID when no trace metadata is present.
This reads back metadata a caller already stored with WithMetadata. It does not resolve an active OpenTelemetry span context: this package is import-isolated from the OpenTelemetry SDK and provides no live tracing, so a context that was never populated yields ZeroTraceID rather than a real trace ID. Live tracing comes from the root ax package, where ax.StartTelemetry installs W3C propagation and extracts TRACEPARENT, and ax.Execute opens a recording root span around the command.
func WithApproval ¶ added in v0.5.0
WithApproval returns a context carrying the per-invocation confirmation decision.
func WithDryRun ¶
WithDryRun returns a context carrying the dry-run state.
func WithIdempotencyKey ¶
WithIdempotencyKey returns a context carrying the idempotency key for the run.
func WithMetadata ¶
WithMetadata returns a context carrying explicit machine-envelope metadata. Stored values are normalized on read by MetadataFromContext, so they are kept here as supplied.
func WriteError ¶
WriteError writes err as a strict minified JSON error envelope followed by a newline.
Types ¶
type Envelope ¶
Envelope is the standard bounded JSON success payload shape.
Example ¶
ExampleEnvelope shows the generic success-envelope shape directly.
package main
import (
"fmt"
"os"
"github.com/rshade/ax-go/contract"
)
func main() {
env := contract.Envelope[string]{
Data: "hello",
Meta: contract.Metadata{TraceID: contract.ZeroTraceID},
}
if err := contract.WriteJSON(os.Stdout, env); err != nil {
fmt.Println("error:", err)
}
}
Output: {"data":"hello","meta":{"trace_id":"00000000000000000000000000000000"}}
func NewEnvelope ¶
NewEnvelope wraps data with standard AX metadata from ctx.
Example ¶
ExampleNewEnvelope shows the strict success envelope produced by the import-isolated contract package.
package main
import (
"context"
"fmt"
"os"
"github.com/rshade/ax-go/contract"
)
func main() {
type result struct {
ID string `json:"id"`
}
env := contract.NewEnvelope(context.Background(), result{ID: "abc"})
if err := contract.WriteJSON(os.Stdout, env); err != nil {
fmt.Println("error:", err)
}
}
Output: {"data":{"id":"abc"},"meta":{"trace_id":"00000000000000000000000000000000","span_id":"0000000000000000"}}
type Error ¶
type Error struct {
ErrorCode string `json:"error_code"`
Message string `json:"message"`
TraceID string `json:"trace_id"`
Tool string `json:"tool"`
Version string `json:"version"`
SchemaVersion string `json:"schema_version"`
ActionableFix string `json:"actionable_fix,omitempty"`
Context map[string]any `json:"context,omitempty"`
Suggestions []string `json:"suggestions,omitempty"`
// Retryable is a tri-state retry-safety signal: a non-nil true means a naive
// re-run of the same command is safe, a non-nil false means it MUST NOT be
// retried, and nil (omitted) means unspecified. Absence is distinguishable
// from explicit false so a consumer can tell "do not retry" from "unknown".
Retryable *bool `json:"retryable,omitempty"`
// RetryAfterSeconds is an advisory, relative backoff in whole seconds before
// a retry should be attempted (delta-seconds, never an absolute timestamp, so
// output stays byte-identical across runs). Meaningful only when Retryable is
// true; omitted when unset or zero.
RetryAfterSeconds int64 `json:"retry_after_seconds,omitempty"`
// contains filtered or unexported fields
}
Error is the structured error envelope emitted to stderr.
func NewError ¶
func NewError(ctx context.Context, code, message string, opts ...ErrorOption) *Error
NewError builds a structured error envelope using explicit metadata from ctx.
Example ¶
ExampleNewError shows a structured error envelope and its deterministic exit code without importing the root runtime package.
package main
import (
"context"
"fmt"
"github.com/rshade/ax-go/contract"
)
func main() {
err := contract.NewError(
context.Background(),
"config_too_large",
"config exceeds maximum size of 1048576 bytes",
contract.WithActionableFix("reduce the config or raise the limit"),
contract.WithErrorExitCode(contract.ExitValidation),
)
fmt.Println(err)
fmt.Println(contract.ErrorExitCode(err))
}
Output: config exceeds maximum size of 1048576 bytes 2
type ErrorOption ¶
type ErrorOption func(*Error)
ErrorOption configures a structured Error.
func WithActionableFix ¶
func WithActionableFix(fix string) ErrorOption
WithActionableFix sets a best-effort remediation hint.
func WithErrorCause ¶
func WithErrorCause(err error) ErrorOption
WithErrorCause attaches the underlying source error to the envelope.
func WithErrorContext ¶
func WithErrorContext(fields map[string]any) ErrorOption
WithErrorContext merges domain-specific context fields into the envelope.
func WithErrorExitCode ¶
func WithErrorExitCode(code int) ErrorOption
WithErrorExitCode sets the deterministic process exit code.
func WithErrorTool ¶
func WithErrorTool(tool string) ErrorOption
WithErrorTool sets the emitting tool name.
func WithErrorVersion ¶
func WithErrorVersion(version string) ErrorOption
WithErrorVersion sets the emitting tool version.
func WithRetryAfterSeconds ¶ added in v0.3.0
func WithRetryAfterSeconds(seconds int64) ErrorOption
WithRetryAfterSeconds sets a relative backoff hint, in whole seconds, before a retry should be attempted. The value is relative (delta-seconds), never an absolute timestamp, to preserve byte-identical output. A negative value is treated as no hint.
func WithRetryable ¶ added in v0.3.0
func WithRetryable(retryable bool) ErrorOption
WithRetryable records whether a naive retry of the failed command is safe. Passing true marks the failure as retryable, false marks it as explicitly non-retryable; not calling the option leaves the signal unspecified (omitted). The bool is stored as a tri-state so an explicit false is distinguishable from absence on the wire.
func WithSuggestions ¶
func WithSuggestions(suggestions ...string) ErrorOption
WithSuggestions sets optional candidate recovery actions.
type Metadata ¶
type Metadata struct {
TraceID string `json:"trace_id" ax:"nondeterministic"`
SpanID string `json:"span_id,omitempty" ax:"nondeterministic"`
IdempotencyKey string `json:"idempotency_key,omitempty" ax:"nondeterministic"`
DryRun bool `json:"dry_run,omitempty"`
}
Metadata carries common machine-readable envelope fields.
func MetadataFromContext ¶
MetadataFromContext returns explicit metadata from ctx merged with dry-run and idempotency-key context helpers.
type Mode ¶
type Mode string
Mode describes whether output should be optimized for agents or humans.
Example ¶
ExampleMode shows output-mode precedence in the isolated contract package.
package main
import (
"fmt"
"github.com/rshade/ax-go/contract"
)
func main() {
mode, err := contract.ResolveMode("", "", false)
if err != nil {
fmt.Println("error:", err)
return
}
fmt.Println(mode)
}
Output: json
func ModeFromContext ¶
ModeFromContext returns the resolved output mode stored in ctx.
func ResolveMode ¶
ResolveMode applies output-mode precedence: explicit --format flag, then AGENT_MODE, then TTY detection.