package exec

// The audit dimensions below are intentionally small closed vocabularies. They
// are not prose-only review notes: catalog construction validates every row
// against one explicit decision and the durable inventory mirrors these values.
type builtinMutationReplayPolicy string

type builtinPermissionExposurePolicy string

type builtinIdentifierPolicy string

type builtinErrorExitPolicy string

type builtinSurfacePolicy string

const (
	builtinReplayNotApplicable builtinMutationReplayPolicy = "not_applicable"
	builtinReplayRequestID     builtinMutationReplayPolicy = "request_id_receipt"
	builtinReplayIdempotency   builtinMutationReplayPolicy = "idempotency_key_receipt"
	builtinReplayNaturalKey    builtinMutationReplayPolicy = "natural_key_no_retry"
	builtinReplayWorkflow      builtinMutationReplayPolicy = "workflow_receipt"

	builtinExposureReadProjection builtinPermissionExposurePolicy = "workspace_read_projection"
	builtinExposureAgentMutation  builtinPermissionExposurePolicy = "agent_scoped_mutation"
	builtinExposureExistingGate   builtinPermissionExposurePolicy = "existing_approval_gate"

	builtinIdentifiersStable builtinIdentifierPolicy = "stable_ids_and_follow_up"
	builtinIdentifiersCursor builtinIdentifierPolicy = "stable_ids_cursor_follow_up"
	builtinIdentifiersPage   builtinIdentifierPolicy = "stable_ids_page_follow_up"
	builtinIdentifiersNarrow builtinIdentifierPolicy = "stable_id_narrow_follow_up"

	builtinErrorTyped builtinErrorExitPolicy = "typed_error_stderr_nonzero"

	builtinSurfaceClosed builtinSurfacePolicy = "closed_schema_help_example_compat"
)

type builtinActionAuditDecision struct {
	MutationReplay          builtinMutationReplayPolicy     `json:"mutationReplay"`
	PermissionExposure      builtinPermissionExposurePolicy `json:"permissionExposure"`
	StableIdentifiers       builtinIdentifierPolicy         `json:"stableIdentifiers"`
	AllowedSensitiveFields  []string                        `json:"allowedSensitiveFields"`
	RedactedSensitiveFields []string                        `json:"redactedSensitiveFields"`
	StableSelectors         []string                        `json:"stableSelectors"`
	CanonicalFollowUp       string                          `json:"canonicalFollowUp"`
	ReplaySelector          string                          `json:"replaySelector"`
	ReplayDigest            string                          `json:"replayDigest"`
	ExpectedErrorClass      string                          `json:"expectedErrorClass"`
	Retryability            string                          `json:"retryability"`
	ErrorExit               builtinErrorExitPolicy          `json:"errorExit"`
	HelpExampleStatus       string                          `json:"helpExampleStatus"`
	HelpSchemaCompatibility builtinSurfacePolicy            `json:"helpSchemaCompatibility"`
	CompatibilityDecision   string                          `json:"compatibilityDecision"`
	Rationale               string                          `json:"rationale"`
}

func builtinReadAudit(identifiers builtinIdentifierPolicy, rationale string) builtinActionAuditDecision {
	return builtinActionAuditDecision{
		MutationReplay:          builtinReplayNotApplicable,
		PermissionExposure:      builtinExposureReadProjection,
		StableIdentifiers:       identifiers,
		ErrorExit:               builtinErrorTyped,
		HelpSchemaCompatibility: builtinSurfaceClosed,
		Rationale:               rationale,
	}
}

func builtinMutationAudit(replay builtinMutationReplayPolicy, rationale string) builtinActionAuditDecision {
	return builtinMutationAuditWithExposure(replay, builtinExposureAgentMutation, rationale)
}

func builtinGateAudit(replay builtinMutationReplayPolicy, rationale string) builtinActionAuditDecision {
	return builtinMutationAuditWithExposure(replay, builtinExposureExistingGate, rationale)
}

func builtinMutationAuditWithExposure(replay builtinMutationReplayPolicy, exposure builtinPermissionExposurePolicy, rationale string) builtinActionAuditDecision {
	return builtinActionAuditDecision{
		MutationReplay:          replay,
		PermissionExposure:      exposure,
		StableIdentifiers:       builtinIdentifiersStable,
		ErrorExit:               builtinErrorTyped,
		HelpSchemaCompatibility: builtinSurfaceClosed,
		Rationale:               rationale,
	}
}

// The key set is intentionally explicit rather than inferred from the
// descriptor list. A newly registered command therefore fails validation until
// its exposure, identifier, error, and compatibility decision is reviewed and
// added here. MutationReplay is retained only as a durable projection field;
// the registered transport capability is authoritative for replay behavior.
var builtinActionAuditDecisions = map[string]builtinActionAuditDecision{
	"workspace list":             builtinReadAudit(builtinIdentifiersCursor, "workspace list is read-only; no mutation replay key is applicable."),
	"project list":               builtinReadAudit(builtinIdentifiersCursor, "project list is read-only; no mutation replay key is applicable."),
	"project create":             builtinMutationAudit(builtinReplayNaturalKey, "project create retains its existing resource boundary; the current API has no durable request receipt, so the client does not transparently retry it."),
	"project delete":             builtinMutationAudit(builtinReplayNaturalKey, "project delete is a natural-key deletion; the client does not transparently retry it without a server receipt."),
	"agent list":                 builtinReadAudit(builtinIdentifiersCursor, "agent list is read-only; no mutation replay key is applicable."),
	"agent get":                  builtinReadAudit(builtinIdentifiersNarrow, "agent get is read-only; no mutation replay key is applicable."),
	"agent start":                builtinMutationAudit(builtinReplayRequestID, "agent start is replayed by its workspace/Agent/requestId receipt."),
	"agent stop":                 builtinMutationAudit(builtinReplayRequestID, "agent stop is replayed by its workspace/Agent/requestId receipt."),
	"agent restart":              builtinMutationAudit(builtinReplayRequestID, "agent restart is replayed by its workspace/Agent/requestId receipt."),
	"agent create":               builtinGateAudit(builtinReplayRequestID, "approval creates one Agent structural request; requestId selects the existing approval receipt and agent request-get is the read-only follow-up."),
	"agent update":               builtinGateAudit(builtinReplayRequestID, "approval updates one Agent structural request; requestId selects the existing approval receipt and agent get is the read-only follow-up."),
	"agent delete":               builtinGateAudit(builtinReplayRequestID, "approval deletes the selected Agent IDs; requestId selects the existing approval receipt and agent list/get is the read-only follow-up."),
	"agent duplicate":            builtinGateAudit(builtinReplayRequestID, "approval duplicates one source Agent; requestId selects the existing approval receipt and agent list/get is the read-only follow-up."),
	"team list":                  builtinReadAudit(builtinIdentifiersCursor, "team list is read-only; no mutation replay key is applicable."),
	"team get":                   builtinReadAudit(builtinIdentifiersNarrow, "team get is read-only; no mutation replay key is applicable."),
	"team update":                builtinMutationAudit(builtinReplayRequestID, "team update is replayed by its workspace/Agent/requestId receipt."),
	"channel list":               builtinReadAudit(builtinIdentifiersCursor, "channel list is read-only; no mutation replay key is applicable."),
	"channel get":                builtinReadAudit(builtinIdentifiersNarrow, "channel get is read-only; no mutation replay key is applicable."),
	"channel members":            builtinReadAudit(builtinIdentifiersCursor, "channel members is read-only; no mutation replay key is applicable."),
	"channel create":             builtinMutationAudit(builtinReplayRequestID, "channel create is replayed by its workspace/Agent/requestId receipt."),
	"channel update":             builtinMutationAudit(builtinReplayRequestID, "channel update is replayed by its workspace/Agent/requestId receipt."),
	"channel agent-add":          builtinMutationAudit(builtinReplayRequestID, "channel agent-add is replayed by its workspace/Agent/requestId receipt."),
	"channel agent-remove":       builtinMutationAudit(builtinReplayRequestID, "channel agent-remove is replayed by its workspace/Agent/requestId receipt."),
	"review list":                builtinReadAudit(builtinIdentifiersCursor, "review list is read-only; no mutation replay key is applicable."),
	"review add":                 builtinMutationAudit(builtinReplayNaturalKey, "review add is an upsert at one resolved thread; no transparent retry is attempted without a server receipt."),
	"review delete":              builtinMutationAudit(builtinReplayNaturalKey, "review delete is a natural-key deletion; no transparent retry is attempted without a server receipt."),
	"role list":                  builtinReadAudit(builtinIdentifiersCursor, "role list is read-only; no mutation replay key is applicable."),
	"role get":                   builtinReadAudit(builtinIdentifiersNarrow, "role get is read-only; no mutation replay key is applicable."),
	"role request-get":           builtinReadAudit(builtinIdentifiersNarrow, "role request-get is read-only; no mutation replay key is applicable."),
	"role create":                builtinGateAudit(builtinReplayRequestID, "approval creates one private Role; requestId selects the existing approval receipt and role request-get is the read-only follow-up."),
	"role update":                builtinGateAudit(builtinReplayRequestID, "approval updates one Role version; roleId plus expectedRoleVersionId select the request and role request-get is the read-only follow-up."),
	"role delete":                builtinGateAudit(builtinReplayRequestID, "approval soft-deletes one Role version; roleId plus expectedRoleVersionId select the request and role request-get is the read-only follow-up."),
	"role apply":                 builtinGateAudit(builtinReplayRequestID, "approval applies one Role version to one Agent; roleId, roleVersionId, and agentId select the request and role request-get is the read-only follow-up."),
	"skill list":                 builtinReadAudit(builtinIdentifiersPage, "skill list is read-only; no mutation replay key is applicable."),
	"skill get":                  builtinReadAudit(builtinIdentifiersNarrow, "skill get is read-only; no mutation replay key is applicable."),
	"skill create":               builtinMutationAudit(builtinReplayNaturalKey, "skill create has no durable request receipt in the current API; the client does not transparently retry it."),
	"skill update":               builtinMutationAudit(builtinReplayNaturalKey, "skill update has no durable request receipt in the current API; the client does not transparently retry it."),
	"skill import":               builtinMutationAudit(builtinReplayNaturalKey, "Skill import streams external content and remains explicitly non-retried to avoid duplicate side effects."),
	"skill delete":               builtinGateAudit(builtinReplayRequestID, "approval deletes one managed Skill; skillId and requestId select the existing approval receipt and skill get is the read-only follow-up."),
	"profile set-avatar":         builtinMutationAudit(builtinReplayNaturalKey, "avatar upload is a bounded multipart replacement and remains non-retried without a server receipt."),
	"task create":                builtinMutationAudit(builtinReplayNaturalKey, "task create has no durable request receipt in the current task API; the client does not transparently retry it."),
	"task get":                   builtinReadAudit(builtinIdentifiersNarrow, "task get is read-only; no mutation replay key is applicable."),
	"task list":                  builtinReadAudit(builtinIdentifiersCursor, "task list is read-only; no mutation replay key is applicable."),
	"task update":                builtinMutationAudit(builtinReplayNaturalKey, "task update uses the stable channel/number selector and is not transparently retried."),
	"task claim":                 builtinMutationAudit(builtinReplayNaturalKey, "task claim uses the stable channel/numbers selector and is not transparently retried."),
	"task unclaim":               builtinMutationAudit(builtinReplayNaturalKey, "task unclaim uses the stable channel/numbers selector and is not transparently retried."),
	"task checkpoint":            builtinMutationAudit(builtinReplayNaturalKey, "task checkpoint is an append operation and is not transparently retried without a receipt."),
	"task delete":                builtinMutationAudit(builtinReplayNaturalKey, "task delete uses the stable channel/number selector and is not transparently retried."),
	"scheduled-message list":     builtinReadAudit(builtinIdentifiersCursor, "scheduled-message list is read-only; no mutation replay key is applicable."),
	"scheduled-message get":      builtinReadAudit(builtinIdentifiersNarrow, "scheduled-message get is read-only; no mutation replay key is applicable."),
	"scheduled-message runs":     builtinReadAudit(builtinIdentifiersCursor, "scheduled-message runs is read-only; no mutation replay key is applicable."),
	"scheduled-message validate": builtinReadAudit(builtinIdentifiersNarrow, "scheduled-message validate is a non-persisting preview; no mutation replay key is applicable."),
	"scheduled-message create":   builtinMutationAudit(builtinReplayIdempotency, "scheduled-message create already carries a durable idempotencyKey and matching payload digest."),
	"scheduled-message update":   builtinMutationAudit(builtinReplayIdempotency, "scheduled-message update already carries a durable idempotencyKey and optimistic version selector."),
	"scheduled-message pause":    builtinMutationAudit(builtinReplayNaturalKey, "pause is a natural status transition and remains non-retried until the API exposes a durable key."),
	"scheduled-message resume":   builtinMutationAudit(builtinReplayNaturalKey, "resume is a natural status transition and remains non-retried until the API exposes a durable key."),
	"scheduled-message delete":   builtinMutationAudit(builtinReplayNaturalKey, "scheduled-message delete is a natural-key deletion and remains non-retried until the API exposes a durable key."),
	"workflow plan":              builtinMutationAudit(builtinReplayWorkflow, "workflow plan is governed by its operation-specific workflow receipt and command idempotency contract."),
	"workflow trigger":           builtinMutationAudit(builtinReplayWorkflow, "workflow trigger is governed by its operation-specific workflow receipt and command idempotency contract."),
	"workflow run":               builtinMutationAudit(builtinReplayWorkflow, "workflow run is governed by its operation-specific workflow receipt and command idempotency contract."),
	"workflow step":              builtinMutationAudit(builtinReplayWorkflow, "workflow step is governed by its trusted run/step identity and operation-specific callback receipt contract."),
}
