1package typesafe23import (4 "encoding/json/jsontext"5 jsonv2 "encoding/json/v2"6 "fmt"7)89// SystemOneRequest contains state and named questions to evaluate.10type SystemOneRequest struct {11 State any `json:"state"`12 Questions map[string]Question `json:"questions"`13 Model string `json:"model,omitempty"`14}1516// Validate checks the locally enforceable System One request constraints.17func (r SystemOneRequest) Validate() error {18 if kind, err := topLevelKind(r.State); err != nil {19 return fmt.Errorf("state: %w", err)20 } else if kind == 'n' {21 return fmt.Errorf("state is required and must not be null")22 }23 if len(r.Questions) == 0 {24 return fmt.Errorf("questions must contain at least one question")25 }26 for name, question := range r.Questions {27 if name == "" {28 return fmt.Errorf("question name must not be empty")29 }30 if err := validateQuestion(name, question); err != nil {31 return err32 }33 }34 return nil35}3637func validateTopLevelValue(value any) error {38 _, err := topLevelKind(value)39 return err40}4142// topLevelKind validates that value encodes as a JSON string, object, array,43// or null, and returns its kind so callers can apply stricter rules.44func topLevelKind(value any) (jsontext.Kind, error) {45 encoded, err := jsonv2.Marshal(value)46 if err != nil {47 return 0, fmt.Errorf("must be valid JSON: %w", err)48 }49 kind := jsontext.Value(encoded).Kind()50 if kind != 'n' && kind != '"' && kind != '{' && kind != '[' {51 return 0, fmt.Errorf("must be a JSON string, object, array, or null")52 }53 return kind, nil54}