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

canon

package
v1.4.13 Latest Latest
Warning

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

Go to latest
Published: Oct 11, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package canon holds the declared command canon: the embedded side table that records what cobra cannot know about a command (canon status, side-effect class, output kind, JSON support, state exit codes and flag escalations).

Purpose: contract:cli.command-registry v1 input and producer of

contract:cli.canon-fragments v1. canon.yaml keeps the schema version
and the core verbs; every command entry lives in
domains/<domain>.yaml (one fragment per domain, ADR 0016).

Inputs: canon.yaml and domains/*.yaml compiled into the binary

(go:embed), an fs.FS (LoadFS, fixtures) or bytes (Parse).

Outputs: Load: the registry view for the running compat mode; LoadRaw: the

merged raw data (canonical paths plus the move rows); both validated.
Tree-dependent rules (completeness, flag existence, targets) are
checked by internal/cmdregistry.Build.

Constraints: stdlib + gopkg.in/yaml.v3 + internal/compat only (Constitution

2.1, L0). Decoding is strict: an unknown key is an error.

Index

Constants

View Source
const (
	// CanonCore marks one of the ADR 0016 verbs.
	CanonCore = "core"
	// CanonSubcommand marks a command at depth >= 2 (the default there).
	CanonSubcommand = "subcommand"
	// CanonPlugin is reserved for plugin-mounted commands; no cobra-native
	// command may carry it.
	CanonPlugin = "plugin"
	// CanonShim marks a hidden alias kept for the deprecation window; its
	// Target names the canonical path.
	CanonShim = "deprecated-shim"
	// CanonPending marks a top-level command outside the canon whose
	// disposition P7-CANON decides.
	CanonPending = "pending"
	// CanonBuiltin marks framework-provided commands (help); not counted
	// against the canon.
	CanonBuiltin = "builtin"
)

Canon status values (Epic P7-REG D4).

View Source
const (
	SideEffectRead        = "read"
	SideEffectWrite       = "write"
	SideEffectRemote      = "remote"
	SideEffectDestructive = "destructive"
)

Side-effect classes (D5), in total order read < write < remote < destructive.

View Source
const (
	OutputDocument    = "document"
	OutputStream      = "stream"
	OutputInteractive = "interactive"
)

Output kinds (D6).

View Source
const (
	JSONEnvelope = "envelope"
	JSONLegacy   = "legacy"
	JSONNone     = "none"
)

JSON support values (D7).

View Source
const GeneratedMarker = "// GENERATED BY tools/canongen — DO NOT HAND EDIT"

GeneratedMarker is the first line of the generated move table.

View Source
const MaxVerbs = 20

MaxVerbs is the ceiling on the core verb list (ADR 0016, VMI). It is a ceiling, not a target: the list may hold fewer verbs, never more.

View Source
const ModeV14 = "v1.4"

ModeV14 is the only value of an entry's `mode`: the entry exists only in v1.4 mode.

View Source
const SchemaVersion = 1

SchemaVersion is the only canon.yaml schema version this package accepts.

Variables

View Source
var RequiredFragments = []string{
	"lifecycle", "build", "io", "observe", "config", "account", "data",
	"deploy", "services", "extend", "mcp", "breakouts", "admin",
}

RequiredFragments are the fragments the embedded canon must contain (EPIC P7-CANON contract table). Later Tickets add fragments; none may remove these.

Functions

func Depth

func Depth(key string) int

Depth returns the number of words in a command key ("config get" is 2).

func NewValidationError

func NewValidationError(problems []string) error

NewValidationError returns nil for no problems, else a *ValidationError with the problems sorted so the message is deterministic.

func Rank

func Rank(sideEffect string) int

Rank returns the position of a side-effect class in the total order read(0) < write(1) < remote(2) < destructive(3), or -1 for an unknown value.

func RenderGoTable

func RenderGoTable(f *File) []byte

RenderGoTable renders the Go source of the move table for f.

func ValidCanon

func ValidCanon(s string) bool

ValidCanon reports whether s is one of the six canon status values.

func ValidJSON

func ValidJSON(s string) bool

ValidJSON reports whether s is one of the three JSON support values.

func ValidOutput

func ValidOutput(s string) bool

ValidOutput reports whether s is one of the three output kinds.

Types

type Breakout

type Breakout struct {
	From   string `yaml:"from"`
	Plugin string `yaml:"plugin"`
	To     string `yaml:"to"`
	Since  string `yaml:"since"`
}

Breakout is a core command that moves to a plugin.

type Confirm

type Confirm struct {
	Flags []string  `yaml:"flags"`
	Plan  *PlanForm `yaml:"plan"`
}

Confirm declares local or inherited flags accepted as confirmation.

type Entry

type Entry struct {
	// Canon is the status (D4). Empty means subcommand at depth >= 2.
	Canon string `yaml:"canon"`
	// Target is the canonical path (without "nself ") a deprecated-shim runs.
	Target string `yaml:"target"`
	// SideEffect is the class of running the command with default flags (D5).
	SideEffect string `yaml:"side_effect"`
	// Output is the output kind (D6); empty means document.
	Output string `yaml:"output"`
	// JSON is the pre-contract JSON support, legacy or none (D7). "envelope"
	// is never declared: it is derived from the registered data types.
	JSON string `yaml:"json"`
	// ExitCodes documents state exit codes in v1.4 mode (keys "0".."125").
	ExitCodes map[string]string `yaml:"exit_codes"`
	// ExitCodesV15 documents state exit codes in v1.5 mode (D10).
	ExitCodesV15 map[string]string `yaml:"exit_codes_v15"`
	// Flags maps a flag name to the escalation it causes when set.
	Flags      map[string]FlagOverride `yaml:"flags"`
	Confirm    *Confirm                `yaml:"confirm"`
	Surface    string                  `yaml:"surface"`
	SecretArgs []string                `yaml:"secret_args"`
	// Mode is empty (the entry exists in both modes) or "v1.4" (it exists only
	// in v1.4 mode: break-outs, removed commands, shim and retired-hub sources).
	Mode string `yaml:"mode"`
}

Entry is the declared data for one command.

type File

type File struct {
	// SchemaVersion is the canon.yaml schema version (1).
	SchemaVersion int `yaml:"schema_version"`
	// Verbs lists the ADR 0016 core verbs in ADR order (at most MaxVerbs).
	Verbs []string `yaml:"verbs"`
	// Commands maps a command path without the leading "nself " to its entry.
	Commands map[string]Entry `yaml:"commands"`
	// Rows are the move rows of contract:cli.canon-fragments v1.
	Rows `yaml:",inline"`
	// contains filtered or unexported fields
}

File is the decoded canon.yaml document.

func Effective

func Effective(v15 bool) (*File, error)

Effective returns the registry view for a compat mode (see (*File).View), built from LoadRaw and memoised per mode. The result is read-only.

func Load

func Load() (*File, error)

Load returns the registry view of the running compat mode, so every registry caller sees the right surface without knowing about modes. Callers must treat the returned *File as read-only.

func LoadFS

func LoadFS(fsys fs.FS) (*File, error)

LoadFS loads canon.yaml and every domains/*.yaml of fsys (lexical order), merges them and validates the result. It is the loader behind LoadRaw and the entry point for fixtures. A failure returns one aggregated *ValidationError (or a decode error for canon.yaml itself) naming file and path.

func LoadRaw

func LoadRaw() (*File, error)

LoadRaw parses and validates the embedded canon.yaml and domains/*.yaml and returns the merged raw data: keys are canonical (v1.5) paths and the move rows are present. The result is memoised and read-only. tools/canongen and tests use it; the registry uses Load.

func Parse

func Parse(data []byte) (*File, error)

Parse strictly decodes canon.yaml bytes (unknown keys are errors) and validates the result. On a validation failure the error is a *ValidationError naming every offending path.

func (*File) Validate

func (f *File) Validate() error

Validate checks every rule that needs only the declared data. Rules that need the cobra tree live in internal/cmdregistry.Build. It returns nil or a *ValidationError.

func (*File) View

func (f *File) View(v15 bool) (*File, error)

View returns the registry view for a compat mode. A rule violation (a generated shim colliding with a command, a `to` that is missing or a shim, two entries mapping onto one v1.4 path) is returned as a *ValidationError.

type FlagOverride

type FlagOverride struct {
	// SideEffect escalates the command's class; it must outrank the command's.
	SideEffect string `yaml:"side_effect"`
	// JSON overrides the command's JSON support: legacy or none.
	JSON string `yaml:"json"`
	// Output is empty or "stream" (D6, invalidation 2026-09-30): the only
	// flag-level output value, allowed on a command whose output is document.
	Output  string `yaml:"output"`
	CLIOnly bool   `yaml:"cli_only"`
	Secret  bool   `yaml:"secret"`
}

FlagOverride is what setting a flag changes about its command.

type Fragment

type Fragment struct {
	SchemaVersion int              `yaml:"schema_version"`
	Commands      map[string]Entry `yaml:"commands"`
	Rows          `yaml:",inline"`
}

Fragment is the decoded form of one domains/<name>.yaml.

type Hub

type Hub struct {
	Path    string `yaml:"path"`
	Summary string `yaml:"summary"`
}

Hub is a non-runnable command group created in v1.5 mode.

type PlanForm

type PlanForm struct {
	Flag   string `yaml:"flag"`
	IDFlag string `yaml:"id_flag"`
}

PlanForm identifies the flag pair used for plan/apply confirmation.

type Removed

type Removed struct {
	From    string `yaml:"from"`
	Since   string `yaml:"since"`
	Message string `yaml:"message"`
}

Removed is a command removed without replacement.

type Row

type Row struct {
	From string `yaml:"from"`
	To   string `yaml:"to"`
	// Since is the release that introduces the new spelling (vX.Y.Z).
	Since string `yaml:"since"`
	// RemovalAt is the release that removes the old spelling (vX.Y.Z, after Since).
	RemovalAt string `yaml:"removal_at"`
	// Equivalence names the Go test proving a shim equals its target (shims only).
	Equivalence string `yaml:"equivalence"`
}

Row is one move, shim or retired-hub row.

type Rows

type Rows struct {
	// Hubs are non-runnable hubs the engine creates in v1.5 mode.
	Hubs []Hub `yaml:"hubs"`
	// Moves relocate a command with its subtree (From old path, To canonical).
	Moves []Row `yaml:"moves"`
	// Shims replace an old command with a forward to an equivalent command.
	Shims []Row `yaml:"shims"`
	// RetiredHubs turn an emptied old hub into a stub forwarding to To.
	RetiredHubs []Row `yaml:"retired_hubs"`
	// Builtins are hidden framework commands (canon builtin in v1.5).
	Builtins []string `yaml:"builtins"`
	// Breakouts leave the core tree for a plugin in v1.5 mode.
	Breakouts []Breakout `yaml:"breakouts"`
	// Removed lists commands removed in v1.5 with the message to print.
	Removed []Removed `yaml:"removed"`
}

Rows are the lists of contract:cli.canon-fragments v1 that describe how the v1.4 surface maps to the v1.5 surface. A fragment and the merged File both carry them. Paths are command paths without the leading "nself ".

type Table

type Table struct {
	Verbs       []string
	Moves       []TableRow
	Shims       []TableRow
	RetiredHubs []TableRow
	Hubs        []TableRow
	Builtins    [][]string
	Breakouts   []TableRow
	Removed     []TableRow
}

Table is the engine's view of the raw canon: no YAML, no maps, token slices.

func BuildTable

func BuildTable(f *File) Table

BuildTable turns the raw canon into a Table. Rows of each list are sorted by prefix length (longest first), then lexically, so a reader scanning the list meets the most specific row first.

type TableRow

type TableRow struct {
	From      []string
	To        []string
	Since     string
	RemovalAt string
	Plugin    string // breakouts: the plugin that now owns the command
	Message   string // removed: the text E410 prints
	Summary   string // hubs: the one-line summary (From holds the hub path)
}

TableRow is one row of the table. From and To are command tokens without the leading "nself ". Which fields are set depends on the list the row is in.

type ValidationError

type ValidationError struct {
	// Problems are sorted, one per violated rule instance.
	Problems []string
}

ValidationError aggregates every problem found in one validation pass. Each problem names the offending path (for example `commands["config get"]`).

func (*ValidationError) Error

func (e *ValidationError) Error() string

Error renders every problem, one per line.

Jump to

Keyboard shortcuts

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