From 0e1c1141634284ff8cb7e8ba4e8487a5b23ef8e7 Mon Sep 17 00:00:00 2001 From: "Jose I. Paris" Date: Tue, 17 Mar 2026 11:20:04 +0100 Subject: [PATCH 1/3] feat: wrap AI agent config in evidence envelope Use the standard custom schema structure for CHAINLOOP_AI_AGENT_CONFIG, matching the pattern used by CHAINLOOP_PR_INFO. The payload is now wrapped with chainloop.material.evidence.id, schema URL, and data fields. Signed-off-by: Jose I. Paris --- internal/aiagentconfig/aiagentconfig.go | 25 ++++++++++++-- internal/aiagentconfig/builder.go | 4 +-- .../crafter/collector_aiagentconfig.go | 3 +- .../materials/chainloop_ai_agent_config.go | 32 +++++++++++------ .../chainloop_ai_agent_config_test.go | 34 +++++++++++-------- .../testdata/ai-agent-config-claude.json | 30 +++++++++------- .../testdata/ai-agent-config-cursor.json | 30 +++++++++------- 7 files changed, 102 insertions(+), 56 deletions(-) diff --git a/internal/aiagentconfig/aiagentconfig.go b/internal/aiagentconfig/aiagentconfig.go index a25f31cc2..a89d840aa 100644 --- a/internal/aiagentconfig/aiagentconfig.go +++ b/internal/aiagentconfig/aiagentconfig.go @@ -23,6 +23,11 @@ const ( ConfigFileKindConfiguration ConfigFileKind = "configuration" // ConfigFileKindInstruction is for markdown instruction/rules files. ConfigFileKindInstruction ConfigFileKind = "instruction" + + // EvidenceID is the identifier for the AI agent config material type + EvidenceID = "CHAINLOOP_AI_AGENT_CONFIG" + // EvidenceSchemaURL is the URL to the JSON schema for AI agent config + EvidenceSchemaURL = "https://schemas.chainloop.dev/aiagentconfig/0.1/ai-agent-config.schema.json" ) // DiscoveredFile represents a file found during discovery, before reading its content. @@ -53,8 +58,8 @@ type ConfigFile struct { Content string `json:"content"` } -// Evidence is the AI agent configuration payload -type Evidence struct { +// Data is the AI agent configuration payload +type Data struct { SchemaVersion string `json:"schema_version"` Agent Agent `json:"agent"` ConfigHash string `json:"config_hash"` @@ -66,3 +71,19 @@ type Evidence struct { MCPServers any `json:"mcp_servers,omitempty"` Subagents any `json:"subagents,omitempty"` } + +// Evidence represents the complete evidence structure for AI agent config +type Evidence struct { + ID string `json:"chainloop.material.evidence.id"` + Schema string `json:"schema"` + Data Data `json:"data"` +} + +// NewEvidence creates a new Evidence instance +func NewEvidence(data Data) *Evidence { + return &Evidence{ + ID: EvidenceID, + Schema: EvidenceSchemaURL, + Data: data, + } +} diff --git a/internal/aiagentconfig/builder.go b/internal/aiagentconfig/builder.go index 197df65cc..0b0eca47d 100644 --- a/internal/aiagentconfig/builder.go +++ b/internal/aiagentconfig/builder.go @@ -33,7 +33,7 @@ import ( // basePath is the base directory, discovered contains files relative to basePath with their kinds. // agentName identifies the AI agent (e.g. "claude", "cursor"). // gitCtx may be nil if not in a git repository. -func Build(basePath string, discovered []DiscoveredFile, agentName string, gitCtx *GitContext) (*Evidence, error) { +func Build(basePath string, discovered []DiscoveredFile, agentName string, gitCtx *GitContext) (*Data, error) { // Resolve basePath to its real path so symlink comparisons are reliable realRoot, err := filepath.EvalSymlinks(basePath) if err != nil { @@ -81,7 +81,7 @@ func Build(basePath string, discovered []DiscoveredFile, agentName string, gitCt }) } - data := Evidence{ + data := Data{ SchemaVersion: string(schemavalidators.AIAgentConfigVersion0_1), Agent: Agent{Name: agentName}, ConfigHash: computeCombinedHash(hashes), diff --git a/pkg/attestation/crafter/collector_aiagentconfig.go b/pkg/attestation/crafter/collector_aiagentconfig.go index 2b88734d3..4b67f97e6 100644 --- a/pkg/attestation/crafter/collector_aiagentconfig.go +++ b/pkg/attestation/crafter/collector_aiagentconfig.go @@ -88,11 +88,12 @@ func (c *AIAgentConfigCollector) uploadAgentConfig( ctx context.Context, cr *Crafter, attestationID string, casBackend *casclient.CASBackend, agentName string, files []aiagentconfig.DiscoveredFile, gitCtx *aiagentconfig.GitContext, ) error { - evidence, err := aiagentconfig.Build(cr.WorkingDir(), files, agentName, gitCtx) + data, err := aiagentconfig.Build(cr.WorkingDir(), files, agentName, gitCtx) if err != nil { return fmt.Errorf("building AI agent config for %s: %w", agentName, err) } + evidence := aiagentconfig.NewEvidence(*data) jsonData, err := json.Marshal(evidence) if err != nil { return fmt.Errorf("marshaling AI agent config for %s: %w", agentName, err) diff --git a/pkg/attestation/crafter/materials/chainloop_ai_agent_config.go b/pkg/attestation/crafter/materials/chainloop_ai_agent_config.go index d639fb41b..a89e1e03b 100644 --- a/pkg/attestation/crafter/materials/chainloop_ai_agent_config.go +++ b/pkg/attestation/crafter/materials/chainloop_ai_agent_config.go @@ -22,6 +22,7 @@ import ( "os" schemaapi "github.com/chainloop-dev/chainloop/app/controlplane/api/workflowcontract/v1" + "github.com/chainloop-dev/chainloop/internal/aiagentconfig" "github.com/chainloop-dev/chainloop/internal/schemavalidators" api "github.com/chainloop-dev/chainloop/pkg/attestation/crafter/api/attestation/v1" "github.com/chainloop-dev/chainloop/pkg/casclient" @@ -55,12 +56,28 @@ func (c *ChainloopAIAgentConfigCrafter) Craft(ctx context.Context, artifactPath return nil, fmt.Errorf("can't open the file: %w", err) } - var rawData any - if err := json.Unmarshal(f, &rawData); err != nil { + // Unmarshal envelope, keeping data as raw JSON for schema validation + var envelope struct { + Data json.RawMessage `json:"data"` + } + if err := json.Unmarshal(f, &envelope); err != nil { c.logger.Debug().Err(err).Msg("error decoding file") return nil, fmt.Errorf("invalid JSON format: %w", err) } + // Unmarshal data into typed struct for agent name extraction + var data aiagentconfig.Data + if err := json.Unmarshal(envelope.Data, &data); err != nil { + c.logger.Debug().Err(err).Msg("error decoding data field") + return nil, fmt.Errorf("failed to unmarshal data: %w", err) + } + + // Validate using raw JSON to preserve unknown fields for strict schema validation + var rawData any + if err := json.Unmarshal(envelope.Data, &rawData); err != nil { + return nil, fmt.Errorf("failed to unmarshal data for validation: %w", err) + } + if err := schemavalidators.ValidateAIAgentConfig(rawData, schemavalidators.AIAgentConfigVersion0_1); err != nil { c.logger.Debug().Err(err).Msg("schema validation failed") return nil, fmt.Errorf("AI agent config validation failed: %w", err) @@ -71,14 +88,9 @@ func (c *ChainloopAIAgentConfigCrafter) Craft(ctx context.Context, artifactPath return nil, err } - // Extract agent name from the validated JSON and surface it as an annotation - var envelope struct { - Agent struct { - Name string `json:"name"` - } `json:"agent"` - } - if err := json.Unmarshal(f, &envelope); err == nil && envelope.Agent.Name != "" { - material.Annotations[annotationAIAgentName] = envelope.Agent.Name + // Surface agent name as an annotation + if data.Agent.Name != "" { + material.Annotations[annotationAIAgentName] = data.Agent.Name } return material, nil diff --git a/pkg/attestation/crafter/materials/chainloop_ai_agent_config_test.go b/pkg/attestation/crafter/materials/chainloop_ai_agent_config_test.go index ecd2d6499..7b27291a6 100644 --- a/pkg/attestation/crafter/materials/chainloop_ai_agent_config_test.go +++ b/pkg/attestation/crafter/materials/chainloop_ai_agent_config_test.go @@ -59,12 +59,12 @@ func TestNewChainloopAIAgentConfigCrafter_CorrectType(t *testing.T) { func TestChainloopAIAgentConfigCrafter_Validation(t *testing.T) { testCases := []struct { name string - data *aiagentconfig.Evidence + data *aiagentconfig.Data wantErr bool }{ { name: "valid full config", - data: &aiagentconfig.Evidence{ + data: &aiagentconfig.Data{ SchemaVersion: string(schemavalidators.AIAgentConfigVersion0_1), Agent: aiagentconfig.Agent{Name: "claude", Version: "4.0"}, ConfigHash: "abc123", @@ -88,7 +88,7 @@ func TestChainloopAIAgentConfigCrafter_Validation(t *testing.T) { }, { name: "valid minimal config", - data: &aiagentconfig.Evidence{ + data: &aiagentconfig.Data{ SchemaVersion: string(schemavalidators.AIAgentConfigVersion0_1), Agent: aiagentconfig.Agent{Name: "claude"}, ConfigHash: "abc123", @@ -107,7 +107,7 @@ func TestChainloopAIAgentConfigCrafter_Validation(t *testing.T) { }, { name: "valid cursor config", - data: &aiagentconfig.Evidence{ + data: &aiagentconfig.Data{ SchemaVersion: string(schemavalidators.AIAgentConfigVersion0_1), Agent: aiagentconfig.Agent{Name: "cursor"}, ConfigHash: "def456", @@ -126,7 +126,7 @@ func TestChainloopAIAgentConfigCrafter_Validation(t *testing.T) { }, { name: "valid cursor with multiple file types", - data: &aiagentconfig.Evidence{ + data: &aiagentconfig.Data{ SchemaVersion: string(schemavalidators.AIAgentConfigVersion0_1), Agent: aiagentconfig.Agent{Name: "cursor"}, ConfigHash: "ghi789", @@ -159,12 +159,12 @@ func TestChainloopAIAgentConfigCrafter_Validation(t *testing.T) { }, { name: "missing required fields", - data: &aiagentconfig.Evidence{}, + data: &aiagentconfig.Data{}, wantErr: true, }, { name: "empty config files", - data: &aiagentconfig.Evidence{ + data: &aiagentconfig.Data{ SchemaVersion: string(schemavalidators.AIAgentConfigVersion0_1), Agent: aiagentconfig.Agent{Name: "claude"}, ConfigHash: "abc123", @@ -220,9 +220,9 @@ func TestChainloopAIAgentConfigCrafter_InvalidSchema(t *testing.T) { crafter, err := NewChainloopAIAgentConfigCrafter(schema, nil, &logger) require.NoError(t, err) - // Valid JSON but missing required fields + // Valid envelope but data is missing required fields tmpFile := filepath.Join(t.TempDir(), "bad-schema.json") - require.NoError(t, os.WriteFile(tmpFile, []byte(`{"foo": "bar"}`), 0o600)) + require.NoError(t, os.WriteFile(tmpFile, []byte(`{"chainloop.material.evidence.id":"CHAINLOOP_AI_AGENT_CONFIG","schema":"test","data":{"foo":"bar"}}`), 0o600)) _, err = crafter.Craft(context.Background(), tmpFile) require.Error(t, err) @@ -253,12 +253,16 @@ func TestChainloopAIAgentConfigCrafter_RejectsExtraFields(t *testing.T) { require.NoError(t, err) payload := `{ - "schema_version": "0.1", - "agent": {"name": "claude"}, - "config_hash": "abc", - "captured_at": "2026-03-13T10:00:00Z", - "config_files": [{"path": "CLAUDE.md", "kind": "instruction", "sha256": "abc", "size": 1, "content": "Yg=="}], - "unknown_field": "should fail" + "chainloop.material.evidence.id": "CHAINLOOP_AI_AGENT_CONFIG", + "schema": "https://schemas.chainloop.dev/aiagentconfig/0.1/ai-agent-config.schema.json", + "data": { + "schema_version": "0.1", + "agent": {"name": "claude"}, + "config_hash": "abc", + "captured_at": "2026-03-13T10:00:00Z", + "config_files": [{"path": "CLAUDE.md", "kind": "instruction", "sha256": "abc", "size": 1, "content": "Yg=="}], + "unknown_field": "should fail" + } }` tmpFile := filepath.Join(t.TempDir(), "extra-fields.json") diff --git a/pkg/attestation/crafter/materials/testdata/ai-agent-config-claude.json b/pkg/attestation/crafter/materials/testdata/ai-agent-config-claude.json index 1e00d3dbf..65e55d972 100644 --- a/pkg/attestation/crafter/materials/testdata/ai-agent-config-claude.json +++ b/pkg/attestation/crafter/materials/testdata/ai-agent-config-claude.json @@ -1,15 +1,19 @@ { - "schema_version": "0.1", - "agent": {"name": "claude"}, - "config_hash": "abc123", - "captured_at": "2026-03-13T10:00:00Z", - "config_files": [ - { - "path": "CLAUDE.md", - "kind": "instruction", - "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - "size": 42, - "content": "IyBQcm9qZWN0IFJ1bGVz" - } - ] + "chainloop.material.evidence.id": "CHAINLOOP_AI_AGENT_CONFIG", + "schema": "https://schemas.chainloop.dev/aiagentconfig/0.1/ai-agent-config.schema.json", + "data": { + "schema_version": "0.1", + "agent": {"name": "claude"}, + "config_hash": "abc123", + "captured_at": "2026-03-13T10:00:00Z", + "config_files": [ + { + "path": "CLAUDE.md", + "kind": "instruction", + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "size": 42, + "content": "IyBQcm9qZWN0IFJ1bGVz" + } + ] + } } diff --git a/pkg/attestation/crafter/materials/testdata/ai-agent-config-cursor.json b/pkg/attestation/crafter/materials/testdata/ai-agent-config-cursor.json index 96159ce36..6f96df924 100644 --- a/pkg/attestation/crafter/materials/testdata/ai-agent-config-cursor.json +++ b/pkg/attestation/crafter/materials/testdata/ai-agent-config-cursor.json @@ -1,15 +1,19 @@ { - "schema_version": "0.1", - "agent": {"name": "cursor"}, - "config_hash": "def456", - "captured_at": "2026-03-13T10:00:00Z", - "config_files": [ - { - "path": ".cursor/rules/coding.md", - "kind": "instruction", - "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - "size": 20, - "content": "IyBDb2RpbmcgUnVsZXM=" - } - ] + "chainloop.material.evidence.id": "CHAINLOOP_AI_AGENT_CONFIG", + "schema": "https://schemas.chainloop.dev/aiagentconfig/0.1/ai-agent-config.schema.json", + "data": { + "schema_version": "0.1", + "agent": {"name": "cursor"}, + "config_hash": "def456", + "captured_at": "2026-03-13T10:00:00Z", + "config_files": [ + { + "path": ".cursor/rules/coding.md", + "kind": "instruction", + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "size": 20, + "content": "IyBDb2RpbmcgUnVsZXM=" + } + ] + } } From 1b0c31b0d8a871d64ec094f45b503a8d1f79996a Mon Sep 17 00:00:00 2001 From: "Jose I. Paris" Date: Tue, 17 Mar 2026 11:42:06 +0100 Subject: [PATCH 2/3] refactor: remove schema_version from AI agent config data The schema version is now conveyed by the evidence envelope's schema URL field, making the redundant schema_version field in the data payload unnecessary. Signed-off-by: Jose I. Paris --- internal/aiagentconfig/aiagentconfig.go | 11 +++--- internal/aiagentconfig/builder.go | 13 +++---- internal/aiagentconfig/builder_test.go | 2 - .../ai-agent-config-0.1.schema.json | 5 --- .../chainloop_ai_agent_config_test.go | 38 ++++++++----------- .../testdata/ai-agent-config-claude.json | 1 - .../testdata/ai-agent-config-cursor.json | 1 - 7 files changed, 26 insertions(+), 45 deletions(-) diff --git a/internal/aiagentconfig/aiagentconfig.go b/internal/aiagentconfig/aiagentconfig.go index a89d840aa..d07d5367a 100644 --- a/internal/aiagentconfig/aiagentconfig.go +++ b/internal/aiagentconfig/aiagentconfig.go @@ -60,12 +60,11 @@ type ConfigFile struct { // Data is the AI agent configuration payload type Data struct { - SchemaVersion string `json:"schema_version"` - Agent Agent `json:"agent"` - ConfigHash string `json:"config_hash"` - CapturedAt string `json:"captured_at"` - GitContext *GitContext `json:"git_context,omitempty"` - ConfigFiles []ConfigFile `json:"config_files"` + Agent Agent `json:"agent"` + ConfigHash string `json:"config_hash"` + CapturedAt string `json:"captured_at"` + GitContext *GitContext `json:"git_context,omitempty"` + ConfigFiles []ConfigFile `json:"config_files"` // Future fields for richer analysis Permissions any `json:"permissions,omitempty"` MCPServers any `json:"mcp_servers,omitempty"` diff --git a/internal/aiagentconfig/builder.go b/internal/aiagentconfig/builder.go index 0b0eca47d..317c8973c 100644 --- a/internal/aiagentconfig/builder.go +++ b/internal/aiagentconfig/builder.go @@ -25,8 +25,6 @@ import ( "sort" "strings" "time" - - "github.com/chainloop-dev/chainloop/internal/schemavalidators" ) // Build reads discovered files and constructs the AI agent config payload. @@ -82,12 +80,11 @@ func Build(basePath string, discovered []DiscoveredFile, agentName string, gitCt } data := Data{ - SchemaVersion: string(schemavalidators.AIAgentConfigVersion0_1), - Agent: Agent{Name: agentName}, - ConfigHash: computeCombinedHash(hashes), - CapturedAt: time.Now().UTC().Format(time.RFC3339), - GitContext: gitCtx, - ConfigFiles: configFiles, + Agent: Agent{Name: agentName}, + ConfigHash: computeCombinedHash(hashes), + CapturedAt: time.Now().UTC().Format(time.RFC3339), + GitContext: gitCtx, + ConfigFiles: configFiles, } return &data, nil diff --git a/internal/aiagentconfig/builder_test.go b/internal/aiagentconfig/builder_test.go index 02607dcae..d1ff4914b 100644 --- a/internal/aiagentconfig/builder_test.go +++ b/internal/aiagentconfig/builder_test.go @@ -53,7 +53,6 @@ func TestBuild(t *testing.T) { }, "claude", gitCtx) require.NoError(t, err) - assert.Equal(t, "0.1", data.SchemaVersion) assert.Equal(t, "claude", data.Agent.Name) assert.NotEmpty(t, data.CapturedAt) assert.NotEmpty(t, data.ConfigHash) @@ -136,7 +135,6 @@ func TestBuildJSONFormat(t *testing.T) { var raw map[string]any require.NoError(t, json.Unmarshal(jsonData, &raw)) - assert.NotNil(t, raw["schema_version"]) assert.NotNil(t, raw["agent"]) assert.NotNil(t, raw["config_hash"]) assert.NotNil(t, raw["captured_at"]) diff --git a/internal/schemavalidators/internal_schemas/aiagentconfig/ai-agent-config-0.1.schema.json b/internal/schemavalidators/internal_schemas/aiagentconfig/ai-agent-config-0.1.schema.json index c56211f2b..6a5a1b817 100644 --- a/internal/schemavalidators/internal_schemas/aiagentconfig/ai-agent-config-0.1.schema.json +++ b/internal/schemavalidators/internal_schemas/aiagentconfig/ai-agent-config-0.1.schema.json @@ -5,17 +5,12 @@ "title": "AI Agent Configuration", "description": "Schema for AI agent configuration data collected during attestation", "required": [ - "schema_version", "agent", "config_hash", "captured_at", "config_files" ], "properties": { - "schema_version": { - "type": "string", - "description": "Schema version identifier" - }, "agent": { "type": "object", "description": "AI agent provider information", diff --git a/pkg/attestation/crafter/materials/chainloop_ai_agent_config_test.go b/pkg/attestation/crafter/materials/chainloop_ai_agent_config_test.go index 7b27291a6..484be6ec8 100644 --- a/pkg/attestation/crafter/materials/chainloop_ai_agent_config_test.go +++ b/pkg/attestation/crafter/materials/chainloop_ai_agent_config_test.go @@ -65,10 +65,9 @@ func TestChainloopAIAgentConfigCrafter_Validation(t *testing.T) { { name: "valid full config", data: &aiagentconfig.Data{ - SchemaVersion: string(schemavalidators.AIAgentConfigVersion0_1), - Agent: aiagentconfig.Agent{Name: "claude", Version: "4.0"}, - ConfigHash: "abc123", - CapturedAt: "2026-03-13T10:00:00Z", + Agent: aiagentconfig.Agent{Name: "claude", Version: "4.0"}, + ConfigHash: "abc123", + CapturedAt: "2026-03-13T10:00:00Z", GitContext: &aiagentconfig.GitContext{ Repository: "https://github.com/org/repo", Branch: "main", @@ -89,10 +88,9 @@ func TestChainloopAIAgentConfigCrafter_Validation(t *testing.T) { { name: "valid minimal config", data: &aiagentconfig.Data{ - SchemaVersion: string(schemavalidators.AIAgentConfigVersion0_1), - Agent: aiagentconfig.Agent{Name: "claude"}, - ConfigHash: "abc123", - CapturedAt: "2026-03-13T10:00:00Z", + Agent: aiagentconfig.Agent{Name: "claude"}, + ConfigHash: "abc123", + CapturedAt: "2026-03-13T10:00:00Z", ConfigFiles: []aiagentconfig.ConfigFile{ { Path: "CLAUDE.md", @@ -108,10 +106,9 @@ func TestChainloopAIAgentConfigCrafter_Validation(t *testing.T) { { name: "valid cursor config", data: &aiagentconfig.Data{ - SchemaVersion: string(schemavalidators.AIAgentConfigVersion0_1), - Agent: aiagentconfig.Agent{Name: "cursor"}, - ConfigHash: "def456", - CapturedAt: "2026-03-13T10:00:00Z", + Agent: aiagentconfig.Agent{Name: "cursor"}, + ConfigHash: "def456", + CapturedAt: "2026-03-13T10:00:00Z", ConfigFiles: []aiagentconfig.ConfigFile{ { Path: ".cursor/rules/coding.md", @@ -127,10 +124,9 @@ func TestChainloopAIAgentConfigCrafter_Validation(t *testing.T) { { name: "valid cursor with multiple file types", data: &aiagentconfig.Data{ - SchemaVersion: string(schemavalidators.AIAgentConfigVersion0_1), - Agent: aiagentconfig.Agent{Name: "cursor"}, - ConfigHash: "ghi789", - CapturedAt: "2026-03-13T10:00:00Z", + Agent: aiagentconfig.Agent{Name: "cursor"}, + ConfigHash: "ghi789", + CapturedAt: "2026-03-13T10:00:00Z", ConfigFiles: []aiagentconfig.ConfigFile{ { Path: ".cursor/rules/react.mdc", @@ -165,11 +161,10 @@ func TestChainloopAIAgentConfigCrafter_Validation(t *testing.T) { { name: "empty config files", data: &aiagentconfig.Data{ - SchemaVersion: string(schemavalidators.AIAgentConfigVersion0_1), - Agent: aiagentconfig.Agent{Name: "claude"}, - ConfigHash: "abc123", - CapturedAt: "2026-03-13T10:00:00Z", - ConfigFiles: []aiagentconfig.ConfigFile{}, + Agent: aiagentconfig.Agent{Name: "claude"}, + ConfigHash: "abc123", + CapturedAt: "2026-03-13T10:00:00Z", + ConfigFiles: []aiagentconfig.ConfigFile{}, }, wantErr: false, }, @@ -256,7 +251,6 @@ func TestChainloopAIAgentConfigCrafter_RejectsExtraFields(t *testing.T) { "chainloop.material.evidence.id": "CHAINLOOP_AI_AGENT_CONFIG", "schema": "https://schemas.chainloop.dev/aiagentconfig/0.1/ai-agent-config.schema.json", "data": { - "schema_version": "0.1", "agent": {"name": "claude"}, "config_hash": "abc", "captured_at": "2026-03-13T10:00:00Z", diff --git a/pkg/attestation/crafter/materials/testdata/ai-agent-config-claude.json b/pkg/attestation/crafter/materials/testdata/ai-agent-config-claude.json index 65e55d972..f835a01cc 100644 --- a/pkg/attestation/crafter/materials/testdata/ai-agent-config-claude.json +++ b/pkg/attestation/crafter/materials/testdata/ai-agent-config-claude.json @@ -2,7 +2,6 @@ "chainloop.material.evidence.id": "CHAINLOOP_AI_AGENT_CONFIG", "schema": "https://schemas.chainloop.dev/aiagentconfig/0.1/ai-agent-config.schema.json", "data": { - "schema_version": "0.1", "agent": {"name": "claude"}, "config_hash": "abc123", "captured_at": "2026-03-13T10:00:00Z", diff --git a/pkg/attestation/crafter/materials/testdata/ai-agent-config-cursor.json b/pkg/attestation/crafter/materials/testdata/ai-agent-config-cursor.json index 6f96df924..c9b6145c7 100644 --- a/pkg/attestation/crafter/materials/testdata/ai-agent-config-cursor.json +++ b/pkg/attestation/crafter/materials/testdata/ai-agent-config-cursor.json @@ -2,7 +2,6 @@ "chainloop.material.evidence.id": "CHAINLOOP_AI_AGENT_CONFIG", "schema": "https://schemas.chainloop.dev/aiagentconfig/0.1/ai-agent-config.schema.json", "data": { - "schema_version": "0.1", "agent": {"name": "cursor"}, "config_hash": "def456", "captured_at": "2026-03-13T10:00:00Z", From 9249788c06e32d790860f7964c0caa444e5b8232 Mon Sep 17 00:00:00 2001 From: "Jose I. Paris" Date: Tue, 17 Mar 2026 13:26:28 +0100 Subject: [PATCH 3/3] fix tests Signed-off-by: Jose I. Paris --- .../testdata/ai_agent_config_empty_config_files.json | 1 - .../schemavalidators/testdata/ai_agent_config_extra_fields.json | 1 - internal/schemavalidators/testdata/ai_agent_config_minimal.json | 1 - internal/schemavalidators/testdata/ai_agent_config_valid.json | 1 - 4 files changed, 4 deletions(-) diff --git a/internal/schemavalidators/testdata/ai_agent_config_empty_config_files.json b/internal/schemavalidators/testdata/ai_agent_config_empty_config_files.json index 0720cb106..a206fb704 100644 --- a/internal/schemavalidators/testdata/ai_agent_config_empty_config_files.json +++ b/internal/schemavalidators/testdata/ai_agent_config_empty_config_files.json @@ -1,5 +1,4 @@ { - "schema_version": "0.1", "agent": { "name": "claude" }, diff --git a/internal/schemavalidators/testdata/ai_agent_config_extra_fields.json b/internal/schemavalidators/testdata/ai_agent_config_extra_fields.json index 567ccf50b..7794f8d72 100644 --- a/internal/schemavalidators/testdata/ai_agent_config_extra_fields.json +++ b/internal/schemavalidators/testdata/ai_agent_config_extra_fields.json @@ -1,5 +1,4 @@ { - "schema_version": "0.1", "agent": { "name": "claude" }, diff --git a/internal/schemavalidators/testdata/ai_agent_config_minimal.json b/internal/schemavalidators/testdata/ai_agent_config_minimal.json index 2f1916261..7eeb4f526 100644 --- a/internal/schemavalidators/testdata/ai_agent_config_minimal.json +++ b/internal/schemavalidators/testdata/ai_agent_config_minimal.json @@ -1,5 +1,4 @@ { - "schema_version": "0.1", "agent": { "name": "claude" }, diff --git a/internal/schemavalidators/testdata/ai_agent_config_valid.json b/internal/schemavalidators/testdata/ai_agent_config_valid.json index 75ab387a2..a51da8ae9 100644 --- a/internal/schemavalidators/testdata/ai_agent_config_valid.json +++ b/internal/schemavalidators/testdata/ai_agent_config_valid.json @@ -1,5 +1,4 @@ { - "schema_version": "0.1", "agent": { "name": "claude", "version": "4.0"