Skip to Content
Numinance
SDKs

Go SDK

The Go packages under sdk/go, their real import paths, a compile-checked example that loads a kind document, and how to run the tests.

View as .mdUpdated
Pre-alpha

Handwritten packages plus generated stubs, all in one untagged Go module. Surfaces can change before the first tag.

Go is the only language with handwritten SDK code. The official providers, the numi command line and the offline evidence verifier are all built from these packages.

Module and toolchain

The repository is a single Go module. Its go.mod declares:

go.mod
module github.com/numinance/numinance-spec

go 1.27

toolchain go1.27.3

Every import path below is that module path plus the directory. The module is not tagged yet, so consume it from a checkout (a replace directive, a go.work workspace or a vendored copy) rather than assuming a published version.

Clone URL and module path differ

You clone https://github.com/dsha256/numinance-spec.git, but the Go module path is github.com/numinance/numinance-spec. Imports use the module path.

Packages

Import pathRole
github.com/numinance/numinance-spec/sdk/go/pluginPlugin handshake line parsing, Serve, the ResolveReference reference check, and StreamCheck, the shape check for an Invoke stream. Imports no port: a port supplies a PortRule.
github.com/numinance/numinance-spec/sdk/go/ports/authorexecutorThe author-executor port rules: NewExecuteRule, NewPlanRule and ValidatePlanRequest. This is the only package under sdk/go/ports today.
github.com/numinance/numinance-spec/sdk/go/kindyamlThe strict loader for configuration kinds: NewLoader, Loader.Decode, Loader.Encode.
github.com/numinance/numinance-spec/sdk/go/schemaJSON Schema 2020-12 compilation and validation for the schemas generated from numinance.kinds.v1. Implements only the keywords the generator emits and fails closed on any other.
github.com/numinance/numinance-spec/sdk/go/cliThe command logic behind numi: dispatch, validate, init, evidence verify and the stable exit-code table. Public so the open and engine builds run the same code.
github.com/numinance/numinance-spec/sdk/go/evidenceverifyThe open verifier of an evidence/v1 export. Standard library only, offline, read-only and size-bounded.
github.com/numinance/numinance-spec/sdk/go/gen/numinance/...Generated Protobuf, gRPC and Connect stubs for annotations, events, evidence, kinds, plugin, ports and types.

There is also sdk/go/internal/annotationlint, which is internal and not importable from outside the module.

plugin

The package comment states the split of responsibility: plugin holds the reference checks that a host, a provider and a conformance kit must apply the same way, namely the shape of an Invoke stream and the references HostService.ResolveReference may serve. StreamCheck bounds the message count (at most 1024), a RUNNING message (64 KiB) and the terminal message (4 MiB), and checks placement, result presence and type, and strict decoding. The host still has to check the things that need its own registry or state. The package comment lists them.

ports

ports/authorexecutor supplies the PortRule for the Execute and Plan streams. A Plan stream is read only: a FILE_CHANGED event breaks it. ValidatePlanRequest rejects a request that names a work unit, allows paths, names a credential capability, or allows a capability that writes.

kindyaml

NewLoader compiles the embedded schema of every kind. Decode runs four stages and stops at the first failure: size cap (128 KiB), strict single-document YAML (no anchors, aliases, merge keys or explicit tags), the kind's generated JSON Schema, then the loader checks that a schema cannot express. Each error wraps one sentinel and never quotes a value of the document. Two behaviors matter to callers:

  • A produced kind (ContextBundle) is never loaded as configuration.
  • EvalSet is a pre-GA kind at numinance.dev/v1alpha1. NewLoader() refuses it; NewLoader(WithAlphaKinds()) accepts it.

A document that decodes has no authority by decoding. metadata.scope is the document's own claim; authority comes from where the document was loaded (a protected path or a signed policy bundle), decided outside this package.

evidenceverify

A call passes the export directory plus pinned runner keys, a log key and a log origin. There is no built-in trust root, so a key stated by the export never reaches verified. The result is Report, which carries LevelEnum and WeakenedByFlags. Automation that needs a full pass tests LevelEnum == "verified" and an empty WeakenedByFlags, never a prefix of the human-readable level. See offline verification and the numi evidence verify command.

Example: load a kind document

This program decodes one kind document with kindyaml and reads typed fields from the generated stub.

main.go
package main

import (
	"fmt"
	"os"

	kindsv1 "github.com/numinance/numinance-spec/sdk/go/gen/numinance/kinds/v1"
	"github.com/numinance/numinance-spec/sdk/go/kindyaml"
)

func main() {
	b, err := os.ReadFile(os.Args[1])
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	loader, err := kindyaml.NewLoader()
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	msg, err := loader.Decode(b)
	if err != nil {
		fmt.Fprintln(os.Stderr, "decode:", err)
		os.Exit(3)
	}
	if p, ok := msg.(*kindsv1.AutonomyPolicy); ok {
		fmt.Println("kind:", p.GetKind(), "name:", p.GetMetadata().GetName())
		fmt.Println("default level:", p.GetSpec().GetDefaults().GetLevel())
		fmt.Println("rules:", len(p.GetSpec().GetRules()))
	}
}

The module that builds it points at a checkout with a replace directive:

go.mod
module example.test/loadkind

go 1.27

require github.com/numinance/numinance-spec v0.0.0

replace github.com/numinance/numinance-spec => /path/to/numinance-spec
kind: AutonomyPolicy name: org-ladder
default level: AUTONOMY_LEVEL_PR
rules: 1
✓ verifiedgo vet, then go run . schemas/examples/AutonomyPolicy/org-ladder.yaml, built against the checkout at revision 3c74d59· numinance-spec @ 3c74d59 · 2026-11-09· 0

go vet ./... passed on the module. It was built offline against the local module cache with GOTOOLCHAIN=local (the local toolchain was Go 1.27.2, while go.mod asks for go1.27.3), so expect the toolchain line to matter on your machine.

Feeding the same program a document whose kind is not a known kind fails in the schema stage:

decode: kind: unknown kind
✓ verifiedprogram run against a file containing only `kind: Nope`· numinance-spec @ 3c74d59 · 2026-11-09

Run the tests

From the root of a checkout:

go test ./sdk/go/... ./cli/...

Narrower commands the repository documents:

CommandCovers
go test ./sdk/go/kindyamlThe loader: one failing case per refused construct and per loader check
go test -race ./sdk/go/evidenceverify/Every vector of conformance/evidence/v1/ plus bounds, cancellation and key-file cases
go test ./cli/... ./sdk/go/cli ./sdk/go/evidenceverifyThe numi command logic and the verifier

In a sandboxed run for this page, sdk/go/ports/authorexecutor, sdk/go/schema, cli/numi and sdk/go/evidenceverify passed. sdk/go/plugin did not finish: TestServe_PrintsTheLineAndStopsOnStop hung until the 10-minute test timeout and the package reported FAIL. The sandbox may have blocked signal or process handling, so this is unconfirmed as a defect; run the suite in your own environment. The sample plugin under plugins/examples/ has no test files.

Failure modes

SymptomCauseResponse
A toolchain error mentioning Go 1.27Local Go is older than go.modInstall the toolchain go.mod names
The module cannot be resolved by versionThe module is not tagged, so there is no version to resolveUse a replace directive or a workspace
ErrAlpha from DecodeThe document is an EvalSetConstruct the loader with WithAlphaKinds()
unknown kindkind is missing, misspelled, or names a produced kindUse a configuration kind from the kinds reference

Next steps

On this page