Initial infra design project config

This is a prototype that started with project_mgmt/project.proto,
trimmed it down a bit to focus on key concepts, then brought in the
concept of build-targets and branches that are tied to the design
project.

The expectation is this will eventually drive CI for factory/firmware,
but also provide accessible config for analysis (e.g. what devices share
what firmware branches, ...).

For release milestones, they will include targeted designprojects, which
will then tie the system build target info, which will then track the
branch defined by the milestones themselves.

Change-Id: I00952042e26fca8e9464cd7ea567927abfe42c71
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/infra/proto/+/2400918
Tested-by: C Shapiro <shapiroc@chromium.org>
Reviewed-by: David Burger <dburger@chromium.org>
Commit-Queue: C Shapiro <shapiroc@chromium.org>
Auto-Submit: C Shapiro <shapiroc@chromium.org>
diff --git a/go/prototype/config_bundle.pb.go b/go/prototype/config_bundle.pb.go
index 9b38ba3..2c9cb90 100644
--- a/go/prototype/config_bundle.pb.go
+++ b/go/prototype/config_bundle.pb.go
@@ -24,6 +24,7 @@
 	Clients              []*Client        `protobuf:"bytes,1,rep,name=clients,proto3" json:"clients,omitempty"`
 	ClientProfiles       []*ClientProfile `protobuf:"bytes,2,rep,name=client_profiles,json=clientProfiles,proto3" json:"client_profiles,omitempty"`
 	Milestones           []*Milestone     `protobuf:"bytes,3,rep,name=milestones,proto3" json:"milestones,omitempty"`
+	DesignProjects       []*DesignProject `protobuf:"bytes,4,rep,name=design_projects,json=designProjects,proto3" json:"design_projects,omitempty"`
 	XXX_NoUnkeyedLiteral struct{}         `json:"-"`
 	XXX_unrecognized     []byte           `json:"-"`
 	XXX_sizecache        int32            `json:"-"`
@@ -75,6 +76,13 @@
 	return nil
 }
 
+func (m *ConfigBundle) GetDesignProjects() []*DesignProject {
+	if m != nil {
+		return m.DesignProjects
+	}
+	return nil
+}
+
 func init() {
 	proto.RegisterType((*ConfigBundle)(nil), "prototype.ConfigBundle")
 }
@@ -82,19 +90,21 @@
 func init() { proto.RegisterFile("prototype/config_bundle.proto", fileDescriptor_fa31c70b5e51112b) }
 
 var fileDescriptor_fa31c70b5e51112b = []byte{
-	// 217 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x2d, 0x28, 0xca, 0x2f,
-	0xc9, 0x2f, 0xa9, 0x2c, 0x48, 0xd5, 0x4f, 0xce, 0xcf, 0x4b, 0xcb, 0x4c, 0x8f, 0x4f, 0x2a, 0xcd,
-	0x4b, 0xc9, 0x49, 0xd5, 0x03, 0x8b, 0x0b, 0x71, 0xc2, 0xa5, 0xa5, 0xc4, 0x90, 0x54, 0xe6, 0x64,
-	0xa6, 0xe6, 0x95, 0x40, 0x94, 0x48, 0xc9, 0xa1, 0x8b, 0xc7, 0x17, 0x14, 0xe5, 0xa7, 0x65, 0xc2,
-	0x8c, 0x90, 0x92, 0x44, 0xc8, 0xe7, 0x66, 0xe6, 0xa4, 0x16, 0x97, 0xe4, 0xe7, 0x41, 0xa5, 0x94,
-	0xb6, 0x30, 0x72, 0xf1, 0x38, 0x83, 0x6d, 0x75, 0x02, 0x5b, 0x2a, 0xa4, 0xcd, 0xc5, 0x0e, 0x31,
-	0xa3, 0x58, 0x82, 0x51, 0x81, 0x59, 0x83, 0xdb, 0x48, 0x50, 0x0f, 0xae, 0x5b, 0xcf, 0x19, 0x2c,
-	0x13, 0x04, 0x53, 0x21, 0xe4, 0xc8, 0xc5, 0x8f, 0x6a, 0x61, 0xb1, 0x04, 0x13, 0x58, 0x93, 0x04,
-	0x86, 0xa6, 0x00, 0x88, 0x82, 0x20, 0xbe, 0x64, 0x64, 0x6e, 0xb1, 0x90, 0x09, 0x17, 0x17, 0xdc,
-	0x4d, 0xc5, 0x12, 0xcc, 0x60, 0xdd, 0x22, 0x48, 0xba, 0x7d, 0x61, 0x92, 0x41, 0x48, 0xea, 0x9c,
-	0x4c, 0xa3, 0x8c, 0xd3, 0xf3, 0xf5, 0x92, 0x33, 0x8a, 0xf2, 0x73, 0x33, 0x4b, 0x73, 0xf5, 0xf2,
-	0x8b, 0xd2, 0xf5, 0x61, 0x9c, 0xfc, 0x62, 0xfd, 0xcc, 0xbc, 0xb4, 0xa2, 0x44, 0x7d, 0xb0, 0x19,
-	0xfa, 0xe9, 0xf9, 0xfa, 0x70, 0xc3, 0x92, 0xd8, 0xc0, 0x4c, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff,
-	0xff, 0xf5, 0xad, 0x22, 0xc9, 0x73, 0x01, 0x00, 0x00,
+	// 251 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x8f, 0x41, 0x4b, 0xc4, 0x30,
+	0x10, 0x85, 0x59, 0x57, 0x14, 0xa3, 0xac, 0x58, 0x44, 0x62, 0x41, 0x11, 0x4f, 0x82, 0x90, 0x80,
+	0xab, 0x3f, 0xc0, 0x5d, 0xaf, 0xc2, 0xd2, 0xa3, 0x97, 0xc5, 0x6d, 0xd3, 0x18, 0x69, 0x33, 0x25,
+	0xd3, 0x3d, 0xf8, 0xcb, 0xbd, 0xca, 0x4e, 0x4c, 0x4c, 0xed, 0x2d, 0x33, 0xef, 0x7b, 0x6f, 0x5e,
+	0xd8, 0x55, 0xe7, 0xa0, 0x87, 0xfe, 0xab, 0x53, 0xb2, 0x04, 0x5b, 0x1b, 0xbd, 0xde, 0x6c, 0x6d,
+	0xd5, 0x28, 0x41, 0xfb, 0xec, 0x28, 0xca, 0xf9, 0x45, 0x42, 0x36, 0x46, 0xd9, 0xde, 0x23, 0xf9,
+	0xf5, 0xff, 0xfd, 0xba, 0x73, 0x50, 0x9b, 0x10, 0x91, 0x5f, 0xfe, 0xe9, 0xad, 0x69, 0x14, 0xf6,
+	0x60, 0xd5, 0xd8, 0x5a, 0x29, 0x34, 0xda, 0xee, 0xac, 0x9f, 0xaa, 0xfc, 0x8d, 0xbe, 0xfd, 0x9e,
+	0xb0, 0x93, 0x25, 0xb5, 0x5a, 0x50, 0xa9, 0xec, 0x9e, 0x1d, 0xfa, 0x1b, 0xc8, 0x27, 0x37, 0xd3,
+	0xbb, 0xe3, 0x87, 0x33, 0x11, 0x23, 0xc4, 0x92, 0x94, 0x22, 0x10, 0xd9, 0x33, 0x3b, 0x1d, 0x16,
+	0x42, 0xbe, 0x47, 0x26, 0x3e, 0x32, 0xad, 0x3c, 0x50, 0xcc, 0xca, 0x74, 0xc4, 0xec, 0x91, 0xb1,
+	0xd8, 0x19, 0xf9, 0x94, 0xdc, 0xe7, 0x89, 0xfb, 0x35, 0x88, 0x45, 0xc2, 0xed, 0x0e, 0x0f, 0xbf,
+	0x83, 0x7c, 0x7f, 0x74, 0xf8, 0x85, 0x88, 0x95, 0x07, 0x8a, 0x59, 0x95, 0x8e, 0xb8, 0x78, 0x7a,
+	0x9b, 0x6b, 0x10, 0xe5, 0x87, 0x83, 0xd6, 0x6c, 0x5b, 0x01, 0x4e, 0xcb, 0x30, 0x00, 0x4a, 0x63,
+	0x6b, 0xf7, 0x2e, 0x29, 0x4b, 0x6a, 0x90, 0x31, 0x74, 0x73, 0x40, 0xcf, 0xf9, 0x4f, 0x00, 0x00,
+	0x00, 0xff, 0xff, 0x9c, 0x00, 0xbc, 0x3a, 0xd6, 0x01, 0x00, 0x00,
 }
diff --git a/go/prototype/design_project.pb.go b/go/prototype/design_project.pb.go
new file mode 100644
index 0000000..7a7f444
--- /dev/null
+++ b/go/prototype/design_project.pb.go
@@ -0,0 +1,249 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: prototype/design_project.proto
+
+package prototype
+
+import (
+	fmt "fmt"
+	proto "github.com/golang/protobuf/proto"
+	math "math"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
+
+// Defines the metadata for a project, which ultimately controls how this
+// project is managed throughout the infrastructure.
+type DesignProject struct {
+	// Defines the human-readable name for the project.
+	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+	// Defines the git-repo path for the project.
+	Repo string `protobuf:"bytes,2,opt,name=repo,proto3" json:"repo,omitempty"`
+	// Defines the path that stores all of the project configuration.
+	// Relative to the git-repo
+	ConfigPath string `protobuf:"bytes,3,opt,name=config_path,json=configPath,proto3" json:"config_path,omitempty"`
+	// Define the project's local_manifest.
+	RepoManifestPath string `protobuf:"bytes,4,opt,name=repo_manifest_path,json=repoManifestPath,proto3" json:"repo_manifest_path,omitempty"`
+	// The Google Storage bucket for artifacts from the project's builds.
+	GsBucket string `protobuf:"bytes,5,opt,name=gs_bucket,json=gsBucket,proto3" json:"gs_bucket,omitempty"`
+	// Defines config needed to maintain firmware builders for the project.
+	FirmwareConfig *DesignProject_FirmwareConfig `protobuf:"bytes,6,opt,name=firmware_config,json=firmwareConfig,proto3" json:"firmware_config,omitempty"`
+	// Define factory build config needed for manufacturing verification.
+	FactoryConfig        *DesignProject_FactoryConfig `protobuf:"bytes,7,opt,name=factory_config,json=factoryConfig,proto3" json:"factory_config,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}                     `json:"-"`
+	XXX_unrecognized     []byte                       `json:"-"`
+	XXX_sizecache        int32                        `json:"-"`
+}
+
+func (m *DesignProject) Reset()         { *m = DesignProject{} }
+func (m *DesignProject) String() string { return proto.CompactTextString(m) }
+func (*DesignProject) ProtoMessage()    {}
+func (*DesignProject) Descriptor() ([]byte, []int) {
+	return fileDescriptor_f430eea6a6b81e0b, []int{0}
+}
+
+func (m *DesignProject) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_DesignProject.Unmarshal(m, b)
+}
+func (m *DesignProject) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_DesignProject.Marshal(b, m, deterministic)
+}
+func (m *DesignProject) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_DesignProject.Merge(m, src)
+}
+func (m *DesignProject) XXX_Size() int {
+	return xxx_messageInfo_DesignProject.Size(m)
+}
+func (m *DesignProject) XXX_DiscardUnknown() {
+	xxx_messageInfo_DesignProject.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_DesignProject proto.InternalMessageInfo
+
+func (m *DesignProject) GetName() string {
+	if m != nil {
+		return m.Name
+	}
+	return ""
+}
+
+func (m *DesignProject) GetRepo() string {
+	if m != nil {
+		return m.Repo
+	}
+	return ""
+}
+
+func (m *DesignProject) GetConfigPath() string {
+	if m != nil {
+		return m.ConfigPath
+	}
+	return ""
+}
+
+func (m *DesignProject) GetRepoManifestPath() string {
+	if m != nil {
+		return m.RepoManifestPath
+	}
+	return ""
+}
+
+func (m *DesignProject) GetGsBucket() string {
+	if m != nil {
+		return m.GsBucket
+	}
+	return ""
+}
+
+func (m *DesignProject) GetFirmwareConfig() *DesignProject_FirmwareConfig {
+	if m != nil {
+		return m.FirmwareConfig
+	}
+	return nil
+}
+
+func (m *DesignProject) GetFactoryConfig() *DesignProject_FactoryConfig {
+	if m != nil {
+		return m.FactoryConfig
+	}
+	return nil
+}
+
+type DesignProject_FirmwareConfig struct {
+	// Defines the firmware branch that will be maintained for the project.
+	FirmwareBranch       string   `protobuf:"bytes,1,opt,name=firmware_branch,json=firmwareBranch,proto3" json:"firmware_branch,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *DesignProject_FirmwareConfig) Reset()         { *m = DesignProject_FirmwareConfig{} }
+func (m *DesignProject_FirmwareConfig) String() string { return proto.CompactTextString(m) }
+func (*DesignProject_FirmwareConfig) ProtoMessage()    {}
+func (*DesignProject_FirmwareConfig) Descriptor() ([]byte, []int) {
+	return fileDescriptor_f430eea6a6b81e0b, []int{0, 0}
+}
+
+func (m *DesignProject_FirmwareConfig) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_DesignProject_FirmwareConfig.Unmarshal(m, b)
+}
+func (m *DesignProject_FirmwareConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_DesignProject_FirmwareConfig.Marshal(b, m, deterministic)
+}
+func (m *DesignProject_FirmwareConfig) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_DesignProject_FirmwareConfig.Merge(m, src)
+}
+func (m *DesignProject_FirmwareConfig) XXX_Size() int {
+	return xxx_messageInfo_DesignProject_FirmwareConfig.Size(m)
+}
+func (m *DesignProject_FirmwareConfig) XXX_DiscardUnknown() {
+	xxx_messageInfo_DesignProject_FirmwareConfig.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_DesignProject_FirmwareConfig proto.InternalMessageInfo
+
+func (m *DesignProject_FirmwareConfig) GetFirmwareBranch() string {
+	if m != nil {
+		return m.FirmwareBranch
+	}
+	return ""
+}
+
+type DesignProject_FactoryConfig struct {
+	// Defines the factory branch that will be maintained for the project.
+	FactoryBranch string `protobuf:"bytes,1,opt,name=factory_branch,json=factoryBranch,proto3" json:"factory_branch,omitempty"`
+	// A key in the project.yaml metadata file, to look up the branch, path,
+	// etc. For example, to match the entry in the project.yaml file:
+	//
+	// MILKYWAY:
+	//   board: GALAXY
+	//   branch: master
+	//   version: 3
+	//   path: v3/MILKYWAY
+	//
+	// project_key should be 'MILKYWAY'. The matching is case-insensitive.
+	HwidProjectKey       string   `protobuf:"bytes,2,opt,name=hwid_project_key,json=hwidProjectKey,proto3" json:"hwid_project_key,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *DesignProject_FactoryConfig) Reset()         { *m = DesignProject_FactoryConfig{} }
+func (m *DesignProject_FactoryConfig) String() string { return proto.CompactTextString(m) }
+func (*DesignProject_FactoryConfig) ProtoMessage()    {}
+func (*DesignProject_FactoryConfig) Descriptor() ([]byte, []int) {
+	return fileDescriptor_f430eea6a6b81e0b, []int{0, 1}
+}
+
+func (m *DesignProject_FactoryConfig) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_DesignProject_FactoryConfig.Unmarshal(m, b)
+}
+func (m *DesignProject_FactoryConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_DesignProject_FactoryConfig.Marshal(b, m, deterministic)
+}
+func (m *DesignProject_FactoryConfig) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_DesignProject_FactoryConfig.Merge(m, src)
+}
+func (m *DesignProject_FactoryConfig) XXX_Size() int {
+	return xxx_messageInfo_DesignProject_FactoryConfig.Size(m)
+}
+func (m *DesignProject_FactoryConfig) XXX_DiscardUnknown() {
+	xxx_messageInfo_DesignProject_FactoryConfig.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_DesignProject_FactoryConfig proto.InternalMessageInfo
+
+func (m *DesignProject_FactoryConfig) GetFactoryBranch() string {
+	if m != nil {
+		return m.FactoryBranch
+	}
+	return ""
+}
+
+func (m *DesignProject_FactoryConfig) GetHwidProjectKey() string {
+	if m != nil {
+		return m.HwidProjectKey
+	}
+	return ""
+}
+
+func init() {
+	proto.RegisterType((*DesignProject)(nil), "prototype.DesignProject")
+	proto.RegisterType((*DesignProject_FirmwareConfig)(nil), "prototype.DesignProject.FirmwareConfig")
+	proto.RegisterType((*DesignProject_FactoryConfig)(nil), "prototype.DesignProject.FactoryConfig")
+}
+
+func init() { proto.RegisterFile("prototype/design_project.proto", fileDescriptor_f430eea6a6b81e0b) }
+
+var fileDescriptor_f430eea6a6b81e0b = []byte{
+	// 332 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x91, 0x41, 0x4f, 0xc2, 0x40,
+	0x10, 0x85, 0x83, 0x20, 0xca, 0x10, 0x2a, 0xd9, 0x53, 0x83, 0x89, 0x12, 0x13, 0x85, 0x83, 0x69,
+	0x13, 0x89, 0x07, 0xaf, 0x68, 0xbc, 0x18, 0x12, 0xc2, 0xd1, 0x4b, 0x5d, 0xca, 0xee, 0x76, 0x25,
+	0xed, 0x36, 0xdb, 0x25, 0xa4, 0x3f, 0xd7, 0x7f, 0x62, 0x3a, 0xbb, 0xad, 0xf4, 0xe0, 0x6d, 0xe6,
+	0xbd, 0xaf, 0x6f, 0x66, 0xba, 0x70, 0x93, 0x6b, 0x65, 0x94, 0x29, 0x73, 0x16, 0xee, 0x58, 0x21,
+	0x45, 0x16, 0xe5, 0x5a, 0x7d, 0xb3, 0xd8, 0x04, 0x68, 0x90, 0x41, 0xe3, 0xdf, 0xfd, 0x74, 0x61,
+	0xf4, 0x86, 0xcc, 0xda, 0x22, 0x84, 0x40, 0x2f, 0xa3, 0x29, 0xf3, 0x3b, 0xd3, 0xce, 0x7c, 0xb0,
+	0xc1, 0xba, 0xd2, 0x34, 0xcb, 0x95, 0x7f, 0x66, 0xb5, 0xaa, 0x26, 0xb7, 0x30, 0x8c, 0x55, 0xc6,
+	0xa5, 0x88, 0x72, 0x6a, 0x12, 0xbf, 0x8b, 0x16, 0x58, 0x69, 0x4d, 0x4d, 0x42, 0x1e, 0x81, 0x54,
+	0x60, 0x94, 0xd2, 0x4c, 0x72, 0x56, 0x18, 0xcb, 0xf5, 0x90, 0x1b, 0x57, 0xce, 0xca, 0x19, 0x48,
+	0x5f, 0xc3, 0x40, 0x14, 0xd1, 0xf6, 0x10, 0xef, 0x99, 0xf1, 0xcf, 0x11, 0xba, 0x14, 0xc5, 0x12,
+	0x7b, 0xb2, 0x86, 0x2b, 0x2e, 0x75, 0x7a, 0xa4, 0x9a, 0x45, 0x76, 0x82, 0xdf, 0x9f, 0x76, 0xe6,
+	0xc3, 0xa7, 0x59, 0xd0, 0x9c, 0x12, 0xb4, 0xce, 0x08, 0xde, 0x1d, 0xff, 0x8a, 0xf8, 0xc6, 0xe3,
+	0xad, 0x9e, 0xac, 0xc0, 0xe3, 0x34, 0x36, 0x4a, 0x97, 0x75, 0xe0, 0x05, 0x06, 0x3e, 0xfc, 0x1f,
+	0x68, 0x71, 0x97, 0x37, 0xe2, 0xa7, 0xed, 0xe4, 0x05, 0xbc, 0xf6, 0x40, 0x32, 0x3b, 0x59, 0x79,
+	0xab, 0x69, 0x16, 0x27, 0xee, 0x8f, 0x36, 0x9b, 0x2c, 0x51, 0x9d, 0x7c, 0xc1, 0xa8, 0x15, 0x4d,
+	0xee, 0xff, 0x56, 0x6b, 0x7d, 0x58, 0x8f, 0xb4, 0xdf, 0x91, 0x39, 0x8c, 0x93, 0xa3, 0xdc, 0xd5,
+	0x4f, 0x1b, 0xed, 0x59, 0xe9, 0xde, 0xc7, 0xab, 0x74, 0xb7, 0xf6, 0x07, 0x2b, 0x97, 0xcf, 0x9f,
+	0x0b, 0xa1, 0x82, 0x38, 0xd1, 0x2a, 0x95, 0x87, 0x34, 0x50, 0x5a, 0x84, 0x75, 0xa3, 0x8a, 0x50,
+	0x66, 0x5c, 0xd3, 0x10, 0xaf, 0x0e, 0x85, 0x0a, 0x9b, 0xf3, 0xb7, 0x7d, 0x2c, 0x17, 0xbf, 0x01,
+	0x00, 0x00, 0xff, 0xff, 0x9a, 0x79, 0x10, 0x90, 0x4e, 0x02, 0x00, 0x00,
+}
diff --git a/src/prototype/config_bundle.proto b/src/prototype/config_bundle.proto
index 29dbce0..0e14151 100644
--- a/src/prototype/config_bundle.proto
+++ b/src/prototype/config_bundle.proto
@@ -11,9 +11,11 @@
 import "prototype/client.proto";
 import "prototype/client_profile.proto";
 import "prototype/milestone.proto";
+import "prototype/design_project.proto";
 
 message ConfigBundle {
   repeated Client clients = 1;
   repeated ClientProfile client_profiles = 2;
   repeated Milestone milestones = 3;
+  repeated DesignProject design_projects = 4;
 }
diff --git a/src/prototype/design_project.proto b/src/prototype/design_project.proto
new file mode 100644
index 0000000..f4f5384
--- /dev/null
+++ b/src/prototype/design_project.proto
@@ -0,0 +1,53 @@
+// Copyright 2020 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+syntax = "proto3";
+
+package prototype;
+
+option go_package = "go.chromium.org/chromiumos/infra/proto/go/prototype";
+
+// Defines the metadata for a project, which ultimately controls how this
+// project is managed throughout the infrastructure.
+message DesignProject {
+  // Defines the human-readable name for the project.
+  string name = 1;
+  // Defines the git-repo path for the project.
+  string repo = 2;
+  // Defines the path that stores all of the project configuration.
+  // Relative to the git-repo
+  string config_path = 3;
+  // Define the project's local_manifest.
+  string repo_manifest_path = 4;
+  // The Google Storage bucket for artifacts from the project's builds.
+  string gs_bucket = 5;
+
+  // Defines config needed to maintain firmware builders for the project.
+  FirmwareConfig firmware_config = 6;
+
+  // Define factory build config needed for manufacturing verification.
+  FactoryConfig factory_config = 7;
+
+  message FirmwareConfig {
+    // Defines the firmware branch that will be maintained for the project.
+    string firmware_branch = 1;
+  }
+
+  message FactoryConfig {
+    // Defines the factory branch that will be maintained for the project.
+    string factory_branch = 1;
+
+    // A key in the project.yaml metadata file, to look up the branch, path,
+    // etc. For example, to match the entry in the project.yaml file:
+    //
+    // MILKYWAY:
+    //   board: GALAXY
+    //   branch: master
+    //   version: 3
+    //   path: v3/MILKYWAY
+    //
+    // project_key should be 'MILKYWAY'. The matching is case-insensitive.
+    string hwid_project_key = 2;
+  }
+}