portable

package module
v0.0.0-...-393d0f4 Latest Latest
Warning

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

Go to latest
Published: Aug 11, 2026 License: Apache-2.0 Imports: 11 Imported by: 0

README

GoForge portable core

This nested Go module is the dependency-free source of truth for deterministic GoForge rules that can cross the native Go, WebAssembly component, and Deno boundaries. It implements contract package pointerbyte:goforge@0.1.0 and the strict JSON bridge goforge.abi.v1.

Contract

ABI v1 exposes eight operations:

Capability Operations
Normalization text.normalize
Validation text.validate
SHA-256 crypto.sha256
HMAC-SHA256 crypto.hmac-sha256
AES-GCM crypto.aes-gcm.encrypt, crypto.aes-gcm.decrypt
Base64 encoding.base64.encode, encoding.base64.decode

The manifest also advertises the host-observed control.deadline and control.cancellation capabilities. A request that supplies either control fails closed unless the host passes matching checked state to the dispatcher. The package never reads a clock itself.

{
  "abi": "goforge.abi.v1",
  "id": "request-1",
  "operation": "crypto.sha256",
  "metadata": {
    "required_capabilities": ["crypto.sha256"]
  },
  "payload": {"data": "YWJj"}
}

Successful responses contain result; failed responses contain a typed error from the manifest catalog. They never contain both.

The operation payload and result fields are stable:

Operation Required payload Successful result
text.normalize value; optional trim, collapse_whitespace, lowercase_ascii booleans value
text.validate value, rules valid, ordered violations
crypto.sha256 Base64 data Base64 digest
crypto.hmac-sha256 Base64 key, Base64 data Base64 mac
crypto.aes-gcm.encrypt Base64 key, nonce, aad, plaintext Base64 ciphertext with the authentication tag appended
crypto.aes-gcm.decrypt Base64 key, nonce, aad, ciphertext Base64 plaintext
encoding.base64.encode UTF-8 text encoded
encoding.base64.decode canonical encoded UTF-8 text

Every listed field is required, including an explicitly empty aad. Validation rules are required, min_bytes, max_bytes, min_runes, max_runes, ascii, forbid_control, forbid_whitespace, prefix, and suffix. Violations follow that rule order so all runtimes produce the same result.

Serialization and bounds

  • JSON must be UTF-8 and contain one object only.
  • Unknown fields, duplicate object names, malformed JSON, and excessive nesting are rejected.
  • Binary fields use RFC 4648's standard alphabet with required padding. URL-safe, unpadded, whitespace-containing, and otherwise non-canonical values fail.
  • Request, response, binary, string, ID, control-token, capability-count, and JSON-depth limits are published by the manifest and enforced before use.
  • The Base64 operations intentionally convert UTF-8 text. Arbitrary binary values in every other ABI operation remain canonical padded Base64 fields.

Cryptographic safety

AES-GCM accepts only 128-, 192-, or 256-bit caller-supplied keys and exactly 12-byte caller-supplied nonces. It never generates randomness and never falls back to another algorithm. Callers must guarantee that a nonce is unique for every encryption under a given key. Authentication failure returns only the stable authentication_failed error and no plaintext. HMAC keys must contain at least 16 bytes.

The implementation imports only the Go standard library. Production files do not access the filesystem, network, environment, logging, cloud SDKs, clocks, or random sources.

Verification

Run this nested module outside the parent workspace until integration adds it to go.work:

GOWORK=off GOTOOLCHAIN=go1.25.0 go test ./...
GOWORK=off GOTOOLCHAIN=go1.25.0 go test -coverprofile=coverage.out ./...
GOWORK=off GOTOOLCHAIN=go1.25.0 go vet ./...
GOWORK=off GOTOOLCHAIN=go1.25.12 go test ./...
GOWORK=off GOTOOLCHAIN=go1.25.12 go test -run '^$' -bench . -benchmem ./...

testdata/vectors/v1.json is the language-neutral deterministic vector set. It covers every operation, including the NIST AES-128-GCM and RFC 4231 HMAC-SHA256 cases. Negative and fuzz tests cover strict decoding, bounds, execution controls, and cryptographic failure behavior.

Component artifact boundary

This module deliberately does not copy a WIT world, generated bindings, or a component build script from a research directory. Promoting the already validated pointerbyte:goforge@0.1.0 world into a production artifact requires the cross-repository integration gate, generated-binding drift checks, and Deno parity validation. Keeping that promotion outside this module prevents a research path from becoming an undeclared production dependency.

That promotion now exists as the sibling component/ module, which owns the WIT world, the checked-in generated bindings and the build pipeline. This module stays free of them so the portable core has no component-toolchain dependency.

cd component
WASM_TOOLS=/path/to/wasm-tools ./scripts/check-generated.sh   # bindings reproduce byte for byte
WASM_TOOLS=/path/to/wasm-tools ./scripts/check.sh             # tests, race, vet, staticcheck
WASM_TOOLS=/path/to/wasm-tools ./scripts/build.sh             # build, validate, transpile, package

build.sh produces a deterministic release bundle under component/artifacts/ (gitignored): the validated component, its extracted WIT, the jco host glue and core modules, the canonical ABI manifest, the shared vectors, toolchain and contract evidence, and SHA256SUMS. Two consecutive rebuilds are byte-identical.

The resulting component is not yet fit to promote. Its Go runtime intermittently traps during garbage collection under sustained dispatch load. Correctness is proven against the shared vectors; endurance is not. See the blocker in the migration log at ../../temp.md.

Documentation

Overview

Package portable contains GoForge's deterministic, runtime-independent business and cryptographic primitives together with the versioned ABI used by component hosts.

Binary values in ABI payloads use canonical, standard, padded Base64. JSON decoding rejects unknown fields, duplicate object keys, invalid UTF-8, and trailing values. The package never reads clocks, randomness, files, the network, environment variables, or host logging facilities.

Index

Constants

View Source
const (
	// PackageName is the canonical Component Model package name.
	PackageName = "pointerbyte:goforge"
	// PackageVersion is the version of the portable contract package.
	PackageVersion = "0.1.0"
	// ABIVersion identifies the JSON bridge contract.
	ABIVersion = "goforge.abi.v1"
	// ManifestSchema identifies the manifest JSON schema family.
	ManifestSchema = "goforge.manifest.v1"
)

Variables

This section is empty.

Functions

func NewDispatcher

func NewDispatcher(limits Limits) (*Dispatcher, *ABIError)

NewDispatcher constructs a dispatcher with explicit resource limits.

Types

type ABIError

type ABIError struct {
	Code      ErrorCode `json:"code"`
	Message   string    `json:"message"`
	Retryable bool      `json:"retryable"`
	Field     string    `json:"field,omitempty"`
}

ABIError is the unified portable error representation. Message is stable and never includes an underlying cryptographic or runtime error.

func (*ABIError) Error

func (e *ABIError) Error() string

Error implements error.

type CapabilityDefinition

type CapabilityDefinition struct {
	Name       string      `json:"name"`
	Version    string      `json:"version"`
	Host       bool        `json:"host"`
	Operations []Operation `json:"operations,omitempty"`
}

CapabilityDefinition describes a portable or host-control capability.

type Dispatcher

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

Dispatcher validates ABI envelopes, enforces execution controls and bounds, and invokes portable operations.

func DefaultDispatcher

func DefaultDispatcher() *Dispatcher

DefaultDispatcher constructs an ABI v1 dispatcher with DefaultLimits.

func (*Dispatcher) Dispatch

func (d *Dispatcher) Dispatch(request Request, state ExecutionState) Response

Dispatch validates and executes one already-decoded request.

func (*Dispatcher) DispatchJSON

func (d *Dispatcher) DispatchJSON(encoded []byte, state ExecutionState) []byte

DispatchJSON decodes one strict request and always returns an ABI response. Malformed input receives an error response with an empty correlation ID.

func (*Dispatcher) Manifest

func (d *Dispatcher) Manifest() Manifest

Manifest returns a fresh deterministic manifest for the dispatcher.

func (*Dispatcher) ManifestJSON

func (d *Dispatcher) ManifestJSON() []byte

ManifestJSON returns the deterministic JSON encoding of Manifest.

type EncodingDefinition

type EncodingDefinition struct {
	JSON   string `json:"json"`
	Binary string `json:"binary"`
}

EncodingDefinition describes the only serialization profile supported by ABI v1.

type ErrorCode

type ErrorCode string

ErrorCode is a stable machine-readable ABI error identifier.

const (
	ErrorInvalidJSON            ErrorCode = "invalid_json"
	ErrorUnknownField           ErrorCode = "unknown_field"
	ErrorDuplicateField         ErrorCode = "duplicate_field"
	ErrorRequestTooLarge        ErrorCode = "request_too_large"
	ErrorResponseTooLarge       ErrorCode = "response_too_large"
	ErrorInvalidABI             ErrorCode = "invalid_abi"
	ErrorInvalidRequest         ErrorCode = "invalid_request"
	ErrorUnknownOperation       ErrorCode = "unknown_operation"
	ErrorCapabilityUnavailable  ErrorCode = "capability_unavailable"
	ErrorExecutionStateRequired ErrorCode = "execution_state_required"
	ErrorDeadlineExceeded       ErrorCode = "deadline_exceeded"
	ErrorCancellationRequested  ErrorCode = "cancellation_requested"
	ErrorInvalidBase64          ErrorCode = "invalid_base64"
	ErrorInvalidUTF8            ErrorCode = "invalid_utf8"
	ErrorInputTooLarge          ErrorCode = "input_too_large"
	ErrorInvalidKey             ErrorCode = "invalid_key"
	ErrorInvalidNonce           ErrorCode = "invalid_nonce"
	ErrorAuthenticationFailed   ErrorCode = "authentication_failed"
	ErrorInternal               ErrorCode = "internal"
)

type ErrorDefinition

type ErrorDefinition struct {
	Code      ErrorCode `json:"code"`
	Message   string    `json:"message"`
	Retryable bool      `json:"retryable"`
}

ErrorDefinition describes a stable catalog entry in the manifest.

type ExecutionState

type ExecutionState struct {
	ClockChecked          bool
	NowUnixMilliseconds   int64
	CancellationChecked   bool
	CancellationToken     string
	CancellationRequested bool
}

ExecutionState is deterministic, host-observed state for one dispatch. ClockChecked and CancellationChecked prevent controls from being silently ignored. CancellationToken must equal the request token.

type Limits

type Limits struct {
	MaxRequestBytes           int `json:"max_request_bytes"`
	MaxResponseBytes          int `json:"max_response_bytes"`
	MaxBinaryBytes            int `json:"max_binary_bytes"`
	MaxStringBytes            int `json:"max_string_bytes"`
	MaxIDBytes                int `json:"max_id_bytes"`
	MaxCancellationTokenBytes int `json:"max_cancellation_token_bytes"`
	MaxRequiredCapabilities   int `json:"max_required_capabilities"`
	MaxJSONDepth              int `json:"max_json_depth"`
}

Limits defines hard resource bounds enforced by a Dispatcher.

func DefaultLimits

func DefaultLimits() Limits

DefaultLimits returns the ABI v1 resource limits.

type Manifest

type Manifest struct {
	Schema       string                 `json:"schema"`
	Package      string                 `json:"package"`
	Version      string                 `json:"version"`
	ABI          string                 `json:"abi"`
	Encoding     EncodingDefinition     `json:"encoding"`
	Limits       Limits                 `json:"limits"`
	Operations   []OperationDefinition  `json:"operations"`
	Capabilities []CapabilityDefinition `json:"capabilities"`
	Errors       []ErrorDefinition      `json:"errors"`
}

Manifest is the deterministic ABI v1 contract manifest.

type Operation

type Operation string

Operation is a stable ABI operation identifier.

const (
	OperationNormalize     Operation = "text.normalize"
	OperationValidate      Operation = "text.validate"
	OperationSHA256        Operation = "crypto.sha256"
	OperationHMACSHA256    Operation = "crypto.hmac-sha256"
	OperationAESGCMEncrypt Operation = "crypto.aes-gcm.encrypt"
	OperationAESGCMDecrypt Operation = "crypto.aes-gcm.decrypt"
	OperationBase64Encode  Operation = "encoding.base64.encode"
	OperationBase64Decode  Operation = "encoding.base64.decode"
)

type OperationDefinition

type OperationDefinition struct {
	Name       Operation `json:"name"`
	Capability string    `json:"capability"`
}

OperationDefinition connects an operation to its required capability.

type Request

type Request struct {
	ABI       string           `json:"abi"`
	ID        string           `json:"id"`
	Operation Operation        `json:"operation"`
	Metadata  *RequestMetadata `json:"metadata,omitempty"`
	Payload   json.RawMessage  `json:"payload"`
}

Request is the strict ABI v1 request envelope.

type RequestMetadata

type RequestMetadata struct {
	DeadlineUnixMilliseconds *int64   `json:"deadline_unix_ms,omitempty"`
	CancellationToken        string   `json:"cancellation_token,omitempty"`
	RequiredCapabilities     []string `json:"required_capabilities,omitempty"`
}

RequestMetadata carries portable control metadata. The host supplies the corresponding checked state through ExecutionState.

type Response

type Response struct {
	ABI    string          `json:"abi"`
	ID     string          `json:"id"`
	OK     bool            `json:"ok"`
	Result json.RawMessage `json:"result,omitempty"`
	Error  *ABIError       `json:"error,omitempty"`
}

Response is the strict ABI v1 response envelope. Exactly one of Result and Error is populated.

Jump to

Keyboard shortcuts

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