Help us shape the future of Go! Take the 2026 Go Developer Survey

toolreg

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Oct 28, 2026 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

Package toolreg is the tool registry (SPEC-ADDITIONS §13): declared capabilities a stage can discover, select by what they verify, and repair. It makes the tool surface uniform and extensible instead of hard-coded.

Index

Constants

View Source
const DefaultRegistryFile = ".adh/tools.json"

DefaultRegistryFile is the conventional repo path the tool registry lives under (SPEC-ADDITIONS §13). It is the single owner of that path across the CLI.

Variables

This section is empty.

Functions

func Marshal

func Marshal(r Registry) ([]byte, error)

Marshal encodes the registry as indented JSON with a trailing newline — the on-disk form Load reads back, so the write and read sides of the registry file agree in one place.

Types

type Registry

type Registry struct {
	Tools []Tool `json:"tools"`
}

Registry is the set of declared tools.

func Load

func Load(path string) (Registry, error)

Load reads a registry from a JSON file.

func LoadRepo

func LoadRepo(repoDir string) (Registry, error)

LoadRepo reads the registry at repoDir's DefaultRegistryFile, best-effort: an absent file is an empty registry (the repository declares no tools), not an error, so a caller can surface tools without requiring the file to exist.

func StarterRegistry

func StarterRegistry() Registry

StarterRegistry is the set of external toolchain capabilities the harness knows how to orchestrate (SPEC-ADDITIONS §13): distillation (exegesis), skill optimization (skillsaw), and domain modeling (modelith). They are declared, not vendored — each Run invokes an installed binary with `--json`/`--format json` where available, so the worker runs it via `adh tool run <id>` and interprets the output in-loop. A repository seeds this via `adh init` and then tailors it; a RepairHint names the install command for a capability the operator has not yet provided. adh does not require any of them to be installed — an absent binary is reported at run time, not a registry defect.

func (Registry) FindByID

func (r Registry) FindByID(id string) (Tool, bool)

FindByID returns the tool with the given ID, so a caller that already knows a check by name (e.g. an NFR finding's Ref, §19.2) can resolve it to a command.

func (Registry) FindByVerifies

func (r Registry) FindByVerifies(verifies string) (Tool, bool)

FindByVerifies returns the first tool whose Verifies matches, so a stage selects a capability by what it proves rather than by a hard-coded command.

func (Registry) Validate

func (r Registry) Validate() error

Validate checks that every tool has an ID, a Run command, and a Verifies description, and that IDs are unique. It returns EINVALID on the first defect.

type Tool

type Tool struct {
	ID         string    `json:"id"`
	Run        string    `json:"run"`
	Result     string    `json:"result,omitempty"`
	Verifies   string    `json:"verifies"`
	RepairHint string    `json:"repair_hint,omitempty"`
	KPIs       []adh.KPI `json:"kpis,omitempty"`

	// Adjudicates is the set of finding kinds this tool can settle. Absent means
	// **unclassified, not "adjudicates nothing"** -- a registry written before this
	// field existed keeps working, and the zero value must not assert something its
	// author never said.
	Adjudicates []adh.FindingKind `json:"adjudicates,omitempty"`
	// IfAbsent is what to do without this capability, as against RepairHint's how to
	// obtain it. Those are different questions and the second is the one that matters
	// where the tool cannot be installed. Authored per tool, because whoever declared
	// the capability knows what its absence costs.
	IfAbsent string `json:"if_absent,omitempty"`
}

Tool is one declared capability: how to run it, the shape of its result, what it verifies, the hint printed when it fails, and any KPIs whose degradation proposes a change to the tool (§16/§18). **Verifies stays free prose and Adjudicates is the machine-matchable axis.** The emitted prompts offer a capability by what it verifies, and the nuance is what makes it selectable -- a model choosing between capabilities is better served by "reference integrity (cardinality, ownership, cycles, dangling refs)" than by any token standing in for it. So the stable layer (what it verifies) and the volatile layer (the command) are already separated, and porting edits this registry rather than a prompt.

What prose cannot do is let adh *require* a capability. Adjudicates reuses adh.FindingKinds -- a closed set with one owner, already the axis the coverage and noisy-kind ledgers are computed over -- rather than inventing a second vocabulary over the same space, which would be the duplicate-classification mistake refused elsewhere in this family and would have no principle for who may add a member.

Jump to

Keyboard shortcuts

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