Publish immutable remote commits

This commit is contained in:
2026-08-10 20:05:24 +00:00
parent d6deccf3e8
commit 361dbb4ca8
15 changed files with 725 additions and 251 deletions

View File

@@ -19,6 +19,7 @@ type RemoteArtifactType string
const (
RemoteArtifactTypeSessionManifest RemoteArtifactType = "session_manifest"
RemoteArtifactTypeRunManifest RemoteArtifactType = "run_manifest"
RemoteArtifactTypeRunFile RemoteArtifactType = "run_file"
RemoteArtifactTypePublishedOutput RemoteArtifactType = "published_output"
RemoteArtifactTypePreviousArtifact RemoteArtifactType = "previous_artifact"
)
@@ -68,15 +69,38 @@ func (m RemoteCommitManifest) Validate() error {
return fmt.Errorf("remote commit artifacts are required")
}
destinations := make(map[string]struct{}, len(m.Artifacts))
if err := ValidateRemoteArtifactMapping(m.Artifacts); err != nil {
return err
}
for index, artifact := range m.Artifacts {
if err := artifact.Validate(); err != nil {
return fmt.Errorf("remote commit artifact %d: %w", index, err)
}
}
return nil
}
// ValidateRemoteArtifactMapping verifies that source and destination identities
// form one unambiguous immutable-object mapping.
func ValidateRemoteArtifactMapping(artifacts []RemoteArtifact) error {
if len(artifacts) == 0 {
return fmt.Errorf("remote commit artifacts are required")
}
destinations := make(map[string]struct{}, len(artifacts))
sources := make(map[string]struct{}, len(artifacts))
for index, artifact := range artifacts {
if err := validateRemoteArtifactIdentity(artifact); err != nil {
return fmt.Errorf("remote commit artifact %d: %w", index, err)
}
if _, exists := destinations[artifact.DestinationKey]; exists {
return fmt.Errorf("remote commit declares duplicate destination %q", artifact.DestinationKey)
}
destinations[artifact.DestinationKey] = struct{}{}
sourceKey := string(artifact.Type) + "\x00" + artifact.Source
if _, exists := sources[sourceKey]; exists {
return fmt.Errorf("remote commit declares ambiguous %s source %q", artifact.Type, artifact.Source)
}
sources[sourceKey] = struct{}{}
}
return nil
}
@@ -98,16 +122,8 @@ func (m RemoteCommitManifest) ValidateForSessionPrefix(sessionPrefix string) err
}
func (a RemoteArtifact) Validate() error {
switch a.Type {
case RemoteArtifactTypeSessionManifest, RemoteArtifactTypeRunManifest, RemoteArtifactTypePublishedOutput, RemoteArtifactTypePreviousArtifact:
default:
return fmt.Errorf("unsupported artifact type %q", a.Type)
}
if strings.TrimSpace(a.Source) == "" {
return fmt.Errorf("source is required")
}
if err := validateRemoteObjectKey(a.DestinationKey); err != nil {
return fmt.Errorf("destination key: %w", err)
if err := validateRemoteArtifactIdentity(a); err != nil {
return err
}
if err := validateSHA256(a.SHA256); err != nil {
return fmt.Errorf("sha256: %w", err)
@@ -121,6 +137,21 @@ func (a RemoteArtifact) Validate() error {
return nil
}
func validateRemoteArtifactIdentity(a RemoteArtifact) error {
switch a.Type {
case RemoteArtifactTypeSessionManifest, RemoteArtifactTypeRunManifest, RemoteArtifactTypeRunFile, RemoteArtifactTypePublishedOutput, RemoteArtifactTypePreviousArtifact:
default:
return fmt.Errorf("unsupported artifact type %q", a.Type)
}
if strings.TrimSpace(a.Source) == "" {
return fmt.Errorf("source is required")
}
if err := validateRemoteObjectKey(a.DestinationKey); err != nil {
return fmt.Errorf("destination key: %w", err)
}
return nil
}
func (p CurrentCommitPointer) Validate() error {
if p.FormatVersion != RemoteCommitFormatVersion {
return fmt.Errorf("unsupported current commit pointer format version %d", p.FormatVersion)