Documentation
¶
Overview ¶
Built-in schema registrations: envelope, error object, command registry.
Purpose: the three schemas every other contract builds on. Enums, patterns and consts that Go types cannot express are Overrides whose values come from the exported constants of internal/output, internal/errs, internal/canon and internal/cmdregistry; no literal is duplicated here.
Schema registration: bundle install-state ledger (contract:cli.bundle-ledger v1, P7-PLUG-18, PLUG D6).
Purpose: schemas/bundle-ledger.v1.schema.json is generated from ledger.Ledger. Patterns, enums and the constants come from exported values of internal/bundle/ledger, never from duplicated literals. Note: a JSON Schema cannot say "_generated is the first key"; the Go reader (ledger.Parse) and its tests enforce that.
Generated schemas for the plugin catalog (contract:plugins.catalog v1) and releases.json (P7-PLUG-07).
Purpose: schemas/catalog.v1.schema.json and schemas/releases.v1.schema.json come from the Go types in tools/catalog/model, the types the generator itself reads and writes; enums, versions and the checksum pattern come from that package's exported values. Slices are never null in a written document, so the schema says `array`; the catalog's nullable keys stay nullable.
One schema per envelope command: schemas/commands/<path, spaces as ->.v1.schema.json.
Purpose: every key of cmd/commands.jsonDataTypes (read through commands.JSONDataTypes) gets a generated data schema, so a command cannot become `json: envelope` without one. cmd/commands/json_contract_test.go asserts the files and golden fixtures exist.
Schema generation for tools/schemagen.
Purpose: turn one registered Spec into the bytes of its schema file and the whole set into a name -> bytes map (schemas plus index.json).
Inputs: a *specSet. Outputs: map of path-under-schemas -> file bytes. Constraints: draft 2020-12; keys sorted (Go marshals maps in key order); 2-space indent; trailing newline; HTML never escaped; first-level $comment carries the GENERATED marker; $id is urn:nself:cli:schema:<name>:v<N>.
Schema registration: project lock nself.lock.yaml (contract:cli.lockfile v1, P7-LIVE-09, EPIC D10).
Purpose: schemas/lockfile.v1.schema.json is generated from lock.Lock. Patterns and enums come from exported values of internal/lock, never from duplicated literals. The file is YAML; the schema describes its parsed document. Its first-line header comment is not part of the document.
Command schemagen writes and checks the generated JSON Schemas under schemas/.
Purpose: one generator for every machine contract the CLI publishes (envelope, error object, command registry, each envelope command's data). Schemas are inferred from Go types with google/jsonschema-go, the library mcp-go already uses, so CLI and MCP schemas come from one place.
Inputs: -dir (default schemas), -check. Specs registered via Register. Outputs: schemas/*.json and schemas/index.json (default), or an exit status in -check mode: 0 current, 1 differs, 2 generator or I/O failure.
Constraints: -check compares only *.json files. A *.json that is neither registered nor the index fails it; a non-JSON file (schemas/embed.go from P7-SURF-30) is ignored. Read-only in -check mode.
Generated schema for nself.yaml (contract config.nself-yaml, P7-SURF-07).
Purpose: schemas/nself-yaml.v1.schema.json describes exactly what the CLI reads from nself.yaml, derived from nsbuild.ProjectManifest by reflection (the yaml tags become the property names), plus the extension rule: keys matching ^x- are allowed and ignored, at the top level and inside the plugins map. A field added to ProjectManifest or ManifestPlugins changes the output, so `schemagen -check` fails until the schema is regenerated.
Constraints: ProjectManifest carries yaml tags only, and its plugins field has a custom decoder, so the plugins property is replaced whole (list, or map with the ManifestPlugins keys) is an override. Null is accepted for every key, as a YAML decoder treats an empty value as the zero value.
Overrides for the data schemas of the read-only pilot commands (P7-REG-09).
Purpose: inference from the Go types gives `type: string` for the closed string sets and `["null","array"]` for slices. The pilots never emit null arrays and only emit the listed values, so the schemas say so.
Inputs: commands.PilotJSONEnums (the same constants the code uses). Outputs: type overrides applied to every schema generated from the pilot data types (see commands.go, which registers them). Constraints: the Go types and their JSON shape are never changed to get here; only the generated schema narrows.
Generated schema for plugin.json manifest v2 (contract plugin.manifest, P7-PLUG-01).
Purpose: schemas/plugin-manifest.v2.schema.json comes from the Go types in internal/plugin/manifestv2; enums and patterns come from that package's exported values, never from copies. Nullable pointers stay nullable only where the contract says object|null (commands, schema, migrations, seed).
Schema registration: portable bundle manifest (contract:cli.portable-export v1, P7-ADOPT-23).
Purpose: schemas/portable-export.v1.schema.json is generated from portable.Manifest. Patterns, enums and the version const come from exported values of internal/portable; arrays are never null in a written manifest (Manifest.Sort replaces nil slices), so the schema says `array`.
Schema registration: shared host proxy registration (contract:cli.shared-proxy v1, P7-ADOPT-03).
Purpose: schemas/shared-proxy.v1.schema.json is generated from sharedproxy.Registration. Lists are never null in a written file (Marshal replaces nil with []), so the schema says `array`.
Registration API for tools/schemagen (contract cli.json-schemas, P7-REG-08).
Purpose: every JSON Schema under schemas/ is generated from a Go type that is registered here, never hand-written. Later Epics add one tools/schemagen/<topic>.go file whose init() calls Register; they never edit spec.go, builtin.go or commands.go.
Inputs: Spec values passed to Register from init(). Outputs: the registered set (sorted by Out) and a list of generator problems. Constraints: Register never panics. A duplicate Out or an Out that does not match outPattern is recorded as a problem; generation and -check then fail.