package skills

import (
	"context"
	"errors"
	"fmt"
	"os"
	"path/filepath"
	"sync/atomic"
	"testing"
	"time"

	"github.com/stretchr/testify/require"
	"github.com/tidbcloud/AgentTeam/internal/contentpayload"
	contentservice "github.com/tidbcloud/AgentTeam/internal/service/content"
	"github.com/tidbcloud/AgentTeam/internal/service/resource/activity"
	"github.com/tidbcloud/AgentTeam/internal/service/resource/repos"
	contentstore "github.com/tidbcloud/AgentTeam/internal/store/content"
	activitystore "github.com/tidbcloud/AgentTeam/internal/store/resource/activity"
	"github.com/tidbcloud/AgentTeam/internal/store/resource/memory"
	reposstore "github.com/tidbcloud/AgentTeam/internal/store/resource/repos"
	store "github.com/tidbcloud/AgentTeam/internal/store/resource/skills"
	"github.com/tidbcloud/AgentTeam/presets"
	"gorm.io/driver/sqlite"
	"gorm.io/gorm"
)

type skillContentWorkspaceAccess struct{ allowed map[string]bool }

func (access skillContentWorkspaceAccess) HasWorkspaceAccess(_ context.Context, workspaceID, subject string) (bool, error) {
	return access.allowed[workspaceID+"\x00"+subject], nil
}

func TestNativeSkillImportReadBackupRestoreUsesExactVersions(t *testing.T) {
	ctx := context.Background()
	db, err := gorm.Open(sqlite.Open("file:"+t.Name()+"?mode=memory&cache=shared"), &gorm.Config{})
	require.NoError(t, err)
	require.NoError(t, db.AutoMigrate(
		&store.Skill{}, &store.SkillVersion{}, &store.SkillGrant{}, &store.SkillRepositoryBranch{}, &store.SkillAgentBinding{},
		&memory.AgentAssetAccessChangeOutbox{},
		&reposstore.ResourceRepository{}, &reposstore.ResourceRepositoryAccessGrant{}, &reposstore.ResourceRepositoryLifecycleEvent{},
		&activitystore.ResourceActivityEvent{}, &activitystore.ResourceActivityLatestCommit{},
		&contentstore.Authority{}, &contentstore.VersionedContent{},
		&contentstore.ContentVersion{}, &contentstore.VersionOperation{}, &contentstore.VersionPath{},
		&contentstore.VersionPin{}, &contentstore.Outbox{}, &contentstore.StagedPayloadGC{},
	))
	tree, err := contentpayload.NewFilesystemTreeBackend(t.TempDir())
	require.NoError(t, err)
	t.Cleanup(func() { require.NoError(t, tree.Close()) })
	var ids atomic.Int64
	core, err := contentservice.NewTree(contentstore.New(db), tree, func(prefix string) (string, error) {
		return fmt.Sprintf("%s_%d", prefix, ids.Add(1)), nil
	})
	require.NoError(t, err)
	workspaceAccess := skillContentWorkspaceAccess{allowed: map[string]bool{"wsp_1\x00usr_1": true}}
	policy, err := NewSkillContentAccessPolicy(workspaceAccess, store.New(db))
	require.NoError(t, err)
	authorized, err := contentservice.NewAuthorizedService(core, policy)
	require.NoError(t, err)
	native := NativeSkillContentStore{Content: authorized}
	authority := contentstore.New(db)
	now := time.Now().UTC()
	require.NoError(t, db.Create(&contentstore.Authority{
		ID: "cta_skill_wildcard", WorkspaceID: "wsp_1", Domain: skillContentDomain,
		BindingKey: contentstore.AuthorityDomainDefaultBinding, State: contentstore.AuthorityStateNativeActive,
		Generation: 1, UpdatedBy: "operator", CreatedAt: now, UpdatedAt: now,
	}).Error)
	legacyContent := &fakeRepositoryContentManager{}
	repositories := &fakeRepositoryEnsurer{}
	issuer := &fakeSkillRepositorySyncTokenIssuer{lease: repos.RepositorySyncTokenLease{
		Token: "ags_rat_legacy_skill", ExpiresAt: now.Add(time.Hour),
	}}
	service := NewWithOptions(store.New(db), reposstore.New(db), repositories, func() time.Time { return now }, ServiceOptions{
		RepositoryContentManager: legacyContent,
		RepositoryDeleter:        repositories,
		AgentOwnershipSource: fakeSkillAgentOwnershipSource{agents: []repos.AgentOwnership{
			{ID: "agt_native", Name: "native"}, {ID: "agt_legacy", Name: "legacy"},
		}},
		AssetAccessOutbox:    memory.New(db),
		SyncTokenIssuer:      issuer,
		ActivityStore:        activitystore.New(db),
		ContentAuthority:     authority,
		NativeContent:        native,
		NativeContentEnabled: true,
	})
	created, err := service.CreateSkill(ctx, "wsp_1", "usr_1", SkillCreateMutation{
		Name: "Reviewer", Description: "Review changes", Actor: repos.ResourceRepositoryActor{Subject: "usr_1", Login: "usr_1"},
	})
	require.NoError(t, err)
	exact, found, err := authority.GetAuthority(ctx, "wsp_1", skillContentDomain, created.ID)
	require.NoError(t, err)
	require.False(t, found)
	require.Equal(t, contentstore.AuthorityStateLegacyActive, exact.State, "persistent wildcard policy must not capture new Skills")

	initial, err := native.Initialize(ctx, NativeSkillInitializeRequest{
		WorkspaceID: created.WorkspaceID, SkillID: created.ID, Actor: "usr_1", Slug: created.Slug,
		Name: created.Name, Description: created.Description, Locale: "en",
	})
	require.NoError(t, err)
	created.ContentID = initial.ContentID
	created.ActiveContentVersionID = initial.VersionID
	created.SkillCount = initial.SkillCount
	created.UpdatedBy = "usr_1"
	created.UpdatedAt = now
	require.NoError(t, service.store.Transaction(ctx, func(tx *store.Store) error {
		if _, err := tx.UpdateSkill(ctx, created); err != nil {
			return err
		}
		_, err := tx.CreateSkillVersion(ctx, store.SkillVersion{
			ID: "skv_initial", WorkspaceID: created.WorkspaceID, SkillID: created.ID,
			ContentID: initial.ContentID, ContentVersionID: initial.VersionID, RootDigest: initial.RootDigest,
			FileCount: initial.FileCount, SizeBytes: initial.SizeBytes, SkillCount: initial.SkillCount,
			CreatedBy: "usr_1", CreatedAt: now,
		})
		return err
	}))
	legacyBound, err := service.BindAgentSkill(ctx, "wsp_1", "usr_1", "agt_native", created.ID, AgentSkillBindingMutation{Branch: "main"})
	require.NoError(t, err)
	require.Equal(t, "main", legacyBound.Branch)
	exact, err = authority.ActivateNativeAuthority(ctx, contentstore.ActivateNativeAuthorityParams{
		WorkspaceID: created.WorkspaceID, Domain: skillContentDomain, BindingKey: created.ID,
		Checkpoint: "import:final", Actor: "operator", Now: now,
	})
	require.NoError(t, err)
	require.Equal(t, contentstore.AuthorityStateNativeActive, exact.State)

	legacyActivatedSummary, err := service.ListAgentSkillBindings(ctx, "wsp_1", "usr_1", AgentSkillBindingsOptions{})
	require.NoError(t, err)
	require.Len(t, legacyActivatedSummary.Bindings, 1)
	require.Empty(t, legacyActivatedSummary.Bindings[0].Branch, "workspace binding inventory must redact a pre-activation legacy branch")
	legacyActivatedForAgent, err := service.ListAgentSkillBindingsForAgent(ctx, "wsp_1", "usr_1", "agt_native")
	require.NoError(t, err)
	require.Len(t, legacyActivatedForAgent, 1)
	require.Empty(t, legacyActivatedForAgent[0].Branch, "per-agent binding inventory must redact a pre-activation legacy branch")
	unbound, err := service.UnbindAgentSkill(ctx, "wsp_1", "usr_1", "agt_native", created.ID)
	require.NoError(t, err)
	require.Empty(t, unbound.Branch, "native unbind result must redact the persisted legacy branch")

	_, err = service.BindAgentSkill(ctx, "wsp_1", "usr_1", "agt_native", created.ID, AgentSkillBindingMutation{Branch: "main"})
	require.ErrorIs(t, err, ErrInvalidArgument)
	bound, err := service.BindAgentSkill(ctx, "wsp_1", "usr_1", "agt_native", created.ID, AgentSkillBindingMutation{LegacyBranchHint: "main"})
	require.NoError(t, err)
	require.Empty(t, bound.Branch, "native Skill owner must ignore a Role-provided legacy branch hint")
	projector := &fakeSkillActivityProjector{}
	service.activityProjector = projector
	updatedName := "Reviewer Native"
	_, err = service.UpdateSkill(ctx, "wsp_1", "usr_1", created.ID, SkillUpdateMutation{Name: &updatedName})
	require.NoError(t, err)
	nativeGrant, err := service.UpsertSkillPermission(ctx, "wsp_1", "usr_1", created.ID, SkillPermissionGrantMutation{SubjectType: "user", SubjectID: "usr_viewer", Role: "view"})
	require.NoError(t, err)
	_, err = service.ListSkills(ctx, "wsp_1", "usr_1", SkillListOptions{Page: 1, PerPage: 20})
	require.NoError(t, err)
	_, err = service.ListSkillActivity(ctx, "wsp_1", "usr_1", activity.ResourceActivityListOptions{Limit: 20})
	require.NoError(t, err)
	require.Empty(t, projector.repos, "native Skill list/activity must not invoke the repository projector")
	require.NoError(t, service.DeleteSkillPermission(ctx, "wsp_1", "usr_1", created.ID, nativeGrant.ID))
	var nativeActivity []activitystore.ResourceActivityEvent
	require.NoError(t, db.Where("workspace_id = ? AND asset_id = ? AND event_type IN ?", "wsp_1", created.ID, []string{skillActivitySettingsChanged, skillActivityGrantAdded, skillActivityGrantRemoved}).Find(&nativeActivity).Error)
	require.NotEmpty(t, nativeActivity)
	for _, event := range nativeActivity {
		require.Equal(t, "contentstore://"+created.ContentID+"/"+created.ActiveContentVersionID, event.RepoFullName)
	}
	var authorityBatchQueries atomic.Int64
	require.NoError(t, db.Callback().Query().Before("gorm:query").Register("test:skill_authority_batch", func(tx *gorm.DB) {
		if tx.Statement != nil && tx.Statement.Schema != nil && tx.Statement.Schema.Table == (contentstore.Authority{}).TableName() {
			authorityBatchQueries.Add(1)
		}
	}))
	authorityBatchQueries.Store(0)
	nativeAccess, err := service.BatchListAgentAccessibleSkills(ctx, "wsp_1", "usr_1", AgentSkillAccessBatchOptions{AgentIDs: []string{"agt_native"}})
	require.NoError(t, err)
	require.Equal(t, int64(1), authorityBatchQueries.Load(), "agent access must resolve authorities in one bounded batch")
	require.Empty(t, nativeAccess.SyncToken)
	require.Empty(t, issuer.requests, "native-only access must not issue an AGS token")
	require.Len(t, nativeAccess.Agents["agt_native"], 1)
	nativeItem := nativeAccess.Agents["agt_native"][0]
	require.Equal(t, created.ContentID, nativeItem.ContentID)
	require.Equal(t, created.ActiveContentVersionID, nativeItem.ContentVersionID)
	require.Nil(t, nativeItem.Repository)
	require.Empty(t, nativeItem.Branch)
	service.nativeContentEnabled = false
	_, err = service.BatchListAgentAccessibleSkills(ctx, "wsp_1", "usr_1", AgentSkillAccessBatchOptions{AgentIDs: []string{"agt_native"}})
	require.ErrorContains(t, err, "native skill content is unavailable")
	require.Empty(t, issuer.requests, "native unavailability must fail closed before AGS token issuance")
	service.nativeContentEnabled = true

	legacySkill, err := service.CreateSkill(ctx, "wsp_1", "usr_1", SkillCreateMutation{
		Name: "Legacy Planner", Actor: repos.ResourceRepositoryActor{Subject: "usr_1", Login: "usr_1"},
	})
	require.NoError(t, err)
	_, err = service.BindAgentSkill(ctx, "wsp_1", "usr_1", "agt_legacy", legacySkill.ID, AgentSkillBindingMutation{Branch: "main"})
	require.NoError(t, err)
	mixedAccess, err := service.BatchListAgentAccessibleSkills(ctx, "wsp_1", "usr_1", AgentSkillAccessBatchOptions{AgentIDs: []string{"agt_native", "agt_legacy"}})
	require.NoError(t, err)
	require.Equal(t, issuer.lease.Token, mixedAccess.SyncToken)
	require.Len(t, issuer.requests, 1)
	require.ElementsMatch(t, []string{"usr_1/legacy-planner.sk"}, issuer.requests[0].Repositories)
	require.Nil(t, mixedAccess.Agents["agt_native"][0].Repository)
	require.NotNil(t, mixedAccess.Agents["agt_legacy"][0].Repository)

	bindingSummary, err := service.ListAgentSkillBindings(ctx, "wsp_1", "usr_1", AgentSkillBindingsOptions{})
	require.NoError(t, err)
	var nativeBindingSkill AgentSkillBindingSkill
	for _, candidate := range bindingSummary.Skills {
		if candidate.ID == created.ID {
			nativeBindingSkill = candidate
			break
		}
	}
	require.Equal(t, created.ContentID, nativeBindingSkill.ContentID)
	require.Equal(t, created.ActiveContentVersionID, nativeBindingSkill.ContentVersionID)
	require.Nil(t, nativeBindingSkill.Repository, "native binding inventory must not expose an AGS repository")

	preview, err := service.ListSkillRepositorySkills(ctx, "wsp_1", "usr_1", created.ID)
	require.NoError(t, err)
	require.Equal(t, initial.VersionID, preview.VersionID)
	require.NotEmpty(t, preview.DetectedSkills)
	contents, err := service.ReadSkillRepositorySkills(ctx, "wsp_1", "usr_1", created.ID, SkillRepositoryContentsRequest{
		ExpectedVersionID: preview.VersionID, Paths: []string{preview.DetectedSkills[0].Path},
	})
	require.NoError(t, err)
	require.Equal(t, initial.VersionID, contents.VersionID)
	require.NotEmpty(t, contents.Items[0].Content)

	backup, err := service.CreateSkillRepositoryBackup(ctx, "wsp_1", "usr_1", created.ID, SkillRepositoryBackupCreateMutation{Name: "Before import"})
	require.NoError(t, err)
	require.Equal(t, initial.VersionID, backup.VersionID)
	importPath := filepath.Join(t.TempDir(), "SKILL.md")
	require.NoError(t, os.WriteFile(importPath, []byte("---\nname: Added Skill\ndescription: Imported skill\n---\n\n# Added\n"), 0o644))
	var failProjection atomic.Bool
	failProjection.Store(true)
	require.NoError(t, db.Callback().Create().Before("gorm:create").Register("test:fail_first_skill_projection", func(tx *gorm.DB) {
		if tx.Statement != nil && tx.Statement.Schema != nil && tx.Statement.Schema.Table == (store.SkillVersion{}).TableName() && failProjection.CompareAndSwap(true, false) {
			tx.AddError(errors.New("injected skill projection failure"))
		}
	}))
	var contentVersionsBefore int64
	require.NoError(t, db.Model(&contentstore.ContentVersion{}).Where("workspace_id = ? AND content_id = ?", created.WorkspaceID, created.ContentID).Count(&contentVersionsBefore).Error)
	_, err = service.ImportSkillContent(ctx, "wsp_1", "usr_1", created.ID, SkillContentImportMutation{
		SourceFilePath: importPath, SourceName: "SKILL.md",
	})
	require.ErrorContains(t, err, "injected skill projection failure")
	var contentVersionsAfterFailedProjection int64
	require.NoError(t, db.Model(&contentstore.ContentVersion{}).Where("workspace_id = ? AND content_id = ?", created.WorkspaceID, created.ContentID).Count(&contentVersionsAfterFailedProjection).Error)
	require.Equal(t, contentVersionsBefore+1, contentVersionsAfterFailedProjection, "Content Store commit succeeds before the injected product transaction failure")
	staleProjection, err := service.store.GetSkill(ctx, created.WorkspaceID, created.ID)
	require.NoError(t, err)
	require.Equal(t, initial.VersionID, staleProjection.ActiveContentVersionID)

	imported, err := service.ImportSkillContent(ctx, "wsp_1", "usr_1", created.ID, SkillContentImportMutation{
		SourceFilePath: importPath, SourceName: "SKILL.md",
	})
	require.NoError(t, err)
	var contentVersionsAfterRetry int64
	require.NoError(t, db.Model(&contentstore.ContentVersion{}).Where("workspace_id = ? AND content_id = ?", created.WorkspaceID, created.ContentID).Count(&contentVersionsAfterRetry).Error)
	require.Equal(t, contentVersionsAfterFailedProjection, contentVersionsAfterRetry, "retry must reuse the durable Content Store receipt instead of publishing another version")
	require.NotEmpty(t, imported.VersionID)
	require.NotEqual(t, initial.VersionID, imported.VersionID)
	require.Empty(t, legacyContent.importRequests, "native import must not fall back to AGS")

	failProjection.Store(true)
	var versionsBeforeBackupRestore int64
	require.NoError(t, db.Model(&contentstore.ContentVersion{}).Where("workspace_id = ? AND content_id = ?", created.WorkspaceID, created.ContentID).Count(&versionsBeforeBackupRestore).Error)
	_, err = service.RestoreSkillRepositoryBackup(ctx, "wsp_1", "usr_1", created.ID, backup.TagName)
	require.ErrorContains(t, err, "injected skill projection failure")
	var versionsAfterFailedBackupRestore int64
	require.NoError(t, db.Model(&contentstore.ContentVersion{}).Where("workspace_id = ? AND content_id = ?", created.WorkspaceID, created.ContentID).Count(&versionsAfterFailedBackupRestore).Error)
	require.Equal(t, versionsBeforeBackupRestore+1, versionsAfterFailedBackupRestore)
	staleProjection, err = service.store.GetSkill(ctx, created.WorkspaceID, created.ID)
	require.NoError(t, err)
	require.Equal(t, imported.VersionID, staleProjection.ActiveContentVersionID)

	restored, err := service.RestoreSkillRepositoryBackup(ctx, "wsp_1", "usr_1", created.ID, backup.TagName)
	require.NoError(t, err)
	var versionsAfterBackupRestoreRetry int64
	require.NoError(t, db.Model(&contentstore.ContentVersion{}).Where("workspace_id = ? AND content_id = ?", created.WorkspaceID, created.ContentID).Count(&versionsAfterBackupRestoreRetry).Error)
	require.Equal(t, versionsAfterFailedBackupRestore, versionsAfterBackupRestoreRetry, "backup restore retry must reuse its exact durable receipt")
	require.NotEqual(t, initial.VersionID, restored.VersionID, "restore publishes a new immutable version instead of moving a mutable head")
	versions, err := service.store.ListSkillVersions(ctx, "wsp_1", created.ID, 10, 0)
	require.NoError(t, err)
	require.Len(t, versions, 3)
	history, err := service.ListSkillVersions(ctx, "wsp_1", "usr_1", created.ID, 1, 10)
	require.NoError(t, err)
	require.Len(t, history.Items, 3)
	require.False(t, history.HasMore, "a full final page must not claim another page")
	firstHistoryPage, err := service.ListSkillVersions(ctx, "wsp_1", "usr_1", created.ID, 1, 2)
	require.NoError(t, err)
	require.Len(t, firstHistoryPage.Items, 2)
	require.True(t, firstHistoryPage.HasMore)
	lastHistoryPage, err := service.ListSkillVersions(ctx, "wsp_1", "usr_1", created.ID, 2, 2)
	require.NoError(t, err)
	require.Len(t, lastHistoryPage.Items, 1)
	require.False(t, lastHistoryPage.HasMore)
	failProjection.Store(true)
	var versionsBeforeHistoryRollback int64
	require.NoError(t, db.Model(&contentstore.ContentVersion{}).Where("workspace_id = ? AND content_id = ?", created.WorkspaceID, created.ContentID).Count(&versionsBeforeHistoryRollback).Error)
	_, err = service.RollbackSkillVersion(ctx, "wsp_1", "usr_1", created.ID, "skv_initial")
	require.ErrorContains(t, err, "injected skill projection failure")
	var versionsAfterFailedHistoryRollback int64
	require.NoError(t, db.Model(&contentstore.ContentVersion{}).Where("workspace_id = ? AND content_id = ?", created.WorkspaceID, created.ContentID).Count(&versionsAfterFailedHistoryRollback).Error)
	require.Equal(t, versionsBeforeHistoryRollback+1, versionsAfterFailedHistoryRollback)
	staleProjection, err = service.store.GetSkill(ctx, created.WorkspaceID, created.ID)
	require.NoError(t, err)
	require.Equal(t, restored.VersionID, staleProjection.ActiveContentVersionID)

	rolledBack, err := service.RollbackSkillVersion(ctx, "wsp_1", "usr_1", created.ID, "skv_initial")
	require.NoError(t, err)
	var versionsAfterHistoryRollbackRetry int64
	require.NoError(t, db.Model(&contentstore.ContentVersion{}).Where("workspace_id = ? AND content_id = ?", created.WorkspaceID, created.ContentID).Count(&versionsAfterHistoryRollbackRetry).Error)
	require.Equal(t, versionsAfterFailedHistoryRollback, versionsAfterHistoryRollbackRetry, "history rollback retry must reuse its exact durable receipt")
	require.NotEqual(t, initial.VersionID, rolledBack.ContentVersionID)
	require.Empty(t, legacyContent.importRequests, "native recovery paths must not fall back to AGS")

	officialInfo, err := presets.OfficialSkillLibrary(workflowPlanAuthorLibrarySlugForTest, presets.LocaleEnglish)
	require.NoError(t, err)
	require.NotEmpty(t, officialInfo.SourceFingerprint)
	workspaceAccess.allowed["wsp_1\x00"+officialInfo.SystemSubject] = true
	_, err = service.store.UpsertSkillGrant(ctx, store.SkillGrant{
		ID: "skg_official_system", WorkspaceID: created.WorkspaceID, SkillID: created.ID,
		SubjectType: "user", SubjectID: officialInfo.SystemSubject, Role: "manage",
		CreatedBy: "usr_1", UpdatedBy: "usr_1", CreatedAt: now, UpdatedAt: now,
	})
	require.NoError(t, err)
	var failOfficialFingerprint atomic.Bool
	failOfficialFingerprint.Store(true)
	require.NoError(t, db.Callback().Update().Before("gorm:update").Register("test:fail_first_official_fingerprint", func(tx *gorm.DB) {
		if tx.Statement == nil || tx.Statement.Schema == nil || tx.Statement.Schema.Table != (store.Skill{}).TableName() {
			return
		}
		values, ok := tx.Statement.Dest.(map[string]any)
		if !ok {
			return
		}
		if _, updatingFingerprint := values["official_source_fingerprint"]; updatingFingerprint && failOfficialFingerprint.CompareAndSwap(true, false) {
			tx.AddError(errors.New("injected official fingerprint failure"))
		}
	}))
	countOfficialImportRows := func() (contentVersions, contentOperations, skillVersions, activities int64) {
		require.NoError(t, db.Model(&contentstore.ContentVersion{}).
			Where("workspace_id = ? AND content_id = ?", created.WorkspaceID, created.ContentID).
			Count(&contentVersions).Error)
		require.NoError(t, db.Model(&contentstore.VersionOperation{}).
			Where("workspace_id = ? AND content_id = ?", created.WorkspaceID, created.ContentID).
			Count(&contentOperations).Error)
		require.NoError(t, db.Model(&store.SkillVersion{}).
			Where("workspace_id = ? AND skill_id = ?", created.WorkspaceID, created.ID).
			Count(&skillVersions).Error)
		require.NoError(t, db.Model(&activitystore.ResourceActivityEvent{}).
			Where("workspace_id = ? AND asset_id = ? AND event_type = ?", created.WorkspaceID, created.ID, skillActivityImported).
			Count(&activities).Error)
		return contentVersions, contentOperations, skillVersions, activities
	}
	officialBase, err := service.store.GetSkill(ctx, created.WorkspaceID, created.ID)
	require.NoError(t, err)
	contentBeforeOfficial, operationsBeforeOfficial, skillVersionsBeforeOfficial, activitiesBeforeOfficial := countOfficialImportRows()
	_, err = service.importOfficialSkillContentForRoute(ctx, officialBase, officialInfo, true, nil)
	require.ErrorContains(t, err, "injected official fingerprint failure")
	contentAfterOfficialFailure, operationsAfterOfficialFailure, skillVersionsAfterOfficialFailure, activitiesAfterOfficialFailure := countOfficialImportRows()
	require.Equal(t, contentBeforeOfficial+1, contentAfterOfficialFailure, "official ContentVersion must commit before the injected product transaction failure")
	require.Equal(t, operationsBeforeOfficial+1, operationsAfterOfficialFailure, "official Content Store receipt must remain durable")
	require.Equal(t, skillVersionsBeforeOfficial, skillVersionsAfterOfficialFailure, "failed official product transaction must roll back SkillVersion")
	require.Equal(t, activitiesBeforeOfficial, activitiesAfterOfficialFailure, "failed official product transaction must roll back activity")
	staleOfficial, err := service.store.GetSkill(ctx, created.WorkspaceID, created.ID)
	require.NoError(t, err)
	require.Equal(t, officialBase.ActiveContentVersionID, staleOfficial.ActiveContentVersionID)
	require.NotEqual(t, officialInfo.SourceFingerprint, staleOfficial.OfficialSourceFingerprint)

	healedOfficial, err := service.importOfficialSkillContentForRoute(ctx, officialBase, officialInfo, true, nil)
	require.NoError(t, err)
	contentAfterOfficialRetry, operationsAfterOfficialRetry, skillVersionsAfterOfficialRetry, activitiesAfterOfficialRetry := countOfficialImportRows()
	require.Equal(t, contentAfterOfficialFailure, contentAfterOfficialRetry, "official retry must reuse the durable Content Store receipt")
	require.Equal(t, operationsAfterOfficialFailure, operationsAfterOfficialRetry, "official retry must not create a second operation receipt")
	require.Equal(t, skillVersionsBeforeOfficial+1, skillVersionsAfterOfficialRetry)
	require.Equal(t, activitiesBeforeOfficial+1, activitiesAfterOfficialRetry)
	require.Equal(t, officialInfo.SourceFingerprint, healedOfficial.OfficialSourceFingerprint)
	require.NotEqual(t, officialBase.ActiveContentVersionID, healedOfficial.ActiveContentVersionID)
	require.Empty(t, legacyContent.importRequests, "native official receipt replay must not fall back to AGS")
	_, err = service.store.UpdateOfficialSourceFingerprint(ctx, created.WorkspaceID, created.ID, "stale-official-fingerprint", officialInfo.SystemSubject, now)
	require.NoError(t, err)
	contentBeforeExistingReplay, operationsBeforeExistingReplay, skillVersionsBeforeExistingReplay, activitiesBeforeExistingReplay := countOfficialImportRows()
	replayedOfficial, err := service.importOfficialSkillContentForRoute(ctx, officialBase, officialInfo, true, nil)
	require.NoError(t, err)
	contentAfterExistingReplay, operationsAfterExistingReplay, skillVersionsAfterExistingReplay, activitiesAfterExistingReplay := countOfficialImportRows()
	require.Equal(t, contentBeforeExistingReplay, contentAfterExistingReplay)
	require.Equal(t, operationsBeforeExistingReplay, operationsAfterExistingReplay)
	require.Equal(t, skillVersionsBeforeExistingReplay, skillVersionsAfterExistingReplay)
	require.Equal(t, activitiesBeforeExistingReplay, activitiesAfterExistingReplay)
	require.Equal(t, healedOfficial.ActiveContentVersionID, replayedOfficial.ActiveContentVersionID)
	require.Equal(t, officialInfo.SourceFingerprint, replayedOfficial.OfficialSourceFingerprint, "an existing receipt projection must also reconcile the official fingerprint")

	preview, err = service.ListSkillRepositorySkills(ctx, "wsp_1", "usr_1", created.ID)
	require.NoError(t, err)
	require.Equal(t, healedOfficial.ActiveContentVersionID, preview.VersionID)
	workspaceAccess.allowed["wsp_1\x00usr_1"] = false
	_, err = service.ListSkillRepositorySkills(ctx, "wsp_1", "usr_1", created.ID)
	require.Error(t, err)
	require.Empty(t, legacyContent.listRequests, "revoked native access must fail closed without AGS fallback")
	workspaceAccess.allowed["wsp_1\x00usr_1"] = true
	require.NoError(t, service.DeleteSkill(ctx, "wsp_1", "usr_1", created.ID))
	require.Empty(t, repositories.deletes, "native delete must not call the AGS repository deleter")
	var remaining int64
	require.NoError(t, db.Model(&store.SkillVersion{}).Where("workspace_id = ? AND skill_id = ?", "wsp_1", created.ID).Count(&remaining).Error)
	require.Zero(t, remaining)
	require.NoError(t, db.Model(&store.SkillAgentBinding{}).Where("workspace_id = ? AND skill_id = ?", "wsp_1", created.ID).Count(&remaining).Error)
	require.Zero(t, remaining)
	require.NoError(t, db.Model(&store.SkillGrant{}).Where("workspace_id = ? AND skill_id = ?", "wsp_1", created.ID).Count(&remaining).Error)
	require.Zero(t, remaining)
	require.NoError(t, db.Model(&reposstore.ResourceRepository{}).Where("workspace_id = ? AND resource_type = ? AND resource_id = ?", "wsp_1", reposstore.ResourceTypeSkillRepository, created.ID).Count(&remaining).Error)
	require.Zero(t, remaining)
	require.NoError(t, db.Model(&store.SkillRepositoryBranch{}).Where("workspace_id = ? AND repo_owner = ? AND repo_name = ?", "wsp_1", "usr_1", "reviewer.sk").Count(&remaining).Error)
	require.Zero(t, remaining)
}
