Skip to content

Go SDK

pyhall-go mirrors the WCP type system and routing interfaces so Go services can participate in a WCP-governed worker fleet. It is for teams that need to write WCP workers or consume WCP routing decisions from a Go service.

Module: github.com/pyhall/pyhall-go Go: 1.22+. Zero external runtime dependencies — stdlib only. WCP compliance: WCP-Basic (partial). See the compliance status table below.


Install

Terminal window
go get github.com/pyhall/pyhall-go@latest

Quick Start

import (
"fmt"
"github.com/pyhall/pyhall-go/wcp"
)
func main() {
registry := wcp.NewRegistry()
// Enroll a worker
err := registry.Enroll(wcp.WorkerRegistryRecord{
WorkerID: "org.example.my-summarizer",
WorkerSpeciesID: "wrk.doc.summarizer",
Capabilities: []string{"cap.doc.summarize"},
RiskTier: "low",
})
if err != nil {
panic(err)
}
// Route a capability request
input := wcp.RouteInput{
CapabilityID: "cap.doc.summarize",
Env: wcp.EnvDev,
DataLabel: wcp.DataLabelInternal,
TenantRisk: wcp.TenantRiskLow,
QoSClass: wcp.QoSP2,
TenantID: "tenant-001",
CorrelationID: "550e8400-e29b-41d4-a716-446655440000",
Request: map[string]any{"text": "Summarize this document..."},
}
decision := wcp.MakeDecision(input, registry, wcp.RouterOptions{})
if decision.Denied {
fmt.Println("Denied:", decision.DenyReasonIfDenied)
} else {
fmt.Println("Route to:", *decision.SelectedWorkerSpeciesID)
}
}

Package Layout

wcp/
models.go — RouteInput, RouteDecision, supporting types
router.go — MakeDecision() — primary routing entrypoint (stub)
registry.go — Registry — in-memory worker enrollment store
policy_gate.go — PolicyGate interface + DefaultPolicyGate stub
common.go — NowUTC(), SHA256Hex(), OK/Err helpers
workers/examples/hello_worker/
worker.go — minimal canonical worker implementation
registry_record.json — enrollment record for the hello worker

Types

Enum Constants

type Env string
const (
EnvDev Env = "dev"
EnvStage Env = "stage"
EnvProd Env = "prod"
EnvEdge Env = "edge"
)
type DataLabel string
const (
DataLabelPublic DataLabel = "PUBLIC"
DataLabelInternal DataLabel = "INTERNAL"
DataLabelRestricted DataLabel = "RESTRICTED"
)
type QoSClass string
const (
QoSP0 QoSClass = "P0"
QoSP1 QoSClass = "P1"
QoSP2 QoSClass = "P2"
QoSP3 QoSClass = "P3"
)
type TenantRisk string
const (
TenantRiskLow TenantRisk = "low"
TenantRiskMedium TenantRisk = "medium"
TenantRiskHigh TenantRisk = "high"
)

RouteInput

type RouteInput struct {
CapabilityID string `json:"capability_id"`
Env Env `json:"env"`
DataLabel DataLabel `json:"data_label"`
TenantRisk TenantRisk `json:"tenant_risk"`
QoSClass QoSClass `json:"qos_class"`
TenantID string `json:"tenant_id"`
CorrelationID string `json:"correlation_id"`
Request map[string]any `json:"request,omitempty"`
BlastRadius map[string]any `json:"blast_radius,omitempty"`
BlastScore *int `json:"blast_score,omitempty"`
PrivilegeContext map[string]any `json:"privilege_context,omitempty"`
DryRun bool `json:"dry_run"`
}

RouteDecision

type RouteDecision struct {
DecisionID string `json:"decision_id"`
Timestamp string `json:"timestamp"`
CorrelationID string `json:"correlation_id"`
TenantID string `json:"tenant_id"`
CapabilityID string `json:"capability_id"`
MatchedRuleID string `json:"matched_rule_id"`
Env Env `json:"env"`
DataLabel DataLabel `json:"data_label"`
TenantRisk TenantRisk `json:"tenant_risk"`
QoSClass QoSClass `json:"qos_class"`
Denied bool `json:"denied"`
DenyReasonIfDenied map[string]any `json:"deny_reason_if_denied,omitempty"`
SelectedWorkerSpeciesID *string `json:"selected_worker_species_id,omitempty"`
CandidateWorkersRanked []CandidateWorker `json:"candidate_workers_ranked"`
RequiredControlsEffective []string `json:"required_controls_effective"`
RecommendedProfilesEffective []map[string]any `json:"recommended_profiles_effective"`
EscalationEffective Escalation `json:"escalation_effective"`
// ... additional governance fields
TelemetryEnvelopes []map[string]any `json:"telemetry_envelopes"`
}

CandidateWorker

type CandidateWorker struct {
WorkerSpeciesID string `json:"worker_species_id"`
ScoreHint *float64 `json:"score_hint,omitempty"`
RequiresControlsMinimum []string `json:"requires_controls_minimum,omitempty"`
SkipReason *string `json:"skip_reason,omitempty"`
}

Escalation

type Escalation struct {
PolicyGate bool `json:"policy_gate"`
MSAVXStepUp bool `json:"msavx_step_up"`
HumanRequiredDefault bool `json:"human_required_default"`
HumanRequiredIf []map[string]any `json:"human_required_if,omitempty"`
Rationale *string `json:"rationale,omitempty"`
}

MakeDecision()

type RouterOptions struct {
// Options for future extension (controls enforcement, blast radius, etc.)
}
func MakeDecision(inp RouteInput, registry *Registry, opts RouterOptions) RouteDecision

The current stub routes to the first enrolled worker that handles the requested capability. Returns a denied decision if no worker is available. Always emits three mandatory telemetry events.


Registry

func NewRegistry() *Registry
func (r *Registry) Enroll(record WorkerRegistryRecord) error
func (r *Registry) WorkersForCapability(capabilityID string) []WorkerRegistryRecord
func (r *Registry) Get(workerID string) (WorkerRegistryRecord, bool)
func (r *Registry) AllWorkers() []WorkerRegistryRecord
func (r *Registry) AllCapabilities() []string
func (r *Registry) ControlsPresent(controlIDs []string) (bool, string)
// ControlsPresent checks whether all given control IDs are present.
// Returns (true, "") when all are present; (false, missingControlID) on first miss.
// To check if a species is available for dispatch, use WorkersForCapability() and
// check whether the returned slice is non-empty.
// To get the enrolled worker count: len(registry.AllWorkers())

WorkerRegistryRecord

type WorkerRegistryRecord struct {
WorkerID string `json:"worker_id"`
WorkerSpeciesID string `json:"worker_species_id"`
Capabilities []string `json:"capabilities"`
RiskTier string `json:"risk_tier,omitempty"`
RequiredControls []string `json:"required_controls,omitempty"`
CurrentlyImplements []string `json:"currently_implements,omitempty"`
AllowedEnvironments []string `json:"allowed_environments,omitempty"`
BlastRadius map[string]any `json:"blast_radius,omitempty"`
PrivilegeEnvelope map[string]any `json:"privilege_envelope,omitempty"`
Owner string `json:"owner,omitempty"`
Contact string `json:"contact,omitempty"`
}

WCP Compliance Status

RequirementStatus
Capability routingStub — workers enrolled via Registry
Fail-closed (unknown capability = deny)Done
Deterministic routingDone
Controls enforcementTODO
Mandatory telemetryDone — three events emitted
Dry-run supportDone
Blast radius scoringTODO
Policy gateStub — DefaultPolicyGate passes through
Evidence receiptsDone — in hello_worker example
Discovery APITODO

Full WCP-Standard and WCP-Full compliance requires completing the TODOs in router.go and policy_gate.go.


CLI

The Go CLI (pyhall) provides catalog search and worker scaffolding.

Terminal window
go install github.com/pyhall/pyhall-go/cmd/pyhall@latest
Terminal window
pyhall search "document summarization"
pyhall explain cap.doc.summarize
pyhall browse
pyhall build
pyhall version