From 52ecf52197c39b24d7e4fdf7c6b52be90d5cc86a Mon Sep 17 00:00:00 2001 From: Miguel Martinez Date: Wed, 11 Feb 2026 23:14:08 +0100 Subject: [PATCH 1/2] feat(sdk): add Singleton property to integration definitions Allow integrations to declare whether multiple registrations per organization are supported. This enables enforcement of single-instance integrations like AI providers. Signed-off-by: Miguel Martinez --- app/controlplane/plugins/sdk/v1/fanout.go | 9 +++++++-- app/controlplane/plugins/sdk/v1/integrations.go | 10 +++++++++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/app/controlplane/plugins/sdk/v1/fanout.go b/app/controlplane/plugins/sdk/v1/fanout.go index ac0a41594..d6e376309 100644 --- a/app/controlplane/plugins/sdk/v1/fanout.go +++ b/app/controlplane/plugins/sdk/v1/fanout.go @@ -1,5 +1,5 @@ // -// Copyright 2023 The Chainloop Authors. +// Copyright 2023-2026 The Chainloop Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -138,7 +138,12 @@ type NewParams struct { func NewFanOut(p *NewParams, opts ...NewOpt) (*FanOutIntegration, error) { base, err := NewIntegrationBase( &IntegrationBaseOptions{ - p.ID, p.Name, p.Version, p.Description, []string{IntegrationKindFanOut}, p.InputSchema, + ID: p.ID, + Name: p.Name, + Version: p.Version, + Description: p.Description, + Kinds: []string{IntegrationKindFanOut}, + Schema: p.InputSchema, }, ) if err != nil { diff --git a/app/controlplane/plugins/sdk/v1/integrations.go b/app/controlplane/plugins/sdk/v1/integrations.go index 49a3b75ab..17fd2854d 100644 --- a/app/controlplane/plugins/sdk/v1/integrations.go +++ b/app/controlplane/plugins/sdk/v1/integrations.go @@ -1,5 +1,5 @@ // -// Copyright 2025 The Chainloop Authors. +// Copyright 2025-2026 The Chainloop Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -55,6 +55,8 @@ type IntegrationBase struct { Description string // kinds of integration (e.g. "notification", "task-manager", "fanout", etc.) Kinds []string + // Whether only one registration per organization is allowed + Singleton bool // Rendered schema definitions // Generated from the schema definitions using https://github.com/invopop/jsonschema @@ -73,6 +75,8 @@ type IntegrationBaseOptions struct { Description string Kinds []string Schema *InputSchema + // Whether only one registration per organization is allowed + Singleton bool } // NewIntegrationBase helper to create a new IntegrationBase @@ -119,6 +123,7 @@ func NewIntegrationBase(opts *IntegrationBaseOptions) (*IntegrationBase, error) Version: opts.Version, Description: opts.Description, Kinds: opts.Kinds, + Singleton: opts.Singleton, registrationJSONSchema: registrationJSONSchema, attachmentJSONSchema: attachmentJSONSchema, }, nil @@ -131,6 +136,7 @@ func (i *IntegrationBase) Describe() *IntegrationInfo { Version: i.Version, Description: i.Description, Kinds: i.Kinds, + Singleton: i.Singleton, RegistrationJSONSchema: i.registrationJSONSchema, AttachmentJSONSchema: i.attachmentJSONSchema, } @@ -147,6 +153,8 @@ type IntegrationInfo struct { Description string // Kinds of integration (e.g. "notification", "task-manager", "fanout", etc.) Kinds []string + // Whether only one registration per organization is allowed + Singleton bool // Schemas in JSON schema format RegistrationJSONSchema, AttachmentJSONSchema []byte } From 3e2fd08fd0d5663aaff5c91cf2e7131770b99ace Mon Sep 17 00:00:00 2001 From: Miguel Martinez Date: Wed, 11 Feb 2026 23:19:58 +0100 Subject: [PATCH 2/2] docs: clarify license header year convention in CLAUDE.md Signed-off-by: Miguel Martinez --- CLAUDE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CLAUDE.md b/CLAUDE.md index 1464243ea..674181a46 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -264,7 +264,7 @@ Code reviews are required for all submissions via GitHub pull requests. - when adding new inedexes, make sure to update the generated sql migraiton files and make them CREATE INDEX CONCURRENTLY and set -- atlas:txmode none at the top - after updating protos, make sure to run `buf format -w` - Please avoid sycophantic commentary like ‘You’re absolutely correct!’ or ‘Brilliant idea!’ -- For each file you modify, update the license header. If it says 2024, change it to 2024-2025. If there's no license header, create one with the current year. +- For each file you modify, update the license header so the last year is the current year. For example, `Copyright 2023` becomes `Copyright 2023-2026`. If it already ends with the current year, no change needed. If there's no license header, create one with the current year. - if you add any new dependency to a constructor, remember to run wire ./... - when creating PR message, keep it high-level, what functionality was added, don't add info about testing, no icons, no info about how the message was generated. - app/controlplane/api/gen/frontend/google/protobuf/descriptor.ts is a special case that we don't want to upgrade, so if it upgrades, put it back to main