Documentation
¶
Overview ¶
Package schemagen generates the run-bundle format v1's JSON Schema (formats/run-bundle/v1/schema.json) from the sdk package's own Go types, via reflection (github.com/invopop/jsonschema), so the Go types stay the format's single source of truth — nobody hand-maintains a second description of the wire shape that can drift from it.
Plain reflection is not quite faithful to this module's actual encoding, for two documented reasons Generate corrects:
- $defs key stability: the published schema's $defs keys were minted when the wire types lived across several runtime packages (platform.JournalEntry -> "PlatformJournalEntry", campaign.Evidence -> "CampaignEvidence", ...). Now that every wire type lives in the single sdk package, reflecting names naively would mint different keys and silently change the published schema. defsName (via Reflector.Namer) pins every $defs key to its published value through an explicit table, and panics on any named struct/map type the table does not know — so an accidental new type can never silently join the wire.
- Nullable non-omitempty slices, maps and pointers: every exported field reaching bundle JSON (Goal, JournalEntry, Observation, DataStateEvidence, ...) carries an explicit lower-camel-case `json` tag — the whole run-bundle wire is uniformly camelCase — but most of those tags carry no `omitempty` option, so encoding/json's default behaviour still applies to presence: a nil slice, map or pointer field with no `omitempty` marshals as JSON null, not as that field's "empty" form ([], {} or an absent property). This is the everyday, common case (e.g. any Task with no DependsOn), not a corner case, and it shows up throughout the golden bundle ("actions": null, "changes": null, ...). invopop/jsonschema has no notion of this at all — a plain reflected schema types every one of these fields as a bare "array"/"object", which would reject a huge share of bundles the runtime's own code legitimately produces. applyNullablePatches walks the real Go type graph reachable from sdk.Bundle (mirroring encoding/json's own tag rules, reading each field's tagged name rather than falling back to its exported Go name) and widens every such field to also accept null.
See Generate.
Index ¶
Constants ¶
const SchemaID = "https://chatwright.dev/formats/run-bundle/v1/schema.json"
SchemaID is the run-bundle format v1 JSON Schema's own "$id" — the schema's stable, dereferenceable identity. Distinct from sdk.FormatV1 (the Bundle document's own "format" field): SchemaID names the schema document itself, FormatV1 names the wire shape a Bundle instance claims to follow.
Variables ¶
This section is empty.
Functions ¶
func Generate ¶
func Generate() (*jsonschema.Schema, error)
Generate builds the run-bundle format v1 JSON Schema (draft 2020-12) from sdk.Bundle's Go types. See the package doc comment for the two documented corrections applied on top of plain reflection.
func Marshal ¶
func Marshal(schema *jsonschema.Schema) ([]byte, error)
Marshal renders schema as indented JSON terminated by a trailing newline — the same convention sdk.Write uses for the JSON it produces, so the committed schema file is reviewable in a PR diff like any other artefact in this repository.
Types ¶
This section is empty.