Documentation
¶
Overview ¶
Package strictjson is the ONE strict request decoder: every JSON request root Pulse accepts — the CLI request files, the MCP tool arguments, a Compose sweep body, a for_each item and a rendered request template — decodes through it, so an unknown key anywhere in the document is refused the same way on every path.
The decode is encoding/json with DisallowUnknownFields semantics, but the refusal is located: before decoding, the raw document is walked against the target type's reflected json tags, and the FIRST object carrying an unrecognised key (an object's own keys before its children's, children in document order) is reported with its path (`sort[0]`, `crosstab.cell`, indexes included), the offending keys, the object's valid keys and a nearest-key suggestion. The standard library's own error names the key alone.
Leaf package: stdlib + types + errors only, so internal/descriptor (no-execute), internal/service, internal/cli, internal/mcp, internal/sweep and internal/template can all import it (TestStrictJSON_ImportBoundary).
Index ¶
- Constants
- func Decode[T any](raw []byte, opts Options) (T, error)
- func DecodeInto(raw []byte, out any, opts Options) error
- func Levenshtein(a, b string) int
- func NearestKey(k string, candidates []string) string
- func UnknownFieldError(objectPath string, unknown, valid []string) *perr.CodedError
- func UnknownFieldErrorAliased(objectPath string, unknown, valid []string, aliases map[string]string) *perr.CodedError
- func UnknownFieldName(err error) (string, bool)
- type Options
- type Unknown
Constants ¶
const ( LocationRequest = "request" // ComposedRequest.requests[i] LocationFit = "fit" // ComposedRequest.fits[i].request LocationStage = "stage" // ChainRequest.stages[i].request )
Location detail keys for an unknown key inside a nested request: the service's located-refusal keys (descx.RefusalAt), so a JSON caller and a library caller see the same details for the same request.
const MetaKey = "_meta"
MetaKey is the example sidecar block (`internal/examples/`) a request file may carry at its root; Options.AllowMeta tolerates it there.
Variables ¶
This section is empty.
Functions ¶
func DecodeInto ¶
DecodeInto strictly decodes raw into out (a non-nil pointer). An unrecognised or hidden key anywhere is a *errors.CodedError PULSE_REQUEST_UNKNOWN_FIELD (UnknownFieldError's shape, located); any other fault (malformed JSON, a wrong-typed value) is the encoding/json error, unchanged, for the caller to wrap.
func Levenshtein ¶
Levenshtein is the rune-level edit distance between a and b.
func NearestKey ¶
NearestKey returns the closest candidate to k by Levenshtein distance, or "" when no candidate is close enough. The acceptance threshold is edit distance < 4, further capped at the key length, so short or unrelated keys do not yield a misleading suggestion. Ties keep the earliest candidate.
func UnknownFieldError ¶
func UnknownFieldError(objectPath string, unknown, valid []string) *perr.CodedError
UnknownFieldError builds THE PULSE_REQUEST_UNKNOWN_FIELD refusal for the unrecognised keys unknown of the object at objectPath inside a request ("" = the request root; "sort[0]", "crosstab.cell", ...), against that object's valid keys. Nil when unknown is empty.
details: unknown_keys (sorted), suggestions (unknown key → nearest valid key, when one is close), valid_keys (sorted) and, below the root, path — the location of the first offending key (`sort[0].direction`). The message names the object and both lists. The strict decoder and the instance slot gate (descx.SlotRefusal) both build it here, so an unknown key and a hidden slot cannot drift.
func UnknownFieldErrorAliased ¶
func UnknownFieldErrorAliased(objectPath string, unknown, valid []string, aliases map[string]string) *perr.CodedError
UnknownFieldErrorAliased is UnknownFieldError with known misnomers: an unknown key found in aliases is suggested as its alias (a valid key no edit distance would reach — GROUP_DATE params.unit is params.component), ahead of the nearest-key guess.
func UnknownFieldName ¶
UnknownFieldName extracts the key from encoding/json's DisallowUnknownFields fault; ok reports whether err was that fault.
Types ¶
type Options ¶
type Options struct {
// Hidden returns the keys of struct type t the calling instance
// hides (a feature-profile-gated slot). A hidden key is refused
// exactly as an unknown one and never appears in valid_keys or a
// suggestion. Nil hides nothing.
Hidden func(t reflect.Type) []string
// AllowMeta tolerates a `_meta` key at the document root (the
// examples sidecar block), as the lenient decode always did. A
// rendered template leaves it false: there `_meta` is refused.
AllowMeta bool
// DocumentOrder reports the first unknown key in document order,
// depth first — the key encoding/json's DisallowUnknownFields names
// (a rendered template's contract). The default reports an object's
// own keys before any child's, so a request root's misspelled slot
// is refused before anything nested inside it (descx.SlotRefusal's
// order).
DocumentOrder bool
// Aliases returns known misnomers for struct type t's keys — an
// unknown key mapped to the valid key no edit distance would reach
// (a synth correlation's `correlation` is `rho`). The refusal
// suggests the alias ahead of the nearest-key guess
// (UnknownFieldErrorAliased). Nil aliases nothing.
Aliases func(t reflect.Type) map[string]string
}
Options tunes one decode.
type Unknown ¶
type Unknown struct {
// Path is the object's location relative to the innermost request
// (Location resets it): "" for that request's root, else e.g.
// "sort[0]" or "crosstab.cell".
Path string
// FullPath is the object's location from the document root.
FullPath string
// Keys are the unrecognised (or hidden) keys, sorted.
Keys []string
// First is the object's first unrecognised key in document order.
First string
// Valid are the object's visible keys, in declaration order.
Valid []string
// Type is the object's struct type.
Type reflect.Type
// LocationKey / LocationIndex name the nested request Path is
// relative to (LocationRequest / LocationFit / LocationStage and
// its index); LocationKey is "" outside a nested request.
LocationKey string
LocationIndex int
// Aliases are Options.Aliases for Type, carried to the refusal.
Aliases map[string]string
}
Unknown is the first object carrying unrecognised keys.
func Check ¶
Check walks raw against type t (a pointer chain is dereferenced) and returns the first object carrying an unrecognised or hidden key, or nil. Malformed JSON yields nil: the decode reports it.
func (*Unknown) Error ¶
func (u *Unknown) Error() *perr.CodedError
Error converts u into the PULSE_REQUEST_UNKNOWN_FIELD refusal, located by details[LocationKey] when u sits in a nested request.
func (*Unknown) FullKeyPath ¶
FullKeyPath is KeyPath from the document root.