package catalogsnapshot

import (
	"bytes"
	"crypto/sha256"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"io"
	"strings"

	"github.com/nexuscrm/kernel/pkg/formula"
	domainSchema "github.com/nexuscrm/kernel/pkg/schema"
	"github.com/nexuscrm/shared/pkg/constants"
	"github.com/nexuscrm/shared/pkg/models"
)

func ComputeDigest(data []byte) Digest {
	sum := sha256.Sum256(data)
	return Digest("sha256:" + hex.EncodeToString(sum[:]))
}

func makeArtifact(kind ArtifactKind, data []byte) Artifact {
	cloned := append([]byte(nil), data...)
	return Artifact{kind: kind, digest: ComputeDigest(cloned), bytes: cloned}
}

func artifactFromBytes(kind ArtifactKind, digest Digest, data []byte) Artifact {
	return Artifact{kind: kind, digest: digest, bytes: append([]byte(nil), data...)}
}

func validDigest(digest Digest) bool {
	value := string(digest)
	if len(value) != len("sha256:")+sha256.Size*2 || !strings.HasPrefix(value, "sha256:") {
		return false
	}
	if value != strings.ToLower(value) {
		return false
	}
	_, err := hex.DecodeString(strings.TrimPrefix(value, "sha256:"))
	return err == nil
}

func verifyArtifactBytes(artifact Artifact) error {
	if artifact.kind != ArtifactCatalogSnapshot && artifact.kind != ArtifactRuntimeMetadataView && artifact.kind != ArtifactServingCompatibilityReceipt {
		return fmt.Errorf("%w: unknown artifact kind %q", ErrArtifactCorrupt, artifact.kind)
	}
	if !validDigest(artifact.digest) {
		return fmt.Errorf("%w: malformed digest %q", ErrArtifactCorrupt, artifact.digest)
	}
	if actual := ComputeDigest(artifact.bytes); actual != artifact.digest {
		return fmt.Errorf("%w: digest mismatch: expected %s, got %s", ErrArtifactCorrupt, artifact.digest, actual)
	}
	return nil
}

func OpenCatalogSnapshot(artifact Artifact) (*CatalogSnapshot, error) {
	if artifact.kind != ArtifactCatalogSnapshot {
		return nil, fmt.Errorf("%w: expected %s, got %s", ErrArtifactCorrupt, ArtifactCatalogSnapshot, artifact.kind)
	}
	if err := verifyArtifactBytes(artifact); err != nil {
		return nil, err
	}
	var doc catalogDocument
	if err := decodeStrict(artifact.bytes, &doc); err != nil {
		return nil, fmt.Errorf("%w: decode catalog snapshot: %v", ErrArtifactCorrupt, err)
	}
	if doc.Schema != CatalogSnapshotSchemaV2 && doc.Schema != CatalogSnapshotSchemaV3 && doc.Schema != CatalogSnapshotSchemaV4 && doc.Schema != CatalogSnapshotSchemaV5 && doc.Schema != CatalogSnapshotSchemaV6 && doc.Schema != CatalogSnapshotSchemaV8 && doc.Schema != CatalogSnapshotSchemaV9 && doc.Schema != CatalogSnapshotSchemaV10 && doc.Schema != CatalogSnapshotSchemaV11 && doc.Schema != CatalogSnapshotSchemaV12 && doc.Schema != CatalogSnapshotSchemaV13 && doc.Schema != CatalogSnapshotSchemaV14 && doc.Schema != CatalogSnapshotSchemaV15 && doc.Schema != CatalogSnapshotSchemaV16 && doc.Schema != CatalogSnapshotSchemaV17 && doc.Schema != CatalogSnapshotSchemaV18 && doc.Schema != CatalogSnapshotSchemaV19 && (doc.Schema != CatalogSnapshotSchemaV20 && doc.Schema != CatalogSnapshotSchemaV21) {
		return nil, fmt.Errorf("%w: catalog snapshot schema %q", ErrUnsupportedSchema, doc.Schema)
	}
	if err := requireCanonicalDocument(artifact.bytes, doc); err != nil {
		return nil, err
	}
	if err := validateCatalogDocument(doc); err != nil {
		return nil, fmt.Errorf("%w: %v", ErrArtifactCorrupt, err)
	}
	return &CatalogSnapshot{digest: artifact.digest, doc: doc}, nil
}

func OpenRuntimeMetadataView(artifact Artifact) (*RuntimeMetadataView, error) {
	if artifact.kind != ArtifactRuntimeMetadataView {
		return nil, fmt.Errorf("%w: expected %s, got %s", ErrArtifactCorrupt, ArtifactRuntimeMetadataView, artifact.kind)
	}
	if err := verifyArtifactBytes(artifact); err != nil {
		return nil, err
	}
	var doc runtimeViewDocument
	if err := decodeStrict(artifact.bytes, &doc); err != nil {
		return nil, fmt.Errorf("%w: decode Runtime metadata view: %v", ErrArtifactCorrupt, err)
	}
	if doc.Schema != RuntimeMetadataViewSchemaV2 && doc.Schema != RuntimeMetadataViewSchemaV3 && doc.Schema != RuntimeMetadataViewSchemaV4 && doc.Schema != RuntimeMetadataViewSchemaV5 && doc.Schema != RuntimeMetadataViewSchemaV6 && doc.Schema != RuntimeMetadataViewSchemaV7 && doc.Schema != RuntimeMetadataViewSchemaV8 && doc.Schema != RuntimeMetadataViewSchemaV10 && doc.Schema != RuntimeMetadataViewSchemaV11 && doc.Schema != RuntimeMetadataViewSchemaV12 && doc.Schema != RuntimeMetadataViewSchemaV13 && doc.Schema != RuntimeMetadataViewSchemaV14 && doc.Schema != RuntimeMetadataViewSchemaV15 && doc.Schema != RuntimeMetadataViewSchemaV16 && doc.Schema != RuntimeMetadataViewSchemaV17 && doc.Schema != RuntimeMetadataViewSchemaV18 && doc.Schema != RuntimeMetadataViewSchemaV19 && doc.Schema != RuntimeMetadataViewSchemaV20 && doc.Schema != RuntimeMetadataViewSchemaV21 && doc.Schema != RuntimeMetadataViewSchemaV22 && doc.Schema != RuntimeMetadataViewSchemaV23 && doc.Schema != RuntimeMetadataViewSchemaV24 && doc.Schema != RuntimeMetadataViewSchemaV25 && doc.Schema != RuntimeMetadataViewSchemaV26 && doc.Schema != RuntimeMetadataViewSchemaV27 && doc.Schema != RuntimeMetadataViewSchemaV28 {
		return nil, fmt.Errorf("%w: Runtime metadata view schema %q", ErrUnsupportedSchema, doc.Schema)
	}
	if doc.Schema == RuntimeMetadataViewSchemaV3 && doc.Profile == ProjectionRecordMutationV1 {
		return nil, fmt.Errorf("%w: v3 record-mutation Runtime view must be regenerated from its Catalog snapshot", ErrUnsupportedSchema)
	}
	if err := requireCanonicalDocument(artifact.bytes, doc); err != nil {
		return nil, err
	}
	if err := validateRuntimeViewDocument(doc); err != nil {
		return nil, fmt.Errorf("%w: %v", ErrArtifactCorrupt, err)
	}
	view := &RuntimeMetadataView{
		digest: artifact.digest, doc: doc,
		objectsByName: make(map[string]int, len(doc.Objects)),
		relsByChild:   make(map[string][]int), relsByParent: make(map[string][]int), rulesByObject: make(map[string][]int),
		definitionsByID:             make(map[string]int, len(doc.Definitions)),
		reportDefinitionsByID:       make(map[string]int, len(doc.Reports)),
		commandRegistrations:        make(map[string]struct{}, len(doc.CommandRegistrations)),
		commandExecutionBindings:    make(map[string]string),
		approvalDefinitionsByID:     make(map[string]int, len(doc.ApprovalDefinitions)),
		approvalDefinitionsByObject: make(map[string][]int),
		referenceIdentitiesByObject: make(map[string]map[string]int),
		attachmentResolversByID:     map[string]int{}, attachmentFieldsByObject: map[string][]int{},
		effectivePermissionObjectsByName: map[string]int{},
		rollupDependenciesByChild:        map[string][]runtimeRollupDependencyIndex{},
	}
	for objectIndex := range doc.Objects {
		object := doc.Objects[objectIndex]
		view.objectsByName[foldIdentity(object.APIName)] = objectIndex
		for fieldIndex := range object.Fields {
			mutation := object.Fields[fieldIndex].Mutation
			if mutation == nil {
				continue
			}
			if mutation.SiblingMaxParentField != nil && strings.TrimSpace(*mutation.SiblingMaxParentField) != "" {
				view.hasAnySiblingMaxDefaults = true
			}
			if mutation.RollupConfig == nil {
				continue
			}
			childKey := foldIdentity(mutation.RollupConfig.SummaryObject)
			if childKey == "" {
				continue
			}
			view.rollupDependenciesByChild[childKey] = append(
				view.rollupDependenciesByChild[childKey],
				runtimeRollupDependencyIndex{
					parentObjectIndex: objectIndex,
					rollupFieldIndex:  fieldIndex,
				},
			)
		}
	}
	if doc.EffectivePermissions != nil {
		for i := range doc.EffectivePermissions.Objects {
			view.effectivePermissionObjectsByName[foldIdentity(doc.EffectivePermissions.Objects[i].ResourceType)] = i
		}
	}
	for i := range doc.Relationships {
		childKey := foldIdentity(doc.Relationships[i].ChildObjectAPIName)
		parentKey := foldIdentity(doc.Relationships[i].ParentObjectAPIName)
		view.relsByChild[childKey] = append(view.relsByChild[childKey], i)
		view.relsByParent[parentKey] = append(view.relsByParent[parentKey], i)
	}
	for i := range doc.SharingRules {
		key := foldIdentity(doc.SharingRules[i].ObjectAPIName)
		view.rulesByObject[key] = append(view.rulesByObject[key], i)
	}
	for i := range doc.Definitions {
		view.definitionsByID[foldIdentity(doc.Definitions[i].ComponentID)] = i
	}
	for i := range doc.Reports {
		view.reportDefinitionsByID[foldIdentity(doc.Reports[i].ID)] = i
	}
	for i := range doc.CommandRegistrations {
		registration := doc.CommandRegistrations[i]
		view.commandRegistrations[commandRegistrationKey(registration.CommandKind, registration.PayloadFormatVersion)] = struct{}{}
		for _, binding := range registration.ExecutionBindings {
			view.commandExecutionBindings[commandExecutionSelectorKey(
				registration.CommandKind,
				registration.PayloadFormatVersion,
				binding,
			)] = binding.ContextNamespace
		}
	}
	for i := range doc.ApprovalDefinitions {
		definition := doc.ApprovalDefinitions[i]
		view.approvalDefinitionsByID[foldIdentity(definition.DefinitionID)] = i
		objectKey := foldIdentity(definition.ObjectAPIName)
		view.approvalDefinitionsByObject[objectKey] = append(
			view.approvalDefinitionsByObject[objectKey],
			i,
		)
	}
	if doc.Schema == RuntimeMetadataViewSchemaV20 {
		view.referenceIdentitiesByObject[foldIdentity(constants.TableProcessDefinition)] = make(map[string]int)
		view.referenceIdentitiesByObject[foldIdentity(constants.TableProcessNode)] = make(map[string]int)
	}
	for i := range doc.ReferenceIdentities {
		record := doc.ReferenceIdentities[i]
		key := foldIdentity(record.ObjectAPIName)
		byID := view.referenceIdentitiesByObject[key]
		if byID == nil {
			byID = make(map[string]int)
			view.referenceIdentitiesByObject[key] = byID
		}
		byID[record.ID] = i
	}
	if doc.RecordView != nil {
		for i := range doc.RecordView.Resolvers {
			view.attachmentResolversByID[foldIdentity(doc.RecordView.Resolvers[i].ResolverID)] = i
		}
		for i := range doc.RecordView.Fields {
			key := foldIdentity(doc.RecordView.Fields[i].ObjectAPIName)
			view.attachmentFieldsByObject[key] = append(view.attachmentFieldsByObject[key], i)
		}
	}
	return view, nil
}

func decodeStrict(data []byte, target any) error {
	decoder := json.NewDecoder(bytes.NewReader(data))
	decoder.DisallowUnknownFields()
	if err := decoder.Decode(target); err != nil {
		return err
	}
	if err := decoder.Decode(&struct{}{}); err != io.EOF {
		if err == nil {
			return fmt.Errorf("trailing JSON value")
		}
		return fmt.Errorf("trailing content: %w", err)
	}
	return nil
}

func requireCanonicalDocument(original []byte, doc any) error {
	canonical, err := marshalCanonical(doc)
	if err != nil {
		return fmt.Errorf("%w: canonical re-encode failed: %v", ErrArtifactCorrupt, err)
	}
	if !bytes.Equal(original, canonical) {
		return fmt.Errorf("%w: artifact bytes are not canonical", ErrArtifactCorrupt)
	}
	return nil
}

func validateCatalogDocument(doc catalogDocument) error {
	if doc.Schema == CatalogSnapshotSchemaV2 && doc.Mutation != nil {
		return fmt.Errorf("v2 Catalog snapshot contains mutation definitions")
	}
	if doc.Schema != CatalogSnapshotSchemaV5 && doc.Schema != CatalogSnapshotSchemaV6 && doc.Schema != CatalogSnapshotSchemaV8 && doc.Schema != CatalogSnapshotSchemaV9 && doc.Schema != CatalogSnapshotSchemaV10 && doc.Schema != CatalogSnapshotSchemaV11 && doc.Schema != CatalogSnapshotSchemaV12 && doc.Schema != CatalogSnapshotSchemaV13 && doc.Schema != CatalogSnapshotSchemaV14 && doc.Schema != CatalogSnapshotSchemaV15 && doc.Schema != CatalogSnapshotSchemaV16 && doc.Schema != CatalogSnapshotSchemaV17 && doc.Schema != CatalogSnapshotSchemaV18 && doc.Schema != CatalogSnapshotSchemaV19 && (doc.Schema != CatalogSnapshotSchemaV20 && doc.Schema != CatalogSnapshotSchemaV21) && doc.RecordView != nil {
		return fmt.Errorf("pre-v5 Catalog snapshot contains record-view definitions")
	}
	if doc.Schema != CatalogSnapshotSchemaV8 && doc.Schema != CatalogSnapshotSchemaV9 && doc.Schema != CatalogSnapshotSchemaV10 && doc.Schema != CatalogSnapshotSchemaV11 && doc.Schema != CatalogSnapshotSchemaV12 && doc.Schema != CatalogSnapshotSchemaV13 && doc.Schema != CatalogSnapshotSchemaV14 && doc.Schema != CatalogSnapshotSchemaV15 && doc.Schema != CatalogSnapshotSchemaV16 && doc.Schema != CatalogSnapshotSchemaV17 && doc.Schema != CatalogSnapshotSchemaV18 && doc.Schema != CatalogSnapshotSchemaV19 && (doc.Schema != CatalogSnapshotSchemaV20 && doc.Schema != CatalogSnapshotSchemaV21) && len(doc.Reports) != 0 {
		return fmt.Errorf("pre-v8 Catalog snapshot contains report definitions")
	}
	if doc.Schema != CatalogSnapshotSchemaV9 && doc.Schema != CatalogSnapshotSchemaV10 && doc.Schema != CatalogSnapshotSchemaV11 && doc.Schema != CatalogSnapshotSchemaV12 && doc.Schema != CatalogSnapshotSchemaV13 && doc.Schema != CatalogSnapshotSchemaV14 && doc.Schema != CatalogSnapshotSchemaV15 && doc.Schema != CatalogSnapshotSchemaV16 && doc.Schema != CatalogSnapshotSchemaV17 && doc.Schema != CatalogSnapshotSchemaV18 && doc.Schema != CatalogSnapshotSchemaV19 && (doc.Schema != CatalogSnapshotSchemaV20 && doc.Schema != CatalogSnapshotSchemaV21) && len(doc.CommandRegistrations) != 0 {
		return fmt.Errorf("pre-v9 Catalog snapshot contains command registrations")
	}
	hasExecutionBindings := commandRecordsHaveExecutionBindings(doc.CommandRegistrations)
	if doc.Schema != CatalogSnapshotSchemaV10 && doc.Schema != CatalogSnapshotSchemaV11 && doc.Schema != CatalogSnapshotSchemaV12 && doc.Schema != CatalogSnapshotSchemaV13 && doc.Schema != CatalogSnapshotSchemaV14 && doc.Schema != CatalogSnapshotSchemaV15 && doc.Schema != CatalogSnapshotSchemaV16 && doc.Schema != CatalogSnapshotSchemaV17 && doc.Schema != CatalogSnapshotSchemaV18 && doc.Schema != CatalogSnapshotSchemaV19 && (doc.Schema != CatalogSnapshotSchemaV20 && doc.Schema != CatalogSnapshotSchemaV21) && hasExecutionBindings {
		return fmt.Errorf("pre-v10 Catalog snapshot contains command execution bindings")
	}
	if doc.Schema == CatalogSnapshotSchemaV10 && !hasExecutionBindings {
		return fmt.Errorf("v10 Catalog snapshot contains no command execution binding")
	}
	hasConnectorRuntimeFacts := mutationHasConnectorRuntimeFacts(doc.Mutation)
	if doc.Schema != CatalogSnapshotSchemaV11 && doc.Schema != CatalogSnapshotSchemaV12 && doc.Schema != CatalogSnapshotSchemaV13 && doc.Schema != CatalogSnapshotSchemaV14 && doc.Schema != CatalogSnapshotSchemaV15 && doc.Schema != CatalogSnapshotSchemaV16 && doc.Schema != CatalogSnapshotSchemaV17 && doc.Schema != CatalogSnapshotSchemaV18 && doc.Schema != CatalogSnapshotSchemaV19 && (doc.Schema != CatalogSnapshotSchemaV20 && doc.Schema != CatalogSnapshotSchemaV21) && hasConnectorRuntimeFacts {
		return fmt.Errorf("pre-v11 Catalog snapshot contains connector execution facts")
	}
	if doc.Schema == CatalogSnapshotSchemaV11 && !hasConnectorRuntimeFacts {
		return fmt.Errorf("v11 Catalog snapshot contains no connector execution facts")
	}
	hasConnectorFinalization := mutationHasConnectorFinalizationAuthority(doc.Mutation)
	if doc.Schema != CatalogSnapshotSchemaV12 && doc.Schema != CatalogSnapshotSchemaV13 && doc.Schema != CatalogSnapshotSchemaV14 && doc.Schema != CatalogSnapshotSchemaV15 && doc.Schema != CatalogSnapshotSchemaV16 && doc.Schema != CatalogSnapshotSchemaV17 && doc.Schema != CatalogSnapshotSchemaV18 && doc.Schema != CatalogSnapshotSchemaV19 && (doc.Schema != CatalogSnapshotSchemaV20 && doc.Schema != CatalogSnapshotSchemaV21) && hasConnectorFinalization {
		return fmt.Errorf("pre-v12 Catalog snapshot contains connector finalization authority")
	}
	if doc.Schema == CatalogSnapshotSchemaV12 && !hasConnectorFinalization {
		return fmt.Errorf("v12 Catalog snapshot contains no connector finalization authority")
	}
	hasRecoveryEligibility := mutationHasConnectorRecoveryEligibility(doc.Mutation)
	if doc.Schema != CatalogSnapshotSchemaV13 && doc.Schema != CatalogSnapshotSchemaV14 && doc.Schema != CatalogSnapshotSchemaV15 && doc.Schema != CatalogSnapshotSchemaV16 && doc.Schema != CatalogSnapshotSchemaV17 && doc.Schema != CatalogSnapshotSchemaV18 && doc.Schema != CatalogSnapshotSchemaV19 && (doc.Schema != CatalogSnapshotSchemaV20 && doc.Schema != CatalogSnapshotSchemaV21) && hasRecoveryEligibility {
		return fmt.Errorf("pre-v13 Catalog snapshot contains connector recovery eligibility")
	}
	if doc.Schema == CatalogSnapshotSchemaV13 && !hasRecoveryEligibility {
		return fmt.Errorf("v13 Catalog snapshot contains no connector recovery eligibility")
	}
	hasApprovalAuthority := len(doc.ApprovalDefinitions) != 0
	for _, projection := range doc.Projections {
		hasApprovalAuthority = hasApprovalAuthority || profileUsesApprovalAuthority(projection.Profile)
	}
	if doc.Schema != CatalogSnapshotSchemaV14 && doc.Schema != CatalogSnapshotSchemaV15 && doc.Schema != CatalogSnapshotSchemaV16 && doc.Schema != CatalogSnapshotSchemaV17 && doc.Schema != CatalogSnapshotSchemaV18 && doc.Schema != CatalogSnapshotSchemaV19 && (doc.Schema != CatalogSnapshotSchemaV20 && doc.Schema != CatalogSnapshotSchemaV21) && hasApprovalAuthority {
		return fmt.Errorf("pre-v14 Catalog snapshot contains approval authority")
	}
	if doc.Schema == CatalogSnapshotSchemaV14 && !hasApprovalAuthority {
		return fmt.Errorf("v14 Catalog snapshot contains no approval authority")
	}
	if doc.Schema != CatalogSnapshotSchemaV15 && doc.Schema != CatalogSnapshotSchemaV16 && doc.Schema != CatalogSnapshotSchemaV17 && doc.Schema != CatalogSnapshotSchemaV18 && doc.Schema != CatalogSnapshotSchemaV19 && (doc.Schema != CatalogSnapshotSchemaV20 && doc.Schema != CatalogSnapshotSchemaV21) && len(doc.FormulaFunctionBundles) != 0 {
		return fmt.Errorf("pre-v15 Catalog snapshot contains formula function bundles")
	}
	if doc.Schema != CatalogSnapshotSchemaV15 && doc.Schema != CatalogSnapshotSchemaV16 && doc.Schema != CatalogSnapshotSchemaV17 && doc.Schema != CatalogSnapshotSchemaV18 && doc.Schema != CatalogSnapshotSchemaV19 && (doc.Schema != CatalogSnapshotSchemaV20 && doc.Schema != CatalogSnapshotSchemaV21) && len(doc.OutboundIntentRoutes) != 0 {
		return fmt.Errorf("pre-v15 Catalog snapshot contains outbound intent routes")
	}
	if doc.Schema == CatalogSnapshotSchemaV15 && len(doc.FormulaFunctionBundles) == 0 && len(doc.OutboundIntentRoutes) == 0 {
		return fmt.Errorf("v15 Catalog snapshot contains no v15 authority")
	}
	hasTypedOutboundIntentGrammar := outboundIntentRoutesUseTypedOperationGrammar(doc.OutboundIntentRoutes)
	hasMailAuthority := outboundIntentRoutesUseMailAuthority(doc.OutboundIntentRoutes)
	hasMailV2Authority := outboundIntentRoutesUseMailV2Authority(doc.OutboundIntentRoutes)
	if doc.Schema != CatalogSnapshotSchemaV16 && doc.Schema != CatalogSnapshotSchemaV17 && doc.Schema != CatalogSnapshotSchemaV18 && doc.Schema != CatalogSnapshotSchemaV19 && (doc.Schema != CatalogSnapshotSchemaV20 && doc.Schema != CatalogSnapshotSchemaV21) && hasTypedOutboundIntentGrammar {
		return fmt.Errorf("pre-v16 Catalog snapshot contains typed outbound intent authority")
	}
	if doc.Schema == CatalogSnapshotSchemaV16 && !hasMailAuthority {
		return fmt.Errorf("v16 Catalog snapshot contains no outbound mail authority")
	}
	if doc.Schema == CatalogSnapshotSchemaV17 && doc.PageLayoutResolution == nil {
		return fmt.Errorf("v17 Catalog snapshot contains no page-layout resolution authority")
	}
	hasFieldMappingValuePolicies := mutationHasFieldMappingValuePolicies(doc.Mutation)
	if doc.Schema != CatalogSnapshotSchemaV18 && doc.Schema != CatalogSnapshotSchemaV19 && (doc.Schema != CatalogSnapshotSchemaV20 && doc.Schema != CatalogSnapshotSchemaV21) && hasFieldMappingValuePolicies {
		return fmt.Errorf("pre-v18 Catalog snapshot contains field-mapping value policies")
	}
	if doc.Schema == CatalogSnapshotSchemaV18 && !hasFieldMappingValuePolicies {
		return fmt.Errorf("v18 Catalog snapshot contains no field-mapping value policy")
	}
	if doc.Schema != CatalogSnapshotSchemaV19 && (doc.Schema != CatalogSnapshotSchemaV20 && doc.Schema != CatalogSnapshotSchemaV21) && hasMailV2Authority {
		return fmt.Errorf("pre-v19 Catalog snapshot contains outbound mail v2 authority")
	}
	if doc.Schema == CatalogSnapshotSchemaV19 && !hasMailV2Authority {
		return fmt.Errorf("v19 Catalog snapshot contains no outbound mail v2 authority")
	}
	hasLayoutAuthoringProfile := false
	for _, projection := range doc.Projections {
		hasLayoutAuthoringProfile = hasLayoutAuthoringProfile || projection.Profile == ProjectionLayoutAuthoringV1
	}
	if (doc.Schema != CatalogSnapshotSchemaV20 && doc.Schema != CatalogSnapshotSchemaV21) && doc.LayoutAuthoring != nil {
		return fmt.Errorf("pre-v20 Catalog snapshot contains Layout authoring authority")
	}
	if (doc.Schema == CatalogSnapshotSchemaV20 || doc.Schema == CatalogSnapshotSchemaV21) && (!hasLayoutAuthoringProfile || doc.LayoutAuthoring == nil) {
		return fmt.Errorf("v20 Catalog snapshot requires Layout authoring authority")
	}
	if hasLayoutAuthoringProfile && doc.LayoutAuthoring == nil {
		return fmt.Errorf("Layout authoring projection has no stored aggregate")
	}
	if doc.LayoutAuthoring != nil {
		if err := validateLayoutCreateContextVersion(doc.LayoutAuthoring, doc.Schema == CatalogSnapshotSchemaV21); err != nil {
			return err
		}
		if err := validateLayoutAuthoringDocument(doc.LayoutAuthoring); err != nil {
			return err
		}
	}
	formulaEngine, err := formulaEngineForCatalogArtifact(doc.Schema, doc.FormulaFunctionBundles)
	if err != nil {
		return err
	}
	if doc.Schema == CatalogSnapshotSchemaV15 || doc.Schema == CatalogSnapshotSchemaV16 || doc.Schema == CatalogSnapshotSchemaV17 || doc.Schema == CatalogSnapshotSchemaV18 || doc.Schema == CatalogSnapshotSchemaV19 || (doc.Schema == CatalogSnapshotSchemaV20 || doc.Schema == CatalogSnapshotSchemaV21) {
		if err := validateFormulaFunctionBundles(doc.FormulaFunctionBundles); err != nil {
			return err
		}
	}
	if err := validateOutboundIntentRoutes(doc.OutboundIntentRoutes, doc.Mutation); err != nil {
		return err
	}
	if err := requireCanonicalIdentity("orgId", doc.OrgID); err != nil {
		return err
	}
	if err := validateLineage(doc.Lineage); err != nil {
		return err
	}
	if len(doc.Objects) == 0 {
		return fmt.Errorf("catalog snapshot has no objects")
	}
	objects := make(map[string]*models.ObjectMetadata, len(doc.Objects))
	objectsByKeyPrefix := make(map[string]string, len(doc.Objects))
	for i := range doc.Objects {
		if len(doc.Objects[i].Metadata.Fields) != 0 || doc.Objects[i].Metadata.FieldsMap != nil {
			return fmt.Errorf("objects[%d] duplicates canonical fields inside metadata", i)
		}
		object, err := reconstructCatalogObject(doc.Objects[i])
		if err != nil {
			return fmt.Errorf("objects[%d]: %w", i, err)
		}
		if err := requireCatalogObjectAPIName(fmt.Sprintf("objects[%d].metadata.name", i), object.APIName); err != nil {
			return err
		}
		key := foldIdentity(object.APIName)
		if _, exists := objects[key]; exists {
			return fmt.Errorf("duplicate object %q", object.APIName)
		}
		if err := registerKeyPrefixOwner(objectsByKeyPrefix, object.KeyPrefix, object.APIName); err != nil {
			return err
		}
		objects[key] = object
		seenFields := map[string]struct{}{}
		for _, field := range object.Fields {
			key := foldIdentity(field.APIName)
			if key == "" {
				return fmt.Errorf("object %q has blank field name", object.APIName)
			}
			if _, exists := seenFields[key]; exists {
				return fmt.Errorf("object %q has duplicate field %q", object.APIName, field.APIName)
			}
			seenFields[key] = struct{}{}
		}
		if _, err := object.ResolveReadSourceTable(); err != nil {
			return err
		}
	}
	if err := validateLayoutCreateContextSource(doc.LayoutAuthoring, objects, doc.Mutation); err != nil {
		return err
	}
	if err := validateOutboundMailCompletionMetadata(doc.OutboundIntentRoutes, objects); err != nil {
		return err
	}
	if err := validatePageLayoutResolutionDocument(doc.PageLayoutResolution, objects, doc.Schema); err != nil {
		return err
	}
	seenRelationships := map[string]struct{}{}
	sharingParents := map[string]struct{}{}
	for i, relationship := range doc.Relationships {
		if objects[foldIdentity(relationship.ChildObjectAPIName)] == nil || objects[foldIdentity(relationship.ParentObjectAPIName)] == nil {
			return fmt.Errorf("relationships[%d] references an absent object", i)
		}
		key := relationshipKey(relationship)
		if _, exists := seenRelationships[key]; exists {
			return fmt.Errorf("relationships[%d] is duplicated", i)
		}
		seenRelationships[key] = struct{}{}
		if relationship.IsSharingParent {
			child := foldIdentity(relationship.ChildObjectAPIName)
			if _, exists := sharingParents[child]; exists {
				return fmt.Errorf("object %q has multiple sharing parents", relationship.ChildObjectAPIName)
			}
			sharingParents[child] = struct{}{}
		}
	}
	// Missing sharing-parent state is representable and remains fail-closed in
	// Runtime. Only contradictory relationship facts are structural corruption.
	seenRules := map[string]struct{}{}
	for i, rule := range doc.SharingRules {
		if err := requireCanonicalIdentity(fmt.Sprintf("sharingRules[%d].id", i), rule.ID); err != nil {
			return err
		}
		object := objects[foldIdentity(rule.ObjectAPIName)]
		if object == nil {
			return fmt.Errorf("sharingRules[%d] references absent object %q", i, rule.ObjectAPIName)
		}
		if criteria := strings.TrimSpace(rule.Criteria); criteria != "" && criteria != "[]" {
			if err := validateSharingRuleCriteria(object, criteria); err != nil {
				return fmt.Errorf("sharingRules[%d] has invalid criteria: %w", i, err)
			}
		}
		key := foldIdentity(rule.ID)
		if _, exists := seenRules[key]; exists {
			return fmt.Errorf("sharingRules[%d] duplicates rule %q", i, rule.ID)
		}
		seenRules[key] = struct{}{}
	}
	definitions := map[string]struct{}{}
	definitionLineages := map[string]definitionRecord{}
	for i, definition := range doc.Definitions {
		if err := requireCanonicalIdentity(fmt.Sprintf("definitions[%d].componentId", i), definition.ComponentID); err != nil {
			return err
		}
		if strings.TrimSpace(string(definition.DefinitionVersion)) == "" || !validDigest(definition.ContentDigest) {
			return fmt.Errorf("definitions[%d] has invalid version or digest", i)
		}
		key := foldIdentity(definition.ComponentID)
		if _, exists := definitions[key]; exists {
			return fmt.Errorf("definitions[%d] duplicates component %q", i, definition.ComponentID)
		}
		definitions[key] = struct{}{}
		definitionLineages[key] = definition
	}
	seenProjection := map[string]struct{}{}
	for i, projection := range doc.Projections {
		if err := requireCanonicalIdentity(fmt.Sprintf("runtimeProjections[%d].appInstallationId", i), projection.AppInstallationID); err != nil {
			return err
		}
		if err := requireCanonicalIdentity(fmt.Sprintf("runtimeProjections[%d].capabilityId", i), projection.CapabilityID); err != nil {
			return err
		}
		key := foldIdentity(projection.AppInstallationID) + "\x00" + foldIdentity(projection.CapabilityID)
		if _, exists := seenProjection[key]; exists {
			return fmt.Errorf("duplicate Runtime projection %q", key)
		}
		seenProjection[key] = struct{}{}
		if len(projection.ObjectAPINames) == 0 && projection.Profile != ProjectionCommandAcceptanceV1 {
			return fmt.Errorf("Runtime projection %q has no objects", key)
		}
		if len(projection.ObjectAPINames) != 0 && projection.Profile == ProjectionCommandAcceptanceV1 {
			return fmt.Errorf("Runtime command-acceptance projection %q contains object metadata", key)
		}
		for _, name := range projection.ObjectAPINames {
			if objects[foldIdentity(name)] == nil {
				return fmt.Errorf("Runtime projection %q references absent object %q", key, name)
			}
		}
		if err := validateProjectionProfile(fmt.Sprintf("runtimeProjections[%d].profile", i), projection.Profile); err != nil {
			return err
		}
		if projection.Profile == ProjectionLayoutAuthoringV1 {
			if err := validateLayoutAuthoringProjectionBinding(projection.CapabilityID, projection.DefinitionComponentIDs); err != nil {
				return fmt.Errorf("Runtime projection %q: %w", key, err)
			}
		}
		if profileUsesMutationClosure(projection.Profile) &&
			(doc.Schema != CatalogSnapshotSchemaV3 && doc.Schema != CatalogSnapshotSchemaV4 && doc.Schema != CatalogSnapshotSchemaV5 && doc.Schema != CatalogSnapshotSchemaV6 && doc.Schema != CatalogSnapshotSchemaV8 && doc.Schema != CatalogSnapshotSchemaV9 && doc.Schema != CatalogSnapshotSchemaV10 && doc.Schema != CatalogSnapshotSchemaV11 && doc.Schema != CatalogSnapshotSchemaV12 && doc.Schema != CatalogSnapshotSchemaV13 && doc.Schema != CatalogSnapshotSchemaV14 && doc.Schema != CatalogSnapshotSchemaV15 && doc.Schema != CatalogSnapshotSchemaV16 && doc.Schema != CatalogSnapshotSchemaV17 && doc.Schema != CatalogSnapshotSchemaV18 && doc.Schema != CatalogSnapshotSchemaV19 && (doc.Schema != CatalogSnapshotSchemaV20 && doc.Schema != CatalogSnapshotSchemaV21) || doc.Mutation == nil) {
			return fmt.Errorf("Runtime mutation projection %q has no supported mutation definition closure", key)
		}
		if projection.Profile == ProjectionEffectivePermissionsV1 && doc.Mutation == nil {
			return fmt.Errorf("Runtime effective-permissions projection %q has no record-type authority closure", key)
		}
		if projection.Profile == ProjectionEffectivePermissionsV1 && len(projection.DefinitionComponentIDs) != 0 {
			return fmt.Errorf("Runtime effective-permissions projection %q contains executable definitions", key)
		}
		if projection.Profile == ProjectionRecordViewV1 && ((doc.Schema != CatalogSnapshotSchemaV5 && doc.Schema != CatalogSnapshotSchemaV6 && doc.Schema != CatalogSnapshotSchemaV8 && doc.Schema != CatalogSnapshotSchemaV9 && doc.Schema != CatalogSnapshotSchemaV10 && doc.Schema != CatalogSnapshotSchemaV11 && doc.Schema != CatalogSnapshotSchemaV12 && doc.Schema != CatalogSnapshotSchemaV13 && doc.Schema != CatalogSnapshotSchemaV14 && doc.Schema != CatalogSnapshotSchemaV15 && doc.Schema != CatalogSnapshotSchemaV16 && doc.Schema != CatalogSnapshotSchemaV17 && doc.Schema != CatalogSnapshotSchemaV18 && doc.Schema != CatalogSnapshotSchemaV19 && (doc.Schema != CatalogSnapshotSchemaV20 && doc.Schema != CatalogSnapshotSchemaV21)) || doc.RecordView == nil) {
			return fmt.Errorf("Runtime record-view projection %q has no resolver closure", key)
		}
		if projection.Profile == ProjectionPageLayoutResolutionV1 && doc.PageLayoutResolution == nil {
			return fmt.Errorf("Runtime page-layout resolution projection %q has no routing closure", key)
		}
		if projection.Profile == ProjectionLayoutAuthoringV1 && doc.LayoutAuthoring == nil {
			return fmt.Errorf("Runtime Layout authoring projection %q has no stored aggregate", key)
		}
		if err := validateProjectionObjectClosure(fmt.Sprintf("runtimeProjections[%d].objectApiNames", i), projection.Profile, projection.ObjectAPINames, objects); err != nil {
			return err
		}
		for _, componentID := range projection.DefinitionComponentIDs {
			if _, exists := definitions[foldIdentity(componentID)]; !exists {
				return fmt.Errorf("Runtime projection %q references absent definition %q", key, componentID)
			}
		}
	}
	if err := validateMutationDefinitions(doc.Mutation, objects, formulaEngine); err != nil {
		return err
	}
	if err := validateRecordViewDefinitions(doc.RecordView, objects, doc.Schema); err != nil {
		return err
	}
	reportComponents := make(map[string]struct{}, len(doc.Reports))
	reportIDs := make(map[string]struct{}, len(doc.Reports))
	for i, report := range doc.Reports {
		if err := validateReportDefinitionRecord(fmt.Sprintf("reports[%d]", i), report, objects); err != nil {
			return err
		}
		componentKey := foldIdentity(report.ComponentID)
		if _, exists := reportComponents[componentKey]; exists {
			return fmt.Errorf("reports[%d] duplicates component %q", i, report.ComponentID)
		}
		reportComponents[componentKey] = struct{}{}
		if _, exists := definitions[componentKey]; !exists {
			return fmt.Errorf("reports[%d] has no matching definition lineage", i)
		}
		idKey := foldIdentity(report.ID)
		if _, exists := reportIDs[idKey]; exists {
			return fmt.Errorf("reports[%d] duplicates report id %q", i, report.ID)
		}
		reportIDs[idKey] = struct{}{}
	}
	for i, projection := range doc.Projections {
		if projection.Profile != ProjectionReportExecutionV1 {
			continue
		}
		for _, componentID := range projection.DefinitionComponentIDs {
			if _, exists := reportComponents[foldIdentity(componentID)]; !exists {
				return fmt.Errorf("Runtime projection %d selects non-report definition %q", i, componentID)
			}
		}
	}
	approvalObjects := make(map[string]string, len(objects))
	for key, object := range objects {
		approvalObjects[key] = object.APIName
	}
	approvalComponents := make(map[string]approvalDefinitionRecord, len(doc.ApprovalDefinitions))
	approvalNames := make(map[string]struct{}, len(doc.ApprovalDefinitions))
	for i, definition := range doc.ApprovalDefinitions {
		if err := validateApprovalDefinitionRecord(
			fmt.Sprintf("approvalDefinitions[%d]", i),
			definition,
			approvalObjects,
		); err != nil {
			return err
		}
		componentKey := foldIdentity(definition.DefinitionID)
		if _, duplicate := approvalComponents[componentKey]; duplicate {
			return fmt.Errorf("approvalDefinitions[%d] duplicates definition %q", i, definition.DefinitionID)
		}
		approvalComponents[componentKey] = definition
		lineage, exists := definitionLineages[componentKey]
		if !exists {
			return fmt.Errorf("approvalDefinitions[%d] has no matching definition lineage", i)
		}
		if lineage.DefinitionVersion != DefinitionVersion(definition.SourceDigest) ||
			lineage.ContentDigest != definition.ContentDigest ||
			lineage.ComponentID != definition.DefinitionID {
			return fmt.Errorf("approvalDefinitions[%d] conflicts with its definition lineage", i)
		}
		nameKey := foldIdentity(definition.ObjectAPIName) + "\x00" + foldIdentity(definition.DeveloperName)
		if _, duplicate := approvalNames[nameKey]; duplicate {
			return fmt.Errorf("approvalDefinitions[%d] duplicates object/name identity", i)
		}
		approvalNames[nameKey] = struct{}{}
	}
	for i, projection := range doc.Projections {
		projectedObjects := make(map[string]struct{}, len(projection.ObjectAPINames))
		for _, objectAPIName := range projection.ObjectAPINames {
			projectedObjects[foldIdentity(objectAPIName)] = struct{}{}
		}
		for _, componentID := range projection.DefinitionComponentIDs {
			approvalDefinition, approval := approvalComponents[foldIdentity(componentID)]
			switch {
			case profileUsesApprovalAuthority(projection.Profile) && !approval:
				return fmt.Errorf("Runtime projection %d selects non-approval definition %q", i, componentID)
			case profileUsesApprovalAuthority(projection.Profile):
				if _, exists := projectedObjects[foldIdentity(approvalDefinition.ObjectAPIName)]; !exists {
					return fmt.Errorf(
						"Runtime projection %d selects approval definition %q outside its object closure",
						i,
						componentID,
					)
				}
			case !profileUsesApprovalAuthority(projection.Profile) && approval:
				return fmt.Errorf("Runtime projection %d selects approval definition %q outside approval authority", i, componentID)
			}
		}
		if projection.Profile == ProjectionApprovalExecutionV1 && len(projection.DefinitionComponentIDs) != 0 {
			selected := make(map[string]struct{}, len(projection.DefinitionComponentIDs))
			for _, componentID := range projection.DefinitionComponentIDs {
				selected[foldIdentity(componentID)] = struct{}{}
			}
			if _, err := projectMutationDefinitions(
				doc.Mutation,
				projectedObjects,
				projection.Profile,
				projection.CapabilityID,
				approvalFlowNames(selectedApprovalDefinitions(doc.ApprovalDefinitions, selected)),
				doc.OutboundIntentRoutes,
				formulaEngine,
			); err != nil {
				return fmt.Errorf("Runtime projection %d has an incomplete approval execution closure: %w", i, err)
			}
		}
	}
	commandComponents := make(map[string]struct{}, len(doc.CommandRegistrations))
	commandPairs := make(map[string]struct{}, len(doc.CommandRegistrations))
	for i, registration := range doc.CommandRegistrations {
		if err := validateCommandRegistrationRecord(fmt.Sprintf("commandRegistrations[%d]", i), registration); err != nil {
			return err
		}
		componentKey := foldIdentity(registration.ComponentID)
		if _, duplicate := commandComponents[componentKey]; duplicate {
			return fmt.Errorf("commandRegistrations[%d] duplicates component %q", i, registration.ComponentID)
		}
		commandComponents[componentKey] = struct{}{}
		if _, exists := definitions[componentKey]; !exists {
			return fmt.Errorf("commandRegistrations[%d] has no matching definition lineage", i)
		}
		pairKey := commandRegistrationKey(registration.CommandKind, registration.PayloadFormatVersion)
		if _, duplicate := commandPairs[pairKey]; duplicate {
			return fmt.Errorf("commandRegistrations[%d] duplicates kind/version %q", i, pairKey)
		}
		commandPairs[pairKey] = struct{}{}
	}
	for i, projection := range doc.Projections {
		if projection.Profile == ProjectionCommandAcceptanceV1 && len(projection.DefinitionComponentIDs) == 0 {
			return fmt.Errorf("Runtime projection %d has no command registrations", i)
		}
		for _, componentID := range projection.DefinitionComponentIDs {
			_, command := commandComponents[foldIdentity(componentID)]
			switch {
			case projection.Profile == ProjectionCommandAcceptanceV1 && !command:
				return fmt.Errorf("Runtime projection %d selects non-command definition %q", i, componentID)
			case projection.Profile != ProjectionCommandAcceptanceV1 && command:
				return fmt.Errorf("Runtime projection %d selects command registration %q outside command authority", i, componentID)
			}
		}
	}
	if doc.Schema == CatalogSnapshotSchemaV3 {
		if err := validateLegacyMutationScopes(doc.Mutation, definitions); err != nil {
			return err
		}
	} else if doc.Mutation != nil && len(doc.Mutation.LegacyScopes) != 0 {
		return fmt.Errorf("v4 Catalog snapshot contains retired mutation component scopes")
	}
	return nil
}

func validateRuntimeViewDocument(doc runtimeViewDocument) error {
	if err := validateRuntimeReferenceIdentities(doc); err != nil {
		return err
	}
	if doc.Schema == RuntimeMetadataViewSchemaV2 && doc.Mutation != nil {
		return fmt.Errorf("v2 Runtime metadata view contains mutation definitions")
	}
	if doc.Profile == ProjectionRecordMutationV1 &&
		((doc.Schema != RuntimeMetadataViewSchemaV4 && doc.Schema != RuntimeMetadataViewSchemaV13 && doc.Schema != RuntimeMetadataViewSchemaV14 && doc.Schema != RuntimeMetadataViewSchemaV15 && doc.Schema != RuntimeMetadataViewSchemaV17 && doc.Schema != RuntimeMetadataViewSchemaV22 && doc.Schema != RuntimeMetadataViewSchemaV25 && doc.Schema != RuntimeMetadataViewSchemaV26) || doc.Mutation == nil) {
		return fmt.Errorf("record-mutation Runtime metadata view requires a supported mutation closure")
	}
	if doc.Profile == ProjectionApprovalExecutionV1 && doc.Schema != RuntimeMetadataViewSchemaV16 && doc.Schema != RuntimeMetadataViewSchemaV19 && doc.Schema != RuntimeMetadataViewSchemaV25 {
		return fmt.Errorf("approval-execution Runtime metadata view requires v16, v19, or v25")
	}
	if doc.Profile == ProjectionApprovalExecutionV1 &&
		((len(doc.ApprovalDefinitions) == 0 && doc.Mutation != nil) ||
			(len(doc.ApprovalDefinitions) != 0 && doc.Mutation == nil)) {
		return fmt.Errorf("approval-execution Runtime metadata view must bind mutation authority exactly when it selects approval definitions")
	}
	if doc.Profile == ProjectionApprovalReadV1 &&
		(doc.Schema != RuntimeMetadataViewSchemaV16 || doc.Mutation != nil) {
		return fmt.Errorf("approval-read Runtime metadata view requires v16 without mutation authority")
	}
	if doc.Schema == RuntimeMetadataViewSchemaV16 && !profileUsesApprovalAuthority(doc.Profile) {
		return fmt.Errorf("v16 Runtime metadata view is reserved for approval authority")
	}
	if doc.Schema == RuntimeMetadataViewSchemaV19 && (doc.Profile != ProjectionApprovalExecutionV1 ||
		doc.Mutation == nil || len(doc.FormulaFunctionBundles) == 0) {
		return fmt.Errorf("v19 Runtime metadata view requires approval-execution formula authority")
	}
	if doc.Profile == ProjectionEffectivePermissionsV1 {
		if (doc.Schema != RuntimeMetadataViewSchemaV18 && doc.Schema != RuntimeMetadataViewSchemaV21) || doc.EffectivePermissions == nil {
			return fmt.Errorf("effective-permissions Runtime metadata view requires v18 or v21 authority")
		}
		if len(doc.SharingRules) != 0 ||
			len(doc.Definitions) != 0 || len(doc.Reports) != 0 || len(doc.CommandRegistrations) != 0 ||
			len(doc.ApprovalDefinitions) != 0 || len(doc.ReferenceIdentities) != 0 || doc.Mutation != nil || doc.RecordView != nil ||
			len(doc.FormulaFunctionBundles) != 0 || len(doc.OutboundIntentRoutes) != 0 {
			return fmt.Errorf("effective-permissions Runtime metadata view contains authority outside its least-privilege projection")
		}
		if doc.Schema == RuntimeMetadataViewSchemaV18 && (len(doc.Objects) != 0 || len(doc.Relationships) != 0) {
			return fmt.Errorf("v18 effective-permissions Runtime metadata view contains decision metadata")
		}
		if doc.Schema == RuntimeMetadataViewSchemaV21 && len(doc.Objects) == 0 {
			return fmt.Errorf("v21 effective-permissions Runtime metadata view has no decision objects")
		}
		if err := validateEffectivePermissionDefinitions(doc.EffectivePermissions); err != nil {
			return fmt.Errorf("effective-permissions Runtime metadata view: %w", err)
		}
	} else if doc.EffectivePermissions != nil {
		return fmt.Errorf("non-effective-permissions Runtime metadata view contains effective-permission metadata")
	}
	if doc.Schema == RuntimeMetadataViewSchemaV18 && doc.Profile != ProjectionEffectivePermissionsV1 {
		return fmt.Errorf("v18 Runtime metadata view is reserved for effective-permission authority")
	}
	if doc.Schema == RuntimeMetadataViewSchemaV21 && doc.Profile != ProjectionEffectivePermissionsV1 {
		return fmt.Errorf("v21 Runtime metadata view is reserved for effective-permission authority")
	}
	if !profileUsesApprovalAuthority(doc.Profile) && len(doc.ApprovalDefinitions) != 0 {
		return fmt.Errorf("non-approval Runtime metadata view contains approval definitions")
	}
	if doc.Profile == ProjectionApprovalExecutionV1 && doc.Mutation != nil &&
		(mutationHasConnectorRuntimeFacts(doc.Mutation) || len(doc.Mutation.OAuthPublicScopes) != 0) {
		return fmt.Errorf("approval-execution Runtime metadata view contains connector or OAuth authority")
	}
	if doc.Profile == ProjectionReportExecutionV1 && doc.Schema != RuntimeMetadataViewSchemaV10 {
		return fmt.Errorf("report-execution Runtime metadata view requires v10")
	}
	if doc.Profile != ProjectionReportExecutionV1 && len(doc.Reports) != 0 {
		return fmt.Errorf("non-report Runtime metadata view contains report definitions")
	}
	if doc.Profile == ProjectionCommandAcceptanceV1 &&
		(doc.Schema != RuntimeMetadataViewSchemaV11 &&
			doc.Schema != RuntimeMetadataViewSchemaV12 ||
			len(doc.CommandRegistrations) == 0) {
		return fmt.Errorf("command-acceptance Runtime metadata view requires the command registration closure")
	}
	if len(doc.CommandRegistrations) != 0 && doc.Profile != ProjectionCommandAcceptanceV1 {
		return fmt.Errorf("Runtime metadata view contains command registrations outside command authority")
	}
	hasExecutionBindings := commandRecordsHaveExecutionBindings(doc.CommandRegistrations)
	if doc.Schema != RuntimeMetadataViewSchemaV12 && hasExecutionBindings {
		return fmt.Errorf("pre-v12 Runtime metadata view contains command execution bindings")
	}
	if doc.Schema == RuntimeMetadataViewSchemaV12 && !hasExecutionBindings {
		return fmt.Errorf("v12 Runtime metadata view contains no command execution binding")
	}
	hasConnectorRuntimeFacts := mutationHasConnectorRuntimeFacts(doc.Mutation)
	if doc.Schema != RuntimeMetadataViewSchemaV13 && doc.Schema != RuntimeMetadataViewSchemaV14 && doc.Schema != RuntimeMetadataViewSchemaV15 && doc.Schema != RuntimeMetadataViewSchemaV17 && doc.Schema != RuntimeMetadataViewSchemaV22 && doc.Schema != RuntimeMetadataViewSchemaV25 && doc.Schema != RuntimeMetadataViewSchemaV26 && hasConnectorRuntimeFacts {
		return fmt.Errorf("pre-v13 Runtime metadata view contains connector execution facts")
	}
	if doc.Schema == RuntimeMetadataViewSchemaV13 && !hasConnectorRuntimeFacts {
		return fmt.Errorf("v13 Runtime metadata view contains no connector execution facts")
	}
	hasConnectorFinalization := mutationHasConnectorFinalizationAuthority(doc.Mutation)
	if doc.Schema != RuntimeMetadataViewSchemaV14 && doc.Schema != RuntimeMetadataViewSchemaV15 && doc.Schema != RuntimeMetadataViewSchemaV17 && doc.Schema != RuntimeMetadataViewSchemaV22 && doc.Schema != RuntimeMetadataViewSchemaV25 && doc.Schema != RuntimeMetadataViewSchemaV26 && hasConnectorFinalization {
		return fmt.Errorf("pre-v14 Runtime metadata view contains connector finalization authority")
	}
	if doc.Schema == RuntimeMetadataViewSchemaV14 && !hasConnectorFinalization {
		return fmt.Errorf("v14 Runtime metadata view contains no connector finalization authority")
	}
	hasRecoveryEligibility := mutationHasConnectorRecoveryEligibility(doc.Mutation)
	if doc.Schema != RuntimeMetadataViewSchemaV15 && doc.Schema != RuntimeMetadataViewSchemaV17 && doc.Schema != RuntimeMetadataViewSchemaV22 && doc.Schema != RuntimeMetadataViewSchemaV25 && doc.Schema != RuntimeMetadataViewSchemaV26 && hasRecoveryEligibility {
		return fmt.Errorf("pre-v15 Runtime metadata view contains connector recovery eligibility")
	}
	if doc.Schema == RuntimeMetadataViewSchemaV15 && !hasRecoveryEligibility {
		return fmt.Errorf("v15 Runtime metadata view contains no connector recovery eligibility")
	}
	if doc.Schema != RuntimeMetadataViewSchemaV17 && doc.Schema != RuntimeMetadataViewSchemaV19 && doc.Schema != RuntimeMetadataViewSchemaV22 && doc.Schema != RuntimeMetadataViewSchemaV25 && doc.Schema != RuntimeMetadataViewSchemaV26 && len(doc.FormulaFunctionBundles) != 0 {
		return fmt.Errorf("Runtime metadata view schema does not carry formula function bundles")
	}
	if doc.Schema != RuntimeMetadataViewSchemaV17 && doc.Schema != RuntimeMetadataViewSchemaV22 && doc.Schema != RuntimeMetadataViewSchemaV25 && doc.Schema != RuntimeMetadataViewSchemaV26 && len(doc.OutboundIntentRoutes) != 0 {
		return fmt.Errorf("pre-v17 Runtime metadata view contains outbound intent routes")
	}
	if doc.Schema == RuntimeMetadataViewSchemaV17 && (doc.Profile != ProjectionRecordMutationV1 ||
		(len(doc.FormulaFunctionBundles) == 0 && len(doc.OutboundIntentRoutes) == 0)) {
		return fmt.Errorf("v17 Runtime metadata view requires record-mutation v17 authority")
	}
	hasTypedOutboundIntentGrammar := outboundIntentRoutesUseTypedOperationGrammar(doc.OutboundIntentRoutes)
	hasMailAuthority := outboundIntentRoutesUseMailAuthority(doc.OutboundIntentRoutes)
	hasMailV2Authority := outboundIntentRoutesUseMailV2Authority(doc.OutboundIntentRoutes)
	if doc.Schema != RuntimeMetadataViewSchemaV22 && doc.Schema != RuntimeMetadataViewSchemaV25 && doc.Schema != RuntimeMetadataViewSchemaV26 && hasTypedOutboundIntentGrammar {
		return fmt.Errorf("pre-v22 Runtime metadata view contains typed outbound intent authority")
	}
	if doc.Schema == RuntimeMetadataViewSchemaV22 &&
		(doc.Profile != ProjectionRecordMutationV1 || doc.Mutation == nil || !hasMailAuthority || hasMailV2Authority) {
		return fmt.Errorf("v22 Runtime metadata view requires record-mutation outbound mail authority")
	}
	if doc.Schema != RuntimeMetadataViewSchemaV26 && hasMailV2Authority {
		return fmt.Errorf("pre-v26 Runtime metadata view contains outbound mail v2 authority")
	}
	if doc.Schema == RuntimeMetadataViewSchemaV26 &&
		(doc.Profile != ProjectionRecordMutationV1 || doc.Mutation == nil || !hasMailV2Authority) {
		return fmt.Errorf("v26 Runtime metadata view requires record-mutation outbound mail v2 authority")
	}
	formulaEngine, err := formulaEngineForRuntimeArtifact(doc.Schema, doc.FormulaFunctionBundles)
	if err != nil {
		return err
	}
	if doc.Schema == RuntimeMetadataViewSchemaV17 || doc.Schema == RuntimeMetadataViewSchemaV19 || doc.Schema == RuntimeMetadataViewSchemaV22 || doc.Schema == RuntimeMetadataViewSchemaV25 || doc.Schema == RuntimeMetadataViewSchemaV26 {
		if err := validateFormulaFunctionBundles(doc.FormulaFunctionBundles); err != nil {
			return err
		}
	}
	if err := validateOutboundIntentRoutes(doc.OutboundIntentRoutes, doc.Mutation); err != nil {
		return err
	}
	if !profileUsesMutationClosure(doc.Profile) && doc.Mutation != nil {
		return fmt.Errorf("non-mutation Runtime metadata view contains mutation definitions")
	}
	if doc.Mutation != nil && len(doc.Mutation.LegacyScopes) != 0 {
		return fmt.Errorf("Runtime metadata view contains retired Catalog component scopes")
	}
	if doc.Profile == ProjectionRecordViewV1 && ((doc.Schema != RuntimeMetadataViewSchemaV5 && doc.Schema != RuntimeMetadataViewSchemaV6 && doc.Schema != RuntimeMetadataViewSchemaV7 && doc.Schema != RuntimeMetadataViewSchemaV24) || doc.RecordView == nil) {
		return fmt.Errorf("record-view Runtime metadata view requires a resolver closure")
	}
	if doc.Profile != ProjectionRecordViewV1 && doc.RecordView != nil {
		return fmt.Errorf("non-record-view Runtime metadata view contains record-view resolver definitions")
	}
	if doc.Profile == ProjectionPageLayoutResolutionV1 {
		if doc.Schema != RuntimeMetadataViewSchemaV23 || doc.PageLayoutResolution == nil {
			return fmt.Errorf("page-layout resolution Runtime metadata view requires v23 routing authority")
		}
		if len(doc.Objects) != 0 || len(doc.Relationships) != 0 || len(doc.SharingRules) != 0 ||
			len(doc.Definitions) != 0 || len(doc.Reports) != 0 || len(doc.CommandRegistrations) != 0 ||
			len(doc.ApprovalDefinitions) != 0 || len(doc.ReferenceIdentities) != 0 || doc.Mutation != nil ||
			doc.RecordView != nil || doc.EffectivePermissions != nil || len(doc.FormulaFunctionBundles) != 0 ||
			len(doc.OutboundIntentRoutes) != 0 {
			return fmt.Errorf("page-layout resolution Runtime metadata view contains authority outside its least-privilege projection")
		}
		if err := validatePageLayoutResolutionDocument(doc.PageLayoutResolution, nil, doc.Schema); err != nil {
			return err
		}
	} else if doc.PageLayoutResolution != nil {
		return fmt.Errorf("non-page-layout Runtime metadata view contains page-layout resolution authority")
	}
	if doc.Profile == ProjectionLayoutAuthoringV1 {
		if (doc.Schema != RuntimeMetadataViewSchemaV27 && doc.Schema != RuntimeMetadataViewSchemaV28) || doc.LayoutAuthoring == nil {
			return fmt.Errorf("Layout authoring Runtime metadata view requires v27/v28 stored authority")
		}
		if err := validateLayoutAuthoringProjectionBinding(doc.CapabilityID, nil); err != nil {
			return err
		}
		if err := validateLayoutCreateContextVersion(doc.LayoutAuthoring, doc.Schema == RuntimeMetadataViewSchemaV28); err != nil {
			return err
		}
		if len(doc.Objects) != 0 || len(doc.Relationships) != 0 || len(doc.SharingRules) != 0 ||
			len(doc.Definitions) != 0 || len(doc.Reports) != 0 || len(doc.CommandRegistrations) != 0 ||
			len(doc.ApprovalDefinitions) != 0 || len(doc.ReferenceIdentities) != 0 || doc.Mutation != nil ||
			doc.RecordView != nil || doc.EffectivePermissions != nil || doc.PageLayoutResolution != nil ||
			len(doc.FormulaFunctionBundles) != 0 || len(doc.OutboundIntentRoutes) != 0 {
			return fmt.Errorf("Layout authoring Runtime metadata view contains authority outside its least-privilege projection")
		}
		if err := validateLayoutAuthoringDocument(doc.LayoutAuthoring); err != nil {
			return err
		}
	} else if doc.LayoutAuthoring != nil {
		return fmt.Errorf("non-Layout-authoring Runtime metadata view contains stored Layout authority")
	}
	if doc.Schema == RuntimeMetadataViewSchemaV23 && doc.Profile != ProjectionPageLayoutResolutionV1 {
		return fmt.Errorf("v23 Runtime metadata view is reserved for page-layout resolution authority")
	}
	if doc.Schema == RuntimeMetadataViewSchemaV24 && doc.Profile != ProjectionRecordViewV1 {
		return fmt.Errorf("v24 Runtime metadata view is reserved for complete record-view authority")
	}
	hasFieldMappingValuePolicies := mutationHasFieldMappingValuePolicies(doc.Mutation)
	if doc.Schema != RuntimeMetadataViewSchemaV25 && doc.Schema != RuntimeMetadataViewSchemaV26 && hasFieldMappingValuePolicies {
		return fmt.Errorf("pre-v25 Runtime metadata view contains field-mapping value policies")
	}
	if doc.Schema == RuntimeMetadataViewSchemaV25 &&
		(!profileUsesMutationClosure(doc.Profile) || doc.Mutation == nil || !hasFieldMappingValuePolicies) {
		return fmt.Errorf("v25 Runtime metadata view requires mutation field-mapping value policies")
	}
	if doc.Schema == RuntimeMetadataViewSchemaV26 && doc.Profile != ProjectionRecordMutationV1 {
		return fmt.Errorf("v26 Runtime metadata view is reserved for outbound-mail v2 mutation authority")
	}
	if (doc.Schema == RuntimeMetadataViewSchemaV27 || doc.Schema == RuntimeMetadataViewSchemaV28) && doc.Profile != ProjectionLayoutAuthoringV1 {
		return fmt.Errorf("v27/v28 Runtime metadata view is reserved for Layout authoring authority")
	}
	if !validDigest(doc.SourceSnapshotDigest) {
		return fmt.Errorf("source snapshot digest %q is invalid", doc.SourceSnapshotDigest)
	}
	if err := requireCanonicalIdentity("orgId", doc.OrgID); err != nil {
		return err
	}
	if err := requireCanonicalIdentity("appInstallationId", doc.AppInstallationID); err != nil {
		return err
	}
	if err := requireCanonicalIdentity("capabilityId", doc.CapabilityID); err != nil {
		return err
	}
	if err := validateProjectionProfile("profile", doc.Profile); err != nil {
		return err
	}
	if err := validateLineage(doc.Lineage); err != nil {
		return err
	}
	if len(doc.Objects) == 0 && doc.Profile != ProjectionCommandAcceptanceV1 && doc.Profile != ProjectionPageLayoutResolutionV1 && doc.Profile != ProjectionLayoutAuthoringV1 &&
		!(doc.Profile == ProjectionEffectivePermissionsV1 && doc.Schema == RuntimeMetadataViewSchemaV18) {
		return fmt.Errorf("Runtime metadata view has no objects")
	}
	if len(doc.Objects) != 0 && (doc.Profile == ProjectionCommandAcceptanceV1 || doc.Profile == ProjectionPageLayoutResolutionV1 || doc.Profile == ProjectionLayoutAuthoringV1) {
		return fmt.Errorf("Runtime metadata view profile %q contains object metadata", doc.Profile)
	}
	usesMutationClosure := profileUsesMutationClosure(doc.Profile) && doc.Mutation != nil
	effectiveProfile := doc.Profile
	if doc.Profile == ProjectionApprovalExecutionV1 && !usesMutationClosure {
		effectiveProfile = ProjectionApprovalReadV1
	}
	objects := make(map[string]struct{}, len(doc.Objects))
	approvalObjects := make(map[string]string, len(doc.Objects))
	objectsByName := make(map[string]runtimeObjectRecord, len(doc.Objects))
	objectsByKeyPrefix := make(map[string]string, len(doc.Objects))
	fieldsByObject := make(map[string]map[string]struct{}, len(doc.Objects))
	for i, object := range doc.Objects {
		if err := requireCatalogObjectAPIName(fmt.Sprintf("objects[%d].apiName", i), object.APIName); err != nil {
			return err
		}
		key := foldIdentity(object.APIName)
		if _, exists := objects[key]; exists {
			return fmt.Errorf("duplicate Runtime object %q", object.APIName)
		}
		objects[key] = struct{}{}
		approvalObjects[key] = object.APIName
		objectsByName[key] = object
		if doc.Profile == ProjectionRecordAccessV1 && doc.Schema == RuntimeMetadataViewSchemaV8 {
			if object.KeyPrefix != nil && strings.TrimSpace(*object.KeyPrefix) == "" {
				return fmt.Errorf("Runtime object %q has a blank KeyPrefix", object.APIName)
			}
		} else if object.KeyPrefix != nil {
			return fmt.Errorf("Runtime object %q contains KeyPrefix outside an identity-bearing projection", object.APIName)
		}
		keyPrefix := object.KeyPrefix
		if object.Mutation != nil {
			keyPrefix = object.Mutation.KeyPrefix
		}
		if err := registerKeyPrefixOwner(objectsByKeyPrefix, keyPrefix, object.APIName); err != nil {
			return fmt.Errorf("Runtime view: %w", err)
		}
		if (effectiveProfile == ProjectionSelectedRootReadV1 || effectiveProfile == ProjectionRecordQueryV1 || effectiveProfile == ProjectionApprovalReadV1 ||
			(effectiveProfile == ProjectionRecordViewV1 && doc.Schema != RuntimeMetadataViewSchemaV24)) &&
			(object.RequiredWritePermission != "" || object.LockRule != nil) {
			return fmt.Errorf("read-only Runtime object %q contains access-decision metadata", object.APIName)
		}
		if effectiveProfile != ProjectionEffectivePermissionsV1 && object.TableType != "" {
			return fmt.Errorf("Runtime object %q contains permission-decision TableType outside effective permissions", object.APIName)
		}
		if err := validateRuntimeAccessPolicyProfile(effectiveProfile, doc.Schema, object.APIName, object.AccessPolicy); err != nil {
			return err
		}
		if usesMutationClosure && object.Mutation == nil {
			return fmt.Errorf("record-mutation Runtime object %q has no write-engine metadata", object.APIName)
		}
		if !usesMutationClosure && object.Mutation != nil {
			return fmt.Errorf("read Runtime object %q contains mutation metadata", object.APIName)
		}
		if object.Mutation != nil {
			mutationObject := runtimeObjectToModel(object)
			if mutationObject == nil {
				return fmt.Errorf("record-mutation Runtime object %q cannot be reconstructed", object.APIName)
			}
		}
		if effectiveProfile == ProjectionEffectivePermissionsV1 {
			model := runtimeObjectToModel(object)
			expected, err := buildRuntimeObject(model, ProjectionEffectivePermissionsV1, nil, doc.Schema)
			if err != nil {
				return fmt.Errorf("effective-permission Runtime object %q is invalid: %w", object.APIName, err)
			}
			actualBytes, actualErr := marshalCanonical(object)
			expectedBytes, expectedErr := marshalCanonical(expected)
			if actualErr != nil || expectedErr != nil || !bytes.Equal(actualBytes, expectedBytes) {
				return fmt.Errorf("effective-permission Runtime object %q contains facts outside its decision closure", object.APIName)
			}
		} else {
			baseReadTable, err := (&models.ObjectMetadata{APIName: object.APIName, ReadSource: object.ReadSource}).ResolveReadSourceTable()
			if err != nil || object.ResolvedBaseReadTable != baseReadTable {
				return fmt.Errorf("Runtime object %q resolved base read table %q does not match readSource result %q: %v", object.APIName, object.ResolvedBaseReadTable, baseReadTable, err)
			}
		}
		seenFields := map[string]struct{}{}
		for _, field := range object.Fields {
			key := foldIdentity(field.APIName)
			if key == "" {
				return fmt.Errorf("Runtime object %q has a blank field", object.APIName)
			}
			if _, exists := seenFields[key]; exists {
				return fmt.Errorf("Runtime object %q has duplicate field %q", object.APIName, field.APIName)
			}
			seenFields[key] = struct{}{}
			if usesMutationClosure && field.Mutation == nil {
				return fmt.Errorf("record-mutation Runtime object %q field %q has no write-engine metadata", object.APIName, field.APIName)
			}
			if !usesMutationClosure && field.Mutation != nil {
				return fmt.Errorf("read Runtime object %q field %q contains mutation metadata", object.APIName, field.APIName)
			}
		}
		fieldsByObject[key] = seenFields
		if object.LockRule != nil {
			if err := formula.ValidateLockRuleExpression(*object.LockRule, formula.NewEngine(), runtimeObjectToModel(object)); err != nil {
				return fmt.Errorf("Runtime object %q LockRule is invalid: %w", object.APIName, err)
			}
		}
	}
	if effectiveProfile == ProjectionEffectivePermissionsV1 && doc.Schema == RuntimeMetadataViewSchemaV21 {
		if len(doc.EffectivePermissions.Objects) != len(objects) {
			return fmt.Errorf("effective-permission Runtime metadata view decision and record-type object scopes differ")
		}
		for _, object := range doc.EffectivePermissions.Objects {
			if len(object.FieldNames) != 0 {
				return fmt.Errorf("v21 effective-permission object %q duplicates field identity", object.ResourceType)
			}
			if _, exists := objects[foldIdentity(object.ResourceType)]; !exists {
				return fmt.Errorf("effective-permission record-type object %q is outside the decision closure", object.ResourceType)
			}
		}
	}
	seenRelationships := map[string]struct{}{}
	sharingParents := map[string]struct{}{}
	for _, relationship := range doc.Relationships {
		childKey := foldIdentity(relationship.ChildObjectAPIName)
		if _, exists := objects[childKey]; !exists {
			return fmt.Errorf("Runtime relationship child %q is outside the view", relationship.ChildObjectAPIName)
		}
		if _, exists := objects[foldIdentity(relationship.ParentObjectAPIName)]; !exists {
			return fmt.Errorf("Runtime relationship parent %q is outside the view", relationship.ParentObjectAPIName)
		}
		if _, exists := fieldsByObject[childKey][foldIdentity(relationship.FieldAPIName)]; !exists {
			return fmt.Errorf("Runtime relationship field %q is absent from child %q", relationship.FieldAPIName, relationship.ChildObjectAPIName)
		}
		if effectiveProfile != ProjectionRecordQueryV1 && !usesMutationClosure && !relationship.IsSharingParent {
			return fmt.Errorf("Runtime relationship for %q is not a sharing-parent edge", relationship.ChildObjectAPIName)
		}
		if effectiveProfile == ProjectionEffectivePermissionsV1 && relationship.RelationshipName != "" {
			return fmt.Errorf("effective-permission Runtime relationship %q.%s contains presentation identity", relationship.ChildObjectAPIName, relationship.FieldAPIName)
		}
		if usesMutationClosure && relationship.Mutation == nil {
			return fmt.Errorf("record-mutation Runtime relationship %q.%s has no write-engine metadata", relationship.ChildObjectAPIName, relationship.FieldAPIName)
		}
		if !usesMutationClosure && relationship.Mutation != nil {
			return fmt.Errorf("read Runtime relationship %q.%s contains mutation metadata", relationship.ChildObjectAPIName, relationship.FieldAPIName)
		}
		key := runtimeRelationshipKey(relationship)
		if _, exists := seenRelationships[key]; exists {
			return fmt.Errorf("Runtime relationship %q is duplicated", key)
		}
		seenRelationships[key] = struct{}{}
		if relationship.IsSharingParent {
			if _, exists := sharingParents[childKey]; exists {
				return fmt.Errorf("Runtime object %q has multiple sharing parents", relationship.ChildObjectAPIName)
			}
			sharingParents[childKey] = struct{}{}
		}
	}
	mutationObjects := make(map[string]*models.ObjectMetadata, len(objectsByName))
	for key, object := range objectsByName {
		mutationObjects[key] = runtimeObjectToModel(object)
	}
	if err := validateOutboundMailCompletionMetadata(doc.OutboundIntentRoutes, mutationObjects); err != nil {
		return err
	}
	if isFlowExecutionCapability(doc.CapabilityID) {
		included := make(map[string]struct{}, len(mutationObjects))
		for key := range mutationObjects {
			included[key] = struct{}{}
		}
		if err := validateRuntimeFlowExecutionDefinitions(doc.Mutation, included, formulaEngine); err != nil {
			return err
		}
	} else if doc.Profile == ProjectionApprovalExecutionV1 {
		if err := validateRuntimeApprovalMutationDefinitions(doc.Mutation, mutationObjects, formulaEngine); err != nil {
			return err
		}
	} else {
		if err := validateRuntimeMutationDefinitions(doc.Mutation, mutationObjects, doc.OutboundIntentRoutes, formulaEngine); err != nil {
			return err
		}
		usesCommand, err := mutationUsesFlowActionType(doc.Mutation, unsupportedFlowAcceptCommandActionType)
		if err != nil {
			return err
		}
		if usesCommand {
			return fmt.Errorf("Flow acceptCommand action is outside the Runtime mutation worker closure")
		}
	}
	// A view may faithfully contain a legacy parent-controlled object with no
	// sharing parent. Exact source verification still detects an edge removed
	// from an otherwise well-formed source projection.
	if err := validateRuntimePolicyDependencies(doc.Objects, objects); err != nil {
		return err
	}
	for _, rule := range doc.SharingRules {
		if _, exists := objects[foldIdentity(rule.ObjectAPIName)]; !exists {
			return fmt.Errorf("Runtime sharing rule object %q is outside the view", rule.ObjectAPIName)
		}
		if strings.TrimSpace(rule.AccessLevel) == "" {
			return fmt.Errorf("Runtime sharing rule for %q has a blank access level", rule.ObjectAPIName)
		}
		for name, value := range map[string]*string{
			"sharedFromRoleId": rule.SharedFromRoleID, "sharedFromGroupId": rule.SharedFromGroupID,
			"shareWithRoleId": rule.ShareWithRoleID, "shareWithGroupId": rule.ShareWithGroupID,
		} {
			if value != nil {
				if err := requireCanonicalIdentity("Runtime sharing rule "+name, *value); err != nil {
					return err
				}
			}
		}
	}
	seenDefinitions := map[string]struct{}{}
	definitionLineages := map[string]definitionRecord{}
	for _, definition := range doc.Definitions {
		key := foldIdentity(definition.ComponentID)
		if key == "" || strings.TrimSpace(string(definition.DefinitionVersion)) == "" || !validDigest(definition.ContentDigest) {
			return fmt.Errorf("Runtime definition %q has invalid identity, version, or digest", definition.ComponentID)
		}
		if _, exists := seenDefinitions[key]; exists {
			return fmt.Errorf("Runtime definition %q is duplicated", definition.ComponentID)
		}
		seenDefinitions[key] = struct{}{}
		definitionLineages[key] = definition
	}
	approvalIDs := make(map[string]struct{}, len(doc.ApprovalDefinitions))
	approvalNames := make(map[string]struct{}, len(doc.ApprovalDefinitions))
	for index, definition := range doc.ApprovalDefinitions {
		if err := validateApprovalDefinitionRecord(
			fmt.Sprintf("approvalDefinitions[%d]", index),
			definition,
			approvalObjects,
		); err != nil {
			return err
		}
		idKey := foldIdentity(definition.DefinitionID)
		if _, duplicate := approvalIDs[idKey]; duplicate {
			return fmt.Errorf("Runtime approval definition %q is duplicated", definition.DefinitionID)
		}
		approvalIDs[idKey] = struct{}{}
		lineage, exists := definitionLineages[idKey]
		if !exists {
			return fmt.Errorf("Runtime approval definition %q has no definition lineage", definition.DefinitionID)
		}
		if lineage.DefinitionVersion != DefinitionVersion(definition.SourceDigest) ||
			lineage.ContentDigest != definition.ContentDigest ||
			lineage.ComponentID != definition.DefinitionID {
			return fmt.Errorf("Runtime approval definition %q conflicts with its definition lineage", definition.DefinitionID)
		}
		nameKey := foldIdentity(definition.ObjectAPIName) + "\x00" + foldIdentity(definition.DeveloperName)
		if _, duplicate := approvalNames[nameKey]; duplicate {
			return fmt.Errorf("Runtime approval definition %q duplicates object/name identity", definition.DefinitionID)
		}
		approvalNames[nameKey] = struct{}{}
	}
	if profileUsesApprovalAuthority(doc.Profile) && len(seenDefinitions) != len(approvalIDs) {
		return fmt.Errorf("Runtime approval view contains definition lineage outside approval authority")
	}
	if doc.Profile == ProjectionApprovalExecutionV1 && len(doc.ApprovalDefinitions) != 0 {
		projected, err := projectMutationDefinitions(
			doc.Mutation,
			objects,
			doc.Profile,
			doc.CapabilityID,
			approvalFlowNames(doc.ApprovalDefinitions),
			doc.OutboundIntentRoutes,
			formulaEngine,
		)
		if err != nil {
			return fmt.Errorf("Runtime approval view has an incomplete execution closure: %w", err)
		}
		actual, err := marshalCanonical(doc.Mutation)
		if err != nil {
			return fmt.Errorf("Runtime approval mutation closure cannot be encoded: %w", err)
		}
		expected, err := marshalCanonical(projected)
		if err != nil {
			return fmt.Errorf("Runtime projected approval mutation closure cannot be encoded: %w", err)
		}
		if !bytes.Equal(actual, expected) {
			return fmt.Errorf("Runtime approval mutation closure contains unselected authority")
		}
	}
	if err := validateRecordViewDefinitions(doc.RecordView, runtimeObjectsToModels(doc.Objects), catalogSchemaForRuntimeViewSchema(doc.Schema)); err != nil {
		return err
	}
	reportComponents := make(map[string]struct{}, len(doc.Reports))
	reportIDs := make(map[string]struct{}, len(doc.Reports))
	for i, report := range doc.Reports {
		if err := validateReportDefinitionRecord(fmt.Sprintf("reports[%d]", i), report, runtimeObjectsToModels(doc.Objects)); err != nil {
			return err
		}
		componentKey := foldIdentity(report.ComponentID)
		if _, exists := reportComponents[componentKey]; exists {
			return fmt.Errorf("Runtime report component %q is duplicated", report.ComponentID)
		}
		reportComponents[componentKey] = struct{}{}
		if _, exists := seenDefinitions[componentKey]; !exists {
			return fmt.Errorf("Runtime report %q has no definition lineage", report.ID)
		}
		idKey := foldIdentity(report.ID)
		if _, exists := reportIDs[idKey]; exists {
			return fmt.Errorf("Runtime report id %q is duplicated", report.ID)
		}
		reportIDs[idKey] = struct{}{}
	}
	commandPairs := make(map[string]struct{}, len(doc.CommandRegistrations))
	for i, registration := range doc.CommandRegistrations {
		if err := validateCommandRegistrationRecord(fmt.Sprintf("commandRegistrations[%d]", i), registration); err != nil {
			return err
		}
		if _, exists := seenDefinitions[foldIdentity(registration.ComponentID)]; !exists {
			return fmt.Errorf("Runtime command registration %q has no definition lineage", registration.CommandKind)
		}
		key := commandRegistrationKey(registration.CommandKind, registration.PayloadFormatVersion)
		if _, duplicate := commandPairs[key]; duplicate {
			return fmt.Errorf("Runtime command registration %q is duplicated", key)
		}
		commandPairs[key] = struct{}{}
	}
	return nil
}

func runtimeObjectsToModels(records []runtimeObjectRecord) map[string]*models.ObjectMetadata {
	result := make(map[string]*models.ObjectMetadata, len(records))
	for _, record := range records {
		object := runtimeObjectToModel(record)
		result[foldIdentity(record.APIName)] = object
	}
	return result
}

// registerKeyPrefixOwner preserves the case-sensitive identity invariant used
// by MetadataService's live identity index at every immutable Catalog boundary.
// Values such as 00K and 00k are distinct; an exact duplicate is ambiguous and
// must never be resolved by input or canonical sort order.
func registerKeyPrefixOwner(owners map[string]string, keyPrefix *string, objectAPIName string) error {
	if keyPrefix == nil {
		return nil
	}
	value := strings.TrimSpace(*keyPrefix)
	if value == "" {
		return nil
	}
	if currentObjectAPIName, exists := owners[value]; exists {
		return fmt.Errorf(
			"duplicate key prefix %q maps to both %q and %q",
			value,
			currentObjectAPIName,
			objectAPIName,
		)
	}
	owners[value] = objectAPIName
	return nil
}

func validateRuntimeAccessPolicyProfile(profile ProjectionProfile, runtimeSchema, objectAPIName string, policy *models.ObjectAccessPolicy) error {
	projected, err := projectAccessPolicy(policy, profile, runtimeSchema)
	if err != nil {
		return fmt.Errorf("Runtime object %q access policy is invalid for profile %q: %w", objectAPIName, profile, err)
	}
	actual, err := marshalCanonical(policy)
	if err != nil {
		return fmt.Errorf("Runtime object %q access policy cannot be encoded: %w", objectAPIName, err)
	}
	expected, err := marshalCanonical(projected)
	if err != nil {
		return fmt.Errorf("Runtime object %q projected access policy cannot be encoded: %w", objectAPIName, err)
	}
	if !bytes.Equal(actual, expected) {
		return fmt.Errorf("Runtime object %q access policy contains facts outside profile %q", objectAPIName, profile)
	}
	return nil
}

func (s *CatalogSnapshot) Digest() Digest   { return s.digest }
func (s *CatalogSnapshot) OrgID() string    { return s.doc.OrgID }
func (s *CatalogSnapshot) Lineage() Lineage { return s.doc.Lineage }
func (s *CatalogSnapshot) ProjectionKeys() []ProjectionKey {
	keys := make([]ProjectionKey, len(s.doc.Projections))
	for i, projection := range s.doc.Projections {
		keys[i] = ProjectionKey{AppInstallationID: projection.AppInstallationID, CapabilityID: projection.CapabilityID}
	}
	return keys
}

func (v *RuntimeMetadataView) Digest() Digest               { return v.digest }
func (v *RuntimeMetadataView) SourceSnapshotDigest() Digest { return v.doc.SourceSnapshotDigest }
func (v *RuntimeMetadataView) OrgID() string                { return v.doc.OrgID }
func (v *RuntimeMetadataView) AppInstallationID() string    { return v.doc.AppInstallationID }
func (v *RuntimeMetadataView) CapabilityID() string         { return v.doc.CapabilityID }
func (v *RuntimeMetadataView) Profile() ProjectionProfile   { return v.doc.Profile }
func (v *RuntimeMetadataView) Lineage() Lineage             { return v.doc.Lineage }

// FormulaFunctionBundles returns the executable formula declarations selected
// by this exact immutable mutation-capable view. Other capability projections
// do not inherit formula authority.
func (v *RuntimeMetadataView) FormulaFunctionBundles() []formula.FunctionBundle {
	if v == nil {
		return nil
	}
	return formula.CloneFunctionBundles(v.doc.FormulaFunctionBundles)
}

// NewFormulaEngine constructs the executable formula engine owned by this
// exact immutable Runtime view. V17 and v19 views deliberately ignore
// process-global L1 registrations: the selected Catalog revision is the only
// formula vocabulary authority for a serving request.
func (v *RuntimeMetadataView) NewFormulaEngine() (*formula.Engine, error) {
	if v == nil {
		return nil, fmt.Errorf("runtime metadata view: formula engine requires a bound view")
	}
	return formulaEngineForRuntimeArtifact(v.doc.Schema, v.doc.FormulaFunctionBundles)
}

// OutboundIntentRoutes returns the detached immutable routes published for
// this exact record-mutation view. The caller still has to match one route to
// the currently executing Flow action; no repository fallback is permitted.
func (v *RuntimeMetadataView) OutboundIntentRoutes() []OutboundIntentRoute {
	if v == nil || len(v.doc.OutboundIntentRoutes) == 0 {
		return nil
	}
	cloned, err := cloneJSON(v.doc.OutboundIntentRoutes)
	if err != nil {
		return nil
	}
	return cloned
}

func (v *RuntimeMetadataView) VerifySource(snapshot *CatalogSnapshot) error {
	if v == nil || snapshot == nil {
		return fmt.Errorf("%w: view and snapshot are required", ErrArtifactCorrupt)
	}
	if v.doc.SourceSnapshotDigest != snapshot.digest || v.doc.OrgID != snapshot.doc.OrgID || v.doc.Lineage != snapshot.doc.Lineage {
		return fmt.Errorf("%w: Runtime view source lineage does not match Catalog snapshot", ErrArtifactCorrupt)
	}
	expected, err := ProjectRuntimeMetadataView(snapshot, ProjectionKey{
		AppInstallationID: v.doc.AppInstallationID,
		CapabilityID:      v.doc.CapabilityID,
	})
	if err != nil {
		return fmt.Errorf("%w: exact Runtime projection cannot be regenerated: %v", ErrArtifactCorrupt, err)
	}
	if expected.digest != v.digest {
		return fmt.Errorf("%w: Runtime view is not the exact projection of its Catalog snapshot", ErrArtifactCorrupt)
	}
	return nil
}

// VerifyCompatibility applies the v2 fail-closed compatibility rule. The
// Runtime must have reached at least the snapshot's physical schema generation,
// and must run the exact engine generation that defined its semantic model.
func (v *RuntimeMetadataView) VerifyCompatibility(local Compatibility) error {
	if v == nil {
		return fmt.Errorf("%w: Runtime metadata view is required", ErrIncompatible)
	}
	if local.SchemaGeneration < v.doc.Lineage.SchemaGeneration {
		return fmt.Errorf("%w: local schema generation %d is below required %d", ErrIncompatible, local.SchemaGeneration, v.doc.Lineage.SchemaGeneration)
	}
	if local.EngineGeneration != v.doc.Lineage.EngineGeneration {
		return fmt.Errorf("%w: local engine generation %d does not equal required %d", ErrIncompatible, local.EngineGeneration, v.doc.Lineage.EngineGeneration)
	}
	return nil
}

func (v *RuntimeMetadataView) Object(apiName string) (*models.ObjectMetadata, bool) {
	if v == nil {
		return nil, false
	}
	index, exists := v.objectsByName[foldIdentity(apiName)]
	if !exists {
		return nil, false
	}
	object := runtimeObjectToModel(v.doc.Objects[index])
	return object, object != nil
}

func (v *RuntimeMetadataView) Objects() []*models.ObjectMetadata {
	if v == nil {
		return nil
	}
	objects := make([]*models.ObjectMetadata, len(v.doc.Objects))
	for i := range v.doc.Objects {
		objects[i] = runtimeObjectToModel(v.doc.Objects[i])
	}
	return objects
}

// RollupChildDependencies returns only the detached rollup facts whose
// summary object is childObjectAPIName. Runtime mutation planning calls this
// repeatedly while it builds one transaction closure; indexing the immutable
// artifact avoids materializing every unrelated object and field on each
// lookup while preserving the public getter detachment contract.
func (v *RuntimeMetadataView) RollupChildDependencies(childObjectAPIName string) []domainSchema.RollupChildDependency {
	if v == nil {
		return nil
	}
	indexes := v.rollupDependenciesByChild[foldIdentity(childObjectAPIName)]
	if len(indexes) == 0 {
		return nil
	}
	dependencies := make([]domainSchema.RollupChildDependency, 0, len(indexes))
	for _, index := range indexes {
		if index.parentObjectIndex < 0 || index.parentObjectIndex >= len(v.doc.Objects) {
			continue
		}
		parent := v.doc.Objects[index.parentObjectIndex]
		if index.rollupFieldIndex < 0 || index.rollupFieldIndex >= len(parent.Fields) {
			continue
		}
		dependencies = append(dependencies, domainSchema.RollupChildDependency{
			ParentObjectAPIName: parent.APIName,
			RollupField:         runtimeFieldToModel(parent.Fields[index.rollupFieldIndex]),
		})
	}
	return dependencies
}

func (v *RuntimeMetadataView) HasRollupChildDependencies(childObjectAPIName string) bool {
	return v != nil && len(v.rollupDependenciesByChild[foldIdentity(childObjectAPIName)]) > 0
}

// HasAnySiblingMaxDefaults reports the one global safety fact needed by the
// insert transaction-boundary planner. The immutable Runtime view computes it
// once at open time so a mutation never has to materialize every unrelated
// object and field merely to answer this boolean question.
func (v *RuntimeMetadataView) HasAnySiblingMaxDefaults() bool {
	return v != nil && v.hasAnySiblingMaxDefaults
}

// RecordObjectCandidateAPINames returns the bounded object identity closure
// admitted into this exact Runtime request. Callers may probe these candidates
// to resolve an opaque record ID, but must still apply their capability's
// definition authority after resolution. This is not a repository-wide object
// inventory and does not infer identity from Catalog order.
func (v *RuntimeMetadataView) RecordObjectCandidateAPINames() []string {
	if v == nil {
		return nil
	}
	result := make([]string, 0, len(v.doc.Objects))
	for _, object := range v.doc.Objects {
		if name := strings.TrimSpace(object.APIName); name != "" {
			result = append(result, name)
		}
	}
	return result
}

func (v *RuntimeMetadataView) RelationshipsForChild(objectAPIName string) []*models.Relationship {
	if v == nil {
		return nil
	}
	indexes := v.relsByChild[foldIdentity(objectAPIName)]
	result := make([]*models.Relationship, 0, len(indexes))
	for _, index := range indexes {
		record := v.doc.Relationships[index]
		result = append(result, relationshipToModel(record))
	}
	return result
}

func (v *RuntimeMetadataView) RelationshipsForParent(objectAPIName string) []*models.Relationship {
	if v == nil {
		return nil
	}
	indexes := v.relsByParent[foldIdentity(objectAPIName)]
	result := make([]*models.Relationship, 0, len(indexes))
	for _, index := range indexes {
		result = append(result, relationshipToModel(v.doc.Relationships[index]))
	}
	return result
}

func (v *RuntimeMetadataView) SharingParentRelationship(objectAPIName string) (*models.Relationship, bool) {
	for _, relationship := range v.RelationshipsForChild(objectAPIName) {
		if relationship.IsSharingParent {
			return relationship, true
		}
	}
	return nil, false
}

func (v *RuntimeMetadataView) SharingRulesForObject(objectAPIName string) []*models.SharingRule {
	if v == nil {
		return nil
	}
	indexes := v.rulesByObject[foldIdentity(objectAPIName)]
	result := make([]*models.SharingRule, 0, len(indexes))
	for _, index := range indexes {
		result = append(result, sharingRuleToModel(v.doc.SharingRules[index]))
	}
	return result
}

func (v *RuntimeMetadataView) Definition(componentID string) (DefinitionVersion, Digest, bool) {
	if v == nil {
		return "", "", false
	}
	index, exists := v.definitionsByID[foldIdentity(componentID)]
	if !exists {
		return "", "", false
	}
	record := v.doc.Definitions[index]
	return record.DefinitionVersion, record.ContentDigest, true
}

func runtimeObjectToModel(record runtimeObjectRecord) *models.ObjectMetadata {
	policy, _ := cloneJSON(record.AccessPolicy)
	readSource, _ := cloneJSON(record.ReadSource)
	object := &models.ObjectMetadata{
		APIName: record.APIName, KeyPrefix: clonePointer(record.KeyPrefix), RequiredReadPermission: record.RequiredReadPermission,
		RequiredWritePermission: record.RequiredWritePermission, AccessPolicy: policy,
		TableType:    record.TableType,
		SharingModel: record.SharingModel, EnableHierarchySharing: record.EnableHierarchySharing,
		ReadSource: readSource, LockRule: clonePointer(record.LockRule), Fields: make([]models.FieldMetadata, len(record.Fields)),
		FieldsMap: make(map[string]*models.FieldMetadata, len(record.Fields)),
	}
	for i, field := range record.Fields {
		object.Fields[i] = runtimeFieldToModel(field)
		object.FieldsMap[foldIdentity(field.APIName)] = &object.Fields[i]
	}
	if mutation := record.Mutation; mutation != nil {
		object.KeyPrefix = clonePointer(mutation.KeyPrefix)
		object.IsSystem = mutation.IsSystem
		object.IsCustom = mutation.IsCustom
		object.CustomSetting = mutation.CustomSetting
		object.TableType = mutation.TableType
		object.DeleteMode = mutation.DeleteMode
		object.SharingParentObject = clonePointer(mutation.SharingParentObject)
		object.SharingParentField = clonePointer(mutation.SharingParentField)
		object.ChildCloneRules, _ = cloneJSON(mutation.ChildCloneRules)
		object.ExclusiveSiblingFields, _ = cloneJSON(mutation.ExclusiveSiblingFields)
		object.DefaultChildRows, _ = cloneJSON(mutation.DefaultChildRows)
	}
	return object
}

func runtimeFieldToModel(field runtimeFieldRecord) models.FieldMetadata {
	projection, _ := cloneJSON(field.ProjectionConfig)
	projected := models.FieldMetadata{
		APIName: field.APIName, PhysicalName: field.PhysicalName,
		Type: field.Type, LogicalType: clonePointer(field.LogicalType), Required: field.Required,
		IsCompound: field.IsCompound, ComposedFrom: append([]string(nil), field.ComposedFrom...),
		ReferenceTo: append([]string(nil), field.ReferenceTo...), IsPolymorphic: field.IsPolymorphic,
		Formula: clonePointer(field.Formula), ReturnType: clonePointer(field.ReturnType),
		FormulaMode: clonePointer(field.FormulaMode), FormulaStorageMode: clonePointer(field.FormulaStorageMode),
		ProjectionConfig: projection, IsMasterDetail: field.IsMasterDetail,
		RelationshipName:      clonePointer(field.RelationshipName),
		ChildRelationshipName: clonePointer(field.ChildRelationshipName),
		Precision:             clonePointer(field.Precision), Scale: clonePointer(field.Scale),
		IsVirtual: field.IsVirtual, VirtualKind: field.VirtualKind, VirtualSourceAPIName: field.VirtualSourceAPIName,
		ReadProtectionPolicy:             field.ReadProtectionPolicy,
		GeneratedForPolymorphicReference: field.GeneratedForPolymorphicReference,
		IsNameField:                      field.IsNameField,
	}
	if mutation := field.Mutation; mutation != nil {
		projected.ID = mutation.ID
		projected.DefaultedOnCreate = mutation.DefaultedOnCreate
		projected.IsUnique = mutation.IsUnique
		projected.IsNameField = mutation.IsNameField
		projected.Source = mutation.Source
		projected.Options = clonePicklistOptions(mutation.Options)
		projected.WritableReferenceTo = append([]string(nil), mutation.WritableReferenceTo...)
		projected.DeleteRule = clonePointer(mutation.DeleteRule)
		projected.IsSystem = mutation.IsSystem
		projected.Createable = mutation.Createable
		projected.Updateable = mutation.Updateable
		projected.DefaultValue = clonePointer(mutation.DefaultValue)
		projected.TrackHistory = mutation.TrackHistory
		projected.MinValue = clonePointer(mutation.MinValue)
		projected.MaxValue = clonePointer(mutation.MaxValue)
		projected.MinLength = clonePointer(mutation.MinLength)
		projected.MaxLength = clonePointer(mutation.MaxLength)
		projected.Regex = clonePointer(mutation.Regex)
		projected.RegexMessage = clonePointer(mutation.RegexMessage)
		projected.Validator = clonePointer(mutation.Validator)
		projected.ValidatorConfig = clonePointer(mutation.ValidatorConfig)
		projected.ControllingField = clonePointer(mutation.ControllingField)
		projected.PicklistDependency = cloneStringSliceMap(mutation.PicklistDependency)
		projected.RollupConfig = cloneRollupConfig(mutation.RollupConfig)
		projected.WriteProtectionPolicy = mutation.WriteProtectionPolicy
		projected.SiblingMaxParentField = clonePointer(mutation.SiblingMaxParentField)
	}
	return projected
}

func relationshipToModel(record runtimeRelationshipRecord) *models.Relationship {
	relationship := &models.Relationship{
		ChildObjectAPIName:  record.ChildObjectAPIName,
		ParentObjectAPIName: record.ParentObjectAPIName, FieldAPIName: record.FieldAPIName,
		RelationshipName: record.RelationshipName, RelationshipType: record.RelationshipType,
		IsSharingParent: record.IsSharingParent,
	}
	if mutation := record.Mutation; mutation != nil {
		relationship.CascadeDelete = mutation.CascadeDelete
		relationship.RestrictedDelete = mutation.RestrictedDelete
	}
	return relationship
}

func sharingRuleToModel(record runtimeSharingRuleRecord) *models.SharingRule {
	return &models.SharingRule{
		ObjectAPIName: record.ObjectAPIName,
		Criteria:      record.Criteria, AccessLevel: record.AccessLevel,
		SharedFromRoleID: clonePointer(record.SharedFromRoleID), SharedFromGroupID: clonePointer(record.SharedFromGroupID),
		ShareWithRoleID: clonePointer(record.ShareWithRoleID), ShareWithGroupID: clonePointer(record.ShareWithGroupID),
	}
}

func clonePointer[T any](source *T) *T {
	if source == nil {
		return nil
	}
	value := *source
	return &value
}

func clonePicklistOptions(source models.PicklistOptions) models.PicklistOptions {
	if source == nil {
		return nil
	}
	result := make(models.PicklistOptions, len(source))
	for i, option := range source {
		result[i] = models.PicklistOption{
			Value: option.Value,
			Label: option.Label,
			Tags:  append([]string(nil), option.Tags...),
		}
		if option.Extensions != nil {
			result[i].Extensions = make(map[string]json.RawMessage, len(option.Extensions))
			for name, value := range option.Extensions {
				result[i].Extensions[name] = append(json.RawMessage(nil), value...)
			}
		}
	}
	return result
}

func cloneStringSliceMap(source map[string][]string) map[string][]string {
	if source == nil {
		return nil
	}
	result := make(map[string][]string, len(source))
	for key, values := range source {
		result[key] = append([]string(nil), values...)
	}
	return result
}

func cloneRollupConfig(source *models.RollupConfig) *models.RollupConfig {
	if source == nil {
		return nil
	}
	result := *source
	result.Filter = clonePointer(source.Filter)
	result.ResultType = clonePointer(source.ResultType)
	result.ResultPrecision = clonePointer(source.ResultPrecision)
	result.ResultScale = clonePointer(source.ResultScale)
	return &result
}
