package packs

import (
	"context"
	"encoding/json"
	"os"
	"path/filepath"
	"strings"
	"testing"

	"github.com/nexuscrm/kernel/pkg/formula"
	"github.com/nexuscrm/shared/pkg/constants"
	"github.com/nexuscrm/shared/pkg/models"
	"github.com/pingcap-inc/nexuscrm-connectors/features/connector/capabilities"
)

type packSourceLegacyVerifier struct{}

func (packSourceLegacyVerifier) Verify(context.Context, *connectorcapabilities.VerifierInput) error {
	return nil
}

func TestValidatePackSourceAcceptsValidLocalPath(t *testing.T) {
	root := writePackFixture(t, "jira-like-sample", validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "object-spec:jira-like-sample",
      "manageability": "locked",
      "path": "objects/spec.json"
    }
  ]`, `"dependencies": [],`))
	writeFile(t, root, "objects/spec.json", `{"objects":[{"apiName":"Issue"}]}`)

	report := ValidatePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	if report.HasErrors() {
		t.Fatalf("validate valid source diagnostics:\n%s", report.Error())
	}
	if report.Source == nil || report.Source.Manifest == nil {
		t.Fatal("validate valid source did not return resolved manifest")
	}
	if got := report.Source.FileRefs; len(got) != 1 || got[0] != "objects/spec.json" {
		t.Fatalf("FileRefs = %#v, want objects/spec.json", got)
	}

	report = ValidatePackSourceWithOptions(root, testPackSourceOptions(t))
	if report.HasErrors() {
		t.Fatalf("validate bare local path source diagnostics:\n%s", report.Error())
	}
}

func TestValidatePackSourceRejectsObjectSpecRecordMutationPolicySurface(t *testing.T) {
	root := writePackFixture(t, "jira-like-sample", validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "object-spec:jira-like-sample",
      "manageability": "locked",
      "path": "objects/spec.json"
    }
  ]`, `"dependencies": [],`))
	writeFile(t, root, "objects/spec.json", `[{
    "apiName": "Issue",
    "label": "Issue",
    "tableType": "standard_object",
    "category": "jira",
    "sharingModel": "Private",
    "enableHierarchySharing": false,
    "fields": [
      {"apiName": "Subject", "label": "Subject", "type": "string", "required": true, "isNameField": true}
    ],
    "accessPolicy": {
      "recordMutation": {
        "deny": [{"surfaces": ["singleCreate"], "message": "closed"}]
      }
    }
  }]`)

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	if !report.HasErrors() {
		t.Fatal("ValidateInstallablePackSourceWithOptions accepted object_spec accessPolicy.recordMutation")
	}
	foundDiagnostic := false
	for _, diagnostic := range report.Diagnostics {
		if diagnostic.Code == "component.object_spec.access_policy_sidecar_surface" {
			foundDiagnostic = true
			break
		}
	}
	if !foundDiagnostic {
		t.Fatalf("diagnostics = %+v, want component.object_spec.access_policy_sidecar_surface", report.Diagnostics)
	}
	if got := report.Error(); !strings.Contains(got, "object_record_mutation_policy") {
		t.Fatalf("diagnostic = %s, want object_record_mutation_policy guidance", got)
	}
}

func TestValidatePackSourceRejectsObjectSpecLifecyclePolicySurface(t *testing.T) {
	root := writePackFixture(t, "jira-like-sample", validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "object-spec:jira-like-sample",
      "manageability": "locked",
      "path": "objects/spec.json"
    }
  ]`, `"dependencies": [],`))
	writeFile(t, root, "objects/spec.json", `[
  {
    "apiName": "Issue",
    "label": "Issue",
    "pluralLabel": "Issues",
    "sharingModel": "ReadWrite",
    "fields": [
      {"apiName": "Subject", "label": "Subject", "type": "string", "required": true, "isNameField": true}
    ],
    "accessPolicy": {
      "lifecycle": {
        "hooks": [{"phase": "after_create_in_tx", "capability": "jira.issue.lifecycle"}]
      }
    }
  }]`)

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	if !report.HasErrors() {
		t.Fatal("ValidateInstallablePackSourceWithOptions accepted object_spec accessPolicy.lifecycle")
	}
	foundDiagnostic := false
	for _, diagnostic := range report.Diagnostics {
		if diagnostic.Code == "component.object_spec.access_policy_sidecar_surface" {
			foundDiagnostic = true
			break
		}
	}
	if !foundDiagnostic {
		t.Fatalf("diagnostics = %+v, want component.object_spec.access_policy_sidecar_surface", report.Diagnostics)
	}
	if got := report.Error(); !strings.Contains(got, "object_lifecycle_policy") {
		t.Fatalf("diagnostic = %s, want object_lifecycle_policy guidance", got)
	}
}

func TestValidatePackSourceCanonicalizesRelativeLocalPathURI(t *testing.T) {
	parent := t.TempDir()
	root := filepath.Join(parent, "pack")
	writeManifest(t, root, validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "object-spec:jira-like-sample",
      "manageability": "locked",
      "path": "objects/spec.json"
    }
  ]`, `"dependencies": [],`))
	writeFile(t, root, "objects/spec.json", `{"objects":[{"apiName":"Issue"}]}`)

	wd, err := os.Getwd()
	if err != nil {
		t.Fatalf("getwd: %v", err)
	}
	if err := os.Chdir(parent); err != nil {
		t.Fatalf("chdir fixture parent: %v", err)
	}
	defer func() {
		if err := os.Chdir(wd); err != nil {
			t.Fatalf("restore wd: %v", err)
		}
	}()

	report := ValidatePackSourceWithOptions("local_path:pack", testPackSourceOptions(t))
	if report.HasErrors() {
		t.Fatalf("validate relative local_path diagnostics:\n%s", report.Error())
	}
	wantURI, err := filepath.EvalSymlinks(root)
	if err != nil {
		t.Fatalf("eval fixture root: %v", err)
	}
	if got := report.Source.URI; got != wantURI {
		t.Fatalf("resolved Source.URI = %q, want canonical %q", got, wantURI)
	}
}

func TestValidatePackSourceAcceptsExtensionsBlock(t *testing.T) {
	root := writePackFixture(t, "with-extensions", `{
  "manifestFormatVersion": "1",
  "name": "with-extensions",
  "displayName": "Extensions Sample",
  "category": "app-pack",
  "version": "0.1.0",
  "platformCompatibility": {"min": "0.2.0", "maxExclusive": "0.3.0"},
  "dependencies": [],
  "components": [
    {
      "kind": "object_spec",
      "businessKey": "object-spec:with-extensions",
      "manageability": "locked",
      "path": "objects/spec.json"
    }
  ],
  "extensions": {
    "salesforceApiCompatibility": "66.0",
    "buildInfo": {"git": "abcdef", "ts": 1717000000},
    "anything": ["else", true, null, 42]
  }
}`)
	writeFile(t, root, "objects/spec.json", `[{"apiName":"Issue","label":"Issue","tableType":"standard_object","category":"jira","sharingModel":"Private","enableHierarchySharing":false,"description":"Issue","fields":[{"apiName":"Subject","label":"Subject","type":"string","required":true,"isNameField":true}]}]`)

	report := ValidatePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	if report.HasErrors() {
		t.Fatalf("manifest with extensions should validate cleanly:\n%s", report.Error())
	}
}

func TestParseObjectSpecsPreservesPicklistOptionExtensions(t *testing.T) {
	specs, err := parseObjectSpecsJSON([]byte(`[
		{
			"apiName": "Issue",
			"label": "Issue",
			"tableType": "standard_object",
			"category": "jira",
			"sharingModel": "Private",
			"enableHierarchySharing": false,
			"description": "Issue",
			"fields": [
				{
					"apiName": "Priority",
					"label": "Priority",
					"type": "picklist",
					"options": [
						{"value": "High", "label": "High", "extensions": {"score": 3, "style": {"color": "red"}}}
					]
				}
			]
		}
	]`), "test")
	if err != nil {
		t.Fatalf("parseObjectSpecsJSON: %v", err)
	}
	if len(specs) != 1 || len(specs[0].Fields) != 1 || len(specs[0].Fields[0].Options) != 1 {
		t.Fatalf("parsed specs shape = %#v, want one picklist option", specs)
	}
	extensions := specs[0].Fields[0].Options[0].Extensions
	if got := string(extensions["score"]); got != "3" {
		t.Fatalf("score extension = %q, want 3", got)
	}
	var style map[string]string
	if err := json.Unmarshal(extensions["style"], &style); err != nil {
		t.Fatalf("style extension JSON: %v", err)
	}
	if got := style["color"]; got != "red" {
		t.Fatalf("style color = %q, want red", got)
	}
}

func TestValidateInstallablePackSourceRejectsInvalidPicklistOptionExtensions(t *testing.T) {
	root := writePackFixture(t, "bad-picklist-extension", validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "object-spec:bad-picklist-extension",
      "manageability": "locked",
      "path": "objects/spec.json"
    }
  ]`, `"dependencies": [],`))
	writeFile(t, root, "objects/spec.json", `[
		{
			"apiName": "Issue",
			"label": "Issue",
			"tableType": "standard_object",
			"category": "jira",
			"sharingModel": "Private",
			"enableHierarchySharing": false,
			"description": "Issue",
			"fields": [
				{
					"apiName": "Priority",
					"label": "Priority",
					"type": "picklist",
					"options": [
						{"value": "High", "label": "High", "extensions": "oops"}
					]
				}
			]
		}
	]`)

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	assertInstallableDiagnostic(t, report, "component.payload.invalid_schema")
}

func TestValidatePackSourceRejectsDuplicateJSONKeys(t *testing.T) {
	root := writePackFixture(t, "bad-pack", `{
  "manifestFormatVersion": "1",
  "name": "bad-pack",
  "name": "bad-pack-duplicate",
  "displayName": "Bad Pack",
  "category": "app-pack",
  "version": "0.1.0",
  "platformCompatibility": {"min": "0.2.0", "maxExclusive": "0.3.0"},
  "dependencies": [],
  "components": []
}`)

	report := ValidatePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	assertDiagnostic(t, report, "manifest.duplicate_key")
}

func TestValidatePackSourceRejectsDuplicateJSONKeysInExtensionlessJSONPayload(t *testing.T) {
	root := writePackFixture(t, "bad-payload", validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "object",
      "manageability": "locked",
      "path": "objects/spec"
    }
  ]`, `"dependencies": [],`))
	writeFile(t, root, "objects/spec", `{"name":"Issue","name":"Duplicate"}`)

	report := ValidatePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	assertDiagnostic(t, report, "payload.duplicate_key")
}

func TestValidatePackSourceRejectsUnknownComponentKinds(t *testing.T) {
	root := writePackFixture(t, "bad-kind", validPackManifest(`[
    {
      "kind": "kanban_view",
      "businessKey": "board",
      "manageability": "locked",
      "payload": {"name": "Board"}
    }
  ]`, `"dependencies": [],`))

	report := ValidatePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	assertDiagnostic(t, report, "component.kind.unsupported")
}

func TestValidatePackSourceRejectsUnresolvedDependsOnAndCycles(t *testing.T) {
	root := writePackFixture(t, "bad-deps", validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "object-a",
      "manageability": "locked",
      "payload": {"name": "A"},
      "dependsOn": [{"kind": "object_spec", "businessKey": "object-b"}]
    },
    {
      "kind": "object_spec",
      "businessKey": "object-b",
      "manageability": "locked",
      "payload": {"name": "B"},
      "dependsOn": [{"kind": "object_spec", "businessKey": "object-a"}]
    },
    {
      "kind": "validation_rule",
      "businessKey": "rule",
      "manageability": "locked",
      "payload": {"name": "Rule"},
      "dependsOn": [{"kind": "object_spec", "businessKey": "missing"}]
    }
  ]`, `"dependencies": [],`))

	report := ValidatePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	assertDiagnostic(t, report, "component.depends_on.unresolved")
	assertDiagnostic(t, report, "component.depends_on.cycle")
}

func TestValidatePackSourceRejectsMalformedManifestDependencies(t *testing.T) {
	root := writePackFixture(t, "bad-manifest-deps", validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "object",
      "manageability": "locked",
      "payload": {"name": "Issue"}
    }
  ]`, `"dependencies": [
    {"name": "", "versionConstraint": "0.1.0"},
    {"name": "base", "versionConstraint": "=>0.1.0"},
    {"name": "base", "versionConstraint": "0.1.0"}
  ],`))

	report := ValidatePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	assertDiagnostic(t, report, "dependency.name.missing")
	assertDiagnostic(t, report, "dependency.name.duplicate")
	assertDiagnostic(t, report, "dependency.version_constraint.invalid")
}

func TestValidatePackSourceRejectsHostRequirementsWithoutRegistrySupport(t *testing.T) {
	root := writePackFixture(t, "needs-host", validPackManifest(`[
	    {
	      "kind": "object_spec",
      "businessKey": "object",
      "manageability": "locked",
      "payload": {"name": "Issue"}
    }
  ]`, `"dependencies": [], "hostRequirements": [{"kind": "renderer", "name": "list-view"}],`))

	report := ValidatePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	assertDiagnostic(t, report, "host.unsupported")

	opts := testPackSourceOptions(t)
	opts.HostPrimitiveRegistry[hostPrimitiveKey("renderer", "list-view")] = HostPrimitive{Kind: "renderer", Name: "list-view"}
	report = ValidatePackSourceWithOptions("local_path:"+root, opts)
	if report.HasErrors() {
		t.Fatalf("validate host-supported source diagnostics:\n%s", report.Error())
	}
}

func TestValidatePackSourceRejectsProductDialectHostRequirementWithoutRegistrySupport(t *testing.T) {
	root := writePackFixture(t, "needs-product-dialect", validPackManifest(`[
	    {
	      "kind": "object_spec",
	      "businessKey": "object",
	      "manageability": "locked",
	      "payload": {"name": "Issue"}
	    }
	  ]`, `"dependencies": [], "hostRequirements": [{"kind": "product-dialect", "name": "salesforce-v63"}],`))

	report := ValidatePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	assertDiagnostic(t, report, "host.unsupported")

	opts := testPackSourceOptions(t)
	opts.HostPrimitiveRegistry[hostPrimitiveKey(HostPrimitiveKindProductDialect, "salesforce-v63")] = HostPrimitive{
		Kind: HostPrimitiveKindProductDialect,
		Name: "salesforce-v63",
	}
	report = ValidatePackSourceWithOptions("local_path:"+root, opts)
	if report.HasErrors() {
		t.Fatalf("validate product-dialect host-supported source diagnostics:\n%s", report.Error())
	}
}

func TestDefaultHostPrimitiveRegistryStartsAppBlind(t *testing.T) {
	resetDefaultHostPrimitivesForTest(t)

	if got := DefaultHostPrimitiveRegistry(); len(got) != 0 {
		t.Fatalf("DefaultHostPrimitiveRegistry() = %#v, want no app renderer facts in the L0 default", got)
	}
}

func TestRegisterDefaultHostPrimitivesAddsDistributionCapabilities(t *testing.T) {
	resetDefaultHostPrimitivesForTest(t)

	const rendererID = "app-pack:jira/action-renderer/transition"
	RegisterDefaultHostPrimitives(HostPrimitive{
		Kind: " Renderer ",
		Name: rendererID,
	})

	registry := DefaultHostPrimitiveRegistry()
	if !registry.Supports(HostPrimitiveRequirement{Kind: hostPrimitiveKindRenderer, Name: rendererID}) {
		t.Fatalf("DefaultHostPrimitiveRegistry() does not include registered renderer %q", rendererID)
	}
	if !registry.Supports(HostPrimitiveRequirement{Kind: "Renderer", Name: rendererID}) {
		t.Fatalf("DefaultHostPrimitiveRegistry() lookup is not normalized for renderer %q", rendererID)
	}
	if !registry.Supports(HostPrimitiveRequirement{Kind: "RENDERER", Name: rendererID}) {
		t.Fatalf("DefaultHostPrimitiveRegistry() upper-case lookup is not normalized for renderer %q", rendererID)
	}
	got, ok := registry[hostPrimitiveKey(hostPrimitiveKindRenderer, rendererID)]
	if !ok {
		t.Fatalf("DefaultHostPrimitiveRegistry() missing canonical registry key for renderer %q", rendererID)
	}
	if got.Kind != hostPrimitiveKindRenderer {
		t.Fatalf("registered HostPrimitive.Kind = %q, want canonical %q", got.Kind, hostPrimitiveKindRenderer)
	}
}

func TestValidatePackSourceRequiresRendererIDsDeclaredAsHostRequirements(t *testing.T) {
	const rendererID = "app-pack:jira/action-renderer/transition"
	root := writePackFixture(t, "needs-renderer-declaration", validPackManifest(`[
    {
      "kind": "ui_action",
      "businessKey": "transition-actions",
      "manageability": "defaults_only",
      "path": "actions/ui_actions.json"
    }
  ]`, `"dependencies": [],`))
	writeFile(t, root, "actions/ui_actions.json", `{
  "actions": [
    {"name": "CloseIssue", "rendererId": "`+rendererID+`"}
  ]
}`)

	opts := testPackSourceOptions(t)
	opts.HostPrimitiveRegistry[hostPrimitiveKey(hostPrimitiveKindRenderer, rendererID)] = HostPrimitive{
		Kind: hostPrimitiveKindRenderer,
		Name: rendererID,
	}
	report := ValidatePackSourceWithOptions("local_path:"+root, opts)
	assertDiagnostic(t, report, "host.renderer_id.undeclared")

	root = writePackFixture(t, "declares-renderer", validPackManifest(`[
    {
      "kind": "ui_action",
      "businessKey": "transition-actions",
      "manageability": "defaults_only",
      "path": "actions/ui_actions.json"
    }
  ]`, `"dependencies": [], "hostRequirements": [{"kind": "renderer", "name": "`+rendererID+`"}],`))
	writeFile(t, root, "actions/ui_actions.json", `{
  "actions": [
    {"name": "CloseIssue", "rendererId": "`+rendererID+`"}
  ]
}`)

	report = ValidatePackSourceWithOptions("local_path:"+root, opts)
	if report.HasErrors() {
		t.Fatalf("validate renderer-declared source diagnostics:\n%s", report.Error())
	}
}

func TestValidateInstallablePackSourceRejectsUnsupportedValidationRuleManageability(t *testing.T) {
	root := writePackFixture(t, "validation-rule-pack", validPackManifest(`[
    {
      "kind": "validation_rule",
      "businessKey": "issue-subject-required",
      "manageability": "locked",
      "payload": {"name": "Issue_Subject_Required"}
    }
  ]`, `"dependencies": [],`))

	sourceReport := ValidatePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	if sourceReport.HasErrors() {
		t.Fatalf("low-level source validation diagnostics:\n%s", sourceReport.Error())
	}
	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	assertInstallableDiagnostic(t, report, "component.manageability.unsupported_for_kind")
}

func TestValidateInstallablePackSourceRejectsUnsupportedUIActionManageability(t *testing.T) {
	root := writePackFixture(t, "ui-action-pack", validPackManifest(`[
    {
      "kind": "ui_action",
      "businessKey": "issue-actions",
      "manageability": "defaults_only",
      "payload": []
    }
  ]`, `"dependencies": [],`))

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	assertInstallableDiagnostic(t, report, "component.manageability.unsupported_for_kind")
}

// TestValidateInstallablePackSourceAcceptsObjectSpecDefaultsOnly locks in the
// L1-defaults / L2-overrides contract for object_spec at the public installable
// pack contract layer. The component-kind capability registry must list
// defaults_only as a supported manageability so a manifest declaring it gets
// past ValidateInstallablePackSource — otherwise NewSourceBackedPack accepts it
// (see TestSourceBackedPackAcceptsObjectSpecDefaultsOnly) but the public
// validate-pack/install-pack entry points block with
// `component.manageability.unsupported_for_kind` first.
func TestValidateInstallablePackSourceAcceptsObjectSpecDefaultsOnly(t *testing.T) {
	root := writePackFixture(t, "object-spec-defaults-only", validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "issue",
      "manageability": "`+string(ManageabilityDefaultsOnly)+`",
      "payload": `+testObjectSpecPayload("Issue")+`
    }
  ]`, `"dependencies": [],`))

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	if report.HasErrors() {
		var got []string
		for _, d := range report.Diagnostics {
			got = append(got, d.String())
		}
		t.Fatalf("validation should accept object_spec/defaults_only, got errors:\n%s", strings.Join(got, "\n"))
	}
}

func TestValidateInstallablePackSourceAcceptsDisplayNameDotPathAcrossObjectSpecComponents(t *testing.T) {
	root := writePackFixture(t, "display-name-cross-component", validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "account",
      "manageability": "locked",
      "path": "objects/account.json"
    },
    {
      "kind": "object_spec",
      "businessKey": "widget",
      "manageability": "locked",
      "path": "objects/widget.json",
      "dependsOn": [{"kind": "object_spec", "businessKey": "account"}]
    }
  ]`, `"dependencies": [],`))
	writeFile(t, root, "objects/account.json", testObjectSpecPayloadWithFields("Account",
		`{"apiName": "Name", "label": "Name", "type": "string", "required": true, "isNameField": true}`,
		`{"apiName": "ExternalId__c", "label": "External ID", "type": "string"}`,
	))
	writeFile(t, root, "objects/widget.json", `[
  {
    "apiName": "Widget__c",
    "label": "Widget",
    "tableType": "standard_object",
    "category": "jira",
    "sharingModel": "Private",
    "enableHierarchySharing": false,
    "description": "Widget work item",
    "displayNameField": "Account.ExternalId__c",
    "fields": [
      {"apiName": "Name", "label": "Name", "type": "string", "required": true, "isNameField": true},
      {"apiName": "AccountId", "label": "Account", "type": "reference", "referenceTo": ["Account"], "relationshipName": "Account"}
    ]
  }
]`)

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	if report.HasErrors() {
		t.Fatalf("validation rejected cross-component displayNameField dot path; want acceptance:\n%s", report.Error())
	}
}

func TestValidateInstallablePackSourceRejectsDuplicateChildRelationshipNamesAcrossObjectSpecs(t *testing.T) {
	root := writeChildRelationshipNamePackFixture(t, "child-relationship-name-duplicate",
		`, "childRelationshipName": "Children"`,
		`, "childRelationshipName": "children"`,
	)

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	assertInstallableDiagnostic(t, report, "component.object_spec.child_relationship_name_duplicate")
	got := report.Error()
	for _, want := range []string{"ChildA__c.Parent__c", "ChildB__c.Parent__c", "duplicate childRelationshipName"} {
		if !strings.Contains(got, want) {
			t.Fatalf("diagnostic = %s, want %q", got, want)
		}
	}
}

func TestValidateInstallablePackSourceRejectsDuplicateLookupChildRelationshipNamesAcrossObjectSpecs(t *testing.T) {
	root := writeChildRelationshipNamePackFixtureWithFieldType(t, "child-relationship-name-lookup-duplicate", "lookup",
		`, "childRelationshipName": "Children"`,
		`, "childRelationshipName": "children"`,
	)

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	assertInstallableDiagnostic(t, report, "component.object_spec.child_relationship_name_duplicate")
	got := report.Error()
	for _, want := range []string{"ChildA__c.Parent__c", "ChildB__c.Parent__c", "duplicate childRelationshipName"} {
		if !strings.Contains(got, want) {
			t.Fatalf("diagnostic = %s, want %q", got, want)
		}
	}
}

func TestValidateInstallablePackSourceAllowsMissingChildRelationshipNameDuringPartialCutover(t *testing.T) {
	root := writeChildRelationshipNamePackFixture(t, "child-relationship-name-partial-cutover", "", "")

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	if report.HasErrors() {
		t.Fatalf("validation rejected missing childRelationshipName before F7 cutover:\n%s", report.Error())
	}
}

func TestValidateInstallablePackSourceRejectsInvalidChildRelationshipName(t *testing.T) {
	for _, name := range []string{"Bad Name", "123Children", "Children-Rel", "Select", "Using", "First", "Last", "Nulls", "Min", " Contacts "} {
		t.Run(name, func(t *testing.T) {
			root := writeChildRelationshipNamePackFixture(t, "child-relationship-name-invalid",
				`, "childRelationshipName": "`+name+`"`,
				"",
			)

			report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
			assertInstallableDiagnostic(t, report, "component.object_spec.child_relationship_name_invalid")
		})
	}
}

func TestValidateInstallablePackSourceRejectsChildRelationshipNameParentFieldCollision(t *testing.T) {
	root := writeChildRelationshipNamePackFixture(t, "child-relationship-name-parent-field-collision",
		`, "childRelationshipName": "Name"`,
		"",
	)

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	assertInstallableDiagnostic(t, report, "component.object_spec.child_relationship_name_invalid")
	for _, want := range []string{"ChildA__c.Parent__c", "Parent__c.Name"} {
		if !strings.Contains(report.Error(), want) {
			t.Fatalf("diagnostic = %s, want %q", report.Error(), want)
		}
	}
}

func TestResolveInstalledSourceBackedPackRejectsDuplicateChildRelationshipNames(t *testing.T) {
	root := writeChildRelationshipNamePackFixture(t, "child-relationship-name-construction-duplicate",
		`, "childRelationshipName": "Children"`,
		`, "childRelationshipName": "children"`,
	)

	_, err := ResolveInstalledSourceBackedPack("jira-like-sample", AppPack, PackSourceKindLocalPath, root)
	if err == nil {
		t.Fatal("ResolveInstalledSourceBackedPack accepted duplicate childRelationshipName declarations")
	}
	for _, want := range []string{"component.object_spec.child_relationship_name_duplicate", "ChildA__c.Parent__c", "ChildB__c.Parent__c"} {
		if !strings.Contains(err.Error(), want) {
			t.Fatalf("err = %v, want %q", err, want)
		}
	}
}

func TestResolveInstalledSourceBackedPackRejectsDuplicateLookupChildRelationshipNames(t *testing.T) {
	root := writeChildRelationshipNamePackFixtureWithFieldType(t, "child-relationship-name-lookup-construction-duplicate", "lookup",
		`, "childRelationshipName": "Children"`,
		`, "childRelationshipName": "children"`,
	)

	_, err := ResolveInstalledSourceBackedPack("jira-like-sample", AppPack, PackSourceKindLocalPath, root)
	if err == nil {
		t.Fatal("ResolveInstalledSourceBackedPack accepted duplicate lookup childRelationshipName declarations")
	}
	for _, want := range []string{"component.object_spec.child_relationship_name_duplicate", "ChildA__c.Parent__c", "ChildB__c.Parent__c"} {
		if !strings.Contains(err.Error(), want) {
			t.Fatalf("err = %v, want %q", err, want)
		}
	}
}

func TestResolveInstalledSourceBackedPackRejectsInvalidChildRelationshipName(t *testing.T) {
	for _, tc := range []struct {
		name string
		want string
	}{
		{name: "Bad Name", want: "must start with an ASCII letter"},
		{name: " Contacts ", want: "leading or trailing whitespace"},
		{name: "Using", want: "SOQL reserved word"},
		{name: "First", want: "SOQL reserved word"},
		{name: "Last", want: "SOQL reserved word"},
		{name: "Nulls", want: "SOQL reserved word"},
	} {
		t.Run(tc.name, func(t *testing.T) {
			root := writeChildRelationshipNamePackFixture(t, "child-relationship-name-construction-invalid",
				`, "childRelationshipName": "`+tc.name+`"`,
				"",
			)

			_, err := ResolveInstalledSourceBackedPack("jira-like-sample", AppPack, PackSourceKindLocalPath, root)
			if err == nil {
				t.Fatal("ResolveInstalledSourceBackedPack accepted invalid childRelationshipName declaration")
			}
			for _, want := range []string{"component.object_spec.child_relationship_name_invalid", tc.name, tc.want} {
				if !strings.Contains(err.Error(), want) {
					t.Fatalf("err = %v, want %q", err, want)
				}
			}
		})
	}
}

func TestValidateInstallablePackSourceRejectsDuplicateExclusiveSiblingFieldsAcrossObjectSpecComponents(t *testing.T) {
	root := writePackFixture(t, "exclusive-sibling-cross-component-duplicate", validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "objects-a",
      "manageability": "locked",
      "path": "objects/a.json"
    },
    {
      "kind": "object_spec",
      "businessKey": "objects-b",
      "manageability": "locked",
      "path": "objects/b.json"
    }
  ]`, `"dependencies": [],`))
	writeFile(t, root, "objects/a.json", `[
  {
    "apiName": "Parent__c",
    "label": "Parent",
    "tableType": "custom_object",
    "category": "jira",
    "sharingModel": "Private",
    "enableHierarchySharing": false,
    "description": "Parent object",
    "fields": [
      {"apiName": "Name", "label": "Name", "type": "string", "required": true, "isNameField": true}
    ]
  },
  {
    "apiName": "Child__c",
    "label": "Child",
    "tableType": "custom_object",
    "category": "jira",
    "sharingModel": "Private",
    "enableHierarchySharing": false,
    "description": "Child object",
    "exclusiveSiblingFields": [
      {"fieldApiName": "IsDefault__c", "partitionFieldApiName": "Parent__c"}
    ],
    "fields": [
      {"apiName": "Name", "label": "Name", "type": "string", "required": true, "isNameField": true},
      {"apiName": "IsDefault__c", "label": "Default", "type": "boolean", "createable": true, "updateable": true},
      {"apiName": "Parent__c", "label": "Parent", "type": "reference", "referenceTo": ["Parent__c"], "createable": true, "updateable": true}
    ]
  }
]`)
	writeFile(t, root, "objects/b.json", `[
  {
    "apiName": "Child__c",
    "label": "Child",
    "tableType": "custom_object",
    "category": "jira",
    "sharingModel": "Private",
    "enableHierarchySharing": false,
    "description": "Child object",
    "exclusiveSiblingFields": [
      {"fieldApiName": "isdefault__c", "partitionFieldApiName": "parent__c"}
    ],
    "fields": [
      {"apiName": "Name", "label": "Name", "type": "string", "required": true, "isNameField": true},
      {"apiName": "IsDefault__c", "label": "Default", "type": "boolean", "createable": true, "updateable": true},
      {"apiName": "Parent__c", "label": "Parent", "type": "reference", "referenceTo": ["Parent__c"], "createable": true, "updateable": true}
    ]
  }
]`)

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	if !report.HasErrors() {
		t.Fatal("ValidateInstallablePackSourceWithOptions accepted duplicate exclusiveSiblingFields across object_spec components")
	}
	foundDiagnostic := false
	for _, diagnostic := range report.Diagnostics {
		if diagnostic.Code == "component.object_spec.duplicate_exclusive_sibling_fields" {
			foundDiagnostic = true
			break
		}
	}
	if !foundDiagnostic {
		t.Fatalf("diagnostics = %+v, want component.object_spec.duplicate_exclusive_sibling_fields", report.Diagnostics)
	}
	got := report.Error()
	for _, want := range []string{"objects-a", "objects-b", "fieldApiName", "partitionFieldApiName"} {
		if !strings.Contains(got, want) {
			t.Fatalf("diagnostic = %s, want %q", got, want)
		}
	}
}

func writeChildRelationshipNamePackFixture(t *testing.T, dirname, childAFieldSuffix, childBFieldSuffix string) string {
	t.Helper()
	return writeChildRelationshipNamePackFixtureWithFieldType(t, dirname, "reference", childAFieldSuffix, childBFieldSuffix)
}

func writeChildRelationshipNamePackFixtureWithFieldType(t *testing.T, dirname, fieldType, childAFieldSuffix, childBFieldSuffix string) string {
	t.Helper()
	root := writePackFixture(t, dirname, validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "objects-a",
      "manageability": "locked",
      "path": "objects/a.json"
    },
    {
      "kind": "object_spec",
      "businessKey": "objects-b",
      "manageability": "locked",
      "path": "objects/b.json"
    }
  ]`, `"dependencies": [],`))
	writeFile(t, root, "objects/a.json", `[
  {
    "apiName": "Parent__c",
    "label": "Parent",
    "tableType": "custom_object",
    "category": "jira",
    "sharingModel": "Private",
    "enableHierarchySharing": false,
    "description": "Parent object",
    "fields": [
      {"apiName": "Name", "label": "Name", "type": "string", "required": true, "isNameField": true}
    ]
  },
  {
    "apiName": "ChildA__c",
    "label": "Child A",
    "tableType": "custom_object",
    "category": "jira",
    "sharingModel": "Private",
    "enableHierarchySharing": false,
    "description": "Child A",
    "fields": [
      {"apiName": "Name", "label": "Name", "type": "string", "required": true, "isNameField": true},
      {"apiName": "Parent__c", "label": "Parent", "type": "`+fieldType+`", "referenceTo": ["Parent__c"], "relationshipName": "Parent"`+childAFieldSuffix+`}
    ]
  }
]`)
	writeFile(t, root, "objects/b.json", `[
  {
    "apiName": "ChildB__c",
    "label": "Child B",
    "tableType": "custom_object",
    "category": "jira",
    "sharingModel": "Private",
    "enableHierarchySharing": false,
    "description": "Child B",
    "fields": [
      {"apiName": "Name", "label": "Name", "type": "string", "required": true, "isNameField": true},
      {"apiName": "Parent__c", "label": "Parent", "type": "`+fieldType+`", "referenceTo": ["Parent__c"], "relationshipName": "Parent"`+childBFieldSuffix+`}
    ]
  }
]`)
	return root
}

func TestValidateInstallablePackSourceRejectsExclusiveSiblingFieldsOnSplitObjectSpec(t *testing.T) {
	root := writePackFixture(t, "exclusive-sibling-split-object", validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "objects-a",
      "manageability": "locked",
      "path": "objects/a.json"
    },
    {
      "kind": "object_spec",
      "businessKey": "objects-b",
      "manageability": "locked",
      "path": "objects/b.json"
    }
  ]`, `"dependencies": [],`))
	writeFile(t, root, "objects/a.json", `[
  {
    "apiName": "Parent__c",
    "label": "Parent",
    "tableType": "custom_object",
    "category": "jira",
    "sharingModel": "Private",
    "enableHierarchySharing": false,
    "description": "Parent object",
    "fields": [
      {"apiName": "Name", "label": "Name", "type": "string", "required": true, "isNameField": true}
    ]
  },
  {
    "apiName": "Child__c",
    "label": "Child",
    "tableType": "custom_object",
    "category": "jira",
    "sharingModel": "Private",
    "enableHierarchySharing": false,
    "description": "Child object",
    "exclusiveSiblingFields": [
      {"fieldApiName": "IsDefault__c", "partitionFieldApiName": "Parent__c"}
    ],
    "fields": [
      {"apiName": "Name", "label": "Name", "type": "string", "required": true, "isNameField": true}
    ]
  }
]`)
	writeFile(t, root, "objects/b.json", `[
  {
    "apiName": "Child__c",
    "label": "Child",
    "tableType": "custom_object",
    "category": "jira",
    "sharingModel": "Private",
    "enableHierarchySharing": false,
    "description": "Child object fields",
    "fields": [
      {"apiName": "IsDefault__c", "label": "Default", "type": "boolean", "createable": true, "updateable": true},
      {"apiName": "Parent__c", "label": "Parent", "type": "reference", "referenceTo": ["Parent__c"], "createable": true, "updateable": true}
    ]
  }
]`)

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	if !report.HasErrors() {
		t.Fatal("ValidateInstallablePackSourceWithOptions accepted ExclusiveSiblingFields on split object_spec authoring")
	}
	foundDiagnostic := false
	for _, diagnostic := range report.Diagnostics {
		if diagnostic.Code == "component.object_spec.exclusive_sibling_fields_split_object" {
			foundDiagnostic = true
			break
		}
	}
	if !foundDiagnostic {
		t.Fatalf("diagnostics = %+v, want component.object_spec.exclusive_sibling_fields_split_object", report.Diagnostics)
	}
	got := report.Error()
	for _, want := range []string{"Child__c", "objects-a", "objects-b", "one object_spec authoring surface"} {
		if !strings.Contains(got, want) {
			t.Fatalf("diagnostic = %s, want %q", got, want)
		}
	}
}

func TestValidateInstallablePackSourceAcceptsDisplayNameDotPathFromDependency(t *testing.T) {
	opts := testPackSourceOptions(t)
	writeManifest(t, filepath.Join(opts.OfficialRepoRoot, "base-crm"), strings.Replace(validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "account",
      "manageability": "locked",
      "path": "objects/account.json"
    }
  ]`, `"dependencies": [],`), `"name": "jira-like-sample"`, `"name": "base-crm"`, 1))
	writeFile(t, filepath.Join(opts.OfficialRepoRoot, "base-crm"), "objects/account.json", testObjectSpecPayloadWithFields("Account",
		`{"apiName": "Name", "label": "Name", "type": "string", "required": true, "isNameField": true}`,
		`{"apiName": "ExternalId__c", "label": "External ID", "type": "string"}`,
	))
	root := writePackFixture(t, "display-name-dependency", validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "widget",
      "manageability": "locked",
      "path": "objects/widget.json"
    }
  ]`, `"dependencies": [{"name": "base-crm"}],`))
	writeFile(t, root, "objects/widget.json", `[
  {
    "apiName": "Widget__c",
    "label": "Widget",
    "tableType": "standard_object",
    "category": "jira",
    "sharingModel": "Private",
    "enableHierarchySharing": false,
    "description": "Widget work item",
    "displayNameField": "Account.ExternalId__c",
    "fields": [
      {"apiName": "Name", "label": "Name", "type": "string", "required": true, "isNameField": true},
      {"apiName": "AccountId", "label": "Account", "type": "reference", "referenceTo": ["Account"], "relationshipName": "Account"}
    ]
  }
]`)

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, opts)
	if report.HasErrors() {
		t.Fatalf("validation rejected dependency-backed displayNameField dot path; want acceptance:\n%s", report.Error())
	}
	if report.Pack == nil {
		t.Fatal("validation did not construct installable pack")
	}
}

func TestValidateInstallablePackSourceRejectsDependencyHostDiagnosticsAfterUsingDependencyObjectSchema(t *testing.T) {
	opts := testPackSourceOptions(t)
	writeManifest(t, filepath.Join(opts.OfficialRepoRoot, "base-crm"), strings.Replace(validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "crm",
      "manageability": "locked",
      "path": "objects/crm.json"
    }
  ]`, `"dependencies": [], "hostRequirements": [{"kind": "renderer", "name": "unsupported-renderer"}],`), `"name": "jira-like-sample"`, `"name": "base-crm"`, 1))
	writeFile(t, filepath.Join(opts.OfficialRepoRoot, "base-crm"), "objects/crm.json", `[
  {
    "apiName": "Account",
    "label": "Account",
    "tableType": "standard_object",
    "category": "crm",
    "sharingModel": "Private",
    "enableHierarchySharing": false,
    "description": "Account",
    "fields": [
      {"apiName": "Name", "label": "Name", "type": "string", "required": true, "isNameField": true},
      {"apiName": "RemoteCompanyId__c", "label": "Remote Company ID", "type": "string"}
    ]
  },
  {
    "apiName": "Opportunity",
    "label": "Opportunity",
    "tableType": "standard_object",
    "category": "crm",
    "sharingModel": "Private",
    "enableHierarchySharing": false,
    "description": "Opportunity",
    "fields": [
      {"apiName": "Name", "label": "Name", "type": "string", "required": true, "isNameField": true},
      {"apiName": "AccountId", "label": "Account", "type": "reference", "referenceTo": ["Account"]},
      {"apiName": "RemoteDealId__c", "label": "Remote Deal ID", "type": "string"}
    ]
  }
]`)

	root := writePackFixture(t, "connector-association-host-diagnostics", validPackManifest(`[
    {"kind":"standard_flow","businessKey":"Opportunity_To_Remote","manageability":"defaults_only","payload":{"start":{"object":"Opportunity"},"actionCalls":[{"name":"PushOpportunity","actionType":"PushToConnector"}]}},
    {"kind":"standard_flow","businessKey":"Account_To_Remote","manageability":"defaults_only","payload":{"start":{"object":"Account"},"actionCalls":[{"name":"PushAccount","actionType":"PushToConnector"}]}},
    {"kind":"connector_field_mapping","businessKey":"jira-like-sample/push-mappings","manageability":"locked","payload":[
      {"sourceObject":"Opportunity","targetObject":"remoteDeal","actionType":"PushToConnector","direction":"outbound","mappings":[{"sourceField":"Name","targetField":"dealname"}]},
      {"sourceObject":"Account","targetObject":"remoteCompany","actionType":"PushToConnector","direction":"outbound","mappings":[{"sourceField":"Name","targetField":"name"}]}
    ]},
    {"kind":"connector_push_contract","businessKey":"jira-like-sample/Account_To_Remote/PushAccount/Account/remote-company","manageability":"locked","payload":{
      "flowDeveloperName":"Account_To_Remote",
      "flowActionName":"PushAccount",
      "slotLineageId":"account-remote-sync",
      "sourceObject":"Account",
      "destinationSlotId":"remote-company",
      "profileOwnerPack":"hubspot-connector",
      "profileName":"default",
      "targetObject":"remoteCompany",
      "createPathTemplate":"/crm/v3/objects/companies",
      "updatePathTemplate":"/crm/v3/objects/companies/{remoteId}",
      "responseIdPath":"id",
      "remoteIdField":"RemoteCompanyId__c"
    }},
    {"kind":"connector_push_contract","businessKey":"jira-like-sample/Opportunity_To_Remote/PushOpportunity/Opportunity/remote-deal","manageability":"locked","payload":{
      "flowDeveloperName":"Opportunity_To_Remote",
      "flowActionName":"PushOpportunity",
      "slotLineageId":"opportunity-remote-sync",
      "sourceObject":"Opportunity",
      "destinationSlotId":"remote-deal",
      "profileOwnerPack":"hubspot-connector",
      "profileName":"default",
      "targetObject":"remoteDeal",
      "createPathTemplate":"/crm/v3/objects/deals",
      "updatePathTemplate":"/crm/v3/objects/deals/{remoteId}",
      "responseIdPath":"id",
      "remoteIdField":"RemoteDealId__c",
      "associations":[{
        "sourceLookupField":"AccountId",
        "sourceObject":"Account",
        "remoteIdField":"RemoteCompanyId__c",
        "targetActionSlotId":"account-remote-sync",
        "targetDestinationSlotId":"remote-company",
        "targetObject":"remoteCompany",
        "payloadField":"associations",
        "payloadMergeMode":"append",
        "inlinePhases":["create"],
        "payloadTemplate":{"to":{"id":"{toId}"}}
      }]
    }}
  ]`, `"dependencies": [{"name": "base-crm"}],`))

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, opts)
	if !report.HasErrors() {
		t.Fatal("validation accepted pack with dependency host diagnostics; want fail-closed diagnostic")
	}
	assertInstallableDiagnostic(t, report, "host.unsupported")
	if strings.Contains(report.Error(), "sourceLookupField") {
		t.Fatalf("validation did not use dependency object schema before failing on dependency diagnostics:\n%s", report.Error())
	}
}

func TestInstalledRowCompatSkipsCurrentDependencyHostDiagnostics(t *testing.T) {
	opts := testPackSourceOptions(t)
	writeManifest(t, filepath.Join(opts.OfficialRepoRoot, "base-crm"), strings.Replace(validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "crm",
      "manageability": "locked",
      "path": "objects/crm.json"
    }
  ]`, `"dependencies": [], "hostRequirements": [{"kind": "renderer", "name": "unsupported-renderer"}],`), `"name": "jira-like-sample"`, `"name": "base-crm"`, 1))
	writeFile(t, filepath.Join(opts.OfficialRepoRoot, "base-crm"), "objects/crm.json", `[
  {
    "apiName": "Account",
    "label": "Account",
    "tableType": "standard_object",
    "category": "crm",
    "sharingModel": "Private",
    "enableHierarchySharing": false,
    "description": "Account",
    "fields": [
      {"apiName": "Name", "label": "Name", "type": "string", "required": true, "isNameField": true},
      {"apiName": "RemoteCompanyId__c", "label": "Remote Company ID", "type": "string"}
    ]
  },
  {
    "apiName": "Opportunity",
    "label": "Opportunity",
    "tableType": "standard_object",
    "category": "crm",
    "sharingModel": "Private",
    "enableHierarchySharing": false,
    "description": "Opportunity",
    "fields": [
      {"apiName": "Name", "label": "Name", "type": "string", "required": true, "isNameField": true},
      {"apiName": "AccountId", "label": "Account", "type": "reference", "referenceTo": ["Account"]},
      {"apiName": "RemoteDealId__c", "label": "Remote Deal ID", "type": "string"}
    ]
  }
]`)

	root := writePackFixture(t, "installed-row-dependency-host-diagnostics", validPackManifest(`[
    {"kind":"standard_flow","businessKey":"Opportunity_To_Remote","manageability":"defaults_only","payload":{"start":{"object":"Opportunity"},"actionCalls":[{"name":"PushOpportunity","actionType":"PushToConnector"}]}},
    {"kind":"standard_flow","businessKey":"Account_To_Remote","manageability":"defaults_only","payload":{"start":{"object":"Account"},"actionCalls":[{"name":"PushAccount","actionType":"PushToConnector"}]}},
    {"kind":"connector_field_mapping","businessKey":"jira-like-sample/push-mappings","manageability":"locked","payload":[
      {"sourceObject":"Opportunity","targetObject":"remoteDeal","actionType":"PushToConnector","direction":"outbound","mappings":[{"sourceField":"Name","targetField":"dealname"}]},
      {"sourceObject":"Account","targetObject":"remoteCompany","actionType":"PushToConnector","direction":"outbound","mappings":[{"sourceField":"Name","targetField":"name"}]}
    ]},
    {"kind":"connector_push_contract","businessKey":"jira-like-sample/Account_To_Remote/PushAccount/Account/remote-company","manageability":"locked","payload":{
      "flowDeveloperName":"Account_To_Remote",
      "flowActionName":"PushAccount",
      "slotLineageId":"account-remote-sync",
      "sourceObject":"Account",
      "destinationSlotId":"remote-company",
      "profileOwnerPack":"hubspot-connector",
      "profileName":"default",
      "targetObject":"remoteCompany",
      "createPathTemplate":"/crm/v3/objects/companies",
      "updatePathTemplate":"/crm/v3/objects/companies/{remoteId}",
      "responseIdPath":"id",
      "remoteIdField":"RemoteCompanyId__c"
    }},
    {"kind":"connector_push_contract","businessKey":"jira-like-sample/Opportunity_To_Remote/PushOpportunity/Opportunity/remote-deal","manageability":"locked","payload":{
      "flowDeveloperName":"Opportunity_To_Remote",
      "flowActionName":"PushOpportunity",
      "slotLineageId":"opportunity-remote-sync",
      "sourceObject":"Opportunity",
      "destinationSlotId":"remote-deal",
      "profileOwnerPack":"hubspot-connector",
      "profileName":"default",
      "targetObject":"remoteDeal",
      "createPathTemplate":"/crm/v3/objects/deals",
      "updatePathTemplate":"/crm/v3/objects/deals/{remoteId}",
      "responseIdPath":"id",
      "remoteIdField":"RemoteDealId__c",
      "associations":[{
        "sourceLookupField":"AccountId",
        "sourceObject":"Account",
        "remoteIdField":"RemoteCompanyId__c",
        "targetActionSlotId":"account-remote-sync",
        "targetDestinationSlotId":"remote-company",
        "targetObject":"remoteCompany",
        "payloadField":"associations",
        "payloadMergeMode":"append",
        "inlinePhases":["create"],
        "payloadTemplate":{"to":{"id":"{toId}"}}
      }]
    }}
  ]`, `"dependencies": [{"name": "base-crm"}],`))

	freshReport := ValidateInstallablePackSourceWithOptions("local_path:"+root, opts)
	if !freshReport.HasErrors() {
		t.Fatal("fresh validation accepted pack with dependency host diagnostics; want fail-closed diagnostic")
	}
	assertInstallableDiagnostic(t, freshReport, "host.unsupported")

	installedPack, err := ResolveInstalledSourceBackedPackForInstalledRowAtSourceRevisionWithPackSourceOptions(
		"jira-like-sample",
		AppPack,
		SupportedManifestFormatVersion,
		PackSourceKindLocalPath,
		root,
		"",
		opts,
	)
	if err != nil {
		t.Fatalf("installed-row compat propagated current dependency host diagnostics; want existing installed pack to resolve: %v", err)
	}
	if installedPack == nil {
		t.Fatal("installed-row compat did not construct installable pack")
	}
}

func TestValidateInstallablePackSourceRejectsConnectorPushAssociationLookupFromDependencyLiveSchemaOnly(t *testing.T) {
	opts := testPackSourceOptions(t)
	opts.ObjectSchemaResolver = func(apiName string) *models.ObjectMetadata {
		if strings.TrimSpace(apiName) != "Opportunity" {
			return nil
		}
		ownerPack := "base-crm"
		return &models.ObjectMetadata{
			APIName: "Opportunity",
			Fields: []models.FieldMetadata{{
				APIName:     "AccountId",
				Type:        constants.FieldTypeReference,
				ReferenceTo: []string{"Account"},
				Createable:  true,
				Updateable:  true,
				OwnerKind:   constants.FieldOwnerKindPack,
				OwnerPack:   &ownerPack,
			}},
		}
	}
	writeManifest(t, filepath.Join(opts.OfficialRepoRoot, "base-crm"), strings.Replace(validPackManifest(`[
	    {
	      "kind": "object_spec",
      "businessKey": "crm",
      "manageability": "locked",
      "path": "objects/crm.json"
    }
  ]`, `"dependencies": [],`), `"name": "jira-like-sample"`, `"name": "base-crm"`, 1))
	writeFile(t, filepath.Join(opts.OfficialRepoRoot, "base-crm"), "objects/crm.json", `[
  {
    "apiName": "Account",
    "label": "Account",
    "tableType": "standard_object",
    "category": "crm",
    "sharingModel": "Private",
    "enableHierarchySharing": false,
    "description": "Account",
    "fields": [
      {"apiName": "Name", "label": "Name", "type": "string", "required": true, "isNameField": true},
      {"apiName": "RemoteCompanyId__c", "label": "Remote Company ID", "type": "string"}
    ]
  },
  {
    "apiName": "Opportunity",
    "label": "Opportunity",
    "tableType": "standard_object",
    "category": "crm",
    "sharingModel": "Private",
    "enableHierarchySharing": false,
	    "description": "Opportunity",
	    "fields": [
	      {"apiName": "Name", "label": "Name", "type": "string", "required": true, "isNameField": true},
	      {"apiName": "RemoteDealId__c", "label": "Remote Deal ID", "type": "string"}
	    ]
	  }
]`)
	opportunityFlow := `{"start":{"object":"Opportunity"},"actionCalls":[{"name":"PushOpportunity","actionType":"PushToConnector"}]}`
	accountFlow := `{"start":{"object":"Account"},"actionCalls":[{"name":"PushAccount","actionType":"PushToConnector"}]}`
	mappings := `[
  {"sourceObject":"Opportunity","targetObject":"remoteDeal","actionType":"PushToConnector","direction":"outbound","mappings":[{"sourceField":"Name","targetField":"dealname"}]},
  {"sourceObject":"Account","targetObject":"remoteCompany","actionType":"PushToConnector","direction":"outbound","mappings":[{"sourceField":"Name","targetField":"name"}]}
]`
	accountContract := `{
  "flowDeveloperName":"Account_To_Remote",
  "flowActionName":"PushAccount",
  "slotLineageId":"account-remote-sync",
  "sourceObject":"Account",
  "destinationSlotId":"remote-company",
  "profileOwnerPack":"hubspot-connector",
  "profileName":"default",
  "targetObject":"remoteCompany",
  "createPathTemplate":"/crm/v3/objects/companies",
  "updatePathTemplate":"/crm/v3/objects/companies/{remoteId}",
  "responseIdPath":"id",
  "remoteIdField":"RemoteCompanyId__c"
}`
	opportunityContract := `{
  "flowDeveloperName":"Opportunity_To_Remote",
  "flowActionName":"PushOpportunity",
  "slotLineageId":"opportunity-remote-sync",
  "sourceObject":"Opportunity",
  "destinationSlotId":"remote-deal",
  "profileOwnerPack":"hubspot-connector",
  "profileName":"default",
  "targetObject":"remoteDeal",
  "createPathTemplate":"/crm/v3/objects/deals",
  "updatePathTemplate":"/crm/v3/objects/deals/{remoteId}",
  "responseIdPath":"id",
  "remoteIdField":"RemoteDealId__c",
  "associations":[{
    "sourceLookupField":"AccountId",
    "sourceObject":"Account",
    "remoteIdField":"RemoteCompanyId__c",
    "targetActionSlotId":"account-remote-sync",
    "targetDestinationSlotId":"remote-company",
    "targetObject":"remoteCompany",
    "payloadField":"associations",
    "payloadMergeMode":"append",
    "inlinePhases":["create"],
    "payloadTemplate":{"to":{"id":"{toId}"}}
  }]
}`
	root := writePackFixture(t, "connector-companion", validPackManifest(`[
    {"kind":"standard_flow","businessKey":"Opportunity_To_Remote","manageability":"defaults_only","payload":`+jsonRawMessage(opportunityFlow)+`},
    {"kind":"standard_flow","businessKey":"Account_To_Remote","manageability":"defaults_only","payload":`+jsonRawMessage(accountFlow)+`},
    {"kind":"connector_field_mapping","businessKey":"jira-like-sample/push-mappings","manageability":"locked","payload":`+jsonRawMessage(mappings)+`},
    {"kind":"connector_push_contract","businessKey":"jira-like-sample/Account_To_Remote/PushAccount/Account/remote-company","manageability":"locked","payload":`+jsonRawMessage(accountContract)+`},
    {"kind":"connector_push_contract","businessKey":"jira-like-sample/Opportunity_To_Remote/PushOpportunity/Opportunity/remote-deal","manageability":"locked","payload":`+jsonRawMessage(opportunityContract)+`}
  ]`, `"dependencies": [{"name": "base-crm"}],`))

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, opts)
	if !report.HasErrors() {
		t.Fatal("validation accepted connector_push association lookup from dependency-owned live schema only; want fail-closed diagnostic")
	}
	if !strings.Contains(report.Error(), "sourceLookupField") {
		t.Fatalf("expected sourceLookupField schema diagnostic, got:\n%s", report.Error())
	}
}

func TestValidateInstallablePackSourceRejectsConnectorPushAssociationLookupFromUndeclaredLiveSchema(t *testing.T) {
	unrelatedOwnerPack := "unrelated-crm-pack"
	cases := []struct {
		name      string
		liveField models.FieldMetadata
	}{
		{
			name: "unrelated pack-owned field",
			liveField: models.FieldMetadata{
				APIName:     "AccountId",
				Type:        constants.FieldTypeReference,
				ReferenceTo: []string{"Account"},
				Createable:  true,
				Updateable:  true,
				OwnerKind:   constants.FieldOwnerKindPack,
				OwnerPack:   &unrelatedOwnerPack,
			},
		},
		{
			name: "admin-owned field",
			liveField: models.FieldMetadata{
				APIName:     "AccountId",
				Type:        constants.FieldTypeReference,
				ReferenceTo: []string{"Account"},
				Createable:  true,
				Updateable:  true,
				OwnerKind:   constants.FieldOwnerKindAdmin,
			},
		},
	}
	for _, tc := range cases {
		tc := tc
		t.Run(tc.name, func(t *testing.T) {
			opts := testPackSourceOptions(t)
			opts.ObjectSchemaResolver = func(apiName string) *models.ObjectMetadata {
				switch strings.TrimSpace(apiName) {
				case "Opportunity":
					return &models.ObjectMetadata{
						APIName: "Opportunity",
						Fields:  []models.FieldMetadata{tc.liveField},
					}
				default:
					return nil
				}
			}
			opportunityFlow := `{"start":{"object":"Opportunity"},"actionCalls":[{"name":"PushOpportunity","actionType":"PushToConnector"}]}`
			accountFlow := `{"start":{"object":"Account"},"actionCalls":[{"name":"PushAccount","actionType":"PushToConnector"}]}`
			mappings := `[
  {"sourceObject":"Opportunity","targetObject":"remoteDeal","actionType":"PushToConnector","direction":"outbound","mappings":[{"sourceField":"Name","targetField":"dealname"}]},
  {"sourceObject":"Account","targetObject":"remoteCompany","actionType":"PushToConnector","direction":"outbound","mappings":[{"sourceField":"Name","targetField":"name"}]}
]`
			accountContract := `{
  "flowDeveloperName":"Account_To_Remote",
  "flowActionName":"PushAccount",
  "slotLineageId":"account-remote-sync",
  "sourceObject":"Account",
  "destinationSlotId":"remote-company",
  "profileOwnerPack":"hubspot-connector",
  "profileName":"default",
  "targetObject":"remoteCompany",
  "createPathTemplate":"/crm/v3/objects/companies",
  "updatePathTemplate":"/crm/v3/objects/companies/{remoteId}",
  "responseIdPath":"id",
  "remoteIdField":"RemoteCompanyId__c"
}`
			opportunityContract := `{
  "flowDeveloperName":"Opportunity_To_Remote",
  "flowActionName":"PushOpportunity",
  "slotLineageId":"opportunity-remote-sync",
  "sourceObject":"Opportunity",
  "destinationSlotId":"remote-deal",
  "profileOwnerPack":"hubspot-connector",
  "profileName":"default",
  "targetObject":"remoteDeal",
  "createPathTemplate":"/crm/v3/objects/deals",
  "updatePathTemplate":"/crm/v3/objects/deals/{remoteId}",
  "responseIdPath":"id",
  "remoteIdField":"RemoteDealId__c",
  "associations":[{
    "sourceLookupField":"AccountId",
    "sourceObject":"Account",
    "remoteIdField":"RemoteCompanyId__c",
    "targetActionSlotId":"account-remote-sync",
    "targetDestinationSlotId":"remote-company",
    "targetObject":"remoteCompany",
    "payloadField":"associations",
    "payloadMergeMode":"append",
    "inlinePhases":["create"],
    "payloadTemplate":{"to":{"id":"{toId}"}}
  }]
}`
			root := writePackFixture(t, "connector-companion", validPackManifest(`[
    {"kind":"object_spec","businessKey":"crm","manageability":"locked","payload":[
      {
        "apiName":"Opportunity",
        "label":"Opportunity",
        "tableType":"standard_object",
        "category":"crm",
        "sharingModel":"Private",
        "enableHierarchySharing":false,
        "description":"Opportunity",
        "fields":[
          {"apiName":"Name","label":"Name","type":"string","required":true,"isNameField":true},
          {"apiName":"RemoteDealId__c","label":"Remote Deal ID","type":"string"}
        ]
      },
      {
        "apiName":"Account",
        "label":"Account",
        "tableType":"standard_object",
        "category":"crm",
        "sharingModel":"Private",
        "enableHierarchySharing":false,
        "description":"Account",
        "fields":[
          {"apiName":"Name","label":"Name","type":"string","required":true,"isNameField":true},
          {"apiName":"RemoteCompanyId__c","label":"Remote Company ID","type":"string"}
        ]
      }
    ]},
    {"kind":"standard_flow","businessKey":"Opportunity_To_Remote","manageability":"defaults_only","payload":`+jsonRawMessage(opportunityFlow)+`},
    {"kind":"standard_flow","businessKey":"Account_To_Remote","manageability":"defaults_only","payload":`+jsonRawMessage(accountFlow)+`},
    {"kind":"connector_field_mapping","businessKey":"jira-like-sample/push-mappings","manageability":"locked","payload":`+jsonRawMessage(mappings)+`},
    {"kind":"connector_push_contract","businessKey":"jira-like-sample/Account_To_Remote/PushAccount/Account/remote-company","manageability":"locked","payload":`+jsonRawMessage(accountContract)+`},
    {"kind":"connector_push_contract","businessKey":"jira-like-sample/Opportunity_To_Remote/PushOpportunity/Opportunity/remote-deal","manageability":"locked","payload":`+jsonRawMessage(opportunityContract)+`}
  ]`, `"dependencies": [],`))

			report := ValidateInstallablePackSourceWithOptions("local_path:"+root, opts)
			if !report.HasErrors() {
				t.Fatal("validation accepted connector_push association lookup from undeclared live schema; want fail-closed diagnostic")
			}
			if !strings.Contains(report.Error(), "sourceLookupField") {
				t.Fatalf("expected sourceLookupField schema diagnostic, got:\n%s", report.Error())
			}
		})
	}
}

func TestValidateInstallablePackSourceAcceptsConnectorPushAssociationLookupFromDependencyCustomField(t *testing.T) {
	opts := testPackSourceOptions(t)
	writeManifest(t, filepath.Join(opts.OfficialRepoRoot, "base-crm"), strings.Replace(validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "crm",
      "manageability": "locked",
      "path": "objects/crm.json"
    },
    {
      "kind": "custom_field",
      "businessKey": "WorkItem__c/Account__c",
      "manageability": "locked",
      "dependsOn": [{"kind":"object_spec","businessKey":"crm"}],
      "payload": {"objectApiName":"WorkItem__c","fieldApiName":"Account__c"}
    }
  ]`, `"dependencies": [],`), `"name": "jira-like-sample"`, `"name": "base-crm"`, 1))
	writeFile(t, filepath.Join(opts.OfficialRepoRoot, "base-crm"), "objects/crm.json", `[
  {
    "apiName": "Account",
    "label": "Account",
    "tableType": "standard_object",
    "category": "crm",
    "sharingModel": "Private",
    "enableHierarchySharing": false,
    "description": "Account",
    "fields": [
      {"apiName": "Name", "label": "Name", "type": "string", "required": true, "isNameField": true},
      {"apiName": "RemoteKey__c", "label": "Remote Key", "type": "string"}
    ]
  },
  {
    "apiName": "WorkItem__c",
    "label": "Work Item",
    "tableType": "custom_object",
    "category": "work",
    "sharingModel": "Private",
    "enableHierarchySharing": false,
    "description": "Work item",
    "fields": [
      {"apiName": "Name", "label": "Name", "type": "string", "required": true, "isNameField": true},
      {"apiName": "RemoteKey__c", "label": "Remote Key", "type": "string"},
      {"apiName": "Account__c", "label": "Account", "type": "reference", "referenceTo": ["Account"], "relationshipName": "Account"}
    ]
  }
]`)
	workItemFlow := `{"start":{"object":"WorkItem__c"},"actionCalls":[{"name":"PushWorkItem","actionType":"PushToConnector"}]}`
	accountFlow := `{"start":{"object":"Account"},"actionCalls":[{"name":"PushAccount","actionType":"PushToConnector"}]}`
	mappings := `[
  {"sourceObject":"WorkItem__c","targetObject":"remoteWorkItem","actionType":"PushToConnector","direction":"outbound","mappings":[{"sourceField":"Name","targetField":"name"}]},
  {"sourceObject":"Account","targetObject":"remoteAccount","actionType":"PushToConnector","direction":"outbound","mappings":[{"sourceField":"Name","targetField":"name"}]}
]`
	accountContract := `{
  "flowDeveloperName":"Account_To_Remote",
  "flowActionName":"PushAccount",
  "slotLineageId":"account-remote-sync",
  "sourceObject":"Account",
  "destinationSlotId":"remote-account",
  "profileOwnerPack":"sample-connector",
  "profileName":"default",
  "targetObject":"remoteAccount",
  "createPathTemplate":"/objects/accounts",
  "updatePathTemplate":"/objects/accounts/{remoteId}",
  "responseIdPath":"id",
  "remoteIdField":"RemoteKey__c"
}`
	workItemContract := `{
  "flowDeveloperName":"WorkItem_To_Remote",
  "flowActionName":"PushWorkItem",
  "slotLineageId":"workitem-remote-sync",
  "sourceObject":"WorkItem__c",
  "destinationSlotId":"remote-workitem",
  "profileOwnerPack":"sample-connector",
  "profileName":"default",
  "targetObject":"remoteWorkItem",
  "createPathTemplate":"/objects/work-items",
  "updatePathTemplate":"/objects/work-items/{remoteId}",
  "responseIdPath":"id",
  "remoteIdField":"RemoteKey__c",
  "associations":[{
    "sourceLookupField":"Account__c",
    "sourceObject":"Account",
    "remoteIdField":"RemoteKey__c",
    "targetActionSlotId":"account-remote-sync",
    "targetDestinationSlotId":"remote-account",
    "targetObject":"remoteAccount",
    "payloadField":"associations",
    "payloadMergeMode":"append",
    "inlinePhases":["create"],
    "payloadTemplate":{"to":{"id":"{toId}"}}
  }]
}`
	root := writePackFixture(t, "connector-companion-custom-field", validPackManifest(`[
    {"kind":"standard_flow","businessKey":"WorkItem_To_Remote","manageability":"defaults_only","payload":`+jsonRawMessage(workItemFlow)+`},
    {"kind":"standard_flow","businessKey":"Account_To_Remote","manageability":"defaults_only","payload":`+jsonRawMessage(accountFlow)+`},
    {"kind":"connector_field_mapping","businessKey":"jira-like-sample/push-mappings","manageability":"locked","payload":`+jsonRawMessage(mappings)+`},
    {"kind":"connector_push_contract","businessKey":"jira-like-sample/Account_To_Remote/PushAccount/Account/remote-account","manageability":"locked","payload":`+jsonRawMessage(accountContract)+`},
    {"kind":"connector_push_contract","businessKey":"jira-like-sample/WorkItem_To_Remote/PushWorkItem/WorkItem__c/remote-workitem","manageability":"locked","payload":`+jsonRawMessage(workItemContract)+`}
  ]`, `"dependencies": [{"name": "base-crm"}],`))

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, opts)
	if report.HasErrors() {
		t.Fatalf("validation rejected dependency custom_field-backed connector_push association lookup; want acceptance:\n%s", report.Error())
	}
	if report.Pack == nil {
		t.Fatal("validation did not construct installable pack")
	}
}

func TestValidateInstallablePackSourceRejectsDependencyDisplayNameDotPathMissingChild(t *testing.T) {
	opts := testPackSourceOptions(t)
	writeManifest(t, filepath.Join(opts.OfficialRepoRoot, "base-crm"), strings.Replace(validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "account",
      "manageability": "locked",
      "path": "objects/account.json"
    }
  ]`, `"dependencies": [],`), `"name": "jira-like-sample"`, `"name": "base-crm"`, 1))
	writeFile(t, filepath.Join(opts.OfficialRepoRoot, "base-crm"), "objects/account.json", testObjectSpecPayloadWithFields("Account",
		`{"apiName": "Name", "label": "Name", "type": "string", "required": true, "isNameField": true}`,
	))
	root := writePackFixture(t, "display-name-dependency", validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "widget",
      "manageability": "locked",
      "path": "objects/widget.json"
    }
  ]`, `"dependencies": [{"name": "base-crm"}],`))
	writeFile(t, root, "objects/widget.json", `[
  {
    "apiName": "Widget__c",
    "label": "Widget",
    "tableType": "standard_object",
    "category": "jira",
    "sharingModel": "Private",
    "enableHierarchySharing": false,
    "description": "Widget work item",
    "displayNameField": "Account.DoesNotExist__c",
    "fields": [
      {"apiName": "Name", "label": "Name", "type": "string", "required": true, "isNameField": true},
      {"apiName": "AccountId", "label": "Account", "type": "reference", "referenceTo": ["Account"], "relationshipName": "Account"}
    ]
  }
]`)

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, opts)
	if !report.HasErrors() {
		t.Fatal("validation accepted missing dependency child displayNameField; want fail-closed diagnostic")
	}
	assertInstallableDiagnostic(t, report, "object.display_name_field.child_unresolved")
}

func TestValidateInstallablePackSourceRejectsDefaultChildRowsMissingRequiredField(t *testing.T) {
	payload := `[
  {
    "apiName": "Parent__c",
    "label": "Parent",
    "tableType": "custom_object",
    "category": "jira",
    "sharingModel": "Private",
    "enableHierarchySharing": false,
    "description": "Parent object",
    "defaultChildRows": [
      {
        "targetObject": "Child__c",
        "targetLookupField": "Parent__c",
        "fieldValues": {
          "Optional__c": "seeded"
        }
      }
    ],
    "fields": [
      {"apiName": "Name", "label": "Name", "type": "string", "required": true, "isNameField": true}
    ]
  },
  {
    "apiName": "Child__c",
    "label": "Child",
    "tableType": "custom_object",
    "category": "jira",
    "sharingModel": "Private",
    "enableHierarchySharing": false,
    "description": "Child object",
    "fields": [
      {"apiName": "Name", "label": "Name", "type": "string", "required": true, "isNameField": true},
      {"apiName": "Parent__c", "label": "Parent", "type": "reference", "referenceTo": ["Parent__c"], "createable": true, "updateable": true},
      {"apiName": "RequiredText__c", "label": "Required Text", "type": "string", "required": true, "createable": true, "updateable": true},
      {"apiName": "Optional__c", "label": "Optional", "type": "string", "createable": true, "updateable": true}
    ]
  }
]`
	root := writePackFixture(t, "object-spec-default-child-rows-required", validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "objects",
      "manageability": "locked",
      "payload": `+payload+`
    }
  ]`, `"dependencies": [],`))

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	if !report.HasErrors() {
		t.Fatal("validation accepted defaultChildRows with unsatisfied required child field; want fail-closed error")
	}
	if !strings.Contains(report.Error(), "DefaultChildRows") {
		t.Fatalf("validation error = %q, want DefaultChildRows context", report.Error())
	}
	if !strings.Contains(report.Error(), "RequiredText__c") {
		t.Fatalf("validation error = %q, want missing required field detail", report.Error())
	}
}

func TestValidateInstallablePackSourceRejectsDefaultChildRowsTargetingSameInstallEngineOwnedField(t *testing.T) {
	payload := `[
  {
    "apiName": "Parent__c",
    "label": "Parent",
    "tableType": "custom_object",
    "category": "jira",
    "sharingModel": "Private",
    "enableHierarchySharing": false,
    "description": "Parent object",
    "defaultChildRows": [
      {
        "targetObject": "Child__c",
        "targetLookupField": "Parent__c",
        "fieldValues": {
          "Name": "Seeded child",
          "EngineOwned__c": "seeded"
        }
      }
    ],
    "fields": [
      {"apiName": "Name", "label": "Name", "type": "string", "required": true, "isNameField": true}
    ]
  },
  {
    "apiName": "Child__c",
    "label": "Child",
    "tableType": "custom_object",
    "category": "jira",
    "sharingModel": "Private",
    "enableHierarchySharing": false,
    "description": "Child object",
    "fields": [
      {"apiName": "Name", "label": "Name", "type": "string", "required": true, "isNameField": true},
      {"apiName": "Parent__c", "label": "Parent", "type": "reference", "referenceTo": ["Parent__c"], "createable": true, "updateable": true},
      {"apiName": "EngineOwned__c", "label": "Engine Owned", "type": "string", "createable": true, "updateable": true}
    ]
  }
]`
	autonumberPayload := `[
  {
    "objectName": "Child__c",
    "fieldApiName": "EngineOwned__c",
    "format": "ENG-{0000}",
    "scope": "global",
    "start": 1
  }
]`
	root := writePackFixture(t, "object-spec-default-child-rows-engine-owned", validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "objects",
      "manageability": "locked",
      "payload": `+payload+`
    },
    {
      "kind": "autonumber_format",
      "businessKey": "autonumber_formats",
      "manageability": "locked",
      "payload": `+autonumberPayload+`,
      "dependsOn": [{"kind": "object_spec", "businessKey": "objects"}]
    }
  ]`, `"dependencies": [],`))

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	if !report.HasErrors() {
		t.Fatal("validation accepted defaultChildRows targeting same-install engine-owned field; want fail-closed error")
	}
	if !strings.Contains(report.Error(), "EngineOwned__c") {
		t.Fatalf("validation error = %q, want engine-owned field detail", report.Error())
	}
	if !strings.Contains(report.Error(), "engine-owned") {
		t.Fatalf("validation error = %q, want engine-owned rejection", report.Error())
	}
}

func TestValidateInstallablePackSourceAllowsDefaultChildRowsNeedingLiveSnapshot(t *testing.T) {
	payload := `[
  {
    "apiName": "Parent__c",
    "label": "Parent",
    "tableType": "custom_object",
    "category": "jira",
    "sharingModel": "Private",
    "enableHierarchySharing": false,
    "description": "Parent object",
    "defaultChildRows": [
      {
        "targetObject": "ExistingChild__c",
        "targetLookupField": "Parent__c",
        "fieldValues": {
          "Status__c": "Seeded"
        }
      }
    ],
    "fields": [
      {"apiName": "Name", "label": "Name", "type": "string", "required": true, "isNameField": true}
    ]
  }
]`
	root := writePackFixture(t, "object-spec-default-child-rows-live-snapshot", validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "objects",
      "manageability": "locked",
      "payload": `+payload+`
    }
  ]`, `"dependencies": [],`))

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	if report.HasErrors() {
		t.Fatalf("source-only validation should defer unresolved external target to install/verify live snapshot, got:\n%s", report.Error())
	}
}

// TestValidateInstallablePackSourceAcceptsChildCloneRulesUnderDefaultsOnly
// locks in the column-scoped ownership path: defaults_only childCloneRules are
// installable because _System_Object.ChildCloneRulesCustomized preserves L2
// overrides across pack reapply and verify.
func TestValidateInstallablePackSourceAcceptsChildCloneRulesUnderDefaultsOnly(t *testing.T) {
	payload := `[
  {
    "apiName": "Parent__c",
    "label": "Parent",
    "tableType": "custom_object",
    "category": "jira",
    "sharingModel": "Private",
    "enableHierarchySharing": false,
    "description": "Parent object",
    "childCloneRules": [
      {
        "parentLookupField": "Source__c",
        "sourceObject": "Source__c",
        "sourceLookupField": "Source__c",
        "targetObject": "Target__c",
        "targetLookupField": "Parent__c",
        "fieldMappings": {"Name": "Name"}
      }
    ],
    "fields": [
      {"apiName": "Name", "label": "Name", "type": "string", "required": true, "isNameField": true},
      {"apiName": "Source__c", "label": "Source", "type": "reference", "referenceTo": ["Source__c"]}
    ]
  },
  {
    "apiName": "Source__c",
    "label": "Source",
    "tableType": "custom_object",
    "category": "jira",
    "sharingModel": "Private",
    "enableHierarchySharing": false,
    "description": "Source object",
    "fields": [
      {"apiName": "Name", "label": "Name", "type": "string", "required": true, "isNameField": true},
      {"apiName": "Source__c", "label": "Source", "type": "reference", "referenceTo": ["Source__c"]}
    ]
  },
  {
    "apiName": "Target__c",
    "label": "Target",
    "tableType": "custom_object",
    "category": "jira",
    "sharingModel": "Private",
    "enableHierarchySharing": false,
    "description": "Target object",
    "fields": [
      {"apiName": "Name", "label": "Name", "type": "string", "required": true, "isNameField": true},
      {"apiName": "Parent__c", "label": "Parent", "type": "reference", "referenceTo": ["Parent__c"], "createable": true, "updateable": true}
    ]
  }
]`
	root := writePackFixture(t, "object-spec-child-clone-defaults-only", validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "objects",
      "manageability": "defaults_only",
      "payload": `+payload+`
    }
  ]`, `"dependencies": [],`))

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	if report.HasErrors() {
		t.Fatalf("validation rejected childCloneRules under defaults_only object_spec; want acceptance:\n%s", report.Error())
	}
}

// TestValidateInstallablePackSourceAcceptsChildCloneRulesUnderLocked is the
// locked counterpart: locked object_spec components also remain a valid
// authoring surface for pack-owned childCloneRules.
func TestValidateInstallablePackSourceAcceptsChildCloneRulesUnderLocked(t *testing.T) {
	payload := `[
  {
    "apiName": "Parent__c",
    "label": "Parent",
    "tableType": "custom_object",
    "category": "jira",
    "sharingModel": "Private",
    "enableHierarchySharing": false,
    "description": "Parent object",
    "childCloneRules": [
      {
        "parentLookupField": "Source__c",
        "sourceObject": "Source__c",
        "sourceLookupField": "Source__c",
        "targetObject": "Target__c",
        "targetLookupField": "Parent__c",
        "fieldMappings": {"Name": "Name"}
      }
    ],
    "fields": [
      {"apiName": "Name", "label": "Name", "type": "string", "required": true, "isNameField": true},
      {"apiName": "Source__c", "label": "Source", "type": "reference", "referenceTo": ["Source__c"]}
    ]
  },
  {
    "apiName": "Source__c",
    "label": "Source",
    "tableType": "custom_object",
    "category": "jira",
    "sharingModel": "Private",
    "enableHierarchySharing": false,
    "description": "Source object",
    "fields": [
      {"apiName": "Name", "label": "Name", "type": "string", "required": true, "isNameField": true},
      {"apiName": "Source__c", "label": "Source", "type": "reference", "referenceTo": ["Source__c"]}
    ]
  },
  {
    "apiName": "Target__c",
    "label": "Target",
    "tableType": "custom_object",
    "category": "jira",
    "sharingModel": "Private",
    "enableHierarchySharing": false,
    "description": "Target object",
    "fields": [
      {"apiName": "Name", "label": "Name", "type": "string", "required": true, "isNameField": true},
      {"apiName": "Parent__c", "label": "Parent", "type": "reference", "referenceTo": ["Parent__c"], "createable": true, "updateable": true}
    ]
  }
]`
	root := writePackFixture(t, "object-spec-child-clone-locked", validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "objects",
      "manageability": "locked",
      "payload": `+payload+`
    }
  ]`, `"dependencies": [],`))

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	if report.HasErrors() {
		t.Fatalf("validation rejected childCloneRules under locked object_spec; want acceptance:\n%s", report.Error())
	}
}

func TestValidateInstallablePackSourceRejectsReservedObjectNames(t *testing.T) {
	for _, reserved := range []string{"User", "Profile", "Group", "UserRole", "PermissionSet", "PermissionSetGroup"} {
		t.Run(reserved, func(t *testing.T) {
			root := writePackFixture(t, "redeclare-platform-object", validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "object",
      "manageability": "locked",
      "payload": `+testObjectSpecPayload(reserved)+`
    }
  ]`, `"dependencies": [],`))

			report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
			assertInstallableDiagnostic(t, report, "component.payload.reserved_object_name")
		})
	}
}

func TestValidateInstallablePackSourceRejectsReservedFieldNames(t *testing.T) {
	for _, reserved := range []string{"Id", "OwnerId", "CreatedById", "LastModifiedById", "CreatedDate", "LastModifiedDate", "SystemModstamp", "IsDeleted"} {
		t.Run(reserved, func(t *testing.T) {
			payload := `[{"apiName":"Issue","label":"Issue","tableType":"standard_object","category":"jira","sharingModel":"Private","enableHierarchySharing":false,"description":"Issue","fields":[{"apiName":"Subject","label":"Subject","type":"string","required":true,"isNameField":true},{"apiName":"` + reserved + `","label":"` + reserved + `","type":"string"}]}]`
			root := writePackFixture(t, "redeclare-system-field", validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "object",
      "manageability": "locked",
      "payload": `+payload+`
    }
  ]`, `"dependencies": [],`))

			report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
			assertInstallableDiagnostic(t, report, "component.payload.reserved_field_name")
		})
	}
}

// TestValidateInstallablePackSourceRejectsUnknownManageability asserts that
// any manageability string outside the wired enum (e.g. "additive",
// "overlayable" — not yet enabled on any component kind) fails as
// component.manageability.unsupported, before per-kind capability checks.
func TestValidateInstallablePackSourceRejectsUnknownManageability(t *testing.T) {
	for _, value := range []string{"additive", "overlayable", "bogus"} {
		t.Run(value, func(t *testing.T) {
			root := writePackFixture(t, "unknown-manageability", validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "issue",
      "manageability": "`+value+`",
      "payload": `+testObjectSpecPayload("Issue")+`
    }
  ]`, `"dependencies": [],`))

			report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
			assertInstallableDiagnostic(t, report, "component.manageability.unsupported")
		})
	}
}

func TestValidateInstallablePackSourceRejectsInvalidObjectSpecPayloadShape(t *testing.T) {
	root := writePackFixture(t, "bad-object-payload", validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "issue",
      "manageability": "locked",
      "payload": {"objects": [{"apiName": "Issue"}]}
    }
  ]`, `"dependencies": [],`))

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	assertInstallableDiagnostic(t, report, "component.payload.invalid_schema")
}

func TestValidateInstallablePackSourceRejectsDependsOnLaterPhase(t *testing.T) {
	root := writePackFixture(t, "bad-phase-dependency", validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "issue",
      "manageability": "locked",
      "payload": `+testObjectSpecPayload("Issue")+`,
      "dependsOn": [{"kind": "report_type", "businessKey": "issue-report"}]
    },
    {
      "kind": "report_type",
      "businessKey": "issue-report",
      "manageability": "locked",
      "payload": {"reportTypes": []}
    }
  ]`, `"dependencies": [],`))

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	assertInstallableDiagnostic(t, report, "component.depends_on.phase_order")
}

func TestValidatePackSourceRejectsUnsafeAndCollidingPaths(t *testing.T) {
	root := writePackFixture(t, "bad-paths", validPackManifest(`[
    {
	      "kind": "object_spec",
      "businessKey": "dotdot",
      "manageability": "locked",
      "path": "../outside.json"
    },
    {
      "kind": "object_spec",
      "businessKey": "nfc-a",
      "manageability": "locked",
      "path": "objects/é.json"
    },
    {
      "kind": "object_spec",
      "businessKey": "nfc-b",
      "manageability": "locked",
      "path": "objects/é.json"
    },
    {
      "kind": "object_spec",
      "businessKey": "windows-absolute",
      "manageability": "locked",
      "path": "C:\\windows\\absolute.json"
    }
  ]`, `"dependencies": [],`))
	writeFile(t, root, "objects/é.json", `{"ok":true}`)

	report := ValidatePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	assertDiagnostic(t, report, "path.invalid")
	assertDiagnostic(t, report, "path.collision")
}

func TestValidatePackSourceRejectsSymlinkEscape(t *testing.T) {
	root := writePackFixture(t, "symlink-pack", validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "object",
      "manageability": "locked",
      "path": "objects/outside.json"
    }
  ]`, `"dependencies": [],`))
	outside := filepath.Join(t.TempDir(), "outside.json")
	if err := os.WriteFile(outside, []byte(`{"outside":true}`), 0o644); err != nil {
		t.Fatalf("write outside target: %v", err)
	}
	objectsDir := filepath.Join(root, "objects")
	if err := os.MkdirAll(objectsDir, 0o755); err != nil {
		t.Fatalf("mkdir objects: %v", err)
	}
	if err := os.Symlink(outside, filepath.Join(objectsDir, "outside.json")); err != nil {
		t.Skipf("symlink unavailable: %v", err)
	}

	report := ValidatePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	assertDiagnostic(t, report, "path.symlink_escape")
}

func TestValidatePackSourceRejectsManifestSymlinkEscape(t *testing.T) {
	root := filepath.Join(t.TempDir(), "manifest-link-pack")
	if err := os.MkdirAll(root, 0o755); err != nil {
		t.Fatalf("mkdir pack root: %v", err)
	}
	outsideManifest := filepath.Join(t.TempDir(), "pack.json")
	if err := os.WriteFile(outsideManifest, []byte(validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "object",
      "manageability": "locked",
      "payload": {"name": "Issue"}
    }
  ]`, `"dependencies": [],`)), 0o644); err != nil {
		t.Fatalf("write outside manifest: %v", err)
	}
	if err := os.Symlink(outsideManifest, filepath.Join(root, "pack.json")); err != nil {
		t.Skipf("symlink unavailable: %v", err)
	}

	report := ValidatePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	assertDiagnostic(t, report, "path.symlink_escape")
}

func TestValidatePackSourceOfficialRepoRequiresManifestBackedRoot(t *testing.T) {
	opts := testPackSourceOptions(t)
	opts.OfficialRepoRoot = t.TempDir()

	report := ValidatePackSourceWithOptions("official_repo:salesforce-crm-standard", opts)
	assertDiagnostic(t, report, "source.not_found")

	root := filepath.Join(opts.OfficialRepoRoot, "jira-like-sample")
	writeManifest(t, root, validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "object",
      "manageability": "locked",
      "payload": {"name": "Issue"}
    }
  ]`, `"dependencies": [],`))
	report = ValidatePackSourceWithOptions("official_repo:jira-like-sample", opts)
	if report.HasErrors() {
		t.Fatalf("validate official_repo source diagnostics:\n%s", report.Error())
	}

	mismatchRoot := filepath.Join(opts.OfficialRepoRoot, "mismatch")
	writeManifest(t, mismatchRoot, validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "object",
      "manageability": "locked",
      "payload": {"name": "Issue"}
    }
  ]`, `"dependencies": [],`))
	report = ValidatePackSourceWithOptions("official_repo:mismatch", opts)
	assertDiagnostic(t, report, "source.name_mismatch")
}

func TestValidatePackSourceOfficialRepoRequiresConfiguredRoot(t *testing.T) {
	opts := testPackSourceOptions(t)
	opts.OfficialRepoRoot = ""

	report := ValidatePackSourceWithOptions("official_repo:salesforce-crm-standard", opts)
	assertDiagnostic(t, report, "source.official_repo.root_missing")
}

func TestValidatePackSourceOfficialRepoUsesConfiguredPackRevision(t *testing.T) {
	const packName = "official-locked-source"

	officialRoot := t.TempDir()
	packRoot := filepath.Join(officialRoot, packName)
	writeManifest(t, packRoot, strings.Replace(validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "issue",
      "manageability": "locked",
      "path": "objects/issue.json"
    }
  ]`, `"dependencies": [],`), `"name": "jira-like-sample"`, `"name": "`+packName+`"`, 1))
	writeFile(t, packRoot, "objects/issue.json", testObjectSpecPayloadWithFields("Issue",
		`{"apiName": "Subject", "label": "Subject", "type": "string", "required": true, "isNameField": true, "description": "initial subject"}`,
	))
	initGitTestRepo(t, officialRoot)
	lockedRevision := gitTestCommit(t, officialRoot, "locked pack")

	writeFile(t, packRoot, "objects/issue.json", testObjectSpecPayloadWithFields("Issue",
		`{"apiName": "Subject", "label": "Subject", "type": "string", "required": true, "isNameField": true, "description": "checkout head subject"}`,
	))
	checkoutHead := gitTestCommit(t, officialRoot, "checkout head")
	if lockedRevision == checkoutHead {
		t.Fatal("test fixture produced identical git revisions")
	}

	opts := testPackSourceOptions(t)
	opts.OfficialRepoRoot = officialRoot
	opts.OfficialRepoSourceRevisions = map[string]string{packName: lockedRevision}
	report := ValidatePackSourceWithOptions("official_repo:"+packName, opts)
	if report.HasErrors() {
		t.Fatalf("validate official_repo source at configured revision diagnostics:\n%s", report.Error())
	}
	if report.Source == nil {
		t.Fatal("validate official_repo source did not return a source")
	}
	if report.Source.Revision != lockedRevision {
		t.Fatalf("ResolvedPackSource.Revision = %q, want configured pack revision %q", report.Source.Revision, lockedRevision)
	}
	gotPayload := string(report.Source.Files["objects/issue.json"])
	if !strings.Contains(gotPayload, "initial subject") || strings.Contains(gotPayload, "checkout head subject") {
		t.Fatalf("official_repo source resolved payload = %s, want locked revision payload", gotPayload)
	}
}

func TestValidatePackSourceReleaseRepoUsesExactRegisteredRevision(t *testing.T) {
	const sourceURI = "urn:nexuscrm:release-pack:pingcap-hubspot-companion"

	repoRoot := t.TempDir()
	packRoot := filepath.Join(repoRoot, "packs", "companion")
	writeManifest(t, packRoot, validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "issue",
      "manageability": "locked",
      "path": "objects/issue.json"
    }
	  ]`, `"dependencies": [],`))
	writeFile(t, packRoot, "objects/issue.json", testObjectSpecPayloadWithFields("Issue",
		`{"apiName": "Subject", "label": "Subject", "type": "string", "required": true, "isNameField": true, "description": "sealed subject"}`,
	))
	initGitTestRepo(t, repoRoot)
	sealedRevision := gitTestCommit(t, repoRoot, "sealed release pack")

	writeFile(t, packRoot, "objects/issue.json", testObjectSpecPayloadWithFields("Issue",
		`{"apiName": "Subject", "label": "Subject", "type": "string", "required": true, "isNameField": true, "description": "mutable checkout subject"}`,
	))
	checkoutRevision := gitTestCommit(t, repoRoot, "mutable checkout head")
	if sealedRevision == checkoutRevision {
		t.Fatal("test fixture produced identical git revisions")
	}

	opts := testPackSourceOptions(t)
	opts.ReleaseRepoSources = map[string]ReleaseRepoSource{
		sourceURI: {Root: packRoot, Revision: sealedRevision},
	}
	report := ValidatePackSourceWithOptions(PackSourceKindReleaseRepo+":"+sourceURI, opts)
	if report.HasErrors() {
		t.Fatalf("validate release_repo source at exact revision diagnostics:\n%s", report.Error())
	}
	if report.Source == nil {
		t.Fatal("validate release_repo source did not return a source")
	}
	if report.Source.Kind != PackSourceKindReleaseRepo || report.Source.URI != sourceURI || report.Source.Revision != sealedRevision {
		t.Fatalf("release_repo identity = %#v, want URI %q revision %q", report.Source, sourceURI, sealedRevision)
	}
	gotPayload := string(report.Source.Files["objects/issue.json"])
	if !strings.Contains(gotPayload, "sealed subject") || strings.Contains(gotPayload, "mutable checkout subject") {
		t.Fatalf("release_repo source resolved payload = %s, want exact sealed revision payload", gotPayload)
	}

	_, diagnostics := resolveStoredPackSourceWithOptions(
		PackSourceKindReleaseRepo,
		sourceURI,
		checkoutRevision,
		opts,
	)
	assertDiagnostic(t, PackValidationReport{Diagnostics: diagnostics}, "source.release_repo.authority_missing")

	opts.ReleaseRepoStoredRevisionSources = map[string]ReleaseRepoSource{
		releaseRepoStoredRevisionAuthorityKey(sourceURI, checkoutRevision): {
			Root: packRoot, Revision: checkoutRevision,
		},
	}
	stored, diagnostics := resolveStoredPackSourceWithOptions(
		PackSourceKindReleaseRepo,
		sourceURI,
		checkoutRevision,
		opts,
	)
	if len(diagnostics) != 0 || stored == nil || stored.Revision != checkoutRevision {
		t.Fatalf("stored revision resolution = %#v diagnostics=%v, want frozen historical authority", stored, diagnostics)
	}
	fresh := ValidatePackSourceWithOptions(PackSourceKindReleaseRepo+":"+sourceURI, opts)
	if fresh.HasErrors() || fresh.Source == nil || fresh.Source.Revision != sealedRevision {
		t.Fatalf("fresh candidate escaped primary authority: source=%#v diagnostics=%s", fresh.Source, fresh.Error())
	}
}

func TestValidatePackSourceReleaseRepoRejectsNonCommitGitObject(t *testing.T) {
	const sourceURI = "urn:nexuscrm:release-pack:tree-object"
	repoRoot := t.TempDir()
	packRoot := filepath.Join(repoRoot, "packs", "companion")
	writeManifest(t, packRoot, validPackManifest(`[]`, `"dependencies": [],`))
	initGitTestRepo(t, repoRoot)
	_ = gitTestCommit(t, repoRoot, "sealed release pack")
	treeRevision := strings.TrimSpace(runGitTestCommand(t, repoRoot, "rev-parse", "HEAD^{tree}"))

	opts := testPackSourceOptions(t)
	opts.ReleaseRepoSources = map[string]ReleaseRepoSource{
		sourceURI: {Root: packRoot, Revision: treeRevision},
	}
	assertDiagnostic(t, ValidatePackSourceWithOptions(PackSourceKindReleaseRepo+":"+sourceURI, opts), "source.revision.not_commit")
}

func TestValidatePackSourceReleaseRepoFailsClosedWithoutExactAuthority(t *testing.T) {
	const sourceURI = "urn:nexuscrm:release-pack:companion"
	opts := testPackSourceOptions(t)

	report := ValidatePackSourceWithOptions(PackSourceKindReleaseRepo+":"+sourceURI, opts)
	assertDiagnostic(t, report, "source.release_repo.authority_missing")

	opts.ReleaseRepoSources = map[string]ReleaseRepoSource{
		sourceURI: {Root: t.TempDir(), Revision: strings.Repeat("g", 40)},
	}
	report = ValidatePackSourceWithOptions(PackSourceKindReleaseRepo+":"+sourceURI, opts)
	assertDiagnostic(t, report, "source.release_repo.revision")
}

func TestResolveInstalledSourceBackedPackOfficialRepoPersistsConfiguredPackRevision(t *testing.T) {
	const packName = "official-locked-install"

	officialRoot := t.TempDir()
	packRoot := filepath.Join(officialRoot, packName)
	writeManifest(t, packRoot, strings.Replace(validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "issue",
      "manageability": "locked",
      "path": "objects/issue.json"
    }
  ]`, `"dependencies": [],`), `"name": "jira-like-sample"`, `"name": "`+packName+`"`, 1))
	writeFile(t, packRoot, "objects/issue.json", testObjectSpecPayloadWithFields("Issue",
		`{"apiName": "Subject", "label": "Subject", "type": "string", "required": true, "isNameField": true, "description": "install lock"}`,
	))
	initGitTestRepo(t, officialRoot)
	lockedRevision := gitTestCommit(t, officialRoot, "locked install pack")

	writeFile(t, packRoot, "objects/issue.json", testObjectSpecPayloadWithFields("Issue",
		`{"apiName": "Subject", "label": "Subject", "type": "string", "required": true, "isNameField": true, "description": "new checkout"}`,
	))
	checkoutHead := gitTestCommit(t, officialRoot, "new checkout")
	if lockedRevision == checkoutHead {
		t.Fatal("test fixture produced identical git revisions")
	}

	t.Setenv(OfficialAppPacksRootEnvVar, officialRoot)
	RegisterDefaultOfficialRepoSourceRevision(packName, lockedRevision)
	pack, err := ResolveInstalledSourceBackedPack(packName, AppPack, PackSourceKindOfficialRepo, packName)
	if err != nil {
		t.Fatalf("ResolveInstalledSourceBackedPack: %v", err)
	}
	meta := PackHashMetadataForPack(pack)
	if meta.SourceRevision != lockedRevision {
		t.Fatalf("PackHashMetadataForPack SourceRevision = %q, want configured pack revision %q", meta.SourceRevision, lockedRevision)
	}
	if meta.SourceRevision == checkoutHead {
		t.Fatalf("PackHashMetadataForPack SourceRevision = checkout HEAD %q, want per-pack lock %q", checkoutHead, lockedRevision)
	}
}

// TestValidateInstallableOfficialRepoCRMPackPasses asserts the official
// salesforce-crm-standard pack validates clean against the full
// validate-installable pipeline. This is the cheap regression net for any
// future fail-closed validator (e.g. column-safety, reserved-name) — adding
// a new validator that the official CRM pack happens to violate would block
// install in CI; this test surfaces that locally before commit.
func TestValidateInstallableOfficialRepoCRMPackPasses(t *testing.T) {
	registerCRMHostPrimitivesForTest(t)
	opts := officialCRMPackSourceOptionsForTest(t)

	report := ValidateInstallablePackSourceWithComponentKindRegistrationSet(
		"official_repo:salesforce-crm-standard",
		opts,
		crmPermissionRegistrationSetForTest(t),
	)
	if report.HasErrors() {
		t.Fatalf("official CRM pack must pass validate-installable; got diagnostics:\n%s", report.Error())
	}
}

func TestValidateInstallableOfficialRepoCRMPackRequiresDistributionHostRegistry(t *testing.T) {
	resetDefaultHostPrimitivesForTest(t)
	opts := DefaultPackSourceOptions()
	opts.OfficialRepoRoot = officialPackRootFromThisFile(t)

	report := ValidateInstallablePackSourceWithComponentKindRegistrationSet(
		"official_repo:salesforce-crm-standard",
		opts,
		crmPermissionRegistrationSetForTest(t),
	)
	assertInstallableDiagnostic(t, report, "host.unsupported")
}

// TestValidateInstallablePackSourceRejectsMixedBlankReferenceTarget proves that
// validateObjectSpecFieldShapes is wired into the public install-time validation
// path: a reference field with a mixed canonical+blank referenceTo slice must
// fail closed through ValidateInstallablePackSourceWithOptions, not pass because
// the validator is only called by unit tests.
func TestValidateInstallablePackSourceRejectsMixedBlankReferenceTarget(t *testing.T) {
	payload := testObjectSpecPayloadWithFields("WorkItem",
		`{"apiName": "Subject", "label": "Subject", "type": "string", "required": true, "isNameField": true}`,
		`{"apiName": "ParentId", "label": "Parent", "type": "reference", "referenceTo": ["Account", ""]}`,
	)
	root := writePackFixture(t, "mixed-blank-ref-target", validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "work-item",
      "manageability": "locked",
      "payload": `+payload+`
    }
  ]`, `"dependencies": [],`))

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	if !report.HasErrors() {
		t.Fatal("ValidateInstallablePackSourceWithOptions accepted reference field with mixed-blank referenceTo; want fail-closed error")
	}
	assertInstallableDiagnostic(t, report, "field.reference.blank_target")
}

// TestValidateInstallablePackSourceRejectsEmptyReferenceTarget proves the
// all-empty-referenceTo case fails closed through the public install path.
func TestValidateInstallablePackSourceRejectsEmptyReferenceTarget(t *testing.T) {
	payload := testObjectSpecPayloadWithFields("WorkItem",
		`{"apiName": "Subject", "label": "Subject", "type": "string", "required": true, "isNameField": true}`,
		`{"apiName": "ParentId", "label": "Parent", "type": "reference", "referenceTo": []}`,
	)
	root := writePackFixture(t, "empty-ref-target", validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "work-item",
      "manageability": "locked",
      "payload": `+payload+`
    }
  ]`, `"dependencies": [],`))

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	if !report.HasErrors() {
		t.Fatal("ValidateInstallablePackSourceWithOptions accepted reference field with empty referenceTo; want fail-closed error")
	}
	assertInstallableDiagnostic(t, report, "field.reference.no_target")
}

// TestValidateInstallablePackSourceRejectsBlankPicklistOptionValue proves the
// blank-option-value case fails closed through the public install path.
func TestValidateInstallablePackSourceRejectsBlankPicklistOptionValue(t *testing.T) {
	payload := testObjectSpecPayloadWithFields("WorkItem",
		`{"apiName": "Subject", "label": "Subject", "type": "string", "required": true, "isNameField": true}`,
		`{"apiName": "Status", "label": "Status", "type": "picklist", "options": ["hot", ""]}`,
	)
	root := writePackFixture(t, "blank-picklist-value", validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "work-item",
      "manageability": "locked",
      "payload": `+payload+`
    }
  ]`, `"dependencies": [],`))

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	if !report.HasErrors() {
		t.Fatal("ValidateInstallablePackSourceWithOptions accepted picklist field with blank option value; want fail-closed error")
	}
	assertInstallableDiagnostic(t, report, "field.picklist.blank_option_value")
}

// TestValidateInstallablePackSourceRejectsMasterDetailEmptyReferenceTo proves
// that a masterdetail field with an empty referenceTo fails closed through the
// public install path. FK DDL uses col.ReferenceTo[0] as the referenced table
// name; an empty slice causes an index-out-of-range at DDL generation time.
func TestValidateInstallablePackSourceRejectsMasterDetailEmptyReferenceTo(t *testing.T) {
	payload := testObjectSpecPayloadWithFields("WorkItem",
		`{"apiName": "Subject", "label": "Subject", "type": "string", "required": true, "isNameField": true}`,
		`{"apiName": "EpicId", "label": "Epic", "type": "masterdetail", "referenceTo": []}`,
	)
	root := writePackFixture(t, "masterdetail-empty-ref", validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "work-item",
      "manageability": "locked",
      "payload": `+payload+`
    }
  ]`, `"dependencies": [],`))

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	if !report.HasErrors() {
		t.Fatal("ValidateInstallablePackSourceWithOptions accepted masterdetail field with empty referenceTo; want fail-closed error")
	}
	assertInstallableDiagnostic(t, report, "field.reference.no_target")
}

// TestValidateInstallablePackSourceRejectsMasterDetailPaddedReferenceTo proves
// that a masterdetail field with a padded referenceTo entry fails closed through
// the public install path. Padded names reach FK DDL generation as-is and
// produce a backtick-wrapped padded identifier that does not match any table.
func TestValidateInstallablePackSourceRejectsMasterDetailPaddedReferenceTo(t *testing.T) {
	payload := testObjectSpecPayloadWithFields("WorkItem",
		`{"apiName": "Subject", "label": "Subject", "type": "string", "required": true, "isNameField": true}`,
		`{"apiName": "EpicId", "label": "Epic", "type": "masterdetail", "referenceTo": [" Epic "]}`,
	)
	root := writePackFixture(t, "masterdetail-padded-ref", validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "work-item",
      "manageability": "locked",
      "payload": `+payload+`
    }
  ]`, `"dependencies": [],`))

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	if !report.HasErrors() {
		t.Fatal("ValidateInstallablePackSourceWithOptions accepted masterdetail field with padded referenceTo; want fail-closed error")
	}
	assertInstallableDiagnostic(t, report, "field.reference.padded_target")
}

// TestValidateInstallablePackSourceAcceptsMasterDetailGoldenReferenceTo proves
// a correctly formed masterdetail field passes the public install path.
func TestValidateInstallablePackSourceAcceptsMasterDetailGoldenReferenceTo(t *testing.T) {
	payload := testObjectSpecPayloadWithFields("WorkItem",
		`{"apiName": "Subject", "label": "Subject", "type": "string", "required": true, "isNameField": true}`,
		`{"apiName": "EpicId", "label": "Epic", "type": "masterdetail", "referenceTo": ["Epic"]}`,
	)
	root := writePackFixture(t, "masterdetail-golden-ref", validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "work-item",
      "manageability": "locked",
      "payload": `+payload+`
    }
  ]`, `"dependencies": [],`))

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	if report.HasErrors() {
		t.Fatalf("ValidateInstallablePackSourceWithOptions rejected masterdetail field with canonical referenceTo; want clean pass:\n%s", report.Error())
	}
}

// TestValidateInstallablePackSourceRejectsPaddedFormulaReturnType proves that a
// formula field with a padded returnType (e.g. " string ") fails closed through
// the public install-time validation path, not just in unit tests. The
// downstream DDL/type-resolution consumers read returnType raw without
// trimming; a padded value either maps to an invalid SQL type or maps to a
// different type than the trimmed value.
func TestValidateInstallablePackSourceRejectsPaddedFormulaReturnType(t *testing.T) {
	payload := testObjectSpecPayloadWithFields("WorkItem",
		`{"apiName": "Subject", "label": "Subject", "type": "string", "required": true, "isNameField": true}`,
		`{"apiName": "Score", "label": "Score", "type": "formula", "returnType": " number "}`,
	)
	root := writePackFixture(t, "padded-formula-return-type", validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "work-item",
      "manageability": "locked",
      "payload": `+payload+`
    }
  ]`, `"dependencies": [],`))

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	if !report.HasErrors() {
		t.Fatal("ValidateInstallablePackSourceWithOptions accepted formula field with padded returnType; want fail-closed error")
	}
	assertInstallableDiagnostic(t, report, "field.formula.padded_return_type")
}

// TestValidateInstallablePackSourceRejectsLegacyActiveScalarFormula verifies
// that all public fresh-source lifecycle entrypoints reject the pre-957
// active-scalar formula shape regardless of manifest version.
func TestValidateInstallablePackSourceRejectsLegacyActiveScalarFormula(t *testing.T) {
	root := writePackFixture(t, "v1-legacy-formula-pack", validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "issue",
      "manageability": "locked",
      "payload": `+testObjectSpecPayloadWithFields("Issue",
		`{"apiName": "Subject", "label": "Subject", "type": "string", "required": true, "isNameField": true}`,
		`{"apiName": "SubjectEcho", "label": "Subject Echo", "type": "string", "formulaMode": "active", "formula": "Subject", "returnType": "string"}`,
	)+`
    }
  ]`, `"dependencies": [],`))

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	if !report.HasErrors() {
		t.Fatal("ValidateInstallablePackSourceWithOptions accepted legacy active-scalar formula shape; want fail-closed error")
	}
	assertInstallableDiagnostic(t, report, "field.formula.expression_on_non_formula_type")
}

func TestValidateInstallablePackSourceRejectsAggregateFormulaAuthoring(t *testing.T) {
	root := writePackFixture(t, "aggregate-formula-pack", validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "parent",
      "manageability": "locked",
      "payload": `+testObjectSpecPayloadWithFields("Parent__c",
		`{"apiName": "Name", "label": "Name", "type": "string", "required": true, "isNameField": true}`,
		`{"apiName": "Total__c", "label": "Total", "type": "formula", "formulaMode": "active", "formula": "SUM(Child__c.Amount__c)", "returnType": "number"}`,
	)+`
    }
  ]`, `"dependencies": [],`))

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	if !report.HasErrors() {
		t.Fatal("ValidateInstallablePackSourceWithOptions accepted aggregate formula authoring; want fail-closed error")
	}
	assertInstallableDiagnostic(t, report, "field.formula.aggregate_authoring_requires_rollupsummary")
}

func TestValidateInstallablePackSourceRejectsNonCanonicalFormulaStorageMode(t *testing.T) {
	root := writePackFixture(t, "invalid-formula-storage-pack", validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "issue",
      "manageability": "locked",
      "payload": `+testObjectSpecPayloadWithFields("Issue",
		`{"apiName": "Subject", "label": "Subject", "type": "string", "required": true, "isNameField": true}`,
		`{"apiName": "SubjectStored", "label": "Subject Stored", "type": "formula", "formulaMode": "active", "formulaStorageMode": "WRITE_MATERIALIZED", "formula": "TEXT(Subject)", "returnType": "string"}`,
	)+`
    }
  ]`, `"dependencies": [],`))

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	if !report.HasErrors() {
		t.Fatal("ValidateInstallablePackSourceWithOptions accepted non-canonical formulaStorageMode; want fail-closed error")
	}
	assertInstallableDiagnostic(t, report, "field.formula.unknown_formula_storage_mode")
}

func TestValidateInstallablePackSourceRejectsMalformedWriteMaterializedFormula(t *testing.T) {
	root := writePackFixture(t, "invalid-stored-formula-pack", validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "issue",
      "manageability": "locked",
      "payload": `+testObjectSpecPayloadWithFields("Issue",
		`{"apiName": "Subject", "label": "Subject", "type": "string", "required": true, "isNameField": true}`,
		`{"apiName": "SubjectStored", "label": "Subject Stored", "type": "formula", "formulaMode": "active", "formulaStorageMode": "write_materialized", "formula": "TEXT(", "returnType": "string"}`,
	)+`
    }
  ]`, `"dependencies": [],`))

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	if !report.HasErrors() {
		t.Fatal("ValidateInstallablePackSourceWithOptions accepted malformed write_materialized formula; want fail-closed error")
	}
	if !strings.Contains(report.Error(), "pack payload write-materialized-formula verification failed") {
		t.Fatalf("report error = %q, want write-materialized formula verification failure", report.Error())
	}
}

func testFlowFilterFormulaWithBundlePayload() string {
	return `{
  "label":"Probe Flow",
  "processType":"AutoLaunchedFlow",
  "start":{"object":"Issue","filterFormula":"PACK_PREFIX(Name) != \"\""}
}`
}

func TestValidateInstallablePackSourceAcceptsFlowStartFilterFormulaWithBundleFunction(t *testing.T) {
	root := writePackFixture(t, "flow-filter-with-bundle", validPackManifest(`[
    {
      "kind": "standard_flow",
      "businessKey": "IssueFlow",
      "manageability": "defaults_only",
      "payload": `+testFlowFilterFormulaWithBundlePayload()+`
    },
    `+formulaFunctionBundleManifestComponent(testFormulaFunctionBundleComponentPayload())+`,
    {
      "kind": "object_spec",
      "businessKey": "issue",
      "manageability": "locked",
      "payload": `+testObjectSpecPayloadWithFields("Issue",
		`{"apiName": "Name", "label": "Name", "type": "string", "required": true, "isNameField": true}`,
	)+`
    }
  ]`, `"dependencies": [],`))

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	if report.HasErrors() {
		t.Fatalf("ValidateInstallablePackSourceWithOptions rejected known bundle filter formula: %s", report.Error())
	}
}

func TestValidateInstallablePackSourceRejectsFlowStartFilterFormulaWithoutBundleFunction(t *testing.T) {
	root := writePackFixture(t, "flow-filter-missing-bundle", validPackManifest(`[
    {
      "kind": "standard_flow",
      "businessKey": "IssueFlow",
      "manageability": "defaults_only",
      "payload": `+testFlowFilterFormulaWithBundlePayload()+`
    },
    {
      "kind": "object_spec",
      "businessKey": "issue",
      "manageability": "locked",
      "payload": `+testObjectSpecPayloadWithFields("Issue",
		`{"apiName": "Name", "label": "Name", "type": "string", "required": true, "isNameField": true}`,
	)+`
    }
  ]`, `"dependencies": [],`))

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	if !report.HasErrors() {
		t.Fatal("ValidateInstallablePackSourceWithOptions accepted flow filter formula with missing bundle function")
	}
	if !strings.Contains(report.Error(), "flow filter formula") || !strings.Contains(report.Error(), ErrFlowFilterFormulaInvalid.Error()) {
		t.Fatalf("report error = %q, want flow filter formula validation failure", report.Error())
	}
}

func testWriteMaterializedFormulaWithBundlePayload() string {
	return `[
  {
    "apiName": "Issue",
    "label": "Issue",
    "tableType": "standard_object",
    "category": "jira",
    "sharingModel": "Private",
    "enableHierarchySharing": false,
    "description": "Issue work item",
    "fields": [
      {"apiName": "Name", "label": "Name", "type": "string", "required": true, "isNameField": true},
      {"apiName": "ProbeStored", "label": "ProbeStored", "type": "formula", "formulaMode": "active", "formulaStorageMode": "write_materialized", "formula": "PACK_PREFIX(Name)", "returnType": "string"}
    ]
  }
]`
}

func TestValidateInstallablePackSourceAcceptsWriteMaterializedFormulaWithBundleFunction(t *testing.T) {
	root := writePackFixture(t, "write-materialized-with-bundle", validPackManifest(`[
    `+formulaFunctionBundleManifestComponent(testFormulaFunctionBundleComponentPayload())+`,
    {
      "kind": "object_spec",
      "businessKey": "issue",
      "manageability": "locked",
      "payload": `+testWriteMaterializedFormulaWithBundlePayload()+`
    }
  ]`, `"dependencies": [],`))

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	if report.HasErrors() {
		t.Fatalf("ValidateInstallablePackSourceWithOptions rejected known bundle write-materialized formula: %s", report.Error())
	}
}

func TestValidateInstallablePackSourceRejectsWriteMaterializedFormulaWithoutBundleFunction(t *testing.T) {
	root := writePackFixture(t, "write-materialized-missing-bundle", validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "issue",
      "manageability": "locked",
      "payload": `+testWriteMaterializedFormulaWithBundlePayload()+`
    }
  ]`, `"dependencies": [],`))

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	if !report.HasErrors() {
		t.Fatal("ValidateInstallablePackSourceWithOptions accepted write-materialized formula with missing bundle function")
	}
	if !strings.Contains(report.Error(), "pack payload write-materialized-formula verification failed") {
		t.Fatalf("report error = %q, want write-materialized-formula verification failure", report.Error())
	}
}

func testObjectSpecPayloadWithBundleWriteFormulaAndLockRule() string {
	return `[
  {
    "apiName": "Issue",
    "label": "Issue",
    "tableType": "standard_object",
    "category": "jira",
    "sharingModel": "Private",
    "enableHierarchySharing": false,
    "description": "Issue work item",
    "lockRule": "PACK_PREFIX(Name) != \"\"",
    "fields": [
      {"apiName": "Name", "label": "Name", "type": "string", "required": true, "isNameField": true},
      {"apiName": "ProbeStored", "label": "ProbeStored", "type": "formula", "formulaMode": "active", "formulaStorageMode": "write_materialized", "formula": "PACK_PREFIX(Name)", "returnType": "string"}
    ]
  }
]`
}

func TestValidateInstallablePackSourceWithRuntimeFormulaFunctionBundlesAcceptsExternalFormulaConsumers(t *testing.T) {
	root := writePackFixture(t, "external-bundle-formula-consumers", validPackManifest(`[
    {
      "kind": "standard_flow",
      "businessKey": "IssueFlow",
      "manageability": "defaults_only",
      "payload": `+testFlowFilterFormulaWithBundlePayload()+`
    },
    {
      "kind": "object_spec",
      "businessKey": "issue",
      "manageability": "locked",
      "payload": `+testObjectSpecPayloadWithBundleWriteFormulaAndLockRule()+`
    }
  ]`, `"dependencies": [],`))

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	if !report.HasErrors() {
		t.Fatal("ValidateInstallablePackSourceWithOptions accepted external function consumers without active bundle")
	}

	bundle, err := formula.ParseFunctionBundlePayload([]byte(testFormulaFunctionBundleComponentPayload()))
	if err != nil {
		t.Fatalf("parse test formula function bundle: %v", err)
	}
	report = ValidateInstallablePackSourceWithRuntimeFormulaFunctionBundles(
		"local_path:"+root,
		testPackSourceOptions(t),
		[]formula.FunctionBundle{bundle},
	)
	if report.HasErrors() {
		t.Fatalf("ValidateInstallablePackSourceWithRuntimeFormulaFunctionBundles rejected external function consumers: %s", report.Error())
	}
}

func TestValidateInstallablePackSourceWithRuntimeFormulaFunctionBundlesIgnoresAlreadyActiveRuntimeCopy(t *testing.T) {
	if err := formula.RegisterRuntimeFunctionBundles(nil); err != nil {
		t.Fatalf("clear runtime formula bundles before test: %v", err)
	}
	t.Cleanup(func() {
		_ = formula.RegisterRuntimeFunctionBundles(nil)
	})

	root := writePackFixture(t, "external-bundle-formula-consumers-active-runtime", validPackManifest(`[
    {
      "kind": "standard_flow",
      "businessKey": "IssueFlow",
      "manageability": "defaults_only",
      "payload": `+testFlowFilterFormulaWithBundlePayload()+`
    },
    {
      "kind": "object_spec",
      "businessKey": "issue",
      "manageability": "locked",
      "payload": `+testObjectSpecPayloadWithBundleWriteFormulaAndLockRule()+`
    }
  ]`, `"dependencies": [],`))
	bundle, err := formula.ParseFunctionBundlePayload([]byte(testFormulaFunctionBundleComponentPayload()))
	if err != nil {
		t.Fatalf("parse test formula function bundle: %v", err)
	}
	if err := formula.RegisterRuntimeFunctionBundles([]formula.FunctionBundle{bundle}); err != nil {
		t.Fatalf("RegisterRuntimeFunctionBundles: %v", err)
	}

	report := ValidateInstallablePackSourceWithRuntimeFormulaFunctionBundles(
		"local_path:"+root,
		testPackSourceOptions(t),
		[]formula.FunctionBundle{bundle},
	)
	if report.HasErrors() {
		t.Fatalf("ValidateInstallablePackSourceWithRuntimeFormulaFunctionBundles with active runtime copy rejected external function consumers: %s", report.Error())
	}
}

func TestValidateInstallablePackSourceRejectsUnsupportedReadSourceAuthoring(t *testing.T) {
	root := writePackFixture(t, "readsource-pack", validPackManifest(`[
    {
      "kind": "object_spec",
      "businessKey": "recordtype",
      "manageability": "locked",
      "payload": [{
        "apiName": "RecordType",
        "label": "RecordType",
        "tableType": "standard_object",
        "category": "system",
        "sharingModel": "PublicRead",
        "readSource": {
          "kind": "physical_table",
          "physicalTable": "_System_RecordType"
        }
      }]
    }
  ]`, `"dependencies": [],`))

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	if !report.HasErrors() {
		t.Fatal("ValidateInstallablePackSourceWithOptions accepted unsupported readSource authoring; want fail-closed diagnostic")
	}
	assertInstallableDiagnostic(t, report, "component.object_spec.invalid_read_source")
}

// TestValidateInstallablePackSourceV2ManifestRejectsLegacyActiveScalarFormula
// verifies the strict enforcement path: a pack with manifestFormatVersion "2"
// must not declare fields using the pre-957 shape (type != formula,
// formulaMode == "active").  The validator must return an error so that pack
// authors receive an immediate signal at validate-pack time.
func TestValidateInstallablePackSourceV2ManifestRejectsLegacyActiveScalarFormula(t *testing.T) {
	root := writePackFixture(t, "v2-strict-formula-pack", validPackManifestV2(`[
    {
      "kind": "object_spec",
      "businessKey": "issue",
      "manageability": "locked",
      "payload": `+testObjectSpecPayloadWithFields("Issue",
		`{"apiName": "Subject", "label": "Subject", "type": "string", "required": true, "isNameField": true}`,
		`{"apiName": "SubjectEcho", "label": "Subject Echo", "type": "string", "formulaMode": "active", "formula": "Subject", "returnType": "string"}`,
	)+`
    }
  ]`, `"dependencies": [],`))

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	if !report.HasErrors() {
		t.Fatal("ValidateInstallablePackSourceWithOptions = nil errors, want error (v2 manifest must reject pre-957 legacy active-scalar formula shape)")
	}
}

func testPackSourceOptions(t *testing.T) PackSourceOptions {
	t.Helper()
	opts := DefaultPackSourceOptions()
	opts.OfficialRepoRoot = filepath.Join(t.TempDir(), "packs")
	return opts
}

func officialCRMPackSourceOptionsForTest(t *testing.T) PackSourceOptions {
	t.Helper()
	opts := DefaultPackSourceOptions()
	opts.OfficialRepoRoot = officialPackRootFromThisFile(t)
	opts.FlowActionCallHandlerImplementations = append(opts.FlowActionCallHandlerImplementations, testCRMFlowActionCallHandlerImplementations()...)
	return opts
}

func officialCRMSourceBackedPackOptionsForTest(t *testing.T, opts PackSourceOptions) []SourceBackedPackOption {
	t.Helper()
	return []SourceBackedPackOption{
		withFlowActionCallHandlerImplementations(opts.FlowActionCallHandlerImplementations),
		WithComponentKindRegistrationSet(crmPermissionRegistrationSetForTest(t)),
	}
}

func validPackManifestV2(componentsJSON string, extraFields string) string {
	return `{
  "manifestFormatVersion": "2",
  "name": "jira-like-sample",
  "displayName": "Jira-Like Sample",
  "category": "app-pack",
  "version": "0.1.0",
  "platformCompatibility": {"min": "0.2.0", "maxExclusive": "0.3.0"},
  ` + extraFields + `
  "components": ` + componentsJSON + `
}`
}

func validPackManifest(componentsJSON string, extraFields string) string {
	return `{
  "manifestFormatVersion": "1",
  "name": "jira-like-sample",
  "displayName": "Jira-Like Sample",
  "category": "app-pack",
  "version": "0.1.0",
  "platformCompatibility": {"min": "0.2.0", "maxExclusive": "0.3.0"},
  ` + extraFields + `
  "components": ` + componentsJSON + `
}`
}

func writePackFixture(t *testing.T, name string, manifest string) string {
	t.Helper()
	root := filepath.Join(t.TempDir(), name)
	writeManifest(t, root, manifest)
	return root
}

func writeManifest(t *testing.T, root string, manifest string) {
	t.Helper()
	if err := os.MkdirAll(root, 0o755); err != nil {
		t.Fatalf("mkdir pack root: %v", err)
	}
	if err := os.WriteFile(filepath.Join(root, "pack.json"), []byte(manifest), 0o644); err != nil {
		t.Fatalf("write pack manifest: %v", err)
	}
}

func writeFile(t *testing.T, root, rel, body string) {
	t.Helper()
	full := filepath.Join(root, filepath.FromSlash(rel))
	if err := os.MkdirAll(filepath.Dir(full), 0o755); err != nil {
		t.Fatalf("mkdir %s: %v", rel, err)
	}
	if err := os.WriteFile(full, []byte(body), 0o644); err != nil {
		t.Fatalf("write %s: %v", rel, err)
	}
}

func assertDiagnostic(t *testing.T, report PackValidationReport, code string) {
	t.Helper()
	for _, diagnostic := range report.Diagnostics {
		if diagnostic.Code == code {
			return
		}
	}
	var got []string
	for _, diagnostic := range report.Diagnostics {
		got = append(got, diagnostic.String())
	}
	t.Fatalf("missing diagnostic %s; got:\n%s", code, strings.Join(got, "\n"))
}

func assertInstallableDiagnostic(t *testing.T, report InstallablePackSourceReport, code string) {
	t.Helper()
	for _, diagnostic := range report.Diagnostics {
		if diagnostic.Code == code {
			return
		}
	}
	var got []string
	for _, diagnostic := range report.Diagnostics {
		got = append(got, diagnostic.String())
	}
	t.Fatalf("missing diagnostic %s; got:\n%s", code, strings.Join(got, "\n"))
}

// TestSourceBackedManifestValidationAcceptsConnectorPackCategory was added by
// PR #1509 and proves connector-pack manifests pass WT2 validate-pack
// (manifest-level Category check). Wave 1 (this PR) consumes that gate.
func TestSourceBackedManifestValidationAcceptsConnectorPackCategory(t *testing.T) {
	manifest := `{
  "manifestFormatVersion": "1",
  "name": "test-connector",
  "displayName": "Test Connector",
  "category": "connector-pack",
  "version": "0.1.0",
  "platformCompatibility": {"min": "0.2.0", "maxExclusive": "0.3.0"},
  "dependencies": [],
  "components": [{
    "kind": "object_spec",
    "businessKey": "object-spec:test-connector",
    "manageability": "locked",
    "path": "objects/spec.json"
  }]
}`
	root := writePackFixture(t, "test-connector", manifest)
	writeFile(t, root, "objects/spec.json", `[{"apiName":"NcrmConnectorConfig","label":"Connector Config","tableType":"standard_object","category":"connector","sharingModel":"Private","enableHierarchySharing":false,"description":"Connector configuration","fields":[{"apiName":"Name","label":"Name","type":"string","required":true,"isNameField":true}]}]`)
	report := ValidatePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	for _, d := range report.Diagnostics {
		if d.Code == "manifest.category.unsupported" {
			t.Fatalf("ValidatePackSourceWithOptions produced manifest.category.unsupported for connector-pack category; want no such diagnostic. Got: %s", d.String())
		}
	}
}

// validConnectorPackManifest returns a well-formed ConnectorPack manifest JSON
// that can be written to a temp directory for validation tests.
func validConnectorPackManifest(packName, componentsJSON string) string {
	return `{
  "manifestFormatVersion": "1",
  "name": "` + packName + `",
  "displayName": "Test Connector Pack",
  "category": "connector-pack",
  "version": "0.1.0",
  "platformCompatibility": {"min": "0.2.0", "maxExclusive": "0.3.0"},
  "dependencies": [],
  "components": ` + componentsJSON + `
}`
}

func connectorCapabilityPayloadJSON(namespace, kind string) string {
	return `{"namespace":"` + namespace + `","kind":"` + kind + `"}`
}

func connectorHandlerConfigComponentJSON(namespace, kind, config string) string {
	return `{"kind":"connector_inbound_handler_config","businessKey":"` + namespace + `:` + kind + `","manageability":"locked","payload":{"namespace":"` + namespace + `","capabilityKind":"` + kind + `","config":` + config + `}}`
}

func validHandlerConfigEnvelopeJSON() string {
	return `{
  "eventArrayPath":".events",
  "rules":[{
    "eventTypeLiteral":"thing.updated",
    "namespaceFromCtx":true,
    "objectKind":"thing",
    "sourceIdPath":".objectId",
    "idempotencyKeyPath":".eventId",
    "payloadProjection":[{"name":"objectId","path":".objectId"}]
  }]
	}`
}

func validHandlerEndpointConfigSignatureJSON() string {
	return `{
  "endpointConfigs":{
    "a":{
      "scheme":"hmac-sha256-template",
      "signingTemplate":"{Timestamp}.{RawBody}",
      "timestampHeader":"X-A-Timestamp",
      "signatureHeader":"X-A-Signature",
      "signatureEncoding":"hex",
      "skewWindow":"5m"
    },
    "b":{
      "scheme":"hmac-sha256-template",
      "signingTemplate":"{Timestamp}:{RawBody}",
      "timestampHeader":"X-B-Timestamp",
      "signatureHeader":"X-B-Signature",
      "signatureEncoding":"hex",
      "skewWindow":"5m"
    }
  }
}`
}

func validHandlerEndpointConfigEnvelopeJSON() string {
	return `{
  "endpointConfigs":{
    "a":` + validHandlerConfigEnvelopeJSON() + `,
    "b":` + validHandlerConfigEnvelopeJSON() + `
  }
}`
}

func conflictingHandlerEndpointConfigEnvelopeJSON() string {
	return `{
  "endpointConfigs":{
    "a":{
      "eventArrayPath":".events",
      "inboundProcessingMode":"payload_only_allowed",
      "rules":[{
        "eventTypeLiteral":"thing.updated",
        "namespaceFromCtx":true,
        "objectKind":"thing",
        "sourceIdPath":".objectId",
        "idempotencyKeyPath":".eventId"
      }]
    },
    "b":{
      "eventArrayPath":".events",
      "inboundProcessingMode":"enrichment_required",
      "rules":[{
        "eventTypeLiteral":"thing.updated",
        "namespaceFromCtx":true,
        "objectKind":"thing",
        "sourceIdPath":".objectId",
        "idempotencyKeyPath":".eventId"
      }]
    }
  }
}`
}

// --- per-Category allowlist tests ---

func TestValidateInstallablePackSourceAcceptsConnectorCapabilityInConnectorPack(t *testing.T) {
	packName := "test-connector"
	root := writePackFixture(t, packName, validConnectorPackManifest(packName, `[
    {
      "kind": "connector_capability",
      "businessKey": "test-connector:signature_verifier",
      "manageability": "locked",
      "payload": `+jsonRawMessage(connectorCapabilityPayloadJSON(packName, "signature_verifier"))+`
    }
  ]`))
	_ = root
	report := ValidatePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	for _, d := range report.Diagnostics {
		if d.Code == "manifest.component.unsupported_for_category" {
			t.Fatalf("connector_capability should be allowed in ConnectorPack but got: %s", d.String())
		}
	}
}

func TestAllowedComponentKindsByCategory_RejectsObjectSpecInConnectorPack(t *testing.T) {
	packName := "test-connector"
	root := writePackFixture(t, packName, validConnectorPackManifest(packName, `[
    {
      "kind": "object_spec",
      "businessKey": "object-spec:test-connector",
      "manageability": "locked",
      "path": "objects/spec.json"
    }
  ]`))
	writeFile(t, root, "objects/spec.json", `[{"apiName":"Issue"}]`)
	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	assertInstallableDiagnostic(t, report, "manifest.component.unsupported_for_category")
}

// TestAllowedComponentKindsByCategory_AllowsWebhookSecretInConnectorPack pins
// the coexistence of NCRM-INT-04A (connector_capability) and NCRM-INT-03 /
// PR #1499 (webhook_secret) inside a connector-pack manifest. Codex Review
// round-7 BLOCK called out that an earlier connector-pack allowlist of only
// connector_capability would have stranded the existing webhook_secret
// surface — already-installed connector packs whose manifests declare
// webhook_secret would have failed verify/reapply. With both kinds in the
// allowlist (via connectorPackOnlyKinds()), the validator no longer emits
// manifest.component.unsupported_for_category for webhook_secret.
func TestAllowedComponentKindsByCategory_AllowsWebhookSecretInConnectorPack(t *testing.T) {
	packName := "test-connector"
	root := writePackFixture(t, packName, validConnectorPackManifest(packName, `[
    {
      "kind": "webhook_secret",
      "businessKey": "test-connector/webhook-secret",
      "manageability": "locked",
      "payload": {"name":"webhook-secret","algorithm":"hmac-sha256"}
    }
  ]`))
	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	for _, d := range report.Diagnostics {
		if d.Code == "manifest.component.unsupported_for_category" {
			t.Fatalf("webhook_secret should be allowed in ConnectorPack but got: %s", d.String())
		}
	}
}

// TestValidateConnectorWebhookCapabilityPair pins the source-validator rule that
// a connector pack declaring a webhook_secret must also declare BOTH
// signature_verifier and envelope_parser connector capabilities (the inbound
// webhook dispatcher #338 needs the full pair to process a delivery). The rule
// lives in the shared source validator so validate-pack / install / verify /
// startup all agree. It does not constrain the number of named webhook secrets
// (multiple named endpoints per pack are supported; handler configs can either
// be shared per capability or use endpointConfigs keyed by webhook_secret Name),
// and it does not trigger for packs without a webhook_secret.
//
// A direct call with isInstalledRow=true still enforces the pair because runtime
// legacy fallback also requires connector_capability declarations.
func TestValidateConnectorWebhookCapabilityPair(t *testing.T) {
	const pack = "test-connector"
	const code = "connector_pack.webhook_secret.incomplete_capability_pair"
	sigCap := `{"kind":"connector_capability","businessKey":"test-connector:signature_verifier","manageability":"locked","payload":` + connectorCapabilityPayloadJSON(pack, "signature_verifier") + `}`
	parCap := `{"kind":"connector_capability","businessKey":"test-connector:envelope_parser","manageability":"locked","payload":` + connectorCapabilityPayloadJSON(pack, "envelope_parser") + `}`
	secret := func(name string) string {
		return `{"kind":"webhook_secret","businessKey":"test-connector/` + name + `","manageability":"locked","payload":{"name":"` + name + `","algorithm":"hmac-sha256"}}`
	}

	cases := []struct {
		name       string
		components []string
		wantDiag   bool
	}{
		{"secret_plus_both_caps", []string{secret("s"), sigCap, parCap}, false},
		{"secret_only_signature_verifier", []string{secret("s"), sigCap}, true},
		{"secret_only_envelope_parser", []string{secret("s"), parCap}, true},
		{"secret_zero_caps", []string{secret("s")}, true},
		// Two webhook_secret components: multi-endpoint authoring is allowed;
		// this specific rule only requires both capabilities to be present.
		{"two_secrets_plus_both_caps", []string{secret("a"), secret("b"), sigCap, parCap}, false},
		{"caps_only_no_secret_ok", []string{sigCap, parCap}, false},
		{"single_cap_no_secret_ok", []string{sigCap}, false},
	}
	for _, tc := range cases {
		t.Run(tc.name, func(t *testing.T) {
			root := writePackFixture(t, pack, validConnectorPackManifest(pack, "[\n"+strings.Join(tc.components, ",\n")+"\n]"))
			report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
			foundPair := false
			for _, d := range report.Diagnostics {
				if d.Code == code {
					foundPair = true
				}
			}
			if foundPair != tc.wantDiag {
				t.Fatalf("diagnostic %q present=%v, want %v; diagnostics=%v", code, foundPair, tc.wantDiag, report.Diagnostics)
			}
		})
	}

	// Direct-call compat gate: isInstalledRow=true still enforces the
	// capability-pair rule because runtime dispatch has no no-declaration
	// fallback path.
	t.Run("compat_gate_still_enforces_pair_rule", func(t *testing.T) {
		// Build a source with two secrets and no capabilities — would normally
		// produce incomplete_capability_pair.
		root := writePackFixture(t, pack, validConnectorPackManifest(pack, "[\n"+secret("a")+",\n"+secret("b")+"\n]"))
		sourceReport := ValidatePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
		if sourceReport.Source == nil {
			t.Fatalf("expected valid source; got nil; diagnostics=%v", sourceReport.Diagnostics)
		}
		for _, allowInstalledRowCompat := range []bool{true, false} {
			got := validateConnectorWebhookCapabilityPair(sourceReport.Source, allowInstalledRowCompat)
			foundPair := false
			for _, d := range got {
				if d.Code == code {
					foundPair = true
				}
			}
			if !foundPair {
				t.Fatalf("allowInstalledRowCompat=%v: expected %q diagnostic, got %v", allowInstalledRowCompat, code, got)
			}
		}
	})
}

func TestValidateInstallablePackSourceRejectsConnectorCapabilityWithoutHandlerConfig(t *testing.T) {
	const pack = "test-connector"
	root := writePackFixture(t, pack, validConnectorPackManifest(pack, `[
    {
      "kind":"connector_capability",
      "businessKey":"test-connector:signature_verifier",
      "manageability":"locked",
      "payload":`+connectorCapabilityPayloadJSON(pack, "signature_verifier")+`
    }
  ]`))

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	assertInstallableDiagnostic(t, report, "connector_capability.handler_config.missing")
}

func TestValidateInstallablePackSourceRejectsConnectorHandlerConfigWithoutCapability(t *testing.T) {
	const pack = "test-connector"
	root := writePackFixture(t, pack, validConnectorPackManifest(pack, `[
    {
      "kind":"connector_inbound_handler_config",
      "businessKey":"test-connector:signature_verifier",
      "manageability":"locked",
      "payload":{
        "namespace":"test-connector",
        "capabilityKind":"signature_verifier",
        "config":`+validHandlerConfigSignatureJSON()+`
      }
    }
  ]`))

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	assertInstallableDiagnostic(t, report, "connector_inbound_handler_config.capability.missing")
}

func TestValidateInstallablePackSourceAcceptsConnectorCapabilityHandlerPair(t *testing.T) {
	const pack = "test-connector"
	root := writePackFixture(t, pack, validConnectorPackManifest(pack, `[
    {
      "kind":"connector_capability",
      "businessKey":"test-connector:signature_verifier",
      "manageability":"locked",
      "payload":`+connectorCapabilityPayloadJSON(pack, "signature_verifier")+`
    },
    {
      "kind":"connector_inbound_handler_config",
      "businessKey":"test-connector:signature_verifier",
      "manageability":"locked",
      "payload":{
        "namespace":"test-connector",
        "capabilityKind":"signature_verifier",
        "config":`+validHandlerConfigSignatureJSON()+`
      }
    }
  ]`))

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	for _, d := range report.Diagnostics {
		if d.Code == "connector_capability.handler_config.missing" || d.Code == "connector_inbound_handler_config.capability.missing" {
			t.Fatalf("unexpected pairing diagnostic for valid connector capability/handler config pair: %s", d.String())
		}
	}
}

func TestValidateInstallablePackSourceAcceptsRequestURLSigningToken(t *testing.T) {
	const pack = "test-connector"
	requestURLConfig := `{
  "scheme":"hmac-sha256-template",
  "signingTemplate":"{Method}\n{RequestURL}\n{RawBody}\n{Timestamp}",
  "timestampHeader":"X-Test-Timestamp",
  "signatureHeader":"X-Test-Signature",
  "signatureEncoding":"hex",
  "skewWindow":"5m",
  "secretName":"default"
}`
	root := writePackFixture(t, pack, validConnectorPackManifest(pack, `[
    {
      "kind":"connector_capability",
      "businessKey":"test-connector:signature_verifier",
      "manageability":"locked",
      "payload":`+connectorCapabilityPayloadJSON(pack, "signature_verifier")+`
    },
    {
      "kind":"connector_inbound_handler_config",
      "businessKey":"test-connector:signature_verifier",
      "manageability":"locked",
      "payload":{
        "namespace":"test-connector",
        "capabilityKind":"signature_verifier",
        "config":`+requestURLConfig+`
      }
    }
  ]`))

	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	if report.HasErrors() {
		t.Fatalf("RequestURL signing-template token should validate cleanly in source-pack path, got:\n%s", report.Error())
	}
}

func TestValidateConnectorCapabilityHandlerConfigPair_InstalledRowCompatRequiresLegacyHandlerRegistration(t *testing.T) {
	const pack = "legacy-compiled-handler-connector"
	t.Cleanup(func() {
		connectorcapabilities.UnregisterCapability(pack, connectorcapabilities.SignatureVerifier)
	})
	root := writePackFixture(t, pack, validConnectorPackManifest(pack, `[
    {
      "kind":"connector_capability",
      "businessKey":"legacy-compiled-handler-connector:signature_verifier",
      "manageability":"locked",
      "payload":`+connectorCapabilityPayloadJSON(pack, "signature_verifier")+`
    }
  ]`))
	sourceReport := ValidatePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	if sourceReport.Source == nil {
		t.Fatalf("expected valid source; diagnostics=%v", sourceReport.Diagnostics)
	}

	if got := validateConnectorCapabilityHandlerConfigPair(sourceReport.Source, true); len(got) == 0 {
		t.Fatal("installed-row compat returned no diagnostics without legacy compiled handler, want missing handler config")
	}

	if err := connectorcapabilities.RegisterCapability(pack, connectorcapabilities.SignatureVerifier, packSourceLegacyVerifier{}); err != nil {
		t.Fatalf("register legacy compiled handler: %v", err)
	}
	if got := validateConnectorCapabilityHandlerConfigPair(sourceReport.Source, true); len(got) != 0 {
		t.Fatalf("installed-row compat returned diagnostics with legacy compiled handler: %v", got)
	}
}

func TestValidateInstallablePackSourceRejectsConnectorHandlerSemanticConfig(t *testing.T) {
	const pack = "test-connector"
	root := writePackFixture(t, pack, validConnectorPackManifest(pack, `[
    {
      "kind":"connector_capability",
      "businessKey":"test-connector:signature_verifier",
      "manageability":"locked",
      "payload":`+connectorCapabilityPayloadJSON(pack, "signature_verifier")+`
    },
    {
      "kind":"connector_inbound_handler_config",
      "businessKey":"test-connector:signature_verifier",
      "manageability":"locked",
      "payload":{
        "namespace":"test-connector",
        "capabilityKind":"signature_verifier",
        "config":{
          "scheme":"hmac-sha256-template",
          "signingTemplate":"{Timestamp}.{RawBody}",
          "timestampHeader":"X-Test-Signature",
          "signatureHeader":"X-Test-Signature",
          "signatureEncoding":"hex",
          "skewWindow":"5m",
          "secretName":"default"
        }
      }
    }
  ]`))
	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	assertInstallableDiagnostic(t, report, "connector_inbound_handler_config.config.invalid")
}

func TestValidateInstallablePackSourceAcceptsEndpointSpecificConnectorHandlerConfigs(t *testing.T) {
	const pack = "test-connector"
	secret := func(name string) string {
		return `{"kind":"webhook_secret","businessKey":"test-connector/` + name + `","manageability":"locked","payload":{"name":"` + name + `","algorithm":"hmac-sha256"}}`
	}
	root := writePackFixture(t, pack, validConnectorPackManifest(pack, `[
    `+secret("a")+`,
    `+secret("b")+`,
    {
      "kind":"connector_capability",
      "businessKey":"test-connector:signature_verifier",
      "manageability":"locked",
      "payload":`+connectorCapabilityPayloadJSON(pack, "signature_verifier")+`
    },
    {
      "kind":"connector_capability",
      "businessKey":"test-connector:envelope_parser",
      "manageability":"locked",
      "payload":`+connectorCapabilityPayloadJSON(pack, "envelope_parser")+`
    },
    `+connectorHandlerConfigComponentJSON(pack, "signature_verifier", validHandlerEndpointConfigSignatureJSON())+`,
    `+connectorHandlerConfigComponentJSON(pack, "envelope_parser", validHandlerEndpointConfigEnvelopeJSON())+`
  ]`))
	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	if report.HasErrors() {
		t.Fatalf("endpoint-specific connector handler configs should validate cleanly, got:\n%s", report.Error())
	}
}

func TestValidateInstallablePackSourceRejectsEndpointEnvelopeConfigWithConflictingInboundProcessingMode(t *testing.T) {
	const pack = "test-connector"
	secret := func(name string) string {
		return `{"kind":"webhook_secret","businessKey":"test-connector/` + name + `","manageability":"locked","payload":{"name":"` + name + `","algorithm":"hmac-sha256"}}`
	}
	root := writePackFixture(t, pack, validConnectorPackManifest(pack, `[
    `+secret("a")+`,
    `+secret("b")+`,
    {
      "kind":"connector_capability",
      "businessKey":"test-connector:envelope_parser",
      "manageability":"locked",
      "payload":`+connectorCapabilityPayloadJSON(pack, "envelope_parser")+`
    },
    `+connectorHandlerConfigComponentJSON(pack, "envelope_parser", conflictingHandlerEndpointConfigEnvelopeJSON())+`
  ]`))
	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	assertInstallableDiagnostic(t, report, "connector_inbound_handler_config.config.invalid")
}

func TestValidateInstallablePackSourceRejectsEndpointHandlerConfigMissingDeclaredSecret(t *testing.T) {
	const pack = "test-connector"
	root := writePackFixture(t, pack, validConnectorPackManifest(pack, `[
    {"kind":"webhook_secret","businessKey":"test-connector/a","manageability":"locked","payload":{"name":"a","algorithm":"hmac-sha256"}},
    {"kind":"webhook_secret","businessKey":"test-connector/b","manageability":"locked","payload":{"name":"b","algorithm":"hmac-sha256"}},
    {
      "kind":"connector_capability",
      "businessKey":"test-connector:signature_verifier",
      "manageability":"locked",
      "payload":`+connectorCapabilityPayloadJSON(pack, "signature_verifier")+`
    },
    `+connectorHandlerConfigComponentJSON(pack, "signature_verifier", `{
      "endpointConfigs":{
        "a":{
          "scheme":"hmac-sha256-template",
          "signingTemplate":"{Timestamp}.{RawBody}",
          "timestampHeader":"X-A-Timestamp",
          "signatureHeader":"X-A-Signature",
          "signatureEncoding":"hex",
          "skewWindow":"5m"
        }
      }
    }`)+`
  ]`))
	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	assertInstallableDiagnostic(t, report, "connector_inbound_handler_config.endpoint.missing")
}

func TestValidateInstallablePackSourceRejectsEndpointHandlerConfigForUndeclaredSecret(t *testing.T) {
	const pack = "test-connector"
	root := writePackFixture(t, pack, validConnectorPackManifest(pack, `[
    {"kind":"webhook_secret","businessKey":"test-connector/a","manageability":"locked","payload":{"name":"a","algorithm":"hmac-sha256"}},
    {
      "kind":"connector_capability",
      "businessKey":"test-connector:signature_verifier",
      "manageability":"locked",
      "payload":`+connectorCapabilityPayloadJSON(pack, "signature_verifier")+`
    },
    `+connectorHandlerConfigComponentJSON(pack, "signature_verifier", `{
      "endpointConfigs":{
        "a":{
          "scheme":"hmac-sha256-template",
          "signingTemplate":"{Timestamp}.{RawBody}",
          "timestampHeader":"X-A-Timestamp",
          "signatureHeader":"X-A-Signature",
          "signatureEncoding":"hex",
          "skewWindow":"5m"
        },
        "ghost":{
          "scheme":"hmac-sha256-template",
          "signingTemplate":"{Timestamp}.{RawBody}",
          "timestampHeader":"X-Ghost-Timestamp",
          "signatureHeader":"X-Ghost-Signature",
          "signatureEncoding":"hex",
          "skewWindow":"5m"
        }
      }
    }`)+`
  ]`))
	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	assertInstallableDiagnostic(t, report, "connector_inbound_handler_config.endpoint.undeclared_webhook_secret")
}

// --- connector_capability payload validation tests ---

func TestValidateConnectorCapabilityComponent(t *testing.T) {
	const pack = "test-connector"
	cases := []struct {
		name        string
		businessKey string
		payload     string
		wantCode    string // "" = expect no connector_capability.* diagnostics
	}{
		{"missing_namespace", "test-connector:signature_verifier", `{"kind":"signature_verifier"}`, "connector_capability.namespace.missing"},
		{"missing_kind", "test-connector:signature_verifier", `{"namespace":"test-connector"}`, "connector_capability.kind.missing"},
		{"unsupported_kind", "test-connector:unknown_cap", connectorCapabilityPayloadJSON(pack, "unknown_cap"), "connector_capability.kind.unsupported"},
		{"namespace_mismatch", "other-connector:signature_verifier", connectorCapabilityPayloadJSON("other-connector", "signature_verifier"), "connector_capability.namespace.mismatch_pack_name"},
		{"valid_envelope_parser", "test-connector:envelope_parser", connectorCapabilityPayloadJSON(pack, "envelope_parser"), ""},
		{"business_key_mismatch_payload", "test-connector:sig", connectorCapabilityPayloadJSON(pack, "signature_verifier"), "connector_capability.business_key.mismatch_payload"},
		// business_key empty is caught upstream by component.business_key.missing
		// (generic component validator). Not re-tested here.
	}
	for _, tc := range cases {
		t.Run(tc.name, func(t *testing.T) {
			components := []string{`{"kind":"connector_capability","businessKey":"` + tc.businessKey + `","manageability":"locked","payload":` + tc.payload + `}`}
			if tc.wantCode == "" {
				components = append(components, connectorHandlerConfigComponentJSON(pack, "envelope_parser", validHandlerConfigEnvelopeJSON()))
			}
			root := writePackFixture(t, pack, validConnectorPackManifest(pack, "[\n"+strings.Join(components, ",\n")+"\n]"))
			report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
			if tc.wantCode != "" {
				assertInstallableDiagnostic(t, report, tc.wantCode)
				return
			}
			for _, d := range report.Diagnostics {
				if strings.HasPrefix(d.Code, "connector_capability.") {
					t.Fatalf("unexpected diagnostic: %s", d.String())
				}
			}
		})
	}
}

// TestValidateConnectorCapabilityComponent_DuplicatePayloadDifferentBusinessKey
// pins the specific malformed-pack scenario Codex Review round-5 BLOCK called
// out: two connector_capability components with DIFFERENT manifest businessKeys
// but the SAME (namespace, kind) payload. Without enforcing
// businessKey == namespace:kind, the manifest-layer dedupe (which keys off
// BusinessKey) would let both pass while the install/verify layer (which keys
// off payload-derived identity via connectorCapabilityComponent.BusinessKey())
// would collapse them to one declaration row. With the canonical-businessKey
// gate, the second component fails validation.
func TestValidateConnectorCapabilityComponent_DuplicatePayloadDifferentBusinessKey(t *testing.T) {
	const pack = "test-connector"
	root := writePackFixture(t, pack, validConnectorPackManifest(pack, `[
    {"kind":"connector_capability","businessKey":"test-connector:signature_verifier","manageability":"locked","payload":`+connectorCapabilityPayloadJSON(pack, "signature_verifier")+`},
    {"kind":"connector_capability","businessKey":"alt:sig","manageability":"locked","payload":`+connectorCapabilityPayloadJSON(pack, "signature_verifier")+`}
  ]`))
	report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
	assertInstallableDiagnostic(t, report, "connector_capability.business_key.mismatch_payload")
}

// TestValidateInstallablePackSource_RejectsCaseVariantConnectorCalloutProfile
// pins the source-validator rule that two connector_callout_profile components
// whose (packName, profileName) tuple is identical after case-normalization
// (strings.ToLower + TrimSpace) must be rejected before any DB writes.
//
// Without this gate a manifest declaring both "Acme-Connector/Default" and
// "acme-connector/default" would pass ValidateInstallablePackSource, upsert the
// same (OwnerPack, ProfileName) _System_ConnectorCalloutProfile row twice, fail
// at final install verify, and leave a live orphan row that strands subsequent
// install/reapply (owner-surface preflight rejects non-active rows).
func TestValidateInstallablePackSource_RejectsCaseVariantConnectorCalloutProfile(t *testing.T) {
	const pack = "acme-connector"
	const code = "connector_callout_profile.duplicate_after_canonicalization"

	// Helper: build a minimal connector_callout_profile component JSON.
	// rawBK is the manifest businessKey as declared (may differ in case from the
	// canonical form); the validator must catch case-variant duplicates even when
	// the two businessKeys differ in casing so the generic identity-key check
	// (which is case-sensitive) does not catch them first.
	profileComponent := func(rawBK, profileName, endpointClass string) string {
		return `{
  "kind":"connector_callout_profile",
  "businessKey":"` + rawBK + `",
  "manageability":"locked",
  "payload":{
    "profileName":"` + profileName + `",
    "credentialRef":"test-nc",
    "endpointClass":"` + endpointClass + `",
    "retryPolicy":{"maxAttempts":3,"baseDelay":100000000,"multiplier":1.5,"maxDelay":5000000000}
  }
}`
	}

	t.Run("case_variant_duplicates_rejected", func(t *testing.T) {
		// Component A: businessKey="acme-connector/Default", profileName="Default" → endpointClass=accounts.
		// Component B: businessKey="acme-connector/default", profileName="default" → endpointClass=contacts.
		// The generic identity-key check is case-sensitive so it does NOT catch these
		// two different businessKeys. After payload canonicalization both map to
		// ("acme-connector", "default") → our new validator must reject the manifest.
		compA := profileComponent(pack+"/Default", "Default", "accounts")
		compB := profileComponent(pack+"/default", "default", "contacts")
		root := writePackFixture(t, pack, validConnectorPackManifest(pack, "[\n"+compA+",\n"+compB+"\n]"))
		report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
		found := false
		for _, d := range report.Diagnostics {
			if d.Code == code {
				found = true
			}
		}
		if !found {
			t.Fatalf("expected diagnostic %q for case-variant duplicate profiles, got: %v", code, report.Diagnostics)
		}
	})

	t.Run("distinct_profiles_accepted", func(t *testing.T) {
		// Two profiles with truly different names must not trigger the duplicate gate.
		compA := profileComponent(pack+"/default", "default", "accounts")
		compB := profileComponent(pack+"/batch", "batch", "accounts")
		root := writePackFixture(t, pack, validConnectorPackManifest(pack, "[\n"+compA+",\n"+compB+"\n]"))
		report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
		for _, d := range report.Diagnostics {
			if d.Code == code {
				t.Fatalf("unexpected duplicate diagnostic for distinct profiles: %s", d.String())
			}
		}
	})
}

func TestValidateInstallablePackSource_RejectsOverlappingExecutableConnectorCalloutProfileBatchCoverage(t *testing.T) {
	const pack = "acme-connector"
	const code = "connector_callout_profile.batch_object_overlap"

	profileComponent := func(rawBK, profileName, objectPathMapJSON, batchSpecJSON string) string {
		batchSpecField := ""
		if batchSpecJSON != "" {
			batchSpecField = `,
    "batchSpec":` + batchSpecJSON
		}
		return `{
  "kind":"connector_callout_profile",
  "businessKey":"` + rawBK + `",
  "manageability":"locked",
  "payload":{
    "profileName":"` + profileName + `",
    "credentialRef":"test-nc",
    "endpointClass":"crm.read",
    "retryPolicy":{"maxAttempts":3,"baseDelay":100000000,"multiplier":1.5,"maxDelay":5000000000},` + `
    "objectPathMap":` + objectPathMapJSON + batchSpecField + `
  }
}`
	}

	validBatchSpec := `{
      "method":"POST",
      "relativePath":"/batch",
      "maxBatchSize":100,
      "idsRequestField":"ids",
      "credentialRef":"test-nc",
      "endpointClass":"crm.batch",
      "idResponseField":"id"
    }`
	emptyRelativePathBatchSpec := `{
      "method":"POST",
      "relativePath":"",
      "maxBatchSize":100,
      "idsRequestField":"ids",
      "credentialRef":"test-nc",
      "endpointClass":"crm.batch",
      "idResponseField":"id"
    }`
	queryRelativePathBatchSpec := `{
      "method":"POST",
      "relativePath":"/batch?version=2",
      "maxBatchSize":100,
      "idsRequestField":"ids",
      "credentialRef":"test-nc",
      "endpointClass":"crm.batch",
      "idResponseField":"id"
    }`
	legacyBatchSpecMissingIDResponse := `{
      "method":"POST",
      "relativePath":"/legacy-batch",
      "maxBatchSize":100,
      "idsRequestField":"ids",
      "credentialRef":"test-nc",
      "endpointClass":"crm.batch"
    }`
	invalidNonExecutableMethodBatchSpec := `{
      "method":"GET",
      "relativePath":"/batch",
      "maxBatchSize":100,
      "idsRequestField":"ids",
      "credentialRef":"test-nc",
      "endpointClass":"crm.batch",
      "idResponseField":"id"
    }`

	t.Run("overlapping_executable_profiles_rejected", func(t *testing.T) {
		compA := profileComponent(pack+"/default", "default", `{"contact":"/contacts"}`, validBatchSpec)
		compB := profileComponent(pack+"/alternate", "alternate", `{" contact ":"/alt-contacts"}`, validBatchSpec)
		root := writePackFixture(t, pack, validConnectorPackManifest(pack, "[\n"+compA+",\n"+compB+"\n]"))
		report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
		assertInstallableDiagnostic(t, report, code)
	})

	t.Run("empty_relative_path_still_counts_as_runtime_executable_overlap", func(t *testing.T) {
		compA := profileComponent(pack+"/default", "default", `{"contact":"/contacts"}`, validBatchSpec)
		compB := profileComponent(pack+"/root-batch", "root-batch", `{"contact":"/root-contacts"}`, emptyRelativePathBatchSpec)
		root := writePackFixture(t, pack, validConnectorPackManifest(pack, "[\n"+compA+",\n"+compB+"\n]"))
		report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
		assertInstallableDiagnostic(t, report, code)
	})

	t.Run("query_relative_path_still_counts_as_runtime_executable_overlap", func(t *testing.T) {
		compA := profileComponent(pack+"/default", "default", `{"contact":"/contacts"}`, validBatchSpec)
		compB := profileComponent(pack+"/query-batch", "query-batch", `{"contact":"/query-contacts"}`, queryRelativePathBatchSpec)
		root := writePackFixture(t, pack, validConnectorPackManifest(pack, "[\n"+compA+",\n"+compB+"\n]"))
		report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
		assertInstallableDiagnostic(t, report, code)
	})

	t.Run("legacy_missing_id_response_still_counts_as_drain_executable_overlap", func(t *testing.T) {
		compA := profileComponent(pack+"/default", "default", `{"contact":"/contacts"}`, validBatchSpec)
		compB := profileComponent(pack+"/legacy", "legacy", `{"contact":"/legacy-contacts"}`, legacyBatchSpecMissingIDResponse)
		root := writePackFixture(t, pack, validConnectorPackManifest(pack, "[\n"+compA+",\n"+compB+"\n]"))
		report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
		assertInstallableDiagnostic(t, report, code)
	})

	t.Run("payload_only_profile_does_not_overlap", func(t *testing.T) {
		compA := profileComponent(pack+"/default", "default", `{"contact":"/contacts"}`, validBatchSpec)
		compB := profileComponent(pack+"/payload-only", "payload-only", `{"contact":"/contacts"}`, "")
		root := writePackFixture(t, pack, validConnectorPackManifest(pack, "[\n"+compA+",\n"+compB+"\n]"))
		report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
		for _, d := range report.Diagnostics {
			if d.Code == code {
				t.Fatalf("unexpected overlap diagnostic for payload-only profile: %s", d.String())
			}
		}
	})

	t.Run("blank_object_path_does_not_overlap", func(t *testing.T) {
		compA := profileComponent(pack+"/default", "default", `{"contact":"/contacts"}`, validBatchSpec)
		compB := profileComponent(pack+"/blank-path", "blank-path", `{"contact":"   "}`, validBatchSpec)
		root := writePackFixture(t, pack, validConnectorPackManifest(pack, "[\n"+compA+",\n"+compB+"\n]"))
		report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
		for _, d := range report.Diagnostics {
			if d.Code == code {
				t.Fatalf("unexpected overlap diagnostic for blank object path: %s", d.String())
			}
		}
	})

	t.Run("runtime_non_executable_batch_spec_does_not_overlap", func(t *testing.T) {
		compA := profileComponent(pack+"/default", "default", `{"contact":"/contacts"}`, validBatchSpec)
		compB := profileComponent(pack+"/get-batch", "get-batch", `{"contact":"/contacts"}`, invalidNonExecutableMethodBatchSpec)
		root := writePackFixture(t, pack, validConnectorPackManifest(pack, "[\n"+compA+",\n"+compB+"\n]"))
		report := ValidateInstallablePackSourceWithOptions("local_path:"+root, testPackSourceOptions(t))
		for _, d := range report.Diagnostics {
			if d.Code == code {
				t.Fatalf("unexpected overlap diagnostic for runtime-non-executable batch profile: %s", d.String())
			}
		}
	})
}

// jsonRawMessage wraps a JSON string so it can be embedded inline in a manifest
// without double-quoting. This is intentionally a test-only helper.
func jsonRawMessage(s string) string { return s }
