From 8977096f6d41ce035c886ad1b1df028f58acbcb6 Mon Sep 17 00:00:00 2001 From: Jennifer Power Date: Fri, 20 Mar 2026 16:01:41 -0400 Subject: [PATCH 1/2] feat: updates to gemara v1.0.0-rc.1 Signed-off-by: Jennifer Power --- Makefile | 2 +- cmd/oscalexport/export/export_test.go | 4 +- control_catalog_yaml.go | 5 +- enums.go | 70 ++- enums_test.go | 135 ++++- generated_types.go | 800 +++++++++----------------- guidance_catalog_yaml.go | 11 +- guideline_yaml.go | 25 +- 8 files changed, 479 insertions(+), 573 deletions(-) diff --git a/Makefile b/Makefile index b32f7c9..017499d 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ GOFLAGS := COVERFILE := coverage.out TESTCOVERAGE_THRESHOLD := 71 GOLANGCI_LINT := golangci-lint -SPECVERSION := v0.23.0 +SPECVERSION := v1.0.0-rc.1 .PHONY: all tidy fmtcheck fmt vet lint test testcov race coverage-check build install generate ci-local clean help diff --git a/cmd/oscalexport/export/export_test.go b/cmd/oscalexport/export/export_test.go index 97cb3ae..6cd0230 100644 --- a/cmd/oscalexport/export/export_test.go +++ b/cmd/oscalexport/export/export_test.go @@ -13,7 +13,7 @@ import ( func TestGuidance(t *testing.T) { tempDir := t.TempDir() -mockYAML := ` + mockYAML := ` metadata: id: Test title: Test @@ -74,7 +74,7 @@ guidelines: func TestCatalog(t *testing.T) { tempDir := t.TempDir() -mockYAML := ` + mockYAML := ` metadata: id: Test title: Test diff --git a/control_catalog_yaml.go b/control_catalog_yaml.go index d30a116..c42e149 100644 --- a/control_catalog_yaml.go +++ b/control_catalog_yaml.go @@ -9,10 +9,10 @@ func (c *ControlCatalog) UnmarshalYAML(data []byte) error { Groups []Group `yaml:"groups,omitempty"` Families []Group `yaml:"families,omitempty"` - Title string `yaml:"title"` + Title string `yaml:"title"` Metadata Metadata `yaml:"metadata"` - Extends []ArtifactMapping `yaml:"extends,omitempty"` + Extends []ArtifactMapping `yaml:"extends,omitempty"` Imports []MultiEntryMapping `yaml:"imports,omitempty"` Controls []Control `yaml:"controls,omitempty"` @@ -38,4 +38,3 @@ func (c *ControlCatalog) UnmarshalYAML(data []byte) error { return nil } - diff --git a/enums.go b/enums.go index bbb6a66..267e97b 100644 --- a/enums.go +++ b/enums.go @@ -54,6 +54,12 @@ type RiskAppetite int // ModType defines the type of modification to the assessment requirement. type ModType int +// ResultType defines the nature of an audit result +type ResultType int + +// EvidenceType categorizes the kind of evidence referenced in an audit +type EvidenceType string + const ( NotRun Result = iota Passed @@ -127,7 +133,8 @@ const ( ) const ( - DispositionEnforced Disposition = iota + DispositionUndetermined Disposition = iota + DispositionEnforced DispositionTolerated DispositionClear ) @@ -161,6 +168,13 @@ const ( ModOverride ) +const ( + ResultObservation ResultType = iota + ResultStrength + ResultFinding + ResultGap +) + var ( toString = map[Result]string{ NotRun: "Not Run", @@ -307,15 +321,17 @@ var ( } dispositionToString = map[Disposition]string{ - DispositionEnforced: "Enforced", - DispositionTolerated: "Tolerated", - DispositionClear: "Clear", + DispositionUndetermined: "Undetermined", + DispositionEnforced: "Enforced", + DispositionTolerated: "Tolerated", + DispositionClear: "Clear", } stringToDisposition = map[string]Disposition{ - "Enforced": DispositionEnforced, - "Tolerated": DispositionTolerated, - "Clear": DispositionClear, + "Undetermined": DispositionUndetermined, + "Enforced": DispositionEnforced, + "Tolerated": DispositionTolerated, + "Clear": DispositionClear, } severityToString = map[Severity]string{ @@ -375,6 +391,20 @@ var ( "Replace": ModReplace, "Override": ModOverride, } + + resultTypeToString = map[ResultType]string{ + ResultObservation: "Observation", + ResultStrength: "Strength", + ResultFinding: "Finding", + ResultGap: "Gap", + } + + stringToResultType = map[string]ResultType{ + "Observation": ResultObservation, + "Strength": ResultStrength, + "Finding": ResultFinding, + "Gap": ResultGap, + } ) // enumStringer is used by marshal helpers. Implemented by all string-backed enums. @@ -802,6 +832,32 @@ func (m *ModType) UnmarshalJSON(data []byte) error { return unmarshalJSONEnum(data, stringToModType, "ModType", m) } +func (r ResultType) String() string { + if r, ok := resultTypeToString[r]; ok { + return r + } + return fmt.Sprintf("ResultType(%d)", r) +} +func (r ResultType) MarshalYAML() (interface{}, error) { return marshalYAMLString(r) } + +func (r ResultType) MarshalJSON() ([]byte, error) { return marshalJSONString(r) } + +func (r *ResultType) UnmarshalYAML(data []byte) error { + return unmarshalYAMLEnum(data, stringToResultType, "ResultType", r) +} + +func (r *ResultType) UnmarshalJSON(data []byte) error { + return unmarshalJSONEnum(data, stringToResultType, "ResultType", r) +} + +// ToArtifactType converts an EvidenceType to the corresponding ArtifactType. +func (e EvidenceType) ToArtifactType() (ArtifactType, error) { + if at, ok := stringToArtifactType[string(e)]; ok { + return at, nil + } + return 0, unknownEnumStringError("ArtifactType", string(e), stringToArtifactType) +} + // UpdateAggregateResult compares the current result with the new result and returns the most severe of the two. func UpdateAggregateResult(previous Result, new Result) Result { if new == NotRun { diff --git a/enums_test.go b/enums_test.go index 75a03d0..c6a695f 100644 --- a/enums_test.go +++ b/enums_test.go @@ -1,6 +1,7 @@ package gemara import ( + "encoding/json" "strings" "testing" ) @@ -364,6 +365,48 @@ func TestEntityTypeString(t *testing.T) { } } +func TestResultStringUnknownValue(t *testing.T) { + // Out-of-range or unknown int should not return empty string + const unknown Result = 99 + got := unknown.String() + if got == "" { + t.Error("String() for unknown Result should not return empty string") + } + if !strings.Contains(got, "99") { + t.Errorf("String() for unknown Result should include numeric value, got %q", got) + } +} + +func TestResultTypeStringUnknownValue(t *testing.T) { + const unknown ResultType = 99 + got := unknown.String() + if got == "" { + t.Error("String() for unknown ResultType should not return empty string") + } + if !strings.Contains(got, "99") { + t.Errorf("String() for unknown ResultType should include numeric value, got %q", got) + } +} + +func TestResultTypeString(t *testing.T) { + tests := []struct { + v ResultType + expected string + }{ + {ResultObservation, "Observation"}, + {ResultStrength, "Strength"}, + {ResultFinding, "Finding"}, + {ResultGap, "Gap"}, + } + for _, tt := range tests { + t.Run(tt.expected, func(t *testing.T) { + if got := tt.v.String(); got != tt.expected { + t.Errorf("String() = %q, want %q", got, tt.expected) + } + }) + } +} + func TestLifecycleMarshalUnmarshalJSON(t *testing.T) { var l Lifecycle if err := l.UnmarshalJSON([]byte(`"Draft"`)); err != nil { @@ -415,14 +458,90 @@ func TestRelationshipTypeUnmarshalJSONInvalid(t *testing.T) { } } -func TestResultStringUnknownValue(t *testing.T) { - // Out-of-range or unknown int should not return empty string - const unknown Result = 99 - got := unknown.String() - if got == "" { - t.Error("String() for unknown Result should not return empty string") +func TestResultTypeMarshalUnmarshalJSON(t *testing.T) { + tests := []struct { + value ResultType + jsonRepr string + }{ + {ResultObservation, `"Observation"`}, + {ResultStrength, `"Strength"`}, + {ResultFinding, `"Finding"`}, + {ResultGap, `"Gap"`}, } - if !strings.Contains(got, "99") { - t.Errorf("String() for unknown Result should include numeric value, got %q", got) + for _, tt := range tests { + t.Run(tt.jsonRepr, func(t *testing.T) { + out, err := tt.value.MarshalJSON() + if err != nil { + t.Fatalf("MarshalJSON: %v", err) + } + if string(out) != tt.jsonRepr { + t.Errorf("MarshalJSON = %s, want %s", out, tt.jsonRepr) + } + + var got ResultType + if err := got.UnmarshalJSON(out); err != nil { + t.Fatalf("UnmarshalJSON: %v", err) + } + if got != tt.value { + t.Errorf("UnmarshalJSON round-trip: got %v, want %v", got, tt.value) + } + }) + } +} + +func TestEvidenceTypeToArtifactType(t *testing.T) { + tests := []struct { + name string + ev EvidenceType + expected ArtifactType + wantErr bool + }{ + {"ControlCatalog", EvidenceType("ControlCatalog"), ControlCatalogArtifact, false}, + {"EvaluationLog", EvidenceType("EvaluationLog"), EvaluationLogArtifact, false}, + {"GuidanceCatalog", EvidenceType("GuidanceCatalog"), GuidanceCatalogArtifact, false}, + {"MappingDocument", EvidenceType("MappingDocument"), MappingDocumentArtifact, false}, + {"Policy", EvidenceType("Policy"), PolicyArtifact, false}, + {"ThreatCatalog", EvidenceType("ThreatCatalog"), ThreatCatalogArtifact, false}, + {"VectorCatalog", EvidenceType("VectorCatalog"), VectorCatalogArtifact, false}, + {"RiskCatalog", EvidenceType("RiskCatalog"), RiskCatalogArtifact, false}, + {"invalid value", EvidenceType("not-an-artifact"), 0, true}, + {"empty string", EvidenceType(""), 0, true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := tt.ev.ToArtifactType() + if (err != nil) != tt.wantErr { + t.Errorf("ToArtifactType() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !tt.wantErr && got != tt.expected { + t.Errorf("ToArtifactType() = %v, want %v", got, tt.expected) + } + }) + } +} + +func TestEvidenceTypeJSONRoundTrip(t *testing.T) { + type wrapper struct { + Type EvidenceType `json:"type"` + } + + tests := []string{"document", "interview", "automated-scan", "custom-value"} + for _, val := range tests { + t.Run(val, func(t *testing.T) { + input := wrapper{Type: EvidenceType(val)} + data, err := json.Marshal(input) + if err != nil { + t.Fatalf("Marshal: %v", err) + } + + var got wrapper + if err := json.Unmarshal(data, &got); err != nil { + t.Fatalf("Unmarshal: %v", err) + } + if got.Type != input.Type { + t.Errorf("round-trip: got %q, want %q", got.Type, input.Type) + } + }) } } diff --git a/generated_types.go b/generated_types.go index 338aebf..ab95a27 100644 --- a/generated_types.go +++ b/generated_types.go @@ -2,57 +2,61 @@ package gemara -// CapabilityCatalog describes a collection of system capabilities -type CapabilityCatalog struct { - // title describes the purpose of this catalog at a glance - Title string `json:"title" yaml:"title"` +// AuditLog records results from an audit performed against a target resource +type AuditLog struct { + // metadata provides detailed data about this log + Metadata Metadata `json:"metadata" yaml:"metadata"` - // metadata provides detailed data about this catalog - Metadata struct { - // id allows this entry to be referenced by other elements - Id string `json:"id"` + // owner defines the RACI roles responsible for managing the audit + Owner RACI `json:"owner,omitempty" yaml:"owner,omitempty"` - // type identifies the kind of Gemara artifact for unambiguous parsing - Type string `json:"type"` + // summary provides the high-level conclusion + Summary string `json:"summary" yaml:"summary"` - // gemara-version declares which version of the Gemara specification this artifact conforms to - GemaraVersion string `json:"gemara-version"` + // criteria defines the acceptable state for the audited resource + Criteria []ArtifactMapping `json:"criteria" yaml:"criteria"` - // version is the version identifier of this artifact - Version string `json:"version,omitempty"` + // results records audit results against the criteria + Results []*AuditResult `json:"results" yaml:"results"` - // date is the publication or effective date of this artifact - Date Datetime `json:"date,omitempty"` + // target identifies the resource being evaluated + Target Resource `json:"target" yaml:"target"` +} - // description provides a high-level summary of the artifact's purpose and scope - Description string `json:"description"` +// Metadata represents common metadata fields shared across all layers +type Metadata struct { + // id allows this entry to be referenced by other elements + Id string `json:"id" yaml:"id"` - // author is the person or group primarily responsible for this artifact - Author Actor `json:"author"` + // type identifies the kind of Gemara artifact for unambiguous parsing + Type ArtifactType `json:"type" yaml:"type"` - // mapping-references is a list of external documents referenced within this artifact - MappingReferences []MappingReference `json:"mapping-references,omitempty"` + // gemara-version declares which version of the Gemara specification this artifact conforms to + GemaraVersion string `json:"gemara-version" yaml:"gemara-version"` - // applicability-groups is a list of groups used to classify within this artifact to specify scope - ApplicabilityGroups []Group `json:"applicability-groups,omitempty"` + // version is the version identifier of this artifact + Version string `json:"version,omitempty" yaml:"version,omitempty"` - // draft indicates whether this artifact is a pre-release version; open to modification - Draft bool `json:"draft,omitempty"` + // date is the publication or effective date of this artifact + Date Datetime `json:"date,omitempty" yaml:"date,omitempty"` - // lexicon is a URI pointing to a controlled vocabulary or glossary relevant to this artifact - Lexicon *ArtifactMapping `json:"lexicon,omitempty"` - } `json:"metadata" yaml:"metadata"` + // description provides a high-level summary of the artifact's purpose and scope + Description string `json:"description" yaml:"description"` - // capabilities is a list of capabilities defined by this catalog - Capabilities []Capability `json:"capabilities,omitempty" yaml:"capabilities,omitempty"` + // author is the person or group primarily responsible for this artifact + Author Actor `json:"author" yaml:"author"` - // groups contains a list of groups that can be referenced by entries in this catalog - Groups []Group `json:"groups,omitempty" yaml:"groups,omitempty"` + // mapping-references is a list of external documents referenced within this artifact + MappingReferences []MappingReference `json:"mapping-references,omitempty" yaml:"mapping-references,omitempty"` - // extends references catalogs that this catalog builds upon - Extends []ArtifactMapping `json:"extends,omitempty" yaml:"extends,omitempty"` + // applicability-groups is a list of groups used to classify within this artifact to specify scope + ApplicabilityGroups []Group `json:"applicability-groups,omitempty" yaml:"applicability-groups,omitempty"` - Imports []MultiEntryMapping `json:"imports,omitempty" yaml:"imports,omitempty"` + // draft indicates whether this artifact is a pre-release version; open to modification + Draft bool `json:"draft,omitempty" yaml:"draft,omitempty"` + + // lexicon is a URI pointing to a controlled vocabulary or glossary relevant to this artifact + Lexicon *ArtifactMapping `json:"lexicon,omitempty" yaml:"lexicon,omitempty"` } // Datetime represents an ISO 8601 formatted datetime string @@ -135,6 +139,68 @@ type ArtifactMapping struct { Remarks string `json:"remarks,omitempty" yaml:"remarks,omitempty"` } +// RACI defines the roles responsible for managing an artifact +type RACI struct { + // responsible identifies the entities responsible for executing work to manage or mitigate the artifact + Responsible []Contact `json:"responsible" yaml:"responsible"` + + // accountable identifies the entity ultimately accountable for the outcome + Accountable []Contact `json:"accountable" yaml:"accountable"` + + // consulted identifies entities whose input is required when assessing or responding to the artifact + Consulted []Contact `json:"consulted,omitempty" yaml:"consulted,omitempty"` + + // informed identifies entities that should be notified about changes to the artifact status + Informed []Contact `json:"informed,omitempty" yaml:"informed,omitempty"` +} + +// Resource represents an entity that exists in the system and can be evaluated +type Resource struct { + // environment describes where the resource exists (e.g., production, staging, development, specific region) + Environment string `json:"environment,omitempty" yaml:"environment,omitempty"` + + // id uniquely identifies the entity and allows this entry to be referenced by other elements + Id string `json:"id" yaml:"id"` + + // name is the name of the entity + Name string `json:"name" yaml:"name"` + + // owner is the contact information for the person or group responsible for managing or owning this resource + Owner Contact `json:"owner,omitempty" yaml:"owner,omitempty"` + + // type specifies the type of entity interacting in the workflow + Type EntityType `json:"type" yaml:"type"` + + // version is the version of the entity (for tools; if applicable) + Version string `json:"version,omitempty" yaml:"version,omitempty"` + + // description provides additional context about the entity + Description string `json:"description,omitempty" yaml:"description,omitempty"` + + // uri is a general URI for the entity information + Uri string `json:"uri,omitempty" yaml:"uri,omitempty"` +} + +// CapabilityCatalog describes a collection of system capabilities +type CapabilityCatalog struct { + // title describes the purpose of this catalog at a glance + Title string `json:"title" yaml:"title"` + + // metadata provides detailed data about this catalog + Metadata Metadata `json:"metadata" yaml:"metadata"` + + // capabilities is a list of capabilities defined by this catalog + Capabilities []Capability `json:"capabilities,omitempty" yaml:"capabilities,omitempty"` + + // groups contains a list of groups that can be referenced by entries in this catalog + Groups []Group `json:"groups,omitempty" yaml:"groups,omitempty"` + + // extends references catalogs that this catalog builds upon + Extends []ArtifactMapping `json:"extends,omitempty" yaml:"extends,omitempty"` + + Imports []MultiEntryMapping `json:"imports,omitempty" yaml:"imports,omitempty"` +} + // Capability describes a system capability such as a feature, component or object. type Capability struct { // id allows this entry to be referenced by other elements @@ -168,40 +234,7 @@ type Catalog struct { Title string `json:"title" yaml:"title"` // metadata provides detailed data about this catalog - Metadata struct { - // id allows this entry to be referenced by other elements - Id string `json:"id"` - - // type identifies the kind of Gemara artifact for unambiguous parsing - Type ArtifactType `json:"type"` - - // gemara-version declares which version of the Gemara specification this artifact conforms to - GemaraVersion string `json:"gemara-version"` - - // version is the version identifier of this artifact - Version string `json:"version,omitempty"` - - // date is the publication or effective date of this artifact - Date Datetime `json:"date,omitempty"` - - // description provides a high-level summary of the artifact's purpose and scope - Description string `json:"description"` - - // author is the person or group primarily responsible for this artifact - Author Actor `json:"author"` - - // mapping-references is a list of external documents referenced within this artifact - MappingReferences []MappingReference `json:"mapping-references,omitempty"` - - // applicability-groups is a list of groups used to classify within this artifact to specify scope - ApplicabilityGroups []Group `json:"applicability-groups,omitempty"` - - // draft indicates whether this artifact is a pre-release version; open to modification - Draft bool `json:"draft,omitempty"` - - // lexicon is a URI pointing to a controlled vocabulary or glossary relevant to this artifact - Lexicon *ArtifactMapping `json:"lexicon,omitempty"` - } `json:"metadata" yaml:"metadata"` + Metadata Metadata `json:"metadata" yaml:"metadata"` // groups contains a list of groups that can be referenced by entries in this catalog Groups []Group `json:"groups,omitempty" yaml:"groups,omitempty"` @@ -218,40 +251,7 @@ type ControlCatalog struct { Title string `json:"title" yaml:"title"` // metadata provides detailed data about this catalog - Metadata struct { - // id allows this entry to be referenced by other elements - Id string `json:"id"` - - // type identifies the kind of Gemara artifact for unambiguous parsing - Type string `json:"type"` - - // gemara-version declares which version of the Gemara specification this artifact conforms to - GemaraVersion string `json:"gemara-version"` - - // version is the version identifier of this artifact - Version string `json:"version,omitempty"` - - // date is the publication or effective date of this artifact - Date Datetime `json:"date,omitempty"` - - // description provides a high-level summary of the artifact's purpose and scope - Description string `json:"description"` - - // author is the person or group primarily responsible for this artifact - Author Actor `json:"author"` - - // mapping-references is a list of external documents referenced within this artifact - MappingReferences []MappingReference `json:"mapping-references,omitempty"` - - // applicability-groups is a list of groups used to classify within this artifact to specify scope - ApplicabilityGroups []Group `json:"applicability-groups,omitempty"` - - // draft indicates whether this artifact is a pre-release version; open to modification - Draft bool `json:"draft,omitempty"` - - // lexicon is a URI pointing to a controlled vocabulary or glossary relevant to this artifact - Lexicon *ArtifactMapping `json:"lexicon,omitempty"` - } `json:"metadata" yaml:"metadata"` + Metadata Metadata `json:"metadata" yaml:"metadata"` // controls is a list of unique controls defined by this catalog Controls []Control `json:"controls,omitempty" yaml:"controls,omitempty"` @@ -331,80 +331,22 @@ type EntryMapping struct { // EnforcementLog records actions taken in response to noncompliance findings from Layer 5 evaluations. type EnforcementLog struct { // metadata provides detailed data about this log - Metadata struct { - // id allows this entry to be referenced by other elements - Id string `json:"id"` - - // type identifies the kind of Gemara artifact for unambiguous parsing - Type string `json:"type"` - - // gemara-version declares which version of the Gemara specification this artifact conforms to - GemaraVersion string `json:"gemara-version"` - - // version is the version identifier of this artifact - Version string `json:"version,omitempty"` - - // date is the publication or effective date of this artifact - Date Datetime `json:"date,omitempty"` - - // description provides a high-level summary of the artifact's purpose and scope - Description string `json:"description"` - - // author is the person or group primarily responsible for this artifact - Author Actor `json:"author"` - - // mapping-references is a list of external documents referenced within this artifact - MappingReferences []MappingReference `json:"mapping-references,omitempty"` - - // applicability-groups is a list of groups used to classify within this artifact to specify scope - ApplicabilityGroups []Group `json:"applicability-groups,omitempty"` - - // draft indicates whether this artifact is a pre-release version; open to modification - Draft bool `json:"draft,omitempty"` - - // lexicon is a URI pointing to a controlled vocabulary or glossary relevant to this artifact - Lexicon *ArtifactMapping `json:"lexicon,omitempty"` - } `json:"metadata" yaml:"metadata"` + Metadata Metadata `json:"metadata" yaml:"metadata"` // disposition is the aggregate enforcement disposition across all actions in this log Disposition Disposition `json:"disposition" yaml:"disposition"` + // actions is the list of enforcement actions performed + // // Enforce that Clear dispositions only contain Passed assessment results - Actions []*ActionLog `json:"actions" yaml:"actions"` + Actions []*ActionResult `json:"actions" yaml:"actions"` // target identifies the resource being evaluated Target Resource `json:"target" yaml:"target"` } -// Resource represents an entity that exists in the system and can be evaluated -type Resource struct { - // environment describes where the resource exists (e.g., production, staging, development, specific region) - Environment string `json:"environment,omitempty" yaml:"environment,omitempty"` - - // id uniquely identifies the entity and allows this entry to be referenced by other elements - Id string `json:"id" yaml:"id"` - - // name is the name of the entity - Name string `json:"name" yaml:"name"` - - // owner is the contact information for the person or group responsible for managing or owning this resource - Owner Contact `json:"owner,omitempty" yaml:"owner,omitempty"` - - // type specifies the type of entity interacting in the workflow - Type EntityType `json:"type" yaml:"type"` - - // version is the version of the entity (for tools; if applicable) - Version string `json:"version,omitempty" yaml:"version,omitempty"` - - // description provides additional context about the entity - Description string `json:"description,omitempty" yaml:"description,omitempty"` - - // uri is a general URI for the entity information - Uri string `json:"uri,omitempty" yaml:"uri,omitempty"` -} - -// ActionLog captures a performed enforcement action. -type ActionLog struct { +// ActionResult captures a performed enforcement action. +type ActionResult struct { // disposition is the enforcement action taken Disposition Disposition `json:"disposition" yaml:"disposition"` @@ -472,46 +414,10 @@ type Entity struct { Uri string `json:"uri,omitempty" yaml:"uri,omitempty"` } -// Email represents a validated email address pattern -type Email string - // EvaluationLog contains the results of evaluating a set of Layer 2 controls. type EvaluationLog struct { // metadata provides detailed data about this log - Metadata struct { - // id allows this entry to be referenced by other elements - Id string `json:"id"` - - // type identifies the kind of Gemara artifact for unambiguous parsing - Type string `json:"type"` - - // gemara-version declares which version of the Gemara specification this artifact conforms to - GemaraVersion string `json:"gemara-version"` - - // version is the version identifier of this artifact - Version string `json:"version,omitempty"` - - // date is the publication or effective date of this artifact - Date Datetime `json:"date,omitempty"` - - // description provides a high-level summary of the artifact's purpose and scope - Description string `json:"description"` - - // author is the person or group primarily responsible for this artifact - Author Actor `json:"author"` - - // mapping-references is a list of external documents referenced within this artifact - MappingReferences []MappingReference `json:"mapping-references,omitempty"` - - // applicability-groups is a list of groups used to classify within this artifact to specify scope - ApplicabilityGroups []Group `json:"applicability-groups,omitempty"` - - // draft indicates whether this artifact is a pre-release version; open to modification - Draft bool `json:"draft,omitempty"` - - // lexicon is a URI pointing to a controlled vocabulary or glossary relevant to this artifact - Lexicon *ArtifactMapping `json:"lexicon,omitempty"` - } `json:"metadata" yaml:"metadata"` + Metadata Metadata `json:"metadata" yaml:"metadata"` // result is the aggregate outcome across all evaluations in this log Result Result `json:"result" yaml:"result"` @@ -582,40 +488,7 @@ type GuidanceCatalog struct { Title string `json:"title" yaml:"title"` // metadata provides detailed data about this catalog - Metadata struct { - // id allows this entry to be referenced by other elements - Id string `json:"id"` - - // type identifies the kind of Gemara artifact for unambiguous parsing - Type string `json:"type"` - - // gemara-version declares which version of the Gemara specification this artifact conforms to - GemaraVersion string `json:"gemara-version"` - - // version is the version identifier of this artifact - Version string `json:"version,omitempty"` - - // date is the publication or effective date of this artifact - Date Datetime `json:"date,omitempty"` - - // description provides a high-level summary of the artifact's purpose and scope - Description string `json:"description"` - - // author is the person or group primarily responsible for this artifact - Author Actor `json:"author"` - - // mapping-references is a list of external documents referenced within this artifact - MappingReferences []MappingReference `json:"mapping-references,omitempty"` - - // applicability-groups is a list of groups used to classify within this artifact to specify scope - ApplicabilityGroups []Group `json:"applicability-groups,omitempty"` - - // draft indicates whether this artifact is a pre-release version; open to modification - Draft bool `json:"draft,omitempty"` - - // lexicon is a URI pointing to a controlled vocabulary or glossary relevant to this artifact - Lexicon *ArtifactMapping `json:"lexicon,omitempty"` - } `json:"metadata" yaml:"metadata"` + Metadata Metadata `json:"metadata" yaml:"metadata"` // groups contains a list of groups that can be referenced by entries in this catalog Groups []Group `json:"groups,omitempty" yaml:"groups,omitempty"` @@ -720,61 +593,22 @@ type Exemption struct { Redirect *MultiEntryMapping `json:"redirect,omitempty" yaml:"redirect,omitempty"` } +// Log describes a set of recorded entries from a measurement activity +type Log struct { + // metadata provides detailed data about this log + Metadata Metadata `json:"metadata" yaml:"metadata"` + + // target identifies the resource being evaluated + Target Resource `json:"target" yaml:"target"` +} + // MappingDocument captures the user's intent for how entries in a source artifact relate to entries in a target artifact type MappingDocument struct { // title describes the purpose of this mapping document at a glance Title string `json:"title" yaml:"title"` // metadata provides detailed data about this document - Metadata struct { - // id allows this entry to be referenced by other elements - Id string `json:"id"` - - // type identifies the kind of Gemara artifact for unambiguous parsing - Type string `json:"type"` - - // gemara-version declares which version of the Gemara specification this artifact conforms to - GemaraVersion string `json:"gemara-version"` - - // version is the version identifier of this artifact - Version string `json:"version,omitempty"` - - // date is the publication or effective date of this artifact - Date Datetime `json:"date,omitempty"` - - // description provides a high-level summary of the artifact's purpose and scope - Description string `json:"description"` - - // author is the person or group primarily responsible for this artifact - Author Actor `json:"author"` - - // mapping-references is a list of external documents referenced within this artifact - MappingReferences []struct { - // id allows this entry to be referenced by other elements - Id string `json:"id"` - - // title describes the purpose of this mapping reference at a glance - Title string `json:"title"` - - // version is the version identifier of the artifact being mapped to - Version string `json:"version"` - - // description is prose regarding the artifact's purpose or content - Description string `json:"description,omitempty"` - - // url is the path where the artifact may be retrieved; preferrably responds with Gemara-compatible YAML/JSON - Url string `json:"url,omitempty"` - } `json:"mapping-references"` - - // applicability-groups is a list of groups used to classify within this artifact to specify scope - ApplicabilityGroups []Group `json:"applicability-groups,omitempty"` - - // draft indicates whether this artifact is a pre-release version; open to modification - Draft bool `json:"draft,omitempty"` - - // lexicon is a URI pointing to a controlled vocabulary or glossary relevant to this artifact - Lexicon *ArtifactMapping `json:"lexicon,omitempty"` - } `json:"metadata" yaml:"metadata"` + Metadata Metadata `json:"metadata" yaml:"metadata"` // source-reference identifies the artifact being mapped from; must match a mapping-reference id SourceReference ArtifactMapping `json:"source-reference" yaml:"source-reference"` @@ -789,118 +623,11 @@ type MappingDocument struct { Remarks string `json:"remarks,omitempty" yaml:"remarks,omitempty"` } -// Mapping represents an atomic relationship between a source entry and an optional target entry -type Mapping struct { - // id allows this mapping to be referenced by other elements - Id string `json:"id" yaml:"id"` - - // source identifies the entry being mapped from - Source TypedEntry `json:"source" yaml:"source"` - - // target identifies the entry being mapped to; absent when relationship is no-match - Target *TypedEntry `json:"target,omitempty" yaml:"target,omitempty"` - - // relationship describes the nature or purpose of the mapping - Relationship RelationshipType `json:"relationship" yaml:"relationship"` - - // strength is the author's estimate of how completely the source entry satisfies the target entry; range 1-10 - Strength int64 `json:"strength,omitempty" yaml:"strength,omitempty"` - - ConfidenceLevel ConfidenceLevel `json:"confidence-level,omitempty" yaml:"confidence-level,omitempty"` - - // applicability constrains the contexts in which this mapping holds - Applicability []string `json:"applicability,omitempty" yaml:"applicability,omitempty"` - - // rationale explains why this relationship exists - Rationale string `json:"rationale,omitempty" yaml:"rationale,omitempty"` - - // remarks is general prose regarding this mapping - Remarks string `json:"remarks,omitempty" yaml:"remarks,omitempty"` -} - -// EntryReference identifies a specific entry within a referenced artifact -type TypedEntry struct { - // entry-id identifies the specific entry in the referenced artifact - EntryId string `json:"entry-id" yaml:"entry-id"` - - // entry-type identifies what kind of atomic unit this entry is - EntryType EntryType `json:"entry-type" yaml:"entry-type"` -} - -// Metadata represents common metadata fields shared across all layers -type Metadata struct { - // id allows this entry to be referenced by other elements - Id string `json:"id" yaml:"id"` - - // type identifies the kind of Gemara artifact for unambiguous parsing - Type ArtifactType `json:"type" yaml:"type"` - - // gemara-version declares which version of the Gemara specification this artifact conforms to - GemaraVersion string `json:"gemara-version" yaml:"gemara-version"` - - // version is the version identifier of this artifact - Version string `json:"version,omitempty" yaml:"version,omitempty"` - - // date is the publication or effective date of this artifact - Date Datetime `json:"date,omitempty" yaml:"date,omitempty"` - - // description provides a high-level summary of the artifact's purpose and scope - Description string `json:"description" yaml:"description"` - - // author is the person or group primarily responsible for this artifact - Author Actor `json:"author" yaml:"author"` - - // mapping-references is a list of external documents referenced within this artifact - MappingReferences []MappingReference `json:"mapping-references,omitempty" yaml:"mapping-references,omitempty"` - - // applicability-groups is a list of groups used to classify within this artifact to specify scope - ApplicabilityGroups []Group `json:"applicability-groups,omitempty" yaml:"applicability-groups,omitempty"` - - // draft indicates whether this artifact is a pre-release version; open to modification - Draft bool `json:"draft,omitempty" yaml:"draft,omitempty"` - - // lexicon is a URI pointing to a controlled vocabulary or glossary relevant to this artifact - Lexicon *ArtifactMapping `json:"lexicon,omitempty" yaml:"lexicon,omitempty"` -} - // Policy represents a policy document with metadata, contacts, scope, imports, implementation plan, risks, and adherence requirements. type Policy struct { Title string `json:"title" yaml:"title"` - Metadata struct { - // id allows this entry to be referenced by other elements - Id string `json:"id"` - - // type identifies the kind of Gemara artifact for unambiguous parsing - Type string `json:"type"` - - // gemara-version declares which version of the Gemara specification this artifact conforms to - GemaraVersion string `json:"gemara-version"` - - // version is the version identifier of this artifact - Version string `json:"version,omitempty"` - - // date is the publication or effective date of this artifact - Date Datetime `json:"date,omitempty"` - - // description provides a high-level summary of the artifact's purpose and scope - Description string `json:"description"` - - // author is the person or group primarily responsible for this artifact - Author Actor `json:"author"` - - // mapping-references is a list of external documents referenced within this artifact - MappingReferences []MappingReference `json:"mapping-references,omitempty"` - - // applicability-groups is a list of groups used to classify within this artifact to specify scope - ApplicabilityGroups []Group `json:"applicability-groups,omitempty"` - - // draft indicates whether this artifact is a pre-release version; open to modification - Draft bool `json:"draft,omitempty"` - - // lexicon is a URI pointing to a controlled vocabulary or glossary relevant to this artifact - Lexicon *ArtifactMapping `json:"lexicon,omitempty"` - } `json:"metadata" yaml:"metadata"` + Metadata Metadata `json:"metadata" yaml:"metadata"` Contacts RACI `json:"contacts" yaml:"contacts"` @@ -915,21 +642,6 @@ type Policy struct { Adherence Adherence `json:"adherence" yaml:"adherence"` } -// RACI defines the roles responsible for managing an artifact -type RACI struct { - // responsible identifies the entities responsible for executing work to manage or mitigate the artifact - Responsible []Contact `json:"responsible" yaml:"responsible"` - - // accountable identifies the entity ultimately accountable for the outcome - Accountable []Contact `json:"accountable" yaml:"accountable"` - - // consulted identifies entities whose input is required when assessing or responding to the artifact - Consulted []Contact `json:"consulted,omitempty" yaml:"consulted,omitempty"` - - // informed identifies entities that should be notified about changes to the artifact status - Informed []Contact `json:"informed,omitempty" yaml:"informed,omitempty"` -} - // Scope defines what is included and excluded from policy applicability. type Scope struct { In Dimensions `json:"in" yaml:"in"` @@ -1124,53 +836,112 @@ type Parameter struct { AcceptedValues []string `json:"accepted-values,omitempty" yaml:"accepted-values,omitempty"` } -// A RiskCatalog is a structured collection of documented risks that may affect an organization, -// system, or service. It provides a centralized reference for risks that can be mapped to threats -// and referenced by policies when documenting how those risks are mitigated or accepted. -type RiskCatalog struct { +// PrincipleCatalog describes a set of related principles and relevant metadata +type PrincipleCatalog struct { // title describes the purpose of this catalog at a glance Title string `json:"title" yaml:"title"` // metadata provides detailed data about this catalog - Metadata struct { - // id allows this entry to be referenced by other elements - Id string `json:"id"` + Metadata Metadata `json:"metadata" yaml:"metadata"` + + // groups contains a list of groups that can be referenced by entries in this catalog + Groups []Group `json:"groups,omitempty" yaml:"groups,omitempty"` + + // extends references catalogs that this catalog builds upon + Extends []ArtifactMapping `json:"extends,omitempty" yaml:"extends,omitempty"` + + Imports []MultiEntryMapping `json:"imports,omitempty" yaml:"imports,omitempty"` + + // principles is a list of unique principles defined by this catalog + Principles []Principle `json:"principles,omitempty" yaml:"principles,omitempty"` +} + +// Principle represents a foundational value or tenet that guides governance, design, and operational decisions +type Principle struct { + // id allows this entry to be referenced by other elements + Id string `json:"id" yaml:"id"` + + // title describes the principle at a glance + Title string `json:"title" yaml:"title"` + + // description explains the principle and its expected outcomes + Description string `json:"description" yaml:"description"` + + // rationale provides the context for this principle + Rationale string `json:"rationale,omitempty" yaml:"rationale,omitempty"` +} + +// Email represents a validated email address pattern +type Email string + +// AuditResult records a single result with supporting evidence and recommendations. +type AuditResult struct { + // id uniquely identifies this result + Id string `json:"id" yaml:"id"` + + // title describes this result at a glance + Title string `json:"title" yaml:"title"` + + // type classifies the nature of this result + Type ResultType `json:"type" yaml:"type"` + + // description explains the result in detail + Description string `json:"description" yaml:"description"` + + // criteria-reference maps this result to specific criteria entries + Criteria_reference MultiEntryMapping `json:"criteria-reference" yaml:"criteria-reference"` - // type identifies the kind of Gemara artifact for unambiguous parsing - Type string `json:"type"` + // evidence records the data sources that support this result + Evidence []Evidence `json:"evidence,omitempty" yaml:"evidence,omitempty"` - // gemara-version declares which version of the Gemara specification this artifact conforms to - GemaraVersion string `json:"gemara-version"` + // recommendations records corrective actions for this result + Recommendations []Recommendation `json:"recommendations,omitempty" yaml:"recommendations,omitempty"` +} + +// Evidence records a specific data source consulted during an audit +type Evidence struct { + // id uniquely identifies this evidence + Id string `json:"id,omitempty" yaml:"id,omitempty"` - // version is the version identifier of this artifact - Version string `json:"version,omitempty"` + // type categorizes the kind of evidence + Type EvidenceType `json:"type" yaml:"type"` - // date is the publication or effective date of this artifact - Date Datetime `json:"date,omitempty"` + // collected is the timestamp when the evidence was gathered + Collected Datetime `json:"collected" yaml:"collected"` - // description provides a high-level summary of the artifact's purpose and scope - Description string `json:"description"` + // location references the artifact containing this evidence + Location ArtifactMapping `json:"location" yaml:"location"` - // author is the person or group primarily responsible for this artifact - Author Actor `json:"author"` + // description explains what this evidence represents + Description string `json:"description,omitempty" yaml:"description,omitempty"` +} - // mapping-references is a list of external documents referenced within this artifact - MappingReferences []MappingReference `json:"mapping-references,omitempty"` +// Recommendation provides a corrective action for an audit result +type Recommendation struct { + // id uniquely identifies this recommendation + Id string `json:"id,omitempty" yaml:"id,omitempty"` - // applicability-groups is a list of groups used to classify within this artifact to specify scope - ApplicabilityGroups []Group `json:"applicability-groups,omitempty"` + // text describes the recommended corrective action + Text string `json:"text" yaml:"text"` - // draft indicates whether this artifact is a pre-release version; open to modification - Draft bool `json:"draft,omitempty"` + // required indicates whether this recommendation is a mandatory corrective action + Required bool `json:"required" yaml:"required"` +} - // lexicon is a URI pointing to a controlled vocabulary or glossary relevant to this artifact - Lexicon *ArtifactMapping `json:"lexicon,omitempty"` - } `json:"metadata" yaml:"metadata"` +// A RiskCatalog is a structured collection of documented risks that may affect an organization, +// system, or service. It provides a centralized reference for risks that can be mapped to threats +// and referenced by policies when documenting how those risks are mitigated or accepted. +type RiskCatalog struct { + // title describes the purpose of this catalog at a glance + Title string `json:"title" yaml:"title"` + + // metadata provides detailed data about this catalog + Metadata Metadata `json:"metadata" yaml:"metadata"` // groups narrows the base groups to risk categories with appetite and severity boundaries // // groups contains a list of groups that can be referenced by entries in this catalog - Groups []any/* TODO: IncompleteKind: _|_ */ `json:"groups,omitempty" yaml:"groups,omitempty"` + Groups []RiskCategory `json:"groups,omitempty" yaml:"groups,omitempty"` // extends references catalogs that this catalog builds upon Extends []ArtifactMapping `json:"extends,omitempty" yaml:"extends,omitempty"` @@ -1181,6 +952,25 @@ type RiskCatalog struct { Risks []Risk `json:"risks,omitempty" yaml:"risks,omitempty"` } +// RiskCategory describes a grouping of risks and defines appetite boundaries +type RiskCategory struct { + // appetite defines the acceptable level of risk for this category + Appetite RiskAppetite `json:"appetite" yaml:"appetite"` + + // id allows this entry to be referenced by other elements + Id string `json:"id" yaml:"id"` + + // max-severity defines the risk tolerance boundary: the highest severity + // the organization will accept within this category + MaxSeverity Severity `json:"max-severity,omitempty" yaml:"max-severity,omitempty"` + + // title describes the purpose of this group at a glance + Title string `json:"title" yaml:"title"` + + // description explains the significance and traits of entries to this group + Description string `json:"description" yaml:"description"` +} + // A Risk represents the potential for negative impact resulting from one or more threats. type Risk struct { // id allows this risk to be referenced by other elements @@ -1208,65 +998,13 @@ type Risk struct { Threats []MultiEntryMapping `json:"threats,omitempty" yaml:"threats,omitempty"` } -// RiskCategory describes a grouping of risks and defines appetite boundaries -type RiskCategory struct { - // appetite defines the acceptable level of risk for this category - Appetite RiskAppetite `json:"appetite" yaml:"appetite"` - - // id allows this entry to be referenced by other elements - Id string `json:"id" yaml:"id"` - - // max-severity defines the risk tolerance boundary: the highest severity - // the organization will accept within this category - MaxSeverity Severity `json:"max-severity,omitempty" yaml:"max-severity,omitempty"` - - // title describes the purpose of this group at a glance - Title string `json:"title" yaml:"title"` - - // description explains the significance and traits of entries to this group - Description string `json:"description" yaml:"description"` -} - // ThreatCatalog describes a set of topically-associated threats type ThreatCatalog struct { // title describes the purpose of this catalog at a glance Title string `json:"title" yaml:"title"` // metadata provides detailed data about this catalog - Metadata struct { - // id allows this entry to be referenced by other elements - Id string `json:"id"` - - // type identifies the kind of Gemara artifact for unambiguous parsing - Type string `json:"type"` - - // gemara-version declares which version of the Gemara specification this artifact conforms to - GemaraVersion string `json:"gemara-version"` - - // version is the version identifier of this artifact - Version string `json:"version,omitempty"` - - // date is the publication or effective date of this artifact - Date Datetime `json:"date,omitempty"` - - // description provides a high-level summary of the artifact's purpose and scope - Description string `json:"description"` - - // author is the person or group primarily responsible for this artifact - Author Actor `json:"author"` - - // mapping-references is a list of external documents referenced within this artifact - MappingReferences []MappingReference `json:"mapping-references,omitempty"` - - // applicability-groups is a list of groups used to classify within this artifact to specify scope - ApplicabilityGroups []Group `json:"applicability-groups,omitempty"` - - // draft indicates whether this artifact is a pre-release version; open to modification - Draft bool `json:"draft,omitempty"` - - // lexicon is a URI pointing to a controlled vocabulary or glossary relevant to this artifact - Lexicon *ArtifactMapping `json:"lexicon,omitempty"` - } `json:"metadata" yaml:"metadata"` + Metadata Metadata `json:"metadata" yaml:"metadata"` // groups contains a list of groups that can be referenced by entries in this catalog Groups []Group `json:"groups,omitempty" yaml:"groups,omitempty"` @@ -1309,40 +1047,7 @@ type VectorCatalog struct { Title string `json:"title" yaml:"title"` // metadata provides detailed data about this catalog - Metadata struct { - // id allows this entry to be referenced by other elements - Id string `json:"id"` - - // type identifies the kind of Gemara artifact for unambiguous parsing - Type string `json:"type"` - - // gemara-version declares which version of the Gemara specification this artifact conforms to - GemaraVersion string `json:"gemara-version"` - - // version is the version identifier of this artifact - Version string `json:"version,omitempty"` - - // date is the publication or effective date of this artifact - Date Datetime `json:"date,omitempty"` - - // description provides a high-level summary of the artifact's purpose and scope - Description string `json:"description"` - - // author is the person or group primarily responsible for this artifact - Author Actor `json:"author"` - - // mapping-references is a list of external documents referenced within this artifact - MappingReferences []MappingReference `json:"mapping-references,omitempty"` - - // applicability-groups is a list of groups used to classify within this artifact to specify scope - ApplicabilityGroups []Group `json:"applicability-groups,omitempty"` - - // draft indicates whether this artifact is a pre-release version; open to modification - Draft bool `json:"draft,omitempty"` - - // lexicon is a URI pointing to a controlled vocabulary or glossary relevant to this artifact - Lexicon *ArtifactMapping `json:"lexicon,omitempty"` - } `json:"metadata" yaml:"metadata"` + Metadata Metadata `json:"metadata" yaml:"metadata"` // groups contains a list of groups that can be referenced by entries in this catalog Groups []Group `json:"groups,omitempty" yaml:"groups,omitempty"` @@ -1374,11 +1079,40 @@ type Vector struct { Applicability []string `json:"applicability,omitempty" yaml:"applicability,omitempty"` } -// Log describes a set of recorded entries from a measurement activity -type Log struct { - // metadata provides detailed data about this log - Metadata Metadata `json:"metadata" yaml:"metadata"` +// Mapping represents an atomic relationship between a source entry and an optional target entry +type Mapping struct { + // id allows this mapping to be referenced by other elements + Id string `json:"id" yaml:"id"` - // target identifies the resource being evaluated - Target Resource `json:"target" yaml:"target"` + // source identifies the entry being mapped from + Source TypedEntry `json:"source" yaml:"source"` + + // target identifies the entry being mapped to; absent when relationship is no-match + Target *TypedEntry `json:"target,omitempty" yaml:"target,omitempty"` + + // relationship describes the nature or purpose of the mapping + Relationship RelationshipType `json:"relationship" yaml:"relationship"` + + // strength is the author's estimate of how completely the source entry satisfies the target entry; range 1-10 + Strength int64 `json:"strength,omitempty" yaml:"strength,omitempty"` + + ConfidenceLevel ConfidenceLevel `json:"confidence-level,omitempty" yaml:"confidence-level,omitempty"` + + // applicability constrains the contexts in which this mapping holds + Applicability []string `json:"applicability,omitempty" yaml:"applicability,omitempty"` + + // rationale explains why this relationship exists + Rationale string `json:"rationale,omitempty" yaml:"rationale,omitempty"` + + // remarks is general prose regarding this mapping + Remarks string `json:"remarks,omitempty" yaml:"remarks,omitempty"` +} + +// EntryReference identifies a specific entry within a referenced artifact +type TypedEntry struct { + // entry-id identifies the specific entry in the referenced artifact + EntryId string `json:"entry-id" yaml:"entry-id"` + + // entry-type identifies what kind of atomic unit this entry is + EntryType EntryType `json:"entry-type" yaml:"entry-type"` } diff --git a/guidance_catalog_yaml.go b/guidance_catalog_yaml.go index c86db45..4c27c7e 100644 --- a/guidance_catalog_yaml.go +++ b/guidance_catalog_yaml.go @@ -8,13 +8,13 @@ import "github.com/goccy/go-yaml" // - `document-type` -> `type` func (g *GuidanceCatalog) UnmarshalYAML(data []byte) error { type guidanceCatalogYAML struct { - Title string `yaml:"title"` - Metadata Metadata `yaml:"metadata"` - Extends []ArtifactMapping `yaml:"extends,omitempty"` - Imports []MultiEntryMapping `yaml:"imports,omitempty"` + Title string `yaml:"title"` + Metadata Metadata `yaml:"metadata"` + Extends []ArtifactMapping `yaml:"extends,omitempty"` + Imports []MultiEntryMapping `yaml:"imports,omitempty"` // Current schema uses `type`, older test data uses `document-type`. - Type GuidanceType `yaml:"type,omitempty"` + Type GuidanceType `yaml:"type,omitempty"` DocumentType GuidanceType `yaml:"document-type,omitempty"` FrontMatter string `yaml:"front-matter,omitempty"` @@ -52,4 +52,3 @@ func (g *GuidanceCatalog) UnmarshalYAML(data []byte) error { return nil } - diff --git a/guideline_yaml.go b/guideline_yaml.go index ab6cdba..9b2aaae 100644 --- a/guideline_yaml.go +++ b/guideline_yaml.go @@ -8,23 +8,23 @@ func (g *Guideline) UnmarshalYAML(data []byte) error { type guidelineYAML struct { Id string `yaml:"id"` - Title string `yaml:"title"` - Objective string `yaml:"objective"` - Group string `yaml:"group,omitempty"` - Family string `yaml:"family,omitempty"` + Title string `yaml:"title"` + Objective string `yaml:"objective"` + Group string `yaml:"group,omitempty"` + Family string `yaml:"family,omitempty"` - Recommendations []string `yaml:"recommendations,omitempty"` + Recommendations []string `yaml:"recommendations,omitempty"` Extends *EntryMapping `yaml:"extends,omitempty"` - Applicability []string `yaml:"applicability,omitempty"` - Rationale *Rationale `yaml:"rationale,omitempty"` + Applicability []string `yaml:"applicability,omitempty"` + Rationale *Rationale `yaml:"rationale,omitempty"` - Statements []Statement `yaml:"statements,omitempty"` + Statements []Statement `yaml:"statements,omitempty"` Principles []MultiEntryMapping `yaml:"principles,omitempty"` - Vectors []MultiEntryMapping `yaml:"vectors,omitempty"` - SeeAlso []string `yaml:"see-also,omitempty"` + Vectors []MultiEntryMapping `yaml:"vectors,omitempty"` + SeeAlso []string `yaml:"see-also,omitempty"` - State Lifecycle `yaml:"state"` - ReplacedBy *EntryMapping `yaml:"replaced-by,omitempty"` + State Lifecycle `yaml:"state"` + ReplacedBy *EntryMapping `yaml:"replaced-by,omitempty"` } var tmp guidelineYAML @@ -54,4 +54,3 @@ func (g *Guideline) UnmarshalYAML(data []byte) error { return nil } - From f5021522f9e4f753901940902d159dc908a3cff7 Mon Sep 17 00:00:00 2001 From: Jennifer Power Date: Sat, 21 Mar 2026 09:45:04 -0400 Subject: [PATCH 2/2] chore: updates Makefile for generation Tested with cue version v0.17.0-0.dev.0.20260320151706-d267795de4d3 Signed-off-by: Jennifer Power --- Makefile | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 017499d..87a7543 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ GOFLAGS := COVERFILE := coverage.out TESTCOVERAGE_THRESHOLD := 71 GOLANGCI_LINT := golangci-lint -SPECVERSION := v1.0.0-rc.1 +SPECVERSION := v1.0.0-rc.0 .PHONY: all tidy fmtcheck fmt vet lint test testcov race coverage-check build install generate ci-local clean help @@ -135,16 +135,11 @@ install: @echo " > Installing module/binaries" @go install ./... -update-schema: - @echo " > Pulling down Gemara CUE package" - @cue def github.com/gemaraproj/gemara@$(SPECVERSION) --outfile schema.cue --force - # Generate files from CUE schemas # Generates Go types from the Gemara CUE package with stable and experimental variants generate: @echo " > Generating types from Gemara CUE package" - @cue exp gengotypes schema.cue - @mv cue_types_gen.go generated_types.go + @cue exp gengotypes --outfile generated_types.go github.com/gemaraproj/gemara@$(SPECVERSION) @go run ./cmd/typestagger generated_types.go genlocal: