harness

package
v0.6.1 Latest Latest
Warning

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

Go to latest
Published: Nov 3, 2026 License: Apache-2.0 Imports: 8 Imported by: 0

Documentation

Overview

Package harness defines the adapter contract every AI coding CLI implements. An adapter turns a resolved policy.Profile into the files that CLI reads as admin-enforced configuration, per OS.

Index

Constants

View Source
const (
	InstallerNPM          = "npm"           // npm package tarball (Meta.NPMPackage)
	InstallerClaudeNative = "claude-native" // Anthropic's signed native-binary manifest
)

Installer kinds for Meta.Installer.

Variables

This section is empty.

Functions

func Matrix

func Matrix() map[string][]Capability

Matrix returns the capability set of every registered adapter, keyed by adapter name. Adapters register from init(), so callers must import internal/harness/all (or the adapters they need) first.

func Names

func Names() []string

Names lists registered adapters, sorted.

func Override

func Override(a Adapter) (restore func())

Override replaces (or adds) the adapter registered under a.Name() and returns a func restoring the previous state. For tests that stand in for a real adapter in a binary that also links the real ones; not concurrency-safe.

func Register

func Register(a Adapter)

Register adds an adapter; called from adapter init().

Types

type Adapter

type Adapter interface {
	Name() string
	Capabilities() []Capability
	// Render returns the admin-enforced files for the profile. Unsupported
	// profile fields must be reported as warnings, never silently dropped.
	Render(p *policy.Profile, c Context) (files []File, warnings []string, err error)
	// InstallCommand returns the shell command that installs exactly version on os.
	InstallCommand(version string, os OS) string
}

Adapter renders one harness.

func Get

func Get(name string) (Adapter, bool)

Get returns an adapter by name.

type Capability

type Capability string

Capability is something an adapter can enforce centrally.

const (
	CapVersionPin   Capability = "version-pin"   // CLI refuses to run outside the pinned version
	CapModelLock    Capability = "model-lock"    // restrict selectable models
	CapMCPAllowlist Capability = "mcp-allowlist" // restrict MCP servers
	CapHooksLock    Capability = "hooks-lock"    // only managed hooks run
	CapPermissions  Capability = "permissions"   // tool allow/deny rules
	CapGateway      Capability = "gateway"       // route traffic through a custom base URL
	CapTelemetry    Capability = "telemetry"     // OTEL export
	CapInstructions Capability = "instructions"  // managed org-wide memory file
	CapHeaders      Capability = "headers"       // custom request headers (ring stamping)
	CapExtensions   Capability = "extensions"    // plugin marketplaces, plugins, skills, subagents (each adapter covers a subset; the rest warns)
	CapSandbox      Capability = "sandbox"       // managed sandbox for shell commands (ADR-0032; paths and modes vary, the rest warns)
	CapEgress       Capability = "egress"        // per-domain network allow/deny for shell commands (ADR-0032)
)

type Context

type Context struct {
	Gateway *policy.Gateway
	Ring    string
	Release string // release digest or version label, stamped into headers/telemetry
	OS      OS
	// Experiment/Variant are set when rendering a client-axis variant release;
	// adapters stamp them into telemetry resource attributes (halo.experiment,
	// halo.variant) so CLI metrics are attributed to the variant. Never sent as
	// request headers: the gateway assigns and stamps x-halo-* itself.
	Experiment string
	Variant    string
}

Context carries everything an adapter needs beyond the profile.

type Describer

type Describer interface {
	Meta() Meta
}

Describer is implemented by adapters that publish Meta.

type File

type File struct {
	// Path is absolute on the target OS.
	Path string
	Mode uint32
	Data []byte
	// Artifact and ArtifactPath are set on a file that is part of a
	// supply-chain artifact (ADR-0028): the artifact's name and the file's
	// path inside it, which halod checks against the artifact's pinned digest.
	Artifact, ArtifactPath string
}

File is one rendered artifact.

type Finding added in v0.4.0

type Finding struct {
	Problem string `json:"problem"`
	Fix     string `json:"fix"`
}

Finding is one local setting that weakens the managed posture, with the fix.

type Meta

type Meta struct {
	Binary     string   // executable name, probed with `--version`
	Installer  string   // InstallerNPM | InstallerClaudeNative | "" (no verified installer)
	NPMPackage string   // npm package name when Installer is InstallerNPM
	UAPrefixes []string // lower-case User-Agent prefixes the CLI sends (none = never seen at the gateway)
	// ManagedDirs are the admin config directories (per OS) the adapter's
	// rendered files live under; halod refuses to write anywhere else.
	ManagedDirs map[OS][]string
	// ManagedFiles are single-file path.Match patterns outside ManagedDirs.
	ManagedFiles map[OS][]string
}

Meta is optional per-adapter metadata that install and traffic code derive their harness lists from, so adding an adapter needs no edits elsewhere.

func MetaOf

func MetaOf(name string) (Meta, bool)

MetaOf returns the Meta of a registered adapter, if it publishes one.

type OS

type OS string

OS is a target platform for rendered files.

const (
	Darwin  OS = "darwin"
	Linux   OS = "linux"
	Windows OS = "windows"
)

type Posture added in v0.4.0

type Posture struct {
	Harness  string    `json:"harness"`
	Sandbox  string    `json:"sandbox"` // human summary, e.g. "on (managed)", "not managed"
	Egress   string    `json:"egress"`
	Managed  bool      `json:"managed"` // the managed file turns the sandbox or egress rules on
	Findings []Finding `json:"findings,omitempty"`
}

Posture is a harness's effective sandbox and egress posture on one device (ADR-0032): what its managed file turns on, plus the per-user settings that weaken it. halod reports Findings as drift; halo doctor prints all of it.

func ReadPosture added in v0.4.0

func ReadPosture(name string, os OS, home string, read func(string) ([]byte, error)) Posture

ReadPosture reads name's managed file and, when home is set, the per-user files under it, through read (an absolute path; halod prefixes its root). A per-user weakening is a Finding only while the managed file turns the sandbox or egress rules on (Cursor, which has no managed file, always).

Directories

Path Synopsis
Package all registers every built-in harness adapter via blank imports.
Package all registers every built-in harness adapter via blank imports.
Package claudecode renders Claude Code's managed settings.
Package claudecode renders Claude Code's managed settings.
Package codex renders OpenAI Codex CLI admin configuration.
Package codex renders OpenAI Codex CLI admin configuration.
Package copilot renders GitHub Copilot CLI file-based enterprise managed settings (managed-settings.json).
Package copilot renders GitHub Copilot CLI file-based enterprise managed settings (managed-settings.json).
Package cursor renders Cursor CLI (cursor-agent) enterprise hooks: the system-wide hooks.json is the one root-owned, admin-controlled file the CLI reads.
Package cursor renders Cursor CLI (cursor-agent) enterprise hooks: the system-wide hooks.json is the one root-owned, admin-controlled file the CLI reads.
Package gemini renders Gemini CLI system settings.
Package gemini renders Gemini CLI system settings.
Package hutil holds helpers shared by harness adapters.
Package hutil holds helpers shared by harness adapters.
hutiltest
Package hutiltest provides a shared rich fixture and golden-file helper for adapter tests.
Package hutiltest provides a shared rich fixture and golden-file helper for adapter tests.
Package opencode renders OpenCode (sst/opencode, npm "opencode-ai") managed configuration: an opencode.json in the system managed-config directory, which OpenCode loads at the highest precedence.
Package opencode renders OpenCode (sst/opencode, npm "opencode-ai") managed configuration: an opencode.json in the system managed-config directory, which OpenCode loads at the highest precedence.

Jump to

Keyboard shortcuts

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