Goose 00036 is a renumbered copy of the vault tables. Degraded read stays off by default and only runs after authorization; tombstones and unpublished artifacts fail closed. Co-authored-by: Cursor <cursoragent@cursor.com>
209 lines
6.2 KiB
Go
209 lines
6.2 KiB
Go
package artifactvault
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
const (
|
|
SchemaMajorMinor = "1.0"
|
|
PublisherVersion = "fav-publisher/1.0"
|
|
PolicyVersion = "fav-eligibility/1.0"
|
|
ClassificationOK = "ok"
|
|
ClassificationSecret = "secret"
|
|
ClassificationRestricted = "restricted"
|
|
ClassificationFailed = "classification_failed"
|
|
|
|
TypeAgentCommit = "agent_commit"
|
|
TypeSealedVersion = "sealed_version"
|
|
TypeApprovedDocument = "approved_document"
|
|
TypeFreeformPublish = "freeform_publish"
|
|
TypeAssistantReply = "assistant_reply"
|
|
|
|
StatusRequested = "requested"
|
|
StatusPublishing = "publishing"
|
|
StatusVerified = "verified"
|
|
StatusRetryableFailed = "retryable_failed"
|
|
StatusTombstoned = "tombstoned"
|
|
StatusPurged = "purged"
|
|
StatusQuarantine = "quarantine"
|
|
|
|
RefActive = "active"
|
|
RefTombstoned = "tombstoned"
|
|
RefPurged = "purged"
|
|
)
|
|
|
|
// Facts are the authoritative database facts used for eligibility. HTTP handlers must not invent them.
|
|
type Facts struct {
|
|
ArtifactType string
|
|
CandidateStatus string
|
|
OutputSnapshotID int64
|
|
ChangeKind string
|
|
ChangeToSnapshotID int64
|
|
VersionStatus string
|
|
SealedAt *time.Time
|
|
HeadSnapshotID int64
|
|
DocState string
|
|
ApprovedAt *time.Time
|
|
ReviewSnapshotID int64
|
|
HasImmutableSnapshot bool
|
|
ExplicitPublish bool
|
|
ChatTurnStatus string
|
|
CompletedAt *time.Time
|
|
AssistantMessageID int64
|
|
ExportPolicy string
|
|
ExplicitPin bool
|
|
PinAfterCompleted bool
|
|
Payload []byte
|
|
Classification string
|
|
}
|
|
|
|
type PublishRequest struct {
|
|
ArtifactType string
|
|
Environment string
|
|
ProjectID int64
|
|
ProjectExternalKey string
|
|
LogicalResourceID string
|
|
SourceEventKind string
|
|
SourceEventID string
|
|
SourceSnapshotID int64
|
|
SourceMessageID int64
|
|
SourceRunID string
|
|
Payload []byte
|
|
TerminalState string
|
|
PolicyVersion string
|
|
Classification string
|
|
Sensitivity string
|
|
RetentionClass string
|
|
}
|
|
|
|
type Artifact struct {
|
|
UUID string
|
|
IdempotencyKey string
|
|
ArtifactType string
|
|
LogicalResourceID string
|
|
Environment string
|
|
ProjectID int64
|
|
ProjectExternalKey string
|
|
SourceEventID string
|
|
SourceEventKind string
|
|
SourceSnapshotID int64
|
|
SourceMessageID int64
|
|
SourceRunID string
|
|
PayloadSHA256 string
|
|
ManifestSHA256 string
|
|
VaultStorageIdentity string
|
|
TerminalState string
|
|
PolicyVersion string
|
|
PublicationStatus string
|
|
RetentionClass string
|
|
RequestedAt time.Time
|
|
VerifiedAt *time.Time
|
|
TombstonedAt *time.Time
|
|
}
|
|
|
|
type Staging struct {
|
|
UUID string
|
|
ProjectID int64
|
|
SourceEventID string
|
|
PayloadSHA256 string
|
|
Payload []byte
|
|
Classification string
|
|
CreatedAt time.Time
|
|
}
|
|
|
|
type Manifest struct {
|
|
ArtifactSchemaVersion string `json:"artifact_schema_version"`
|
|
ArtifactUUID string `json:"artifact_uuid"`
|
|
ArtifactType string `json:"artifact_type"`
|
|
LogicalResourceID string `json:"logical_resource_id"`
|
|
Environment string `json:"environment"`
|
|
ProjectID int64 `json:"project_id,omitempty"`
|
|
ProjectExternalKey string `json:"project_external_key"`
|
|
SourceEventID string `json:"source_event_id"`
|
|
SourceEventKind string `json:"source_event_kind,omitempty"`
|
|
SourceSnapshotID *int64 `json:"source_snapshot_id"`
|
|
SourceMessageID *int64 `json:"source_message_id"`
|
|
SourceRunID string `json:"source_run_id,omitempty"`
|
|
PayloadMembers []PayloadMember `json:"payload_members"`
|
|
TerminalEvidence TerminalEvidence `json:"terminal_evidence"`
|
|
Lineage map[string]any `json:"lineage,omitempty"`
|
|
RetentionClass string `json:"retention_class,omitempty"`
|
|
Sensitivity string `json:"sensitivity,omitempty"`
|
|
EncryptionKeyRef string `json:"encryption_key_ref,omitempty"`
|
|
VaultStorageIdentity string `json:"vault_storage_identity"`
|
|
PublisherVersion string `json:"publisher_version,omitempty"`
|
|
PublishedAt string `json:"published_at,omitempty"`
|
|
ManifestSHA256 string `json:"manifest_sha256"`
|
|
}
|
|
|
|
type PayloadMember struct {
|
|
Name string `json:"name"`
|
|
MediaType string `json:"media_type"`
|
|
ByteSize int `json:"byte_size"`
|
|
SHA256 string `json:"sha256"`
|
|
Required bool `json:"required"`
|
|
}
|
|
|
|
type TerminalEvidence struct {
|
|
State string `json:"state"`
|
|
DecidedAt string `json:"decided_at"`
|
|
ActorRef string `json:"actor_ref,omitempty"`
|
|
PolicyVersion string `json:"policy_version"`
|
|
}
|
|
|
|
type CommitMarker struct {
|
|
ArtifactUUID string `json:"artifact_uuid"`
|
|
ManifestSHA256 string `json:"manifest_sha256"`
|
|
MemberSHAs []string `json:"member_shas"`
|
|
VaultStorageIdentity string `json:"vault_storage_identity"`
|
|
CommittedAt string `json:"committed_at"`
|
|
PublisherVersion string `json:"publisher_version"`
|
|
}
|
|
|
|
type Tombstone struct {
|
|
ArtifactUUID string `json:"artifact_uuid"`
|
|
EventUUID string `json:"event_uuid"`
|
|
Reason string `json:"reason"`
|
|
Authority string `json:"authority,omitempty"`
|
|
EffectiveAt string `json:"effective_at"`
|
|
AuditRef string `json:"audit_ref,omitempty"`
|
|
}
|
|
|
|
func SHA256Hex(b []byte) string {
|
|
sum := sha256.Sum256(b)
|
|
return hex.EncodeToString(sum[:])
|
|
}
|
|
|
|
func IdempotencyKey(req PublishRequest, payloadSHA string) string {
|
|
return strings.Join([]string{
|
|
req.ArtifactType,
|
|
req.Environment,
|
|
req.ProjectExternalKey,
|
|
req.LogicalResourceID,
|
|
req.SourceEventKind,
|
|
req.SourceEventID,
|
|
payloadSHA,
|
|
nz(req.PolicyVersion, PolicyVersion),
|
|
}, "|")
|
|
}
|
|
|
|
func nz(v, def string) string {
|
|
if strings.TrimSpace(v) == "" {
|
|
return def
|
|
}
|
|
return v
|
|
}
|
|
|
|
func ValidateEnv(env string) error {
|
|
switch env {
|
|
case "dev", "test", "main":
|
|
return nil
|
|
default:
|
|
return fmt.Errorf("artifactvault: invalid environment %q", env)
|
|
}
|
|
}
|